Structural, AST-aware code navigation CLI for large, multi-language repositories.
> /plugin marketplace add defendend/Claude-ast-index-search> /plugin install ast-index@ast-index-marketplace
What's inside
Structural, AST-aware code navigation CLI for large, multi-language repositories. It builds a local SQLite index of symbols, references, imports, modules, dependencies, and inheritance so humans and agents can move through code by exact structure instead of grep-style text matches.
explore, then jump to exact definitions with symbol,
class, outline, and refs.ast-index update after the first rebuild.Languages: Kotlin, Java, Swift, Objective-C, TypeScript, JavaScript, Vue, Svelte, CSS, SCSS, Less, Rust, Zig, C#, Python, Go, C, C++, Scala, PHP, Ruby, Perl, Dart, Protocol Buffers, WSDL, XSD, BSL (1C:Enterprise), Lua, Bash, Elixir, SQL, R, Matlab, Groovy, Common Lisp, GDScript. Project type is auto-detected.
# Install
brew tap defendend/ast-index
brew install ast-index
# Build an index once per project
cd /path/to/project
ast-index rebuild
# Ask code questions
ast-index explore "payment flow"
ast-index search ViewModel
ast-index class BaseFragment
ast-index usages Repository
ast-index implementations Presenter
ast-index deps app
Use ast-index update after edits or branch switches. Hooks can queue a
trailing-debounced refresh without losing edits that arrive during an update:
ast-index update --background --debounce-ms 500
Index-reading commands wait (with a bounded timeout) for an already queued
generation, so they do not observe stale results. In monorepos with nested
project markers, add --walk-up or AST_INDEX_WALK_UP=1 to reuse the root
index.
Guides: User guide for everyday workflow; command setup guide for install/options/examples; CodeGraph comparison for a dated, source-backed feature comparison.
Benchmarks on large Android project (~29k files, ~300k symbols):
| Command | ast-index | grep | Speedup |
|---|---|---|---|
| imports | 0.3ms | 90ms | 260x |
| dependents | 2ms | 100ms | 100x |
| deps | 3ms | 90ms | 90x |
| class | 1ms | 90ms | 90x |
| search | 11ms | 280ms | 14x |
| usages | 8ms | 90ms | 12x |
brew tap defendend/ast-index
brew install ast-index
Requires a Rust toolchain.
cargo install ast-index --locked
To build the unreleased default branch instead:
cargo install --locked --git https://github.com/defendend/Claude-ast-index-search ast-index
Both build from source. For prebuilt release binaries, use Homebrew, npm, or Winget.
winget install --id defendend.ast-index
If you have the old kotlin-index installed:
brew uninstall kotlin-index
brew untap defendend/kotlin-index
brew tap defendend/ast-index
brew install ast-index
git clone https://github.com/defendend/Claude-ast-index-search.git
cd Claude-ast-index-search
cargo build --release
# Binary: target/release/ast-index (~44 MB)
If brew install ast-index fails with merge conflict errors (<<<<<<< HEAD), reset your local tap:
cd /opt/homebrew/Library/Taps/defendend/homebrew-ast-index
git fetch origin
git reset --hard origin/main
brew install ast-index
If your repo has subdirectories with their own VCS markers (git submodules,
subtrees, nested Cargo.toml / settings.gradle), read-commands normally
stop at the nearest marker โ they won't reuse a parent-level index even
if one exists. Pass --walk-up, or set AST_INDEX_WALK_UP=1, to tell
the lookup to prefer any existing parent DB over nested markers:
# once, in the root
cd /monorepo && ast-index rebuild
# later, from any subproject โ reuse the root index
AST_INDEX_WALK_UP=1 ast-index search ViewModel
# or per-call:
ast-index --walk-up search ViewModel
This is opt-in by design: silently preferring a far-away parent DB could
surface a stale or misconfigured index from an earlier accidental
rebuild higher up. With the flag you explicitly say "trust the parent".
Independent git worktrees get independent indexes because their canonical root paths differ. Rebuild once inside each worktree; do not attach worktrees to one another.
For source trees that intentionally form one workspace, create the primary index first, attach a named subtree, then index the attached files:
cd /path/to/application
ast-index rebuild
ast-index subtree add shared ../shared-library
ast-index update # or: ast-index rebuild
ast-index subtree list
Use --subtree shared to query only that attachment and --local to query
only the primary project. The legacy root commands remain compatibility
aliases; new automation should use subtree add/remove/list.
# Option 1: via marketplace
claude plugin marketplace add defendend/Claude-ast-index-search
claude plugin install ast-index
# Option 2: if ast-index is already installed
ast-index install-claude-plugin
Restart Claude Code to activate.
Update: brew upgrade ast-index && claude plugin update ast-index.
Uninstall: claude plugin uninstall ast-index.
The Claude plugin ships /initialize as the default setup command. It
auto-detects project stack(s), including KMP and polyglot repos, then writes
.claude/settings.json and .claude/rules/ast-index.md. Use
/initialize-android, /initialize-ios, /initialize-web, /initialize-rust,
/initialize-csharp, or /initialize-ruby only as manual overrides.
See examples/.claude/rules/ast-index.md
for a template rules file that teaches the agent to use ast-index for
structural navigation, outline before reading large files, and pass the same
instructions to subagents. Adapt before dropping into your project's
.claude/rules/.
Codex can use the shared ast-index skill directly. For local development,
symlink or copy the skill directory into Codex's global skills directory:
mkdir -p ~/.codex/skills
ln -s /absolute/path/to/Claude-ast-index-search/plugin/skills/ast-index ~/.codex/skills/ast-index
This repository also includes a Codex plugin manifest at
plugin/.codex-plugin/plugin.json and a
repo marketplace at .agents/plugins/marketplace.json
for Codex builds that support plugin marketplaces.
If your Codex build supports plugin marketplaces, restart Codex in this repo
and install ast-index from the repo marketplace. For a remote marketplace,
add the repository:
codex plugin marketplace add defendend/Claude-ast-index-search
The Codex package exposes the same ast-index skill. Command-style project
setup is kept out of the Codex manifest because Codex uses skills and local
project configuration as first-class components.
Cursor can use the shared skill directly:
mkdir -p ~/.cursor/skills
ln -s /absolute/path/to/Claude-ast-index-search/plugin/skills/ast-index ~/.cursor/skills/ast-index
This repository also includes a Cursor plugin manifest at
plugin/.cursor-plugin/plugin.json and a
multi-plugin marketplace at .cursor-plugin/marketplace.json.
For local Cursor testing:
mkdir -p ~/.cursor/plugins/local
ln -s /absolute/path/to/Claude-ast-index-search/plugin ~/.cursor/plugins/local/ast-index
Reload Cursor after creating the symlink. The Cursor plugin package exposes the
shared ast-index skill, a project rule in plugin/rules/, and a Cursor-specific
initialize-ast-index command that writes .cursor/rules/ast-index.mdc.
gemini skills install https://github.com/defendend/Claude-ast-index-search.git --path plugin/skills/ast-index
Run ast-index rebuild once per project, then use ast-index update to keep
the index fresh.
ast-index explore <QUERY...> # One-shot context: ranked source + neighbours + tests (--rwr for graph)
ast-index search <QUERY> # Universal structural search
ast-index file <PATTERN> # Find files
ast-index symbol <NAME> # Find symbols
ast-index class <NAME> # Find classes/interfaces
ast-index outline <FILE> # Symbols in file
ast-index imports <FILE> # Imports in file
ast-index refs <SYMBOL> # Definitions + imports + usages
ast-index usages <SYMBOL> # Symbol usages
ast-index callers <FUNCTION> # Function call sites
ast-index implementations <PARENT> # Find implementations
ast-index hierarchy <CLASS> # Class hierarchy tree
ast-index changed [--base BRANCH] # Branch-level changed files (A/M/D/R)
ast-index todo [PATTERN] # TODO/FIXME/HACK comments
ast-index deprecated [QUERY] # Deprecated items
Limited search commands now report completeness explicitly. symbol, class,
implementations, usages, and callers use this shape:
{
"schema_version": 2,
"items": [],
"pagination": {
"total": 0,
"returned": 0,
"truncated": false,
"limit": 50
}
}
search and refs keep their named result arrays and provide one pagination
object per array under pagination. Consumers migrating from bare arrays must
read items for single-result-set commands and must check truncated before
treating a response as complete. This is limit-based pagination, not a cursor:
rerun with a larger --limit when more results are required.
The cache-independent changed command retains its separate JSON schema v1;
its schema version did not change with this pagination migration.
changed asks the detected version-control repository for the files changed from
merge-base(base, HEAD) to HEAD. Without --base, Git resolves
origin/HEAD, then tries origin/main, origin/master, main, master, and
trunk; other supported backends select their conventional mainline. It reads
version-control state directly, so it works without an
ast-index database and does not require rebuild or update. Results are
scoped to the current working directory, while paths remain
repository-relative. Staged and unstaged working-tree edits are not included.
# Compact text summary
ast-index changed
# Stable schema v1; the VCS timeout defaults to 30000 ms
ast-index --format json changed --base origin/main --timeout-ms 30000
# Print the detected root, scope, exact VCS argv, and timing to stderr
ast-index changed --verbose
Text output uses A (added), M (modified), D (deleted), and R (renamed):
Changed files against origin/main (3):
M README.md
R docs/old-guide.md -> docs/setup-guide.md
M docs/generated\nname.md
Control characters and backslashes in text paths are escaped, so every change
FAQ
ast-index is a Claude Code plugin with 1 hand-picked skill for development work, indexed on Flowy. Install it with the command on its page. It includes ast-index. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it