opencode-codebase-index 0.5.0 → 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
@@ -16,8 +16,8 @@
16
16
  - ⚡ **Blazing Fast Indexing**: Powered by a Rust native module using `tree-sitter` and `usearch`. Incremental updates take milliseconds.
17
17
  - 🌿 **Branch-Aware**: Seamlessly handles git branch switches — reuses embeddings, filters stale results.
18
18
  - 🔒 **Privacy Focused**: Your vector index is stored locally in your project.
19
- 🔌 **Model Agnostic**: Works out-of-the-box with GitHub Copilot, OpenAI, Gemini, or local Ollama models.
20
- 🌐 **MCP Server**: Use with Cursor, Claude Code, Windsurf, or any MCP-compatible client — index once, search from anywhere.
19
+ - 🔌 **Model Agnostic**: Works out-of-the-box with GitHub Copilot, OpenAI, Gemini, or local Ollama models.
20
+ - 🌐 **MCP Server**: Use with Cursor, Claude Code, Windsurf, or any MCP-compatible client — index once, search from anywhere.
21
21
 
22
22
  ## ⚡ Quick Start
23
23
 
@@ -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": {
@@ -315,7 +333,7 @@ Zero-config by default (uses `auto` mode). Customize in `.opencode/codebase-inde
315
333
 
316
334
  | Option | Default | Description |
317
335
  |--------|---------|-------------|
318
- | `embeddingProvider` | `"auto"` | Which AI to use: `auto`, `github-copilot`, `openai`, `google`, `ollama` |
336
+ | `embeddingProvider` | `"auto"` | Which AI to use: `auto`, `github-copilot`, `openai`, `google`, `ollama`, `custom` |
319
337
  | `scope` | `"project"` | `project` = index per repo, `global` = shared index across repos |
320
338
  | **indexing** | | |
321
339
  | `autoIndex` | `false` | Automatically index on plugin load |
@@ -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)
@@ -351,6 +381,8 @@ The plugin automatically detects available credentials in this order:
351
381
  3. **Google** (Gemini Embeddings)
352
382
  4. **Ollama** (Local/Private - requires `nomic-embed-text`)
353
383
 
384
+ You can also use **Custom** to connect any OpenAI-compatible embedding endpoint (llama.cpp, vLLM, text-embeddings-inference, LiteLLM, etc.).
385
+
354
386
  ### Rate Limits by Provider
355
387
 
356
388
  Each provider has different rate limits. The plugin automatically adjusts concurrency and delays:
@@ -361,6 +393,7 @@ Each provider has different rate limits. The plugin automatically adjusts concur
361
393
  | **OpenAI** | 3 | 500ms | Medium codebases |
362
394
  | **Google** | 5 | 200ms | Medium-large codebases |
363
395
  | **Ollama** | 5 | None | Large codebases (10k+ files) |
396
+ | **Custom** | 3 | 1s | Any OpenAI-compatible endpoint |
364
397
 
365
398
  **For large codebases**, use Ollama locally to avoid rate limits:
366
399
 
@@ -460,6 +493,7 @@ Use this decision tree to pick the right embedding provider:
460
493
  | **GitHub Copilot** | Slow (rate limited) | Free* | Cloud | Small codebases, existing subscribers |
461
494
  | **OpenAI** | Medium | ~$0.0001/1K tokens | Cloud | General use |
462
495
  | **Google** | Fast | Free tier available | Cloud | Medium-large codebases |
496
+ | **Custom** | Varies | Varies | Varies | Self-hosted or third-party endpoints |
463
497
 
464
498
  *Requires active Copilot subscription
465
499
 
@@ -495,6 +529,23 @@ No setup needed if you have an active Copilot subscription.
495
529
  { "embeddingProvider": "github-copilot" }
496
530
  ```
497
531
 
532
+ **Custom (OpenAI-compatible)**
533
+ Works with any server that implements the OpenAI `/v1/embeddings` API format (llama.cpp, vLLM, text-embeddings-inference, LiteLLM, etc.).
534
+ ```json
535
+ {
536
+ "embeddingProvider": "custom",
537
+ "customProvider": {
538
+ "baseUrl": "http://localhost:11434/v1",
539
+ "model": "nomic-embed-text",
540
+ "dimensions": 768,
541
+ "apiKey": "optional-api-key",
542
+ "maxTokens": 8192,
543
+ "timeoutMs": 30000
544
+ }
545
+ }
546
+ ```
547
+ Required fields: `baseUrl`, `model`, `dimensions` (positive integer). Optional: `apiKey`, `maxTokens`, `timeoutMs` (default: 30000).
548
+
498
549
  ## ⚠️ Tradeoffs
499
550
 
500
551
  Be aware of these characteristics:
@@ -564,12 +615,27 @@ CI will automatically run tests and type checking on your PR.
564
615
  The Rust native module handles performance-critical operations:
565
616
  - **tree-sitter**: Language-aware code parsing with JSDoc/docstring extraction
566
617
  - **usearch**: High-performance vector similarity search with F16 quantization
567
- - **SQLite**: Persistent storage for embeddings, chunks, and branch catalog
618
+ - **SQLite**: Persistent storage for embeddings, chunks, branch catalog, symbols, and call edges
568
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)
569
621
  - **xxhash**: Fast content hashing for change detection
570
622
 
571
623
  Rebuild with: `npm run build:native` (requires Rust toolchain)
572
624
 
625
+ ### Platform Support
626
+
627
+ Pre-built native binaries are published for:
628
+
629
+ | Platform | Architecture | SIMD Acceleration |
630
+ |----------|-------------|--------------------|
631
+ | macOS | x86_64 | ✅ simsimd |
632
+ | macOS | ARM64 (Apple Silicon) | ✅ simsimd |
633
+ | Linux | x86_64 (GNU) | ✅ simsimd |
634
+ | Linux | ARM64 (GNU) | ✅ simsimd |
635
+ | Windows | x86_64 (MSVC) | ❌ scalar fallback |
636
+
637
+ Windows builds use scalar distance functions instead of SIMD — functionally identical, marginally slower for very large indexes. This is due to MSVC lacking support for certain AVX-512 intrinsics used by simsimd.
638
+
573
639
  ## License
574
640
 
575
641
  MIT
@@ -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.