@jafreck/lore 0.1.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 (239) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +405 -0
  3. package/dist/cli.d.ts +19 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +345 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/index.d.ts +22 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +16 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/indexer/call-graph.d.ts +39 -0
  12. package/dist/indexer/call-graph.d.ts.map +1 -0
  13. package/dist/indexer/call-graph.js +193 -0
  14. package/dist/indexer/call-graph.js.map +1 -0
  15. package/dist/indexer/complexity.d.ts +9 -0
  16. package/dist/indexer/complexity.d.ts.map +1 -0
  17. package/dist/indexer/complexity.js +66 -0
  18. package/dist/indexer/complexity.js.map +1 -0
  19. package/dist/indexer/config-parser.d.ts +16 -0
  20. package/dist/indexer/config-parser.d.ts.map +1 -0
  21. package/dist/indexer/config-parser.js +261 -0
  22. package/dist/indexer/config-parser.js.map +1 -0
  23. package/dist/indexer/coverage.d.ts +13 -0
  24. package/dist/indexer/coverage.d.ts.map +1 -0
  25. package/dist/indexer/coverage.js +84 -0
  26. package/dist/indexer/coverage.js.map +1 -0
  27. package/dist/indexer/db.d.ts +38 -0
  28. package/dist/indexer/db.d.ts.map +1 -0
  29. package/dist/indexer/db.js +275 -0
  30. package/dist/indexer/db.js.map +1 -0
  31. package/dist/indexer/embedder.d.ts +70 -0
  32. package/dist/indexer/embedder.d.ts.map +1 -0
  33. package/dist/indexer/embedder.js +186 -0
  34. package/dist/indexer/embedder.js.map +1 -0
  35. package/dist/indexer/ensure-python-deps.d.ts +22 -0
  36. package/dist/indexer/ensure-python-deps.d.ts.map +1 -0
  37. package/dist/indexer/ensure-python-deps.js +47 -0
  38. package/dist/indexer/ensure-python-deps.js.map +1 -0
  39. package/dist/indexer/extractors/bash.d.ts +12 -0
  40. package/dist/indexer/extractors/bash.d.ts.map +1 -0
  41. package/dist/indexer/extractors/bash.js +57 -0
  42. package/dist/indexer/extractors/bash.js.map +1 -0
  43. package/dist/indexer/extractors/c.d.ts +12 -0
  44. package/dist/indexer/extractors/c.d.ts.map +1 -0
  45. package/dist/indexer/extractors/c.js +106 -0
  46. package/dist/indexer/extractors/c.js.map +1 -0
  47. package/dist/indexer/extractors/cpp.d.ts +12 -0
  48. package/dist/indexer/extractors/cpp.d.ts.map +1 -0
  49. package/dist/indexer/extractors/cpp.js +84 -0
  50. package/dist/indexer/extractors/cpp.js.map +1 -0
  51. package/dist/indexer/extractors/csharp.d.ts +12 -0
  52. package/dist/indexer/extractors/csharp.d.ts.map +1 -0
  53. package/dist/indexer/extractors/csharp.js +79 -0
  54. package/dist/indexer/extractors/csharp.js.map +1 -0
  55. package/dist/indexer/extractors/dart.d.ts +12 -0
  56. package/dist/indexer/extractors/dart.d.ts.map +1 -0
  57. package/dist/indexer/extractors/dart.js +80 -0
  58. package/dist/indexer/extractors/dart.js.map +1 -0
  59. package/dist/indexer/extractors/elixir.d.ts +12 -0
  60. package/dist/indexer/extractors/elixir.d.ts.map +1 -0
  61. package/dist/indexer/extractors/elixir.js +87 -0
  62. package/dist/indexer/extractors/elixir.js.map +1 -0
  63. package/dist/indexer/extractors/elm.d.ts +12 -0
  64. package/dist/indexer/extractors/elm.d.ts.map +1 -0
  65. package/dist/indexer/extractors/elm.js +87 -0
  66. package/dist/indexer/extractors/elm.js.map +1 -0
  67. package/dist/indexer/extractors/go.d.ts +12 -0
  68. package/dist/indexer/extractors/go.d.ts.map +1 -0
  69. package/dist/indexer/extractors/go.js +158 -0
  70. package/dist/indexer/extractors/go.js.map +1 -0
  71. package/dist/indexer/extractors/haskell.d.ts +12 -0
  72. package/dist/indexer/extractors/haskell.d.ts.map +1 -0
  73. package/dist/indexer/extractors/haskell.js +104 -0
  74. package/dist/indexer/extractors/haskell.js.map +1 -0
  75. package/dist/indexer/extractors/java.d.ts +12 -0
  76. package/dist/indexer/extractors/java.d.ts.map +1 -0
  77. package/dist/indexer/extractors/java.js +68 -0
  78. package/dist/indexer/extractors/java.js.map +1 -0
  79. package/dist/indexer/extractors/javascript.d.ts +13 -0
  80. package/dist/indexer/extractors/javascript.d.ts.map +1 -0
  81. package/dist/indexer/extractors/javascript.js +180 -0
  82. package/dist/indexer/extractors/javascript.js.map +1 -0
  83. package/dist/indexer/extractors/julia.d.ts +12 -0
  84. package/dist/indexer/extractors/julia.d.ts.map +1 -0
  85. package/dist/indexer/extractors/julia.js +94 -0
  86. package/dist/indexer/extractors/julia.js.map +1 -0
  87. package/dist/indexer/extractors/kotlin.d.ts +12 -0
  88. package/dist/indexer/extractors/kotlin.d.ts.map +1 -0
  89. package/dist/indexer/extractors/kotlin.js +71 -0
  90. package/dist/indexer/extractors/kotlin.js.map +1 -0
  91. package/dist/indexer/extractors/lua.d.ts +12 -0
  92. package/dist/indexer/extractors/lua.d.ts.map +1 -0
  93. package/dist/indexer/extractors/lua.js +68 -0
  94. package/dist/indexer/extractors/lua.js.map +1 -0
  95. package/dist/indexer/extractors/objc.d.ts +12 -0
  96. package/dist/indexer/extractors/objc.d.ts.map +1 -0
  97. package/dist/indexer/extractors/objc.js +129 -0
  98. package/dist/indexer/extractors/objc.js.map +1 -0
  99. package/dist/indexer/extractors/ocaml.d.ts +12 -0
  100. package/dist/indexer/extractors/ocaml.d.ts.map +1 -0
  101. package/dist/indexer/extractors/ocaml.js +92 -0
  102. package/dist/indexer/extractors/ocaml.js.map +1 -0
  103. package/dist/indexer/extractors/php.d.ts +12 -0
  104. package/dist/indexer/extractors/php.d.ts.map +1 -0
  105. package/dist/indexer/extractors/php.js +99 -0
  106. package/dist/indexer/extractors/php.js.map +1 -0
  107. package/dist/indexer/extractors/python.d.ts +12 -0
  108. package/dist/indexer/extractors/python.d.ts.map +1 -0
  109. package/dist/indexer/extractors/python.js +129 -0
  110. package/dist/indexer/extractors/python.js.map +1 -0
  111. package/dist/indexer/extractors/ruby.d.ts +12 -0
  112. package/dist/indexer/extractors/ruby.d.ts.map +1 -0
  113. package/dist/indexer/extractors/ruby.js +100 -0
  114. package/dist/indexer/extractors/ruby.js.map +1 -0
  115. package/dist/indexer/extractors/rust.d.ts +12 -0
  116. package/dist/indexer/extractors/rust.d.ts.map +1 -0
  117. package/dist/indexer/extractors/rust.js +82 -0
  118. package/dist/indexer/extractors/rust.js.map +1 -0
  119. package/dist/indexer/extractors/scala.d.ts +12 -0
  120. package/dist/indexer/extractors/scala.d.ts.map +1 -0
  121. package/dist/indexer/extractors/scala.js +91 -0
  122. package/dist/indexer/extractors/scala.js.map +1 -0
  123. package/dist/indexer/extractors/swift.d.ts +12 -0
  124. package/dist/indexer/extractors/swift.d.ts.map +1 -0
  125. package/dist/indexer/extractors/swift.js +90 -0
  126. package/dist/indexer/extractors/swift.js.map +1 -0
  127. package/dist/indexer/extractors/types.d.ts +118 -0
  128. package/dist/indexer/extractors/types.d.ts.map +1 -0
  129. package/dist/indexer/extractors/types.js +43 -0
  130. package/dist/indexer/extractors/types.js.map +1 -0
  131. package/dist/indexer/extractors/typescript.d.ts +14 -0
  132. package/dist/indexer/extractors/typescript.d.ts.map +1 -0
  133. package/dist/indexer/extractors/typescript.js +172 -0
  134. package/dist/indexer/extractors/typescript.js.map +1 -0
  135. package/dist/indexer/extractors/zig.d.ts +12 -0
  136. package/dist/indexer/extractors/zig.d.ts.map +1 -0
  137. package/dist/indexer/extractors/zig.js +95 -0
  138. package/dist/indexer/extractors/zig.js.map +1 -0
  139. package/dist/indexer/git-history.d.ts +23 -0
  140. package/dist/indexer/git-history.d.ts.map +1 -0
  141. package/dist/indexer/git-history.js +144 -0
  142. package/dist/indexer/git-history.js.map +1 -0
  143. package/dist/indexer/git-hooks.d.ts +19 -0
  144. package/dist/indexer/git-hooks.d.ts.map +1 -0
  145. package/dist/indexer/git-hooks.js +74 -0
  146. package/dist/indexer/git-hooks.js.map +1 -0
  147. package/dist/indexer/index.d.ts +83 -0
  148. package/dist/indexer/index.d.ts.map +1 -0
  149. package/dist/indexer/index.js +431 -0
  150. package/dist/indexer/index.js.map +1 -0
  151. package/dist/indexer/parser.d.ts +30 -0
  152. package/dist/indexer/parser.d.ts.map +1 -0
  153. package/dist/indexer/parser.js +114 -0
  154. package/dist/indexer/parser.js.map +1 -0
  155. package/dist/indexer/poller.d.ts +50 -0
  156. package/dist/indexer/poller.d.ts.map +1 -0
  157. package/dist/indexer/poller.js +140 -0
  158. package/dist/indexer/poller.js.map +1 -0
  159. package/dist/indexer/resolver.d.ts +52 -0
  160. package/dist/indexer/resolver.d.ts.map +1 -0
  161. package/dist/indexer/resolver.js +271 -0
  162. package/dist/indexer/resolver.js.map +1 -0
  163. package/dist/indexer/test-mapper.d.ts +6 -0
  164. package/dist/indexer/test-mapper.d.ts.map +1 -0
  165. package/dist/indexer/test-mapper.js +48 -0
  166. package/dist/indexer/test-mapper.js.map +1 -0
  167. package/dist/indexer/walker.d.ts +51 -0
  168. package/dist/indexer/walker.d.ts.map +1 -0
  169. package/dist/indexer/walker.js +100 -0
  170. package/dist/indexer/walker.js.map +1 -0
  171. package/dist/indexer/watcher.d.ts +51 -0
  172. package/dist/indexer/watcher.d.ts.map +1 -0
  173. package/dist/indexer/watcher.js +107 -0
  174. package/dist/indexer/watcher.js.map +1 -0
  175. package/dist/kb-server/db.d.ts +241 -0
  176. package/dist/kb-server/db.d.ts.map +1 -0
  177. package/dist/kb-server/db.js +659 -0
  178. package/dist/kb-server/db.js.map +1 -0
  179. package/dist/kb-server/server.d.ts +35 -0
  180. package/dist/kb-server/server.d.ts.map +1 -0
  181. package/dist/kb-server/server.js +240 -0
  182. package/dist/kb-server/server.js.map +1 -0
  183. package/dist/kb-server/tools/annotations.d.ts +40 -0
  184. package/dist/kb-server/tools/annotations.d.ts.map +1 -0
  185. package/dist/kb-server/tools/annotations.js +35 -0
  186. package/dist/kb-server/tools/annotations.js.map +1 -0
  187. package/dist/kb-server/tools/architecture.d.ts +60 -0
  188. package/dist/kb-server/tools/architecture.d.ts.map +1 -0
  189. package/dist/kb-server/tools/architecture.js +174 -0
  190. package/dist/kb-server/tools/architecture.js.map +1 -0
  191. package/dist/kb-server/tools/blame.d.ts +67 -0
  192. package/dist/kb-server/tools/blame.d.ts.map +1 -0
  193. package/dist/kb-server/tools/blame.js +162 -0
  194. package/dist/kb-server/tools/blame.js.map +1 -0
  195. package/dist/kb-server/tools/coverage.d.ts +67 -0
  196. package/dist/kb-server/tools/coverage.d.ts.map +1 -0
  197. package/dist/kb-server/tools/coverage.js +74 -0
  198. package/dist/kb-server/tools/coverage.js.map +1 -0
  199. package/dist/kb-server/tools/graph.d.ts +56 -0
  200. package/dist/kb-server/tools/graph.d.ts.map +1 -0
  201. package/dist/kb-server/tools/graph.js +188 -0
  202. package/dist/kb-server/tools/graph.js.map +1 -0
  203. package/dist/kb-server/tools/history.d.ts +47 -0
  204. package/dist/kb-server/tools/history.d.ts.map +1 -0
  205. package/dist/kb-server/tools/history.js +91 -0
  206. package/dist/kb-server/tools/history.js.map +1 -0
  207. package/dist/kb-server/tools/lookup.d.ts +36 -0
  208. package/dist/kb-server/tools/lookup.d.ts.map +1 -0
  209. package/dist/kb-server/tools/lookup.js +45 -0
  210. package/dist/kb-server/tools/lookup.js.map +1 -0
  211. package/dist/kb-server/tools/metrics.d.ts +73 -0
  212. package/dist/kb-server/tools/metrics.d.ts.map +1 -0
  213. package/dist/kb-server/tools/metrics.js +79 -0
  214. package/dist/kb-server/tools/metrics.js.map +1 -0
  215. package/dist/kb-server/tools/notes.d.ts +165 -0
  216. package/dist/kb-server/tools/notes.d.ts.map +1 -0
  217. package/dist/kb-server/tools/notes.js +175 -0
  218. package/dist/kb-server/tools/notes.js.map +1 -0
  219. package/dist/kb-server/tools/routes.d.ts +38 -0
  220. package/dist/kb-server/tools/routes.d.ts.map +1 -0
  221. package/dist/kb-server/tools/routes.js +38 -0
  222. package/dist/kb-server/tools/routes.js.map +1 -0
  223. package/dist/kb-server/tools/search.d.ts +60 -0
  224. package/dist/kb-server/tools/search.d.ts.map +1 -0
  225. package/dist/kb-server/tools/search.js +170 -0
  226. package/dist/kb-server/tools/search.js.map +1 -0
  227. package/dist/kb-server/tools/snippet.d.ts +44 -0
  228. package/dist/kb-server/tools/snippet.d.ts.map +1 -0
  229. package/dist/kb-server/tools/snippet.js +49 -0
  230. package/dist/kb-server/tools/snippet.js.map +1 -0
  231. package/dist/kb-server/tools/test-map.d.ts +38 -0
  232. package/dist/kb-server/tools/test-map.d.ts.map +1 -0
  233. package/dist/kb-server/tools/test-map.js +32 -0
  234. package/dist/kb-server/tools/test-map.js.map +1 -0
  235. package/dist/kb-server/tools/writeback.d.ts +49 -0
  236. package/dist/kb-server/tools/writeback.d.ts.map +1 -0
  237. package/dist/kb-server/tools/writeback.js +68 -0
  238. package/dist/kb-server/tools/writeback.js.map +1 -0
  239. package/package.json +92 -0
@@ -0,0 +1,431 @@
1
+ /**
2
+ * @module indexer/index
3
+ *
4
+ * The `IndexBuilder` class orchestrates the full indexing pipeline:
5
+ * walk → parse → extract → resolve → persist
6
+ *
7
+ * It also supports incremental updates (`update()`) and a stub for
8
+ * LLM-summary ingestion (`ingestSummary()`).
9
+ */
10
+ import * as fs from 'node:fs';
11
+ import * as crypto from 'node:crypto';
12
+ import { execFileSync } from 'node:child_process';
13
+ import { openDb, setKbMeta, getKbMeta, createVec0Tables, KB_META_INDEX_CHECKPOINT, KB_META_LAST_HEAD_SHA, KB_META_COVERAGE_LAST_SOURCE_PATH, KB_META_COVERAGE_LAST_SOURCE_MTIME, } from './db.js';
14
+ import { walkFiles } from './walker.js';
15
+ import { detectLanguageForPath } from './walker.js';
16
+ import { ingestGitHistory } from './git-history.js';
17
+ import { ParserPool } from './parser.js';
18
+ import { ImportResolver } from './resolver.js';
19
+ import { buildCallGraph } from './call-graph.js';
20
+ import { CExtractor } from './extractors/c.js';
21
+ import { RustExtractor } from './extractors/rust.js';
22
+ import { PythonExtractor } from './extractors/python.js';
23
+ import { CppExtractor } from './extractors/cpp.js';
24
+ import { TypeScriptExtractor } from './extractors/typescript.js';
25
+ import { JavaScriptExtractor } from './extractors/javascript.js';
26
+ import { GoExtractor } from './extractors/go.js';
27
+ import { JavaExtractor } from './extractors/java.js';
28
+ import { CSharpExtractor } from './extractors/csharp.js';
29
+ import { RubyExtractor } from './extractors/ruby.js';
30
+ import { PhpExtractor } from './extractors/php.js';
31
+ import { SwiftExtractor } from './extractors/swift.js';
32
+ import { KotlinExtractor } from './extractors/kotlin.js';
33
+ import { ScalaExtractor } from './extractors/scala.js';
34
+ import { LuaExtractor } from './extractors/lua.js';
35
+ import { BashExtractor } from './extractors/bash.js';
36
+ import { ElixirExtractor } from './extractors/elixir.js';
37
+ import { ZigExtractor } from './extractors/zig.js';
38
+ import { DartExtractor } from './extractors/dart.js';
39
+ import { OcamlExtractor } from './extractors/ocaml.js';
40
+ import { HaskellExtractor } from './extractors/haskell.js';
41
+ import { JuliaExtractor } from './extractors/julia.js';
42
+ import { ElmExtractor } from './extractors/elm.js';
43
+ import { ObjcExtractor } from './extractors/objc.js';
44
+ import { DEFAULT_EMBEDDING_MODEL } from './embedder.js';
45
+ import { ingestCoverageReport } from './coverage.js';
46
+ import { refreshTestMappings } from './test-mapper.js';
47
+ // ─── Extractor registry ───────────────────────────────────────────────────────
48
+ const EXTRACTORS = {
49
+ c: new CExtractor(),
50
+ rust: new RustExtractor(),
51
+ python: new PythonExtractor(),
52
+ cpp: new CppExtractor(),
53
+ typescript: new TypeScriptExtractor(),
54
+ javascript: new JavaScriptExtractor(),
55
+ go: new GoExtractor(),
56
+ java: new JavaExtractor(),
57
+ csharp: new CSharpExtractor(),
58
+ ruby: new RubyExtractor(),
59
+ php: new PhpExtractor(),
60
+ swift: new SwiftExtractor(),
61
+ kotlin: new KotlinExtractor(),
62
+ scala: new ScalaExtractor(),
63
+ lua: new LuaExtractor(),
64
+ bash: new BashExtractor(),
65
+ elixir: new ElixirExtractor(),
66
+ zig: new ZigExtractor(),
67
+ dart: new DartExtractor(),
68
+ ocaml: new OcamlExtractor(),
69
+ haskell: new HaskellExtractor(),
70
+ julia: new JuliaExtractor(),
71
+ elm: new ElmExtractor(),
72
+ objc: new ObjcExtractor(),
73
+ };
74
+ /** Number of symbols to embed per batch. */
75
+ const EMBED_BATCH_SIZE = 64;
76
+ // ─── IndexBuilder ─────────────────────────────────────────────────────────────
77
+ /**
78
+ * Orchestrates the full M1 indexing pipeline.
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * const builder = new IndexBuilder('/path/to/kb.db', { rootDir: '/path/to/src' });
83
+ * await builder.build();
84
+ * ```
85
+ */
86
+ export class IndexBuilder {
87
+ dbPath;
88
+ walkerConfig;
89
+ pool;
90
+ resolver;
91
+ embedder;
92
+ history;
93
+ embeddingModel;
94
+ constructor(dbPath, walkerConfig, embedder, embeddingModelOrOptions) {
95
+ this.dbPath = dbPath;
96
+ this.walkerConfig = walkerConfig;
97
+ this.pool = new ParserPool();
98
+ this.resolver = new ImportResolver();
99
+ const opts = typeof embeddingModelOrOptions === 'string'
100
+ ? { embeddingModel: embeddingModelOrOptions }
101
+ : (embeddingModelOrOptions ?? {});
102
+ if (embedder) {
103
+ this.embedder = embedder;
104
+ this.embeddingModel = embedder.modelName;
105
+ }
106
+ else {
107
+ this.embeddingModel = opts.embeddingModel ?? DEFAULT_EMBEDDING_MODEL;
108
+ this.embedder = null;
109
+ }
110
+ this.history = opts.history ?? false;
111
+ }
112
+ // ─── Public API ──────────────────────────────────────────────────────────
113
+ /**
114
+ * Performs a full build: walks all files, parses them, extracts
115
+ * symbols/imports/callRefs, resolves imports, and persists everything to
116
+ * the database.
117
+ */
118
+ async build() {
119
+ const db = openDb(this.dbPath);
120
+ const branch = this.resolveBranch();
121
+ try {
122
+ const files = await walkFiles(this.walkerConfig);
123
+ const resumeAt = this.loadBuildCheckpoint(db, branch, files.length);
124
+ db.transaction(() => {
125
+ for (let i = resumeAt; i < files.length; i++) {
126
+ const file = files[i];
127
+ if (!file)
128
+ continue;
129
+ this.processFile(db, file.path, file.language, branch);
130
+ this.saveBuildCheckpoint(db, branch, i + 1, files.length);
131
+ }
132
+ })();
133
+ this.saveBuildCheckpoint(db, branch, files.length, files.length);
134
+ this.resolveImports(db, branch);
135
+ refreshTestMappings(db, branch);
136
+ buildCallGraph(db);
137
+ this.saveLastKnownHead(db);
138
+ if (this.embedder) {
139
+ await this.embedder.init();
140
+ await this.embedStructural(db);
141
+ }
142
+ if (this.history) {
143
+ const historyOptions = typeof this.history === 'object' ? this.history : undefined;
144
+ await ingestGitHistory(db, this.walkerConfig.rootDir, historyOptions);
145
+ }
146
+ }
147
+ finally {
148
+ db.close();
149
+ }
150
+ }
151
+ /**
152
+ * Incrementally re-processes only the listed files and updates the DB.
153
+ * Symbols and imports for changed files are deleted then re-inserted.
154
+ *
155
+ * @param changedFiles Absolute paths of files that have changed.
156
+ */
157
+ async update(changedFiles) {
158
+ const db = openDb(this.dbPath);
159
+ const branch = this.resolveBranch();
160
+ try {
161
+ db.transaction(() => {
162
+ for (const filePath of changedFiles) {
163
+ // If the file no longer exists, remove it from the DB
164
+ if (!fs.existsSync(filePath)) {
165
+ const row = db.prepare('SELECT id FROM files WHERE path = ? AND branch = ?').get(filePath, branch);
166
+ if (row) {
167
+ // Null out any resolved_id references pointing to this file
168
+ db.prepare('UPDATE file_imports SET resolved_id = NULL WHERE resolved_id = ?').run(row.id);
169
+ db.prepare('DELETE FROM symbols_fts WHERE rowid IN (SELECT id FROM symbols WHERE file_id = ?)').run(row.id);
170
+ db.prepare('DELETE FROM files WHERE id = ?').run(row.id);
171
+ }
172
+ continue;
173
+ }
174
+ const language = detectLanguageForPath(filePath, this.walkerConfig);
175
+ if (!language)
176
+ continue;
177
+ // Null out resolved_id references pointing to this file before deletion
178
+ const existingRow = db.prepare('SELECT id FROM files WHERE path = ? AND branch = ?').get(filePath, branch);
179
+ if (existingRow) {
180
+ db.prepare('UPDATE file_imports SET resolved_id = NULL WHERE resolved_id = ?').run(existingRow.id);
181
+ db.prepare('DELETE FROM symbols_fts WHERE rowid IN (SELECT id FROM symbols WHERE file_id = ?)').run(existingRow.id);
182
+ }
183
+ // Delete existing rows for this file (cascade handles symbols/imports)
184
+ db.prepare('DELETE FROM files WHERE path = ? AND branch = ?').run(filePath, branch);
185
+ this.processFile(db, filePath, language, branch);
186
+ }
187
+ })();
188
+ this.resolveImports(db, branch);
189
+ refreshTestMappings(db, branch);
190
+ if (this.history) {
191
+ const historyOptions = typeof this.history === 'object' ? this.history : undefined;
192
+ await ingestGitHistory(db, this.walkerConfig.rootDir, historyOptions);
193
+ }
194
+ if (this.embedder) {
195
+ await this.embedder.init();
196
+ await this.embedStructural(db);
197
+ }
198
+ buildCallGraph(db);
199
+ this.saveLastKnownHead(db);
200
+ }
201
+ finally {
202
+ db.close();
203
+ }
204
+ }
205
+ /**
206
+ * Writes an LLM-generated summary for a symbol to `symbol_summaries`.
207
+ * If an `EmbeddingProvider` was configured, also embeds the summary text
208
+ * and persists it to `symbol_semantic_embeddings`.
209
+ *
210
+ * @param symbolId Row ID of the symbol in the `symbols` table.
211
+ * @param summary Natural-language summary text.
212
+ * @param model Name of the model that produced the summary.
213
+ */
214
+ async ingestSummary(symbolId, summary, model = 'unknown') {
215
+ const db = openDb(this.dbPath);
216
+ try {
217
+ db.prepare(`INSERT OR REPLACE INTO symbol_summaries (symbol_id, summary, model)
218
+ VALUES (?, ?, ?)`).run(symbolId, summary, model);
219
+ if (this.embedder) {
220
+ const [[embedding]] = await Promise.all([this.embedder.embed([summary])]);
221
+ db.prepare('INSERT OR REPLACE INTO symbol_semantic_embeddings(rowid, embedding) VALUES (CAST(? AS INTEGER), json(?))').run(symbolId, JSON.stringify(embedding));
222
+ }
223
+ }
224
+ finally {
225
+ db.close();
226
+ }
227
+ }
228
+ async ingestCoverage(reportPath, format, commitSha) {
229
+ const db = openDb(this.dbPath);
230
+ try {
231
+ const resolvedCommitSha = commitSha ?? this.readGitValue(['rev-parse', 'HEAD']) ?? 'HEAD';
232
+ const sourceMtime = Math.floor(fs.statSync(reportPath).mtimeMs / 1000);
233
+ ingestCoverageReport({
234
+ db,
235
+ rootDir: this.walkerConfig.rootDir,
236
+ reportPath,
237
+ format,
238
+ commitSha: resolvedCommitSha,
239
+ sourceMtime,
240
+ });
241
+ setKbMeta(db, KB_META_COVERAGE_LAST_SOURCE_PATH, reportPath);
242
+ setKbMeta(db, KB_META_COVERAGE_LAST_SOURCE_MTIME, String(sourceMtime));
243
+ }
244
+ finally {
245
+ db.close();
246
+ }
247
+ }
248
+ // ─── Private helpers ──────────────────────────────────────────────────────
249
+ /** Parse one file, extract symbols/imports/callRefs, and insert into the DB. */
250
+ processFile(db, filePath, language, branch) {
251
+ let source;
252
+ try {
253
+ source = fs.readFileSync(filePath, 'utf8');
254
+ }
255
+ catch {
256
+ return; // Skip unreadable files
257
+ }
258
+ const hash = crypto.createHash('sha256').update(source).digest('hex');
259
+ // Check if the file is already up-to-date
260
+ const existing = db.prepare('SELECT id, last_hash FROM files WHERE path = ? AND branch = ?').get(filePath, branch);
261
+ if (existing?.last_hash === hash)
262
+ return;
263
+ const sizeBytes = Buffer.byteLength(source, 'utf8');
264
+ // Upsert the file row
265
+ let fileId;
266
+ if (existing) {
267
+ db.prepare(`UPDATE files SET language = ?, size_bytes = ?, last_hash = ?, indexed_at = unixepoch()
268
+ WHERE id = ?`).run(language, sizeBytes, hash, existing.id);
269
+ fileId = existing.id;
270
+ // Remove stale symbols / imports / external deps (also clean up FTS5 index)
271
+ db.prepare(`DELETE FROM symbols_fts WHERE rowid IN (SELECT id FROM symbols WHERE file_id = ?)`).run(fileId);
272
+ db.prepare('DELETE FROM symbols WHERE file_id = ?').run(fileId);
273
+ db.prepare('DELETE FROM file_imports WHERE file_id = ?').run(fileId);
274
+ db.prepare('DELETE FROM external_deps WHERE file_id = ?').run(fileId);
275
+ db.prepare('DELETE FROM api_routes WHERE file_id = ?').run(fileId);
276
+ }
277
+ else {
278
+ const info = db
279
+ .prepare(`INSERT INTO files (path, branch, language, size_bytes, last_hash)
280
+ VALUES (?, ?, ?, ?, ?)`)
281
+ .run(filePath, branch, language, sizeBytes, hash);
282
+ fileId = Number(info.lastInsertRowid);
283
+ }
284
+ // Parse the source
285
+ const tree = this.pool.parse(language, source);
286
+ if (!tree)
287
+ return;
288
+ const extractor = EXTRACTORS[language];
289
+ if (!extractor)
290
+ return;
291
+ const result = extractor.extract(tree, source, filePath);
292
+ // Insert symbols and keep FTS5 index in sync
293
+ const insertSymbol = db.prepare(`INSERT INTO symbols (file_id, name, kind, start_line, end_line, signature, doc_comment)
294
+ VALUES (?, ?, ?, ?, ?, ?, ?)`);
295
+ const insertFts = db.prepare(`INSERT INTO symbols_fts(rowid, name, signature, kind) VALUES (?, ?, ?, ?)`);
296
+ // Map from callerSymbol name → symbol row ID (for call refs)
297
+ const symbolIdMap = new Map();
298
+ for (const sym of result.symbols) {
299
+ const info = insertSymbol.run(fileId, sym.name, sym.kind, sym.startLine, sym.endLine, sym.signature ?? null, sym.docComment ?? null);
300
+ const symId = Number(info.lastInsertRowid);
301
+ symbolIdMap.set(sym.name, symId);
302
+ insertFts.run(symId, sym.name, sym.signature ?? '', sym.kind);
303
+ }
304
+ const insertRoute = db.prepare(`INSERT INTO api_routes (file_id, method, path, handler_id, handler_name, framework, line, middleware)
305
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);
306
+ for (const route of result.routes) {
307
+ insertRoute.run(fileId, route.method, route.path, symbolIdMap.get(route.handler) ?? null, route.handler, route.framework, route.line, route.middleware ? JSON.stringify(route.middleware) : null);
308
+ }
309
+ // Insert raw imports (resolved_id will be filled in resolveImports())
310
+ const insertImport = db.prepare(`INSERT INTO file_imports (file_id, raw_import) VALUES (?, ?)`);
311
+ for (const imp of result.imports) {
312
+ insertImport.run(fileId, imp.source);
313
+ }
314
+ // Insert call refs (callee_id resolved in call-graph phase)
315
+ const insertCallRef = db.prepare(`INSERT INTO symbol_refs (caller_id, callee_name, call_line)
316
+ VALUES (?, ?, ?)`);
317
+ for (const ref of result.callRefs) {
318
+ const callerId = symbolIdMap.get(ref.callerSymbol);
319
+ if (callerId !== undefined) {
320
+ insertCallRef.run(callerId, ref.calleeRaw, ref.line);
321
+ }
322
+ }
323
+ }
324
+ /**
325
+ * Second pass: resolve raw_import strings to file IDs in the
326
+ * `file_imports.resolved_id` column. Also populates `external_deps` for
327
+ * any import that resolves to an external package.
328
+ */
329
+ resolveImports(db, branch) {
330
+ const rootDir = this.walkerConfig.rootDir;
331
+ // Fetch all unresolved imports with their file's path, language, and file_id
332
+ const rows = db
333
+ .prepare(`SELECT fi.id, fi.file_id, fi.raw_import, f.path, f.language
334
+ FROM file_imports fi
335
+ JOIN files f ON f.id = fi.file_id
336
+ WHERE fi.resolved_id IS NULL AND f.branch = ?`)
337
+ .all(branch);
338
+ const updateResolved = db.prepare('UPDATE file_imports SET resolved_id = ? WHERE id = ?');
339
+ const insertExternalDep = db.prepare('INSERT OR IGNORE INTO external_deps (file_id, package) VALUES (?, ?)');
340
+ for (const row of rows) {
341
+ const resolved = this.resolver.resolve({ source: row.raw_import, importedNames: [] }, row.path, rootDir, row.language);
342
+ if (resolved.resolvedPath) {
343
+ const targetFile = db
344
+ .prepare('SELECT id FROM files WHERE path = ? AND branch = ?')
345
+ .get(resolved.resolvedPath, branch);
346
+ if (targetFile) {
347
+ updateResolved.run(targetFile.id, row.id);
348
+ }
349
+ }
350
+ else if (resolved.isExternal && resolved.externalName) {
351
+ insertExternalDep.run(row.file_id, resolved.externalName);
352
+ }
353
+ }
354
+ }
355
+ resolveBranch() {
356
+ if (this.walkerConfig.branch)
357
+ return this.walkerConfig.branch;
358
+ return this.readGitValue(['rev-parse', '--abbrev-ref', 'HEAD']) ?? 'HEAD';
359
+ }
360
+ saveLastKnownHead(db) {
361
+ const headSha = this.readGitValue(['rev-parse', 'HEAD']);
362
+ if (headSha) {
363
+ setKbMeta(db, KB_META_LAST_HEAD_SHA, headSha);
364
+ }
365
+ }
366
+ readGitValue(args) {
367
+ try {
368
+ const value = execFileSync('git', ['-C', this.walkerConfig.rootDir, ...args], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
369
+ return value || undefined;
370
+ }
371
+ catch {
372
+ return undefined;
373
+ }
374
+ }
375
+ loadBuildCheckpoint(db, branch, totalFiles) {
376
+ const raw = getKbMeta(db, KB_META_INDEX_CHECKPOINT);
377
+ if (!raw)
378
+ return 0;
379
+ try {
380
+ const parsed = JSON.parse(raw);
381
+ if (parsed.branch !== branch || parsed.rootDir !== this.walkerConfig.rootDir)
382
+ return 0;
383
+ const nextFileIndex = parsed.nextFileIndex ?? 0;
384
+ return Math.max(0, Math.min(totalFiles, nextFileIndex));
385
+ }
386
+ catch {
387
+ return 0;
388
+ }
389
+ }
390
+ saveBuildCheckpoint(db, branch, nextFileIndex, totalFiles) {
391
+ const checkpoint = {
392
+ branch,
393
+ rootDir: this.walkerConfig.rootDir,
394
+ totalFiles,
395
+ nextFileIndex,
396
+ updatedAt: Math.floor(Date.now() / 1000),
397
+ };
398
+ setKbMeta(db, KB_META_INDEX_CHECKPOINT, JSON.stringify(checkpoint));
399
+ }
400
+ /**
401
+ * Embed structural symbol signatures in batches and persist results to
402
+ * the `symbol_embeddings` vec0 virtual table.
403
+ *
404
+ * Also stores the embedding model name and dims in `kb_meta` and
405
+ * creates the vec0 tables if they don't exist yet.
406
+ */
407
+ async embedStructural(db) {
408
+ const embedder = this.embedder;
409
+ setKbMeta(db, 'embedding_model', embedder.modelName);
410
+ setKbMeta(db, 'embedding_dims', String(embedder.dims));
411
+ createVec0Tables(db, embedder.dims);
412
+ // Fetch all symbols that have a signature to embed.
413
+ const symbols = db
414
+ .prepare('SELECT id, name, signature FROM symbols WHERE signature IS NOT NULL')
415
+ .all();
416
+ const insertEmbed = db.prepare('INSERT OR REPLACE INTO symbol_embeddings(rowid, embedding) VALUES (CAST(? AS INTEGER), json(?))');
417
+ for (let i = 0; i < symbols.length; i += EMBED_BATCH_SIZE) {
418
+ const batch = symbols.slice(i, i + EMBED_BATCH_SIZE);
419
+ const texts = batch.map(s => s.signature || s.name);
420
+ const embeddings = await embedder.embed(texts);
421
+ db.transaction(() => {
422
+ for (let j = 0; j < batch.length; j++) {
423
+ const sym = batch[j];
424
+ if (sym)
425
+ insertEmbed.run(sym.id, JSON.stringify(embeddings[j]));
426
+ }
427
+ })();
428
+ }
429
+ }
430
+ }
431
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/indexer/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @module indexer/parser
3
+ *
4
+ * Provides a `ParserPool` that lazily creates one tree-sitter `Parser` per
5
+ * language and caches it for reuse. Grammar packages that are not installed
6
+ * are silently skipped — `parse()` returns `null` for those languages.
7
+ */
8
+ import Parser from 'tree-sitter';
9
+ /**
10
+ * Maintains one `Parser` instance per language for efficient reuse.
11
+ *
12
+ * Grammar packages are loaded lazily on the first `parse()` call for a given
13
+ * language. If the package is not installed, `parse()` returns `null` and the
14
+ * failed language is never retried.
15
+ */
16
+ export declare class ParserPool {
17
+ /** Cache of successfully initialised parsers, keyed by language. */
18
+ private readonly parsers;
19
+ /** Languages whose grammar package could not be loaded. */
20
+ private readonly unavailable;
21
+ /**
22
+ * Parses `source` with the grammar for `language`.
23
+ *
24
+ * Returns `null` if the grammar package is not installed or `language` is
25
+ * not recognised. Each `Parser` instance is created once and reused.
26
+ */
27
+ parse(language: string, source: string): Parser.Tree | null;
28
+ private initParser;
29
+ }
30
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/indexer/parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AAiDjC;;;;;;GAMG;AACH,qBAAa,UAAU;IACrB,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IAErD,2DAA2D;IAC3D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IAEjD;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,IAAI,GAAG,IAAI;IAe3D,OAAO,CAAC,UAAU;CA+BnB"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * @module indexer/parser
3
+ *
4
+ * Provides a `ParserPool` that lazily creates one tree-sitter `Parser` per
5
+ * language and caches it for reuse. Grammar packages that are not installed
6
+ * are silently skipped — `parse()` returns `null` for those languages.
7
+ */
8
+ import Parser from 'tree-sitter';
9
+ import { createRequire } from 'node:module';
10
+ const esmRequire = createRequire(import.meta.url);
11
+ /**
12
+ * Size of chunks returned to tree-sitter when parsing source text.
13
+ *
14
+ * We intentionally stream source via callback input instead of passing a raw
15
+ * string to avoid a tree-sitter binding bug that can throw `Invalid argument`
16
+ * on large files when it chunks strings internally.
17
+ */
18
+ const PARSER_CHUNK_SIZE = 4096;
19
+ // ─── Grammar package map ──────────────────────────────────────────────────────
20
+ /**
21
+ * Maps a language identifier (as returned by the file walker) to the npm
22
+ * package name that exports the corresponding tree-sitter grammar.
23
+ */
24
+ const LANG_PACKAGES = {
25
+ c: 'tree-sitter-c',
26
+ rust: 'tree-sitter-rust',
27
+ python: 'tree-sitter-python',
28
+ cpp: 'tree-sitter-cpp',
29
+ typescript: 'tree-sitter-typescript',
30
+ javascript: 'tree-sitter-javascript',
31
+ go: 'tree-sitter-go',
32
+ java: 'tree-sitter-java',
33
+ csharp: 'tree-sitter-c-sharp',
34
+ ruby: 'tree-sitter-ruby',
35
+ php: 'tree-sitter-php',
36
+ swift: 'tree-sitter-swift',
37
+ kotlin: 'tree-sitter-kotlin',
38
+ scala: 'tree-sitter-scala',
39
+ lua: 'tree-sitter-lua',
40
+ bash: 'tree-sitter-bash',
41
+ elixir: 'tree-sitter-elixir',
42
+ zig: 'tree-sitter-zig',
43
+ dart: 'tree-sitter-dart',
44
+ ocaml: 'tree-sitter-ocaml',
45
+ haskell: 'tree-sitter-haskell',
46
+ julia: 'tree-sitter-julia',
47
+ elm: 'tree-sitter-elm',
48
+ objc: 'tree-sitter-objc',
49
+ };
50
+ // ─── ParserPool ───────────────────────────────────────────────────────────────
51
+ /**
52
+ * Maintains one `Parser` instance per language for efficient reuse.
53
+ *
54
+ * Grammar packages are loaded lazily on the first `parse()` call for a given
55
+ * language. If the package is not installed, `parse()` returns `null` and the
56
+ * failed language is never retried.
57
+ */
58
+ export class ParserPool {
59
+ /** Cache of successfully initialised parsers, keyed by language. */
60
+ parsers = new Map();
61
+ /** Languages whose grammar package could not be loaded. */
62
+ unavailable = new Set();
63
+ /**
64
+ * Parses `source` with the grammar for `language`.
65
+ *
66
+ * Returns `null` if the grammar package is not installed or `language` is
67
+ * not recognised. Each `Parser` instance is created once and reused.
68
+ */
69
+ parse(language, source) {
70
+ if (this.unavailable.has(language))
71
+ return null;
72
+ if (!this.parsers.has(language)) {
73
+ this.initParser(language);
74
+ }
75
+ const parser = this.parsers.get(language);
76
+ if (!parser)
77
+ return null;
78
+ return parser.parse((offset) => source.slice(offset, offset + PARSER_CHUNK_SIZE));
79
+ }
80
+ // ─── Private helpers ────────────────────────────────────────────────────────
81
+ initParser(language) {
82
+ const pkg = LANG_PACKAGES[language];
83
+ if (!pkg) {
84
+ this.unavailable.add(language);
85
+ return;
86
+ }
87
+ try {
88
+ // Native addons must be loaded via require(), not import().
89
+ // Use createRequire to ensure it works in both CJS and ESM contexts.
90
+ let grammar = esmRequire(pkg);
91
+ // Some packages (e.g. tree-sitter-typescript) export sub-grammars.
92
+ if (language === 'typescript' && grammar.typescript) {
93
+ grammar = grammar.typescript;
94
+ }
95
+ else if (language === 'javascript' && grammar.javascript) {
96
+ grammar = grammar.javascript;
97
+ }
98
+ else if (language === 'php' && grammar.php) {
99
+ grammar = grammar.php;
100
+ }
101
+ else if (language === 'ocaml' && grammar.ocaml) {
102
+ grammar = grammar.ocaml;
103
+ }
104
+ const parser = new Parser();
105
+ parser.setLanguage(grammar);
106
+ this.parsers.set(language, parser);
107
+ }
108
+ catch {
109
+ // Grammar not installed — mark as unavailable to avoid repeated attempts.
110
+ this.unavailable.add(language);
111
+ }
112
+ }
113
+ }
114
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/indexer/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @module indexer/poller
3
+ *
4
+ * FilePoller periodically walks the directory tree, diffs file mtimes against
5
+ * a stored snapshot, and calls `IndexBuilder.update()` for any files that were
6
+ * created, modified, or deleted since the last poll.
7
+ */
8
+ import type { WalkerConfig } from './walker.js';
9
+ /** Configuration options for FilePoller. */
10
+ export interface PollerOptions {
11
+ /** Whether the poller is active. Defaults to `true`. */
12
+ enabled?: boolean;
13
+ /** Polling interval in milliseconds. Defaults to 5000 (5 s). */
14
+ intervalMs?: number;
15
+ /** Whether to refresh git history during poll update cycles. */
16
+ history?: boolean | {
17
+ depth?: number;
18
+ all?: boolean;
19
+ };
20
+ }
21
+ /**
22
+ * Polls a directory tree on a configurable interval, compares mtimes against
23
+ * a snapshot, and triggers incremental index updates via `IndexBuilder.update()`.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const poller = new FilePoller('/path/to/kb.db', { rootDir: '/path/to/src' });
28
+ * poller.start();
29
+ * // ...later...
30
+ * poller.stop();
31
+ * ```
32
+ */
33
+ export declare class FilePoller {
34
+ private readonly dbPath;
35
+ private readonly walkerConfig;
36
+ private readonly intervalMs;
37
+ private readonly enabled;
38
+ private readonly history;
39
+ /** Maps absolute path → last seen mtime (ms since epoch). */
40
+ private snapshot;
41
+ private timer;
42
+ private pollRunning;
43
+ constructor(dbPath: string, walkerConfig: WalkerConfig, options?: PollerOptions);
44
+ /** Begin polling `walkerConfig.rootDir` at the configured interval. */
45
+ start(): void;
46
+ /** Stop the polling interval. */
47
+ stop(): void;
48
+ private poll;
49
+ }
50
+ //# sourceMappingURL=poller.d.ts.map