opencode-codebase-index 0.18.1 → 0.19.1
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +33 -8
- package/commands/call-graph.md +5 -4
- package/dist/cli.cjs +3991 -1296
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +3896 -1201
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +4985 -2285
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5455 -2755
- package/dist/index.js.map +1 -1
- package/dist/pi-extension.cjs +3712 -906
- package/dist/pi-extension.cjs.map +1 -1
- package/dist/pi-extension.js +3633 -827
- package/dist/pi-extension.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.win32-x64-msvc.node +0 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -407,7 +407,7 @@ Use `include` to replace defaults, or `additionalInclude` to extend (e.g. `"**/*
|
|
|
407
407
|
2. **Chunking**: Large blocks are split with overlapping windows to preserve context across chunk boundaries.
|
|
408
408
|
3. **Embedding**: These blocks are converted into vector representations using your configured AI provider.
|
|
409
409
|
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.
|
|
410
|
-
5. **Hybrid Search**: Combines semantic similarity (vectors) with BM25 keyword matching, fuses (`rrf` default, `weighted` fallback), applies deterministic
|
|
410
|
+
5. **Hybrid Search**: Combines semantic similarity (vectors) with BM25 keyword matching, applies branch and hard metadata scopes before reranking, fuses candidates (`rrf` default, `weighted` fallback), then applies deterministic local intent ranking and optional external reranking.
|
|
411
411
|
|
|
412
412
|
**Performance characteristics:**
|
|
413
413
|
- **Incremental indexing**: ~50ms check time — only re-embeds changed files
|
|
@@ -479,9 +479,13 @@ The plugin exposes these tools to the OpenCode agent:
|
|
|
479
479
|
**Behavioral semantic retrieval with full content.** Searches code by describing behavior.
|
|
480
480
|
- **Use for**: Discovery when you already want full matching snippets and are ready to inspect implementation text.
|
|
481
481
|
- **Example**: `"find the middleware that sanitizes input"`
|
|
482
|
-
- **Ranking path**: hybrid retrieval → fusion (`search.fusionStrategy`) → deterministic rerank (`search.rerankTopN`) →
|
|
482
|
+
- **Ranking path**: hybrid retrieval → branch/directory/file-type/chunk/blame scope → fusion (`search.fusionStrategy`) → deterministic local intent rerank (`search.rerankTopN`) → optional external rerank within local evidence classes → minimum-score filter
|
|
483
483
|
- **Blame filters**: when `indexing.gitBlame.enabled` is `true`, filter with `blameAuthor`, `blameSha`, or `blameSince`.
|
|
484
484
|
|
|
485
|
+
The local ranker is deterministic and does not call another model. Exact symbol names receive a strong NFKC and case-normalized match signal. Definition and implementation questions prefer authoritative declarations over imports, export wrappers, tests, fixtures, docs, and generated or vendor files. Explicit test, docs, config, and call-flow wording instead promotes the requested evidence class. Natural-language conceptual queries keep retrieval score as the dominant signal, while nested duplicate chunks are removed and remaining evidence is spread across relevant files. True score ties retain input order, then candidate id as a final deterministic fallback.
|
|
486
|
+
|
|
487
|
+
When an external reranker is enabled, hard directory, file-type, chunk-type, and blame scopes are enforced before any request. The external service receives only candidates already inside that scope and only the candidate's exact indexed line range, without extra surrounding source. Local intent classification, exact-name promotion, duplicate suppression, and evidence-class ordering remain local.
|
|
488
|
+
|
|
485
489
|
**Writing good queries:**
|
|
486
490
|
|
|
487
491
|
| ✅ Good queries (describe behavior) | ❌ Bad queries (too vague) |
|
|
@@ -530,8 +534,12 @@ Checks if the index is ready and healthy.
|
|
|
530
534
|
Maintenance tool to remove stale entries from deleted files and orphaned embeddings/chunks from the database.
|
|
531
535
|
|
|
532
536
|
### `index_metrics`
|
|
533
|
-
Returns collected metrics about indexing and search performance.
|
|
537
|
+
Returns collected metrics about indexing and search performance. Operational metrics require `debug.enabled` and `debug.metrics` to be `true`.
|
|
534
538
|
- **Metrics include**: Files indexed, chunks created, cache hit rate, search timing breakdown, GC stats, embedding API call stats.
|
|
539
|
+
- **Privacy-safe effectiveness metrics**: Set top-level `effectivenessMetrics.enabled` to `true`. This path does not enable debug logging. It records only fixed route/host/outcome counters and bounded result-count, latency, token-budget, and returned-token histograms. Counters are disabled by default, memory-only, fixed-cardinality, and process-lifetime across Indexer replacement and configuration-watcher refresh. One process-wide collector aggregates opted-in calls without project or repository identity dimensions. It never retains queries, response text, source, symbols, paths, repository names, user identity, or stable identifiers.
|
|
540
|
+
- **Effectiveness-only privacy boundary**: With only `effectivenessMetrics.enabled` set, `debug.enabled` remains `false`, `index_logs` remains disabled, operational debug metrics remain off, and no query, path, source, secret, or response text is emitted by metrics output or written to index files. Only the bounded aggregate snapshot is returned by `index_metrics`.
|
|
541
|
+
- **Debug logging is separate**: Explicitly enabling `debug.enabled` with `debug.logSearch` preserves the existing diagnostic behavior and may retain raw queries and repository details in memory. Do not enable debug search logs when only privacy-safe aggregates are wanted.
|
|
542
|
+
- **Reset**: Pass `reset: true` to clear both operational and process-wide effectiveness metrics before returning the new zeroed snapshot. Process exit also clears effectiveness metrics because they are never persisted.
|
|
535
543
|
|
|
536
544
|
### `index_logs`
|
|
537
545
|
Returns recent debug logs with optional filtering.
|
|
@@ -544,7 +552,7 @@ Query the call graph to find callers or callees of a function/method. Automatica
|
|
|
544
552
|
For Swift, resolution remains name-based, so overloads, extension duplicates, and protocol dispatch can remain ambiguous. Syntax alone cannot always distinguish a superclass from a protocol conformance or an enum raw-value type from a protocol. Constructor classification uses an uppercase ASCII initial heuristic while retaining the exact name for resolution. `tree-sitter-swift` 0.7.3 also has limitations around `sending`, abbreviated collection constructors such as `[Int]()`, and some generic calls after `self`, `super`, optional chaining, or chained calls. The index does not infer SourceKit semantics for these cases.
|
|
545
553
|
|
|
546
554
|
- **Use for**: Understanding code flow, tracing dependencies, impact analysis.
|
|
547
|
-
- **Parameters**: `name` (function name), `direction` (`callers` or `callees`), `
|
|
555
|
+
- **Parameters**: `name` (function name), `direction` (`callers` or `callees`), `filePath` (optional duplicate-name disambiguator), `symbolId` (optional backward-compatible escape hatch), `relationshipType` (optional: `Call`, `MethodCall`, `Constructor`, `Import`, `Inherits`, `Implements`). Unique names resolve automatically; ambiguous names return bounded candidate locations.
|
|
548
556
|
- **Example**: Find who calls `validateToken` → `call_graph(name="validateToken", direction="callers")`
|
|
549
557
|
|
|
550
558
|
### `call_graph_path`
|
|
@@ -552,7 +560,7 @@ For Swift, resolution remains name-based, so overloads, extension duplicates, an
|
|
|
552
560
|
Find the shortest known call-graph path between two symbols. Use it after `codebase_peek`, `implementation_lookup`, or `call_graph` identifies the important source and target names.
|
|
553
561
|
|
|
554
562
|
- **Use for**: Blast-radius checks, dependency-chain discovery, explaining how one subsystem reaches another.
|
|
555
|
-
- **Parameters**: `from` (source symbol name), `to` (target symbol name), `maxDepth` (optional, default `10`).
|
|
563
|
+
- **Parameters**: `from` (source symbol name), `to` (target symbol name), `fromFilePath` and `toFilePath` (optional duplicate-name disambiguators), `maxDepth` (optional, default `10`).
|
|
556
564
|
- **Example**: Trace how `createOrder` reaches `chargeCard` → `call_graph_path(from="createOrder", to="chargeCard")`
|
|
557
565
|
|
|
558
566
|
### `pr_impact`
|
|
@@ -788,7 +796,10 @@ Zero-config by default (uses `auto` mode). Customize in `.opencode/codebase-inde
|
|
|
788
796
|
|
|
789
797
|
// === Indexing ===
|
|
790
798
|
"indexing": {
|
|
791
|
-
"autoIndex": false, //
|
|
799
|
+
"autoIndex": false, // Explicit opt-in for automatic indexing
|
|
800
|
+
"autoIndexWaitMs": 10000, // First-retrieval wait bound (0-60000ms)
|
|
801
|
+
"autoIndexMaxRetries": 5, // Transient interprocess lock retries (0-10)
|
|
802
|
+
"autoIndexRetryDelayMs": 100, // Initial exponential lock retry delay
|
|
792
803
|
"watchFiles": true, // Re-index on file changes
|
|
793
804
|
"maxFileSize": 1048576, // Max file size in bytes (default: 1MB)
|
|
794
805
|
"maxChunksPerFile": 100, // Max chunks per file
|
|
@@ -833,7 +844,10 @@ Zero-config by default (uses `auto` mode). Customize in `.opencode/codebase-inde
|
|
|
833
844
|
"logCache": true, // Log cache hits/misses
|
|
834
845
|
"logGc": true, // Log garbage collection
|
|
835
846
|
"logBranch": true, // Log branch detection
|
|
836
|
-
"metrics": false // Enable metrics collection
|
|
847
|
+
"metrics": false // Enable operational metrics collection
|
|
848
|
+
},
|
|
849
|
+
"effectivenessMetrics": {
|
|
850
|
+
"enabled": false // Opt in without enabling debug logs
|
|
837
851
|
}
|
|
838
852
|
}
|
|
839
853
|
```
|
|
@@ -854,6 +868,8 @@ String values in `codebase-index.json` can reference environment variables with
|
|
|
854
868
|
|
|
855
869
|
### Options Reference
|
|
856
870
|
|
|
871
|
+
`indexing.autoIndex` remains disabled by default because indexing can invoke a paid embedding provider. When explicitly enabled, MCP hosts start one process-scoped job before accepting tool work where practical, skip a healthy current index, retry transient multiprocess lock contention within the configured bound, and expose sanitized state/progress through `index_status`. If no readable index exists, retrieval tools wait up to `autoIndexWaitMs`; after that they report that indexing is still running or failed instead of returning misleading empty search results. Home-directory and project-marker protections still apply.
|
|
872
|
+
|
|
857
873
|
| Option | Default | Description |
|
|
858
874
|
|--------|---------|-------------|
|
|
859
875
|
| `embeddingProvider` | `"auto"` | Which AI to use: `auto`, `github-copilot`, `openai`, `google`, `ollama`, `custom` |
|
|
@@ -863,7 +879,10 @@ String values in `codebase-index.json` can reference environment variables with
|
|
|
863
879
|
| `additionalInclude` | `[]` | Additional file patterns to include (extends defaults, e.g. `"**/*.txt"`, `"**/*.html"`) |
|
|
864
880
|
| `knowledgeBases` | `[]` | External directories to index as knowledge bases (absolute or relative paths) |
|
|
865
881
|
| **indexing** | | |
|
|
866
|
-
| `autoIndex` | `false` |
|
|
882
|
+
| `autoIndex` | `false` | Explicitly opt in to automatic startup/first-use indexing. When disabled, retrieval never starts indexing or paid embedding work. |
|
|
883
|
+
| `autoIndexWaitMs` | `10000` | Maximum time (0-60000ms) a first retrieval waits for an enabled automatic index job before returning actionable in-progress status. |
|
|
884
|
+
| `autoIndexMaxRetries` | `5` | Maximum transient interprocess lock retries (0-10) for background automatic indexing. |
|
|
885
|
+
| `autoIndexRetryDelayMs` | `100` | Initial exponential lock retry delay in milliseconds (10-10000). |
|
|
867
886
|
| `watchFiles` | `true` | Re-index when files change |
|
|
868
887
|
| `maxFileSize` | `1048576` | Skip files larger than this (bytes). Default: 1MB |
|
|
869
888
|
| `maxChunksPerFile` | `100` | Maximum chunks to index per file (controls token costs for large files) |
|
|
@@ -906,6 +925,8 @@ String values in `codebase-index.json` can reference environment variables with
|
|
|
906
925
|
| `logGc` | `true` | Log garbage collection operations |
|
|
907
926
|
| `logBranch` | `true` | Log branch detection and switches |
|
|
908
927
|
| `metrics` | `false` | Enable metrics collection (indexing stats, search timing, cache performance) |
|
|
928
|
+
| **effectivenessMetrics** | | |
|
|
929
|
+
| `enabled` | `false` | Independently opt in to memory-only, fixed-cardinality repository-tool effectiveness counters. Does not enable debug logs; stores no queries, response text, code, symbols, paths, repo names, user identity, or stable identifiers. |
|
|
909
930
|
|
|
910
931
|
### Recovery warnings in debug logs
|
|
911
932
|
|
|
@@ -938,12 +959,16 @@ npm run eval
|
|
|
938
959
|
npm run eval:ci
|
|
939
960
|
npm run eval:ci:ollama
|
|
940
961
|
npm run eval:compare -- --against benchmarks/baselines/eval-baseline-summary.json
|
|
962
|
+
npm run eval:effectiveness
|
|
941
963
|
```
|
|
942
964
|
|
|
943
965
|
CI usage split:
|
|
944
966
|
|
|
945
967
|
- `npm run eval:smoke`: harness smoke check with local mock embeddings (used in main CI)
|
|
946
968
|
- `npm run eval:ci`: real quality gate against baseline/budget (for scheduled/manual quality workflow)
|
|
969
|
+
- `npm run eval:effectiveness`: deterministic offline synthetic-fixture formatting report. Every route receives the same capped ranked result list and final-response token budget. Evidence is credited only when its literal marker is visible in returned text. The baseline emits only exact matching source lines, performs no arbitrary complete reads, makes no network calls, and writes `benchmarks/baselines/privacy-safe-effectiveness.json`.
|
|
970
|
+
|
|
971
|
+
The effectiveness report includes median/p95 `cl100k_base` token counts and final-text evidence recall. Context and peek are metadata-oriented in this benchmark, so they receive no content-evidence credit unless the marker is actually visible in their response. The exact-search snippet baseline uses oracle markers and excludes discovery cost. The report does not measure retrieval quality, latency, end-to-end agent success, causal impact, or production-repository performance.
|
|
947
972
|
|
|
948
973
|
For `eval-quality.yml`, the default CI path uses **GitHub Models** with the workflow `GITHUB_TOKEN` plus `models: read`, so you do not need a separate OpenAI API key just to run the scheduled gate.
|
|
949
974
|
|
package/commands/call-graph.md
CHANGED
|
@@ -10,19 +10,20 @@ Interpret input as follows:
|
|
|
10
10
|
- If input asks for a path, connection, route, chain, or "from X to Y", use `call_graph_path`.
|
|
11
11
|
- Default to `direction="callers"` unless input asks for callees/calls/makes calls.
|
|
12
12
|
- `name=<function>` or plain text function name sets `name`.
|
|
13
|
-
- `
|
|
13
|
+
- Unique names resolve automatically for both directions. Use optional `filePath=<path>` only when duplicate names are reported.
|
|
14
|
+
- `symbolId=<id>` remains an optional backward-compatible escape hatch.
|
|
14
15
|
- For path queries, parse `from=<function>`, `to=<function>`, and optional `maxDepth=<number>`.
|
|
15
16
|
|
|
16
17
|
Execution flow:
|
|
17
18
|
1. If input asks for a path and has source/target names, call `call_graph_path` with `{ from, to, maxDepth? }`.
|
|
18
19
|
2. If direction is `callers`, call `call_graph` with `{ name, direction: "callers" }`.
|
|
19
|
-
3. If direction is `callees
|
|
20
|
-
4. If
|
|
20
|
+
3. If direction is `callees`, call `call_graph` with `{ name, direction: "callees" }`.
|
|
21
|
+
4. If the tool reports duplicate names, retry with the suggested `filePath`; for paths use `fromFilePath` or `toFilePath`.
|
|
21
22
|
|
|
22
23
|
Examples:
|
|
23
24
|
- `/call-graph Database` → callers for `Database`
|
|
24
25
|
- `/call-graph callers name=Indexer` → callers for `Indexer`
|
|
25
|
-
- `/call-graph callees name=Database
|
|
26
|
+
- `/call-graph callees name=Database filePath=src/database.ts` → callees for a duplicate name at that location
|
|
26
27
|
- `/call-graph path from=createOrder to=chargeCard` → shortest known path between the two symbols
|
|
27
28
|
|
|
28
29
|
If output says no callers found, suggest running `/index force` first.
|