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 +76 -10
- package/commands/call-graph.md +24 -0
- package/dist/cli.cjs +1393 -47
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1393 -47
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1393 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1393 -47
- package/dist/index.js.map +1 -1
- package/native/codebase-index-native.darwin-arm64.node +0 -0
- package/native/codebase-index-native.darwin-x64.node +0 -0
- package/native/codebase-index-native.linux-arm64-gnu.node +0 -0
- package/native/codebase-index-native.linux-x64-gnu.node +0 -0
- package/native/codebase-index-native.win32-x64-msvc.node +0 -0
- package/package.json +2 -3
- package/skill/SKILL.md +13 -1
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
|
|
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
|
-
|
|
161
|
-
D --> F[Hybrid Fusion]
|
|
161
|
+
D --> F[Hybrid Fusion RRF/Weighted]
|
|
162
162
|
E --> F
|
|
163
|
-
F -->
|
|
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,
|
|
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
|
|
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.
|