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. paragraph.com/@metaend
ai llm eco ast golang
Go 90.7%
Shell 4.9%
Other 4.4%
2 1 0

Clone this repository

https://tangled.org/metaend.eth.xyz/codebase-indexer
git@tangled.org:metaend.eth.xyz/codebase-indexer

For self-hosted knots, clone URLs may differ based on your setup.

README.md

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#

cd /path/to/codebase-indexer
go build -o ~/go/bin/codebase-indexer .

Make sure ~/go/bin is in your PATH.

Usage#

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)#

cp post-commit .git/hooks/
chmod +x .git/hooks/post-commit

Watch Mode (Optional)#

Requires fswatch (brew install fswatch / apt install fswatch).

./watch-index.sh

Output Format#

{
  "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.

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 {
    // ...
}