opencode-codebase-index 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -82,7 +82,7 @@ Use the same semantic search from any MCP-compatible client. Index once, search
82
82
  npx opencode-codebase-index-mcp # uses current directory
83
83
  ```
84
84
 
85
- The MCP server exposes all 8 tools (`codebase_search`, `codebase_peek`, `find_similar`, `index_codebase`, `index_status`, `index_health_check`, `index_metrics`, `index_logs`) and 4 prompts (`search`, `find`, `index`, `status`).
85
+ The MCP server exposes all 9 tools (`codebase_search`, `codebase_peek`, `find_similar`, `call_graph`, `index_codebase`, `index_status`, `index_health_check`, `index_metrics`, `index_logs`) and 4 prompts (`search`, `find`, `index`, `status`).
86
86
 
87
87
  The MCP dependencies (`@modelcontextprotocol/sdk`, `zod`) are optional peer dependencies — they're only needed if you use the MCP server.
88
88
 
@@ -112,6 +112,7 @@ src/api/checkout.ts:89 (Route handler for /pay)
112
112
  | Don't know the function name | `codebase_search` | Semantic search finds by meaning |
113
113
  | Exploring unfamiliar codebase | `codebase_search` | Discovers related code across files |
114
114
  | Just need to find locations | `codebase_peek` | Returns metadata only, saves ~90% tokens |
115
+ | Understand code flow | `call_graph` | Find callers/callees of any function |
115
116
  | Know exact identifier | `grep` | Faster, finds all occurrences |
116
117
  | Need ALL matches | `grep` | Semantic returns top N only |
117
118
  | Mixed discovery + precision | `/find` (hybrid) | Best of both worlds |
@@ -157,10 +158,11 @@ graph TD
157
158
  Q[User Query] -->|Embedding Model| V[Query Vector]
158
159
  V -->|Cosine Similarity| D
159
160
  Q -->|BM25| E
160
- G -->|Branch Filter| F
161
- D --> F[Hybrid Fusion]
161
+ D --> F[Hybrid Fusion RRF/Weighted]
162
162
  E --> F
163
- F --> R[Ranked Results]
163
+ F --> X[Deterministic Rerank]
164
+ G -->|Branch + Metadata Filters| X
165
+ X --> R[Ranked Results]
164
166
  end
165
167
  ```
166
168
 
@@ -170,7 +172,7 @@ graph TD
170
172
  2. **Chunking**: Large blocks are split with overlapping windows to preserve context across chunk boundaries.
171
173
  3. **Embedding**: These blocks are converted into vector representations using your configured AI provider.
172
174
  4. **Storage**: Embeddings are stored in SQLite (deduplicated by content hash) and vectors in `usearch` with F16 quantization for 50% memory savings. A branch catalog tracks which chunks exist on each branch.
173
- 5. **Hybrid Search**: Combines semantic similarity (vectors) with BM25 keyword matching, filtered by current branch.
175
+ 5. **Hybrid Search**: Combines semantic similarity (vectors) with BM25 keyword matching, fuses (`rrf` default, `weighted` fallback), applies deterministic rerank, then filters by current branch/metadata.
174
176
 
175
177
  **Performance characteristics:**
176
178
  - **Incremental indexing**: ~50ms check time — only re-embeds changed files
@@ -211,7 +213,7 @@ When you switch branches, code changes but embeddings for unchanged content rema
211
213
 
212
214
  ```
213
215
  .opencode/index/
214
- ├── codebase.db # SQLite: embeddings, chunks, branch catalog
216
+ ├── codebase.db # SQLite: embeddings, chunks, branch catalog, symbols, call edges
215
217
  ├── vectors.usearch # Vector index (uSearch)
216
218
  ├── inverted-index.json # BM25 keyword index
217
219
  └── file-hashes.json # File change detection
@@ -225,6 +227,7 @@ The plugin exposes these tools to the OpenCode agent:
225
227
  **The primary tool.** Searches code by describing behavior.
226
228
  - **Use for**: Discovery, understanding flows, finding logic when you don't know the names.
227
229
  - **Example**: `"find the middleware that sanitizes input"`
230
+ - **Ranking path**: hybrid retrieval → fusion (`search.fusionStrategy`) → deterministic rerank (`search.rerankTopN`) → filters
228
231
 
229
232
  **Writing good queries:**
230
233
 
@@ -239,6 +242,7 @@ The plugin exposes these tools to the OpenCode agent:
239
242
  ### `codebase_peek`
240
243
  **Token-efficient discovery.** Returns only metadata (file, line, name, type) without code content.
241
244
  - **Use for**: Finding WHERE code is before deciding what to read. Saves ~90% tokens vs `codebase_search`.
245
+ - **Ranking path**: same hybrid ranking path as `codebase_search` (metadata-only output)
242
246
  - **Example output**:
243
247
  ```
244
248
  [1] function "validatePayment" at src/billing.ts:45-67 (score: 0.92)
@@ -248,6 +252,11 @@ The plugin exposes these tools to the OpenCode agent:
248
252
  ```
249
253
  - **Workflow**: `codebase_peek` → find locations → `Read` specific files
250
254
 
255
+ ### `find_similar`
256
+ Find code similar to a provided snippet.
257
+ - **Use for**: Duplicate detection, refactor prep, pattern mining.
258
+ - **Ranking path**: semantic retrieval only + deterministic rerank (no BM25, no RRF).
259
+
251
260
  ### `index_codebase`
252
261
  Manually trigger indexing.
253
262
  - **Use for**: Forcing a re-index or checking stats.
@@ -267,6 +276,12 @@ Returns collected metrics about indexing and search performance. Requires `debug
267
276
  Returns recent debug logs with optional filtering.
268
277
  - **Parameters**: `category` (optional: `search`, `embedding`, `cache`, `gc`, `branch`), `level` (optional: `error`, `warn`, `info`, `debug`), `limit` (default: 50).
269
278
 
279
+ ### `call_graph`
280
+ Query the call graph to find callers or callees of a function/method. Automatically built during indexing for TypeScript, JavaScript, Python, Go, and Rust.
281
+ - **Use for**: Understanding code flow, tracing dependencies, impact analysis.
282
+ - **Parameters**: `name` (function name), `direction` (`callers` or `callees`), `symbolId` (required for `callees`, returned by previous queries).
283
+ - **Example**: Find who calls `validateToken` → `call_graph(name="validateToken", direction="callers")`
284
+
270
285
  ## 🎮 Slash Commands
271
286
 
272
287
  The plugin automatically registers these slash commands:
@@ -301,6 +316,9 @@ Zero-config by default (uses `auto` mode). Customize in `.opencode/codebase-inde
301
316
  "maxResults": 20,
302
317
  "minScore": 0.1,
303
318
  "hybridWeight": 0.5,
319
+ "fusionStrategy": "rrf",
320
+ "rrfK": 60,
321
+ "rerankTopN": 20,
304
322
  "contextLines": 0
305
323
  },
306
324
  "debug": {
@@ -333,6 +351,9 @@ Zero-config by default (uses `auto` mode). Customize in `.opencode/codebase-inde
333
351
  | `maxResults` | `20` | Maximum results to return |
334
352
  | `minScore` | `0.1` | Minimum similarity score (0-1). Lower = more results |
335
353
  | `hybridWeight` | `0.5` | Balance between keyword (1.0) and semantic (0.0) search |
354
+ | `fusionStrategy` | `"rrf"` | Hybrid fusion mode: `"rrf"` (rank-based reciprocal rank fusion) or `"weighted"` (legacy score blending fallback) |
355
+ | `rrfK` | `60` | RRF smoothing constant. Higher values flatten rank impact, lower values prioritize top-ranked candidates more strongly |
356
+ | `rerankTopN` | `20` | Deterministic rerank depth cap. Applies lightweight name/path/chunk-type rerank to top-N only |
336
357
  | `contextLines` | `0` | Extra lines to include before/after each match |
337
358
  | **debug** | | |
338
359
  | `enabled` | `false` | Enable debug logging and metrics collection |
@@ -344,6 +365,15 @@ Zero-config by default (uses `auto` mode). Customize in `.opencode/codebase-inde
344
365
  | `logBranch` | `true` | Log branch detection and switches |
345
366
  | `metrics` | `false` | Enable metrics collection (indexing stats, search timing, cache performance) |
346
367
 
368
+ ### Retrieval ranking behavior (Phase 1)
369
+
370
+ - `codebase_search` and `codebase_peek` use the hybrid path: semantic + keyword retrieval → fusion (`fusionStrategy`) → deterministic rerank (`rerankTopN`) → filtering.
371
+ - `find_similar` stays semantic-only: semantic retrieval + deterministic rerank only (no keyword retrieval, no RRF).
372
+ - For compatibility rollbacks, set `search.fusionStrategy` to `"weighted"` to use the legacy weighted fusion path.
373
+ - Retrieval benchmark artifacts are separated by role:
374
+ - baseline (versioned): `benchmarks/baselines/retrieval-baseline.json`
375
+ - latest candidate run (generated): `benchmark-results/retrieval-candidate.json`
376
+
347
377
  ### Embedding Providers
348
378
  The plugin automatically detects available credentials in this order:
349
379
  1. **GitHub Copilot** (Free if you have it)
@@ -585,8 +615,9 @@ CI will automatically run tests and type checking on your PR.
585
615
  The Rust native module handles performance-critical operations:
586
616
  - **tree-sitter**: Language-aware code parsing with JSDoc/docstring extraction
587
617
  - **usearch**: High-performance vector similarity search with F16 quantization
588
- - **SQLite**: Persistent storage for embeddings, chunks, and branch catalog
618
+ - **SQLite**: Persistent storage for embeddings, chunks, branch catalog, symbols, and call edges
589
619
  - **BM25 inverted index**: Fast keyword search for hybrid retrieval
620
+ - **Call graph extraction**: Tree-sitter query-based extraction of function calls, method calls, constructors, and imports (TypeScript/JavaScript, Python, Go, Rust)
590
621
  - **xxhash**: Fast content hashing for change detection
591
622
 
592
623
  Rebuild with: `npm run build:native` (requires Rust toolchain)
@@ -0,0 +1,24 @@
1
+ ---
2
+ description: Trace callers or callees using the call graph
3
+ ---
4
+
5
+ Trace function dependencies using the `call_graph` tool.
6
+
7
+ User input: $ARGUMENTS
8
+
9
+ Interpret input as follows:
10
+ - Default to `direction="callers"` unless input asks for callees/calls/makes calls.
11
+ - `name=<function>` or plain text function name sets `name`.
12
+ - `symbolId=<id>` is required for `direction="callees"`.
13
+
14
+ Execution flow:
15
+ 1. If direction is `callers`, call `call_graph` with `{ name, direction: "callers" }`.
16
+ 2. If direction is `callees` and `symbolId` is present, call `call_graph` with `{ name, direction: "callees", symbolId }`.
17
+ 3. If direction is `callees` and `symbolId` is missing, first call `call_graph` with `direction="callers"` to get symbol IDs, then ask the user to choose one if multiple are returned.
18
+
19
+ Examples:
20
+ - `/call-graph Database` → callers for `Database`
21
+ - `/call-graph callers name=Indexer` → callers for `Indexer`
22
+ - `/call-graph callees name=Database symbolId=sym_abc123` → callees for selected symbol
23
+
24
+ If output says no callers found, suggest running `/index force` first.