ai-mind-map 1.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 (154) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +554 -0
  3. package/dist/change-tracker/change-log.d.ts +160 -0
  4. package/dist/change-tracker/change-log.d.ts.map +1 -0
  5. package/dist/change-tracker/change-log.js +507 -0
  6. package/dist/change-tracker/change-log.js.map +1 -0
  7. package/dist/change-tracker/diff-engine.d.ts +149 -0
  8. package/dist/change-tracker/diff-engine.d.ts.map +1 -0
  9. package/dist/change-tracker/diff-engine.js +530 -0
  10. package/dist/change-tracker/diff-engine.js.map +1 -0
  11. package/dist/change-tracker/watcher.d.ts +137 -0
  12. package/dist/change-tracker/watcher.d.ts.map +1 -0
  13. package/dist/change-tracker/watcher.js +300 -0
  14. package/dist/change-tracker/watcher.js.map +1 -0
  15. package/dist/cli.d.ts +20 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +937 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/config.d.ts +38 -0
  20. package/dist/config.d.ts.map +1 -0
  21. package/dist/config.js +222 -0
  22. package/dist/config.js.map +1 -0
  23. package/dist/context/compressor.d.ts +49 -0
  24. package/dist/context/compressor.d.ts.map +1 -0
  25. package/dist/context/compressor.js +769 -0
  26. package/dist/context/compressor.js.map +1 -0
  27. package/dist/context/progressive-disclosure.d.ts +71 -0
  28. package/dist/context/progressive-disclosure.d.ts.map +1 -0
  29. package/dist/context/progressive-disclosure.js +470 -0
  30. package/dist/context/progressive-disclosure.js.map +1 -0
  31. package/dist/context/token-budget.d.ts +121 -0
  32. package/dist/context/token-budget.d.ts.map +1 -0
  33. package/dist/context/token-budget.js +282 -0
  34. package/dist/context/token-budget.js.map +1 -0
  35. package/dist/index.d.ts +13 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +944 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/install.d.ts +66 -0
  40. package/dist/install.d.ts.map +1 -0
  41. package/dist/install.js +946 -0
  42. package/dist/install.js.map +1 -0
  43. package/dist/knowledge-graph/architecture.d.ts +213 -0
  44. package/dist/knowledge-graph/architecture.d.ts.map +1 -0
  45. package/dist/knowledge-graph/architecture.js +585 -0
  46. package/dist/knowledge-graph/architecture.js.map +1 -0
  47. package/dist/knowledge-graph/cypher.d.ts +113 -0
  48. package/dist/knowledge-graph/cypher.d.ts.map +1 -0
  49. package/dist/knowledge-graph/cypher.js +1051 -0
  50. package/dist/knowledge-graph/cypher.js.map +1 -0
  51. package/dist/knowledge-graph/dead-code.d.ts +121 -0
  52. package/dist/knowledge-graph/dead-code.d.ts.map +1 -0
  53. package/dist/knowledge-graph/dead-code.js +331 -0
  54. package/dist/knowledge-graph/dead-code.js.map +1 -0
  55. package/dist/knowledge-graph/flow-analyzer.d.ts +167 -0
  56. package/dist/knowledge-graph/flow-analyzer.d.ts.map +1 -0
  57. package/dist/knowledge-graph/flow-analyzer.js +739 -0
  58. package/dist/knowledge-graph/flow-analyzer.js.map +1 -0
  59. package/dist/knowledge-graph/graph.d.ts +291 -0
  60. package/dist/knowledge-graph/graph.d.ts.map +1 -0
  61. package/dist/knowledge-graph/graph.js +978 -0
  62. package/dist/knowledge-graph/graph.js.map +1 -0
  63. package/dist/knowledge-graph/index.d.ts +17 -0
  64. package/dist/knowledge-graph/index.d.ts.map +1 -0
  65. package/dist/knowledge-graph/index.js +14 -0
  66. package/dist/knowledge-graph/index.js.map +1 -0
  67. package/dist/knowledge-graph/indexer.d.ts +112 -0
  68. package/dist/knowledge-graph/indexer.d.ts.map +1 -0
  69. package/dist/knowledge-graph/indexer.js +506 -0
  70. package/dist/knowledge-graph/indexer.js.map +1 -0
  71. package/dist/knowledge-graph/pagerank.d.ts +141 -0
  72. package/dist/knowledge-graph/pagerank.d.ts.map +1 -0
  73. package/dist/knowledge-graph/pagerank.js +493 -0
  74. package/dist/knowledge-graph/pagerank.js.map +1 -0
  75. package/dist/knowledge-graph/parser.d.ts +55 -0
  76. package/dist/knowledge-graph/parser.d.ts.map +1 -0
  77. package/dist/knowledge-graph/parser.js +1090 -0
  78. package/dist/knowledge-graph/parser.js.map +1 -0
  79. package/dist/knowledge-graph/snapshot.d.ts +107 -0
  80. package/dist/knowledge-graph/snapshot.d.ts.map +1 -0
  81. package/dist/knowledge-graph/snapshot.js +435 -0
  82. package/dist/knowledge-graph/snapshot.js.map +1 -0
  83. package/dist/memory/decision-log.d.ts +151 -0
  84. package/dist/memory/decision-log.d.ts.map +1 -0
  85. package/dist/memory/decision-log.js +482 -0
  86. package/dist/memory/decision-log.js.map +1 -0
  87. package/dist/memory/persistent-memory.d.ts +182 -0
  88. package/dist/memory/persistent-memory.d.ts.map +1 -0
  89. package/dist/memory/persistent-memory.js +579 -0
  90. package/dist/memory/persistent-memory.js.map +1 -0
  91. package/dist/memory/session-memory.d.ts +165 -0
  92. package/dist/memory/session-memory.d.ts.map +1 -0
  93. package/dist/memory/session-memory.js +382 -0
  94. package/dist/memory/session-memory.js.map +1 -0
  95. package/dist/stress-test.d.ts +10 -0
  96. package/dist/stress-test.d.ts.map +1 -0
  97. package/dist/stress-test.js +258 -0
  98. package/dist/stress-test.js.map +1 -0
  99. package/dist/tools/advanced-tools.d.ts +32 -0
  100. package/dist/tools/advanced-tools.d.ts.map +1 -0
  101. package/dist/tools/advanced-tools.js +480 -0
  102. package/dist/tools/advanced-tools.js.map +1 -0
  103. package/dist/tools/change-tools.d.ts +76 -0
  104. package/dist/tools/change-tools.d.ts.map +1 -0
  105. package/dist/tools/change-tools.js +93 -0
  106. package/dist/tools/change-tools.js.map +1 -0
  107. package/dist/tools/context-tools.d.ts +68 -0
  108. package/dist/tools/context-tools.d.ts.map +1 -0
  109. package/dist/tools/context-tools.js +141 -0
  110. package/dist/tools/context-tools.js.map +1 -0
  111. package/dist/tools/debug-tools.d.ts +25 -0
  112. package/dist/tools/debug-tools.d.ts.map +1 -0
  113. package/dist/tools/debug-tools.js +286 -0
  114. package/dist/tools/debug-tools.js.map +1 -0
  115. package/dist/tools/evolving-tools.d.ts +23 -0
  116. package/dist/tools/evolving-tools.d.ts.map +1 -0
  117. package/dist/tools/evolving-tools.js +207 -0
  118. package/dist/tools/evolving-tools.js.map +1 -0
  119. package/dist/tools/flow-tools.d.ts +24 -0
  120. package/dist/tools/flow-tools.d.ts.map +1 -0
  121. package/dist/tools/flow-tools.js +265 -0
  122. package/dist/tools/flow-tools.js.map +1 -0
  123. package/dist/tools/graph-tools.d.ts +71 -0
  124. package/dist/tools/graph-tools.d.ts.map +1 -0
  125. package/dist/tools/graph-tools.js +165 -0
  126. package/dist/tools/graph-tools.js.map +1 -0
  127. package/dist/tools/memory-tools.d.ts +62 -0
  128. package/dist/tools/memory-tools.d.ts.map +1 -0
  129. package/dist/tools/memory-tools.js +195 -0
  130. package/dist/tools/memory-tools.js.map +1 -0
  131. package/dist/tools/smart-tools.d.ts +23 -0
  132. package/dist/tools/smart-tools.d.ts.map +1 -0
  133. package/dist/tools/smart-tools.js +482 -0
  134. package/dist/tools/smart-tools.js.map +1 -0
  135. package/dist/tools/snapshot-tools.d.ts +19 -0
  136. package/dist/tools/snapshot-tools.d.ts.map +1 -0
  137. package/dist/tools/snapshot-tools.js +149 -0
  138. package/dist/tools/snapshot-tools.js.map +1 -0
  139. package/dist/types.d.ts +181 -0
  140. package/dist/types.d.ts.map +1 -0
  141. package/dist/types.js +45 -0
  142. package/dist/types.js.map +1 -0
  143. package/dist/utils/logger.d.ts +59 -0
  144. package/dist/utils/logger.d.ts.map +1 -0
  145. package/dist/utils/logger.js +142 -0
  146. package/dist/utils/logger.js.map +1 -0
  147. package/dist/utils/token-counter.d.ts +51 -0
  148. package/dist/utils/token-counter.d.ts.map +1 -0
  149. package/dist/utils/token-counter.js +181 -0
  150. package/dist/utils/token-counter.js.map +1 -0
  151. package/install.ps1 +321 -0
  152. package/install.sh +345 -0
  153. package/package.json +94 -0
  154. package/setup.bat +62 -0
@@ -0,0 +1,493 @@
1
+ /**
2
+ * AI Mind Map — PageRank-based Relevance Ranking
3
+ *
4
+ * Implements standard and personalized PageRank to rank code symbols
5
+ * by structural importance. Directly inspired by Aider's Personalized
6
+ * PageRank approach for generating compact repo maps within a token budget.
7
+ *
8
+ * Key features:
9
+ * - Standard PageRank with configurable damping factor
10
+ * - Personalized PageRank biased toward conversation-relevant nodes
11
+ * - Token-budget-aware repo map generation
12
+ * - Caching with graph-change invalidation
13
+ */
14
+ // ============================================================
15
+ // Constants
16
+ // ============================================================
17
+ const DEFAULT_CONFIG = {
18
+ dampingFactor: 0.85,
19
+ maxIterations: 100,
20
+ epsilon: 1e-6,
21
+ };
22
+ /**
23
+ * Weights for different edge types when building the adjacency matrix.
24
+ * Higher weight = stronger connection = more rank transferred.
25
+ */
26
+ const EDGE_WEIGHTS = {
27
+ calls: 1.0,
28
+ imports: 0.8,
29
+ exports: 0.6,
30
+ inherits: 1.2,
31
+ implements: 1.1,
32
+ uses: 0.7,
33
+ decorates: 0.5,
34
+ overrides: 1.0,
35
+ contains: 0.9,
36
+ tests: 0.6,
37
+ depends_on: 0.8,
38
+ routes_to: 0.7,
39
+ };
40
+ // ============================================================
41
+ // PageRank Engine
42
+ // ============================================================
43
+ /**
44
+ * PageRank-based relevance ranking engine for the knowledge graph.
45
+ *
46
+ * Computes structural importance of each node based on the link structure
47
+ * of the codebase graph. Supports personalized PageRank to bias rankings
48
+ * toward nodes relevant to the current conversation or query.
49
+ */
50
+ export class PageRankEngine {
51
+ graph;
52
+ config;
53
+ cache = null;
54
+ constructor(graph, config = {}) {
55
+ this.graph = graph;
56
+ this.config = { ...DEFAULT_CONFIG, ...config };
57
+ }
58
+ // ============================================================
59
+ // Graph Hash (for cache invalidation)
60
+ // ============================================================
61
+ /**
62
+ * Compute a hash of the current graph state for cache invalidation.
63
+ * Uses node/edge counts + a sample of recent update timestamps.
64
+ */
65
+ computeGraphHash() {
66
+ const stats = this.graph.getStats();
67
+ return `${stats.totalNodes}:${stats.totalEdges}:${Date.now() >> 16}`;
68
+ }
69
+ /**
70
+ * Check if the cached PageRank scores are still valid.
71
+ */
72
+ isCacheValid() {
73
+ if (!this.cache)
74
+ return false;
75
+ const currentHash = this.computeGraphHash();
76
+ return this.cache.graphHash === currentHash;
77
+ }
78
+ /**
79
+ * Invalidate the PageRank cache (call when graph changes).
80
+ */
81
+ invalidateCache() {
82
+ this.cache = null;
83
+ }
84
+ // ============================================================
85
+ // Adjacency Matrix Construction
86
+ // ============================================================
87
+ /**
88
+ * Build a weighted adjacency list from graph edges.
89
+ *
90
+ * @returns Adjacency list: nodeId → [(targetId, weight)]
91
+ */
92
+ buildAdjacencyList(nodeIds, edges) {
93
+ const nodeSet = new Set(nodeIds);
94
+ const outLinks = new Map();
95
+ const inLinks = new Map();
96
+ // Initialize empty adjacency lists
97
+ for (const id of nodeIds) {
98
+ outLinks.set(id, []);
99
+ inLinks.set(id, []);
100
+ }
101
+ // Populate from edges
102
+ for (const edge of edges) {
103
+ if (!nodeSet.has(edge.sourceId) || !nodeSet.has(edge.targetId))
104
+ continue;
105
+ if (edge.sourceId === edge.targetId)
106
+ continue; // Skip self-loops
107
+ const weight = EDGE_WEIGHTS[edge.type] ?? 0.5;
108
+ outLinks.get(edge.sourceId).push({ target: edge.targetId, weight });
109
+ inLinks.get(edge.targetId).push({ source: edge.sourceId, weight });
110
+ }
111
+ return { outLinks, inLinks };
112
+ }
113
+ // ============================================================
114
+ // Standard PageRank
115
+ // ============================================================
116
+ /**
117
+ * Compute standard PageRank for all nodes in the graph.
118
+ *
119
+ * Uses the power iteration method with weighted edges.
120
+ *
121
+ * @returns Map of node ID → PageRank score
122
+ */
123
+ computePageRank() {
124
+ // Check cache first
125
+ if (this.isCacheValid() && this.cache) {
126
+ return new Map(this.cache.scores);
127
+ }
128
+ const nodeIds = this.graph.getAllNodeIds();
129
+ if (nodeIds.length === 0)
130
+ return new Map();
131
+ const edges = this.graph.getAllEdges();
132
+ const { outLinks, inLinks } = this.buildAdjacencyList(nodeIds, edges);
133
+ const n = nodeIds.length;
134
+ const d = this.config.dampingFactor;
135
+ const uniformProb = 1 / n;
136
+ // Initialize scores uniformly
137
+ let scores = new Map();
138
+ for (const id of nodeIds) {
139
+ scores.set(id, uniformProb);
140
+ }
141
+ // Power iteration
142
+ for (let iter = 0; iter < this.config.maxIterations; iter++) {
143
+ const newScores = new Map();
144
+ let maxDelta = 0;
145
+ // Handle dangling nodes (nodes with no outgoing edges)
146
+ let danglingSum = 0;
147
+ for (const id of nodeIds) {
148
+ if (outLinks.get(id).length === 0) {
149
+ danglingSum += scores.get(id);
150
+ }
151
+ }
152
+ for (const id of nodeIds) {
153
+ // Sum of weighted incoming rank
154
+ let incomingRank = 0;
155
+ const incomingEdges = inLinks.get(id);
156
+ for (const { source, weight } of incomingEdges) {
157
+ const sourceScore = scores.get(source);
158
+ const sourceOutLinks = outLinks.get(source);
159
+ // Total outgoing weight from source
160
+ const totalOutWeight = sourceOutLinks.reduce((sum, l) => sum + l.weight, 0);
161
+ if (totalOutWeight > 0) {
162
+ incomingRank += (sourceScore * weight) / totalOutWeight;
163
+ }
164
+ }
165
+ // PageRank formula with dangling node handling
166
+ const newScore = (1 - d) / n + d * (incomingRank + danglingSum / n);
167
+ newScores.set(id, newScore);
168
+ const delta = Math.abs(newScore - (scores.get(id) ?? 0));
169
+ if (delta > maxDelta)
170
+ maxDelta = delta;
171
+ }
172
+ scores = newScores;
173
+ // Check convergence
174
+ if (maxDelta < this.config.epsilon)
175
+ break;
176
+ }
177
+ // Normalize scores to sum to 1
178
+ const total = Array.from(scores.values()).reduce((s, v) => s + v, 0);
179
+ if (total > 0) {
180
+ for (const [id, score] of scores) {
181
+ scores.set(id, score / total);
182
+ }
183
+ }
184
+ // Cache the results
185
+ this.cache = {
186
+ scores: new Map(scores),
187
+ graphHash: this.computeGraphHash(),
188
+ computedAt: Date.now(),
189
+ };
190
+ return scores;
191
+ }
192
+ // ============================================================
193
+ // Personalized PageRank
194
+ // ============================================================
195
+ /**
196
+ * Compute Personalized PageRank biased toward specific seed nodes.
197
+ *
198
+ * This is the key algorithm inspired by Aider's approach:
199
+ * instead of uniform random jumps, jumps are biased toward nodes
200
+ * mentioned in the current conversation or query.
201
+ *
202
+ * @param seedNodeIds - Node IDs to bias toward (e.g., nodes matching a query)
203
+ * @param seedWeight - How much to bias toward seeds (0-1, default 0.5)
204
+ * @returns Map of node ID → personalized PageRank score
205
+ */
206
+ computePersonalizedPageRank(seedNodeIds, seedWeight = 0.5) {
207
+ const nodeIds = this.graph.getAllNodeIds();
208
+ if (nodeIds.length === 0)
209
+ return new Map();
210
+ const edges = this.graph.getAllEdges();
211
+ const { outLinks, inLinks } = this.buildAdjacencyList(nodeIds, edges);
212
+ const n = nodeIds.length;
213
+ const d = this.config.dampingFactor;
214
+ // Build personalization vector
215
+ const seedSet = new Set(seedNodeIds.filter(id => nodeIds.includes(id)));
216
+ const personalization = new Map();
217
+ if (seedSet.size > 0) {
218
+ const seedProb = seedWeight / seedSet.size;
219
+ const nonSeedProb = (1 - seedWeight) / Math.max(n - seedSet.size, 1);
220
+ for (const id of nodeIds) {
221
+ personalization.set(id, seedSet.has(id) ? seedProb : nonSeedProb);
222
+ }
223
+ }
224
+ else {
225
+ // No valid seeds — fall back to uniform
226
+ const uniformProb = 1 / n;
227
+ for (const id of nodeIds) {
228
+ personalization.set(id, uniformProb);
229
+ }
230
+ }
231
+ // Initialize scores from personalization vector
232
+ let scores = new Map(personalization);
233
+ // Power iteration with personalization
234
+ for (let iter = 0; iter < this.config.maxIterations; iter++) {
235
+ const newScores = new Map();
236
+ let maxDelta = 0;
237
+ // Handle dangling nodes
238
+ let danglingSum = 0;
239
+ for (const id of nodeIds) {
240
+ if (outLinks.get(id).length === 0) {
241
+ danglingSum += scores.get(id);
242
+ }
243
+ }
244
+ for (const id of nodeIds) {
245
+ let incomingRank = 0;
246
+ const incomingEdges = inLinks.get(id);
247
+ for (const { source, weight } of incomingEdges) {
248
+ const sourceScore = scores.get(source);
249
+ const sourceOutLinks = outLinks.get(source);
250
+ const totalOutWeight = sourceOutLinks.reduce((sum, l) => sum + l.weight, 0);
251
+ if (totalOutWeight > 0) {
252
+ incomingRank += (sourceScore * weight) / totalOutWeight;
253
+ }
254
+ }
255
+ // Personalized PageRank: random jumps go to personalization vector instead of uniform
256
+ const pv = personalization.get(id);
257
+ const danglingContrib = danglingSum * pv;
258
+ const newScore = (1 - d) * pv + d * (incomingRank + danglingContrib);
259
+ newScores.set(id, newScore);
260
+ const delta = Math.abs(newScore - (scores.get(id) ?? 0));
261
+ if (delta > maxDelta)
262
+ maxDelta = delta;
263
+ }
264
+ scores = newScores;
265
+ if (maxDelta < this.config.epsilon)
266
+ break;
267
+ }
268
+ // Normalize
269
+ const total = Array.from(scores.values()).reduce((s, v) => s + v, 0);
270
+ if (total > 0) {
271
+ for (const [id, score] of scores) {
272
+ scores.set(id, score / total);
273
+ }
274
+ }
275
+ return scores;
276
+ }
277
+ // ============================================================
278
+ // Ranking & Token Budget
279
+ // ============================================================
280
+ /**
281
+ * Estimate the token cost of a node's signature representation.
282
+ * Rough estimate: ~4 characters per token.
283
+ */
284
+ estimateNodeTokenCost(node) {
285
+ let text = node.signature;
286
+ if (node.docComment) {
287
+ // Include first line of doc comment
288
+ const firstLine = node.docComment.split('\n')[0];
289
+ text += `\n/** ${firstLine} */`;
290
+ }
291
+ return Math.ceil(text.length / 4);
292
+ }
293
+ /**
294
+ * Get the top-N most important nodes ranked by PageRank.
295
+ *
296
+ * @param limit - Maximum number of nodes to return
297
+ * @param excludeTypes - Node types to exclude (e.g., ['file'] to skip file nodes)
298
+ * @returns Ranked nodes with scores and token costs
299
+ */
300
+ getTopNodes(limit = 50, excludeTypes = ['file']) {
301
+ const scores = this.computePageRank();
302
+ return this.rankNodes(scores, limit, excludeTypes);
303
+ }
304
+ /**
305
+ * Get the most relevant nodes for a set of seed nodes (personalized).
306
+ *
307
+ * @param seedNodeIds - Seed node IDs to bias toward
308
+ * @param limit - Maximum number of nodes
309
+ * @param seedWeight - Bias weight (0-1)
310
+ * @param excludeTypes - Node types to exclude
311
+ */
312
+ getRelevantNodes(seedNodeIds, limit = 50, seedWeight = 0.5, excludeTypes = ['file']) {
313
+ const scores = this.computePersonalizedPageRank(seedNodeIds, seedWeight);
314
+ return this.rankNodes(scores, limit, excludeTypes);
315
+ }
316
+ /**
317
+ * Rank nodes by their scores, applying filters.
318
+ */
319
+ rankNodes(scores, limit, excludeTypes) {
320
+ const excludeSet = new Set(excludeTypes);
321
+ // Sort by score descending
322
+ const sortedIds = Array.from(scores.entries())
323
+ .sort((a, b) => b[1] - a[1])
324
+ .map(([id]) => id);
325
+ const ranked = [];
326
+ // Fetch nodes in batches for efficiency
327
+ const batchSize = Math.min(limit * 3, sortedIds.length); // Fetch extra to account for filtering
328
+ const candidateIds = sortedIds.slice(0, batchSize);
329
+ const nodes = this.graph.getNodesByIds(candidateIds);
330
+ const nodeMap = new Map(nodes.map(n => [n.id, n]));
331
+ for (const id of sortedIds) {
332
+ if (ranked.length >= limit)
333
+ break;
334
+ const node = nodeMap.get(id);
335
+ if (!node)
336
+ continue;
337
+ if (excludeSet.has(node.type))
338
+ continue;
339
+ ranked.push({
340
+ node,
341
+ score: scores.get(id),
342
+ tokenCost: this.estimateNodeTokenCost(node),
343
+ });
344
+ }
345
+ return ranked;
346
+ }
347
+ /**
348
+ * Get nodes that fit within a token budget, ranked by importance.
349
+ *
350
+ * Greedily fills the budget with the highest-ranked nodes first.
351
+ *
352
+ * @param tokenBudget - Maximum tokens to use
353
+ * @param seedNodeIds - Optional seed nodes for personalized ranking
354
+ * @param excludeTypes - Node types to exclude
355
+ * @returns Ranked nodes fitting within budget
356
+ */
357
+ getNodesWithinBudget(tokenBudget, seedNodeIds, excludeTypes = ['file']) {
358
+ const scores = seedNodeIds && seedNodeIds.length > 0
359
+ ? this.computePersonalizedPageRank(seedNodeIds)
360
+ : this.computePageRank();
361
+ const excludeSet = new Set(excludeTypes);
362
+ // Sort by score descending
363
+ const sortedIds = Array.from(scores.entries())
364
+ .sort((a, b) => b[1] - a[1])
365
+ .map(([id]) => id);
366
+ const allNodes = this.graph.getNodesByIds(sortedIds.slice(0, sortedIds.length));
367
+ const nodeMap = new Map(allNodes.map(n => [n.id, n]));
368
+ const result = [];
369
+ let usedTokens = 0;
370
+ for (const id of sortedIds) {
371
+ const node = nodeMap.get(id);
372
+ if (!node)
373
+ continue;
374
+ if (excludeSet.has(node.type))
375
+ continue;
376
+ const cost = this.estimateNodeTokenCost(node);
377
+ if (usedTokens + cost > tokenBudget) {
378
+ // Try to fit a few more smaller nodes
379
+ if (cost > tokenBudget * 0.1)
380
+ continue;
381
+ if (usedTokens + cost > tokenBudget)
382
+ break;
383
+ }
384
+ result.push({
385
+ node,
386
+ score: scores.get(id),
387
+ tokenCost: cost,
388
+ });
389
+ usedTokens += cost;
390
+ }
391
+ return result;
392
+ }
393
+ // ============================================================
394
+ // Repo Map Generation
395
+ // ============================================================
396
+ /**
397
+ * Generate a compact repository map string within a token budget.
398
+ *
399
+ * Produces an Aider-style repo map that shows the most important
400
+ * symbols' signatures, organized by file. This is the primary
401
+ * output for token-efficient context.
402
+ *
403
+ * @param tokenBudget - Maximum tokens for the repo map
404
+ * @param seedNodeIds - Optional seed nodes for personalized ranking
405
+ * @returns Compact repo map string
406
+ */
407
+ generateRepoMap(tokenBudget, seedNodeIds) {
408
+ const rankedNodes = this.getNodesWithinBudget(tokenBudget, seedNodeIds);
409
+ if (rankedNodes.length === 0) {
410
+ return '// Empty repo map — no nodes indexed yet';
411
+ }
412
+ // Group nodes by file
413
+ const fileGroups = new Map();
414
+ for (const rn of rankedNodes) {
415
+ const group = fileGroups.get(rn.node.filePath) ?? [];
416
+ group.push(rn);
417
+ fileGroups.set(rn.node.filePath, group);
418
+ }
419
+ // Sort files by max score of their nodes
420
+ const sortedFiles = Array.from(fileGroups.entries())
421
+ .sort((a, b) => {
422
+ const maxA = Math.max(...a[1].map(rn => rn.score));
423
+ const maxB = Math.max(...b[1].map(rn => rn.score));
424
+ return maxB - maxA;
425
+ });
426
+ // Build the repo map string
427
+ const lines = [];
428
+ let currentTokens = 0;
429
+ for (const [filePath, nodes] of sortedFiles) {
430
+ // File header
431
+ const header = `\n// ${filePath}`;
432
+ const headerCost = Math.ceil(header.length / 4);
433
+ if (currentTokens + headerCost > tokenBudget)
434
+ break;
435
+ lines.push(header);
436
+ currentTokens += headerCost;
437
+ // Sort nodes within file by line number
438
+ nodes.sort((a, b) => a.node.startLine - b.node.startLine);
439
+ for (const { node } of nodes) {
440
+ // Build the entry
441
+ let entry = '';
442
+ // Add a brief doc comment if available
443
+ if (node.docComment) {
444
+ const firstLine = node.docComment.split('\n')[0].trim();
445
+ if (firstLine.length <= 80) {
446
+ entry += ` /** ${firstLine} */\n`;
447
+ }
448
+ }
449
+ // Indent methods/properties (nested under class)
450
+ const indent = node.qualifiedName.includes('.') ? ' ' : '';
451
+ entry += `${indent}${node.signature}`;
452
+ const entryCost = Math.ceil(entry.length / 4);
453
+ if (currentTokens + entryCost > tokenBudget)
454
+ continue;
455
+ lines.push(entry);
456
+ currentTokens += entryCost;
457
+ }
458
+ }
459
+ return lines.join('\n').trim();
460
+ }
461
+ /**
462
+ * Get a simple map of file paths → their top symbols.
463
+ * Useful for a table-of-contents view of the project.
464
+ *
465
+ * @param maxSymbolsPerFile - Max symbols to show per file (default 10)
466
+ * @returns Map of file path → symbol signatures
467
+ */
468
+ getProjectTOC(maxSymbolsPerFile = 10) {
469
+ const scores = this.computePageRank();
470
+ const nodeIds = Array.from(scores.keys());
471
+ const allNodes = this.graph.getNodesByIds(nodeIds);
472
+ // Group by file
473
+ const fileNodes = new Map();
474
+ for (const node of allNodes) {
475
+ if (node.type === 'file')
476
+ continue;
477
+ const score = scores.get(node.id) ?? 0;
478
+ const group = fileNodes.get(node.filePath) ?? [];
479
+ group.push({ node, score });
480
+ fileNodes.set(node.filePath, group);
481
+ }
482
+ // Build TOC
483
+ const toc = new Map();
484
+ for (const [filePath, nodes] of fileNodes) {
485
+ // Sort by score, take top N
486
+ nodes.sort((a, b) => b.score - a.score);
487
+ const topNodes = nodes.slice(0, maxSymbolsPerFile);
488
+ toc.set(filePath, topNodes.map(n => n.node.signature));
489
+ }
490
+ return toc;
491
+ }
492
+ }
493
+ //# sourceMappingURL=pagerank.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagerank.js","sourceRoot":"","sources":["../../src/knowledge-graph/pagerank.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * AI Mind Map — Tree-sitter AST Parser with Regex Fallback
3
+ *
4
+ * Extracts structural information (functions, classes, methods, interfaces,
5
+ * types, enums, constants, exports, imports) from source code files.
6
+ *
7
+ * Inspired by codebase-memory-mcp (158 languages) and Aider's repo map.
8
+ * Uses tree-sitter grammars for accurate parsing with a regex-based fallback
9
+ * when native bindings are unavailable or parsing fails.
10
+ */
11
+ import type { GraphNode, GraphEdge } from '../types.js';
12
+ /** Result of parsing a single file */
13
+ export interface ParseResult {
14
+ filePath: string;
15
+ language: string;
16
+ nodes: GraphNode[];
17
+ edges: GraphEdge[];
18
+ parseErrors: string[];
19
+ }
20
+ /** Generate a unique deterministic ID for a node */
21
+ export declare function generateNodeId(filePath: string, name: string, type: string): string;
22
+ /** Generate a content hash for change detection */
23
+ export declare function generateContentHash(content: string): string;
24
+ /** Detect language from file extension */
25
+ export declare function detectLanguage(filePath: string): string | null;
26
+ /** Get all supported file extensions */
27
+ export declare function getSupportedExtensions(): string[];
28
+ /**
29
+ * Parse a source code file and extract its structural information.
30
+ *
31
+ * Attempts tree-sitter parsing first, falls back to regex if unavailable.
32
+ *
33
+ * @param filePath - Absolute path to the source file
34
+ * @param source - Optional pre-read source code (reads from disk if not provided)
35
+ * @returns ParseResult with extracted nodes, edges, and any parse errors
36
+ */
37
+ export declare function parseFile(filePath: string, source?: string): Promise<ParseResult>;
38
+ /**
39
+ * Parse multiple files concurrently in batches.
40
+ *
41
+ * @param files - Array of file paths to parse
42
+ * @param concurrency - Max concurrent parses (default 8)
43
+ * @param onProgress - Optional progress callback (current, total)
44
+ * @returns Array of ParseResults
45
+ */
46
+ export declare function parseFiles(files: string[], concurrency?: number, onProgress?: (current: number, total: number) => void): Promise<ParseResult[]>;
47
+ /**
48
+ * Check if a file extension is supported for parsing.
49
+ */
50
+ export declare function isSupportedFile(filePath: string): boolean;
51
+ /**
52
+ * Get the list of supported languages.
53
+ */
54
+ export declare function getSupportedLanguages(): string[];
55
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/knowledge-graph/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EACV,SAAS,EACT,SAAS,EAIV,MAAM,aAAa,CAAC;AAuErB,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAMD,oDAAoD;AACpD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKnF;AAED,mDAAmD;AACnD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,0CAA0C;AAC1C,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG9D;AAED,wCAAwC;AACxC,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD;AAg8BD;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAmEvF;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EAAE,EACf,WAAW,GAAE,MAAU,EACvB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACpD,OAAO,CAAC,WAAW,EAAE,CAAC,CAiBxB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD"}