opencode-codebase-index 0.6.1 → 0.8.0

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
@@ -17,6 +17,8 @@
17
17
  - [🎯 When to Use What](#-when-to-use-what)
18
18
  - [🧰 Tools Available](#-tools-available)
19
19
  - [🎮 Slash Commands](#-slash-commands)
20
+ - [📚 Knowledge Base](#-knowledge-base)
21
+ - [🔄 Reranking](#-reranking)
20
22
  - [⚙️ Configuration](#️-configuration)
21
23
  - [🤝 Contributing](#-contributing)
22
24
 
@@ -54,10 +56,32 @@
54
56
  3. **Index your codebase**
55
57
  Run `/index` or ask the agent to index your codebase. This only needs to be done once — subsequent updates are incremental.
56
58
 
59
+ **Recommended check:** run `/status` after the first index so you can confirm the detected provider/model before you start searching.
60
+
57
61
  4. **Start Searching**
58
62
  Ask:
59
63
  > "Find the function that handles credit card validation errors"
60
64
 
65
+ ### Provider selection notes
66
+
67
+ - **Default auto-detect order:** Ollama → GitHub Copilot → OpenAI → Google
68
+ - **Ollama** is the preferred zero-cost local option and works especially well for large repos:
69
+
70
+ ```bash
71
+ ollama pull nomic-embed-text
72
+ ```
73
+
74
+ ```json
75
+ {
76
+ "embeddingProvider": "ollama"
77
+ }
78
+ ```
79
+
80
+ - **GitHub Copilot** is a good default if OpenCode already has Copilot auth and you prefer hosted embeddings.
81
+ - **OpenAI** is a good hosted option when you want predictable API behavior and standard cloud setup.
82
+ - **Google** is available if you prefer Gemini-hosted embeddings.
83
+ - If `/status` reports provider or compatibility problems, follow that guidance before using `/index force`.
84
+
61
85
  ## 🌐 MCP Server (Cursor, Claude Code, Windsurf, etc.)
62
86
 
63
87
  Use the same semantic search from any MCP-compatible client. Index once, search from anywhere.
@@ -130,12 +154,13 @@ src/api/checkout.ts:89 (Route handler for /pay)
130
154
  | Don't know the function name | `codebase_search` | Semantic search finds by meaning |
131
155
  | Exploring unfamiliar codebase | `codebase_search` | Discovers related code across files |
132
156
  | Just need to find locations | `codebase_peek` | Returns metadata only, saves ~90% tokens |
157
+ | Need the authoritative definition site | `implementation_lookup` | Prioritizes real implementation definitions over docs/tests |
133
158
  | Understand code flow | `call_graph` | Find callers/callees of any function |
134
159
  | Know exact identifier | `grep` | Faster, finds all occurrences |
135
160
  | Need ALL matches | `grep` | Semantic returns top N only |
136
161
  | Mixed discovery + precision | `/find` (hybrid) | Best of both worlds |
137
162
 
138
- **Rule of thumb**: `codebase_peek` to find locations → `Read` to examine → `grep` for precision.
163
+ **Rule of thumb**: `codebase_peek` to find locations → `Read` to examine → `grep` for precision. For symbol-definition questions, use `implementation_lookup` first.
139
164
 
140
165
  ## 📊 Token Usage
141
166
 
@@ -186,7 +211,24 @@ graph TD
186
211
 
187
212
  1. **Parsing**: We use `tree-sitter` to intelligently parse your code into meaningful blocks (functions, classes, interfaces). JSDoc comments and docstrings are automatically included with their associated code.
188
213
 
189
- **Supported Languages**: TypeScript, JavaScript, Python, Rust, Go, Java, C#, Ruby, PHP, Bash, C, C++, JSON, TOML, YAML
214
+ **Supported Languages (Tree-sitter semantic parsing)**: TypeScript, JavaScript, Python, Rust, Go, Java, C#, Ruby, PHP, Apex, Bash, C, C++, JSON, TOML, YAML, Zig
215
+
216
+ **Additional Supported Formats (line-based chunking)**: TXT, HTML, HTM, Markdown, Shell scripts
217
+
218
+ **Default File Patterns**:
219
+ ```
220
+ **/*.{ts,tsx,js,jsx,mjs,cjs} **/*.{py,pyi}
221
+ **/*.{go,rs,java,kt,scala} **/*.{c,cpp,cc,h,hpp}
222
+ **/*.{rb,php,inc,swift} **/*.{vue,svelte,astro}
223
+ **/*.{sql,graphql,proto} **/*.{yaml,yml,toml}
224
+ **/*.{md,mdx} **/*.{sh,bash,zsh}
225
+ **/*.{txt,html,htm} **/*.{cls,trigger}
226
+ **/*.zig
227
+ ```
228
+
229
+ Use `include` to replace defaults, or `additionalInclude` to extend (e.g. `"**/*.pdf"`, `"**/*.csv"`).
230
+
231
+ **Max File Size**: Default 1MB (1048576 bytes). Configure via `indexing.maxFileSize` (bytes).
190
232
  2. **Chunking**: Large blocks are split with overlapping windows to preserve context across chunk boundaries.
191
233
  3. **Embedding**: These blocks are converted into vector representations using your configured AI provider.
192
234
  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.
@@ -237,6 +279,14 @@ When you switch branches, code changes but embeddings for unchanged content rema
237
279
  └── file-hashes.json # File change detection
238
280
  ```
239
281
 
282
+ ### File Exclusions
283
+
284
+ The following files/folders are excluded from indexing by default:
285
+
286
+ - **Hidden files/folders**: Files starting with `.` (e.g., `.github`, `.vscode`, `.env`)
287
+ - **Build folders**: Folders containing "build" in their name (e.g., `build`, `mingwBuildDebug`, `cmake-build-debug`)
288
+ - **Default excludes**: `node_modules`, `dist`, `vendor`, `__pycache__`, `target`, `coverage`, etc.
289
+
240
290
  ## 🧰 Tools Available
241
291
 
242
292
  The plugin exposes these tools to the OpenCode agent:
@@ -265,11 +315,17 @@ The plugin exposes these tools to the OpenCode agent:
265
315
  ```
266
316
  [1] function "validatePayment" at src/billing.ts:45-67 (score: 0.92)
267
317
  [2] class "PaymentProcessor" at src/processor.ts:12-89 (score: 0.87)
268
-
318
+
269
319
  Use Read tool to examine specific files.
270
320
  ```
271
321
  - **Workflow**: `codebase_peek` → find locations → `Read` specific files
272
322
 
323
+ ### `implementation_lookup`
324
+ **Definition-first lookup.** Jumps to the authoritative definition site for a symbol or natural-language definition query.
325
+ - **Use for**: "Where is X defined?", symbol-definition requests, and cases where you want the implementation site rather than all usages.
326
+ - **Behavior**: Prefers real implementation files over tests, docs, examples, and fixtures.
327
+ - **Fallback**: If nothing authoritative is found, use `codebase_search` for broader discovery.
328
+
273
329
  ### `find_similar`
274
330
  Find code similar to a provided snippet.
275
331
  - **Use for**: Duplicate detection, refactor prep, pattern mining.
@@ -282,6 +338,7 @@ Manually trigger indexing.
282
338
 
283
339
  ### `index_status`
284
340
  Checks if the index is ready and healthy.
341
+ - **Recommended workflow**: run this after `/index` to confirm the detected provider/model and whether the index is ready to search.
285
342
 
286
343
  ### `index_health_check`
287
344
  Maintenance tool to remove stale entries from deleted files and orphaned embeddings/chunks from the database.
@@ -295,55 +352,240 @@ Returns recent debug logs with optional filtering.
295
352
  - **Parameters**: `category` (optional: `search`, `embedding`, `cache`, `gc`, `branch`), `level` (optional: `error`, `warn`, `info`, `debug`), `limit` (default: 50).
296
353
 
297
354
  ### `call_graph`
298
- Query the call graph to find callers or callees of a function/method. Automatically built during indexing for TypeScript, JavaScript, Python, Go, and Rust.
355
+
356
+ Query the call graph to find callers or callees of a function/method. Automatically built during indexing for TypeScript, JavaScript, Python, Go, Rust, PHP, and Zig.
357
+
299
358
  - **Use for**: Understanding code flow, tracing dependencies, impact analysis.
300
359
  - **Parameters**: `name` (function name), `direction` (`callers` or `callees`), `symbolId` (required for `callees`, returned by previous queries).
301
360
  - **Example**: Find who calls `validateToken` → `call_graph(name="validateToken", direction="callers")`
302
361
 
362
+ ### `add_knowledge_base`
363
+ Add a folder as a knowledge base to be indexed alongside project code.
364
+ - **Use for**: Indexing external documentation, API references, example programs.
365
+ - **Parameters**: `path` (folder path, absolute or relative), `reindex` (optional, default `true`).
366
+ - **Example**: `add_knowledge_base(path="/path/to/docs")`
367
+
368
+ ### `list_knowledge_bases`
369
+ List all configured knowledge base folders and their status.
370
+
371
+ ### `remove_knowledge_base`
372
+ Remove a knowledge base folder from the index.
373
+ - **Parameters**: `path` (folder path to remove), `reindex` (optional, default `false`).
374
+ - **Example**: `remove_knowledge_base(path="/path/to/docs")`
375
+
303
376
  ## 🎮 Slash Commands
304
377
 
305
378
  The plugin automatically registers these slash commands:
306
379
 
307
380
  | Command | Description |
308
381
  | ------- | ----------- |
382
+ | `/definition <query>` | **Definition Lookup**. Finds the authoritative implementation site for a symbol or concept. |
383
+ | `/peek <query>` | **Quick Semantic Lookup**. Returns likely locations only, without full code content. |
384
+ | `/reindex` | **Full Rebuild**. Rebuilds the codebase index from scratch. |
309
385
  | `/search <query>` | **Pure Semantic Search**. Best for "How does X work?" |
310
386
  | `/find <query>` | **Hybrid Search**. Combines semantic search + grep. Best for "Find usage of X". |
311
387
  | `/call-graph <query>` | **Call Graph Trace**. Find callers/callees to understand execution flow. |
312
- | `/index` | **Update Index**. Forces a refresh of the codebase index. |
388
+ | `/index` | **Update Index**. Runs incremental indexing by default; use `/index force` for a full rebuild. |
313
389
  | `/status` | **Check Status**. Shows if indexed, chunk count, and provider info. |
314
390
 
391
+ ## 📚 Knowledge Base
392
+
393
+ The plugin can index **external documentation** alongside your project code. The indexed codebase includes:
394
+
395
+ - **Project Source Code** — all code files in the current workspace
396
+ - **API References** — hardware API docs, library documentation
397
+ - **Usage Guides** — tutorials, how-to guides
398
+ - **Example Programs** — code samples, demo projects
399
+
400
+ ### Adding Knowledge Base Folders
401
+
402
+ Use the built-in tools to add documentation folders:
403
+
404
+ ```
405
+ add_knowledge_base(path="/path/to/api-docs")
406
+ add_knowledge_base(path="/path/to/examples")
407
+ ```
408
+
409
+ The folder will be indexed into the **same database** as your project code. All searches automatically include both sources.
410
+
411
+ ### Managing Knowledge Bases
412
+
413
+ ```
414
+ list_knowledge_bases # Show configured knowledge bases
415
+ remove_knowledge_base(path="/path/to/api-docs") # Remove a knowledge base
416
+ ```
417
+
418
+ ### Configuration Example
419
+
420
+ Project-level config (`.opencode/codebase-index.json`):
421
+ ```json
422
+ {
423
+ "knowledgeBases": [
424
+ "/home/user/docs/esp-idf",
425
+ "/home/user/docs/arduino"
426
+ ]
427
+ }
428
+ ```
429
+
430
+ Global-level config (`~/.config/opencode/codebase-index.json`):
431
+ ```json
432
+ {
433
+ "embeddingProvider": "custom",
434
+ "customProvider": {
435
+ "baseUrl": "https://api.siliconflow.cn/v1",
436
+ "model": "BAAI/bge-m3",
437
+ "dimensions": 1024,
438
+ "apiKey": "{env:SILICONFLOW_API_KEY}"
439
+ }
440
+ }
441
+ ```
442
+
443
+ Config merging: Global config is the base, project config overrides. Knowledge bases from both levels are merged.
444
+
445
+ ### Syncing Changes
446
+
447
+ - **Project code**: Auto-synced via file watcher (real-time)
448
+ - **Knowledge base folders**: Manual sync — run `/index force` after changes
449
+
450
+ ## 🔄 Reranking
451
+
452
+ The plugin supports **API-based reranking** for improved search result quality. Reranking uses a cross-encoder model to rescore the top search results.
453
+
454
+ ### Enable Reranking
455
+
456
+ Add to your config (`.opencode/codebase-index.json` or global config):
457
+
458
+ ```json
459
+ {
460
+ "reranker": {
461
+ "enabled": true,
462
+ "baseUrl": "https://api.siliconflow.cn/v1",
463
+ "model": "BAAI/bge-reranker-v2-m3",
464
+ "apiKey": "{env:SILICONFLOW_API_KEY}",
465
+ "topN": 20
466
+ }
467
+ }
468
+ ```
469
+
470
+ ### Reranker Options
471
+
472
+ | Option | Default | Description |
473
+ |--------|---------|-------------|
474
+ | `enabled` | `false` | Enable reranking |
475
+ | `baseUrl` | - | Rerank API endpoint |
476
+ | `model` | - | Reranking model name |
477
+ | `apiKey` | - | API key (use `{env:VAR}` for security) |
478
+ | `topN` | `20` | Number of top results to rerank |
479
+ | `timeoutMs` | `30000` | Request timeout |
480
+
481
+ ### How It Works
482
+
483
+ ```
484
+ Query → Embedding Search → BM25 Search → Fusion → Reranking → Results
485
+ ```
486
+
487
+ 1. **Embedding Search**: Semantic similarity via vector search
488
+ 2. **BM25 Search**: Keyword matching via inverted index
489
+ 3. **Fusion**: Combine semantic + keyword results (RRF or weighted)
490
+ 4. **Reranking**: Cross-encoder rescores top N results via API
491
+ 5. **Results**: Final ranked results
492
+
493
+ ### Supported Reranking APIs
494
+
495
+ Any OpenAI-compatible reranking endpoint. Examples:
496
+ - **SiliconFlow**: `BAAI/bge-reranker-v2-m3`
497
+ - **Cohere**: `rerank-english-v3.0`
498
+ - **Local models**: Any server implementing `/v1/rerank` format
499
+
315
500
  ## ⚙️ Configuration
316
501
 
317
502
  Zero-config by default (uses `auto` mode). Customize in `.opencode/codebase-index.json`:
318
503
 
504
+ ### Full Configuration Example
505
+
319
506
  ```json
320
507
  {
321
- "embeddingProvider": "auto",
322
- "scope": "project",
508
+ // === Embedding Provider ===
509
+ "embeddingProvider": "custom", // auto | github-copilot | openai | google | ollama | custom
510
+ "scope": "project", // project (per-repo) | global (shared)
511
+
512
+ // === Custom Embedding API (when embeddingProvider is "custom") ===
513
+ "customProvider": {
514
+ "baseUrl": "https://api.siliconflow.cn/v1",
515
+ "model": "BAAI/bge-m3",
516
+ "dimensions": 1024,
517
+ "apiKey": "{env:SILICONFLOW_API_KEY}",
518
+ "maxTokens": 8192, // Max tokens per input text
519
+ "timeoutMs": 30000, // Request timeout (ms)
520
+ "concurrency": 3, // Max concurrent requests
521
+ "requestIntervalMs": 1000, // Min delay between requests (ms)
522
+ "maxBatchSize": 64 // Max inputs per /embeddings request
523
+ },
524
+
525
+ // === File Patterns ===
526
+ "include": [ // Override default include patterns
527
+ "**/*.{ts,js,py,go,rs}"
528
+ ],
529
+ "exclude": [ // Override default exclude patterns
530
+ "**/node_modules/**"
531
+ ],
532
+ "additionalInclude": [ // Extend defaults (not replace)
533
+ "**/*.{txt,html,htm}",
534
+ "**/*.pdf"
535
+ ],
536
+
537
+ // === Knowledge Bases ===
538
+ "knowledgeBases": [ // External docs to index alongside code
539
+ "/home/user/docs/esp-idf",
540
+ "/home/user/docs/arduino"
541
+ ],
542
+
543
+ // === Indexing ===
323
544
  "indexing": {
324
- "autoIndex": false,
325
- "watchFiles": true,
326
- "maxFileSize": 1048576,
327
- "maxChunksPerFile": 100,
328
- "semanticOnly": false,
329
- "autoGc": true,
330
- "gcIntervalDays": 7,
331
- "gcOrphanThreshold": 100,
332
- "requireProjectMarker": true
545
+ "autoIndex": false, // Auto-index on plugin load
546
+ "watchFiles": true, // Re-index on file changes
547
+ "maxFileSize": 1048576, // Max file size in bytes (default: 1MB)
548
+ "maxChunksPerFile": 100, // Max chunks per file
549
+ "semanticOnly": false, // Only index functions/classes (skip blocks)
550
+ "retries": 3, // Embedding API retry attempts
551
+ "retryDelayMs": 1000, // Delay between retries (ms)
552
+ "autoGc": true, // Auto garbage collection
553
+ "gcIntervalDays": 7, // GC interval (days)
554
+ "gcOrphanThreshold": 100, // GC trigger threshold
555
+ "requireProjectMarker": true, // Require .git/package.json to index
556
+ "maxDepth": 5, // Max directory depth (-1=unlimited, 0=root only)
557
+ "maxFilesPerDirectory": 100, // Max files per directory (smallest first)
558
+ "fallbackToTextOnMaxChunks": true // Fallback to text chunking on maxChunksPerFile
333
559
  },
560
+
561
+ // === Search ===
334
562
  "search": {
335
- "maxResults": 20,
336
- "minScore": 0.1,
337
- "hybridWeight": 0.5,
338
- "fusionStrategy": "rrf",
339
- "rrfK": 60,
340
- "rerankTopN": 20,
341
- "contextLines": 0
563
+ "maxResults": 20, // Max results to return
564
+ "minScore": 0.1, // Min similarity score (0-1)
565
+ "hybridWeight": 0.5, // Keyword (1.0) vs semantic (0.0)
566
+ "fusionStrategy": "rrf", // rrf | weighted
567
+ "rrfK": 60, // RRF smoothing constant
568
+ "rerankTopN": 20, // Deterministic rerank depth
569
+ "contextLines": 0, // Extra lines before/after match
570
+ "routingHints": true // Runtime nudges for local discovery/definition queries
342
571
  },
343
- "debug": {
572
+ "reranker": {
344
573
  "enabled": false,
345
- "logLevel": "info",
346
- "metrics": false
574
+ "provider": "cohere",
575
+ "model": "rerank-v3.5",
576
+ "apiKey": "{env:RERANK_API_KEY}",
577
+ "topN": 15,
578
+ "timeoutMs": 10000
579
+ },
580
+ "debug": {
581
+ "enabled": false, // Enable debug logging
582
+ "logLevel": "info", // error | warn | info | debug
583
+ "logSearch": true, // Log search operations
584
+ "logEmbedding": true, // Log embedding API calls
585
+ "logCache": true, // Log cache hits/misses
586
+ "logGc": true, // Log garbage collection
587
+ "logBranch": true, // Log branch detection
588
+ "metrics": false // Enable metrics collection
347
589
  }
348
590
  }
349
591
  ```
@@ -368,6 +610,10 @@ String values in `codebase-index.json` can reference environment variables with
368
610
  |--------|---------|-------------|
369
611
  | `embeddingProvider` | `"auto"` | Which AI to use: `auto`, `github-copilot`, `openai`, `google`, `ollama`, `custom` |
370
612
  | `scope` | `"project"` | `project` = index per repo, `global` = shared index across repos |
613
+ | `include` | (defaults) | Override the default include patterns (replaces defaults) |
614
+ | `exclude` | (defaults) | Override the default exclude patterns (replaces defaults) |
615
+ | `additionalInclude` | `[]` | Additional file patterns to include (extends defaults, e.g. `"**/*.txt"`, `"**/*.html"`) |
616
+ | `knowledgeBases` | `[]` | External directories to index as knowledge bases (absolute or relative paths) |
371
617
  | **indexing** | | |
372
618
  | `autoIndex` | `false` | Automatically index on plugin load |
373
619
  | `watchFiles` | `true` | Re-index when files change |
@@ -380,6 +626,9 @@ String values in `codebase-index.json` can reference environment variables with
380
626
  | `gcIntervalDays` | `7` | Run GC on initialization if last GC was more than N days ago |
381
627
  | `gcOrphanThreshold` | `100` | Run GC after indexing if orphan count exceeds this threshold |
382
628
  | `requireProjectMarker` | `true` | Require a project marker (`.git`, `package.json`, etc.) to enable file watching and auto-indexing. Prevents accidentally indexing large directories like home. Set to `false` to index any directory. |
629
+ | `maxDepth` | `5` | Max directory traversal depth. `-1` = unlimited, `0` = only files in root dir, `1` = one level of subdirectories, etc. |
630
+ | `maxFilesPerDirectory` | `100` | Max files to index per directory. Always picks the smallest files first. |
631
+ | `fallbackToTextOnMaxChunks` | `true` | When a file exceeds `maxChunksPerFile`, fallback to text-based (line-by-line) chunking instead of skipping the rest of the file. |
383
632
  | **search** | | |
384
633
  | `maxResults` | `20` | Maximum results to return |
385
634
  | `minScore` | `0.1` | Minimum similarity score (0-1). Lower = more results |
@@ -388,6 +637,15 @@ String values in `codebase-index.json` can reference environment variables with
388
637
  | `rrfK` | `60` | RRF smoothing constant. Higher values flatten rank impact, lower values prioritize top-ranked candidates more strongly |
389
638
  | `rerankTopN` | `20` | Deterministic rerank depth cap. Applies lightweight name/path/chunk-type rerank to top-N only |
390
639
  | `contextLines` | `0` | Extra lines to include before/after each match |
640
+ | `routingHints` | `true` | Inject lightweight runtime hints for local conceptual discovery and definition lookups. Set to `false` to disable plugin-side routing nudges. |
641
+ | **reranker** | | Optional second-stage model reranker for the top candidate pool |
642
+ | `enabled` | `false` | Turn external reranking on/off |
643
+ | `provider` | `"custom"` | Hosted shortcuts: `cohere`, `jina`, or `custom` |
644
+ | `model` | — | Reranker model name required when enabled |
645
+ | `baseUrl` | provider default | Override reranker endpoint base URL. `cohere` → `https://api.cohere.ai/v1`, `jina` → `https://api.jina.ai/v1` |
646
+ | `apiKey` | — | API key for hosted reranker providers |
647
+ | `topN` | `15` | Number of top candidates to send to the external reranker |
648
+ | `timeoutMs` | `10000` | Timeout for external rerank requests |
391
649
  | **debug** | | |
392
650
  | `enabled` | `false` | Enable debug logging and metrics collection |
393
651
  | `logLevel` | `"info"` | Log level: `error`, `warn`, `info`, `debug` |
@@ -400,9 +658,11 @@ String values in `codebase-index.json` can reference environment variables with
400
658
 
401
659
  ### Retrieval ranking behavior
402
660
 
403
- - `codebase_search` and `codebase_peek` use the hybrid path: semantic + keyword retrieval → fusion (`fusionStrategy`) → deterministic rerank (`rerankTopN`) → filtering.
661
+ - `codebase_search` and `codebase_peek` use the hybrid path: semantic + keyword retrieval → fusion (`fusionStrategy`) → deterministic rerank (`rerankTopN`) → optional external reranker (`reranker`) → filtering.
662
+ - When `search.routingHints` is enabled (default), the plugin adds tiny per-turn runtime hints for local conceptual discovery and definition queries. Conceptual discovery is nudged toward `codebase_peek` / `codebase_search`, while definition questions are nudged toward `implementation_lookup`. Exact identifier and unrelated operational tasks are left alone.
404
663
  - `find_similar` stays semantic-only: semantic retrieval + deterministic rerank only (no keyword retrieval, no RRF).
405
664
  - For compatibility rollbacks, set `search.fusionStrategy` to `"weighted"` to use the legacy weighted fusion path.
665
+ - When enabled, the external reranker sees path metadata plus a bounded on-disk code snippet for each candidate so it can distinguish real implementations from docs/tests more reliably.
406
666
  - Retrieval benchmark artifacts are separated by role:
407
667
  - baseline (versioned): `benchmarks/baselines/retrieval-baseline.json`
408
668
  - latest candidate run (generated): `benchmark-results/retrieval-candidate.json`
@@ -571,6 +831,12 @@ ollama pull nomic-embed-text
571
831
  }
572
832
  ```
573
833
 
834
+ The built-in `ollama` provider uses Ollama's native `/api/embeddings` endpoint and is the simplest setup when you want to use `nomic-embed-text`.
835
+
836
+ For the built-in Ollama path, the plugin budgets `nomic-embed-text` against an observed effective input limit of about **2048 tokens**, not the model's higher advertised theoretical context. This keeps batching and chunk text generation aligned with real Ollama embedding runtime behavior.
837
+
838
+ If you want to use a different Ollama embedding model through its OpenAI-compatible API, use the `custom` provider instead and set `customProvider.baseUrl` to `http://127.0.0.1:11434/v1` so the plugin calls `.../v1/embeddings`.
839
+
574
840
  ## 📈 Performance
575
841
 
576
842
  The plugin is built for speed with a Rust native module (`tree-sitter`, `usearch`, SQLite). In practice, indexing and retrieval remain fast enough for interactive use on medium/large repositories.
@@ -630,6 +896,26 @@ Works with any server that implements the OpenAI `/v1/embeddings` API format (ll
630
896
  ```
631
897
  Required fields: `baseUrl`, `model`, `dimensions` (positive integer). Optional: `apiKey`, `maxTokens`, `timeoutMs` (default: 30000), `maxBatchSize` (or `max_batch_size`) to cap inputs per `/embeddings` request for servers like text-embeddings-inference. `{env:VAR_NAME}` placeholders are resolved before config validation for fields that are actually used and throw if the referenced environment variable is missing or malformed.
632
898
 
899
+ **Custom Ollama models via OpenAI-compatible API**
900
+ If you are running Ollama locally and want to use an embedding model other than the built-in `ollama` setup, point the custom provider at Ollama's OpenAI-compatible base URL with the `/v1` suffix:
901
+
902
+ ```json
903
+ {
904
+ "embeddingProvider": "custom",
905
+ "customProvider": {
906
+ "baseUrl": "http://127.0.0.1:11434/v1",
907
+ "model": "qwen3-embedding:0.6b",
908
+ "dimensions": 1024,
909
+ "apiKey": "ollama"
910
+ }
911
+ }
912
+ ```
913
+
914
+ Notes:
915
+ - The plugin appends `/embeddings`, so `baseUrl` should be `http://127.0.0.1:11434/v1`, not just `http://127.0.0.1:11434`.
916
+ - Ollama ignores the API key, but some OpenAI-compatible clients expect one, so a placeholder like `"ollama"` is fine.
917
+ - Make sure `dimensions` matches the actual output size of the model you pulled locally.
918
+
633
919
  ## ⚠️ Tradeoffs
634
920
 
635
921
  Be aware of these characteristics:
@@ -657,7 +943,7 @@ Be aware of these characteristics:
657
943
  ]
658
944
  }
659
945
  ```
660
-
946
+
661
947
  This loads directly from your source directory, so changes take effect after rebuilding.
662
948
 
663
949
  ## 🤝 Contributing
@@ -720,7 +1006,7 @@ The Rust native module handles performance-critical operations:
720
1006
  - **usearch**: High-performance vector similarity search with F16 quantization
721
1007
  - **SQLite**: Persistent storage for embeddings, chunks, branch catalog, symbols, and call edges
722
1008
  - **BM25 inverted index**: Fast keyword search for hybrid retrieval
723
- - **Call graph extraction**: Tree-sitter query-based extraction of function calls, method calls, constructors, and imports (TypeScript/JavaScript, Python, Go, Rust)
1009
+ - **Call graph extraction**: Tree-sitter query-based extraction of function calls, method calls, constructors, and imports (TypeScript/JavaScript, Python, Go, Rust, PHP, Zig)
724
1010
  - **xxhash**: Fast content hashing for change detection
725
1011
 
726
1012
  Rebuild with: `npm run build:native` (requires Rust toolchain)
package/commands/index.md CHANGED
@@ -9,13 +9,19 @@ User input: $ARGUMENTS
9
9
  Parse the input and set tool arguments:
10
10
  - force=true if input contains "force"
11
11
  - estimateOnly=true if input contains "estimate"
12
- - verbose=true (always, for detailed output)
12
+ - verbose=false (default, for token efficiency)
13
+ - verbose=true if input contains "verbose" (for detailed output)
13
14
 
14
15
  Examples:
15
- - `/index` → force=false, estimateOnly=false, verbose=true
16
- - `/index force` → force=true, estimateOnly=false, verbose=true
17
- - `/index estimate` → force=false, estimateOnly=true, verbose=true
16
+ - `/index` → force=false, estimateOnly=false, verbose=false
17
+ - `/index force` → force=true, estimateOnly=false, verbose=false
18
+ - `/index estimate` → force=false, estimateOnly=true, verbose=false
19
+ - `/index verbose` → force=false, estimateOnly=false, verbose=true
18
20
 
19
21
  IMPORTANT: You MUST pass the parsed arguments to `index_codebase`. Do not ignore them.
20
22
 
21
23
  Show final statistics including files processed, chunks indexed, tokens used, and duration.
24
+
25
+ If indexing completes but the codebase still is not ready, tell the user to run `/status` next.
26
+ - If `/status` reports failed embedding batches, fix the provider/auth issue and rerun `/index` normally.
27
+ - Use `/index force` only for a full rebuild or when `/status` reports provider/model incompatibility.
@@ -0,0 +1,24 @@
1
+ ---
2
+ description: Quickly find likely code locations without returning full code
3
+ ---
4
+
5
+ Search the codebase using `codebase_peek`.
6
+
7
+ User input: $ARGUMENTS
8
+
9
+ The first part is the search query. Look for optional parameters:
10
+ - `limit=N` or "top N" or "first N" → set limit
11
+ - `type=X` or mentions "functions"/"classes"/"methods" → set chunkType
12
+ - `dir=X` or "in folder X" → set directory filter
13
+ - File extensions like ".ts", "typescript", ".py" → set fileType
14
+
15
+ Call `codebase_peek` with the parsed arguments.
16
+
17
+ Examples:
18
+ - `/peek authentication logic` → query="authentication logic"
19
+ - `/peek error handling limit=5` → query="error handling", limit=5
20
+ - `/peek validation functions` → query="validation", chunkType="function"
21
+
22
+ If the index doesn't exist, run `index_codebase` first.
23
+
24
+ Return results as concise locations with file paths and line numbers. Suggest reading the returned files or using `codebase_search` when the user needs full code context.
@@ -0,0 +1,25 @@
1
+ ---
2
+ description: Fully rebuild the codebase index from scratch
3
+ ---
4
+
5
+ Run the `index_codebase` tool with `force=true` to rebuild the index from scratch.
6
+
7
+ User input: $ARGUMENTS
8
+
9
+ Parse the input and set tool arguments:
10
+ - force=true always
11
+ - estimateOnly=false always
12
+ - verbose=false (default, for token efficiency)
13
+ - verbose=true if input contains "verbose" (for detailed output)
14
+
15
+ Examples:
16
+ - `/reindex` → force=true, estimateOnly=false, verbose=false
17
+ - `/reindex verbose` → force=true, estimateOnly=false, verbose=true
18
+
19
+ IMPORTANT: You MUST call `index_codebase` with `force=true`.
20
+
21
+ Show final statistics including files processed, chunks indexed, tokens used, and duration.
22
+
23
+ If indexing completes but the codebase still is not ready, tell the user to run `/status` next.
24
+ - If `/status` reports failed embedding batches, fix the provider/auth issue and rerun `/index` normally.
25
+ - If `/status` reports provider/model incompatibility again after a rebuild, surface that clearly as an unexpected issue.
@@ -9,7 +9,11 @@ This shows:
9
9
  - Number of indexed chunks
10
10
  - Embedding provider and model being used
11
11
  - Current git branch
12
+ - Failed embedding batches or compatibility warnings that explain why search is not ready
12
13
 
13
14
  No arguments needed - just run `index_status`.
14
15
 
15
- If not indexed, suggest running `/index` to create the index.
16
+ If not indexed:
17
+ - suggest running `/index` when no index exists yet
18
+ - if status reports failed embedding batches, tell the user to fix the provider/auth issue and rerun `/index` normally
19
+ - if status reports provider/model incompatibility, tell the user to run `/index force` for a full rebuild