brainbank 0.2.2 → 0.3.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 (48) hide show
  1. package/README.md +19 -9
  2. package/dist/{base-9vfWRHCV.d.ts → base-4SUgeRWT.d.ts} +25 -2
  3. package/dist/{chunk-ZJ5LLMGM.js → chunk-2BEWWQL2.js} +432 -415
  4. package/dist/chunk-2BEWWQL2.js.map +1 -0
  5. package/dist/{chunk-OPQ3ZIPV.js → chunk-5VUYPNH3.js} +47 -3
  6. package/dist/chunk-5VUYPNH3.js.map +1 -0
  7. package/dist/chunk-CCXVL56V.js +120 -0
  8. package/dist/chunk-CCXVL56V.js.map +1 -0
  9. package/dist/{chunk-FEAMUZGJ.js → chunk-E6WQM4DN.js} +3 -3
  10. package/dist/chunk-E6WQM4DN.js.map +1 -0
  11. package/dist/chunk-FI7GWG4W.js +309 -0
  12. package/dist/chunk-FI7GWG4W.js.map +1 -0
  13. package/dist/{chunk-X6645UVR.js → chunk-FINIFKAY.js} +136 -4
  14. package/dist/chunk-FINIFKAY.js.map +1 -0
  15. package/dist/{chunk-4DM3XWO6.js → chunk-MGIFEPYZ.js} +54 -42
  16. package/dist/chunk-MGIFEPYZ.js.map +1 -0
  17. package/dist/{chunk-T2VXF5S5.js → chunk-Y3JKI6QN.js} +152 -137
  18. package/dist/chunk-Y3JKI6QN.js.map +1 -0
  19. package/dist/cli.js +34 -28
  20. package/dist/cli.js.map +1 -1
  21. package/dist/code.d.ts +1 -1
  22. package/dist/code.js +1 -1
  23. package/dist/docs.d.ts +1 -1
  24. package/dist/docs.js +1 -1
  25. package/dist/git.d.ts +1 -1
  26. package/dist/git.js +1 -1
  27. package/dist/index.d.ts +121 -82
  28. package/dist/index.js +66 -15
  29. package/dist/index.js.map +1 -1
  30. package/dist/memory.d.ts +1 -1
  31. package/dist/memory.js +3 -137
  32. package/dist/memory.js.map +1 -1
  33. package/dist/notes.d.ts +1 -1
  34. package/dist/notes.js +4 -49
  35. package/dist/notes.js.map +1 -1
  36. package/dist/{openai-CYDMYX7X.js → openai-embedding-VQZCZQYT.js} +2 -2
  37. package/package.json +1 -1
  38. package/dist/chunk-4DM3XWO6.js.map +0 -1
  39. package/dist/chunk-7JCEW7LT.js +0 -266
  40. package/dist/chunk-7JCEW7LT.js.map +0 -1
  41. package/dist/chunk-FEAMUZGJ.js.map +0 -1
  42. package/dist/chunk-GUT5MSJT.js +0 -99
  43. package/dist/chunk-GUT5MSJT.js.map +0 -1
  44. package/dist/chunk-OPQ3ZIPV.js.map +0 -1
  45. package/dist/chunk-T2VXF5S5.js.map +0 -1
  46. package/dist/chunk-X6645UVR.js.map +0 -1
  47. package/dist/chunk-ZJ5LLMGM.js.map +0 -1
  48. /package/dist/{openai-CYDMYX7X.js.map → openai-embedding-VQZCZQYT.js.map} +0 -0
@@ -5,7 +5,7 @@ import {
5
5
  __name
6
6
  } from "./chunk-7QVYU63E.js";
7
7
 
8
- // src/memory/store.ts
8
+ // src/indexers/memory/pattern-store.ts
9
9
  var PatternStore = class {
10
10
  static {
11
11
  __name(this, "PatternStore");
@@ -95,7 +95,7 @@ var PatternStore = class {
95
95
  }
96
96
  };
97
97
 
98
- // src/memory/consolidator.ts
98
+ // src/indexers/memory/consolidator.ts
99
99
  var Consolidator = class {
100
100
  constructor(_db, _vectorCache) {
101
101
  this._db = _db;
@@ -164,8 +164,140 @@ var Consolidator = class {
164
164
  }
165
165
  };
166
166
 
167
+ // src/indexers/memory/distiller.ts
168
+ var StrategyDistiller = class {
169
+ constructor(_db) {
170
+ this._db = _db;
171
+ }
172
+ static {
173
+ __name(this, "StrategyDistiller");
174
+ }
175
+ /**
176
+ * Distill top patterns for a task type into a strategy.
177
+ * Updates the distilled_strategies table.
178
+ */
179
+ distill(taskType, topK = 10) {
180
+ const patterns = this._db.prepare(`
181
+ SELECT task, approach, outcome, critique, success_rate
182
+ FROM memory_patterns
183
+ WHERE task_type = ? AND success_rate >= 0.7
184
+ ORDER BY success_rate DESC, created_at DESC
185
+ LIMIT ?
186
+ `).all(taskType, topK);
187
+ if (patterns.length === 0) return null;
188
+ const lines = [];
189
+ const avgSuccess = patterns.reduce((sum, p) => sum + p.success_rate, 0) / patterns.length;
190
+ lines.push(`Strategy for "${taskType}" (${patterns.length} patterns, avg success ${Math.round(avgSuccess * 100)}%):`);
191
+ lines.push("");
192
+ for (const p of patterns) {
193
+ lines.push(`\u2022 ${p.approach} (${Math.round(p.success_rate * 100)}%)`);
194
+ if (p.critique) lines.push(` \u2514 ${p.critique}`);
195
+ }
196
+ const strategy = lines.join("\n");
197
+ const confidence = avgSuccess;
198
+ const now = Math.floor(Date.now() / 1e3);
199
+ this._db.prepare(`
200
+ INSERT INTO distilled_strategies (task_type, strategy, confidence, updated_at)
201
+ VALUES (?, ?, ?, ?)
202
+ ON CONFLICT(task_type) DO UPDATE SET
203
+ strategy = excluded.strategy,
204
+ confidence = excluded.confidence,
205
+ updated_at = excluded.updated_at
206
+ `).run(taskType, strategy, confidence, now);
207
+ return { taskType, strategy, confidence, updatedAt: now };
208
+ }
209
+ /**
210
+ * Get a distilled strategy for a task type.
211
+ */
212
+ get(taskType) {
213
+ const row = this._db.prepare(
214
+ "SELECT * FROM distilled_strategies WHERE task_type = ?"
215
+ ).get(taskType);
216
+ if (!row) return null;
217
+ return {
218
+ taskType: row.task_type,
219
+ strategy: row.strategy,
220
+ confidence: row.confidence,
221
+ updatedAt: row.updated_at
222
+ };
223
+ }
224
+ /**
225
+ * List all distilled strategies.
226
+ */
227
+ list() {
228
+ const rows = this._db.prepare(
229
+ "SELECT * FROM distilled_strategies ORDER BY confidence DESC"
230
+ ).all();
231
+ return rows.map((r) => ({
232
+ taskType: r.task_type,
233
+ strategy: r.strategy,
234
+ confidence: r.confidence,
235
+ updatedAt: r.updated_at
236
+ }));
237
+ }
238
+ };
239
+
240
+ // src/indexers/memory/memory-plugin.ts
241
+ var MemoryPlugin = class {
242
+ static {
243
+ __name(this, "MemoryPlugin");
244
+ }
245
+ name = "memory";
246
+ hnsw;
247
+ patternStore;
248
+ consolidator;
249
+ distiller;
250
+ vecCache = /* @__PURE__ */ new Map();
251
+ _db;
252
+ async initialize(ctx) {
253
+ this._db = ctx.db;
254
+ this.hnsw = await ctx.createHnsw(1e5);
255
+ ctx.loadVectors("memory_vectors", "pattern_id", this.hnsw, this.vecCache);
256
+ this.patternStore = new PatternStore({
257
+ db: ctx.db,
258
+ hnsw: this.hnsw,
259
+ vectorCache: this.vecCache,
260
+ embedding: ctx.embedding
261
+ });
262
+ this.consolidator = new Consolidator(ctx.db, this.vecCache);
263
+ this.distiller = new StrategyDistiller(ctx.db);
264
+ }
265
+ /** Store a learned pattern. */
266
+ async learn(pattern) {
267
+ const id = await this.patternStore.learn(pattern);
268
+ if (this.patternStore.count > 0 && this.patternStore.count % 50 === 0) {
269
+ this.consolidator.consolidate();
270
+ }
271
+ return id;
272
+ }
273
+ /** Search for similar patterns. */
274
+ async search(query, k = 4) {
275
+ return this.patternStore.search(query, k);
276
+ }
277
+ /** Consolidate: prune old failures + deduplicate. */
278
+ consolidate() {
279
+ return this.consolidator.consolidate();
280
+ }
281
+ /** Distill patterns into a strategy. */
282
+ distill(taskType) {
283
+ return this.distiller.distill(taskType);
284
+ }
285
+ stats() {
286
+ return {
287
+ patterns: this.patternStore.count,
288
+ avgSuccess: this._db.prepare("SELECT AVG(success_rate) as a FROM memory_patterns").get().a ?? 0,
289
+ hnswSize: this.hnsw.size
290
+ };
291
+ }
292
+ };
293
+ function memory() {
294
+ return new MemoryPlugin();
295
+ }
296
+ __name(memory, "memory");
297
+
167
298
  export {
168
299
  PatternStore,
169
- Consolidator
300
+ Consolidator,
301
+ memory
170
302
  };
171
- //# sourceMappingURL=chunk-X6645UVR.js.map
303
+ //# sourceMappingURL=chunk-FINIFKAY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/indexers/memory/pattern-store.ts","../src/indexers/memory/consolidator.ts","../src/indexers/memory/distiller.ts","../src/indexers/memory/memory-plugin.ts"],"sourcesContent":["/**\n * BrainBank — Pattern Store (Agent Memory)\n * \n * Stores what the agent learned from past tasks.\n * Each pattern records task, approach, and success rate.\n * Searchable by semantic similarity via HNSW.\n */\n\nimport type { Database } from '@/db/database.ts';\nimport type { EmbeddingProvider, LearningPattern } from '@/types.ts';\nimport type { HNSWIndex } from '@/providers/vector/hnsw-index.ts';\n\nexport interface PatternStoreDeps {\n db: Database;\n hnsw: HNSWIndex;\n vectorCache: Map<number, Float32Array>;\n embedding: EmbeddingProvider;\n}\n\nexport class PatternStore {\n private _deps: PatternStoreDeps;\n\n constructor(deps: PatternStoreDeps) {\n this._deps = deps;\n }\n\n /**\n * Store a learned pattern.\n * Returns the pattern ID.\n */\n async learn(pattern: LearningPattern): Promise<number> {\n const result = this._deps.db.prepare(`\n INSERT INTO memory_patterns (task_type, task, approach, outcome, success_rate, critique, tokens_used, latency_ms)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n pattern.taskType,\n pattern.task,\n pattern.approach,\n pattern.outcome ?? null,\n pattern.successRate,\n pattern.critique ?? null,\n pattern.tokensUsed ?? null,\n pattern.latencyMs ?? null,\n );\n\n const id = Number(result.lastInsertRowid);\n\n // Embed and store vector\n const text = `${pattern.taskType} ${pattern.task} ${pattern.approach}`;\n const vec = await this._deps.embedding.embed(text);\n\n this._deps.db.prepare(\n 'INSERT INTO memory_vectors (pattern_id, embedding) VALUES (?, ?)'\n ).run(id, Buffer.from(vec.buffer));\n\n this._deps.hnsw.add(vec, id);\n this._deps.vectorCache.set(id, vec);\n\n return id;\n }\n\n /**\n * Search for similar successful patterns.\n * Filters by minimum success rate.\n */\n async search(query: string, k: number = 4, minSuccess: number = 0.5): Promise<(LearningPattern & { score: number })[]> {\n if (this._deps.hnsw.size === 0) return [];\n\n const vec = await this._deps.embedding.embed(query);\n const hits = this._deps.hnsw.search(vec, k * 2);\n\n if (hits.length === 0) return [];\n\n const ids = hits.map(h => h.id);\n const scoreMap = new Map(hits.map(h => [h.id, h.score]));\n\n const placeholders = ids.map(() => '?').join(',');\n const rows = this._deps.db.prepare(\n `SELECT * FROM memory_patterns WHERE id IN (${placeholders}) AND success_rate >= ?`\n ).all(...ids, minSuccess) as any[];\n\n return rows\n .map(r => ({\n id: r.id,\n taskType: r.task_type,\n task: r.task,\n approach: r.approach,\n outcome: r.outcome,\n successRate: r.success_rate,\n critique: r.critique,\n tokensUsed: r.tokens_used,\n latencyMs: r.latency_ms,\n score: scoreMap.get(r.id) ?? 0,\n }))\n .sort((a, b) => b.score - a.score)\n .slice(0, k);\n }\n\n /**\n * Get all patterns for a specific task type.\n */\n getByTaskType(taskType: string, limit: number = 20): LearningPattern[] {\n const rows = this._deps.db.prepare(\n `SELECT * FROM memory_patterns WHERE task_type = ? ORDER BY success_rate DESC LIMIT ?`\n ).all(taskType, limit) as any[];\n\n return rows.map(r => ({\n id: r.id,\n taskType: r.task_type,\n task: r.task,\n approach: r.approach,\n outcome: r.outcome,\n successRate: r.success_rate,\n critique: r.critique,\n tokensUsed: r.tokens_used,\n latencyMs: r.latency_ms,\n }));\n }\n\n /** Total number of stored patterns. */\n get count(): number {\n return (this._deps.db.prepare('SELECT COUNT(*) as c FROM memory_patterns').get() as any).c;\n }\n}\n","/**\n * BrainBank — Consolidator\n * \n * Maintenance operations for the agent memory:\n * - prune: remove old failed patterns\n * - dedup: merge near-duplicate patterns (cosine > 0.95)\n * - consolidate: run both\n */\n\nimport type { Database } from '@/db/database.ts';\nimport { cosineSimilarity } from '@/lib/math.ts';\n\nexport class Consolidator {\n constructor(\n private _db: Database,\n private _vectorCache: Map<number, Float32Array>,\n ) {}\n\n /**\n * Remove old failed patterns.\n * Criteria: success_rate < 0.3 AND created > 90 days ago.\n */\n prune(maxAgeDays: number = 90, minSuccess: number = 0.3): number {\n const cutoff = Math.floor(Date.now() / 1000) - maxAgeDays * 86400;\n const result = this._db.prepare(\n 'DELETE FROM memory_patterns WHERE success_rate < ? AND created_at < ?'\n ).run(minSuccess, cutoff);\n return result.changes;\n }\n\n /**\n * Merge near-duplicate patterns.\n * Keeps the one with higher success_rate.\n * Threshold: cosine similarity > 0.95.\n */\n dedup(threshold: number = 0.95): number {\n const entries = Array.from(this._vectorCache.entries());\n const toDelete = new Set<number>();\n\n for (let i = 0; i < entries.length; i++) {\n if (toDelete.has(entries[i][0])) continue;\n\n for (let j = i + 1; j < entries.length; j++) {\n if (toDelete.has(entries[j][0])) continue;\n\n const sim = cosineSimilarity(entries[i][1], entries[j][1]);\n if (sim > threshold) {\n // Keep the one with higher success rate\n const pi = this._db.prepare(\n 'SELECT success_rate FROM memory_patterns WHERE id = ?'\n ).get(entries[i][0]) as any;\n const pj = this._db.prepare(\n 'SELECT success_rate FROM memory_patterns WHERE id = ?'\n ).get(entries[j][0]) as any;\n\n if (pi && pj) {\n const deleteId = pi.success_rate >= pj.success_rate\n ? entries[j][0]\n : entries[i][0];\n toDelete.add(deleteId);\n }\n }\n }\n }\n\n if (toDelete.size > 0) {\n const ids = Array.from(toDelete);\n const placeholders = ids.map(() => '?').join(',');\n this._db.prepare(\n `DELETE FROM memory_patterns WHERE id IN (${placeholders})`\n ).run(...ids);\n\n // Clean vector cache\n for (const id of ids) {\n this._vectorCache.delete(id);\n }\n }\n\n return toDelete.size;\n }\n\n /**\n * Run full consolidation: prune + dedup.\n */\n consolidate(): { pruned: number; deduped: number } {\n const pruned = this.prune();\n const deduped = this.dedup();\n return { pruned, deduped };\n }\n}\n","/**\n * BrainBank — Strategy Distiller\n * \n * Aggregates top patterns for a task type into a single strategy text.\n * Analogous to SONA's Deep Loop — periodic knowledge distillation.\n */\n\nimport type { Database } from '@/db/database.ts';\nimport type { DistilledStrategy } from '@/types.ts';\n\nexport class StrategyDistiller {\n constructor(private _db: Database) {}\n\n /**\n * Distill top patterns for a task type into a strategy.\n * Updates the distilled_strategies table.\n */\n distill(taskType: string, topK: number = 10): DistilledStrategy | null {\n const patterns = this._db.prepare(`\n SELECT task, approach, outcome, critique, success_rate\n FROM memory_patterns\n WHERE task_type = ? AND success_rate >= 0.7\n ORDER BY success_rate DESC, created_at DESC\n LIMIT ?\n `).all(taskType, topK) as any[];\n\n if (patterns.length === 0) return null;\n\n // Build strategy text from top patterns\n const lines: string[] = [];\n const avgSuccess = patterns.reduce((sum: number, p: any) => sum + p.success_rate, 0) / patterns.length;\n\n lines.push(`Strategy for \"${taskType}\" (${patterns.length} patterns, avg success ${Math.round(avgSuccess * 100)}%):`);\n lines.push('');\n\n for (const p of patterns) {\n lines.push(`• ${p.approach} (${Math.round(p.success_rate * 100)}%)`);\n if (p.critique) lines.push(` └ ${p.critique}`);\n }\n\n const strategy = lines.join('\\n');\n const confidence = avgSuccess;\n const now = Math.floor(Date.now() / 1000);\n\n this._db.prepare(`\n INSERT INTO distilled_strategies (task_type, strategy, confidence, updated_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(task_type) DO UPDATE SET\n strategy = excluded.strategy,\n confidence = excluded.confidence,\n updated_at = excluded.updated_at\n `).run(taskType, strategy, confidence, now);\n\n return { taskType, strategy, confidence, updatedAt: now };\n }\n\n /**\n * Get a distilled strategy for a task type.\n */\n get(taskType: string): DistilledStrategy | null {\n const row = this._db.prepare(\n 'SELECT * FROM distilled_strategies WHERE task_type = ?'\n ).get(taskType) as any;\n\n if (!row) return null;\n return {\n taskType: row.task_type,\n strategy: row.strategy,\n confidence: row.confidence,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * List all distilled strategies.\n */\n list(): DistilledStrategy[] {\n const rows = this._db.prepare(\n 'SELECT * FROM distilled_strategies ORDER BY confidence DESC'\n ).all() as any[];\n\n return rows.map(r => ({\n taskType: r.task_type,\n strategy: r.strategy,\n confidence: r.confidence,\n updatedAt: r.updated_at,\n }));\n }\n}\n","/**\n * BrainBank — Memory Plugin\n * \n * Agent learns from completed tasks — stores patterns,\n * consolidates failures, distills strategies.\n * \n * import { memory } from 'brainbank/memory';\n * brain.use(memory());\n */\n\nimport type { Indexer, IndexerContext } from '@/indexers/base.ts';\nimport type { HNSWIndex } from '@/providers/vector/hnsw-index.ts';\nimport type { Database } from '@/db/database.ts';\nimport { PatternStore } from './pattern-store.ts';\nimport { Consolidator } from './consolidator.ts';\nimport { StrategyDistiller } from './distiller.ts';\nimport type { LearningPattern, DistilledStrategy } from '@/types.ts';\n\nclass MemoryPlugin implements Indexer {\n readonly name = 'memory';\n hnsw!: HNSWIndex;\n patternStore!: PatternStore;\n consolidator!: Consolidator;\n distiller!: StrategyDistiller;\n vecCache = new Map<number, Float32Array>();\n private _db!: Database;\n\n async initialize(ctx: IndexerContext): Promise<void> {\n this._db = ctx.db;\n this.hnsw = await ctx.createHnsw(100_000);\n ctx.loadVectors('memory_vectors', 'pattern_id', this.hnsw, this.vecCache);\n\n this.patternStore = new PatternStore({\n db: ctx.db,\n hnsw: this.hnsw,\n vectorCache: this.vecCache,\n embedding: ctx.embedding,\n });\n\n this.consolidator = new Consolidator(ctx.db, this.vecCache);\n this.distiller = new StrategyDistiller(ctx.db);\n }\n\n /** Store a learned pattern. */\n async learn(pattern: LearningPattern): Promise<number> {\n const id = await this.patternStore.learn(pattern);\n\n // Auto-consolidate every 50 patterns (guard against count=0)\n if (this.patternStore.count > 0 && this.patternStore.count % 50 === 0) {\n this.consolidator.consolidate();\n }\n\n return id;\n }\n\n /** Search for similar patterns. */\n async search(query: string, k: number = 4): Promise<(LearningPattern & { score: number })[]> {\n return this.patternStore.search(query, k);\n }\n\n /** Consolidate: prune old failures + deduplicate. */\n consolidate(): { pruned: number; deduped: number } {\n return this.consolidator.consolidate();\n }\n\n /** Distill patterns into a strategy. */\n distill(taskType: string): DistilledStrategy | null {\n return this.distiller.distill(taskType);\n }\n\n stats(): Record<string, any> {\n return {\n patterns: this.patternStore.count,\n avgSuccess: (this._db.prepare('SELECT AVG(success_rate) as a FROM memory_patterns').get() as any).a ?? 0,\n hnswSize: this.hnsw.size,\n };\n }\n}\n\n/** Create an agent memory plugin. */\nexport function memory(): Indexer {\n return new MemoryPlugin();\n}\n"],"mappings":"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","names":[]}
@@ -573,10 +573,7 @@ var CodeIndexer = class {
573
573
  this._repoPath = repoPath;
574
574
  this._maxFileSize = maxFileSize;
575
575
  }
576
- /**
577
- * Index all supported files in the repository.
578
- * Skips unchanged files (same content hash).
579
- */
576
+ /** Index all supported files. Skips unchanged files (same content hash). */
580
577
  async index(options = {}) {
581
578
  const { forceReindex = false, onProgress } = options;
582
579
  const files = this._walkRepo(this._repoPath);
@@ -599,46 +596,55 @@ var CodeIndexer = class {
599
596
  skipped++;
600
597
  continue;
601
598
  }
602
- const oldChunks = this._deps.db.prepare(
603
- "SELECT id FROM code_chunks WHERE file_path = ?"
604
- ).all(rel);
605
- if (oldChunks.length > 0) {
606
- for (const { id } of oldChunks) {
607
- this._deps.hnsw.remove(id);
608
- this._deps.vectorCache.delete(id);
609
- }
610
- this._deps.db.prepare("DELETE FROM code_chunks WHERE file_path = ?").run(rel);
611
- }
612
- const ext = path2.extname(filePath).toLowerCase();
613
- const language = SUPPORTED_EXTENSIONS[ext] ?? "text";
614
- const chunks = await this._chunker.chunk(rel, content, language);
615
- const embeddingTexts = chunks.map((chunk) => [
616
- `File: ${rel}`,
617
- chunk.name ? `${chunk.chunkType}: ${chunk.name}` : chunk.chunkType,
618
- chunk.content
619
- ].join("\n"));
620
- const vecs = await this._deps.embedding.embedBatch(embeddingTexts);
621
- for (let ci = 0; ci < chunks.length; ci++) {
622
- const chunk = chunks[ci];
623
- const result = this._deps.db.prepare(
624
- `INSERT INTO code_chunks (file_path, chunk_type, name, start_line, end_line, content, language, file_hash)
625
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
626
- ).run(rel, chunk.chunkType, chunk.name ?? null, chunk.startLine, chunk.endLine, chunk.content, language, hash);
627
- const id = Number(result.lastInsertRowid);
628
- this._deps.db.prepare(
629
- "INSERT INTO code_vectors (chunk_id, embedding) VALUES (?, ?)"
630
- ).run(id, Buffer.from(vecs[ci].buffer));
631
- this._deps.hnsw.add(vecs[ci], id);
632
- this._deps.vectorCache.set(id, vecs[ci]);
633
- totalChunks++;
634
- }
635
- this._deps.db.prepare(
636
- "INSERT OR REPLACE INTO indexed_files (file_path, file_hash) VALUES (?, ?)"
637
- ).run(rel, hash);
599
+ this._removeOldChunks(rel);
600
+ const chunkCount = await this._indexFile(filePath, rel, content, hash);
638
601
  indexed++;
602
+ totalChunks += chunkCount;
639
603
  }
640
604
  return { indexed, skipped, chunks: totalChunks };
641
605
  }
606
+ /** Remove old chunks and their HNSW vectors for a file. */
607
+ _removeOldChunks(relPath) {
608
+ const oldChunks = this._deps.db.prepare(
609
+ "SELECT id FROM code_chunks WHERE file_path = ?"
610
+ ).all(relPath);
611
+ if (oldChunks.length > 0) {
612
+ for (const { id } of oldChunks) {
613
+ this._deps.hnsw.remove(id);
614
+ this._deps.vectorCache.delete(id);
615
+ }
616
+ this._deps.db.prepare("DELETE FROM code_chunks WHERE file_path = ?").run(relPath);
617
+ }
618
+ }
619
+ /** Chunk, embed, and store a single file. Returns chunk count. */
620
+ async _indexFile(filePath, rel, content, hash) {
621
+ const ext = path2.extname(filePath).toLowerCase();
622
+ const language = SUPPORTED_EXTENSIONS[ext] ?? "text";
623
+ const chunks = await this._chunker.chunk(rel, content, language);
624
+ const embeddingTexts = chunks.map((chunk) => [
625
+ `File: ${rel}`,
626
+ chunk.name ? `${chunk.chunkType}: ${chunk.name}` : chunk.chunkType,
627
+ chunk.content
628
+ ].join("\n"));
629
+ const vecs = await this._deps.embedding.embedBatch(embeddingTexts);
630
+ for (let ci = 0; ci < chunks.length; ci++) {
631
+ const chunk = chunks[ci];
632
+ const result = this._deps.db.prepare(
633
+ `INSERT INTO code_chunks (file_path, chunk_type, name, start_line, end_line, content, language, file_hash)
634
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
635
+ ).run(rel, chunk.chunkType, chunk.name ?? null, chunk.startLine, chunk.endLine, chunk.content, language, hash);
636
+ const id = Number(result.lastInsertRowid);
637
+ this._deps.db.prepare(
638
+ "INSERT INTO code_vectors (chunk_id, embedding) VALUES (?, ?)"
639
+ ).run(id, Buffer.from(vecs[ci].buffer));
640
+ this._deps.hnsw.add(vecs[ci], id);
641
+ this._deps.vectorCache.set(id, vecs[ci]);
642
+ }
643
+ this._deps.db.prepare(
644
+ "INSERT OR REPLACE INTO indexed_files (file_path, file_hash) VALUES (?, ?)"
645
+ ).run(rel, hash);
646
+ return chunks.length;
647
+ }
642
648
  // ── File Walker ─────────────────────────────────
643
649
  _walkRepo(dir, files = []) {
644
650
  let entries;
@@ -687,10 +693,12 @@ var CodePlugin = class {
687
693
  __name(this, "CodePlugin");
688
694
  }
689
695
  name;
696
+ db;
690
697
  hnsw;
691
698
  indexer;
692
699
  vecCache = /* @__PURE__ */ new Map();
693
700
  async initialize(ctx) {
701
+ this.db = ctx.db;
694
702
  const shared = await ctx.getOrCreateSharedHnsw("code");
695
703
  this.hnsw = shared.hnsw;
696
704
  this.vecCache = shared.vecCache;
@@ -709,7 +717,11 @@ var CodePlugin = class {
709
717
  return this.indexer.index(options);
710
718
  }
711
719
  stats() {
712
- return { hnswSize: this.hnsw.size };
720
+ return {
721
+ files: this.db.prepare("SELECT COUNT(DISTINCT file_path) as c FROM code_chunks").get().c,
722
+ chunks: this.db.prepare("SELECT COUNT(*) as c FROM code_chunks").get().c,
723
+ hnswSize: this.hnsw.size
724
+ };
713
725
  }
714
726
  };
715
727
  function code(opts) {
@@ -728,4 +740,4 @@ export {
728
740
  CodeIndexer,
729
741
  code
730
742
  };
731
- //# sourceMappingURL=chunk-4DM3XWO6.js.map
743
+ //# sourceMappingURL=chunk-MGIFEPYZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/indexers/code/code-indexer.ts","../src/indexers/code/code-chunker.ts","../src/indexers/code/grammars.ts","../src/indexers/languages.ts","../src/indexers/code/code-plugin.ts"],"sourcesContent":["/**\n * BrainBank — Code Indexer\n * \n * Walks a repository, chunks source files semantically,\n * embeds each chunk, and stores in SQLite + HNSW.\n * Incremental: only re-indexes files that changed (by content hash).\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { CodeChunker } from './code-chunker.ts';\nimport { SUPPORTED_EXTENSIONS, IGNORE_DIRS, isIgnoredDir, isIgnoredFile } from '@/indexers/languages.ts';\nimport type { Database } from '@/db/database.ts';\nimport type { EmbeddingProvider, ProgressCallback, IndexResult } from '@/types.ts';\nimport type { HNSWIndex } from '@/providers/vector/hnsw-index.ts';\n\nexport interface CodeIndexerDeps {\n db: Database;\n hnsw: HNSWIndex;\n vectorCache: Map<number, Float32Array>;\n embedding: EmbeddingProvider;\n}\n\nexport interface CodeIndexOptions {\n forceReindex?: boolean;\n onProgress?: ProgressCallback;\n}\n\nexport class CodeIndexer {\n private _chunker = new CodeChunker();\n private _deps: CodeIndexerDeps;\n private _repoPath: string;\n private _maxFileSize: number;\n\n constructor(repoPath: string, deps: CodeIndexerDeps, maxFileSize: number = 512_000) {\n this._deps = deps;\n this._repoPath = repoPath;\n this._maxFileSize = maxFileSize;\n }\n\n /** Index all supported files. Skips unchanged files (same content hash). */\n async index(options: CodeIndexOptions = {}): Promise<IndexResult> {\n const { forceReindex = false, onProgress } = options;\n const files = this._walkRepo(this._repoPath);\n let indexed = 0, skipped = 0, totalChunks = 0;\n\n for (let i = 0; i < files.length; i++) {\n const filePath = files[i];\n const rel = path.relative(this._repoPath, filePath);\n onProgress?.(rel, i + 1, files.length);\n\n let content: string;\n try { content = fs.readFileSync(filePath, 'utf-8'); }\n catch { continue; }\n\n const hash = this._hash(content);\n const existing = this._deps.db.prepare(\n 'SELECT file_hash FROM indexed_files WHERE file_path = ?'\n ).get(rel) as any;\n\n if (!forceReindex && existing?.file_hash === hash) {\n skipped++;\n continue;\n }\n\n this._removeOldChunks(rel);\n const chunkCount = await this._indexFile(filePath, rel, content, hash);\n indexed++;\n totalChunks += chunkCount;\n }\n\n return { indexed, skipped, chunks: totalChunks };\n }\n\n /** Remove old chunks and their HNSW vectors for a file. */\n private _removeOldChunks(relPath: string): void {\n const oldChunks = this._deps.db.prepare(\n 'SELECT id FROM code_chunks WHERE file_path = ?'\n ).all(relPath) as any[];\n\n if (oldChunks.length > 0) {\n for (const { id } of oldChunks) {\n this._deps.hnsw.remove(id);\n this._deps.vectorCache.delete(id);\n }\n this._deps.db.prepare('DELETE FROM code_chunks WHERE file_path = ?').run(relPath);\n }\n }\n\n /** Chunk, embed, and store a single file. Returns chunk count. */\n private async _indexFile(\n filePath: string, rel: string, content: string, hash: string,\n ): Promise<number> {\n const ext = path.extname(filePath).toLowerCase();\n const language = SUPPORTED_EXTENSIONS[ext] ?? 'text';\n const chunks = await this._chunker.chunk(rel, content, language);\n\n const embeddingTexts = chunks.map(chunk => [\n `File: ${rel}`,\n chunk.name ? `${chunk.chunkType}: ${chunk.name}` : chunk.chunkType,\n chunk.content,\n ].join('\\n'));\n\n const vecs = await this._deps.embedding.embedBatch(embeddingTexts);\n\n for (let ci = 0; ci < chunks.length; ci++) {\n const chunk = chunks[ci];\n const result = this._deps.db.prepare(\n `INSERT INTO code_chunks (file_path, chunk_type, name, start_line, end_line, content, language, file_hash)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`\n ).run(rel, chunk.chunkType, chunk.name ?? null, chunk.startLine, chunk.endLine, chunk.content, language, hash);\n\n const id = Number(result.lastInsertRowid);\n this._deps.db.prepare(\n 'INSERT INTO code_vectors (chunk_id, embedding) VALUES (?, ?)'\n ).run(id, Buffer.from(vecs[ci].buffer));\n\n this._deps.hnsw.add(vecs[ci], id);\n this._deps.vectorCache.set(id, vecs[ci]);\n }\n\n this._deps.db.prepare(\n 'INSERT OR REPLACE INTO indexed_files (file_path, file_hash) VALUES (?, ?)'\n ).run(rel, hash);\n\n return chunks.length;\n }\n\n // ── File Walker ─────────────────────────────────\n\n private _walkRepo(dir: string, files: string[] = []): string[] {\n let entries: fs.Dirent[];\n try { entries = fs.readdirSync(dir, { withFileTypes: true }); }\n catch { return files; }\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n if (isIgnoredDir(entry.name)) continue;\n this._walkRepo(path.join(dir, entry.name), files);\n } else if (entry.isFile()) {\n if (isIgnoredFile(entry.name)) continue;\n const ext = path.extname(entry.name).toLowerCase();\n if (!(ext in SUPPORTED_EXTENSIONS)) continue;\n\n const full = path.join(dir, entry.name);\n try {\n if (fs.statSync(full).size <= this._maxFileSize) {\n files.push(full);\n }\n } catch {}\n }\n }\n return files;\n }\n\n // ── FNV-1a Hash ─────────────────────────────────\n\n private _hash(content: string): string {\n let h = 2166136261;\n for (let i = 0; i < content.length; i++) {\n h ^= content.charCodeAt(i);\n h = (h * 16777619) >>> 0;\n }\n return h.toString(16);\n }\n}\n","/**\n * BrainBank — Tree-Sitter Code Chunker\n * \n * AST-aware code splitting using native tree-sitter bindings.\n * Extracts semantic blocks (functions, classes, methods, interfaces)\n * from the AST. Falls back to sliding window for unsupported languages.\n */\n\nimport { createRequire } from 'node:module';\nimport type { CodeChunk } from '@/types.ts';\nimport { GRAMMARS, type LangGrammar } from './grammars.ts';\n\nconst require = createRequire(import.meta.url);\n\n// ── Configuration ───────────────────────────────────\n\nexport interface ChunkerConfig {\n /** Max lines per chunk. Default: 80 */\n maxLines?: number;\n /** Min lines for a detected block to be a chunk. Default: 3 */\n minLines?: number;\n /** Overlap between adjacent generic chunks. Default: 5 */\n overlap?: number;\n}\n\n// ── CodeChunker ─────────────────────────────────────\n\nexport class CodeChunker {\n private MAX: number;\n private MIN: number;\n private OVERLAP: number;\n private _parser: any = null;\n private _langCache = new Map<string, LangGrammar | null>();\n\n constructor(config: ChunkerConfig = {}) {\n this.MAX = config.maxLines ?? 80;\n this.MIN = config.minLines ?? 3;\n this.OVERLAP = config.overlap ?? 5;\n }\n\n /** Lazy-init tree-sitter parser. */\n private _ensureParser(): any {\n if (!this._parser) {\n try {\n const Parser = require('tree-sitter');\n this._parser = new Parser();\n } catch {\n this._parser = false; // Mark as unavailable\n }\n }\n return this._parser || null;\n }\n\n /** Load a language grammar (cached). */\n private _loadGrammar(language: string): LangGrammar | null {\n if (this._langCache.has(language)) return this._langCache.get(language)!;\n\n const factory = GRAMMARS[language];\n const grammar = factory ? factory() : null;\n this._langCache.set(language, grammar);\n return grammar;\n }\n\n /**\n * Split file content into semantic chunks using tree-sitter AST.\n * Falls back to sliding window if grammar isn't available.\n */\n async chunk(filePath: string, content: string, language: string): Promise<CodeChunk[]> {\n const lines = content.split('\\n');\n\n // Small file → single chunk\n if (lines.length <= this.MAX) {\n return [{\n filePath,\n chunkType: 'file',\n startLine: 1,\n endLine: lines.length,\n content: content.trim(),\n language,\n }];\n }\n\n // Try tree-sitter AST chunking\n const parser = this._ensureParser();\n const langConfig = this._loadGrammar(language);\n\n if (parser && langConfig) {\n try {\n parser.setLanguage(langConfig.grammar);\n const tree = parser.parse(content);\n const chunks = this._extractChunks(filePath, lines, tree.rootNode, langConfig, language);\n\n if (chunks.length > 0) {\n return chunks.filter(c => c.content.length > 20);\n }\n } catch {\n // Tree-sitter failed — fall through to generic\n }\n }\n\n // Fallback to sliding window\n return this._chunkGeneric(filePath, lines, language);\n }\n\n /** Walk AST and extract top-level semantic blocks. */\n private _extractChunks(\n filePath: string, lines: string[],\n rootNode: any, langConfig: LangGrammar, language: string,\n ): CodeChunk[] {\n const chunks: CodeChunk[] = [];\n const seen = new Set<string>();\n\n for (let i = 0; i < rootNode.childCount; i++) {\n const child = rootNode.child(i);\n this._processNode(filePath, lines, child, langConfig, language, chunks, seen);\n }\n\n return chunks;\n }\n\n /** Classify and process a single AST node. */\n private _processNode(\n filePath: string, lines: string[], node: any,\n langConfig: LangGrammar, language: string,\n chunks: CodeChunk[], seen: Set<string>,\n ): void {\n const type = node.type;\n\n // Handle export_statement: process what it wraps\n if (type === 'export_statement') {\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n const category = this._categorize(child.type, langConfig);\n if (category) {\n this._processDeclaration(filePath, lines, node, child, category, langConfig, language, chunks, seen);\n return;\n }\n }\n // Export with no recognized declaration — chunk the whole thing if big enough\n const nodeLines = node.endPosition.row - node.startPosition.row + 1;\n if (nodeLines >= this.MIN) {\n this._addChunk(filePath, lines, node, 'function', this._extractName(node), language, chunks, seen);\n }\n return;\n }\n\n // Python decorated definitions (@decorator + class/def)\n if (type === 'decorated_definition') {\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n const category = this._categorize(child.type, langConfig);\n if (category) {\n this._processDeclaration(filePath, lines, node, child, category, langConfig, language, chunks, seen);\n return;\n }\n }\n }\n\n // Direct match\n const category = this._categorize(type, langConfig);\n if (category) {\n this._processDeclaration(filePath, lines, node, node, category, langConfig, language, chunks, seen);\n }\n }\n\n /** Check which category a node type belongs to. */\n private _categorize(nodeType: string, langConfig: LangGrammar): string | null {\n for (const [category, types] of Object.entries(langConfig.nodeTypes)) {\n if (types && types.includes(nodeType)) return category;\n }\n return null;\n }\n\n /** Process a matched declaration: class → split by methods, else → chunk directly. */\n private _processDeclaration(\n filePath: string, lines: string[],\n outerNode: any, innerNode: any, category: string,\n langConfig: LangGrammar, language: string,\n chunks: CodeChunk[], seen: Set<string>,\n ): void {\n const nodeLines = outerNode.endPosition.row - outerNode.startPosition.row + 1;\n const name = this._extractName(innerNode);\n const chunkType = this._toChunkType(category);\n\n // Large class → split into methods\n if ((category === 'class' || category === 'struct' || category === 'impl') && nodeLines > this.MAX) {\n this._splitClassIntoMethods(filePath, lines, outerNode, innerNode, name, langConfig, language, chunks, seen);\n return;\n }\n\n // Large non-class → split with overlap\n if (nodeLines > this.MAX) {\n chunks.push(...this._splitLargeBlock(filePath, lines,\n outerNode.startPosition.row, outerNode.endPosition.row,\n name, chunkType, language));\n return;\n }\n\n // Normal-sized node\n if (nodeLines >= this.MIN) {\n this._addChunk(filePath, lines, outerNode, chunkType, name, language, chunks, seen);\n }\n }\n\n /** Split a large class into individual method chunks. */\n private _splitClassIntoMethods(\n filePath: string, lines: string[],\n outerNode: any, classNode: any, className: string,\n langConfig: LangGrammar, language: string,\n chunks: CodeChunk[], seen: Set<string>,\n ): void {\n // Find class body\n const body = this._findClassBody(classNode);\n if (!body) {\n chunks.push(...this._splitLargeBlock(filePath, lines,\n outerNode.startPosition.row, outerNode.endPosition.row,\n className, 'class', language));\n return;\n }\n\n // Get method node types\n const methodTypes = new Set([\n ...(langConfig.nodeTypes.function || []),\n ...(langConfig.nodeTypes.method || []),\n ]);\n\n let methodsFound = false;\n for (let i = 0; i < body.childCount; i++) {\n const child = body.child(i);\n let methodNode = child;\n\n // Decorated methods\n if (child.type === 'decorated_definition') {\n for (let j = 0; j < child.childCount; j++) {\n if (methodTypes.has(child.child(j).type)) {\n methodNode = child.child(j);\n break;\n }\n }\n }\n\n if (methodTypes.has(methodNode.type) || methodTypes.has(child.type)) {\n const methodName = this._extractName(methodNode);\n const nodeToChunk = child.type === 'decorated_definition' ? child : methodNode;\n const methodLineCount = nodeToChunk.endPosition.row - nodeToChunk.startPosition.row + 1;\n\n if (methodLineCount >= this.MIN) {\n methodsFound = true;\n const fullName = `${className}.${methodName}`;\n\n if (methodLineCount > this.MAX) {\n chunks.push(...this._splitLargeBlock(filePath, lines,\n nodeToChunk.startPosition.row, nodeToChunk.endPosition.row,\n fullName, 'method', language));\n } else {\n this._addChunk(filePath, lines, nodeToChunk, 'method', fullName, language, chunks, seen);\n }\n }\n }\n }\n\n // Fallback: no methods found → split the whole class\n if (!methodsFound) {\n chunks.push(...this._splitLargeBlock(filePath, lines,\n outerNode.startPosition.row, outerNode.endPosition.row,\n className, 'class', language));\n }\n }\n\n /** Find the class body node. */\n private _findClassBody(classNode: any): any | null {\n const bodyTypes = ['class_body', 'block', 'declaration_list', 'body'];\n for (let i = 0; i < classNode.childCount; i++) {\n const child = classNode.child(i);\n if (bodyTypes.includes(child.type)) return child;\n }\n return null;\n }\n\n /** Extract name from an AST node. */\n private _extractName(node: any): string {\n // Try childForFieldName('name')\n if (typeof node.childForFieldName === 'function') {\n const nameNode = node.childForFieldName('name');\n if (nameNode) return nameNode.text;\n }\n // Try identifier children\n for (let i = 0; i < node.namedChildCount; i++) {\n const child = node.namedChild(i);\n if (['identifier', 'type_identifier', 'property_identifier'].includes(child.type)) {\n return child.text;\n }\n }\n // For variable declarations, dig into declarators\n if (node.type === 'lexical_declaration' || node.type === 'variable_declaration') {\n for (let i = 0; i < node.namedChildCount; i++) {\n const child = node.namedChild(i);\n if (child.type === 'variable_declarator') {\n const nameNode = child.childForFieldName('name');\n if (nameNode) return nameNode.text;\n }\n }\n }\n return 'anonymous';\n }\n\n /** Map category to chunk type. */\n private _toChunkType(category: string): string {\n if (category === 'class' || category === 'struct' || category === 'impl') return 'class';\n if (category === 'interface') return 'interface';\n if (category === 'variable') return 'function';\n return category;\n }\n\n /** Add a node as a chunk, avoiding duplicates. */\n private _addChunk(\n filePath: string, lines: string[], node: any,\n chunkType: string, name: string, language: string,\n chunks: CodeChunk[], seen: Set<string>,\n ): void {\n const start = node.startPosition.row;\n const end = node.endPosition.row;\n const key = `${start}-${end}`;\n if (seen.has(key)) return;\n seen.add(key);\n\n const content = lines.slice(start, end + 1).join('\\n').trim();\n if (content.length <= 20) return;\n\n chunks.push({\n filePath,\n chunkType,\n name,\n startLine: start + 1,\n endLine: end + 1,\n content,\n language,\n });\n }\n\n // ── Fallback: Generic sliding window ────────────\n\n private _chunkGeneric(filePath: string, lines: string[], language: string): CodeChunk[] {\n const chunks: CodeChunk[] = [];\n const step = Math.max(this.MAX - this.OVERLAP, 1);\n\n for (let s = 0; s < lines.length; s += step) {\n const e = Math.min(s + this.MAX, lines.length);\n const content = lines.slice(s, e).join('\\n').trim();\n if (content.length > 20) {\n chunks.push({\n filePath,\n chunkType: 'block',\n startLine: s + 1,\n endLine: e,\n content,\n language,\n });\n }\n if (e >= lines.length) break;\n }\n\n return chunks;\n }\n\n /** Split a large block into overlapping sub-chunks. */\n private _splitLargeBlock(\n filePath: string, lines: string[],\n start: number, end: number,\n name: string, type: string, language: string,\n ): CodeChunk[] {\n const chunks: CodeChunk[] = [];\n const step = Math.max(this.MAX - this.OVERLAP, 1);\n let part = 1;\n\n for (let s = start; s <= end; s += step) {\n const e = Math.min(s + this.MAX, end + 1);\n const content = lines.slice(s, e).join('\\n').trim();\n if (content.length > 20) {\n chunks.push({\n filePath,\n chunkType: type,\n name: `${name} (part ${part++})`,\n startLine: s + 1,\n endLine: e,\n content,\n language,\n });\n }\n if (e > end) break;\n }\n\n return chunks;\n }\n}\n","/**\n * BrainBank — Tree-Sitter Grammar Registry\n *\n * Maps language names to their tree-sitter grammar packages\n * and the AST node types that represent semantic blocks.\n */\n\nimport { createRequire } from 'node:module';\n\nconst require = createRequire(import.meta.url);\n\n// ── Types ───────────────────────────────────────────\n\nexport interface LangGrammar {\n grammar: any;\n nodeTypes: {\n class?: string[];\n function?: string[];\n interface?: string[];\n variable?: string[];\n method?: string[];\n struct?: string[];\n impl?: string[];\n };\n}\n\n// ── Loader ──────────────────────────────────────────\n\n/** Try to require a grammar, return null if not installed. */\nfunction tryGrammar(pkg: string, nodeTypes: LangGrammar['nodeTypes'], accessor?: string): () => LangGrammar | null {\n return () => {\n try {\n const mod = require(pkg);\n return { grammar: accessor ? mod[accessor] : mod, nodeTypes };\n } catch { return null; }\n };\n}\n\n// ── Grammar Table ───────────────────────────────────\n\nexport const GRAMMARS: Record<string, () => LangGrammar | null> = {\n // ── Web ──────────────────────────────────────────\n typescript: tryGrammar('tree-sitter-typescript', {\n class: ['class_declaration'],\n interface: ['interface_declaration', 'type_alias_declaration'],\n function: ['function_declaration', 'method_definition'],\n variable: ['lexical_declaration'],\n }, 'typescript'),\n javascript: tryGrammar('tree-sitter-javascript', {\n class: ['class_declaration'],\n function: ['function_declaration', 'method_definition'],\n variable: ['lexical_declaration'],\n }),\n html: tryGrammar('tree-sitter-html', {}),\n css: tryGrammar('tree-sitter-css', {}),\n\n // ── Systems ──────────────────────────────────────\n go: tryGrammar('tree-sitter-go', {\n function: ['function_declaration', 'method_declaration'],\n struct: ['type_declaration'],\n }),\n rust: tryGrammar('tree-sitter-rust', {\n function: ['function_item'],\n struct: ['struct_item'],\n impl: ['impl_item'],\n }),\n c: tryGrammar('tree-sitter-c', {\n function: ['function_definition'],\n struct: ['struct_specifier'],\n }),\n cpp: tryGrammar('tree-sitter-cpp', {\n class: ['class_specifier'],\n function: ['function_definition'],\n }),\n swift: tryGrammar('tree-sitter-swift', {\n class: ['class_declaration'],\n function: ['function_declaration'],\n struct: ['struct_declaration'],\n }),\n\n // ── JVM ──────────────────────────────────────────\n java: tryGrammar('tree-sitter-java', {\n class: ['class_declaration'],\n interface: ['interface_declaration'],\n method: ['method_declaration'],\n }),\n kotlin: tryGrammar('tree-sitter-kotlin', {\n class: ['class_declaration'],\n function: ['function_declaration'],\n }),\n scala: tryGrammar('tree-sitter-scala', {\n class: ['class_definition'],\n function: ['function_definition'],\n }),\n\n // ── Scripting ────────────────────────────────────\n python: tryGrammar('tree-sitter-python', {\n class: ['class_definition'],\n function: ['function_definition'],\n }),\n ruby: tryGrammar('tree-sitter-ruby', {\n class: ['class'],\n method: ['method', 'singleton_method'],\n }),\n php: tryGrammar('tree-sitter-php', {\n class: ['class_declaration'],\n function: ['function_definition', 'method_declaration'],\n }, 'php'),\n lua: tryGrammar('tree-sitter-lua', {\n function: ['function_declaration'],\n }),\n bash: tryGrammar('tree-sitter-bash', {\n function: ['function_definition'],\n }),\n elixir: tryGrammar('tree-sitter-elixir', {\n function: ['call'], // defmodule, def, defp\n }),\n\n // ── .NET ─────────────────────────────────────────\n c_sharp: tryGrammar('tree-sitter-c-sharp', {\n class: ['class_declaration'],\n interface: ['interface_declaration'],\n method: ['method_declaration'],\n }),\n};\n","/**\n * BrainBank — Language Registry\n * \n * Supported file extensions, language mappings, and ignore lists.\n * Controls which files get indexed and how they're chunked.\n */\n\n// ── Supported Extensions ────────────────────────────\n\nexport const SUPPORTED_EXTENSIONS: Record<string, string> = {\n // TypeScript / JavaScript\n '.ts': 'typescript',\n '.tsx': 'typescript',\n '.js': 'javascript',\n '.jsx': 'javascript',\n '.mjs': 'javascript',\n '.cjs': 'javascript',\n\n // Systems\n '.go': 'go',\n '.rs': 'rust',\n '.cpp': 'cpp',\n '.cc': 'cpp',\n '.c': 'c',\n '.h': 'c',\n '.hpp': 'cpp',\n\n // JVM\n '.java': 'java',\n '.kt': 'kotlin',\n '.scala': 'scala',\n\n // Scripting\n '.py': 'python',\n '.rb': 'ruby',\n '.php': 'php',\n '.lua': 'lua',\n '.sh': 'bash',\n '.bash': 'bash',\n '.zsh': 'bash',\n\n // Web\n '.html': 'html',\n '.css': 'css',\n '.scss': 'scss',\n '.less': 'less',\n '.svelte': 'svelte',\n '.vue': 'vue',\n\n // Data / Config\n '.json': 'json',\n '.yaml': 'yaml',\n '.yml': 'yaml',\n '.toml': 'toml',\n '.xml': 'xml',\n '.graphql': 'graphql',\n '.gql': 'graphql',\n\n // Docs\n '.md': 'markdown',\n '.mdx': 'markdown',\n\n // Database\n '.sql': 'sql',\n '.prisma': 'prisma',\n\n // Other\n '.swift': 'swift',\n '.dart': 'dart',\n '.r': 'r',\n '.ex': 'elixir',\n '.exs': 'elixir',\n '.erl': 'erlang',\n '.zig': 'zig',\n};\n\n// ── Ignore Directories ──────────────────────────────\n\nexport const IGNORE_DIRS = new Set([\n // Package managers\n 'node_modules',\n 'bower_components',\n '.pnpm',\n\n // Build output\n 'dist',\n 'build',\n 'out',\n '.next',\n '.nuxt',\n '.output',\n '.svelte-kit',\n\n // Auto-generated code\n 'generated',\n 'sdk',\n 'openapi',\n\n // Version control\n '.git',\n '.hg',\n '.svn',\n\n // IDE / Editor\n '.idea',\n '.vscode',\n\n // Runtime / Cache\n '__pycache__',\n '.pytest_cache',\n 'venv',\n '.venv',\n '.env',\n '.tox',\n\n // Coverage / Test artifacts\n 'coverage',\n '.nyc_output',\n 'htmlcov',\n\n // Compiled\n 'target', // Rust, Java\n '.cargo',\n 'vendor', // Go, PHP\n\n // Database (auto-generated migrations, dumps, seeds)\n 'migrations',\n 'db_dumps',\n 'seeds',\n\n // AI / Model cache\n '.model-cache',\n '.brainbank',\n\n // OS\n '.DS_Store',\n]);\n\n// ── Ignore Files ────────────────────────────────────\n\nexport const IGNORE_FILES = new Set([\n 'package-lock.json',\n 'yarn.lock',\n 'pnpm-lock.yaml',\n 'bun.lockb',\n 'Cargo.lock',\n 'Gemfile.lock',\n 'poetry.lock',\n 'composer.lock',\n 'go.sum',\n]);\n\n// ── Helpers ─────────────────────────────────────────\n\nimport path from 'node:path';\n\n/** Check if a file extension is supported for indexing. */\nexport function isSupported(filePath: string): boolean {\n const ext = path.extname(filePath).toLowerCase();\n return ext in SUPPORTED_EXTENSIONS;\n}\n\n/** Get the language name for a file. Returns undefined if not supported. */\nexport function getLanguage(filePath: string): string | undefined {\n const ext = path.extname(filePath).toLowerCase();\n return SUPPORTED_EXTENSIONS[ext];\n}\n\n/** Check if a directory name should be ignored. */\nexport function isIgnoredDir(dirName: string): boolean {\n return IGNORE_DIRS.has(dirName);\n}\n\n/** Check if a filename should be ignored. */\nexport function isIgnoredFile(fileName: string): boolean {\n return IGNORE_FILES.has(fileName);\n}\n","/**\n * BrainBank — Code Module\n * \n * Language-aware code indexing for 30+ languages.\n * \n * import { BrainBank } from 'brainbank';\n * import { code } from 'brainbank/code';\n * \n * const brain = new BrainBank().use(code({ repoPath: '.' }));\n * \n * // Multi-repo: namespace to avoid key collisions\n * brain\n * .use(code({ repoPath: './frontend', name: 'code:frontend' }))\n * .use(code({ repoPath: './backend', name: 'code:backend' }));\n */\n\nimport type { Indexer, IndexerContext } from '@/indexers/base.ts';\nimport type { HNSWIndex } from '@/providers/vector/hnsw-index.ts';\nimport type { Database } from '@/db/database.ts';\nimport { CodeIndexer } from './code-indexer.ts';\nimport type { IndexResult, ProgressCallback } from '@/types.ts';\n\nexport interface CodePluginOptions {\n /** Repository path to index. Default: '.' */\n repoPath?: string;\n /** Maximum file size in bytes. Default: from config */\n maxFileSize?: number;\n /** Custom indexer name for multi-repo (e.g. 'code:frontend'). Default: 'code' */\n name?: string;\n}\n\nclass CodePlugin implements Indexer {\n readonly name: string;\n private db!: Database;\n hnsw!: HNSWIndex;\n indexer!: CodeIndexer;\n vecCache = new Map<number, Float32Array>();\n\n constructor(private opts: CodePluginOptions = {}) {\n this.name = opts.name ?? 'code';\n }\n\n async initialize(ctx: IndexerContext): Promise<void> {\n this.db = ctx.db;\n // Use shared HNSW so all code indexers (code, code:frontend, etc.) share one index\n const shared = await ctx.getOrCreateSharedHnsw('code');\n this.hnsw = shared.hnsw;\n this.vecCache = shared.vecCache;\n\n // Only load vectors once (first code indexer to initialize)\n if (shared.isNew) {\n ctx.loadVectors('code_vectors', 'chunk_id', this.hnsw, this.vecCache);\n }\n\n const repoPath = this.opts.repoPath ?? ctx.config.repoPath;\n this.indexer = new CodeIndexer(repoPath, {\n db: ctx.db,\n hnsw: this.hnsw,\n vectorCache: this.vecCache,\n embedding: ctx.embedding,\n }, this.opts.maxFileSize ?? ctx.config.maxFileSize);\n }\n\n async index(options: {\n forceReindex?: boolean;\n onProgress?: ProgressCallback;\n } = {}): Promise<IndexResult> {\n return this.indexer.index(options);\n }\n\n stats(): Record<string, number> {\n return {\n files: (this.db.prepare('SELECT COUNT(DISTINCT file_path) as c FROM code_chunks').get() as { c: number }).c,\n chunks: (this.db.prepare('SELECT COUNT(*) as c FROM code_chunks').get() as { c: number }).c,\n hnswSize: this.hnsw.size,\n };\n }\n}\n\n/** Create a code indexing plugin. */\nexport function code(opts?: CodePluginOptions): Indexer {\n return new CodePlugin(opts);\n}\n"],"mappings":"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","names":["path","createRequire","require","require","createRequire","category","path"]}