@jafreck/lore 0.3.3 → 0.3.5

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 (41) hide show
  1. package/README.md +23 -6
  2. package/dist/cli.js +56 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/index.d.ts +6 -5
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +3 -3
  7. package/dist/index.js.map +1 -1
  8. package/dist/indexer/embedder.d.ts +67 -30
  9. package/dist/indexer/embedder.d.ts.map +1 -1
  10. package/dist/indexer/embedder.js +151 -146
  11. package/dist/indexer/embedder.js.map +1 -1
  12. package/dist/indexer/graph-analysis.d.ts +115 -0
  13. package/dist/indexer/graph-analysis.d.ts.map +1 -0
  14. package/dist/indexer/graph-analysis.js +575 -0
  15. package/dist/indexer/graph-analysis.js.map +1 -0
  16. package/dist/indexer/stages/embedding.d.ts +9 -0
  17. package/dist/indexer/stages/embedding.d.ts.map +1 -1
  18. package/dist/indexer/stages/embedding.js +127 -83
  19. package/dist/indexer/stages/embedding.js.map +1 -1
  20. package/dist/lore-server/db.d.ts +74 -0
  21. package/dist/lore-server/db.d.ts.map +1 -1
  22. package/dist/lore-server/db.js +114 -0
  23. package/dist/lore-server/db.js.map +1 -1
  24. package/dist/lore-server/server.d.ts.map +1 -1
  25. package/dist/lore-server/server.js +7 -17
  26. package/dist/lore-server/server.js.map +1 -1
  27. package/dist/lore-server/tool-registry.d.ts.map +1 -1
  28. package/dist/lore-server/tool-registry.js +6 -1
  29. package/dist/lore-server/tool-registry.js.map +1 -1
  30. package/dist/lore-server/tools/graph-analysis.d.ts +64 -0
  31. package/dist/lore-server/tools/graph-analysis.d.ts.map +1 -0
  32. package/dist/lore-server/tools/graph-analysis.js +82 -0
  33. package/dist/lore-server/tools/graph-analysis.js.map +1 -0
  34. package/dist/runtime.d.ts.map +1 -1
  35. package/dist/runtime.js +4 -5
  36. package/dist/runtime.js.map +1 -1
  37. package/package.json +2 -1
  38. package/dist/indexer/ensure-python-deps.d.ts +0 -22
  39. package/dist/indexer/ensure-python-deps.d.ts.map +0 -1
  40. package/dist/indexer/ensure-python-deps.js +0 -47
  41. package/dist/indexer/ensure-python-deps.js.map +0 -1
@@ -0,0 +1,575 @@
1
+ /**
2
+ * @module indexer/graph-analysis
3
+ *
4
+ * Higher-level graph analysis primitives operating on the SQLite
5
+ * knowledge-base:
6
+ *
7
+ * - `detectSymbolCycles(db, opts)` — Tarjan's SCC on the symbol adjacency
8
+ * graph (call_refs, type_refs, or both).
9
+ * - `findConnectedComponents(db, opts)` — union-find connected components
10
+ * at file or symbol scope.
11
+ * - `clusterSymbols(db, opts)` — partitions the call graph into bounded-
12
+ * size coherent chunks via SCC contraction, same-file merge, greedy
13
+ * edge-weight consolidation, and affinity folding.
14
+ * - `buildCodebaseSummary(db, opts)` — condensed dependency summary with
15
+ * per-module files, symbol counts, line spans, and SCCs.
16
+ */
17
+ import { RESOLVED_METHODS } from './resolution-method.js';
18
+ /**
19
+ * Loads resolved symbol-level edges from the database.
20
+ * Returns only edges where both source and target are non-NULL and the
21
+ * resolution_method passes the configured filter.
22
+ */
23
+ function loadSymbolEdges(db, options = {}) {
24
+ const edgeKinds = options.edgeKinds ?? 'both';
25
+ const methods = options.methods ?? [...RESOLVED_METHODS];
26
+ const branch = options.branch;
27
+ if (methods.length === 0)
28
+ return [];
29
+ const placeholders = methods.map(() => '?').join(', ');
30
+ const edges = [];
31
+ if (edgeKinds === 'call' || edgeKinds === 'both') {
32
+ const where = [`sr.callee_id IS NOT NULL`, `sr.resolution_method IN (${placeholders})`];
33
+ const params = [...methods];
34
+ if (branch !== undefined) {
35
+ where.push('f.branch = ?');
36
+ params.push(branch);
37
+ }
38
+ const rows = db.prepare(`SELECT sr.caller_id AS source, sr.callee_id AS target
39
+ FROM symbol_refs sr
40
+ JOIN symbols s ON s.id = sr.caller_id
41
+ JOIN files f ON f.id = s.file_id
42
+ WHERE ${where.join(' AND ')}`).all(...params);
43
+ edges.push(...rows);
44
+ }
45
+ if (edgeKinds === 'type' || edgeKinds === 'both') {
46
+ const where = [`tr.type_id IS NOT NULL`, `tr.resolution_method IN (${placeholders})`];
47
+ const params = [...methods];
48
+ if (branch !== undefined) {
49
+ where.push('f.branch = ?');
50
+ params.push(branch);
51
+ }
52
+ const rows = db.prepare(`SELECT tr.symbol_id AS source, tr.type_id AS target
53
+ FROM type_refs tr
54
+ JOIN files f ON f.id = tr.file_id
55
+ WHERE tr.symbol_id IS NOT NULL AND ${where.join(' AND ')}`).all(...params);
56
+ edges.push(...rows);
57
+ }
58
+ return edges;
59
+ }
60
+ // ─── detectSymbolCycles ───────────────────────────────────────────────────────
61
+ /**
62
+ * Detects strongly connected components (mutual recursion, circular type
63
+ * dependencies) in the **symbol** adjacency graph using Tarjan's algorithm.
64
+ *
65
+ * Returns arrays of symbol IDs where each SCC has 2+ members (or a single
66
+ * member with a self-edge).
67
+ */
68
+ export function detectSymbolCycles(db, options = {}) {
69
+ const edges = loadSymbolEdges(db, options);
70
+ // Build directed adjacency list
71
+ const adjacency = new Map();
72
+ const allNodes = new Set();
73
+ for (const { source, target } of edges) {
74
+ allNodes.add(source);
75
+ allNodes.add(target);
76
+ let list = adjacency.get(source);
77
+ if (!list) {
78
+ list = [];
79
+ adjacency.set(source, list);
80
+ }
81
+ list.push(target);
82
+ }
83
+ // Tarjan's SCC
84
+ let index = 0;
85
+ const indices = new Map();
86
+ const lowlink = new Map();
87
+ const onStack = new Set();
88
+ const stack = [];
89
+ const sccs = [];
90
+ function strongConnect(v) {
91
+ indices.set(v, index);
92
+ lowlink.set(v, index);
93
+ index++;
94
+ stack.push(v);
95
+ onStack.add(v);
96
+ for (const w of adjacency.get(v) ?? []) {
97
+ if (!indices.has(w)) {
98
+ strongConnect(w);
99
+ lowlink.set(v, Math.min(lowlink.get(v), lowlink.get(w)));
100
+ }
101
+ else if (onStack.has(w)) {
102
+ lowlink.set(v, Math.min(lowlink.get(v), indices.get(w)));
103
+ }
104
+ }
105
+ if (lowlink.get(v) === indices.get(v)) {
106
+ const scc = [];
107
+ let w;
108
+ do {
109
+ w = stack.pop();
110
+ onStack.delete(w);
111
+ scc.push(w);
112
+ } while (w !== v);
113
+ if (scc.length > 1) {
114
+ sccs.push(scc);
115
+ }
116
+ else {
117
+ // Single-node SCC — only report if self-loop exists
118
+ const selfLoop = (adjacency.get(scc[0]) ?? []).includes(scc[0]);
119
+ if (selfLoop)
120
+ sccs.push(scc);
121
+ }
122
+ }
123
+ }
124
+ for (const node of allNodes) {
125
+ if (!indices.has(node)) {
126
+ strongConnect(node);
127
+ }
128
+ }
129
+ return sccs;
130
+ }
131
+ /**
132
+ * Finds connected components in the **undirected** graph of files or symbols
133
+ * using a union-find (disjoint set) data structure.
134
+ *
135
+ * Returns arrays of IDs where each component has 2+ members.
136
+ */
137
+ export function findConnectedComponents(db, options = {}) {
138
+ const scope = options.scope ?? 'symbol';
139
+ if (scope === 'file') {
140
+ return findFileComponents(db, options);
141
+ }
142
+ return findSymbolComponents(db, options);
143
+ }
144
+ function findFileComponents(db, options) {
145
+ const branch = options.branch;
146
+ const allFiles = (branch !== undefined
147
+ ? db.prepare('SELECT id FROM files WHERE branch = ?').all(branch)
148
+ : db.prepare('SELECT id FROM files').all());
149
+ const edges = (branch !== undefined
150
+ ? db.prepare(`SELECT fi.file_id AS source, fi.resolved_id AS target
151
+ FROM file_imports fi
152
+ JOIN files f ON f.id = fi.file_id
153
+ WHERE fi.resolved_id IS NOT NULL AND f.branch = ?`).all(branch)
154
+ : db.prepare(`SELECT fi.file_id AS source, fi.resolved_id AS target
155
+ FROM file_imports fi
156
+ WHERE fi.resolved_id IS NOT NULL`).all());
157
+ const uf = new UnionFind();
158
+ for (const f of allFiles)
159
+ uf.makeSet(f.id);
160
+ for (const { source, target } of edges)
161
+ uf.union(source, target);
162
+ return uf.components().filter(c => c.length > 1);
163
+ }
164
+ function findSymbolComponents(db, options) {
165
+ const edges = loadSymbolEdges(db, options);
166
+ const uf = new UnionFind();
167
+ for (const { source, target } of edges) {
168
+ uf.makeSet(source);
169
+ uf.makeSet(target);
170
+ uf.union(source, target);
171
+ }
172
+ return uf.components().filter(c => c.length > 1);
173
+ }
174
+ /** Simple union-find with path compression and union by rank. */
175
+ class UnionFind {
176
+ parent = new Map();
177
+ rank = new Map();
178
+ makeSet(x) {
179
+ if (!this.parent.has(x)) {
180
+ this.parent.set(x, x);
181
+ this.rank.set(x, 0);
182
+ }
183
+ }
184
+ find(x) {
185
+ let root = x;
186
+ while (this.parent.get(root) !== root) {
187
+ root = this.parent.get(root);
188
+ }
189
+ // Path compression
190
+ let curr = x;
191
+ while (curr !== root) {
192
+ const next = this.parent.get(curr);
193
+ this.parent.set(curr, root);
194
+ curr = next;
195
+ }
196
+ return root;
197
+ }
198
+ union(a, b) {
199
+ this.makeSet(a);
200
+ this.makeSet(b);
201
+ const ra = this.find(a);
202
+ const rb = this.find(b);
203
+ if (ra === rb)
204
+ return;
205
+ const rankA = this.rank.get(ra);
206
+ const rankB = this.rank.get(rb);
207
+ if (rankA < rankB) {
208
+ this.parent.set(ra, rb);
209
+ }
210
+ else if (rankA > rankB) {
211
+ this.parent.set(rb, ra);
212
+ }
213
+ else {
214
+ this.parent.set(rb, ra);
215
+ this.rank.set(ra, rankA + 1);
216
+ }
217
+ }
218
+ components() {
219
+ const groups = new Map();
220
+ for (const x of this.parent.keys()) {
221
+ const root = this.find(x);
222
+ let list = groups.get(root);
223
+ if (!list) {
224
+ list = [];
225
+ groups.set(root, list);
226
+ }
227
+ list.push(x);
228
+ }
229
+ return [...groups.values()];
230
+ }
231
+ }
232
+ /**
233
+ * Partition the symbol call graph into bounded-size coherent clusters.
234
+ *
235
+ * Algorithm:
236
+ * 1. Contract SCCs (mutually dependent symbols → same cluster)
237
+ * 2. Merge same-file symbols into one cluster per file
238
+ * 3. Greedy merge by edge weight (respecting maxLines)
239
+ * 4. Fold undersized clusters into their heaviest-edge neighbor
240
+ */
241
+ export function clusterSymbols(db, options = {}) {
242
+ const maxLines = options.maxLinesPerCluster ?? 500;
243
+ const branch = options.branch;
244
+ // Load all symbols with line spans
245
+ const symbolRows = (branch !== undefined
246
+ ? db.prepare(`SELECT s.id, s.file_id, (s.end_line - s.start_line + 1) AS lines
247
+ FROM symbols s JOIN files f ON f.id = s.file_id
248
+ WHERE f.branch = ?`).all(branch)
249
+ : db.prepare('SELECT id, file_id, (end_line - start_line + 1) AS lines FROM symbols').all());
250
+ if (symbolRows.length === 0)
251
+ return [];
252
+ const symbolById = new Map();
253
+ for (const s of symbolRows)
254
+ symbolById.set(s.id, s);
255
+ const edges = loadSymbolEdges(db, options);
256
+ // Filter edges to only include symbols we loaded
257
+ const validEdges = edges.filter(e => symbolById.has(e.source) && symbolById.has(e.target));
258
+ // Step 1: SCC contraction — assign each symbol to a cluster
259
+ const sccs = detectSymbolCycles(db, options);
260
+ const clusterOf = new Map(); // symbol → cluster representative
261
+ let nextCluster = 0;
262
+ for (const scc of sccs) {
263
+ const cid = nextCluster++;
264
+ for (const sid of scc)
265
+ clusterOf.set(sid, cid);
266
+ }
267
+ // Assign singletons
268
+ for (const s of symbolRows) {
269
+ if (!clusterOf.has(s.id)) {
270
+ clusterOf.set(s.id, nextCluster++);
271
+ }
272
+ }
273
+ // Step 2: Same-file merge — merge clusters whose symbols share a file
274
+ const fileToClusterIds = new Map();
275
+ for (const s of symbolRows) {
276
+ const cid = clusterOf.get(s.id);
277
+ let set = fileToClusterIds.get(s.fileId);
278
+ if (!set) {
279
+ set = new Set();
280
+ fileToClusterIds.set(s.fileId, set);
281
+ }
282
+ set.add(cid);
283
+ }
284
+ // Use union-find for merging
285
+ const clusterUf = new UnionFind();
286
+ for (const cid of new Set(clusterOf.values()))
287
+ clusterUf.makeSet(cid);
288
+ for (const clusterIds of fileToClusterIds.values()) {
289
+ const ids = [...clusterIds];
290
+ for (let i = 1; i < ids.length; i++) {
291
+ // Only merge if combined size stays within bounds
292
+ const rootA = clusterUf.find(ids[0]);
293
+ const rootB = clusterUf.find(ids[i]);
294
+ if (rootA !== rootB) {
295
+ const sizeA = clusterLineCount(rootA, clusterOf, clusterUf, symbolById);
296
+ const sizeB = clusterLineCount(rootB, clusterOf, clusterUf, symbolById);
297
+ if (sizeA + sizeB <= maxLines) {
298
+ clusterUf.union(rootA, rootB);
299
+ }
300
+ }
301
+ }
302
+ }
303
+ // Step 3: Greedy merge by edge weight
304
+ const crossEdgeWeights = new Map();
305
+ for (const { source, target } of validEdges) {
306
+ const ca = clusterUf.find(clusterOf.get(source));
307
+ const cb = clusterUf.find(clusterOf.get(target));
308
+ if (ca === cb)
309
+ continue;
310
+ const key = ca < cb ? `${ca}:${cb}` : `${cb}:${ca}`;
311
+ crossEdgeWeights.set(key, (crossEdgeWeights.get(key) ?? 0) + 1);
312
+ }
313
+ // Sort by edge weight descending and greedily merge
314
+ const sortedPairs = [...crossEdgeWeights.entries()]
315
+ .sort((a, b) => b[1] - a[1]);
316
+ for (const [key] of sortedPairs) {
317
+ const [aStr, bStr] = key.split(':');
318
+ const ca = clusterUf.find(Number(aStr));
319
+ const cb = clusterUf.find(Number(bStr));
320
+ if (ca === cb)
321
+ continue;
322
+ const sizeA = clusterLineCount(ca, clusterOf, clusterUf, symbolById);
323
+ const sizeB = clusterLineCount(cb, clusterOf, clusterUf, symbolById);
324
+ if (sizeA + sizeB <= maxLines) {
325
+ clusterUf.union(ca, cb);
326
+ }
327
+ }
328
+ // Step 4: Fold undersized clusters (<30 lines) into heaviest neighbor
329
+ const MIN_CLUSTER_LINES = 30;
330
+ const finalClusters = new Map(); // root → symbol ids
331
+ for (const s of symbolRows) {
332
+ const root = clusterUf.find(clusterOf.get(s.id));
333
+ let list = finalClusters.get(root);
334
+ if (!list) {
335
+ list = [];
336
+ finalClusters.set(root, list);
337
+ }
338
+ list.push(s.id);
339
+ }
340
+ // Find undersized clusters and their best merge target
341
+ for (const [root, symbolIds] of finalClusters) {
342
+ const totalLines = symbolIds.reduce((sum, id) => sum + (symbolById.get(id)?.lines ?? 0), 0);
343
+ if (totalLines >= MIN_CLUSTER_LINES)
344
+ continue;
345
+ // Find the neighbor cluster with the most edges
346
+ let bestNeighbor;
347
+ let bestWeight = 0;
348
+ for (const { source, target } of validEdges) {
349
+ const cs = clusterUf.find(clusterOf.get(source));
350
+ const ct = clusterUf.find(clusterOf.get(target));
351
+ if (cs === root && ct !== root) {
352
+ const neighborLines = clusterLineCount(ct, clusterOf, clusterUf, symbolById);
353
+ if (neighborLines + totalLines <= maxLines) {
354
+ const key = root < ct ? `${root}:${ct}` : `${ct}:${root}`;
355
+ const w = crossEdgeWeights.get(key) ?? 1;
356
+ if (w > bestWeight) {
357
+ bestWeight = w;
358
+ bestNeighbor = ct;
359
+ }
360
+ }
361
+ }
362
+ else if (ct === root && cs !== root) {
363
+ const neighborLines = clusterLineCount(cs, clusterOf, clusterUf, symbolById);
364
+ if (neighborLines + totalLines <= maxLines) {
365
+ const key = root < cs ? `${root}:${cs}` : `${cs}:${root}`;
366
+ const w = crossEdgeWeights.get(key) ?? 1;
367
+ if (w > bestWeight) {
368
+ bestWeight = w;
369
+ bestNeighbor = cs;
370
+ }
371
+ }
372
+ }
373
+ }
374
+ if (bestNeighbor !== undefined) {
375
+ clusterUf.union(root, bestNeighbor);
376
+ }
377
+ }
378
+ // Build final result
379
+ const resultMap = new Map();
380
+ for (const s of symbolRows) {
381
+ const root = clusterUf.find(clusterOf.get(s.id));
382
+ let entry = resultMap.get(root);
383
+ if (!entry) {
384
+ entry = { symbolIds: [], fileIds: new Set(), totalLines: 0 };
385
+ resultMap.set(root, entry);
386
+ }
387
+ entry.symbolIds.push(s.id);
388
+ entry.fileIds.add(s.fileId);
389
+ entry.totalLines += s.lines;
390
+ }
391
+ // Count internal/external edges per cluster
392
+ const results = [];
393
+ let idx = 0;
394
+ for (const entry of resultMap.values()) {
395
+ const memberSet = new Set(entry.symbolIds);
396
+ let internalEdges = 0;
397
+ let externalEdges = 0;
398
+ for (const { source, target } of validEdges) {
399
+ const sIn = memberSet.has(source);
400
+ const tIn = memberSet.has(target);
401
+ if (sIn && tIn)
402
+ internalEdges++;
403
+ else if (sIn || tIn)
404
+ externalEdges++;
405
+ }
406
+ results.push({
407
+ id: idx++,
408
+ symbolIds: entry.symbolIds,
409
+ totalLines: entry.totalLines,
410
+ fileIds: [...entry.fileIds],
411
+ internalEdges,
412
+ externalEdges,
413
+ });
414
+ }
415
+ return results.sort((a, b) => b.totalLines - a.totalLines);
416
+ }
417
+ function clusterLineCount(clusterRoot, clusterOf, uf, symbolById) {
418
+ let total = 0;
419
+ for (const [symId, cid] of clusterOf) {
420
+ if (uf.find(cid) === clusterRoot) {
421
+ total += symbolById.get(symId)?.lines ?? 0;
422
+ }
423
+ }
424
+ return total;
425
+ }
426
+ /**
427
+ * Produces a condensed dependency summary of the codebase — the "30-second
428
+ * architecture overview."
429
+ *
430
+ * Combines symbol clustering with inter-module edge analysis and SCC/CC
431
+ * detection at the module level.
432
+ */
433
+ export function buildCodebaseSummary(db, options = {}) {
434
+ const branch = options.branch;
435
+ // Counts
436
+ const totalFiles = (branch !== undefined
437
+ ? db.prepare('SELECT COUNT(*) AS cnt FROM files WHERE branch = ?').get(branch)
438
+ : db.prepare('SELECT COUNT(*) AS cnt FROM files').get());
439
+ const totalSymbols = (branch !== undefined
440
+ ? db.prepare('SELECT COUNT(*) AS cnt FROM symbols s JOIN files f ON f.id = s.file_id WHERE f.branch = ?').get(branch)
441
+ : db.prepare('SELECT COUNT(*) AS cnt FROM symbols').get());
442
+ const totalEdges = (branch !== undefined
443
+ ? db.prepare(`SELECT COUNT(*) AS cnt FROM symbol_refs sr
444
+ JOIN symbols s ON s.id = sr.caller_id
445
+ JOIN files f ON f.id = s.file_id
446
+ WHERE sr.callee_id IS NOT NULL AND f.branch = ?`).get(branch)
447
+ : db.prepare('SELECT COUNT(*) AS cnt FROM symbol_refs WHERE callee_id IS NOT NULL').get());
448
+ // Cluster symbols into modules
449
+ const clusters = clusterSymbols(db, {
450
+ ...options,
451
+ maxLinesPerCluster: options.maxLinesPerModule ?? 500,
452
+ });
453
+ if (clusters.length === 0) {
454
+ return {
455
+ totalFiles: totalFiles.cnt,
456
+ totalSymbols: totalSymbols.cnt,
457
+ totalEdges: totalEdges.cnt,
458
+ modules: [],
459
+ connectedComponents: [],
460
+ cyclicGroups: [],
461
+ };
462
+ }
463
+ // Build symbol → cluster mapping
464
+ const symbolToCluster = new Map();
465
+ for (const c of clusters) {
466
+ for (const sid of c.symbolIds) {
467
+ symbolToCluster.set(sid, c.id);
468
+ }
469
+ }
470
+ // Load file paths for each cluster
471
+ const filePathById = new Map((branch !== undefined
472
+ ? db.prepare('SELECT id, path FROM files WHERE branch = ?').all(branch)
473
+ : db.prepare('SELECT id, path FROM files').all()).map((r) => [r.id, r.path]));
474
+ // Build module summaries
475
+ const edges = loadSymbolEdges(db, options);
476
+ const moduleAdj = new Map(); // module → set of modules it depends on
477
+ const moduleRevAdj = new Map(); // module → set of modules that depend on it
478
+ for (const c of clusters) {
479
+ moduleAdj.set(c.id, new Set());
480
+ moduleRevAdj.set(c.id, new Set());
481
+ }
482
+ for (const { source, target } of edges) {
483
+ const cm = symbolToCluster.get(source);
484
+ const cn = symbolToCluster.get(target);
485
+ if (cm === undefined || cn === undefined || cm === cn)
486
+ continue;
487
+ moduleAdj.get(cm).add(cn);
488
+ moduleRevAdj.get(cn).add(cm);
489
+ }
490
+ const modules = clusters.map(c => ({
491
+ id: c.id,
492
+ files: c.fileIds.map(fid => filePathById.get(fid) ?? `file:${fid}`).sort(),
493
+ symbolCount: c.symbolIds.length,
494
+ totalLines: c.totalLines,
495
+ dependsOn: [...(moduleAdj.get(c.id) ?? [])].sort((a, b) => a - b),
496
+ dependedOnBy: [...(moduleRevAdj.get(c.id) ?? [])].sort((a, b) => a - b),
497
+ }));
498
+ // Module-level connected components
499
+ const moduleUf = new UnionFind();
500
+ for (const c of clusters)
501
+ moduleUf.makeSet(c.id);
502
+ for (const { source, target } of edges) {
503
+ const cm = symbolToCluster.get(source);
504
+ const cn = symbolToCluster.get(target);
505
+ if (cm !== undefined && cn !== undefined && cm !== cn) {
506
+ moduleUf.union(cm, cn);
507
+ }
508
+ }
509
+ const connectedComponents = moduleUf.components().filter(c => c.length > 1);
510
+ // Module-level SCCs
511
+ const moduleSccAdj = new Map();
512
+ for (const c of clusters)
513
+ moduleSccAdj.set(c.id, []);
514
+ for (const [mid, deps] of moduleAdj) {
515
+ moduleSccAdj.set(mid, [...deps]);
516
+ }
517
+ const cyclicGroups = tarjanScc(moduleSccAdj);
518
+ return {
519
+ totalFiles: totalFiles.cnt,
520
+ totalSymbols: totalSymbols.cnt,
521
+ totalEdges: totalEdges.cnt,
522
+ modules,
523
+ connectedComponents,
524
+ cyclicGroups,
525
+ };
526
+ }
527
+ /** Generic Tarjan's SCC for number-keyed adjacency. */
528
+ function tarjanScc(adjacency) {
529
+ let index = 0;
530
+ const indices = new Map();
531
+ const lowlink = new Map();
532
+ const onStack = new Set();
533
+ const stack = [];
534
+ const sccs = [];
535
+ function strongConnect(v) {
536
+ indices.set(v, index);
537
+ lowlink.set(v, index);
538
+ index++;
539
+ stack.push(v);
540
+ onStack.add(v);
541
+ for (const w of adjacency.get(v) ?? []) {
542
+ if (!indices.has(w)) {
543
+ strongConnect(w);
544
+ lowlink.set(v, Math.min(lowlink.get(v), lowlink.get(w)));
545
+ }
546
+ else if (onStack.has(w)) {
547
+ lowlink.set(v, Math.min(lowlink.get(v), indices.get(w)));
548
+ }
549
+ }
550
+ if (lowlink.get(v) === indices.get(v)) {
551
+ const scc = [];
552
+ let w;
553
+ do {
554
+ w = stack.pop();
555
+ onStack.delete(w);
556
+ scc.push(w);
557
+ } while (w !== v);
558
+ if (scc.length > 1) {
559
+ sccs.push(scc);
560
+ }
561
+ else {
562
+ const selfLoop = (adjacency.get(scc[0]) ?? []).includes(scc[0]);
563
+ if (selfLoop)
564
+ sccs.push(scc);
565
+ }
566
+ }
567
+ }
568
+ for (const node of adjacency.keys()) {
569
+ if (!indices.has(node)) {
570
+ strongConnect(node);
571
+ }
572
+ }
573
+ return sccs;
574
+ }
575
+ //# sourceMappingURL=graph-analysis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-analysis.js","sourceRoot":"","sources":["../../src/indexer/graph-analysis.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,15 @@
3
3
  *
4
4
  * Pipeline stage: embed symbol signatures, documentation sections, and
5
5
  * commit messages into vec0 virtual tables for semantic search.
6
+ *
7
+ * Optimisations:
8
+ * - **Token-aware batching**: batches are sized by estimated token budget
9
+ * rather than a fixed item count, avoiding pathological padding waste
10
+ * when one long signature inflates the whole batch.
11
+ * - **Skip-unchanged**: in update mode, symbols whose embedding input text
12
+ * has not changed (by SHA-256 hash) are skipped entirely.
13
+ * - **Double-buffered I/O**: the next `embed()` call fires while the
14
+ * current batch's vectors are written to SQLite.
6
15
  */
7
16
  import type { PipelineContext, PipelineStage } from '../pipeline.js';
8
17
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"embedding.d.ts","sourceRoot":"","sources":["../../../src/indexer/stages/embedding.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AASrE;;;;GAIG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,eAAe;IAEtB,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CA6BjF"}
1
+ {"version":3,"file":"embedding.d.ts","sourceRoot":"","sources":["../../../src/indexer/stages/embedding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAMrE;;;;GAIG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,eAAe;IAEtB,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CA6BjF"}