# Codebase Indexer Lightweight AST-based codebase indexer for AI coding assistants. Generates a `relationships.json` that Claude Code / Cursor / etc. can reference instead of exploring the entire codebase. ## Supported Languages - JavaScript / TypeScript (.js, .jsx, .ts, .tsx) - Astro (.astro) — parses frontmatter imports, treats component as default export - Go (.go) - Python (.py) - Clojure / ClojureScript (.cljs, .clj, .cljc) — detected but not yet parsed (no tree-sitter grammar available) ## Install ```bash cd /path/to/codebase-indexer go build -o ~/go/bin/codebase-indexer . ``` Make sure `~/go/bin` is in your `PATH`. ## Usage ```bash codebase-indexer -root . -out .context/relationships.json ``` ### Flags - `-root` — project root directory (default: `.`) - `-out` — output JSON file (default: `.context/relationships.json`) ## Integration with AI Assistants Copy the snippet from `CLAUDE.md.example` into your project's `CLAUDE.md` (or `AGENTS.md`). ## Auto-index on Commit (Optional) ```bash cp post-commit .git/hooks/ chmod +x .git/hooks/post-commit ``` ## Watch Mode (Optional) Requires `fswatch` (`brew install fswatch` / `apt install fswatch`). ```bash ./watch-index.sh ``` ## Output Format ```json { "files": { "src/utils.py": { "language": "python", "imports": ["os", "pathlib"], "exports": ["load_config", "Config"], "defines": [ {"name": "Config", "type": "class", "line": 4}, {"name": "load_config", "type": "function", "line": 8} ] } }, "symbols": { "Config": {"file": "src/utils.py", "line": 4, "type": "class"} }, "dependencyGraph": { "src/utils.py": ["os", "pathlib"] } } ``` ## .gitignore Add if you don't want to track the index: ``` .context/ ``` Or keep it tracked so it's available immediately on clone. ## Extending To add more languages, add a tree-sitter grammar import and a `parseXXX()` function. Tree-sitter has grammars for 100+ languages. ```go import "github.com/smacker/go-tree-sitter/rust" // In parseFile() switch: case "rust": treeSitterLang = rust.GetLanguage() // Add extension mapping ".rs": "rust", // Add parser function func parseRust(root *sitter.Node, content []byte) FileInfo { // ... } ```