trellis 1.0.8 → 2.0.6

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 (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +564 -83
  3. package/bin/trellis.mjs +2 -0
  4. package/dist/cli/index.js +4718 -0
  5. package/dist/core/index.js +12 -0
  6. package/dist/decisions/index.js +19 -0
  7. package/dist/embeddings/index.js +43 -0
  8. package/dist/index-1j1anhmr.js +4038 -0
  9. package/dist/index-3s0eak0p.js +1556 -0
  10. package/dist/index-8pce39mh.js +272 -0
  11. package/dist/index-a76rekgs.js +67 -0
  12. package/dist/index-cy9k1g6v.js +684 -0
  13. package/dist/index-fd4e26s4.js +69 -0
  14. package/dist/{store/eav-store.js → index-gkvhzm9f.js} +4 -6
  15. package/dist/index-gnw8d7d6.js +51 -0
  16. package/dist/index-vkpkfwhq.js +817 -0
  17. package/dist/index.js +118 -2876
  18. package/dist/links/index.js +55 -0
  19. package/dist/transformers-m9je15kg.js +32491 -0
  20. package/dist/vcs/index.js +110 -0
  21. package/logo.png +0 -0
  22. package/logo.svg +9 -0
  23. package/package.json +79 -76
  24. package/src/cli/index.ts +2340 -0
  25. package/src/core/index.ts +35 -0
  26. package/src/core/kernel/middleware.ts +44 -0
  27. package/src/core/persist/backend.ts +64 -0
  28. package/src/core/store/eav-store.ts +467 -0
  29. package/src/decisions/auto-capture.ts +136 -0
  30. package/src/decisions/hooks.ts +163 -0
  31. package/src/decisions/index.ts +261 -0
  32. package/src/decisions/types.ts +103 -0
  33. package/src/embeddings/chunker.ts +327 -0
  34. package/src/embeddings/index.ts +41 -0
  35. package/src/embeddings/model.ts +95 -0
  36. package/src/embeddings/search.ts +305 -0
  37. package/src/embeddings/store.ts +313 -0
  38. package/src/embeddings/types.ts +85 -0
  39. package/src/engine.ts +1083 -0
  40. package/src/garden/cluster.ts +330 -0
  41. package/src/garden/garden.ts +306 -0
  42. package/src/garden/index.ts +29 -0
  43. package/src/git/git-exporter.ts +286 -0
  44. package/src/git/git-importer.ts +329 -0
  45. package/src/git/git-reader.ts +189 -0
  46. package/src/git/index.ts +22 -0
  47. package/src/identity/governance.ts +211 -0
  48. package/src/identity/identity.ts +224 -0
  49. package/src/identity/index.ts +30 -0
  50. package/src/identity/signing-middleware.ts +97 -0
  51. package/src/index.ts +20 -0
  52. package/src/links/index.ts +49 -0
  53. package/src/links/lifecycle.ts +400 -0
  54. package/src/links/parser.ts +484 -0
  55. package/src/links/ref-index.ts +186 -0
  56. package/src/links/resolver.ts +314 -0
  57. package/src/links/types.ts +108 -0
  58. package/src/mcp/index.ts +22 -0
  59. package/src/mcp/server.ts +1278 -0
  60. package/src/semantic/csharp-parser.ts +493 -0
  61. package/src/semantic/go-parser.ts +585 -0
  62. package/src/semantic/index.ts +34 -0
  63. package/src/semantic/java-parser.ts +456 -0
  64. package/src/semantic/python-parser.ts +659 -0
  65. package/src/semantic/ruby-parser.ts +446 -0
  66. package/src/semantic/rust-parser.ts +784 -0
  67. package/src/semantic/semantic-merge.ts +210 -0
  68. package/src/semantic/ts-parser.ts +681 -0
  69. package/src/semantic/types.ts +175 -0
  70. package/src/sync/index.ts +32 -0
  71. package/src/sync/memory-transport.ts +66 -0
  72. package/src/sync/reconciler.ts +237 -0
  73. package/src/sync/sync-engine.ts +258 -0
  74. package/src/sync/types.ts +104 -0
  75. package/src/vcs/blob-store.ts +124 -0
  76. package/src/vcs/branch.ts +150 -0
  77. package/src/vcs/checkpoint.ts +64 -0
  78. package/src/vcs/decompose.ts +469 -0
  79. package/src/vcs/diff.ts +409 -0
  80. package/src/vcs/engine-context.ts +26 -0
  81. package/src/vcs/index.ts +23 -0
  82. package/src/vcs/issue.ts +800 -0
  83. package/src/vcs/merge.ts +425 -0
  84. package/src/vcs/milestone.ts +124 -0
  85. package/src/vcs/ops.ts +59 -0
  86. package/src/vcs/types.ts +213 -0
  87. package/src/vcs/vcs-middleware.ts +81 -0
  88. package/src/watcher/fs-watcher.ts +217 -0
  89. package/src/watcher/index.ts +9 -0
  90. package/src/watcher/ingestion.ts +116 -0
  91. package/dist/ai/index.js +0 -688
  92. package/dist/cli/server.js +0 -3321
  93. package/dist/cli/tql.js +0 -5282
  94. package/dist/client/tql-client.js +0 -108
  95. package/dist/graph/index.js +0 -2248
  96. package/dist/kernel/logic-middleware.js +0 -179
  97. package/dist/kernel/middleware.js +0 -0
  98. package/dist/kernel/operations.js +0 -32
  99. package/dist/kernel/schema-middleware.js +0 -34
  100. package/dist/kernel/security-middleware.js +0 -53
  101. package/dist/kernel/trellis-kernel.js +0 -2239
  102. package/dist/kernel/workspace.js +0 -91
  103. package/dist/persist/backend.js +0 -0
  104. package/dist/persist/sqlite-backend.js +0 -123
  105. package/dist/query/index.js +0 -1643
  106. package/dist/server/index.js +0 -3309
  107. package/dist/workflows/index.js +0 -3160
@@ -0,0 +1,684 @@
1
+ // @bun
2
+ import {
3
+ __esm,
4
+ __export,
5
+ __require
6
+ } from "./index-a76rekgs.js";
7
+
8
+ // src/embeddings/types.ts
9
+ var DEFAULT_MODEL_CONFIG;
10
+ var init_types = __esm(() => {
11
+ DEFAULT_MODEL_CONFIG = {
12
+ modelName: "Xenova/all-MiniLM-L6-v2",
13
+ dimension: 384
14
+ };
15
+ });
16
+
17
+ // src/embeddings/model.ts
18
+ async function loadModel(config = DEFAULT_MODEL_CONFIG) {
19
+ if (pipeline)
20
+ return pipeline;
21
+ if (!loadPromise) {
22
+ loadPromise = (async () => {
23
+ const { pipeline: createPipeline } = await import("./transformers-m9je15kg.js");
24
+ const opts = {};
25
+ if (config.cacheDir) {
26
+ opts.cache_dir = config.cacheDir;
27
+ }
28
+ pipeline = await createPipeline("feature-extraction", config.modelName, opts);
29
+ return pipeline;
30
+ })();
31
+ }
32
+ return loadPromise;
33
+ }
34
+ async function embed(text, config = DEFAULT_MODEL_CONFIG) {
35
+ const pipe = await loadModel(config);
36
+ const output = await pipe(text, { pooling: "mean", normalize: true });
37
+ return new Float32Array(output.data);
38
+ }
39
+ async function embedBatch(texts, config = DEFAULT_MODEL_CONFIG) {
40
+ if (texts.length === 0)
41
+ return [];
42
+ const pipe = await loadModel(config);
43
+ const results = [];
44
+ const batchSize = 32;
45
+ for (let i = 0;i < texts.length; i += batchSize) {
46
+ const batch = texts.slice(i, i + batchSize);
47
+ for (const text of batch) {
48
+ const output = await pipe(text, { pooling: "mean", normalize: true });
49
+ results.push(new Float32Array(output.data));
50
+ }
51
+ }
52
+ return results;
53
+ }
54
+ function resetModel() {
55
+ pipeline = null;
56
+ loadPromise = null;
57
+ }
58
+ var pipeline = null, loadPromise = null;
59
+ var init_model = __esm(() => {
60
+ init_types();
61
+ });
62
+
63
+ // src/embeddings/store.ts
64
+ import { Database } from "bun:sqlite";
65
+
66
+ class VectorStore {
67
+ db;
68
+ constructor(dbPath) {
69
+ this.db = new Database(dbPath);
70
+ this.db.exec("PRAGMA journal_mode=WAL;");
71
+ this.db.exec("PRAGMA foreign_keys=ON;");
72
+ this.db.exec(SCHEMA_SQL);
73
+ }
74
+ upsert(record) {
75
+ const insertChunk = this.db.prepare(`
76
+ INSERT OR REPLACE INTO chunks (id, entity_id, content, chunk_type, file_path, updated_at)
77
+ VALUES ($id, $entityId, $content, $chunkType, $filePath, $updatedAt)
78
+ `);
79
+ const insertVector = this.db.prepare(`
80
+ INSERT OR REPLACE INTO vectors (id, embedding)
81
+ VALUES ($id, $embedding)
82
+ `);
83
+ const embeddingBlob = Buffer.from(record.embedding.buffer);
84
+ this.db.transaction(() => {
85
+ insertChunk.run({
86
+ $id: record.id,
87
+ $entityId: record.entityId,
88
+ $content: record.content,
89
+ $chunkType: record.chunkType,
90
+ $filePath: record.filePath ?? null,
91
+ $updatedAt: record.updatedAt
92
+ });
93
+ insertVector.run({
94
+ $id: record.id,
95
+ $embedding: embeddingBlob
96
+ });
97
+ })();
98
+ }
99
+ upsertBatch(records) {
100
+ if (records.length === 0)
101
+ return;
102
+ const insertChunk = this.db.prepare(`
103
+ INSERT OR REPLACE INTO chunks (id, entity_id, content, chunk_type, file_path, updated_at)
104
+ VALUES ($id, $entityId, $content, $chunkType, $filePath, $updatedAt)
105
+ `);
106
+ const insertVector = this.db.prepare(`
107
+ INSERT OR REPLACE INTO vectors (id, embedding)
108
+ VALUES ($id, $embedding)
109
+ `);
110
+ this.db.transaction(() => {
111
+ for (const record of records) {
112
+ const embeddingBlob = Buffer.from(record.embedding.buffer);
113
+ insertChunk.run({
114
+ $id: record.id,
115
+ $entityId: record.entityId,
116
+ $content: record.content,
117
+ $chunkType: record.chunkType,
118
+ $filePath: record.filePath ?? null,
119
+ $updatedAt: record.updatedAt
120
+ });
121
+ insertVector.run({
122
+ $id: record.id,
123
+ $embedding: embeddingBlob
124
+ });
125
+ }
126
+ })();
127
+ }
128
+ delete(id) {
129
+ this.db.prepare("DELETE FROM vectors WHERE id = ?").run(id);
130
+ this.db.prepare("DELETE FROM chunks WHERE id = ?").run(id);
131
+ }
132
+ deleteByEntity(entityId) {
133
+ const ids = this.db.prepare("SELECT id FROM chunks WHERE entity_id = ?").all(entityId);
134
+ if (ids.length === 0)
135
+ return;
136
+ this.db.transaction(() => {
137
+ for (const { id } of ids) {
138
+ this.db.prepare("DELETE FROM vectors WHERE id = ?").run(id);
139
+ this.db.prepare("DELETE FROM chunks WHERE id = ?").run(id);
140
+ }
141
+ })();
142
+ }
143
+ deleteByFile(filePath) {
144
+ const ids = this.db.prepare("SELECT id FROM chunks WHERE file_path = ?").all(filePath);
145
+ if (ids.length === 0)
146
+ return;
147
+ this.db.transaction(() => {
148
+ for (const { id } of ids) {
149
+ this.db.prepare("DELETE FROM vectors WHERE id = ?").run(id);
150
+ this.db.prepare("DELETE FROM chunks WHERE id = ?").run(id);
151
+ }
152
+ })();
153
+ }
154
+ getChunk(id) {
155
+ const row = this.db.prepare("SELECT * FROM chunks WHERE id = ?").get(id);
156
+ if (!row)
157
+ return null;
158
+ return rowToChunkMeta(row);
159
+ }
160
+ search(queryVector, opts = {}) {
161
+ const limit = opts.limit ?? 10;
162
+ const minScore = opts.minScore ?? 0;
163
+ const conditions = [];
164
+ const params = {};
165
+ if (opts.types && opts.types.length > 0) {
166
+ const placeholders = opts.types.map((_, i) => `$type${i}`).join(", ");
167
+ conditions.push(`c.chunk_type IN (${placeholders})`);
168
+ opts.types.forEach((t, i) => {
169
+ params[`$type${i}`] = t;
170
+ });
171
+ }
172
+ if (opts.filePrefix) {
173
+ conditions.push("c.file_path LIKE $filePrefix");
174
+ params.$filePrefix = `${opts.filePrefix}%`;
175
+ }
176
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
177
+ const sql = `
178
+ SELECT c.id, c.entity_id, c.content, c.chunk_type, c.file_path, c.updated_at,
179
+ v.embedding
180
+ FROM chunks c
181
+ JOIN vectors v ON c.id = v.id
182
+ ${where}
183
+ `;
184
+ const rows = this.db.prepare(sql).all(params);
185
+ const scored = [];
186
+ for (const row of rows) {
187
+ const storedVec = new Float32Array(row.embedding.buffer, row.embedding.byteOffset, row.embedding.byteLength / 4);
188
+ const score = cosineSimilarity(queryVector, storedVec);
189
+ if (score >= minScore) {
190
+ scored.push({
191
+ chunk: rowToChunkMeta(row),
192
+ score
193
+ });
194
+ }
195
+ }
196
+ scored.sort((a, b) => b.score - a.score);
197
+ return scored.slice(0, limit);
198
+ }
199
+ count() {
200
+ const row = this.db.prepare("SELECT COUNT(*) as cnt FROM chunks").get();
201
+ return row?.cnt ?? 0;
202
+ }
203
+ countByType() {
204
+ const rows = this.db.prepare("SELECT chunk_type, COUNT(*) as cnt FROM chunks GROUP BY chunk_type").all();
205
+ const result = {};
206
+ for (const row of rows) {
207
+ result[row.chunk_type] = row.cnt;
208
+ }
209
+ return result;
210
+ }
211
+ clear() {
212
+ this.db.exec("DELETE FROM vectors");
213
+ this.db.exec("DELETE FROM chunks");
214
+ }
215
+ close() {
216
+ this.db.close();
217
+ }
218
+ }
219
+ function rowToChunkMeta(row) {
220
+ return {
221
+ id: row.id,
222
+ entityId: row.entity_id,
223
+ content: row.content,
224
+ chunkType: row.chunk_type,
225
+ filePath: row.file_path ?? undefined,
226
+ updatedAt: row.updated_at
227
+ };
228
+ }
229
+ function cosineSimilarity(a, b) {
230
+ if (a.length !== b.length)
231
+ return 0;
232
+ let dot = 0;
233
+ let normA = 0;
234
+ let normB = 0;
235
+ for (let i = 0;i < a.length; i++) {
236
+ dot += a[i] * b[i];
237
+ normA += a[i] * a[i];
238
+ normB += b[i] * b[i];
239
+ }
240
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
241
+ return denom === 0 ? 0 : dot / denom;
242
+ }
243
+ var SCHEMA_SQL = `
244
+ CREATE TABLE IF NOT EXISTS chunks (
245
+ id TEXT PRIMARY KEY,
246
+ entity_id TEXT NOT NULL,
247
+ content TEXT NOT NULL,
248
+ chunk_type TEXT NOT NULL,
249
+ file_path TEXT,
250
+ updated_at TEXT NOT NULL
251
+ );
252
+
253
+ CREATE TABLE IF NOT EXISTS vectors (
254
+ id TEXT PRIMARY KEY,
255
+ embedding BLOB NOT NULL,
256
+ FOREIGN KEY (id) REFERENCES chunks(id) ON DELETE CASCADE
257
+ );
258
+
259
+ CREATE INDEX IF NOT EXISTS idx_chunks_entity ON chunks(entity_id);
260
+ CREATE INDEX IF NOT EXISTS idx_chunks_type ON chunks(chunk_type);
261
+ CREATE INDEX IF NOT EXISTS idx_chunks_file ON chunks(file_path);
262
+ `;
263
+ var init_store = () => {};
264
+
265
+ // src/embeddings/chunker.ts
266
+ function chunkIssue(issue) {
267
+ const now = new Date().toISOString();
268
+ const chunks = [];
269
+ if (issue.title) {
270
+ chunks.push({
271
+ id: `issue:${issue.id}:title`,
272
+ entityId: `issue:${issue.id}`,
273
+ content: issue.title,
274
+ chunkType: "issue_title",
275
+ updatedAt: now
276
+ });
277
+ }
278
+ if (issue.description) {
279
+ chunks.push({
280
+ id: `issue:${issue.id}:desc`,
281
+ entityId: `issue:${issue.id}`,
282
+ content: issue.description,
283
+ chunkType: "issue_desc",
284
+ updatedAt: now
285
+ });
286
+ }
287
+ return chunks;
288
+ }
289
+ function chunkDecision(decision) {
290
+ const parts = [];
291
+ parts.push(`Decision ${decision.id}: ${decision.toolName}`);
292
+ if (decision.rationale)
293
+ parts.push(`Rationale: ${decision.rationale}`);
294
+ if (decision.context)
295
+ parts.push(`Context: ${decision.context}`);
296
+ if (decision.outputSummary)
297
+ parts.push(`Output: ${decision.outputSummary}`);
298
+ const content = parts.join(`
299
+ `);
300
+ if (!content.trim())
301
+ return [];
302
+ return [
303
+ {
304
+ id: `decision:${decision.id}:rationale`,
305
+ entityId: `decision:${decision.id}`,
306
+ content,
307
+ chunkType: "decision_rationale",
308
+ updatedAt: new Date().toISOString()
309
+ }
310
+ ];
311
+ }
312
+ function chunkMilestone(milestone) {
313
+ if (!milestone.message)
314
+ return [];
315
+ return [
316
+ {
317
+ id: `milestone:${milestone.id}:msg`,
318
+ entityId: `milestone:${milestone.id}`,
319
+ content: milestone.message,
320
+ chunkType: "milestone_msg",
321
+ updatedAt: new Date().toISOString()
322
+ }
323
+ ];
324
+ }
325
+ function chunkMarkdown(filePath, content) {
326
+ if (!content.trim())
327
+ return [];
328
+ const entityId = `file:${filePath}`;
329
+ const now = new Date().toISOString();
330
+ const sections = splitByHeadings(content);
331
+ const chunks = [];
332
+ for (let i = 0;i < sections.length; i++) {
333
+ const section = sections[i];
334
+ if (!section.text.trim())
335
+ continue;
336
+ if (section.text.length <= MAX_CHUNK_CHARS) {
337
+ chunks.push({
338
+ id: `${entityId}:section:${i}`,
339
+ entityId,
340
+ content: section.text,
341
+ chunkType: "markdown",
342
+ filePath,
343
+ updatedAt: now
344
+ });
345
+ } else {
346
+ const windows = slidingWindow(section.text);
347
+ for (let w = 0;w < windows.length; w++) {
348
+ chunks.push({
349
+ id: `${entityId}:section:${i}:w${w}`,
350
+ entityId,
351
+ content: windows[w],
352
+ chunkType: "markdown",
353
+ filePath,
354
+ updatedAt: now
355
+ });
356
+ }
357
+ }
358
+ }
359
+ return chunks;
360
+ }
361
+ function chunkCodeEntities(filePath, declarations) {
362
+ const now = new Date().toISOString();
363
+ const chunks = [];
364
+ for (const decl of declarations) {
365
+ const parts = [];
366
+ if (decl.docComment)
367
+ parts.push(decl.docComment);
368
+ parts.push(`${decl.kind} ${decl.name}`);
369
+ parts.push(decl.signature);
370
+ const content = parts.join(`
371
+ `).slice(0, MAX_CHUNK_CHARS);
372
+ chunks.push({
373
+ id: `symbol:${filePath}#${decl.name}`,
374
+ entityId: `symbol:${filePath}#${decl.name}`,
375
+ content,
376
+ chunkType: "code_entity",
377
+ filePath,
378
+ updatedAt: now
379
+ });
380
+ }
381
+ return chunks;
382
+ }
383
+ function chunkDocComments(filePath, comments) {
384
+ if (comments.length === 0)
385
+ return [];
386
+ const entityId = `file:${filePath}`;
387
+ const now = new Date().toISOString();
388
+ const chunks = [];
389
+ for (let i = 0;i < comments.length; i++) {
390
+ const comment = comments[i];
391
+ if (!comment.text.trim())
392
+ continue;
393
+ chunks.push({
394
+ id: `${entityId}:doc:${i}`,
395
+ entityId,
396
+ content: comment.text.slice(0, MAX_CHUNK_CHARS),
397
+ chunkType: "doc_comment",
398
+ filePath,
399
+ updatedAt: now
400
+ });
401
+ }
402
+ return chunks;
403
+ }
404
+ function chunkSummary(filePath, content) {
405
+ if (!content.trim())
406
+ return [];
407
+ const entityId = `file:${filePath}`;
408
+ const now = new Date().toISOString();
409
+ if (content.length <= MAX_CHUNK_CHARS) {
410
+ return [
411
+ {
412
+ id: `${entityId}:summary`,
413
+ entityId,
414
+ content,
415
+ chunkType: "summary_md",
416
+ filePath,
417
+ updatedAt: now
418
+ }
419
+ ];
420
+ }
421
+ return chunkMarkdown(filePath, content).map((c) => ({
422
+ ...c,
423
+ chunkType: "summary_md"
424
+ }));
425
+ }
426
+ function chunkFile(filePath, content) {
427
+ if (!content.trim())
428
+ return [];
429
+ const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
430
+ if (filePath.endsWith("summary.md")) {
431
+ return chunkSummary(filePath, content);
432
+ }
433
+ if (ext === "md") {
434
+ return chunkMarkdown(filePath, content);
435
+ }
436
+ return [];
437
+ }
438
+ function splitByHeadings(content) {
439
+ const lines = content.split(`
440
+ `);
441
+ const sections = [];
442
+ let currentSection = { text: "" };
443
+ for (const line of lines) {
444
+ if (/^#{1,3}\s/.test(line)) {
445
+ if (currentSection.text.trim()) {
446
+ sections.push(currentSection);
447
+ }
448
+ currentSection = { heading: line, text: line + `
449
+ ` };
450
+ } else {
451
+ currentSection.text += line + `
452
+ `;
453
+ }
454
+ }
455
+ if (currentSection.text.trim()) {
456
+ sections.push(currentSection);
457
+ }
458
+ return sections;
459
+ }
460
+ function slidingWindow(text) {
461
+ const windows = [];
462
+ let start = 0;
463
+ while (start < text.length) {
464
+ const end = Math.min(start + MAX_CHUNK_CHARS, text.length);
465
+ windows.push(text.slice(start, end));
466
+ if (end >= text.length)
467
+ break;
468
+ start += MAX_CHUNK_CHARS - OVERLAP_CHARS;
469
+ }
470
+ return windows;
471
+ }
472
+ var MAX_CHUNK_CHARS = 512, OVERLAP_CHARS = 64;
473
+ var init_chunker = () => {};
474
+
475
+ // src/embeddings/search.ts
476
+ import { join } from "path";
477
+ import { readFileSync, existsSync } from "fs";
478
+
479
+ class EmbeddingManager {
480
+ store;
481
+ embedFn;
482
+ constructor(dbPath, embedFn) {
483
+ this.store = new VectorStore(dbPath);
484
+ this.embedFn = embedFn ?? embed;
485
+ }
486
+ async reindex(engine) {
487
+ this.store.clear();
488
+ const allChunks = [];
489
+ const issues = engine.listIssues();
490
+ for (const issue of issues) {
491
+ allChunks.push(...chunkIssue(issue));
492
+ }
493
+ const milestones = engine.listMilestones();
494
+ for (const ms of milestones) {
495
+ allChunks.push(...chunkMilestone(ms));
496
+ }
497
+ if (engine.queryDecisions) {
498
+ const decisions = engine.queryDecisions();
499
+ for (const dec of decisions) {
500
+ allChunks.push(...chunkDecision(dec));
501
+ }
502
+ }
503
+ const rootPath = engine.getRootPath();
504
+ const trackedFiles = engine.trackedFiles();
505
+ for (const tf of trackedFiles) {
506
+ try {
507
+ const absPath = join(rootPath, tf.path);
508
+ if (!existsSync(absPath))
509
+ continue;
510
+ const content = readFileSync(absPath, "utf-8");
511
+ allChunks.push(...chunkFile(tf.path, content));
512
+ } catch {}
513
+ }
514
+ if (engine.parseFile) {
515
+ for (const tf of trackedFiles) {
516
+ const ext = tf.path.split(".").pop()?.toLowerCase() ?? "";
517
+ if (![
518
+ "ts",
519
+ "js",
520
+ "tsx",
521
+ "jsx",
522
+ "py",
523
+ "go",
524
+ "rs",
525
+ "rb",
526
+ "java",
527
+ "cs"
528
+ ].includes(ext)) {
529
+ continue;
530
+ }
531
+ try {
532
+ const parsed = engine.parseFile(tf.path);
533
+ if (parsed && Array.isArray(parsed.entities)) {
534
+ const declarations = parsed.entities.map((e) => ({
535
+ id: e.id ?? e.name,
536
+ name: e.name,
537
+ kind: e.kind,
538
+ signature: e.signature ?? e.rawText?.split(`
539
+ `)[0] ?? "",
540
+ docComment: e.docComment
541
+ }));
542
+ allChunks.push(...chunkCodeEntities(tf.path, declarations));
543
+ }
544
+ } catch {}
545
+ }
546
+ }
547
+ const records = [];
548
+ for (const chunk of allChunks) {
549
+ try {
550
+ const vector = await this.embedFn(chunk.content);
551
+ records.push({ ...chunk, embedding: vector });
552
+ } catch {}
553
+ }
554
+ this.store.upsertBatch(records);
555
+ return { chunks: records.length };
556
+ }
557
+ async indexFile(filePath, content, engine) {
558
+ this.store.deleteByFile(filePath);
559
+ const chunks = chunkFile(filePath, content);
560
+ if (engine?.parseFile) {
561
+ const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
562
+ if ([
563
+ "ts",
564
+ "js",
565
+ "tsx",
566
+ "jsx",
567
+ "py",
568
+ "go",
569
+ "rs",
570
+ "rb",
571
+ "java",
572
+ "cs"
573
+ ].includes(ext)) {
574
+ try {
575
+ const parsed = engine.parseFile(filePath);
576
+ if (parsed && Array.isArray(parsed.entities)) {
577
+ const declarations = parsed.entities.map((e) => ({
578
+ id: e.id ?? e.name,
579
+ name: e.name,
580
+ kind: e.kind,
581
+ signature: e.signature ?? e.rawText?.split(`
582
+ `)[0] ?? "",
583
+ docComment: e.docComment
584
+ }));
585
+ chunks.push(...chunkCodeEntities(filePath, declarations));
586
+ }
587
+ } catch {}
588
+ }
589
+ }
590
+ const records = [];
591
+ for (const chunk of chunks) {
592
+ try {
593
+ const vector = await this.embedFn(chunk.content);
594
+ records.push({ ...chunk, embedding: vector });
595
+ } catch {}
596
+ }
597
+ if (records.length > 0) {
598
+ this.store.upsertBatch(records);
599
+ }
600
+ return records.length;
601
+ }
602
+ async indexIssue(issue) {
603
+ this.store.deleteByEntity(`issue:${issue.id}`);
604
+ const chunks = chunkIssue(issue);
605
+ const records = [];
606
+ for (const chunk of chunks) {
607
+ try {
608
+ const vector = await this.embedFn(chunk.content);
609
+ records.push({ ...chunk, embedding: vector });
610
+ } catch {}
611
+ }
612
+ if (records.length > 0) {
613
+ this.store.upsertBatch(records);
614
+ }
615
+ return records.length;
616
+ }
617
+ async indexMilestone(milestone) {
618
+ this.store.deleteByEntity(`milestone:${milestone.id}`);
619
+ const chunks = chunkMilestone(milestone);
620
+ const records = [];
621
+ for (const chunk of chunks) {
622
+ try {
623
+ const vector = await this.embedFn(chunk.content);
624
+ records.push({ ...chunk, embedding: vector });
625
+ } catch {}
626
+ }
627
+ if (records.length > 0) {
628
+ this.store.upsertBatch(records);
629
+ }
630
+ return records.length;
631
+ }
632
+ async search(query, opts) {
633
+ const queryVector = await this.embedFn(query);
634
+ return this.store.search(queryVector, opts);
635
+ }
636
+ removeFile(filePath) {
637
+ this.store.deleteByFile(filePath);
638
+ }
639
+ stats() {
640
+ return {
641
+ total: this.store.count(),
642
+ byType: this.store.countByType()
643
+ };
644
+ }
645
+ close() {
646
+ this.store.close();
647
+ }
648
+ }
649
+ var init_search = __esm(() => {
650
+ init_store();
651
+ init_model();
652
+ init_chunker();
653
+ });
654
+
655
+ // src/embeddings/index.ts
656
+ var exports_embeddings = {};
657
+ __export(exports_embeddings, {
658
+ slidingWindow: () => slidingWindow,
659
+ resetModel: () => resetModel,
660
+ loadModel: () => loadModel,
661
+ embedBatch: () => embedBatch,
662
+ embed: () => embed,
663
+ cosineSimilarity: () => cosineSimilarity,
664
+ chunkSummary: () => chunkSummary,
665
+ chunkMilestone: () => chunkMilestone,
666
+ chunkMarkdown: () => chunkMarkdown,
667
+ chunkIssue: () => chunkIssue,
668
+ chunkFile: () => chunkFile,
669
+ chunkDocComments: () => chunkDocComments,
670
+ chunkDecision: () => chunkDecision,
671
+ chunkCodeEntities: () => chunkCodeEntities,
672
+ VectorStore: () => VectorStore,
673
+ EmbeddingManager: () => EmbeddingManager,
674
+ DEFAULT_MODEL_CONFIG: () => DEFAULT_MODEL_CONFIG
675
+ });
676
+ var init_embeddings = __esm(() => {
677
+ init_types();
678
+ init_model();
679
+ init_store();
680
+ init_search();
681
+ init_chunker();
682
+ });
683
+
684
+ export { DEFAULT_MODEL_CONFIG, loadModel, embed, embedBatch, resetModel, VectorStore, cosineSimilarity, chunkIssue, chunkDecision, chunkMilestone, chunkMarkdown, chunkCodeEntities, chunkDocComments, chunkSummary, chunkFile, slidingWindow, EmbeddingManager, exports_embeddings, init_embeddings };