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.
- package/README.md +87 -29
- package/dist/build-info.d.ts +3 -0
- package/dist/build-info.js +4 -0
- package/dist/config.d.ts +25 -5
- package/dist/config.js +15 -5
- package/dist/core/global-concepts.d.ts +8 -0
- package/dist/core/global-concepts.js +38 -0
- package/dist/core/indexer.js +13 -1
- package/dist/core/raptor-cache.d.ts +6 -0
- package/dist/core/raptor-cache.js +45 -0
- package/dist/core/raptor.d.ts +31 -0
- package/dist/core/raptor.js +209 -0
- package/dist/core/snapshot-io.d.ts +4 -0
- package/dist/core/snapshot-io.js +81 -23
- package/dist/core/sync.js +3 -4
- package/dist/embedding/openai.js +7 -3
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +2 -0
- package/dist/format.js +10 -10
- package/dist/hooks/hook-output.d.ts +56 -0
- package/dist/hooks/hook-output.js +21 -0
- package/dist/hooks/post-tool-extract.js +47 -39
- package/dist/hooks/post-tool-use.js +8 -2
- package/dist/hooks/stop-hook.js +15 -2
- package/dist/hooks/targeted-runner.js +17 -11
- package/dist/hooks/user-prompt-inject.d.ts +9 -0
- package/dist/hooks/user-prompt-inject.js +113 -0
- package/dist/index.js +36 -19
- package/dist/infra/chroma-bootstrap.d.ts +7 -0
- package/dist/infra/chroma-bootstrap.js +71 -0
- package/dist/infra/qdrant-bootstrap.d.ts +5 -1
- package/dist/infra/qdrant-bootstrap.js +4 -2
- package/dist/memory/buffer-consolidator.d.ts +7 -0
- package/dist/memory/buffer-consolidator.js +142 -0
- package/dist/memory/buffer-runner.d.ts +14 -0
- package/dist/memory/buffer-runner.js +83 -0
- package/dist/memory/buffer.d.ts +22 -0
- package/dist/memory/buffer.js +92 -0
- package/dist/memory/graph.d.ts +37 -0
- package/dist/memory/graph.js +270 -0
- package/dist/memory/migration.d.ts +10 -0
- package/dist/memory/migration.js +76 -0
- package/dist/memory/query-classifier.d.ts +8 -0
- package/dist/memory/query-classifier.js +52 -0
- package/dist/memory/reconciler.d.ts +2 -1
- package/dist/memory/reconciler.js +7 -2
- package/dist/memory/store.d.ts +15 -5
- package/dist/memory/store.js +299 -105
- package/dist/memory/types.d.ts +94 -4
- package/dist/paths.d.ts +5 -0
- package/dist/paths.js +15 -0
- package/dist/precompact/hook.js +77 -7
- package/dist/precompact/index-runner.js +2 -12
- package/dist/precompact/memory-extractor.d.ts +17 -0
- package/dist/precompact/memory-extractor.js +86 -0
- package/dist/precompact/memory-inject.js +7 -6
- package/dist/setup-message.d.ts +1 -0
- package/dist/setup-message.js +35 -5
- package/dist/state/registry.d.ts +1 -0
- package/dist/state/registry.js +13 -0
- package/dist/state/snapshot.d.ts +1 -0
- package/dist/state/snapshot.js +27 -12
- package/dist/tool-schemas.d.ts +37 -12
- package/dist/tool-schemas.js +39 -37
- package/dist/tools.d.ts +8 -0
- package/dist/tools.js +76 -6
- package/dist/vectordb/chroma.d.ts +25 -0
- package/dist/vectordb/chroma.js +249 -0
- package/dist/vectordb/factory.d.ts +8 -0
- package/dist/vectordb/factory.js +43 -0
- package/dist/vectordb/milvus.d.ts +6 -0
- package/dist/vectordb/milvus.js +38 -0
- package/dist/vectordb/qdrant.d.ts +8 -31
- package/dist/vectordb/qdrant.js +46 -84
- package/dist/vectordb/rrf.d.ts +32 -0
- package/dist/vectordb/rrf.js +88 -0
- package/dist/vectordb/types.d.ts +6 -0
- package/messages.yaml +33 -13
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
```
|
|
2
|
+
┌─────────────────────────────────────────────┐
|
|
3
|
+
│ ╔═╗╦╔╦╗╔═╗╔╦╗╦╔═╗ │
|
|
4
|
+
│ ║╣ ║ ║║║╣ ║ ║║ semantic code search │
|
|
5
|
+
│ ╚═╝╩═╩╝╚═╝ ╩ ╩╚═╝ for Claude Code │
|
|
6
|
+
└─────────────────────────────────────────────┘
|
|
7
|
+
```
|
|
3
8
|
|
|
4
9
|
[](https://github.com/eidetics/claude-eidetic/actions/workflows/ci.yml)
|
|
5
10
|
[](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
|
-
##
|
|
17
|
+
## Quick Start
|
|
13
18
|
|
|
14
19
|
```bash
|
|
15
|
-
claude plugin
|
|
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
|
-
##
|
|
37
|
+
## Features
|
|
32
38
|
|
|
33
|
-
###
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
|
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
|
-
##
|
|
144
|
+
## Installation
|
|
139
145
|
|
|
140
146
|
### Plugin (recommended)
|
|
141
147
|
|
|
142
148
|
```bash
|
|
143
|
-
claude plugin
|
|
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):
|
|
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
|
-
##
|
|
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` | `
|
|
214
|
-
| `
|
|
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
|
|
285
|
+
<summary><strong>Tool Reference</strong></summary>
|
|
228
286
|
|
|
229
|
-
###
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
380
|
+
## License
|
|
323
381
|
|
|
324
382
|
MIT
|
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('
|
|
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
|
|
40
|
+
openaiBaseUrl: process.env.OPENAI_BASE_URL?.trim() ?? undefined,
|
|
35
41
|
ollamaBaseUrl: process.env.OLLAMA_BASE_URL,
|
|
36
|
-
embeddingModel: process.env.EMBEDDING_MODEL
|
|
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, '')
|
|
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, '')
|
|
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
|
package/dist/core/indexer.js
CHANGED
|
@@ -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?.(
|
|
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
|