viberag 0.4.4 → 0.6.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.
Files changed (257) hide show
  1. package/README.md +108 -114
  2. package/dist/cli/app.js +38 -11
  3. package/dist/cli/commands/handlers.d.ts +17 -14
  4. package/dist/cli/commands/handlers.js +403 -71
  5. package/dist/cli/commands/mcp-setup.js +8 -4
  6. package/dist/cli/commands/useCommands.js +41 -17
  7. package/dist/cli/components/CleanWizard.js +31 -3
  8. package/dist/cli/components/InitWizard.d.ts +3 -3
  9. package/dist/cli/components/InitWizard.js +123 -45
  10. package/dist/cli/components/McpSetupWizard.js +1 -1
  11. package/dist/cli/components/SearchResultsDisplay.js +101 -29
  12. package/dist/cli/components/StatusBar.js +72 -12
  13. package/dist/cli/components/WelcomeBanner.js +10 -2
  14. package/dist/cli/index.js +2 -0
  15. package/dist/cli/store/app/slice.d.ts +2524 -182
  16. package/dist/cli/store/app/slice.js +7 -1
  17. package/dist/cli/store/wizard/selectors.d.ts +1 -1
  18. package/dist/cli/store/wizard/selectors.js +1 -1
  19. package/dist/cli/store/wizard/slice.d.ts +38 -22
  20. package/dist/cli/store/wizard/slice.js +3 -3
  21. package/dist/cli/utils/error-handler.d.ts +3 -3
  22. package/dist/cli/utils/error-handler.js +3 -3
  23. package/dist/client/auto-start.js +28 -18
  24. package/dist/client/index.d.ts +28 -1
  25. package/dist/client/index.js +35 -0
  26. package/dist/client/types.d.ts +49 -15
  27. package/dist/common/types.d.ts +61 -11
  28. package/dist/daemon/handlers.js +110 -14
  29. package/dist/daemon/index.d.ts +5 -2
  30. package/dist/daemon/index.js +15 -9
  31. package/dist/daemon/lib/abort.d.ts +7 -0
  32. package/dist/daemon/lib/abort.js +42 -0
  33. package/dist/daemon/lib/chunker/grammars.d.ts +25 -0
  34. package/dist/daemon/lib/chunker/grammars.js +69 -0
  35. package/dist/daemon/lib/chunker/index.d.ts +55 -1
  36. package/dist/daemon/lib/chunker/index.js +1591 -49
  37. package/dist/daemon/lib/chunker/types.d.ts +49 -0
  38. package/dist/daemon/lib/config.d.ts +13 -4
  39. package/dist/daemon/lib/config.js +48 -5
  40. package/dist/daemon/lib/constants.d.ts +51 -17
  41. package/dist/daemon/lib/constants.js +94 -20
  42. package/dist/daemon/lib/gitignore.d.ts +4 -2
  43. package/dist/daemon/lib/gitignore.js +58 -28
  44. package/dist/daemon/lib/logger.d.ts +5 -5
  45. package/dist/daemon/lib/logger.js +6 -6
  46. package/dist/daemon/lib/merkle/index.d.ts +10 -2
  47. package/dist/daemon/lib/merkle/index.js +23 -3
  48. package/dist/daemon/lib/secrets.d.ts +51 -0
  49. package/dist/daemon/lib/secrets.js +128 -0
  50. package/dist/daemon/lib/update-check.d.ts +31 -0
  51. package/dist/daemon/lib/update-check.js +160 -0
  52. package/dist/daemon/owner.d.ts +71 -20
  53. package/dist/daemon/owner.js +267 -66
  54. package/dist/daemon/protocol.d.ts +1 -1
  55. package/dist/daemon/providers/api-utils.d.ts +18 -4
  56. package/dist/daemon/providers/api-utils.js +102 -17
  57. package/dist/daemon/providers/gemini.js +5 -4
  58. package/dist/daemon/providers/local.d.ts +1 -1
  59. package/dist/daemon/providers/local.js +7 -3
  60. package/dist/daemon/providers/mistral.js +4 -2
  61. package/dist/daemon/providers/mock.js +2 -0
  62. package/dist/daemon/providers/openai.js +3 -2
  63. package/dist/daemon/providers/types.d.ts +2 -0
  64. package/dist/daemon/server.js +3 -3
  65. package/dist/daemon/services/types.d.ts +30 -8
  66. package/dist/daemon/services/types.js +9 -3
  67. package/dist/daemon/services/v2/eval/eval.d.ts +50 -0
  68. package/dist/daemon/services/v2/eval/eval.js +522 -0
  69. package/dist/daemon/services/v2/extract/extract.d.ts +110 -0
  70. package/dist/daemon/services/v2/extract/extract.js +440 -0
  71. package/dist/daemon/services/v2/indexing.d.ts +69 -0
  72. package/dist/daemon/services/v2/indexing.js +680 -0
  73. package/dist/daemon/services/v2/manifest.d.ts +56 -0
  74. package/dist/daemon/services/v2/manifest.js +161 -0
  75. package/dist/daemon/services/v2/search/engine.d.ts +69 -0
  76. package/dist/daemon/services/v2/search/engine.js +1932 -0
  77. package/dist/daemon/services/v2/search/types.d.ts +101 -0
  78. package/dist/daemon/services/v2/search/types.js +6 -0
  79. package/dist/daemon/services/v2/storage/index.d.ts +59 -0
  80. package/dist/daemon/services/v2/storage/index.js +323 -0
  81. package/dist/daemon/services/v2/storage/schema.d.ts +32 -0
  82. package/dist/daemon/services/v2/storage/schema.js +139 -0
  83. package/dist/daemon/services/v2/storage/types.d.ts +100 -0
  84. package/dist/daemon/services/v2/storage/types.js +7 -0
  85. package/dist/daemon/services/watcher.d.ts +15 -1
  86. package/dist/daemon/services/watcher.js +132 -7
  87. package/dist/daemon/state.d.ts +17 -3
  88. package/dist/daemon/state.js +13 -0
  89. package/dist/mcp/index.js +1 -1
  90. package/dist/mcp/server.d.ts +13 -12
  91. package/dist/mcp/server.js +690 -700
  92. package/dist/test-setup.js +9 -0
  93. package/package.json +10 -3
  94. package/scripts/clean-dist.js +20 -0
  95. package/dist/cli/commands/index.d.ts +0 -2
  96. package/dist/cli/commands/index.js +0 -2
  97. package/dist/cli/commands/useRagCommands.d.ts +0 -20
  98. package/dist/cli/commands/useRagCommands.js +0 -183
  99. package/dist/cli/components/SlotRow.d.ts +0 -22
  100. package/dist/cli/components/SlotRow.js +0 -55
  101. package/dist/cli/components/index.d.ts +0 -1
  102. package/dist/cli/components/index.js +0 -1
  103. package/dist/cli/hooks/useStatusPolling.d.ts +0 -34
  104. package/dist/cli/hooks/useStatusPolling.js +0 -121
  105. package/dist/cli-bundle.cjs +0 -5269
  106. package/dist/common/components/SlotRow.d.ts +0 -22
  107. package/dist/common/components/SlotRow.js +0 -53
  108. package/dist/common/components/StatusBar.d.ts +0 -8
  109. package/dist/common/components/StatusBar.js +0 -128
  110. package/dist/common/components/index.d.ts +0 -3
  111. package/dist/common/components/index.js +0 -3
  112. package/dist/common/hooks/index.d.ts +0 -4
  113. package/dist/common/hooks/index.js +0 -4
  114. package/dist/common/hooks/useStaticOutputBuffer.d.ts +0 -31
  115. package/dist/common/hooks/useStaticOutputBuffer.js +0 -58
  116. package/dist/common/index.d.ts +0 -13
  117. package/dist/common/index.js +0 -17
  118. package/dist/daemon/lib/manifest.d.ts +0 -67
  119. package/dist/daemon/lib/manifest.js +0 -118
  120. package/dist/daemon/providers/index.d.ts +0 -14
  121. package/dist/daemon/providers/index.js +0 -14
  122. package/dist/daemon/providers/local-4b.d.ts +0 -28
  123. package/dist/daemon/providers/local-4b.js +0 -51
  124. package/dist/daemon/services/index.d.ts +0 -11
  125. package/dist/daemon/services/index.js +0 -16
  126. package/dist/daemon/services/indexing.d.ts +0 -121
  127. package/dist/daemon/services/indexing.js +0 -656
  128. package/dist/daemon/services/search/filters.d.ts +0 -21
  129. package/dist/daemon/services/search/filters.js +0 -106
  130. package/dist/daemon/services/search/fts.d.ts +0 -32
  131. package/dist/daemon/services/search/fts.js +0 -61
  132. package/dist/daemon/services/search/hybrid.d.ts +0 -17
  133. package/dist/daemon/services/search/hybrid.js +0 -58
  134. package/dist/daemon/services/search/index.d.ts +0 -108
  135. package/dist/daemon/services/search/index.js +0 -417
  136. package/dist/daemon/services/search/types.d.ts +0 -126
  137. package/dist/daemon/services/search/types.js +0 -4
  138. package/dist/daemon/services/search/vector.d.ts +0 -25
  139. package/dist/daemon/services/search/vector.js +0 -44
  140. package/dist/daemon/services/storage/index.d.ts +0 -110
  141. package/dist/daemon/services/storage/index.js +0 -383
  142. package/dist/daemon/services/storage/schema.d.ts +0 -24
  143. package/dist/daemon/services/storage/schema.js +0 -51
  144. package/dist/daemon/services/storage/types.d.ts +0 -105
  145. package/dist/daemon/services/storage/types.js +0 -71
  146. package/dist/mcp/services/lazy-loader.d.ts +0 -23
  147. package/dist/mcp/services/lazy-loader.js +0 -34
  148. package/dist/mcp/warmup.d.ts +0 -92
  149. package/dist/mcp/warmup.js +0 -202
  150. package/dist/mcp/watcher.d.ts +0 -84
  151. package/dist/mcp/watcher.js +0 -343
  152. package/dist/rag/config/index.d.ts +0 -67
  153. package/dist/rag/config/index.js +0 -135
  154. package/dist/rag/constants.d.ts +0 -71
  155. package/dist/rag/constants.js +0 -95
  156. package/dist/rag/embeddings/api-utils.d.ts +0 -121
  157. package/dist/rag/embeddings/api-utils.js +0 -259
  158. package/dist/rag/embeddings/fastembed.d.ts +0 -62
  159. package/dist/rag/embeddings/fastembed.js +0 -124
  160. package/dist/rag/embeddings/gemini.d.ts +0 -28
  161. package/dist/rag/embeddings/gemini.js +0 -169
  162. package/dist/rag/embeddings/index.d.ts +0 -13
  163. package/dist/rag/embeddings/index.js +0 -13
  164. package/dist/rag/embeddings/local-4b.d.ts +0 -28
  165. package/dist/rag/embeddings/local-4b.js +0 -51
  166. package/dist/rag/embeddings/local.d.ts +0 -36
  167. package/dist/rag/embeddings/local.js +0 -166
  168. package/dist/rag/embeddings/mistral.d.ts +0 -24
  169. package/dist/rag/embeddings/mistral.js +0 -124
  170. package/dist/rag/embeddings/mock.d.ts +0 -35
  171. package/dist/rag/embeddings/mock.js +0 -69
  172. package/dist/rag/embeddings/openai.d.ts +0 -30
  173. package/dist/rag/embeddings/openai.js +0 -152
  174. package/dist/rag/embeddings/types.d.ts +0 -63
  175. package/dist/rag/embeddings/validate.d.ts +0 -30
  176. package/dist/rag/embeddings/validate.js +0 -161
  177. package/dist/rag/gitignore/index.d.ts +0 -57
  178. package/dist/rag/gitignore/index.js +0 -231
  179. package/dist/rag/index.d.ts +0 -15
  180. package/dist/rag/index.js +0 -25
  181. package/dist/rag/indexer/bounded-channel.d.ts +0 -51
  182. package/dist/rag/indexer/bounded-channel.js +0 -138
  183. package/dist/rag/indexer/chunker.d.ts +0 -129
  184. package/dist/rag/indexer/chunker.js +0 -1364
  185. package/dist/rag/indexer/index.d.ts +0 -6
  186. package/dist/rag/indexer/index.js +0 -6
  187. package/dist/rag/indexer/indexer.d.ts +0 -76
  188. package/dist/rag/indexer/indexer.js +0 -521
  189. package/dist/rag/indexer/types.d.ts +0 -74
  190. package/dist/rag/indexer/types.js +0 -47
  191. package/dist/rag/logger/index.d.ts +0 -42
  192. package/dist/rag/logger/index.js +0 -152
  193. package/dist/rag/manifest/index.d.ts +0 -50
  194. package/dist/rag/manifest/index.js +0 -96
  195. package/dist/rag/merkle/diff.d.ts +0 -26
  196. package/dist/rag/merkle/diff.js +0 -95
  197. package/dist/rag/merkle/hash.d.ts +0 -34
  198. package/dist/rag/merkle/hash.js +0 -165
  199. package/dist/rag/merkle/index.d.ts +0 -68
  200. package/dist/rag/merkle/index.js +0 -298
  201. package/dist/rag/merkle/node.d.ts +0 -51
  202. package/dist/rag/merkle/node.js +0 -69
  203. package/dist/rag/search/filters.d.ts +0 -21
  204. package/dist/rag/search/filters.js +0 -100
  205. package/dist/rag/search/fts.d.ts +0 -32
  206. package/dist/rag/search/fts.js +0 -61
  207. package/dist/rag/search/hybrid.d.ts +0 -17
  208. package/dist/rag/search/hybrid.js +0 -58
  209. package/dist/rag/search/index.d.ts +0 -101
  210. package/dist/rag/search/index.js +0 -393
  211. package/dist/rag/search/types.d.ts +0 -126
  212. package/dist/rag/search/types.js +0 -4
  213. package/dist/rag/search/vector.d.ts +0 -25
  214. package/dist/rag/search/vector.js +0 -44
  215. package/dist/rag/storage/index.d.ts +0 -106
  216. package/dist/rag/storage/index.js +0 -374
  217. package/dist/rag/storage/lancedb-native.d.ts +0 -7
  218. package/dist/rag/storage/lancedb-native.js +0 -10
  219. package/dist/rag/storage/schema.d.ts +0 -21
  220. package/dist/rag/storage/schema.js +0 -48
  221. package/dist/rag/storage/types.d.ts +0 -100
  222. package/dist/rag/storage/types.js +0 -68
  223. package/dist/store/app/selectors.d.ts +0 -87
  224. package/dist/store/app/selectors.js +0 -28
  225. package/dist/store/app/slice.d.ts +0 -1013
  226. package/dist/store/app/slice.js +0 -112
  227. package/dist/store/hooks.d.ts +0 -22
  228. package/dist/store/hooks.js +0 -17
  229. package/dist/store/index.d.ts +0 -12
  230. package/dist/store/index.js +0 -18
  231. package/dist/store/indexing/listeners.d.ts +0 -25
  232. package/dist/store/indexing/listeners.js +0 -46
  233. package/dist/store/indexing/selectors.d.ts +0 -195
  234. package/dist/store/indexing/selectors.js +0 -69
  235. package/dist/store/indexing/slice.d.ts +0 -309
  236. package/dist/store/indexing/slice.js +0 -113
  237. package/dist/store/slot-progress/listeners.d.ts +0 -23
  238. package/dist/store/slot-progress/listeners.js +0 -33
  239. package/dist/store/slot-progress/selectors.d.ts +0 -67
  240. package/dist/store/slot-progress/selectors.js +0 -36
  241. package/dist/store/slot-progress/slice.d.ts +0 -246
  242. package/dist/store/slot-progress/slice.js +0 -70
  243. package/dist/store/store.d.ts +0 -17
  244. package/dist/store/store.js +0 -18
  245. package/dist/store/warmup/selectors.d.ts +0 -109
  246. package/dist/store/warmup/selectors.js +0 -44
  247. package/dist/store/warmup/slice.d.ts +0 -137
  248. package/dist/store/warmup/slice.js +0 -72
  249. package/dist/store/watcher/selectors.d.ts +0 -115
  250. package/dist/store/watcher/selectors.js +0 -52
  251. package/dist/store/watcher/slice.d.ts +0 -269
  252. package/dist/store/watcher/slice.js +0 -100
  253. package/dist/store/wizard/selectors.d.ts +0 -115
  254. package/dist/store/wizard/selectors.js +0 -36
  255. package/dist/store/wizard/slice.d.ts +0 -523
  256. package/dist/store/wizard/slice.js +0 -119
  257. /package/dist/{rag/embeddings/types.js → test-setup.d.ts} +0 -0
package/README.md CHANGED
@@ -6,9 +6,9 @@
6
6
 
7
7
  VibeRAG is fully local, offline capable MCP server for local codebase search.
8
8
 
9
- - Semantic codebase search
10
- - Keyword codebase search (BM25)
11
- - Hybrid codebase search (with tunable parameters)
9
+ - Intent-routed codebase search (definitions/files/blocks/usages)
10
+ - Hybrid retrieval (full-text + vector search)
11
+ - Explainable results with stable follow-ups (open spans, get symbols, find usages)
12
12
 
13
13
  VibeRAG automatically indexes your codebase into a local container-free vector database ([lancedb](https://lancedb.com/)). Every time you make a change, the indexes are automatically updated.
14
14
 
@@ -48,11 +48,11 @@ When using a coding agent like [Claude Code](https://claude.ai/code), add `use v
48
48
  ## Features
49
49
 
50
50
  - **CLI based setup** - CLI commands and wizards for setup, editor integration, and configuration
51
- - **Semantic code search** - Find code by meaning, not just keywords
51
+ - **Agent-first search** - Find definitions, entry files, and relevant blocks (not just “chunks”)
52
52
  - **Flexible embeddings** - Local model (offline, free) or cloud providers (Gemini, Mistral, OpenAI)
53
53
  - **MCP server** - Works with Claude Code, Cursor, VS Code Copilot, and more
54
- - **Automatic incremental indexing** - Watches for file changes (respects `.gitignore`) and reindexes only what has changed in real time
55
- - **Resilient indexing** - Retries embedding errors and reports failed batches in `/status`
54
+ - **Automatic incremental indexing** - Watches for file changes (respects `.gitignore` + `.viberagignore`) and reindexes only what has changed in real time
55
+ - **Cancelable indexing** - Supports `/cancel` and clear status reporting via `/status`
56
56
  - **Multi-language support** - TypeScript, JavaScript, Python, Go, Rust, and more
57
57
  - **Blazing fast** - The data storage and search functionality is local on your machine, meaning the full power of your machine can churn through massive amounts of data and execute complex search queries in milliseconds.
58
58
 
@@ -452,120 +452,107 @@ args = ["-y", "viberag-mcp"]
452
452
 
453
453
  ## Exposed MCP Tools
454
454
 
455
- | Tool | Description |
456
- | -------------------------- | ---------------------------------------------------- |
457
- | `codebase_search` | Semantic, keyword, or hybrid search for code |
458
- | `codebase_parallel_search` | Run multiple search strategies in parallel |
459
- | `viberag_index` | Index the codebase (incremental by default) |
460
- | `viberag_status` | Get index status, file count, and embedding provider |
461
- | `viberag_watch_status` | Get file watcher status for auto-indexing |
455
+ VibeRAG exposes a small set of agent-centric tools. Backward compatibility with
456
+ legacy tool names is not provided.
462
457
 
463
- #### `codebase_search`
458
+ | Tool | Description |
459
+ | ---------------------- | --------------------------------------------------------------------- |
460
+ | `codebase_search` | Intent-routed search with grouped results + stable IDs for follow-ups |
461
+ | `help` | Usage guide for MCP tools + how search works |
462
+ | `read_file_lines` | Read an exact line range from disk |
463
+ | `get_symbol_details` | Fetch a symbol definition + deterministic metadata by `symbol_id` |
464
+ | `find_references` | Find usage occurrences (refs) for a symbol name or `symbol_id` |
465
+ | `get_surrounding_code` | Expand a hit into neighbors (symbols/chunks) and related metadata |
466
+ | `build_index` | Build/update the index (incremental by default) |
467
+ | `get_status` | Get index + daemon status summary |
468
+ | `get_watcher_status` | Get watcher status (auto-indexing) |
469
+ | `cancel_operation` | Cancel indexing or warmup without shutting down the daemon |
464
470
 
465
- The primary search tool. Finds code by meaning, not just keywords.
471
+ ### `codebase_search`
466
472
 
467
- **Search Modes:**
473
+ Single entry point with intent routing. Use `scope` for transparent filters.
468
474
 
469
- | Mode | Best For |
470
- | ------------ | -------------------------------------------- |
471
- | `hybrid` | Most queries (default) - combines both |
472
- | `semantic` | Conceptual queries ("how does auth work?") |
473
- | `exact` | Symbol names, specific strings |
474
- | `definition` | Direct symbol lookup ("where is X defined?") |
475
- | `similar` | Find code similar to a snippet |
475
+ - `intent`: `auto|definition|usage|concept|exact_text|similar_code`
476
+ - Definition-style symbol lookups tolerate small typos via fuzzy (Levenshtein) name matching.
477
+ - `scope`: `path_prefix`, `path_contains`, `path_not_contains`, `extension`
478
+ - `explain`: include per-hit channels + ranking priors
476
479
 
477
- **Key Parameters:**
478
-
479
- - `query` - Natural language search query
480
- - `mode` - Search mode (default: `hybrid`)
481
- - `limit` - Max results (default: 10, max: 100)
482
- - `bm25_weight` - Balance keyword vs semantic (0-1, default: 0.3)
483
- - `filters` - Path, type, and metadata filters
484
-
485
- **Example:**
480
+ Example:
486
481
 
487
482
  ```json
488
483
  {
489
- "query": "authentication middleware",
490
- "mode": "hybrid",
491
- "limit": 15,
492
- "filters": {
493
- "path_not_contains": ["test", "mock"],
494
- "is_exported": true
495
- }
484
+ "query": "how does authentication work",
485
+ "intent": "concept",
486
+ "scope": {
487
+ "path_prefix": ["src/"],
488
+ "path_not_contains": ["test", "__tests__", ".spec.", ".test."]
489
+ },
490
+ "k": 20,
491
+ "explain": true
496
492
  }
497
493
  ```
498
494
 
499
- #### `codebase_parallel_search`
500
-
501
- Run multiple search strategies simultaneously and merge results. Best for comprehensive exploration.
502
-
503
- **Use Cases:**
495
+ Follow-ups: `get_symbol_details`, `read_file_lines`, `get_surrounding_code`, `find_references`.
504
496
 
505
- - Compare semantic vs keyword results
506
- - Search related concepts together
507
- - Test different weight settings
497
+ ## CLI Commands
508
498
 
509
- **Example:**
499
+ VibeRAG includes a CLI for easy execution of initialization, indexing, setup, and other things you may want to manually control outside of agent use.
510
500
 
511
- ```json
512
- {
513
- "searches": [
514
- {"query": "authentication", "mode": "semantic", "limit": 10},
515
- {"query": "auth login JWT", "mode": "exact", "limit": 10},
516
- {"query": "user session", "mode": "hybrid", "bm25_weight": 0.5, "limit": 10}
517
- ],
518
- "merge_results": true,
519
- "merge_strategy": "rrf",
520
- "merged_limit": 20
521
- }
522
- ```
501
+ | Command | Description |
502
+ | ----------------- | --------------------------------------------------------- |
503
+ | `/init` | Initialize VibeRAG (configure embeddings, index codebase) |
504
+ | `/index` | Index the codebase (incremental) |
505
+ | `/reindex` | Force full reindex |
506
+ | `/search <query>` | Semantic search |
507
+ | `/status` | Show daemon and index status |
508
+ | `/cancel` | Cancel indexing or warmup |
509
+ | `/mcp-setup` | Configure MCP server for AI tools |
510
+ | `/clean` | Remove VibeRAG from project |
511
+ | `/help` | Show all commands |
523
512
 
524
- #### `viberag_index`
513
+ ## Data Directory
525
514
 
526
- Manually trigger indexing. Normally not needed as file watching handles updates automatically.
515
+ VibeRAG stores all per-project state (config, index, logs) globally under:
527
516
 
528
- **Parameters:**
517
+ - `~/.local/share/viberag/projects/<projectId>/` (override via `VIBERAG_HOME`)
529
518
 
530
- - `force` - Full reindex ignoring cache (default: `false`)
519
+ No files are written into your repo.
531
520
 
532
- #### `viberag_status`
521
+ ## Ignoring Files
533
522
 
534
- Check index health and configuration.
523
+ VibeRAG uses `.gitignore` rules to exclude files and folders from indexing. For
524
+ non-git projects (or for additional ignore patterns), you can create a
525
+ `.viberagignore` file in the project root.
535
526
 
536
- **Returns:**
527
+ - `.viberagignore` uses the exact same pattern syntax as `.gitignore`
528
+ - It is applied in addition to `.gitignore` (if present)
537
529
 
538
- - File count, chunk count
539
- - Embedding provider and dimensions
540
- - Schema version
541
- - Last update timestamp
542
- - Warmup status (ready, initializing, etc.)
530
+ Example `.viberagignore`:
543
531
 
544
- #### `viberag_watch_status`
532
+ ```gitignore
533
+ # build outputs
534
+ dist/
535
+ build/
545
536
 
546
- Check the file watcher for auto-indexing.
537
+ # local artifacts
538
+ coverage/
539
+ tmp/
547
540
 
548
- **Returns:**
541
+ # generated bundles
542
+ **/*.min.js
543
+ ```
549
544
 
550
- - Whether watching is active
551
- - Number of files being watched
552
- - Pending changes count
553
- - Last update timestamp
545
+ ## Logs
554
546
 
555
- ## CLI Commands
547
+ VibeRAG writes per-service logs with hourly rotation:
556
548
 
557
- VibeRAG includes a CLI for easy execution of initialization, indexing, setup, and other things you may want to manually control outside of agent use.
549
+ - `~/.local/share/viberag/projects/<projectId>/logs/daemon/` - daemon lifecycle and IPC errors
550
+ - `~/.local/share/viberag/projects/<projectId>/logs/indexer/` - indexing progress, retries, and batch failures
551
+ - `~/.local/share/viberag/projects/<projectId>/logs/mcp/` - MCP server errors
552
+ - `~/.local/share/viberag/projects/<projectId>/logs/cli/` - CLI errors
558
553
 
559
- | Command | Description |
560
- | ----------------- | --------------------------------------------------------- |
561
- | `/init` | Initialize VibeRAG (configure embeddings, index codebase) |
562
- | `/index` | Index the codebase (incremental) |
563
- | `/reindex` | Force full reindex |
564
- | `/search <query>` | Semantic search |
565
- | `/status` | Show index status |
566
- | `/mcp-setup` | Configure MCP server for AI tools |
567
- | `/clean` | Remove VibeRAG from project |
568
- | `/help` | Show all commands |
554
+ If indexing appears slow or retries are happening, check the latest file under
555
+ `~/.local/share/viberag/projects/<projectId>/logs/indexer/`.
569
556
 
570
557
  ## Embedding Providers
571
558
 
@@ -593,7 +580,7 @@ Choose your embedding provider during `/init`:
593
580
  - **Mistral** - Code-optimized embeddings for technical content
594
581
  - **OpenAI** - Fast and reliable with low cost
595
582
 
596
- API keys are entered during the `/init` wizard and stored securely in `.viberag/config.json` (automatically added to `.gitignore`).
583
+ API keys are entered during the `/init` wizard and stored globally in `~/.local/share/viberag/secrets/secrets.json` (override via `VIBERAG_HOME`). Project configs store only a key id reference (never the raw API key).
597
584
 
598
585
  ## How It Works
599
586
 
@@ -633,7 +620,7 @@ Add to your `CLAUDE.md`:
633
620
 
634
621
  ```markdown
635
622
  When exploring the codebase, use Task(subagent_type='Explore') and instruct it
636
- to use codebase_search or codebase_parallel_search. This keeps the main context clean.
623
+ to use the viberag `codebase_search` tool (and follow-ups like `get_symbol_details` / `read_file_lines`). This keeps the main context clean.
637
624
  ```
638
625
 
639
626
  #### VS Code Copilot
@@ -686,46 +673,53 @@ to use codebase_search or codebase_parallel_search. This keeps the main context
686
673
 
687
674
  ### Quick Lookup vs Exploration
688
675
 
689
- | Task Type | Recommended Approach |
690
- | ------------------------------- | ----------------------------------------------- |
691
- | "Where is function X defined?" | Direct `codebase_search` with mode='definition' |
692
- | "What file handles Y?" | Direct `codebase_search` - single query |
693
- | "How does authentication work?" | **Sub-agent** - needs multiple searches |
694
- | "Find all API endpoints" | **Sub-agent** or `codebase_parallel_search` |
695
- | "Understand the data flow" | **Sub-agent** - iterative exploration |
676
+ | Task Type | Recommended Approach |
677
+ | ------------------------------- | --------------------------------------------------------- |
678
+ | "Where is function X defined?" | `codebase_search` with `intent="definition"` |
679
+ | "What file handles Y?" | `codebase_search` with `intent="concept"` (check `files`) |
680
+ | "How does authentication work?" | **Sub-agent** - needs multi-step search + follow-ups |
681
+ | "Find all API endpoints" | **Sub-agent** - iterative search + scope filters |
682
+ | "Understand the data flow" | **Sub-agent** - iterative exploration |
696
683
 
697
684
  ### For Platforms Without Sub-Agents
698
685
 
699
- Use `codebase_parallel_search` to run multiple search strategies in a single call:
686
+ Use a few targeted `codebase_search` calls with different intents, then follow up with
687
+ `get_symbol_details`, `read_file_lines`, `get_surrounding_code`, and `find_references` as needed.
688
+
689
+ Example sequence:
690
+
691
+ ```json
692
+ {"query": "authentication", "intent": "concept", "k": 20}
693
+ ```
700
694
 
701
695
  ```json
702
696
  {
703
- "searches": [
704
- {"query": "authentication", "mode": "semantic"},
705
- {"query": "auth login", "mode": "exact"},
706
- {"query": "user session", "mode": "hybrid", "bm25_weight": 0.5}
707
- ],
708
- "merge_results": true,
709
- "merge_strategy": "rrf"
697
+ "query": "login",
698
+ "intent": "definition",
699
+ "k": 20,
700
+ "scope": {"path_prefix": ["src/"]}
710
701
  }
711
702
  ```
712
703
 
713
- This provides comprehensive coverage without multiple round-trips.
704
+ ```json
705
+ {"symbol_name": "login", "k": 200}
706
+ ```
714
707
 
715
708
  ## Troubleshooting
716
709
 
717
710
  ### Watcher EMFILE (too many open files)
718
711
 
719
- Large repos can exceed OS watch limits. The watcher now honors `.gitignore`, but if you still see EMFILE:
712
+ Large repos can exceed OS watch limits. The watcher honors `.gitignore` and `.viberagignore`, but if you still see EMFILE:
720
713
 
721
- - Add more ignores in `.gitignore` to reduce watched files.
714
+ - Add more ignores in `.gitignore` or `.viberagignore` to reduce watched files.
722
715
  - Increase OS limits:
723
716
  - macOS: raise `kern.maxfiles`, `kern.maxfilesperproc`, and `ulimit -n`
724
717
  - Linux: raise `fs.inotify.max_user_watches`, `fs.inotify.max_user_instances`, and `ulimit -n`
725
718
 
726
719
  ### Index failures (network/API errors)
727
720
 
728
- Embedding batches retry up to 10 attempts. If failures persist:
721
+ If indexing fails due to transient network/API issues:
729
722
 
730
- - Run `/status` to see failed batch counts.
731
- - Re-run `/index` to retry failed files once connectivity is stable.
723
+ - Run `/status` to confirm daemon/index state.
724
+ - Re-run `/index` after connectivity is stable.
725
+ - Use `/cancel` to stop a stuck run, then `/reindex` if you need a clean rebuild.
package/dist/cli/app.js CHANGED
@@ -5,7 +5,7 @@ import { Provider } from 'react-redux';
5
5
  import { store } from './store/store.js';
6
6
  import { useAppDispatch, useAppSelector } from './store/hooks.js';
7
7
  import { WizardActions } from './store/wizard/slice.js';
8
- import { selectActiveWizard, selectInitStep, selectMcpStep, selectInitConfig, selectMcpConfig, selectIsReinit, selectShowMcpPrompt, selectExistingApiKey, selectExistingProvider, } from './store/wizard/selectors.js';
8
+ import { selectActiveWizard, selectInitStep, selectMcpStep, selectInitConfig, selectMcpConfig, selectIsReinit, selectShowMcpPrompt, selectExistingApiKeyId, selectExistingProvider, } from './store/wizard/selectors.js';
9
9
  import { AppActions } from './store/app/slice.js';
10
10
  import { selectIsInitialized, selectIndexStats, selectAppStatus, selectOutputItems, selectStartupLoaded, } from './store/app/selectors.js';
11
11
  // Common infrastructure
@@ -26,6 +26,8 @@ import { DaemonStatusProvider } from './contexts/DaemonStatusContext.js';
26
26
  import { checkInitialized, loadIndexStats, runInit, runIndex, formatIndexStats, } from './commands/handlers.js';
27
27
  import { getViberagDir } from '../daemon/lib/constants.js';
28
28
  import { loadConfig } from '../daemon/lib/config.js';
29
+ import { checkNpmForUpdate } from '../daemon/lib/update-check.js';
30
+ import { checkV2IndexCompatibility } from '../daemon/services/v2/manifest.js';
29
31
  const require = createRequire(import.meta.url);
30
32
  // Path is relative from dist/ after compilation
31
33
  const { version } = require('../../package.json');
@@ -41,7 +43,8 @@ const COMMANDS = [
41
43
  { command: '/index', description: 'Index the codebase' },
42
44
  { command: '/reindex', description: 'Force full reindex' },
43
45
  { command: '/search', description: 'Search codebase semantically' },
44
- { command: '/status', description: 'Show index statistics' },
46
+ { command: '/status', description: 'Show daemon and index status' },
47
+ { command: '/cancel', description: 'Cancel indexing or warmup' },
45
48
  { command: '/mcp-setup', description: 'Configure MCP for AI tools' },
46
49
  { command: '/clean', description: 'Remove Viberag from project' },
47
50
  { command: '/quit', description: 'Exit the application' },
@@ -60,7 +63,7 @@ function AppContent() {
60
63
  const mcpConfig = useAppSelector(selectMcpConfig);
61
64
  const isReinit = useAppSelector(selectIsReinit);
62
65
  const showMcpPrompt = useAppSelector(selectShowMcpPrompt);
63
- const existingApiKey = useAppSelector(selectExistingApiKey);
66
+ const existingApiKeyId = useAppSelector(selectExistingApiKeyId);
64
67
  const existingProvider = useAppSelector(selectExistingProvider);
65
68
  // Redux app state (migrated from useState)
66
69
  const isInitialized = useAppSelector(selectIsInitialized);
@@ -81,29 +84,53 @@ function AppContent() {
81
84
  if (initialized) {
82
85
  const config = await loadConfig(projectRoot);
83
86
  dispatch(WizardActions.setExistingConfig({
84
- apiKey: config.apiKey,
87
+ apiKeyId: config.apiKeyRef?.keyId,
85
88
  provider: config.embeddingProvider,
86
89
  }));
87
90
  }
88
91
  });
89
92
  loadIndexStats(projectRoot).then(stats => dispatch(AppActions.setIndexStats(stats)));
90
93
  }, [projectRoot, dispatch]);
91
- // Command history
92
- const { addToHistory, navigateUp, navigateDown, resetIndex } = useCommandHistory();
93
94
  const addOutput = useCallback((type, content) => {
94
95
  dispatch(AppActions.addOutput({ type, content }));
95
96
  }, [dispatch]);
96
97
  const addSearchResults = useCallback((data) => {
97
98
  dispatch(AppActions.addSearchResults(data));
98
99
  }, [dispatch]);
100
+ // Startup checks: updates + index compatibility (best-effort, non-blocking)
101
+ useEffect(() => {
102
+ const disabled = process.env['VIBERAG_SKIP_UPDATE_CHECK'] === '1' ||
103
+ process.env['VIBERAG_SKIP_UPDATE_CHECK'] === 'true' ||
104
+ process.env['NODE_ENV'] === 'test';
105
+ if (!disabled) {
106
+ checkNpmForUpdate({ timeoutMs: 3000 })
107
+ .then(result => {
108
+ if (result.status === 'update_available' && result.message) {
109
+ addOutput('system', result.message);
110
+ }
111
+ })
112
+ .catch(() => { });
113
+ }
114
+ checkV2IndexCompatibility(projectRoot)
115
+ .then(result => {
116
+ if ((result.status === 'needs_reindex' ||
117
+ result.status === 'corrupt_manifest') &&
118
+ result.message) {
119
+ addOutput('system', result.message);
120
+ }
121
+ })
122
+ .catch(() => { });
123
+ }, [projectRoot, addOutput]);
124
+ // Command history
125
+ const { addToHistory, navigateUp, navigateDown, resetIndex } = useCommandHistory();
99
126
  // Start the init wizard
100
127
  const startInitWizard = useCallback((isReinit) => {
101
128
  dispatch(WizardActions.startInit({
102
129
  isReinit,
103
- existingApiKey: existingApiKey ?? undefined,
130
+ existingApiKeyId: existingApiKeyId ?? undefined,
104
131
  existingProvider: existingProvider ?? undefined,
105
132
  }));
106
- }, [dispatch, existingApiKey, existingProvider]);
133
+ }, [dispatch, existingApiKeyId, existingProvider]);
107
134
  // Start the MCP setup wizard
108
135
  const startMcpSetupWizard = useCallback((showPrompt = false) => {
109
136
  dispatch(WizardActions.startMcpSetup({ showPrompt }));
@@ -133,9 +160,9 @@ function AppContent() {
133
160
  // Wait for next tick so wizard unmounts before we add output
134
161
  await new Promise(resolve => setTimeout(resolve, 50));
135
162
  addOutput('system', 'Initializing Viberag...');
136
- dispatch(AppActions.setWarning('Initializing...'));
163
+ dispatch(AppActions.setWorking('Initializing...'));
137
164
  try {
138
- const result = await runInit(projectRoot, isInitialized ?? false, config);
165
+ const result = await runInit(projectRoot, isInitialized ?? false, config, message => dispatch(AppActions.setWorking(message)));
139
166
  addOutput('system', result);
140
167
  dispatch(AppActions.setInitialized(true));
141
168
  // Automatically start indexing after init
@@ -230,7 +257,7 @@ function AppContent() {
230
257
  item.content)) : (React.createElement(Text, null, item.content))));
231
258
  }),
232
259
  React.createElement(StatusBar, { status: appStatus, stats: indexStats }),
233
- activeWizard === 'init' ? (React.createElement(InitWizard, { step: initStep, config: initConfig, isReinit: isReinit, existingApiKey: existingApiKey ?? undefined, existingProvider: existingProvider ?? undefined, onStepChange: handleInitWizardStep, onComplete: handleInitWizardComplete, onCancel: handleWizardCancel })) : activeWizard === 'mcp-setup' ? (React.createElement(McpSetupWizard, { step: mcpStep, config: mcpConfig, projectRoot: projectRoot, showPrompt: showMcpPrompt, onStepChange: handleMcpWizardStep, onComplete: handleMcpWizardComplete, onCancel: handleWizardCancel, addOutput: addOutput })) : activeWizard === 'clean' ? (React.createElement(CleanWizard, { projectRoot: projectRoot, viberagDir: getViberagDir(projectRoot), onComplete: handleCleanWizardComplete, onCancel: handleWizardCancel, addOutput: addOutput })) : (React.createElement(TextInput, { onSubmit: handleSubmit, onCtrlC: handleCtrlC, commands: COMMANDS, navigateHistoryUp: navigateUp, navigateHistoryDown: navigateDown, resetHistoryIndex: resetIndex }))));
260
+ activeWizard === 'init' ? (React.createElement(InitWizard, { step: initStep, config: initConfig, isReinit: isReinit, existingApiKeyId: existingApiKeyId ?? undefined, existingProvider: existingProvider ?? undefined, onStepChange: handleInitWizardStep, onComplete: handleInitWizardComplete, onCancel: handleWizardCancel })) : activeWizard === 'mcp-setup' ? (React.createElement(McpSetupWizard, { step: mcpStep, config: mcpConfig, projectRoot: projectRoot, showPrompt: showMcpPrompt, onStepChange: handleMcpWizardStep, onComplete: handleMcpWizardComplete, onCancel: handleWizardCancel, addOutput: addOutput })) : activeWizard === 'clean' ? (React.createElement(CleanWizard, { projectRoot: projectRoot, viberagDir: getViberagDir(projectRoot), onComplete: handleCleanWizardComplete, onCancel: handleWizardCancel, addOutput: addOutput })) : (React.createElement(TextInput, { onSubmit: handleSubmit, onCtrlC: handleCtrlC, commands: COMMANDS, navigateHistoryUp: navigateUp, navigateHistoryDown: navigateDown, resetHistoryIndex: resetIndex }))));
234
261
  }
235
262
  /**
236
263
  * Main App component with Redux Provider and DaemonStatusProvider.
@@ -1,15 +1,8 @@
1
1
  /**
2
2
  * RAG commands for the CLI.
3
3
  */
4
- import type { IndexStats, SearchResults } from '../../client/types.js';
5
- import type { InitWizardConfig } from '../../common/types.js';
6
- /**
7
- * Index display stats type (re-exported for convenience).
8
- */
9
- export type IndexDisplayStats = {
10
- totalFiles: number;
11
- totalChunks: number;
12
- };
4
+ import type { IndexStats, EvalReport } from '../../client/types.js';
5
+ import type { InitWizardConfig, IndexDisplayStats, SearchResultsData } from '../../common/types.js';
13
6
  /**
14
7
  * Check if project is initialized.
15
8
  */
@@ -20,10 +13,11 @@ export declare function checkInitialized(projectRoot: string): Promise<boolean>;
20
13
  export declare function loadIndexStats(projectRoot: string): Promise<IndexDisplayStats | null>;
21
14
  /**
22
15
  * Initialize a project for Viberag.
23
- * Creates .viberag/ directory with config.json.
16
+ * Creates a global per-project data directory with config.json.
24
17
  * With isReinit=true, shuts down daemon and deletes everything first.
18
+ * Optionally reports progress for UI status updates.
25
19
  */
26
- export declare function runInit(projectRoot: string, isReinit?: boolean, wizardConfig?: InitWizardConfig): Promise<string>;
20
+ export declare function runInit(projectRoot: string, isReinit?: boolean, wizardConfig?: InitWizardConfig, onProgress?: (message: string) => void): Promise<string>;
27
21
  /**
28
22
  * Run the indexer and return stats.
29
23
  * Delegates to daemon which handles dimension sync internally.
@@ -39,18 +33,27 @@ export declare function formatIndexStats(stats: IndexStats): string;
39
33
  * Run a search query and return results.
40
34
  * Delegates to daemon for search.
41
35
  */
42
- export declare function runSearch(projectRoot: string, query: string, limit?: number): Promise<SearchResults>;
36
+ export declare function runSearch(projectRoot: string, query: string, k?: number): Promise<SearchResultsData>;
37
+ /**
38
+ * Run the v2 eval harness via daemon.
39
+ */
40
+ export declare function runEval(projectRoot: string): Promise<EvalReport>;
41
+ export declare function formatEvalReport(report: EvalReport): string;
43
42
  /**
44
43
  * Format search results for display with colors.
45
44
  */
46
- export declare function formatSearchResults(results: SearchResults): string;
45
+ export declare function formatSearchResults(data: SearchResultsData): string;
47
46
  /**
48
47
  * Get index status.
49
48
  */
50
49
  export declare function getStatus(projectRoot: string): Promise<string>;
50
+ /**
51
+ * Cancel indexing or warmup.
52
+ */
53
+ export declare function cancelActivity(projectRoot: string, target?: string): Promise<string>;
51
54
  /**
52
55
  * Clean/uninstall Viberag from a project.
53
- * Shuts down daemon first, then removes the entire .viberag/ directory.
56
+ * Shuts down daemon first, then removes the entire project data directory.
54
57
  */
55
58
  export declare function runClean(projectRoot: string): Promise<string>;
56
59
  /**