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
Repo: defendend/Claude-ast-index-search
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. 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.
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
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".
# 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
changed asks the detected Git or Arc 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; Arc uses trunk. It reads VCS 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 stays on one output line. Use JSON instead of parsing this human-readable summary in scripts.
JSON output preserves rename metadata:
{
"schema_version": 1,
"vcs": "git",
"base": "origin/main",
"head": "HEAD",
"scope": null,
"changes": [
{ "status": "M", "path": "README.md" },
{ "status": "R", "path": "docs/setup-guide.md", "old_path": "docs/old-guide.md" }
]
}
At the repository root, scope is null; from a nested working directory it
is that repository-relative directory path.
This is a fast file summary for branch review, not a changed-symbol report and
not a replacement for git diff / arc diff when patch hunks are needed.
ast-index module <PATTERN> # Find modules
ast-index deps <MODULE> # Module dependencies
ast-index dependents <MODULE> # Dependent modules
ast-index unused-deps <MODULE> # Find unused dependencies (v3.2: +transitive, XML, resources)
ast-index api <MODULE> # Public API of module
Show how module A reaches module B through the dependency graph:
# Shortest path (default)
ast-index module-route --from core.utils --to features.payments.api
# All simple paths, filtered to api edges only
ast-index module-route --from app --to core.db --all --via-kind api
# JSON output โ machine-readable, no ANSI
ast-index module-route --from app --to core.db --format json
# Mermaid diagram (paste into any markdown renderer)
ast-index module-route --from app --to core.db --format mermaid
# Graphviz DOT
ast-index module-route --from app --to core.db --format dot
# Gradle-style module names work too
ast-index module-route --from :app --to :core:utils
Options:
--all โ return all simple paths instead of the single shortest--via-kind <api|implementation|all> โ filter traversal to one edge kind (default: all)--max-paths <N> โ cap on returned paths when --all is set (default: 50)--max-depth <N> โ cap on path length in hops (default: 20)--timeout-ms <N> โ wall-clock guard in milliseconds (default: 5000)ast-index xml-usages <CLASS> # Find class usages in XML layouts
ast-index resource-usages <RES> # Find resource usages (@drawable/ic_name, R.string.x)
ast-index resource-usages --unused --module <MODULE> # Find unused resources
ast-index storyboard-usages <CLASS> # Class usages in storyboards/xibs
ast-index asset-usages [ASSET] # iOS asset usages (xcassets)
ast-index asset-usages --unused --module <MODULE> # Find unused assets
ast-index swiftui [QUERY] # @State/@Binding/@Published props
ast-index async-funcs [QUERY] # Swift async functions
ast-index publishers [QUERY] # Combine publishers
ast-index main-actor [QUERY] # @MainActor usages
ast-index perl-exports [QUERY] # Find @EXPORT/@EXPORT_OK
ast-index perl-subs [QUERY] # Find subroutines
ast-index perl-pod [QUERY] # Find POD documentation (=head1, =item, etc.)
ast-index perl-tests [QUERY] # Find Test::More assertions (ok, is, like, etc.)
ast-index perl-imports [QUERY] # Find use/require statements
ast-index init # Initialize DB
ast-index rebuild [--type TYPE] # Full reindex
ast-index update # Incremental update
ast-index stats # Index statistics
ast-index version # Version info
Supported elements:
#members, abstract methodsuseXxx)<script> extraction)ast-index class "Component" # Find React/Vue components
ast-index search "use" # Find React hooks
ast-index search "@Controller" # Find NestJS controllers
ast-index class "Props" # Find prop interfaces
Supported elements:
impl Trait for Type)macro_rules!)ast-index class "Service" # Find structs
ast-index class "Repository" # Find traits
ast-index search "impl" # Find impl blocks
ast-index search "macro_rules" # Find macros
Supported elements:
ast-index class "Controller" # Find controllers
ast-index search "has_many" # Find associations
ast-index search "describe" # Find RSpec tests
ast-index search "scope" # Find scopes
Supported elements:
ast-index class "Controller" # Find ASP.NET controllers
ast-index class "IRepository" # Find interfaces
ast-index search "[HttpGet]" # Find API endpoints
ast-index search "MonoBehaviour" # Find Unity scripts
Supported elements:
ast-index class "Widget" # Find widget classes
ast-index class "Provider" # Find providers
ast-index search "mixin" # Find mixins
ast-index implementations "State" # Find State implementations
ast-index outline "main.dart" # Show file structure
ast-index imports "app.dart" # Show imports
ast-index class "ClassName" # Find Python classes
ast-index symbol "function" # Find functions
ast-index outline "file.py" # Show file structure
ast-index imports "file.py" # Show imports
ast-index class "StructName" # Find structs/interfaces
ast-index symbol "FuncName" # Find functions
ast-index outline "file.go" # Show file structure
ast-index imports "file.go" # Show imports
Create .ast-index.yaml in your project root to configure ast-index:
# Additional directories to index
roots:
- "../shared-lib"
- "../common-modules"
# Directories to exclude from indexing
exclude:
- "vendor"
- "build"
- "node_modules"
# Include files ignored by .gitignore
no_ignore: false
All fields are optional. CLI flags override config file values.
Monorepo with shared libraries:
roots:
- "../core"
- "../network"
Project with generated code to skip:
exclude:
- "generated"
- "proto/gen"
changed
from the CLI or MCP to read cache-independent Git/Arc branch changes with
added, modified, deleted, and renamed files, rename metadata,
working-directory scope, a bounded VCS timeout, Git base auto-detection, and
stable JSON schema v1.changed consumers to the file-level contract โ text output now
prints an A/M/D/R file summary instead of regex-derived declaration
pseudo-symbols. Scripts should request --format json and read
changes[].status, changes[].path, and changes[].old_path for renames.
Library callers can use the deprecated Rust compatibility wrappers while
migrating to the new API.See CHANGELOG.md for earlier releases.
.agents/
plugins/
marketplace.json
.claude/
.claude-plugin/
marketplace.json
plugin.json
agents/
bug-fix.md
research.md
review.md
rules/
architecture.md
commands.md
commits.md
parsers.md
release.md
testing.md
verify.md
.cursor-plugin/
marketplace.json
.github/
FUNDING.yml
workflows/
release.yml
sync-plugin.yml
.gitignore
benches/
db_bench.rs
db_query.rs
fixtures/
sample.kt
sample.ts
index_build.rs
parser_bench.rs
parser.rs
pipeline_bench.rs
benchmark.sh
build.rs
Cargo.lock
Cargo.toml
CHANGELOG.md
CLAUDE.md
CONTRIBUTING.md
crates/
ast-index-mcp/
Cargo.toml
src/
format.rs
main.rs
docs/
benchmarks.md
db-schema.md
mcp-setup.md
setup-guide.md
smart-build-research.md
smoke-testing.md
telemetry-pipeline-guide.md
examples/
.claude/
rules/
ast-index.md
README.md
LICENSE
npm/
bin/
ast-index
package.json
platforms/
darwin-arm64/
bin/
.gitkeep
package.json
darwin-x64/
bin/
.gitkeep
package.json
linux-arm64/
bin/
.gitkeep
package.json
linux-x64/
bin/
.gitkeep
package.json
win32-x64/
bin/
.gitkeep
package.json
README.md
plugin/
.claude-plugin/
plugin.json
.codex-plugin/
plugin.json
.cursor-plugin/
plugin.json
commands/
commands-cursor/
initialize-ast-index.md
initialize-android.md
initialize-csharp.md
initialize-ios.md
initialize-ruby.md
initialize-rust.md
initialize-web.md
initialize.md
hooks/
hooks.json
scripts/
grep-reminder.sh
post-edit-update.sh
session-start-refresh.sh
README.md
rules/
ast-index.mdc
skills/
ast-index/
references/
android-commands.md
cpp-commands.md
csharp-commands.md
dart-commands.md
go-commands.md
ios-commands.md
matlab-commands.md
module-commands.md
perl-commands.md
proto-commands.md
python-commands.md
ruby-commands.md
rust-commands.md
typescript-commands.md
wsdl-commands.md
SKILL.md
README.md
scripts/
bump.sh
check-pr.sh
smoke.sh
validate-agent-plugins.sh
src/
commands/
analysis.rs
android.rs
changed.rs
explore.rs
files.rs
grep.rs
index.rs
ios.rs
management.rs
mod.rs
modules.rs
perl.rs
project_info.rs
watch.rs
db.rs
indexer.rs
lib.rs
main.rs
parsers/
mod.rs
perl.rs
treesitter/
bash.rs
bsl.rs
common_lisp.rs
cpp.rs
csharp.rs
css.rs
dart.rs
elixir.rs
gdscript.rs
go.rs
groovy.rs
java.rs
kotlin.rs
less.rs
lua.rs
matlab.rs
mod.rs
objc.rs
php.rs
proto.rs
python.rs
queries/
bash.scm
bsl.scm
commonlisp.scm
cpp.scm
csharp.scm
css.scm
dart.scm
elixir.scm
gdscript.scm
go.scm
groovy.scm
java.scm
kotlin.scm
less.scm
lua.scm
matlab.scm
objc.scm
php.scm
proto.scm
python.scm
r.scm
ruby.scm
rust.scm
scala.scm
scss.scm
sql.scm
swift.scm
typescript.scm
zig.scm
r_lang.rs
ruby.rs
rust_lang.rs
scala.rs
scss.rs
sql.rs
swift.rs
typescript.rs
zig.rs
typescript.rs
wsdl.rs
tests/
api_compatibility_tests.rs
cache_access_cli_tests.rs
cache_path_migration_tests.rs
cache_symlink_migration_tests.rs
changed_command_tests.rs
css_tests.rs
custom_cache_cleanup_tests.rs
db_open_concurrency_tests.rs
detect_stacks_tests.rs
extra_root_collision_tests.rs
files_command_tests.rs
fixture_runner.rs
fixtures/
java/
java-main-test/
Main.java
pom.xml
tests.yaml
User.java
UserService.java
index_publication_tests.rs
indexer_correctness_tests.rs
indexer_detection_tests.rs
management_query_tests.rs
memory_protection_tests.rs
memory_tests.rs
module_route_tests.rs
open_db_gc_lease_tests.rs
parser_proptest.rs
path_resolver_tests.rs
rebuild_freshness_tests.rs
rebuild_swap_path_stability_tests.rs
rebuild_swap_relative_override_tests.rs
rebuild_swap_tests.rs
relative_cache_dir_tests.rs
restore_tests.rs
safe_canonicalize_tests.rs
sql_tests.rs
stale_cache_gc_cli_tests.rs
stale_cache_gc_tests.rs
sub_projects_android_resources_tests.rs
subtree_cli_tests.rs
subtree_decoration_tests.rs
subtree_filter_tests.rs
subtree_legacy_migration_tests.rs
subtree_schema_tests.rs
swift_issues_tests.rs
typescript_issues_tests.rs
update_extra_roots_tests.rs
update_freshness_recovery_tests.rs
usages_activity_tests.rs
vendor_dir_tests.rs
zig_tests.rs
tree-sitter-bsl/
grammar.js
package.json
src/
grammar.json
node-types.json
parser.c
tree_sitter/
alloc.h
array.h
parser.h
tree-sitter.json
USER_GUIDE.mdFAQ
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.