claude-eidetic 0.1.5 → 2026.306.1433

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 (79) hide show
  1. package/README.md +87 -29
  2. package/dist/build-info.d.ts +3 -0
  3. package/dist/build-info.js +4 -0
  4. package/dist/config.d.ts +25 -5
  5. package/dist/config.js +15 -5
  6. package/dist/core/global-concepts.d.ts +8 -0
  7. package/dist/core/global-concepts.js +38 -0
  8. package/dist/core/indexer.js +13 -1
  9. package/dist/core/raptor-cache.d.ts +6 -0
  10. package/dist/core/raptor-cache.js +45 -0
  11. package/dist/core/raptor.d.ts +31 -0
  12. package/dist/core/raptor.js +209 -0
  13. package/dist/core/snapshot-io.d.ts +4 -0
  14. package/dist/core/snapshot-io.js +81 -23
  15. package/dist/core/sync.js +3 -4
  16. package/dist/embedding/openai.js +7 -3
  17. package/dist/errors.d.ts +2 -0
  18. package/dist/errors.js +2 -0
  19. package/dist/format.js +10 -10
  20. package/dist/hooks/hook-output.d.ts +56 -0
  21. package/dist/hooks/hook-output.js +21 -0
  22. package/dist/hooks/post-tool-extract.js +47 -39
  23. package/dist/hooks/post-tool-use.js +8 -2
  24. package/dist/hooks/stop-hook.js +15 -2
  25. package/dist/hooks/targeted-runner.js +17 -11
  26. package/dist/hooks/user-prompt-inject.d.ts +9 -0
  27. package/dist/hooks/user-prompt-inject.js +113 -0
  28. package/dist/index.js +36 -19
  29. package/dist/infra/chroma-bootstrap.d.ts +7 -0
  30. package/dist/infra/chroma-bootstrap.js +71 -0
  31. package/dist/infra/qdrant-bootstrap.d.ts +5 -1
  32. package/dist/infra/qdrant-bootstrap.js +4 -2
  33. package/dist/memory/buffer-consolidator.d.ts +7 -0
  34. package/dist/memory/buffer-consolidator.js +142 -0
  35. package/dist/memory/buffer-runner.d.ts +14 -0
  36. package/dist/memory/buffer-runner.js +83 -0
  37. package/dist/memory/buffer.d.ts +22 -0
  38. package/dist/memory/buffer.js +92 -0
  39. package/dist/memory/graph.d.ts +37 -0
  40. package/dist/memory/graph.js +270 -0
  41. package/dist/memory/migration.d.ts +10 -0
  42. package/dist/memory/migration.js +76 -0
  43. package/dist/memory/query-classifier.d.ts +8 -0
  44. package/dist/memory/query-classifier.js +52 -0
  45. package/dist/memory/reconciler.d.ts +2 -1
  46. package/dist/memory/reconciler.js +7 -2
  47. package/dist/memory/store.d.ts +15 -5
  48. package/dist/memory/store.js +299 -105
  49. package/dist/memory/types.d.ts +94 -4
  50. package/dist/paths.d.ts +5 -0
  51. package/dist/paths.js +15 -0
  52. package/dist/precompact/hook.js +77 -7
  53. package/dist/precompact/index-runner.js +2 -12
  54. package/dist/precompact/memory-extractor.d.ts +17 -0
  55. package/dist/precompact/memory-extractor.js +86 -0
  56. package/dist/precompact/memory-inject.js +7 -6
  57. package/dist/setup-message.d.ts +1 -0
  58. package/dist/setup-message.js +35 -5
  59. package/dist/state/registry.d.ts +1 -0
  60. package/dist/state/registry.js +13 -0
  61. package/dist/state/snapshot.d.ts +1 -0
  62. package/dist/state/snapshot.js +27 -12
  63. package/dist/tool-schemas.d.ts +37 -12
  64. package/dist/tool-schemas.js +39 -37
  65. package/dist/tools.d.ts +8 -0
  66. package/dist/tools.js +76 -6
  67. package/dist/vectordb/chroma.d.ts +25 -0
  68. package/dist/vectordb/chroma.js +249 -0
  69. package/dist/vectordb/factory.d.ts +8 -0
  70. package/dist/vectordb/factory.js +43 -0
  71. package/dist/vectordb/milvus.d.ts +6 -0
  72. package/dist/vectordb/milvus.js +38 -0
  73. package/dist/vectordb/qdrant.d.ts +8 -31
  74. package/dist/vectordb/qdrant.js +46 -84
  75. package/dist/vectordb/rrf.d.ts +32 -0
  76. package/dist/vectordb/rrf.js +88 -0
  77. package/dist/vectordb/types.d.ts +6 -0
  78. package/messages.yaml +33 -13
  79. package/package.json +5 -3
package/README.md CHANGED
@@ -1,5 +1,10 @@
1
- # claude-eidetic
2
-
1
+ ```
2
+ ┌─────────────────────────────────────────────┐
3
+ │ ╔═╗╦╔╦╗╔═╗╔╦╗╦╔═╗ │
4
+ │ ║╣ ║ ║║║╣ ║ ║║ semantic code search │
5
+ │ ╚═╝╩═╩╝╚═╝ ╩ ╩╚═╝ for Claude Code │
6
+ └─────────────────────────────────────────────┘
7
+ ```
3
8
 
4
9
  [![tests](https://img.shields.io/github/actions/workflow/status/eidetics/claude-eidetic/ci.yml?style=flat-square&label=tests)](https://github.com/eidetics/claude-eidetic/actions/workflows/ci.yml)
5
10
  [![npm](https://img.shields.io/npm/v/claude-eidetic)](https://www.npmjs.com/package/claude-eidetic)
@@ -9,10 +14,11 @@ Semantic code search, persistent memory, and session continuity for Claude Code.
9
14
 
10
15
  ---
11
16
 
12
- ## 🚀 Quick Start
17
+ ## Quick Start
13
18
 
14
19
  ```bash
15
- claude plugin install eidetics/claude-eidetic
20
+ claude plugin marketplace add eidetics/claude-eidetic
21
+ claude plugin install claude-eidetic
16
22
  ```
17
23
 
18
24
  ```bash
@@ -28,9 +34,9 @@ search_code("how does authentication work")
28
34
 
29
35
  ---
30
36
 
31
- ## Features
37
+ ## Features
32
38
 
33
- ### 🔍 Semantic Code Search
39
+ ### Semantic Code Search
34
40
 
35
41
  **Find code by meaning, not keywords.** Search across your entire codebase with natural language, returning the most relevant functions and classes, not a list of files to read.
36
42
 
@@ -40,7 +46,7 @@ search_code("authentication middleware", extensionFilter=[".ts"])
40
46
  search_code(project="backend", query="auth flow")
41
47
  ```
42
48
 
43
- ### 🏗️ Architecture at a Glance
49
+ ### Architecture at a Glance
44
50
 
45
51
  **Get every class, function, and method in one call.** `browse_structure` returns a condensed map of your codebase with signatures, grouped by file, replacing a Glob + Read cascade with a single tool call.
46
52
 
@@ -49,7 +55,7 @@ browse_structure(path="/my/project", kind="class")
49
55
  list_symbols(path="/my/project", nameFilter="handle")
50
56
  ```
51
57
 
52
- ### 📚 Documentation Cache
58
+ ### Documentation Cache
53
59
 
54
60
  **Fetch docs once, search them forever.** Cache external documentation as searchable embeddings. Retrieve relevant passages instantly, far cheaper than re-fetching the same page each session.
55
61
 
@@ -58,7 +64,7 @@ index_document(content=..., library="react", topic="hooks", source="https://..."
58
64
  search_documents("React useCallback dependencies", library="react")
59
65
  ```
60
66
 
61
- ### 🧠 Persistent Memory
67
+ ### Persistent Memory
62
68
 
63
69
  **Claude remembers your preferences between sessions.** `add_memory` uses an LLM to extract structured facts from conversation text (coding style, architecture decisions, debugging insights) and deduplicates them semantically. Not a static config file you forget to update.
64
70
 
@@ -67,11 +73,11 @@ add_memory("Always use absolute imports, never relative")
67
73
  search_memory("how does this team handle errors")
68
74
  ```
69
75
 
70
- ### 🔄 Session Continuity
76
+ ### Session Continuity
71
77
 
72
78
  **Every session picks up where the last one left off.** When a session ends (or context compacts mid-session), Eidetic automatically writes a structured note capturing files changed, tasks, commands, and decisions. `/catchup` at the start of a new session reconstructs exactly where you were. No user action required.
73
79
 
74
- ### 👻 Invisible Optimizations
80
+ ### Invisible Optimizations
75
81
 
76
82
  Eight hook events fire automatically, nudging toward cheaper tools, redirecting file reads for 15-20% token savings, tracking changed files, and saving session state on exit.
77
83
 
@@ -93,7 +99,7 @@ Eight hook events fire automatically, nudging toward cheaper tools, redirecting
93
99
 
94
100
  ---
95
101
 
96
- ## 🗺️ When to Use What
102
+ ## When to Use What
97
103
 
98
104
  | Need | Use | Notes |
99
105
  |---|---|---|
@@ -107,7 +113,7 @@ Eight hook events fire automatically, nudging toward cheaper tools, redirecting
107
113
 
108
114
  ---
109
115
 
110
- ## 📖 Skills Reference
116
+ ## Skills Reference
111
117
 
112
118
  | Skill | What it does |
113
119
  |---|---|
@@ -120,7 +126,7 @@ Eight hook events fire automatically, nudging toward cheaper tools, redirecting
120
126
  ---
121
127
 
122
128
  <details>
123
- <summary><strong>🔥 Why does this exist? (The Problem)</strong></summary>
129
+ <summary><strong>Why does this exist? (The Problem)</strong></summary>
124
130
 
125
131
  Every new Claude Code session starts cold. You re-explain the architecture. You re-fetch the same docs. Claude reads the same files repeatedly, burning tokens just to get back to where you were.
126
132
 
@@ -135,16 +141,20 @@ Every new Claude Code session starts cold. You re-explain the architecture. You
135
141
 
136
142
  ---
137
143
 
138
- ## 📦 Installation
144
+ ## Installation
139
145
 
140
146
  ### Plugin (recommended)
141
147
 
142
148
  ```bash
143
- claude plugin install eidetics/claude-eidetic
149
+ claude plugin marketplace add eidetics/claude-eidetic
150
+ claude plugin install claude-eidetic
144
151
  ```
145
152
 
146
153
  The plugin auto-starts the MCP server, installs skills, and configures hooks.
147
154
 
155
+ <details>
156
+ <summary><strong>Alternative installation methods</strong></summary>
157
+
148
158
  ### npx (manual MCP config)
149
159
 
150
160
  Add to your `.mcp.json`:
@@ -177,16 +187,18 @@ cd claude-eidetic
177
187
  npm install && npx tsc && npm start
178
188
  ```
179
189
 
190
+ </details>
191
+
180
192
  ### Requirements
181
193
 
182
194
  - Node.js >= 20.0.0
183
195
  - An API key (OpenAI for embeddings, or Ollama for free local embeddings)
184
- - Docker (optional): Qdrant auto-provisions via Docker if not already running
196
+ - Docker (optional): only needed if using Qdrant provider (`VECTORDB_PROVIDER=qdrant`)
185
197
  - C/C++ build tools: required by tree-sitter native bindings (`node-gyp`)
186
198
 
187
199
  ---
188
200
 
189
- ## ⚙️ Configuration
201
+ ## Configuration
190
202
 
191
203
  All configuration is via environment variables. No config files.
192
204
 
@@ -210,8 +222,9 @@ export MEMORY_LLM_PROVIDER=ollama
210
222
  | `INDEXING_CONCURRENCY` | `8` | Parallel file indexing workers (1-32) |
211
223
  | `OPENAI_BASE_URL` | _(none)_ | Custom OpenAI-compatible endpoint |
212
224
  | `OLLAMA_BASE_URL` | `http://localhost:11434/v1` | Ollama server URL |
213
- | `VECTORDB_PROVIDER` | `qdrant` | `qdrant` or `milvus` |
214
- | `QDRANT_URL` | `http://localhost:6333` | Qdrant server URL |
225
+ | `VECTORDB_PROVIDER` | `chroma` | `chroma`, `qdrant`, or `milvus` |
226
+ | `CHROMA_DATA_DIR` | `~/.eidetic/chroma/` | ChromaDB persistent data directory |
227
+ | `QDRANT_URL` | `http://localhost:6333` | Qdrant server URL (when using qdrant provider) |
215
228
  | `QDRANT_API_KEY` | _(none)_ | Qdrant API key (for remote/cloud instances) |
216
229
  | `MILVUS_ADDRESS` | `localhost:19530` | Milvus server address |
217
230
  | `MILVUS_TOKEN` | _(none)_ | Milvus authentication token |
@@ -223,10 +236,55 @@ export MEMORY_LLM_PROVIDER=ollama
223
236
 
224
237
  ---
225
238
 
239
+ ## Troubleshooting
240
+
241
+ ### `OPENAI_API_KEY` not set
242
+
243
+ Eidetic needs an embedding API key. Set it in your shell profile:
244
+
245
+ ```bash
246
+ export OPENAI_API_KEY=sk-... # macOS/Linux
247
+ setx OPENAI_API_KEY sk-... # Windows
248
+ ```
249
+
250
+ Or use Ollama for free local embeddings: `export EMBEDDING_PROVIDER=ollama`
251
+
252
+ ### Using Qdrant instead of Chroma
253
+
254
+ ChromaDB is the default (no Docker needed). To use Qdrant:
255
+
256
+ ```bash
257
+ export VECTORDB_PROVIDER=qdrant
258
+ ```
259
+
260
+ Qdrant auto-provisions via Docker. If Docker isn't installed:
261
+ - **Option A:** Install [Docker Desktop](https://www.docker.com/products/docker-desktop/) and retry
262
+ - **Option B:** Run Qdrant manually and set `QDRANT_URL` to point to it
263
+
264
+ ### Tree-sitter native build fails on Windows
265
+
266
+ Tree-sitter requires C/C++ build tools. Install them:
267
+
268
+ ```bash
269
+ npm install -g windows-build-tools # or install Visual Studio Build Tools
270
+ ```
271
+
272
+ If the build still fails, Eidetic falls back to line-based chunking (works, but less precise).
273
+
274
+ ### Ollama model not pulled
275
+
276
+ If using `EMBEDDING_PROVIDER=ollama`, ensure the model is available:
277
+
278
+ ```bash
279
+ ollama pull nomic-embed-text
280
+ ```
281
+
282
+ ---
283
+
226
284
  <details>
227
- <summary><strong>🔧 Tool Reference</strong></summary>
285
+ <summary><strong>Tool Reference</strong></summary>
228
286
 
229
- ### 🔍 Code Search
287
+ ### Code Search
230
288
 
231
289
  | Tool | Description |
232
290
  |---|---|
@@ -239,20 +297,20 @@ export MEMORY_LLM_PROVIDER=ollama
239
297
  | `browse_structure` | Condensed structural map: classes, functions, methods with signatures, grouped by file. |
240
298
  | `list_symbols` | Compact symbol table with name/kind/file/line. Supports name, kind, and path filters. |
241
299
 
242
- ### 📄 File Reading
300
+ ### File Reading
243
301
 
244
302
  | Tool | Description |
245
303
  |---|---|
246
304
  | `read_file` | Read file without line-number overhead. Cheaper than built-in Read for code files. |
247
305
 
248
- ### 📚 Documentation Cache
306
+ ### Documentation Cache
249
307
 
250
308
  | Tool | Description |
251
309
  |---|---|
252
310
  | `index_document` | Cache external documentation for semantic search. Supports TTL for staleness tracking. |
253
311
  | `search_documents` | Search cached docs. Far cheaper than re-fetching the same page. |
254
312
 
255
- ### 🧠 Memory
313
+ ### Memory
256
314
 
257
315
  | Tool | Description |
258
316
  |---|---|
@@ -266,7 +324,7 @@ export MEMORY_LLM_PROVIDER=ollama
266
324
 
267
325
  ---
268
326
 
269
- ## 🌐 Supported Languages
327
+ ## Supported Languages
270
328
 
271
329
  **AST-aware** (functions and classes chunked intact):
272
330
 
@@ -298,7 +356,7 @@ export MEMORY_LLM_PROVIDER=ollama
298
356
 
299
357
  ---
300
358
 
301
- ## 🛠️ Development
359
+ ## Development
302
360
 
303
361
  ```bash
304
362
  npm install && npx tsc # install and build
@@ -313,12 +371,12 @@ Scopes: `embedding`, `vectordb`, `splitter`, `indexer`, `mcp`, `infra`, `config`
313
371
 
314
372
  ---
315
373
 
316
- ## 🙏 Acknowledgements
374
+ ## Acknowledgements
317
375
 
318
376
  Heavily inspired by [mem0](https://github.com/mem0ai/mem0), [claude-mem](https://github.com/thedotmack/claude-mem), and [claude-context](https://github.com/zilliztech/claude-context). Documentation retrieval powered by [context7](https://github.com/upstash/context7).
319
377
 
320
378
  ---
321
379
 
322
- ## 📄 License
380
+ ## License
323
381
 
324
382
  MIT
@@ -0,0 +1,3 @@
1
+ export declare const BUILD_VERSION: "2026.306.1433";
2
+ export declare const BUILD_TIMESTAMP: "2026-03-06T14:33:25.851Z";
3
+ //# sourceMappingURL=build-info.d.ts.map
@@ -0,0 +1,4 @@
1
+ // Auto-generated by scripts/generate-build-info.ts — do not edit
2
+ export const BUILD_VERSION = '2026.306.1433';
3
+ export const BUILD_TIMESTAMP = '2026-03-06T14:33:25.851Z';
4
+ //# sourceMappingURL=build-info.js.map
package/dist/config.d.ts CHANGED
@@ -9,12 +9,16 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
9
9
  indexingConcurrency: z.ZodDefault<z.ZodNumber>;
10
10
  qdrantUrl: z.ZodDefault<z.ZodString>;
11
11
  qdrantApiKey: z.ZodOptional<z.ZodString>;
12
- vectordbProvider: z.ZodDefault<z.ZodEnum<["qdrant", "milvus"]>>;
12
+ vectordbProvider: z.ZodDefault<z.ZodEnum<["chroma", "qdrant", "milvus"]>>;
13
+ chromaDataDir: z.ZodOptional<z.ZodString>;
13
14
  milvusAddress: z.ZodDefault<z.ZodString>;
14
15
  milvusToken: z.ZodOptional<z.ZodString>;
15
16
  eideticDataDir: z.ZodDefault<z.ZodString>;
16
17
  customExtensions: z.ZodEffects<z.ZodDefault<z.ZodArray<z.ZodString, "many">>, string[], unknown>;
17
18
  customIgnorePatterns: z.ZodEffects<z.ZodDefault<z.ZodArray<z.ZodString, "many">>, string[], unknown>;
19
+ raptorEnabled: z.ZodEffects<z.ZodDefault<z.ZodBoolean>, boolean, unknown>;
20
+ raptorTimeoutMs: z.ZodDefault<z.ZodNumber>;
21
+ raptorLlmModel: z.ZodDefault<z.ZodString>;
18
22
  }, "strip", z.ZodTypeAny, {
19
23
  embeddingProvider: "openai" | "ollama" | "local";
20
24
  openaiApiKey: string;
@@ -22,14 +26,18 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
22
26
  embeddingBatchSize: number;
23
27
  indexingConcurrency: number;
24
28
  qdrantUrl: string;
25
- vectordbProvider: "qdrant" | "milvus";
29
+ vectordbProvider: "chroma" | "qdrant" | "milvus";
26
30
  milvusAddress: string;
27
31
  eideticDataDir: string;
28
32
  customExtensions: string[];
29
33
  customIgnorePatterns: string[];
34
+ raptorEnabled: boolean;
35
+ raptorTimeoutMs: number;
36
+ raptorLlmModel: string;
30
37
  openaiBaseUrl?: string | undefined;
31
38
  embeddingModel?: string | undefined;
32
39
  qdrantApiKey?: string | undefined;
40
+ chromaDataDir?: string | undefined;
33
41
  milvusToken?: string | undefined;
34
42
  }, {
35
43
  embeddingProvider?: "openai" | "ollama" | "local" | undefined;
@@ -41,25 +49,33 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
41
49
  indexingConcurrency?: number | undefined;
42
50
  qdrantUrl?: string | undefined;
43
51
  qdrantApiKey?: string | undefined;
44
- vectordbProvider?: "qdrant" | "milvus" | undefined;
52
+ vectordbProvider?: "chroma" | "qdrant" | "milvus" | undefined;
53
+ chromaDataDir?: string | undefined;
45
54
  milvusAddress?: string | undefined;
46
55
  milvusToken?: string | undefined;
47
56
  eideticDataDir?: string | undefined;
48
57
  customExtensions?: unknown;
49
58
  customIgnorePatterns?: unknown;
59
+ raptorEnabled?: unknown;
60
+ raptorTimeoutMs?: number | undefined;
61
+ raptorLlmModel?: string | undefined;
50
62
  }>, {
51
63
  embeddingModel: string;
64
+ chromaDataDir: string;
52
65
  embeddingProvider: "openai" | "ollama" | "local";
53
66
  openaiApiKey: string;
54
67
  ollamaBaseUrl: string;
55
68
  embeddingBatchSize: number;
56
69
  indexingConcurrency: number;
57
70
  qdrantUrl: string;
58
- vectordbProvider: "qdrant" | "milvus";
71
+ vectordbProvider: "chroma" | "qdrant" | "milvus";
59
72
  milvusAddress: string;
60
73
  eideticDataDir: string;
61
74
  customExtensions: string[];
62
75
  customIgnorePatterns: string[];
76
+ raptorEnabled: boolean;
77
+ raptorTimeoutMs: number;
78
+ raptorLlmModel: string;
63
79
  openaiBaseUrl?: string | undefined;
64
80
  qdrantApiKey?: string | undefined;
65
81
  milvusToken?: string | undefined;
@@ -73,12 +89,16 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
73
89
  indexingConcurrency?: number | undefined;
74
90
  qdrantUrl?: string | undefined;
75
91
  qdrantApiKey?: string | undefined;
76
- vectordbProvider?: "qdrant" | "milvus" | undefined;
92
+ vectordbProvider?: "chroma" | "qdrant" | "milvus" | undefined;
93
+ chromaDataDir?: string | undefined;
77
94
  milvusAddress?: string | undefined;
78
95
  milvusToken?: string | undefined;
79
96
  eideticDataDir?: string | undefined;
80
97
  customExtensions?: unknown;
81
98
  customIgnorePatterns?: unknown;
99
+ raptorEnabled?: unknown;
100
+ raptorTimeoutMs?: number | undefined;
101
+ raptorLlmModel?: string | undefined;
82
102
  }>;
83
103
  export type Config = z.infer<typeof configSchema>;
84
104
  export declare function loadConfig(): Config;
package/dist/config.js CHANGED
@@ -13,37 +13,47 @@ const configSchema = z
13
13
  indexingConcurrency: z.coerce.number().int().min(1).max(32).default(8),
14
14
  qdrantUrl: z.string().default('http://localhost:6333'),
15
15
  qdrantApiKey: z.string().optional(),
16
- vectordbProvider: z.enum(['qdrant', 'milvus']).default('qdrant'),
16
+ vectordbProvider: z.enum(['chroma', 'qdrant', 'milvus']).default('chroma'),
17
+ chromaDataDir: z.string().optional(),
17
18
  milvusAddress: z.string().default('localhost:19530'),
18
19
  milvusToken: z.string().optional(),
19
20
  eideticDataDir: z.string().default(path.join(os.homedir(), '.eidetic')),
20
21
  customExtensions: z.preprocess((val) => (typeof val === 'string' ? JSON.parse(val) : val), z.array(z.string()).default([])),
21
22
  customIgnorePatterns: z.preprocess((val) => (typeof val === 'string' ? JSON.parse(val) : val), z.array(z.string()).default([])),
23
+ raptorEnabled: z.preprocess((val) => (val === 'false' ? false : val === 'true' ? true : val), z.boolean().default(true)),
24
+ raptorTimeoutMs: z.coerce.number().int().min(1000).default(60000),
25
+ raptorLlmModel: z.string().default('gpt-4o-mini'),
22
26
  })
23
27
  .transform((cfg) => ({
24
28
  ...cfg,
25
29
  // Default embedding model depends on provider
26
30
  embeddingModel: cfg.embeddingModel ??
27
31
  (cfg.embeddingProvider === 'ollama' ? 'nomic-embed-text' : 'text-embedding-3-small'),
32
+ // Default Chroma data directory under eidetic data dir
33
+ chromaDataDir: cfg.chromaDataDir ?? path.join(cfg.eideticDataDir, 'chroma'),
28
34
  }));
29
35
  let cachedConfig = null;
30
36
  export function loadConfig() {
31
37
  const raw = {
32
38
  embeddingProvider: process.env.EMBEDDING_PROVIDER,
33
39
  openaiApiKey: (process.env.OPENAI_API_KEY ?? '').trim().replace(/^["']|["']$/g, ''),
34
- openaiBaseUrl: process.env.OPENAI_BASE_URL || undefined,
40
+ openaiBaseUrl: process.env.OPENAI_BASE_URL?.trim() ?? undefined,
35
41
  ollamaBaseUrl: process.env.OLLAMA_BASE_URL,
36
- embeddingModel: process.env.EMBEDDING_MODEL || undefined,
42
+ embeddingModel: process.env.EMBEDDING_MODEL?.trim() ?? undefined,
37
43
  embeddingBatchSize: process.env.EMBEDDING_BATCH_SIZE,
38
44
  indexingConcurrency: process.env.INDEXING_CONCURRENCY,
39
45
  qdrantUrl: process.env.QDRANT_URL,
40
- qdrantApiKey: process.env.QDRANT_API_KEY?.trim().replace(/^["']|["']$/g, '') || undefined,
46
+ qdrantApiKey: process.env.QDRANT_API_KEY?.trim().replace(/^["']|["']$/g, '') ?? undefined,
41
47
  vectordbProvider: process.env.VECTORDB_PROVIDER,
48
+ chromaDataDir: process.env.CHROMA_DATA_DIR?.trim() ?? undefined,
42
49
  milvusAddress: process.env.MILVUS_ADDRESS,
43
- milvusToken: process.env.MILVUS_TOKEN?.trim().replace(/^["']|["']$/g, '') || undefined,
50
+ milvusToken: process.env.MILVUS_TOKEN?.trim().replace(/^["']|["']$/g, '') ?? undefined,
44
51
  eideticDataDir: process.env.EIDETIC_DATA_DIR,
45
52
  customExtensions: process.env.CUSTOM_EXTENSIONS,
46
53
  customIgnorePatterns: process.env.CUSTOM_IGNORE_PATTERNS,
54
+ raptorEnabled: process.env.RAPTOR_ENABLED,
55
+ raptorTimeoutMs: process.env.RAPTOR_TIMEOUT_MS,
56
+ raptorLlmModel: process.env.RAPTOR_LLM_MODEL,
47
57
  };
48
58
  const result = configSchema.safeParse(raw);
49
59
  if (!result.success) {
@@ -0,0 +1,8 @@
1
+ import type { Embedding } from '../embedding/types.js';
2
+ import type { VectorDB } from '../vectordb/types.js';
3
+ /**
4
+ * Replicate knowledge summaries from a project's knowledge collection
5
+ * to the global concepts collection, tagged with the project name.
6
+ */
7
+ export declare function replicateToGlobalConcepts(project: string, knowledgeCollectionName: string, embedding: Embedding, vectordb: VectorDB): Promise<number>;
8
+ //# sourceMappingURL=global-concepts.d.ts.map
@@ -0,0 +1,38 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { globalConceptsCollectionName } from '../paths.js';
3
+ /**
4
+ * Replicate knowledge summaries from a project's knowledge collection
5
+ * to the global concepts collection, tagged with the project name.
6
+ */
7
+ export async function replicateToGlobalConcepts(project, knowledgeCollectionName, embedding, vectordb) {
8
+ const globalCol = globalConceptsCollectionName();
9
+ // Ensure global collection exists
10
+ if (!(await vectordb.hasCollection(globalCol))) {
11
+ await vectordb.createCollection(globalCol, embedding.dimension);
12
+ }
13
+ // Scroll all knowledge points
14
+ const points = await vectordb.scrollAll(knowledgeCollectionName);
15
+ if (points.length === 0)
16
+ return 0;
17
+ // Clean up stale entries for this project
18
+ await vectordb.deleteByFilter(globalCol, { project });
19
+ // Upsert knowledge points into global collection
20
+ let replicated = 0;
21
+ for (const point of points) {
22
+ const id = randomUUID();
23
+ await vectordb.updatePoint(globalCol, id, point.vector, {
24
+ ...point.payload,
25
+ content: typeof point.payload.content === 'string' ? point.payload.content : '',
26
+ relativePath: id,
27
+ startLine: 0,
28
+ endLine: 0,
29
+ fileExtension: 'knowledge',
30
+ language: 'summary',
31
+ project,
32
+ source: 'raptor',
33
+ });
34
+ replicated++;
35
+ }
36
+ return replicated;
37
+ }
38
+ //# sourceMappingURL=global-concepts.js.map
@@ -158,8 +158,20 @@ export async function indexCodebase(rootPath, embedding, vectordb, force = false
158
158
  await vectordb.insert(collectionName, documents);
159
159
  processedChunks += batch.length;
160
160
  }
161
- onProgress?.(98, 'Saving snapshot...');
161
+ onProgress?.(95, 'Saving snapshot...');
162
162
  saveSnapshot(normalizedPath, currentSnapshot);
163
+ // Run RAPTOR knowledge generation (non-fatal)
164
+ if (config.raptorEnabled) {
165
+ try {
166
+ onProgress?.(97, 'Generating knowledge summaries...');
167
+ const projectName = path.basename(normalizedPath);
168
+ const { runRaptor } = await import('./raptor.js');
169
+ await runRaptor(projectName, collectionName, embedding, vectordb);
170
+ }
171
+ catch (err) {
172
+ console.warn(`RAPTOR knowledge generation failed (non-fatal): ${String(err)}`);
173
+ }
174
+ }
163
175
  onProgress?.(100, 'Done');
164
176
  return {
165
177
  totalFiles: filePaths.length,
@@ -0,0 +1,6 @@
1
+ export declare function getCachedSummary(clusterHash: string): string | null;
2
+ export declare function setCachedSummary(clusterHash: string, summary: string, project: string, level?: number): void;
3
+ export declare function clearProjectCache(project: string): void;
4
+ /** Reset the module-level DB connection (for testing). */
5
+ export declare function _resetDb(): void;
6
+ //# sourceMappingURL=raptor-cache.d.ts.map
@@ -0,0 +1,45 @@
1
+ import Database from 'better-sqlite3';
2
+ import { mkdirSync } from 'node:fs';
3
+ import { dirname } from 'node:path';
4
+ import { getRaptorDbPath } from '../paths.js';
5
+ let db = null;
6
+ function getDb() {
7
+ if (db)
8
+ return db;
9
+ const dbPath = getRaptorDbPath();
10
+ mkdirSync(dirname(dbPath), { recursive: true });
11
+ db = new Database(dbPath);
12
+ db.pragma('journal_mode = WAL');
13
+ db.exec(`
14
+ CREATE TABLE IF NOT EXISTS raptor_clusters (
15
+ cluster_hash TEXT PRIMARY KEY,
16
+ summary TEXT NOT NULL,
17
+ project TEXT NOT NULL,
18
+ level INTEGER NOT NULL DEFAULT 0,
19
+ updated_at TEXT NOT NULL
20
+ )
21
+ `);
22
+ return db;
23
+ }
24
+ export function getCachedSummary(clusterHash) {
25
+ const row = getDb()
26
+ .prepare('SELECT summary FROM raptor_clusters WHERE cluster_hash = ?')
27
+ .get(clusterHash);
28
+ return row?.summary ?? null;
29
+ }
30
+ export function setCachedSummary(clusterHash, summary, project, level = 0) {
31
+ getDb()
32
+ .prepare('INSERT OR REPLACE INTO raptor_clusters (cluster_hash, summary, project, level, updated_at) VALUES (?, ?, ?, ?, ?)')
33
+ .run(clusterHash, summary, project, level, new Date().toISOString());
34
+ }
35
+ export function clearProjectCache(project) {
36
+ getDb().prepare('DELETE FROM raptor_clusters WHERE project = ?').run(project);
37
+ }
38
+ /** Reset the module-level DB connection (for testing). */
39
+ export function _resetDb() {
40
+ if (db) {
41
+ db.close();
42
+ db = null;
43
+ }
44
+ }
45
+ //# sourceMappingURL=raptor-cache.js.map
@@ -0,0 +1,31 @@
1
+ import type { Embedding } from '../embedding/types.js';
2
+ import type { VectorDB } from '../vectordb/types.js';
3
+ export interface RaptorResult {
4
+ clustersProcessed: number;
5
+ summariesGenerated: number;
6
+ cached: number;
7
+ timedOut: boolean;
8
+ }
9
+ interface Point {
10
+ id: string | number;
11
+ vector: number[];
12
+ content: string;
13
+ }
14
+ /**
15
+ * Run RAPTOR knowledge generation: cluster code chunks, summarize each cluster,
16
+ * store summaries in the knowledge collection.
17
+ */
18
+ export declare function runRaptor(project: string, codeCollectionName: string, embedding: Embedding, vectordb: VectorDB, options?: {
19
+ timeoutMs?: number;
20
+ llmModel?: string;
21
+ summarize?: LlmSummarizer;
22
+ }): Promise<RaptorResult>;
23
+ export type LlmSummarizer = (content: string, model: string, apiKey: string) => Promise<string>;
24
+ /**
25
+ * K-means clustering (Lloyd's algorithm).
26
+ * Returns an array of clusters, each containing the points assigned to it.
27
+ */
28
+ export declare function kMeans(points: Point[], k: number, maxIter?: number): Point[][];
29
+ export declare function clusterHash(memberIds: string[]): string;
30
+ export {};
31
+ //# sourceMappingURL=raptor.d.ts.map