brainbank 0.5.0 → 0.7.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 (46) hide show
  1. package/README.md +233 -126
  2. package/dist/{base-DZWtdgIf.d.ts → base-3SNc_CeY.d.ts} +24 -24
  3. package/dist/chunk-424UFCY7.js +78 -0
  4. package/dist/chunk-424UFCY7.js.map +1 -0
  5. package/dist/{chunk-HNPABX7L.js → chunk-7EZR47JV.js} +1 -1
  6. package/dist/{chunk-HNPABX7L.js.map → chunk-7EZR47JV.js.map} +1 -1
  7. package/dist/chunk-B77KABWH.js +41 -0
  8. package/dist/chunk-B77KABWH.js.map +1 -0
  9. package/dist/{chunk-MY36UPPQ.js → chunk-DI3H6JVZ.js} +357 -379
  10. package/dist/chunk-DI3H6JVZ.js.map +1 -0
  11. package/dist/{chunk-DDECTPRM.js → chunk-FGL32LUJ.js} +20 -14
  12. package/dist/chunk-FGL32LUJ.js.map +1 -0
  13. package/dist/{chunk-TTXVJFAE.js → chunk-JRSKWF6K.js} +4 -3
  14. package/dist/{chunk-TTXVJFAE.js.map → chunk-JRSKWF6K.js.map} +1 -1
  15. package/dist/{chunk-YRGUIRN5.js → chunk-VQ27YUHH.js} +18 -14
  16. package/dist/chunk-VQ27YUHH.js.map +1 -0
  17. package/dist/{chunk-BNV43SEF.js → chunk-VVXYZIIB.js} +5 -5
  18. package/dist/chunk-VVXYZIIB.js.map +1 -0
  19. package/dist/chunk-ZNLN2VWV.js +110 -0
  20. package/dist/chunk-ZNLN2VWV.js.map +1 -0
  21. package/dist/cli.js +102 -45
  22. package/dist/cli.js.map +1 -1
  23. package/dist/code.d.ts +4 -2
  24. package/dist/code.js +1 -1
  25. package/dist/docs.d.ts +7 -3
  26. package/dist/docs.js +1 -1
  27. package/dist/git.d.ts +4 -2
  28. package/dist/git.js +1 -1
  29. package/dist/index.d.ts +77 -17
  30. package/dist/index.js +21 -9
  31. package/dist/index.js.map +1 -1
  32. package/dist/local-embedding-ZIMTK6PU.js +8 -0
  33. package/dist/local-embedding-ZIMTK6PU.js.map +1 -0
  34. package/dist/memory.d.ts +2 -2
  35. package/dist/memory.js +1 -1
  36. package/dist/notes.d.ts +2 -2
  37. package/dist/notes.js +1 -1
  38. package/dist/qwen3-reranker-3MHEENT5.js +8 -0
  39. package/dist/qwen3-reranker-3MHEENT5.js.map +1 -0
  40. package/dist/resolve-CUJWY6HP.js +10 -0
  41. package/dist/resolve-CUJWY6HP.js.map +1 -0
  42. package/package.json +10 -9
  43. package/dist/chunk-BNV43SEF.js.map +0 -1
  44. package/dist/chunk-DDECTPRM.js.map +0 -1
  45. package/dist/chunk-MY36UPPQ.js.map +0 -1
  46. package/dist/chunk-YRGUIRN5.js.map +0 -1
package/dist/index.js CHANGED
@@ -4,15 +4,21 @@ import {
4
4
  import {
5
5
  PerplexityEmbedding
6
6
  } from "./chunk-N2OJRXSB.js";
7
+ import {
8
+ LocalEmbedding
9
+ } from "./chunk-424UFCY7.js";
10
+ import {
11
+ Qwen3Reranker
12
+ } from "./chunk-ZNLN2VWV.js";
7
13
  import {
8
14
  NoteStore,
9
15
  notes
10
- } from "./chunk-HNPABX7L.js";
16
+ } from "./chunk-7EZR47JV.js";
11
17
  import {
12
18
  Consolidator,
13
19
  PatternStore,
14
20
  memory
15
- } from "./chunk-BNV43SEF.js";
21
+ } from "./chunk-VVXYZIIB.js";
16
22
  import {
17
23
  BrainBank,
18
24
  Collection,
@@ -20,29 +26,32 @@ import {
20
26
  DEFAULTS,
21
27
  HNSWIndex,
22
28
  KeywordSearch,
23
- LocalEmbedding,
24
29
  VectorSearch,
25
30
  resolveConfig,
26
31
  searchMMR
27
- } from "./chunk-MY36UPPQ.js";
32
+ } from "./chunk-DI3H6JVZ.js";
33
+ import {
34
+ providerKey,
35
+ resolveEmbedding
36
+ } from "./chunk-B77KABWH.js";
28
37
  import {
29
38
  CodeChunker,
30
- CodeIndexer,
39
+ CodeWalker,
31
40
  IGNORE_DIRS,
32
41
  SUPPORTED_EXTENSIONS,
33
42
  code,
34
43
  getLanguage,
35
44
  isSupported
36
- } from "./chunk-DDECTPRM.js";
45
+ } from "./chunk-FGL32LUJ.js";
37
46
  import {
38
47
  CoEditAnalyzer,
39
48
  GitIndexer,
40
49
  git
41
- } from "./chunk-TTXVJFAE.js";
50
+ } from "./chunk-JRSKWF6K.js";
42
51
  import {
43
52
  DocsIndexer,
44
53
  docs
45
- } from "./chunk-YRGUIRN5.js";
54
+ } from "./chunk-VQ27YUHH.js";
46
55
  import {
47
56
  reciprocalRankFusion
48
57
  } from "./chunk-YOLKSYWK.js";
@@ -98,7 +107,7 @@ export {
98
107
  BrainBank,
99
108
  CoEditAnalyzer,
100
109
  CodeChunker,
101
- CodeIndexer,
110
+ CodeWalker,
102
111
  Collection,
103
112
  Consolidator,
104
113
  ContextBuilder,
@@ -115,6 +124,7 @@ export {
115
124
  PatternStore,
116
125
  PerplexityContextEmbedding,
117
126
  PerplexityEmbedding,
127
+ Qwen3Reranker,
118
128
  SUPPORTED_EXTENSIONS,
119
129
  VectorSearch,
120
130
  code,
@@ -132,8 +142,10 @@ export {
132
142
  memory,
133
143
  normalize,
134
144
  notes,
145
+ providerKey,
135
146
  reciprocalRankFusion,
136
147
  resolveConfig,
148
+ resolveEmbedding,
137
149
  searchMMR
138
150
  };
139
151
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * BrainBank — Type Definitions\n * \n * All interfaces and types for the semantic knowledge bank.\n */\n\n\n\n// ── Configuration ───────────────────────────────────\n\nexport interface BrainBankConfig {\n /** Root path of the repository to index. Default: '.' */\n repoPath?: string;\n /** SQLite database path. Default: '.brainbank/brainbank.db' */\n dbPath?: string;\n\n /** Max git commits to index. Default: 500 */\n gitDepth?: number;\n /** Max file size in bytes to index. Default: 512_000 (500KB) */\n maxFileSize?: number;\n /** Max diff bytes per commit. Default: 8192 */\n maxDiffBytes?: number;\n /** HNSW M parameter (connections per node). Default: 16 */\n hnswM?: number;\n /** HNSW efConstruction (build-time candidates). Default: 200 */\n hnswEfConstruction?: number;\n /** HNSW efSearch (query-time candidates). Default: 50 */\n hnswEfSearch?: number;\n /** Embedding dimensions. Default: 384 */\n embeddingDims?: number;\n /** Max HNSW elements. Default: 2_000_000 */\n maxElements?: number;\n /** Custom embedding provider (default: local WASM model) */\n embeddingProvider?: EmbeddingProvider;\n /** Optional reranker for improved search quality */\n reranker?: Reranker;\n}\n\nexport interface ResolvedConfig {\n repoPath: string;\n dbPath: string;\n gitDepth: number;\n maxFileSize: number;\n maxDiffBytes: number;\n hnswM: number;\n hnswEfConstruction: number;\n hnswEfSearch: number;\n embeddingDims: number;\n maxElements: number;\n embeddingProvider?: EmbeddingProvider;\n reranker?: Reranker;\n}\n\n// ── Embedding Provider ──────────────────────────────\n\nexport interface EmbeddingProvider {\n /** Vector dimensions produced by this provider. */\n readonly dims: number;\n /** Embed a single text string. */\n embed(text: string): Promise<Float32Array>;\n /** Embed multiple texts (batch). */\n embedBatch(texts: string[]): Promise<Float32Array[]>;\n /** Release resources. */\n close(): Promise<void>;\n}\n\n// ── Reranker ────────────────────────────────────────\n\nexport interface Reranker {\n /**\n * Score each document's relevance to the query.\n * @param query - The search query\n * @param documents - Document contents to rank\n * @returns Relevance scores (0.0 - 1.0) in same order as documents\n */\n rank(query: string, documents: string[]): Promise<number[]>;\n /** Release resources (e.g. unload model). */\n close?(): Promise<void>;\n}\n\n// ── Vector Index ────────────────────────────────────\n\nexport interface SearchHit {\n id: number;\n score: number;\n}\n\nexport interface VectorIndex {\n /** Initialize the index. Must be called before add/search. */\n init(): Promise<this>;\n /** Add a vector with an integer ID. Idempotent: duplicate IDs are skipped. */\n add(vector: Float32Array, id: number): void;\n /** Mark a vector as deleted so it no longer appears in searches. */\n remove(id: number): void;\n /** Search for k nearest neighbors. */\n search(query: Float32Array, k: number): SearchHit[];\n /** Clear all vectors and reset to empty state. */\n reinit(): void;\n /** Number of vectors in the index. */\n readonly size: number;\n}\n\n// ── Code Chunking ───────────────────────────────────\n\nexport interface CodeChunk {\n /** Auto-incremented DB id (set after insert) */\n id?: number;\n /** Relative file path from repo root */\n filePath: string;\n /** Chunk type: 'file' | 'function' | 'class' | 'block' */\n chunkType: string;\n /** Function/class name (if detected) */\n name?: string;\n /** Start line (1-indexed) */\n startLine: number;\n /** End line (1-indexed, inclusive) */\n endLine: number;\n /** Raw content of the chunk */\n content: string;\n /** Language identifier */\n language: string;\n}\n\n// ── Git ─────────────────────────────────────────────\n\nexport interface GitCommitRecord {\n id?: number;\n hash: string;\n shortHash: string;\n message: string;\n author: string;\n date: string;\n timestamp: number;\n filesChanged: string[];\n diff?: string;\n additions: number;\n deletions: number;\n isMerge: boolean;\n}\n\n// ── Agent Learning ─────────────────────────────────────────\n\nexport interface LearningPattern {\n id?: number;\n /** Category (e.g. 'api', 'refactor', 'debug') */\n taskType: string;\n /** What was the task */\n task: string;\n /** How it was approached */\n approach: string;\n /** What happened */\n outcome?: string;\n /** 0.0 – 1.0 */\n successRate: number;\n /** Lessons learned */\n critique?: string;\n /** Tokens consumed (optional tracking) */\n tokensUsed?: number;\n /** Latency in ms (optional tracking) */\n latencyMs?: number;\n}\n\nexport interface DistilledStrategy {\n taskType: string;\n strategy: string;\n confidence: number;\n updatedAt: number;\n}\n\n// ── Search Results ──────────────────────────────────\n\nexport type SearchResultType = 'code' | 'commit' | 'pattern' | 'document' | 'collection';\n\n// Typed metadata per result type\n\nexport interface CodeResultMetadata {\n chunkType: string;\n name?: string;\n startLine: number;\n endLine: number;\n language: string;\n searchType?: string;\n}\n\nexport interface CommitResultMetadata {\n hash: string;\n shortHash: string;\n author: string;\n date: string;\n files: string[];\n additions?: number;\n deletions?: number;\n diff?: string;\n searchType?: string;\n}\n\nexport interface PatternResultMetadata {\n taskType: string;\n task: string;\n outcome?: string;\n successRate: number;\n critique?: string;\n searchType?: string;\n}\n\nexport interface DocumentResultMetadata {\n collection?: string;\n title?: string;\n seq?: number;\n path?: string;\n searchType?: string;\n /** Internal chunk ID used by hybrid search to map fused results. */\n chunkId?: number;\n}\n\n// Discriminated union\n\nexport interface CodeResult {\n type: 'code';\n score: number;\n filePath: string;\n content: string;\n context?: string;\n metadata: CodeResultMetadata;\n}\n\nexport interface CommitResult {\n type: 'commit';\n score: number;\n filePath?: string;\n content: string;\n context?: string;\n metadata: CommitResultMetadata;\n}\n\nexport interface PatternResult {\n type: 'pattern';\n score: number;\n filePath?: string;\n content: string;\n context?: string;\n metadata: PatternResultMetadata;\n}\n\nexport interface DocumentResult {\n type: 'document';\n score: number;\n filePath: string;\n content: string;\n context?: string;\n metadata: DocumentResultMetadata;\n}\n\nexport interface CollectionResult {\n type: 'collection';\n score: number;\n filePath?: string;\n content: string;\n context?: string;\n metadata: Record<string, any>;\n}\n\nexport type SearchResult = CodeResult | CommitResult | PatternResult | DocumentResult | CollectionResult;\n\n// ── Type Guards ──────────────────────────────────────\n\n/** Narrow a SearchResult to CodeResult. */\nexport function isCodeResult(r: SearchResult): r is CodeResult {\n return r.type === 'code';\n}\n/** Narrow a SearchResult to CommitResult. */\nexport function isCommitResult(r: SearchResult): r is CommitResult {\n return r.type === 'commit';\n}\n/** Narrow a SearchResult to DocumentResult. */\nexport function isDocumentResult(r: SearchResult): r is DocumentResult {\n return r.type === 'document';\n}\n/** Narrow a SearchResult to PatternResult. */\nexport function isPatternResult(r: SearchResult): r is PatternResult {\n return r.type === 'pattern';\n}\n/** Narrow a SearchResult to CollectionResult. */\nexport function isCollectionResult(r: SearchResult): r is CollectionResult {\n return r.type === 'collection';\n}\n\n// ── Match Helper ─────────────────────────────────────\n\ntype MatchHandlers<T> = {\n code?: (r: CodeResult) => T;\n commit?: (r: CommitResult) => T;\n pattern?: (r: PatternResult) => T;\n document?: (r: DocumentResult) => T;\n collection?: (r: CollectionResult) => T;\n _?: (r: SearchResult) => T;\n};\n\n/**\n * Pattern-match on SearchResult type. Calls the matching handler\n * or the `_` fallback. Returns undefined if no handler matches.\n */\nexport function matchResult<T>(\n result: SearchResult,\n handlers: MatchHandlers<T>,\n): T | undefined {\n switch (result.type) {\n case 'code': return (handlers.code ?? handlers._)?.(result);\n case 'commit': return (handlers.commit ?? handlers._)?.(result);\n case 'pattern': return (handlers.pattern ?? handlers._)?.(result);\n case 'document': return (handlers.document ?? handlers._)?.(result);\n case 'collection': return (handlers.collection ?? handlers._)?.(result);\n }\n}\n\n// ── Context Builder ─────────────────────────────────\n\nexport interface ContextOptions {\n /** Max code chunks to include. Default: 6 */\n codeResults?: number;\n /** Max git commits to include. Default: 5 */\n gitResults?: number;\n /** Max memory patterns to include. Default: 4 */\n patternResults?: number;\n /** Files the agent is about to modify (improves co-edit suggestions) */\n affectedFiles?: string[];\n /** Minimum similarity score threshold. Default: 0.25 */\n minScore?: number;\n /** Use MMR for diversity. Default: true */\n useMMR?: boolean;\n /** MMR lambda (0 = diversity, 1 = relevance). Default: 0.7 */\n mmrLambda?: number;\n}\n\n// ── Document Collections ────────────────────────────\n\nexport interface DocumentCollection {\n /** Collection name (e.g. 'notes', 'docs') */\n name: string;\n /** Directory path to index */\n path: string;\n /** Glob pattern for files (default: all markdown) */\n pattern?: string;\n /** Glob patterns to ignore */\n ignore?: string[];\n /** Context description for this collection */\n context?: string;\n}\n\nexport interface DocChunk {\n id?: number;\n /** Collection name */\n collection: string;\n /** Relative file path within the collection */\n filePath: string;\n /** Document title (first heading or filename) */\n title: string;\n /** Chunk content */\n content: string;\n /** Chunk sequence within the document (0, 1, 2...) */\n seq: number;\n /** Character position in original document */\n pos: number;\n /** Content hash for incremental updates */\n contentHash: string;\n}\n\n// ── Stats ───────────────────────────────────────────\n\nexport interface IndexStats {\n code?: {\n files: number;\n chunks: number;\n hnswSize: number;\n };\n git?: {\n commits: number;\n filesTracked: number;\n coEdits: number;\n hnswSize: number;\n };\n memory?: {\n patterns: number;\n avgSuccess: number;\n hnswSize: number;\n };\n documents?: {\n collections: number;\n documents: number;\n chunks: number;\n hnswSize: number;\n };\n notes?: {\n total: number;\n short: number;\n long: number;\n };\n}\n\n// ── Index Progress ──────────────────────────────────\n\n/** File-level progress (used by indexers). */\nexport type ProgressCallback = (file: string, current: number, total: number) => void;\n\n/** Stage-level progress (used by BrainBank.index() orchestrator). */\nexport type StageProgressCallback = (stage: string, message: string) => void;\n\nexport interface IndexResult {\n indexed: number;\n skipped: number;\n chunks?: number;\n}\n\n// ── Co-Edits ────────────────────────────────────────\n\nexport interface CoEditSuggestion {\n file: string;\n count: number;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2QO,SAAS,aAAa,GAAkC;AAC3D,SAAO,EAAE,SAAS;AACtB;AAFgB;AAIT,SAAS,eAAe,GAAoC;AAC/D,SAAO,EAAE,SAAS;AACtB;AAFgB;AAIT,SAAS,iBAAiB,GAAsC;AACnE,SAAO,EAAE,SAAS;AACtB;AAFgB;AAIT,SAAS,gBAAgB,GAAqC;AACjE,SAAO,EAAE,SAAS;AACtB;AAFgB;AAIT,SAAS,mBAAmB,GAAwC;AACvE,SAAO,EAAE,SAAS;AACtB;AAFgB;AAmBT,SAAS,YACZ,QACA,UACa;AACb,UAAQ,OAAO,MAAM;AAAA,IACjB,KAAK;AAAc,cAAQ,SAAS,QAAc,SAAS,KAAK,MAAM;AAAA,IACtE,KAAK;AAAc,cAAQ,SAAS,UAAc,SAAS,KAAK,MAAM;AAAA,IACtE,KAAK;AAAc,cAAQ,SAAS,WAAc,SAAS,KAAK,MAAM;AAAA,IACtE,KAAK;AAAc,cAAQ,SAAS,YAAc,SAAS,KAAK,MAAM;AAAA,IACtE,KAAK;AAAc,cAAQ,SAAS,cAAc,SAAS,KAAK,MAAM;AAAA,EAC1E;AACJ;AAXgB;","names":[]}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * BrainBank — Type Definitions\n * \n * All interfaces and types for the semantic knowledge bank.\n */\n\n\n\n// ── Configuration ───────────────────────────────────\n\nexport interface BrainBankConfig {\n /** Root path of the repository to index. Default: '.' */\n repoPath?: string;\n /** SQLite database path. Default: '.brainbank/brainbank.db' */\n dbPath?: string;\n\n /** Max git commits to index. Default: 500 */\n gitDepth?: number;\n /** Max file size in bytes to index. Default: 512_000 (500KB) */\n maxFileSize?: number;\n /** Max diff bytes per commit. Default: 8192 */\n maxDiffBytes?: number;\n /** HNSW M parameter (connections per node). Default: 16 */\n hnswM?: number;\n /** HNSW efConstruction (build-time candidates). Default: 200 */\n hnswEfConstruction?: number;\n /** HNSW efSearch (query-time candidates). Default: 50 */\n hnswEfSearch?: number;\n /** Embedding dimensions. Default: 384 */\n embeddingDims?: number;\n /** Max HNSW elements. Default: 2_000_000 */\n maxElements?: number;\n /** Custom embedding provider (default: local WASM model) */\n embeddingProvider?: EmbeddingProvider;\n /** Optional reranker for improved search quality */\n reranker?: Reranker;\n}\n\nexport interface ResolvedConfig {\n repoPath: string;\n dbPath: string;\n gitDepth: number;\n maxFileSize: number;\n maxDiffBytes: number;\n hnswM: number;\n hnswEfConstruction: number;\n hnswEfSearch: number;\n embeddingDims: number;\n maxElements: number;\n embeddingProvider?: EmbeddingProvider;\n reranker?: Reranker;\n}\n\n// ── Embedding Provider ──────────────────────────────\n\nexport interface EmbeddingProvider {\n /** Vector dimensions produced by this provider. */\n readonly dims: number;\n /** Embed a single text string. */\n embed(text: string): Promise<Float32Array>;\n /** Embed multiple texts (batch). */\n embedBatch(texts: string[]): Promise<Float32Array[]>;\n /** Release resources. */\n close(): Promise<void>;\n}\n\n// ── Reranker ────────────────────────────────────────\n\nexport interface Reranker {\n /**\n * Score each document's relevance to the query.\n * @param query - The search query\n * @param documents - Document contents to rank\n * @returns Relevance scores (0.0 - 1.0) in same order as documents\n */\n rank(query: string, documents: string[]): Promise<number[]>;\n /** Release resources (e.g. unload model). */\n close?(): Promise<void>;\n}\n\n// ── Vector Index ────────────────────────────────────\n\nexport interface SearchHit {\n id: number;\n score: number;\n}\n\nexport interface VectorIndex {\n /** Initialize the index. Must be called before add/search. */\n init(): Promise<this>;\n /** Add a vector with an integer ID. Idempotent: duplicate IDs are skipped. */\n add(vector: Float32Array, id: number): void;\n /** Mark a vector as deleted so it no longer appears in searches. */\n remove(id: number): void;\n /** Search for k nearest neighbors. */\n search(query: Float32Array, k: number): SearchHit[];\n /** Clear all vectors and reset to empty state. */\n reinit(): void;\n /** Number of vectors in the index. */\n readonly size: number;\n}\n\n// ── Code Chunking ───────────────────────────────────\n\nexport interface CodeChunk {\n /** Auto-incremented DB id (set after insert) */\n id?: number;\n /** Relative file path from repo root */\n filePath: string;\n /** Chunk type: 'file' | 'function' | 'class' | 'block' */\n chunkType: string;\n /** Function/class name (if detected) */\n name?: string;\n /** Start line (1-indexed) */\n startLine: number;\n /** End line (1-indexed, inclusive) */\n endLine: number;\n /** Raw content of the chunk */\n content: string;\n /** Language identifier */\n language: string;\n}\n\n// ── Git ─────────────────────────────────────────────\n\nexport interface GitCommitRecord {\n id?: number;\n hash: string;\n shortHash: string;\n message: string;\n author: string;\n date: string;\n timestamp: number;\n filesChanged: string[];\n diff?: string;\n additions: number;\n deletions: number;\n isMerge: boolean;\n}\n\n// ── Agent Learning ─────────────────────────────────────────\n\nexport interface LearningPattern {\n id?: number;\n /** Category (e.g. 'api', 'refactor', 'debug') */\n taskType: string;\n /** What was the task */\n task: string;\n /** How it was approached */\n approach: string;\n /** What happened */\n outcome?: string;\n /** 0.0 – 1.0 */\n successRate: number;\n /** Lessons learned */\n critique?: string;\n /** Tokens consumed (optional tracking) */\n tokensUsed?: number;\n /** Latency in ms (optional tracking) */\n latencyMs?: number;\n}\n\nexport interface DistilledStrategy {\n taskType: string;\n strategy: string;\n confidence: number;\n updatedAt: number;\n}\n\n// ── Search Results ──────────────────────────────────\n\nexport type SearchResultType = 'code' | 'commit' | 'pattern' | 'document' | 'collection';\n\n// Typed metadata per result type\n\nexport interface CodeResultMetadata {\n chunkType: string;\n name?: string;\n startLine: number;\n endLine: number;\n language: string;\n searchType?: string;\n}\n\nexport interface CommitResultMetadata {\n hash: string;\n shortHash: string;\n author: string;\n date: string;\n files: string[];\n additions?: number;\n deletions?: number;\n diff?: string;\n searchType?: string;\n}\n\nexport interface PatternResultMetadata {\n taskType: string;\n task: string;\n outcome?: string;\n successRate: number;\n critique?: string;\n searchType?: string;\n}\n\nexport interface DocumentResultMetadata {\n collection?: string;\n title?: string;\n seq?: number;\n path?: string;\n searchType?: string;\n /** Internal chunk ID used by hybrid search to map fused results. */\n chunkId?: number;\n}\n\n// Discriminated union\n\nexport interface CodeResult {\n type: 'code';\n score: number;\n filePath: string;\n content: string;\n context?: string;\n metadata: CodeResultMetadata;\n}\n\nexport interface CommitResult {\n type: 'commit';\n score: number;\n filePath?: string;\n content: string;\n context?: string;\n metadata: CommitResultMetadata;\n}\n\nexport interface PatternResult {\n type: 'pattern';\n score: number;\n filePath?: string;\n content: string;\n context?: string;\n metadata: PatternResultMetadata;\n}\n\nexport interface DocumentResult {\n type: 'document';\n score: number;\n filePath: string;\n content: string;\n context?: string;\n metadata: DocumentResultMetadata;\n}\n\nexport interface CollectionResult {\n type: 'collection';\n score: number;\n filePath?: string;\n content: string;\n context?: string;\n metadata: Record<string, any>;\n}\n\nexport type SearchResult = CodeResult | CommitResult | PatternResult | DocumentResult | CollectionResult;\n\n// ── Type Guards ──────────────────────────────────────\n\n/** Narrow a SearchResult to CodeResult. */\nexport function isCodeResult(r: SearchResult): r is CodeResult {\n return r.type === 'code';\n}\n/** Narrow a SearchResult to CommitResult. */\nexport function isCommitResult(r: SearchResult): r is CommitResult {\n return r.type === 'commit';\n}\n/** Narrow a SearchResult to DocumentResult. */\nexport function isDocumentResult(r: SearchResult): r is DocumentResult {\n return r.type === 'document';\n}\n/** Narrow a SearchResult to PatternResult. */\nexport function isPatternResult(r: SearchResult): r is PatternResult {\n return r.type === 'pattern';\n}\n/** Narrow a SearchResult to CollectionResult. */\nexport function isCollectionResult(r: SearchResult): r is CollectionResult {\n return r.type === 'collection';\n}\n\n// ── Match Helper ─────────────────────────────────────\n\ntype MatchHandlers<T> = {\n code?: (r: CodeResult) => T;\n commit?: (r: CommitResult) => T;\n pattern?: (r: PatternResult) => T;\n document?: (r: DocumentResult) => T;\n collection?: (r: CollectionResult) => T;\n _?: (r: SearchResult) => T;\n};\n\n/**\n * Pattern-match on SearchResult type. Calls the matching handler\n * or the `_` fallback. Returns undefined if no handler matches.\n */\nexport function matchResult<T>(\n result: SearchResult,\n handlers: MatchHandlers<T>,\n): T | undefined {\n switch (result.type) {\n case 'code': return (handlers.code ?? handlers._)?.(result);\n case 'commit': return (handlers.commit ?? handlers._)?.(result);\n case 'pattern': return (handlers.pattern ?? handlers._)?.(result);\n case 'document': return (handlers.document ?? handlers._)?.(result);\n case 'collection': return (handlers.collection ?? handlers._)?.(result);\n }\n}\n\n// ── Context Builder ─────────────────────────────────\n\nexport interface ContextOptions {\n /** Max code chunks to include. Default: 6 */\n codeResults?: number;\n /** Max git commits to include. Default: 5 */\n gitResults?: number;\n /** Max memory patterns to include. Default: 4 */\n patternResults?: number;\n /** Files the agent is about to modify (improves co-edit suggestions) */\n affectedFiles?: string[];\n /** Minimum similarity score threshold. Default: 0.25 */\n minScore?: number;\n /** Use MMR for diversity. Default: true */\n useMMR?: boolean;\n /** MMR lambda (0 = diversity, 1 = relevance). Default: 0.7 */\n mmrLambda?: number;\n}\n\n// ── Document Collections ────────────────────────────\n\nexport interface DocumentCollection {\n /** Collection name (e.g. 'notes', 'docs') */\n name: string;\n /** Directory path to index */\n path: string;\n /** Glob pattern for files (default: all markdown) */\n pattern?: string;\n /** Glob patterns to ignore */\n ignore?: string[];\n /** Context description for this collection */\n context?: string;\n}\n\nexport interface DocChunk {\n id?: number;\n /** Collection name */\n collection: string;\n /** Relative file path within the collection */\n filePath: string;\n /** Document title (first heading or filename) */\n title: string;\n /** Chunk content */\n content: string;\n /** Chunk sequence within the document (0, 1, 2...) */\n seq: number;\n /** Character position in original document */\n pos: number;\n /** Content hash for incremental updates */\n contentHash: string;\n}\n\n// ── Stats ───────────────────────────────────────────\n\nexport interface IndexStats {\n code?: {\n files: number;\n chunks: number;\n hnswSize: number;\n };\n git?: {\n commits: number;\n filesTracked: number;\n coEdits: number;\n hnswSize: number;\n };\n memory?: {\n patterns: number;\n avgSuccess: number;\n hnswSize: number;\n };\n documents?: {\n collections: number;\n documents: number;\n chunks: number;\n hnswSize: number;\n };\n notes?: {\n total: number;\n short: number;\n long: number;\n };\n}\n\n// ── Index Progress ──────────────────────────────────\n\n/** File-level progress (used by indexers). */\nexport type ProgressCallback = (file: string, current: number, total: number) => void;\n\n/** Stage-level progress (used by BrainBank.index() orchestrator). */\nexport type StageProgressCallback = (stage: string, message: string) => void;\n\nexport interface IndexResult {\n indexed: number;\n skipped: number;\n chunks?: number;\n}\n\n// ── Co-Edits ────────────────────────────────────────\n\nexport interface CoEditSuggestion {\n file: string;\n count: number;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2QO,SAAS,aAAa,GAAkC;AAC3D,SAAO,EAAE,SAAS;AACtB;AAFgB;AAIT,SAAS,eAAe,GAAoC;AAC/D,SAAO,EAAE,SAAS;AACtB;AAFgB;AAIT,SAAS,iBAAiB,GAAsC;AACnE,SAAO,EAAE,SAAS;AACtB;AAFgB;AAIT,SAAS,gBAAgB,GAAqC;AACjE,SAAO,EAAE,SAAS;AACtB;AAFgB;AAIT,SAAS,mBAAmB,GAAwC;AACvE,SAAO,EAAE,SAAS;AACtB;AAFgB;AAmBT,SAAS,YACZ,QACA,UACa;AACb,UAAQ,OAAO,MAAM;AAAA,IACjB,KAAK;AAAc,cAAQ,SAAS,QAAc,SAAS,KAAK,MAAM;AAAA,IACtE,KAAK;AAAc,cAAQ,SAAS,UAAc,SAAS,KAAK,MAAM;AAAA,IACtE,KAAK;AAAc,cAAQ,SAAS,WAAc,SAAS,KAAK,MAAM;AAAA,IACtE,KAAK;AAAc,cAAQ,SAAS,YAAc,SAAS,KAAK,MAAM;AAAA,IACtE,KAAK;AAAc,cAAQ,SAAS,cAAc,SAAS,KAAK,MAAM;AAAA,EAC1E;AACJ;AAXgB;","names":[]}
@@ -0,0 +1,8 @@
1
+ import {
2
+ LocalEmbedding
3
+ } from "./chunk-424UFCY7.js";
4
+ import "./chunk-7QVYU63E.js";
5
+ export {
6
+ LocalEmbedding
7
+ };
8
+ //# sourceMappingURL=local-embedding-ZIMTK6PU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/memory.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { I as Indexer } from './base-DZWtdgIf.js';
1
+ import { P as Plugin } from './base-3SNc_CeY.js';
2
2
  import 'better-sqlite3';
3
3
 
4
4
  /**
@@ -12,6 +12,6 @@ import 'better-sqlite3';
12
12
  */
13
13
 
14
14
  /** Create an agent memory plugin. */
15
- declare function memory(): Indexer;
15
+ declare function memory(): Plugin;
16
16
 
17
17
  export { memory };
package/dist/memory.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  memory
3
- } from "./chunk-BNV43SEF.js";
3
+ } from "./chunk-VVXYZIIB.js";
4
4
  import "./chunk-U2Q2XGPZ.js";
5
5
  import "./chunk-7QVYU63E.js";
6
6
  export {
package/dist/notes.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { I as Indexer } from './base-DZWtdgIf.js';
1
+ import { P as Plugin } from './base-3SNc_CeY.js';
2
2
  import 'better-sqlite3';
3
3
 
4
4
  /**
@@ -12,6 +12,6 @@ import 'better-sqlite3';
12
12
  */
13
13
 
14
14
  /** Create a notes plugin. */
15
- declare function notes(): Indexer;
15
+ declare function notes(): Plugin;
16
16
 
17
17
  export { notes };
package/dist/notes.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  notes
3
- } from "./chunk-HNPABX7L.js";
3
+ } from "./chunk-7EZR47JV.js";
4
4
  import "./chunk-YOLKSYWK.js";
5
5
  import "./chunk-U2Q2XGPZ.js";
6
6
  import "./chunk-7QVYU63E.js";
@@ -0,0 +1,8 @@
1
+ import {
2
+ Qwen3Reranker
3
+ } from "./chunk-ZNLN2VWV.js";
4
+ import "./chunk-7QVYU63E.js";
5
+ export {
6
+ Qwen3Reranker
7
+ };
8
+ //# sourceMappingURL=qwen3-reranker-3MHEENT5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,10 @@
1
+ import {
2
+ providerKey,
3
+ resolveEmbedding
4
+ } from "./chunk-B77KABWH.js";
5
+ import "./chunk-7QVYU63E.js";
6
+ export {
7
+ providerKey,
8
+ resolveEmbedding
9
+ };
10
+ //# sourceMappingURL=resolve-CUJWY6HP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brainbank",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Pluggable semantic memory for AI agents — hybrid search (vector + BM25) in a single SQLite file. Built-in code, git, and docs indexers. Bring your own.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -73,6 +73,14 @@
73
73
  "better-sqlite3": "^11.8.1",
74
74
  "hnswlib-node": "^3.0.0",
75
75
  "tree-sitter": "^0.25.0",
76
+ "tree-sitter-javascript": "^0.25.0",
77
+ "tree-sitter-python": "^0.25.0",
78
+ "tree-sitter-typescript": "^0.23.2"
79
+ },
80
+ "optionalDependencies": {
81
+ "@xenova/transformers": "^2.17.2",
82
+ "node-llama-cpp": "^3.18.1",
83
+ "simple-git": "^3.27.0",
76
84
  "tree-sitter-bash": "^0.25.1",
77
85
  "tree-sitter-c": "^0.24.1",
78
86
  "tree-sitter-c-sharp": "^0.23.1",
@@ -82,20 +90,13 @@
82
90
  "tree-sitter-go": "^0.25.0",
83
91
  "tree-sitter-html": "^0.23.2",
84
92
  "tree-sitter-java": "^0.23.5",
85
- "tree-sitter-javascript": "^0.25.0",
86
93
  "tree-sitter-kotlin": "^0.3.8",
87
94
  "tree-sitter-lua": "^2.1.3",
88
95
  "tree-sitter-php": "^0.24.2",
89
- "tree-sitter-python": "^0.25.0",
90
96
  "tree-sitter-ruby": "^0.23.1",
91
97
  "tree-sitter-rust": "^0.24.0",
92
98
  "tree-sitter-scala": "^0.24.0",
93
- "tree-sitter-swift": "^0.7.1",
94
- "tree-sitter-typescript": "^0.23.2"
95
- },
96
- "optionalDependencies": {
97
- "@xenova/transformers": "^2.17.2",
98
- "simple-git": "^3.27.0"
99
+ "tree-sitter-swift": "^0.7.1"
99
100
  },
100
101
  "devDependencies": {
101
102
  "@ai-sdk/openai": "^3.0.47",
@@ -1 +0,0 @@
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 { vecToBuffer } from '@/lib/math.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, vecToBuffer(vec));\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":[]}
@@ -1 +0,0 @@
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 { vecToBuffer } from '@/lib/math.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 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 // Transaction: delete old + insert new atomically — prevents orphaned files on crash\n this._deps.db.transaction(() => {\n this._removeOldChunks(rel);\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, vecToBuffer(vecs[ci]));\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\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"]}