Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"name": "codebase-index",
"source": "./",
"description": "Local-first hybrid codebase index skill with auto-provisioned CLI."
"description": "Find, trace, and predict across a local codebase with evidence-bearing retrieval."
}
]
}
4 changes: 2 additions & 2 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "codebase-index",
"displayName": "Codebase Index",
"description": "Local-first hybrid codebase index. Auto-provisions its Python CLI on first session start; the skill searches the index so Claude reads only the most relevant files.",
"version": "1.6.0",
"description": "Give Claude a precise local map of your codebase: find implementations, trace behavior, and predict change impact with file-line evidence.",
"version": "1.7.0",
"author": {
"name": "codebase-index contributors"
},
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/codebase-index/.skill_version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.6.0
1.7.0
265 changes: 78 additions & 187 deletions .claude/skills/codebase-index/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,198 +1,89 @@
---
name: codebase-index
description: Use this skill before answering questions about a repository's architecture, implementation locations, symbols, references, dependencies, refactoring impact, data flow, bugs, or where something is implemented. It searches a local hybrid codebase index so Claude reads only the most relevant files instead of scanning the entire project.
allowed-tools: Bash(python -m codebase_index *), Bash(python3 -m codebase_index *), Bash(codebase-index *), Bash(cbx *), Read, Grep, Glob
description: Use before answering repository questions about architecture, implementation, symbols, references, dependencies, refactoring impact, data flow, or bugs. Query the local hybrid index first so the agent reads only evidence-bearing file:line ranges instead of scanning the repository.
allowed-tools: Bash(codebase-index search *), Bash(codebase-index explain *), Bash(codebase-index architecture *), Bash(codebase-index symbol *), Bash(codebase-index refs *), Bash(codebase-index impact *), Bash(codebase-index diff-impact *), Bash(codebase-index path *), Bash(codebase-index describe *), Bash(codebase-index graph *), Bash(codebase-index stats *), Bash(codebase-index doctor *), Bash(codebase-index update *), Bash(codebase-index index *), Bash(cbx *), Read, Grep, Glob
---

# Codebase Index

Use this skill first for codebase questions.
Use the local index before reading repository files.

Never scan the entire repository before searching the index.
The operating principle is **Find → Trace → Predict**:

## When to use
- **Find** the implementation with ranked retrieval.
- **Trace** behavior through definitions, callers, dependencies, and paths.
- **Predict** change impact while preserving an explicit evidence trail.

Invoke this skill **before reading any files** when the user asks about this project's code:
## Route the question

- "where is X implemented" / "find X" / "locate the X function"
- "how does X work" / "explain the X flow"
- "what breaks if I change X" / "what depends on X" (impact analysis)
- "who calls X" / "references to X"
- "trace the data flow of X"
- "why is this error happening" (error/stack trace)
- "explain the architecture" / "give me an overview"
- Any question about symbols, files, dependencies, or refactoring scope

Do **not** use it for: editing files, running the application, or non-code questions.

## How to call the CLI

Use the `codebase-index` CLI directly, or the bundled `cbx` wrapper:

```bash
codebase-index search "$QUERY" --json
```

Pick the subcommand by intent:

| User intent | Command |
| Intent | Command |
|---|---|
| "how does X work" / "explain X" / "walk me through" | `codebase-index explain "$QUERY" --json` |
| overview / architecture / "map the codebase" | `codebase-index architecture --json` |
| general / unsure | `codebase-index search "$QUERY" --json` |
| keyword / "where is" | `codebase-index search "$QUERY" --json` |
| a specific symbol name | `codebase-index symbol "<name>" --json` |
| "who calls / references" | `codebase-index refs "<name>" --json` |
| "what breaks if I change" | `codebase-index impact "<file-or-symbol>" --json` |
| "how is X connected to Y" / dependency path | `codebase-index path "<A>" "<B>" --json` |
| "what is X" / describe a symbol's role | `codebase-index describe "<name>" --json` |
| visual graph / "open graph" (for the human, not for you to read) | `codebase-index graph "<file-or-symbol>" --open` |

`architecture` returns the codebase map computed at index time — detected modules
(communities), god nodes (most-connected symbols), surprising cross-module links,
and suggested questions. Reach for it on "give me an overview" / "where do I
start" questions instead of a broad `explain`.

`path "A" "B"` returns the shortest dependency/call chain between two symbols or
files; `describe "X"` returns a node card (definition, callers, callees,
in/out degree, module, god-node rank). Both annotate edges with a `confidence`
(`extracted` exact, `inferred` heuristic, `ambiguous` unresolved) — treat a path
or callee list that leans on `inferred`/`ambiguous` edges as less certain.

The `graph` command renders an HTML dependency graph for a person to look at —
it is not a retrieval packet. Use it only when the user explicitly wants a visual
graph; for "what depends on X" answer from `impact`/`refs` instead. In a headless
session prefer `--output <path>` over `--open`. `--format graphml|dot|neo4j`
exports the graph for external tools (Gephi/yEd, Graphviz, Neo4j) instead of HTML.

`explain` has a higher default token budget (2200) and HOW_IT_WORKS intent weights — use it whenever the question is about understanding behavior or flow.

For `search`, pick a `--mode` when the intent is clear:
- `--mode symbol` — pure symbol lookups (faster, no FTS noise)
- `--mode fts` — text/keyword queries where symbol names don't matter
- `--mode hybrid` — default; best for mixed queries
- `--mode vector` — semantic / near-synonym queries ("where do we rate-limit
requests" without the exact words). Requires opt-in embeddings; falls back with
a clear message when they are not enabled. `hybrid` already blends vectors in
when embeddings are on, so reach for `vector` only for pure-semantic recall.

Natural-language kind words such as `method`, `function`, `class`, `interface`,
`enum`, and `type` constrain the symbol retriever inside `search`.

Use `--json` for programmatic parsing; omit for human-readable output.
Search/read commands auto-build the index when it is missing; still check
freshness and run `update`/`index` when responses report stale data.

## Step-by-step workflow

1. **Query the index** using the appropriate subcommand for `$QUERY`.
2. **Check index freshness** in the response:
- `index.exists: false` → run `codebase-index index` first, then re-query.
- `index.stale: true`, `files_changed_since_build < 20` → run `codebase-index update`, then re-query.
- `index.stale: true`, `files_changed_since_build ≥ 20` → run `codebase-index index` (full rebuild).
- Otherwise proceed with results.
3. **Read ONLY the `recommended_reads`** — use the Read tool with `offset`/`limit` to read the exact line ranges returned. Do not open whole files.
4. **Answer** with file:line citations (e.g., `src/auth/token.py:88-134`).
5. **Fallback** only if confidence is low or results are empty (see below).

## Token-budgeted output interpretation

The index returns a **ranked retrieval packet** with:

- `rank` — result position (start with 1-3)
- `path` — file path
- `line_start` / `line_end` — exact line range to read
- `symbols` — symbols found in this range
- `score` — relevance score
- `reason` — why this result ranked (e.g., "exact symbol match, 4 callers")
- `snippet` — compact code excerpt (may already answer the question); `null` means budget was spent — read via `recommended_reads` instead
- `skeletonized` — when `true`, the `snippet` is a **focus skeleton**: import/signature/class lines and the line(s) matching your query are kept, while function bodies collapse to a marker like `... 24 lines elided (read 88-134)`. Read that line range (or the result's `line_start`/`line_end`) when you need a full body.
- `elided_lines` — how many source lines the skeleton folded away (`0` when not skeletonized).

Top-level fields:

- `recommended_reads` — the precise `{path, line_start, line_end}` list to open next. This is your read plan.
- `confidence` — `high` (answer directly), `medium` (read + optionally confirm with one Grep), `low` (use fallback).
- `fallback_suggestions` — ripgrep patterns and paths to try if the index is weak.
- `intent` / `mode` — how the query was classified and which retrievers ran;
useful to sanity-check a weak result (e.g. a "how does X work" question that
resolved to a bare symbol lookup may need `explain` instead).
- `pagination` — present only when more results exist than fit the page. It
reports `has_more` and `next_offset`. To page, re-run `search` with
`--offset <next_offset>` (e.g. `search "query" --limit 10 --offset 10`). Prefer
refining with a more specific subcommand or raising `--token-budget` first —
page only when the top results genuinely miss the answer.
- `coverage` (on `refs`/`impact` only) — graph-completeness signal. Dependency
edges (imports/inheritance) are extracted only for fully supported languages.
When `coverage.partial` is `true` (the symbol/file is in a Tier-B language such
as Lua), an **empty or short `refs`/`impact` result is inconclusive** — it may
just be unanalyzed, not absent. Confirm with a Grep before concluding "nothing
references this". `coverage.languages` lists the affected languages.

## Token efficiency rules

- Trust the index. Read the **fewest** files needed — start with rank 1-3 only.
- Read **line ranges**, not whole files. Use `line_start`/`line_end` with Read's `offset`/`limit`.
- The `snippet` may already answer the question — re-read only if you need more context.
- Prefer `search`/`symbol`/`refs`/`impact`/`explain` over manual Grep/Glob — those are expensive fallbacks, not step 1.
- Don't re-run the query with trivially reworded text; refine with a different subcommand instead.
- For broad questions (`confidence: low`, architecture, data-flow), raise the budget: `--token-budget 3000`.
- Test files are demoted in ranking by default. Include "test" in the query to surface them.
- Snippets are skeletonized by default to fit more results in the budget. The matched line is always preserved; pass `--raw` (CLI) or `raw: true` (MCP) on the rare occasion you need full bodies inline instead of reading the cited line range.

## Fallback behavior

Fall back to built-in search **only** when: results are empty, `confidence` is `low`, or the user asks for something the index clearly doesn't cover.

0. If confidence is consistently low across queries, run diagnostics first:
```bash
codebase-index stats --json # per-language file/symbol counts + graph tier
codebase-index doctor # surface config or security issues
```
Low symbol counts for a language may mean the index needs a full rebuild: `codebase-index index`.
In `stats`, each language carries `graph: full|partial` (and `doctor` reports a
`graph_coverage` finding): `partial` (Tier-B) means `refs`/`impact` lack
import/inheritance edges for that language — treat empty results there as
inconclusive.

1. Use `fallback_suggestions.ripgrep` patterns from the response via Grep.
2. If still nothing, Glob for likely paths, then Grep within them.
3. As a last resort, broaden the search — but tell the user the index was weak here (it may need a rebuild: `codebase-index index`).

Never start with a full-repo scan when the index exists and is fresh.

## Examples

```bash
# "how does the auth flow work?"
codebase-index explain "auth flow" --json

# "explain the overall architecture" / "where do I start" — modules, god nodes
codebase-index architecture --json

# "where is auth token refresh implemented?"
codebase-index search "auth token refresh" --json

# "what breaks if I change the User model?"
codebase-index impact "User" --json

# "who calls send_email?"
codebase-index refs "send_email" --json

# "find the AuthService class"
codebase-index symbol "AuthService" --json

# precise symbol search (faster, no FTS noise)
codebase-index search "AuthService" --mode symbol --json

# "how is the API layer connected to the database?"
codebase-index path "ApiController" "Database" --json

# "what is the Database class and how is it used?"
codebase-index describe "Database" --json

# generate and open an HTML graph around a file or symbol
codebase-index graph "User" --direction both --depth 2 --open
```

Then Read only the returned line ranges and answer with citations.
| Where is X implemented? | `codebase-index search "X" --json` |
| How does X work? | `codebase-index explain "X" --json` |
| What is this codebase? | `codebase-index architecture --json` |
| Find a named symbol | `codebase-index symbol "X" --json` |
| Who calls or references X? | `codebase-index refs "X" --json` |
| What changes if X changes? | `codebase-index impact "X" --json` |
| What does my current diff affect? | `codebase-index diff-impact --json` |
| How are X and Y connected? | `codebase-index path "X" "Y" --json` |
| Describe X and its neighborhood | `codebase-index describe "X" --json` |
| Produce a human graph | `codebase-index graph "X" --output <path>` |

Use `search --mode symbol` for exact symbol work, `--mode fts` for text and
error messages, and the default `hybrid` mode for mixed questions. Use pure
`vector` mode only when embeddings are enabled and exact vocabulary is unknown.

Read [references/commands.md](references/commands.md) only when command options
or routing remain unclear.

## Evidence protocol

1. Run the best-matching command with `--json`.
2. Check `index` before trusting the payload:
- missing → run `codebase-index index`, then repeat;
- stale with fewer than 20 changed files → run `codebase-index update`;
- stale with 20 or more changed files → run `codebase-index index`;
- fresh → continue.
3. Start with ranks 1–3. Read only `recommended_reads` line ranges.
4. Trace one additional hop only when the question requires behavior,
ownership, or impact.
5. Answer with `file:line` evidence and state uncertainty explicitly.

Do not open whole files when a line range is available. A snippet may already
be sufficient. `skeletonized: true` means the response intentionally folded
unrelated body lines; read the supplied range when the missing body matters.

## Confidence contract

- **high** — answer from the indexed evidence.
- **medium** — read the recommended ranges and confirm the key claim with one
targeted lookup if necessary.
- **low** or no results — follow `fallback_suggestions`, then use a narrow
Grep/Glob fallback.

On `refs` and `impact`, inspect `coverage`. If `coverage.partial` is true, an
empty result is inconclusive; confirm with targeted Grep before saying that
nothing references the target.

Edges carry `confidence`:

- `extracted` — exact parser evidence;
- `inferred` — heuristic resolution;
- `ambiguous` — unresolved or non-unique.

Never present an inferred or ambiguous chain as certain.

## Answer contract

Structure repository answers around:

1. **Answer** — the direct conclusion.
2. **Evidence** — the minimum supporting `file:line` references.
3. **Confidence** — only when evidence is partial, inferred, stale, or missing.
4. **Next check** — only when another check would materially reduce uncertainty.

Do not narrate every search step. Do not claim absence from a partial graph.
Do not replace evidence with a generated HTML graph.

For payload fields and failure handling, read
[references/response-contract.md](references/response-contract.md).
73 changes: 73 additions & 0 deletions .claude/skills/codebase-index/references/commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Command Reference

Load this reference only when the intent table in `SKILL.md` is insufficient.

## Retrieval

```bash
codebase-index search "<query>" --json
codebase-index explain "<topic or flow>" --json
```

Useful search options:

- `--mode hybrid|fts|symbol|vector`
- `--token-budget <tokens>`
- `--limit <count>`
- `--offset <pagination offset>`
- `--raw` to disable snippet skeletonization
- `--no-fallback` to suppress fallback suggestions

`explain` uses the HOW_IT_WORKS intent and a larger default token budget. Prefer
it over repeatedly rewording a broad search.

## Code graph

```bash
codebase-index architecture --json
codebase-index refs "<symbol>" --json
codebase-index impact "<file-or-symbol>" --direction up --depth 2 --json
codebase-index diff-impact --base HEAD --direction up --depth 2 --json
codebase-index path "<source>" "<target>" --json
codebase-index describe "<file-or-symbol>" --json
```

- `architecture` reads module analysis cached at index time.
- `refs` finds definitions, calls, and graph-backed references.
- `impact` walks dependents (`up`), dependencies (`down`), or both.
- `diff-impact` aggregates impact for tracked changes relative to a verified
Git commit; new or excluded files are reported as unresolved.
- `path` returns the shortest known dependency/call chain.
- `describe` returns a node card with callers, callees, module, and centrality.

Use `graph` only for a visualization intended for a person:

```bash
codebase-index graph "<target>" --direction both --depth 2 --output graph.html
```

For headless work, use `--output`; do not use `--open`. Exports also support
`--format graphml|dot|neo4j`.

## Index health

```bash
codebase-index stats --json
codebase-index doctor
codebase-index update
codebase-index index
```

Run `stats` and `doctor` when several unrelated queries have low confidence.
Low symbol counts or partial graph coverage can explain weak results.

## Query examples

```bash
codebase-index search "auth token refresh" --json
codebase-index search "AuthService class" --mode symbol --json
codebase-index search "connection reset by peer" --mode fts --json
codebase-index explain "checkout flow" --json
codebase-index impact "User" --direction up --depth 2 --json
codebase-index path "ApiController" "Database" --json
```
Loading
Loading