index — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited index (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Build the symbol index. Run once before using fetch or search, and re-run when code changes significantly.
# Check config exists
cat .claude/codemunch/config.json 2>/dev/null || echo "NOT_CONFIGURED"
# If missing, run detect-lsp skill first
# Create index directory
mkdir -p .claude/codemunch
# Add to gitignore
grep -q ".claude/codemunch" .gitignore 2>/dev/null || echo ".claude/codemunch" >> .gitignoreLSP doesn't have a batch "index all files" API, but we can use it for on-demand precise symbol lookup. For the index build, use textDocument/documentSymbol on each file.
For each source file in the project:
# Get list of source files (respects .gitignore)
rg --files --type [lang] 2>/dev/null || \
find . -name "*.[ext]" \
-not -path "*/node_modules/*" \
-not -path "*/.git/*" \
-not -path "*/target/*" \
-not -path "*/__pycache__/*" \
-not -path "*/.claude/codemunch/*"Use Claude Code's built-in LSP tool (/lsp) to call textDocument/documentSymbol for each file. This returns all symbols with:
Filter noise kinds: Skip noise kinds: constant, property, variable, enumerator. These inflate the index 15x without adding useful navigation value. Only keep symbols where kind is one of: function, method, class, interface, type, enum, namespace.
Store each kept symbol as:
{
"name": "validateToken",
"kind": "function",
"file": "src/auth/tokens.ts",
"start_line": 142,
"end_line": 163,
"signature": "validateToken(token: string): Promise<User | null>",
"container": "AuthService"
}When LSP is unavailable for a language:
# Universal ctags — generates precise symbol table
universal-ctags \
--recurse \
--output-format=json \
--fields=+n+e+K+S \
--extras=+q \
--exclude=node_modules \
--exclude=.git \
--exclude=target \
--exclude=__pycache__ \
--exclude=.claude/codemunch \
--languages=[detected_languages] \
-f .claude/codemunch/ctags.json \
. 2>/dev/null
# Parse ctags output into codemunch index format
# ctags JSON fields: name, path, pattern, kind, line, end, signature
# Filter: skip noise kinds (constant, property, variable, enumerator)
# Only keep: function, method, class, interface, type, enum, namespacectags supports 40+ languages natively: ActionScript, Ada, Ant, Bash, C, C++, C#, Clojure, CoffeeScript, D, Elixir, Erlang, Fortran, Go, Groovy, Haskell, HTML, Java, JavaScript, JSON, Julia, Kotlin, Lisp, Lua, Make, Matlab, ObjectiveC, OCaml, Perl, PHP, PowerShell, Python, R, Rake, Ruby, Rust, Scala, Scheme, Shell, SQL, Swift, Tcl, TypeScript, Verilog, VHDL, Vim, YAML, Zig
# Verify ctags found symbols
wc -l .claude/codemunch/ctags.jsonWhen neither LSP nor ctags is available. Uses language-aware regex patterns to find symbol declarations:
# TypeScript/JavaScript
rg --json "^(export\s+)?(async\s+)?function\s+(\w+)|^(export\s+)?(abstract\s+)?class\s+(\w+)|^\s+(async\s+)?(\w+)\s*\([^)]*\)\s*[:{]" \
--type ts --type js \
--glob "!node_modules" \
--glob "!.git" \
> .claude/codemunch/rg-ts.jsonl
# Python
rg --json "^(async\s+)?def\s+(\w+)|^class\s+(\w+)" \
--type py \
> .claude/codemunch/rg-py.jsonl
# Go
rg --json "^func\s+(\(.*?\)\s+)?(\w+)|^type\s+(\w+)\s+(struct|interface)" \
--type go \
> .claude/codemunch/rg-go.jsonl
# Rust
rg --json "^(pub(\(.*?\))?\s+)?(async\s+)?fn\s+(\w+)|^(pub(\(.*?\))?\s+)?(struct|enum|trait|impl)\s+(\w+)" \
--type rust \
> .claude/codemunch/rg-rs.jsonl
# Ruby
rg --json "^\s*(def\s+(\w+)|class\s+(\w+)|module\s+(\w+))" \
--type ruby \
> .claude/codemunch/rg-rb.jsonl
# Java/Kotlin
rg --json "(public|private|protected|internal)?\s*(static\s+)?\w+\s+(\w+)\s*\(" \
--type java --type kotlin \
> .claude/codemunch/rg-jvm.jsonl
# C/C++
rg --json "^\w[\w\s\*]+\s+(\w+)\s*\([^;]*\)\s*\{|^(class|struct|enum)\s+(\w+)" \
--type c --type cpp \
> .claude/codemunch/rg-c.jsonl
# PHP
rg --json "^(public|private|protected)?\s*(static\s+)?function\s+(\w+)|^class\s+(\w+)" \
--type php \
> .claude/codemunch/rg-php.jsonlFilter noise kinds: Skip noise kinds: constant, property, variable, enumerator. These inflate the index 15x without adding useful navigation value. The rg patterns should only match function/class/interface/type declarations, not const/let/var assignments unless they are arrow functions. Only keep: function, method, class, interface, type, enum, namespace.
Parse the ripgrep JSONL output to extract symbol name, file, and line number. End line is estimated as start + average function length (20 lines) — this is the only imprecise step. LSP and ctags give exact end lines.
Merge results from whichever engines ran into a single .claude/codemunch/index.json:
{
"version": "2.0",
"generated": "2026-03-11T02:14:00Z",
"engine": "lsp|ctags|rg",
"project_root": "/path/to/project",
"stats": {
"total_symbols": 1247,
"files_indexed": 89,
"languages": ["typescript", "python", "go"]
},
"file_hashes": {
"src/auth/tokens.ts": "a3f2b1c",
"src/lib/validation.ts": "e7d4f9a",
"convex/expenses.ts": "b1c3d5e"
},
"symbols": [
{
"name": "validateToken",
"kind": "function",
"file": "src/auth/tokens.ts",
"start_line": 142,
"end_line": 163,
"signature": "validateToken(token: string): Promise<User | null>",
"container": "AuthService",
"engine": "lsp"
}
]
}The file_hashes field maps each indexed file to its git blob hash (git hash-object <file>). This enables incremental re-indexing — only files whose hash changed need to be re-processed.
# Generate file hashes for all indexed files
for file in $(rg --files --type [lang]); do
echo "\"$file\": \"$(git hash-object "$file" 2>/dev/null || md5 -q "$file")\""
doneAlso build a fast name-lookup dictionary:
{
"validateToken": [0],
"AuthService": [1, 5, 23],
"getUserById": [2]
}(values are indexes into the symbols array)
When called with a list of changed files (from the staleness-gate skill), only re-index those files:
symbol.file is in the changed file listfile_hashes for the changed filesfile_hashes for deleted filesgenerated timestamp and statsThis is much faster than a full re-index for typical edits (1-5 files changed).
If more than 50 files have changed, fall back to a full re-index — it's faster than incremental at that scale.
✅ codemunch index built
Files indexed: 89
Symbols found: 1,247
Engine used: LSP (TypeScript), ctags (Python, Go), rg (Bash)
Index size: 142 KB
Index written to: .claude/codemunch/index.json
Top files by symbol count:
src/api/invoices.ts — 34 symbols
src/lib/auth.ts — 28 symbols
convex/schema.ts — 19 symbols
Run /codemunch:find <name> to look up any symbol.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.