Code Indexing
The indexer turns your workspace into a searchable database. Both Ask + Agent modes then retrieve relevant code as context automatically, and you can call search_vector_db explicitly.
Related: Semantic search covers the query side.
Quick start
Section titled “Quick start”CodeBuddy: Index Workspace for Semantic SearchScans → chunks → embeds → persists. Progress notification shows file + chunk counts and whether embeddings succeeded.
Pipeline
Section titled “Pipeline”File discovery
Section titled “File discovery”Supported extensions: .ts, .tsx, .js, .jsx, .py, .java, .go, .rs, .cpp, .c, .h, .cs, .rb, .php.
Exclusions, layered:
| Layer | Excludes |
|---|---|
| Base | node_modules, .git, dist, out, build, coverage, .codebuddy |
.codebuddyignore | Custom patterns (.gitignore syntax — **, negation !, trailing / for dirs) |
| Sync excludes | *.min.js, *.bundle.js, *.d.ts, .DS_Store, .vscode-test |
| File size | Varies by performance mode |
Run CodeBuddy: Init .codebuddyignore for a starter ignore file. Live-reloads when edited.
.codebuddyignore syntax:
tests/fixtures/** # ignoresrc/generated/*.csv!tests/fixtures/sample.ts # negation — re-includetmp/ # trailing / = dir only/scripts/legacy/ # leading / = anchored to root# comment lines start with #File size limits by performance mode:
| Mode | Max size |
|---|---|
balanced (default) | 1 MB |
performance | 2 MB |
memory | 512 KB |
Chunking
Section titled “Chunking”Runs in a worker thread — never blocks the UI.
| Parameter | Value |
|---|---|
| Chunk size | 1000 chars |
| Overlap | 200 chars |
| Min chunk | 50 chars (smaller discarded) |
Each chunk records id = filePath::charOffset, text, line range, chunk type (text_chunk / function / class / method / block), and language.
Tree-sitter AST chunking ships for 8 grammars — TypeScript, JavaScript, Python, Java, Go, Rust, PHP, C/C++. Split at function/method boundaries, group class bodies, keep imports together, attach docstrings/JSDoc to their function. Languages without a grammar fall back to text-based splitting (char offset + overlap).
Embedding
Section titled “Embedding”Providers:
| Provider | Model | Notes |
|---|---|---|
| Gemini (default) | text-embedding-004 | When codebuddy.vectorDb.embeddingModel = "gemini" |
| OpenAI | text-embedding-3-small | OpenAI-compatible endpoint |
| Local | Configurable | Uses local server’s /embeddings (e.g., nomic-embed-text) |
| DeepSeek / Groq | OpenAI-compatible | Same SDK, different base URL |
Anthropic doesn’t support embeddings — auto-falls back to Gemini.
Batching + rate limits:
| Param | Default |
|---|---|
| Batch size | 5 chunks |
| Rate limit | 1500 req/min (40 ms min interval) |
| Retries | 3, exponential backoff (delay × attempt) |
| Base delay | 1000 ms |
Between batches, setImmediate() yields to the event loop — editor stays responsive.
Smart phases — the embedding pipeline uses different configs per context:
| Phase | Batch | Max files | Delay | Timeout | Retries |
|---|---|---|---|---|---|
| Immediate (save) | 5 | 20 | 100 ms | 30 s | 3 |
| On-demand (query) | 3 | 15 | 200 ms | 20 s | 2 |
| Background (idle) | 10 | 100 | 1000 ms | 60 s | 1 |
| Bulk (full index) | 20 | Unlimited | 500 ms | 120 s | 2 |
Pre-flight check — before bulk indexing, a test embedding verifies the API is reachable. Failure → indexing continues in text-only mode: chunks stored without vectors, keyword search still works, semantic search doesn’t. Re-run after fixing to generate embeddings.
Incremental updates
Section titled “Incremental updates”Content-hash-driven. Cheap on unchanged files.
onDidSaveTextDocumentfires.- SHA-256 hash compared to
file_metadatarow. - Unchanged → skip (no work).
- Changed → remove old chunks for this file → re-chunk → re-embed → persist.
Triggers:
| Trigger | Scope | Behavior |
|---|---|---|
| File save | Single file | Immediate incremental |
| Index Workspace | Whole repo | Bulk; skips unchanged |
| Background processing | Changed files | Debounced (default 1000 ms) |
Auto-filtered: git commit messages, log files, paths containing node_modules, .git, .codebuddy.
Storage
Section titled “Storage”Location: <workspace>/.codebuddy/vector_store.db. Falls back to editor global storage if workspace is unwritable.
Backing: sql.js (WASM). See WASM.
Schema:
CREATE TABLE chunks ( id TEXT PRIMARY KEY, text TEXT NOT NULL, vector BLOB, -- Float32Array (NULL in text-only mode) file_path TEXT NOT NULL, start_line INTEGER NOT NULL, end_line INTEGER NOT NULL, chunk_type TEXT NOT NULL DEFAULT 'text_chunk', language TEXT NOT NULL DEFAULT '', indexed_at TEXT NOT NULL);
CREATE TABLE file_metadata ( file_path TEXT PRIMARY KEY, file_hash TEXT NOT NULL, -- SHA-256 chunk_count INTEGER NOT NULL DEFAULT 0, indexed_at TEXT NOT NULL);FTS4 virtual table synced via SQL triggers on the chunks table (INSERT / DELETE / UPDATE). On startup, if FTS row count falls behind chunks (post-crash), a back-fill runs — anti-join INSERT for < 100 rows, rebuild for larger gaps.
Persistence: dirty-flag + 5-second debounce save. Changes accumulate in memory, flush to disk periodically. Deactivation triggers immediate final flush.
Startup order
Section titled “Startup order”SqliteVectorStoresingleton — loads/creates the DB.HybridSearchService— inits FTS4 virtual table.AstIndexingService— spawns worker, wires embedding service.ContextRetriever— wires search pipeline.onDidSaveTextDocument— enables incremental indexing.codebuddy.indexWorkspacecommand registered.
Settings
Section titled “Settings”Full list in Settings Reference under Vector database + Hybrid search. Key ones:
| Setting | Default | Effect |
|---|---|---|
codebuddy.vectorDb.enabled | true | Master toggle |
codebuddy.vectorDb.performanceMode | "balanced" | Size limits + resource caps |
codebuddy.vectorDb.enableBackgroundProcessing | true | Index changes in the background |
codebuddy.vectorDb.debounceDelay | 1000 | ms wait before re-indexing a changed file |
codebuddy.vectorDb.batchSize | 10 | Files per embedding batch |
codebuddy.indexCodebase | false | Auto-index on startup |
Related
Section titled “Related”- Semantic search — the query side
- WASM — sql.js + Tree-sitter grammars
- Workers — the chunking + embedding pools