Skip to content
rohitkg98Public

About

DSL for token effiencient & readable codesearch

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

smartgrep

Your code is a database. Why query it with full-text search?

Agents using grep have to regex their way to understanding — pattern-matching raw text, parsing noise, running multiple commands to answer one question. smartgrep parses source files via tree-sitter, extracts symbols into a structured index, and lets agents query the code the same way you'd query a database.

The queries are designed to be readable by humans and generatable by LLMs, unlike grep regexes.

# grep — terse, brittle, requires regex expertise to read
grep -rn "^pub\s\+fn\|pub async fn" src/commands/ | grep -v "//\|mod.rs"

# smartgrep — reads like a sentence
smartgrep query "functions where visibility = public and file contains 'commands/'"

When Claude uses smartgrep, you can see exactly what it's looking for at a glance.


Installation

macOS, Linux, FreeBSD, Android (Termux):

curl -fsSL https://raw.githubusercontent.com/rohitkg98/smartgrep/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/rohitkg98/smartgrep/main/install.ps1 | iex

Both install a prebuilt binary for your platform from the latest release. No Rust required.

OS Architectures Release asset
macOS Apple Silicon (arm64), Intel (x86_64) smartgrep-{aarch64,x86_64}-apple-darwin.tar.gz
Linux x86_64, arm64, armv7, armv6 (Raspberry Pi Zero/1), i686, riscv64, ppc64le, loongarch64 smartgrep-<arch>-unknown-linux-musl*.tar.gz (static, any distro)
Linux s390x smartgrep-s390x-unknown-linux-gnu.tar.gz (glibc 2.17+)
Windows x86_64, arm64 smartgrep-{x86_64,aarch64}-pc-windows-msvc.zip
FreeBSD x86_64 smartgrep-x86_64-unknown-freebsd.tar.gz
Android (Termux) arm64, armv7 uses the static Linux binaries; installs into $PREFIX/bin

Where it installs: /usr/local/bin if writable, else ~/.local/bin (Termux: $PREFIX/bin; Windows: %LOCALAPPDATA%\Programs\smartgrep, added to your user PATH). Options, as environment variables for either script:

curl -fsSL https://raw.githubusercontent.com/rohitkg98/smartgrep/main/install.sh | SMARTGREP_VERSION=0.4.0 sh      # pin a version
curl -fsSL https://raw.githubusercontent.com/rohitkg98/smartgrep/main/install.sh | SMARTGREP_INSTALL_DIR=~/bin sh   # install elsewhere
$env:SMARTGREP_VERSION = "0.4.0"; irm https://raw.githubusercontent.com/rohitkg98/smartgrep/main/install.ps1 | iex

Checksums: every release has a SHA256SUMS file. The install scripts verify the download against it (when sha256sum, shasum, sha256 or openssl is available; always on Windows). To check a manual download: sha256sum -c SHA256SUMS --ignore-missing.

Other platforms: no prebuilt binary? Build from source (Rust 1.70+):

cargo install --git https://github.com/rohitkg98/smartgrep

Update

smartgrep update

Fetches and runs the install script to replace the binary in-place.

From source

git clone git@github.com:rohitkg98/smartgrep.git
cd smartgrep
cargo install --path .

Requires Rust 1.70+.


Quick start

curl -fsSL https://raw.githubusercontent.com/rohitkg98/smartgrep/main/install.sh | sh
cd your-project
smartgrep init

smartgrep init makes the project agent-ready in one non-interactive step: it detects languages, builds the index, adds a short smartgrep section (between <!-- smartgrep:start --> / <!-- smartgrep:end --> markers) to CLAUDE.md and/or AGENTS.md with examples that use your project's real symbols, installs the repo-scoped Claude Code skill, and adds .smartgrep/ to .gitignore. Re-running it refreshes the section in place; nothing outside the markers is touched.

smartgrep init --dry-run     # show what would change, write nothing
smartgrep init --agents-md   # also create/update AGENTS.md
smartgrep init --no-skill    # skip .claude/skills/smartgrep/SKILL.md

Giving smartgrep to Claude

smartgrep init (above) covers this for a single repo. To install only the skill:

Install as a Claude Code skill so Claude automatically uses smartgrep for structural questions — no prompting needed:

smartgrep install-skill --global    # all projects (~/.claude/skills/)
smartgrep install-skill             # this repo only (.claude/skills/)

Or add to your project's CLAUDE.md manually:

## Code Navigation

Use `smartgrep` for structural code queries instead of grep/find.

- `smartgrep query "<dsl>"` for composable one-shot structural questions
- `smartgrep context <file>` for a structural overview of a file
- `smartgrep query "symbol <Name> | with deps, refs"` to understand a symbol's role
- Use batch queries (semicolon-separated) to answer multi-part questions in one call

Watching what Claude does

Every smartgrep call is logged. Run this to see Claude's recent queries:

smartgrep log

Example output:

ts                   command  args                                                      results  ms
2026-03-14 10:42:11  query    classes where attributes contains '@RestController'            4  12
2026-03-14 10:42:18  query    methods where parent = UserController | with signature         7   9
2026-03-14 10:42:31  query    symbol OrderService | with deps, refs                          1   8
2026-03-14 10:43:02  query    functions where file contains 'commands/' | with params        6  11

Each line is one tool call Claude made. Compare these to what you'd have had to decipher with grep:

# What Claude asked for (smartgrep)              # What you'd have with grep
classes where attributes contains '@RestController'   grep -rn "@RestController" src/ | grep "^class\|^public class"
methods where parent = UserController                 grep -rn "UserController" src/ | grep "^\s\+public\|void\|String"
symbol OrderService | with deps, refs                 grep -rn "OrderService" src/ | grep "import\|extends\|new OrderService"

The smartgrep query column tells you exactly what Claude was looking for, in plain language.


Query DSL

The query command is the main feature. Queries compose a source, optional filters, and pipeline stages:

source [where conditions] [| stage] [| stage] ...

Readability in practice

Side by side with grep, for the same questions:

What you want to know grep smartgrep
All public functions grep -rn "^pub fn|pub async fn" src/ functions where visibility = public
Spring REST controllers grep -rn "@RestController" src/ | grep "class " classes where attributes contains '@RestController'
Methods on UserService grep -rn "UserService" src/ | grep "def |public " methods where parent = UserService
Structs with 5+ fields (requires reading each file) structs | with fields | where field_count > 5
What does Config depend on grep -rn "Config" src/ | grep "use |import |new " symbol Config | with deps

The grep column requires knowing the language's syntax, writing a correct regex, and filtering noise. The smartgrep column reads like a question.

Sources

symbols / structs / classes / interfaces / records / functions / methods
traits / enums / impls / consts / types / modules
symbol <name>          -- single symbol lookup
deps [<name>]          -- dependencies (all, or for one symbol)
refs [<name>]          -- references (all, or to one symbol)
<source> in '<path>'   -- restrict to files matching a path substring

Filters

where <field> <op> <value> [and|or ...]
Field Applies to
name, file, visibility, kind, parent symbols
attributes symbols with annotations/decorators
field_count, param_count after with fields / with params
from, to, dep_kind dependency rows
Operator Meaning
= / is equals (case-insensitive)
!= not equals
contains substring match
starts_with / ends_with prefix / suffix
not contains / not starts_with / not ends_with negated match (true when the field is absent)
> < >= <= numeric comparison

Pipeline stages

Stages follow | and apply left to right:

  • with fields — add struct/class/enum field list and count
  • with params — add function/method parameter list and count
  • with deps — add outbound dependencies
  • with refs — add inbound references
  • with signature — add full type signature
  • show col1, col2 — select specific output columns
  • where field_count > 5 — filter after enrichment
  • sort field asc|desc — sort results
  • limit N — cap output

Batch queries

Separate queries with ; to run multiple in one call:

smartgrep query "structs | with fields; enums | with fields"
smartgrep query "classes where file contains 'service/'; methods where parent = UserController"

Results print under # Query 1, # Query 2 headers.

Path aliases

Long file paths in text output are automatically shortened. src/main/java/com/example/catalog/controller/ProductController.java becomes [P]controller/ProductController.java, with a [paths] legend at the top. JSON output always keeps full paths.


Supported languages

  • Rust — full support via tree-sitter-rust
  • Java — full support via tree-sitter-java
  • Go — full support via tree-sitter-go
  • TypeScript — full support via tree-sitter-typescript (.ts, .tsx)
  • Python — full support via tree-sitter-python (.py, .pyi)

Adding a language means writing one parser and registering it in src/lang.rs. The IR layer and query engine are language-agnostic.


Architecture

Parser (tree-sitter) --> IR --> Index Builder --> Index --> Commands / Query Engine
  • Parser (src/parser/) — language-specific, produces the IR
  • IR (src/ir/types.rs) — language-agnostic symbol and dependency maps
  • Index (src/index/types.rs) — queryable, with lookup tables for fast symbol resolution

Auto-indexing: queries trigger indexing implicitly. The index rebuilds when source files change.

See AGENTS_README.md for the agent-targeted reference.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in smartgrep by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

DSL for token effiencient & readable codesearch

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages