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.
- package/LICENSE +21 -0
- package/README.md +554 -0
- package/dist/change-tracker/change-log.d.ts +160 -0
- package/dist/change-tracker/change-log.d.ts.map +1 -0
- package/dist/change-tracker/change-log.js +507 -0
- package/dist/change-tracker/change-log.js.map +1 -0
- package/dist/change-tracker/diff-engine.d.ts +149 -0
- package/dist/change-tracker/diff-engine.d.ts.map +1 -0
- package/dist/change-tracker/diff-engine.js +530 -0
- package/dist/change-tracker/diff-engine.js.map +1 -0
- package/dist/change-tracker/watcher.d.ts +137 -0
- package/dist/change-tracker/watcher.d.ts.map +1 -0
- package/dist/change-tracker/watcher.js +300 -0
- package/dist/change-tracker/watcher.js.map +1 -0
- package/dist/cli.d.ts +20 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +937 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +38 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +222 -0
- package/dist/config.js.map +1 -0
- package/dist/context/compressor.d.ts +49 -0
- package/dist/context/compressor.d.ts.map +1 -0
- package/dist/context/compressor.js +769 -0
- package/dist/context/compressor.js.map +1 -0
- package/dist/context/progressive-disclosure.d.ts +71 -0
- package/dist/context/progressive-disclosure.d.ts.map +1 -0
- package/dist/context/progressive-disclosure.js +470 -0
- package/dist/context/progressive-disclosure.js.map +1 -0
- package/dist/context/token-budget.d.ts +121 -0
- package/dist/context/token-budget.d.ts.map +1 -0
- package/dist/context/token-budget.js +282 -0
- package/dist/context/token-budget.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +944 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +66 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +946 -0
- package/dist/install.js.map +1 -0
- package/dist/knowledge-graph/architecture.d.ts +213 -0
- package/dist/knowledge-graph/architecture.d.ts.map +1 -0
- package/dist/knowledge-graph/architecture.js +585 -0
- package/dist/knowledge-graph/architecture.js.map +1 -0
- package/dist/knowledge-graph/cypher.d.ts +113 -0
- package/dist/knowledge-graph/cypher.d.ts.map +1 -0
- package/dist/knowledge-graph/cypher.js +1051 -0
- package/dist/knowledge-graph/cypher.js.map +1 -0
- package/dist/knowledge-graph/dead-code.d.ts +121 -0
- package/dist/knowledge-graph/dead-code.d.ts.map +1 -0
- package/dist/knowledge-graph/dead-code.js +331 -0
- package/dist/knowledge-graph/dead-code.js.map +1 -0
- package/dist/knowledge-graph/flow-analyzer.d.ts +167 -0
- package/dist/knowledge-graph/flow-analyzer.d.ts.map +1 -0
- package/dist/knowledge-graph/flow-analyzer.js +739 -0
- package/dist/knowledge-graph/flow-analyzer.js.map +1 -0
- package/dist/knowledge-graph/graph.d.ts +291 -0
- package/dist/knowledge-graph/graph.d.ts.map +1 -0
- package/dist/knowledge-graph/graph.js +978 -0
- package/dist/knowledge-graph/graph.js.map +1 -0
- package/dist/knowledge-graph/index.d.ts +17 -0
- package/dist/knowledge-graph/index.d.ts.map +1 -0
- package/dist/knowledge-graph/index.js +14 -0
- package/dist/knowledge-graph/index.js.map +1 -0
- package/dist/knowledge-graph/indexer.d.ts +112 -0
- package/dist/knowledge-graph/indexer.d.ts.map +1 -0
- package/dist/knowledge-graph/indexer.js +506 -0
- package/dist/knowledge-graph/indexer.js.map +1 -0
- package/dist/knowledge-graph/pagerank.d.ts +141 -0
- package/dist/knowledge-graph/pagerank.d.ts.map +1 -0
- package/dist/knowledge-graph/pagerank.js +493 -0
- package/dist/knowledge-graph/pagerank.js.map +1 -0
- package/dist/knowledge-graph/parser.d.ts +55 -0
- package/dist/knowledge-graph/parser.d.ts.map +1 -0
- package/dist/knowledge-graph/parser.js +1090 -0
- package/dist/knowledge-graph/parser.js.map +1 -0
- package/dist/knowledge-graph/snapshot.d.ts +107 -0
- package/dist/knowledge-graph/snapshot.d.ts.map +1 -0
- package/dist/knowledge-graph/snapshot.js +435 -0
- package/dist/knowledge-graph/snapshot.js.map +1 -0
- package/dist/memory/decision-log.d.ts +151 -0
- package/dist/memory/decision-log.d.ts.map +1 -0
- package/dist/memory/decision-log.js +482 -0
- package/dist/memory/decision-log.js.map +1 -0
- package/dist/memory/persistent-memory.d.ts +182 -0
- package/dist/memory/persistent-memory.d.ts.map +1 -0
- package/dist/memory/persistent-memory.js +579 -0
- package/dist/memory/persistent-memory.js.map +1 -0
- package/dist/memory/session-memory.d.ts +165 -0
- package/dist/memory/session-memory.d.ts.map +1 -0
- package/dist/memory/session-memory.js +382 -0
- package/dist/memory/session-memory.js.map +1 -0
- package/dist/stress-test.d.ts +10 -0
- package/dist/stress-test.d.ts.map +1 -0
- package/dist/stress-test.js +258 -0
- package/dist/stress-test.js.map +1 -0
- package/dist/tools/advanced-tools.d.ts +32 -0
- package/dist/tools/advanced-tools.d.ts.map +1 -0
- package/dist/tools/advanced-tools.js +480 -0
- package/dist/tools/advanced-tools.js.map +1 -0
- package/dist/tools/change-tools.d.ts +76 -0
- package/dist/tools/change-tools.d.ts.map +1 -0
- package/dist/tools/change-tools.js +93 -0
- package/dist/tools/change-tools.js.map +1 -0
- package/dist/tools/context-tools.d.ts +68 -0
- package/dist/tools/context-tools.d.ts.map +1 -0
- package/dist/tools/context-tools.js +141 -0
- package/dist/tools/context-tools.js.map +1 -0
- package/dist/tools/debug-tools.d.ts +25 -0
- package/dist/tools/debug-tools.d.ts.map +1 -0
- package/dist/tools/debug-tools.js +286 -0
- package/dist/tools/debug-tools.js.map +1 -0
- package/dist/tools/evolving-tools.d.ts +23 -0
- package/dist/tools/evolving-tools.d.ts.map +1 -0
- package/dist/tools/evolving-tools.js +207 -0
- package/dist/tools/evolving-tools.js.map +1 -0
- package/dist/tools/flow-tools.d.ts +24 -0
- package/dist/tools/flow-tools.d.ts.map +1 -0
- package/dist/tools/flow-tools.js +265 -0
- package/dist/tools/flow-tools.js.map +1 -0
- package/dist/tools/graph-tools.d.ts +71 -0
- package/dist/tools/graph-tools.d.ts.map +1 -0
- package/dist/tools/graph-tools.js +165 -0
- package/dist/tools/graph-tools.js.map +1 -0
- package/dist/tools/memory-tools.d.ts +62 -0
- package/dist/tools/memory-tools.d.ts.map +1 -0
- package/dist/tools/memory-tools.js +195 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/smart-tools.d.ts +23 -0
- package/dist/tools/smart-tools.d.ts.map +1 -0
- package/dist/tools/smart-tools.js +482 -0
- package/dist/tools/smart-tools.js.map +1 -0
- package/dist/tools/snapshot-tools.d.ts +19 -0
- package/dist/tools/snapshot-tools.d.ts.map +1 -0
- package/dist/tools/snapshot-tools.js +149 -0
- package/dist/tools/snapshot-tools.js.map +1 -0
- package/dist/types.d.ts +181 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +45 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/logger.d.ts +59 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +142 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/token-counter.d.ts +51 -0
- package/dist/utils/token-counter.d.ts.map +1 -0
- package/dist/utils/token-counter.js +181 -0
- package/dist/utils/token-counter.js.map +1 -0
- package/install.ps1 +321 -0
- package/install.sh +345 -0
- package/package.json +94 -0
- package/setup.bat +62 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Mind Map — Codebase Indexer (Full & Incremental)
|
|
3
|
+
*
|
|
4
|
+
* Scans a project's source files, parses each with the tree-sitter/regex parser,
|
|
5
|
+
* and stores extracted structural information in the knowledge graph.
|
|
6
|
+
*
|
|
7
|
+
* Supports full re-indexing and incremental updates (only re-parse changed files).
|
|
8
|
+
* Respects .gitignore patterns and custom ignore lists.
|
|
9
|
+
*
|
|
10
|
+
* Inspired by CocoIndex's incremental approach and Cursor's Merkle tree.
|
|
11
|
+
*/
|
|
12
|
+
import { readFileSync } from 'node:fs';
|
|
13
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
14
|
+
import { relative, join } from 'node:path';
|
|
15
|
+
import { glob } from 'glob';
|
|
16
|
+
import ignore from 'ignore';
|
|
17
|
+
import { parseFile, parseFiles, isSupportedFile, detectLanguage, getSupportedExtensions, generateContentHash, } from './parser.js';
|
|
18
|
+
/** Maximum file size to index (default 512KB). Files larger than this are skipped to prevent OOM. */
|
|
19
|
+
const MAX_FILE_SIZE_BYTES = 512 * 1024;
|
|
20
|
+
// ============================================================
|
|
21
|
+
// Indexer Class
|
|
22
|
+
// ============================================================
|
|
23
|
+
/**
|
|
24
|
+
* Codebase indexer that scans, parses, and indexes source files
|
|
25
|
+
* into the knowledge graph.
|
|
26
|
+
*/
|
|
27
|
+
export class Indexer {
|
|
28
|
+
graph;
|
|
29
|
+
config;
|
|
30
|
+
ig;
|
|
31
|
+
constructor(graph, config) {
|
|
32
|
+
this.graph = graph;
|
|
33
|
+
this.config = config;
|
|
34
|
+
this.ig = ignore();
|
|
35
|
+
// Load .gitignore patterns
|
|
36
|
+
this.loadIgnorePatterns();
|
|
37
|
+
}
|
|
38
|
+
/** Load ignore patterns from .gitignore and config */
|
|
39
|
+
loadIgnorePatterns() {
|
|
40
|
+
// Add config-specified ignore patterns
|
|
41
|
+
if (this.config.ignore.length > 0) {
|
|
42
|
+
this.ig.add(this.config.ignore);
|
|
43
|
+
}
|
|
44
|
+
// Try to read .gitignore
|
|
45
|
+
try {
|
|
46
|
+
const gitignorePath = join(this.config.projectRoot, '.gitignore');
|
|
47
|
+
const gitignoreContent = readFileSync(gitignorePath, 'utf-8');
|
|
48
|
+
this.ig.add(gitignoreContent);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// No .gitignore file, continue
|
|
52
|
+
}
|
|
53
|
+
// Try nested .gitignore files
|
|
54
|
+
try {
|
|
55
|
+
const nestedIgnores = [
|
|
56
|
+
join(this.config.projectRoot, 'src', '.gitignore'),
|
|
57
|
+
join(this.config.projectRoot, 'packages', '.gitignore'),
|
|
58
|
+
];
|
|
59
|
+
for (const p of nestedIgnores) {
|
|
60
|
+
try {
|
|
61
|
+
const content = readFileSync(p, 'utf-8');
|
|
62
|
+
this.ig.add(content);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Skip non-existent files
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Skip
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Scan the project directory for indexable source files.
|
|
75
|
+
*
|
|
76
|
+
* Respects .gitignore and custom ignore patterns.
|
|
77
|
+
* Skips binary files and files exceeding maxFileSize.
|
|
78
|
+
*/
|
|
79
|
+
async scanFiles() {
|
|
80
|
+
const extensions = getSupportedExtensions();
|
|
81
|
+
// Build glob patterns from supported extensions
|
|
82
|
+
const patterns = extensions.map(ext => `**/*${ext}`);
|
|
83
|
+
// Find all matching files
|
|
84
|
+
const allFiles = [];
|
|
85
|
+
for (const pattern of patterns) {
|
|
86
|
+
const matches = await glob(pattern, {
|
|
87
|
+
cwd: this.config.projectRoot,
|
|
88
|
+
absolute: true,
|
|
89
|
+
nodir: true,
|
|
90
|
+
dot: false,
|
|
91
|
+
ignore: this.config.ignore.map(p => {
|
|
92
|
+
// Convert simple names to glob patterns
|
|
93
|
+
if (!p.includes('/') && !p.includes('*')) {
|
|
94
|
+
return `**/${p}/**`;
|
|
95
|
+
}
|
|
96
|
+
return p;
|
|
97
|
+
}),
|
|
98
|
+
});
|
|
99
|
+
allFiles.push(...matches);
|
|
100
|
+
}
|
|
101
|
+
// De-duplicate
|
|
102
|
+
const uniqueFiles = [...new Set(allFiles)];
|
|
103
|
+
// Filter through ignore patterns and size checks
|
|
104
|
+
const validFiles = [];
|
|
105
|
+
for (const absPath of uniqueFiles) {
|
|
106
|
+
const relPath = relative(this.config.projectRoot, absPath).replace(/\\/g, '/');
|
|
107
|
+
// Check ignore patterns
|
|
108
|
+
if (this.ig.ignores(relPath))
|
|
109
|
+
continue;
|
|
110
|
+
// Check file size
|
|
111
|
+
try {
|
|
112
|
+
const fileStat = await stat(absPath);
|
|
113
|
+
if (fileStat.size > this.config.maxFileSize)
|
|
114
|
+
continue;
|
|
115
|
+
if (fileStat.size === 0)
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
// Check if it's a supported source file
|
|
122
|
+
if (!isSupportedFile(absPath))
|
|
123
|
+
continue;
|
|
124
|
+
validFiles.push(absPath);
|
|
125
|
+
}
|
|
126
|
+
return validFiles.sort();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Perform a full index of the entire codebase.
|
|
130
|
+
*
|
|
131
|
+
* Scans all files, parses each, and stores results in the graph.
|
|
132
|
+
* Clears existing data before indexing.
|
|
133
|
+
*
|
|
134
|
+
* @param onProgress - Optional progress callback
|
|
135
|
+
* @returns Indexing statistics
|
|
136
|
+
*/
|
|
137
|
+
async fullIndex(onProgress) {
|
|
138
|
+
const startTime = Date.now();
|
|
139
|
+
const stats = {
|
|
140
|
+
filesScanned: 0,
|
|
141
|
+
filesParsed: 0,
|
|
142
|
+
filesSkipped: 0,
|
|
143
|
+
filesDeleted: 0,
|
|
144
|
+
nodesCreated: 0,
|
|
145
|
+
edgesCreated: 0,
|
|
146
|
+
parseErrors: 0,
|
|
147
|
+
durationMs: 0,
|
|
148
|
+
languages: {},
|
|
149
|
+
};
|
|
150
|
+
// Phase 1: Scanning
|
|
151
|
+
onProgress?.({
|
|
152
|
+
phase: 'scanning',
|
|
153
|
+
current: 0,
|
|
154
|
+
total: 0,
|
|
155
|
+
message: 'Scanning project for source files...',
|
|
156
|
+
});
|
|
157
|
+
const files = await this.scanFiles();
|
|
158
|
+
stats.filesScanned = files.length;
|
|
159
|
+
if (files.length === 0) {
|
|
160
|
+
onProgress?.({
|
|
161
|
+
phase: 'complete',
|
|
162
|
+
current: 0,
|
|
163
|
+
total: 0,
|
|
164
|
+
message: 'No source files found to index.',
|
|
165
|
+
});
|
|
166
|
+
stats.durationMs = Date.now() - startTime;
|
|
167
|
+
return stats;
|
|
168
|
+
}
|
|
169
|
+
// Clear existing graph data
|
|
170
|
+
this.graph.clear();
|
|
171
|
+
// Phase 2: Parsing
|
|
172
|
+
onProgress?.({
|
|
173
|
+
phase: 'parsing',
|
|
174
|
+
current: 0,
|
|
175
|
+
total: files.length,
|
|
176
|
+
message: `Parsing ${files.length} files...`,
|
|
177
|
+
});
|
|
178
|
+
const parseResults = await parseFiles(files, 8, (current, total) => {
|
|
179
|
+
onProgress?.({
|
|
180
|
+
phase: 'parsing',
|
|
181
|
+
current,
|
|
182
|
+
total,
|
|
183
|
+
currentFile: files[Math.min(current, files.length - 1)],
|
|
184
|
+
message: `Parsed ${current}/${total} files`,
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
// Phase 3: Storing
|
|
188
|
+
onProgress?.({
|
|
189
|
+
phase: 'storing',
|
|
190
|
+
current: 0,
|
|
191
|
+
total: parseResults.length,
|
|
192
|
+
message: 'Storing parsed data in knowledge graph...',
|
|
193
|
+
});
|
|
194
|
+
for (let i = 0; i < parseResults.length; i++) {
|
|
195
|
+
const result = parseResults[i];
|
|
196
|
+
// If any single file fails, log and continue
|
|
197
|
+
try {
|
|
198
|
+
if (result.nodes.length === 0 && result.parseErrors.length > 0) {
|
|
199
|
+
stats.filesSkipped++;
|
|
200
|
+
stats.parseErrors += result.parseErrors.length;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
stats.filesParsed++;
|
|
204
|
+
stats.nodesCreated += result.nodes.length;
|
|
205
|
+
stats.edgesCreated += result.edges.length;
|
|
206
|
+
// Track language distribution
|
|
207
|
+
if (result.language !== 'unknown') {
|
|
208
|
+
stats.languages[result.language] = (stats.languages[result.language] ?? 0) + 1;
|
|
209
|
+
}
|
|
210
|
+
if (result.parseErrors.length > 0) {
|
|
211
|
+
stats.parseErrors += result.parseErrors.length;
|
|
212
|
+
}
|
|
213
|
+
// Store in graph
|
|
214
|
+
this.graph.replaceFileData(result.filePath, result.nodes, result.edges);
|
|
215
|
+
if (i % 50 === 0) {
|
|
216
|
+
onProgress?.({
|
|
217
|
+
phase: 'storing',
|
|
218
|
+
current: i + 1,
|
|
219
|
+
total: parseResults.length,
|
|
220
|
+
currentFile: result.filePath,
|
|
221
|
+
message: `Stored ${i + 1}/${parseResults.length} files`,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
stats.parseErrors++;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Phase 4: Complete
|
|
230
|
+
stats.durationMs = Date.now() - startTime;
|
|
231
|
+
onProgress?.({
|
|
232
|
+
phase: 'complete',
|
|
233
|
+
current: stats.filesParsed,
|
|
234
|
+
total: stats.filesScanned,
|
|
235
|
+
message: `Indexing complete: ${stats.filesParsed} files, ${stats.nodesCreated} nodes, ${stats.edgesCreated} edges in ${stats.durationMs}ms`,
|
|
236
|
+
});
|
|
237
|
+
return stats;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Perform an incremental index — only re-parse files that have changed.
|
|
241
|
+
*
|
|
242
|
+
* Detects changes by comparing content hashes stored in the graph
|
|
243
|
+
* against current file contents.
|
|
244
|
+
*
|
|
245
|
+
* @param onProgress - Optional progress callback
|
|
246
|
+
* @returns Indexing statistics
|
|
247
|
+
*/
|
|
248
|
+
async incrementalIndex(onProgress) {
|
|
249
|
+
const startTime = Date.now();
|
|
250
|
+
const stats = {
|
|
251
|
+
filesScanned: 0,
|
|
252
|
+
filesParsed: 0,
|
|
253
|
+
filesSkipped: 0,
|
|
254
|
+
filesDeleted: 0,
|
|
255
|
+
nodesCreated: 0,
|
|
256
|
+
edgesCreated: 0,
|
|
257
|
+
parseErrors: 0,
|
|
258
|
+
durationMs: 0,
|
|
259
|
+
languages: {},
|
|
260
|
+
};
|
|
261
|
+
// Phase 1: Scanning
|
|
262
|
+
onProgress?.({
|
|
263
|
+
phase: 'scanning',
|
|
264
|
+
current: 0,
|
|
265
|
+
total: 0,
|
|
266
|
+
message: 'Scanning for changes...',
|
|
267
|
+
});
|
|
268
|
+
const currentFiles = await this.scanFiles();
|
|
269
|
+
stats.filesScanned = currentFiles.length;
|
|
270
|
+
const indexedFiles = new Set(this.graph.getIndexedFiles());
|
|
271
|
+
const currentFileSet = new Set(currentFiles);
|
|
272
|
+
// Find files to add/update and files to delete
|
|
273
|
+
const filesToParse = [];
|
|
274
|
+
const filesToDelete = [];
|
|
275
|
+
// Check for new or modified files
|
|
276
|
+
for (const filePath of currentFiles) {
|
|
277
|
+
const existingHash = this.graph.getFileHash(filePath);
|
|
278
|
+
if (!existingHash) {
|
|
279
|
+
// New file
|
|
280
|
+
filesToParse.push(filePath);
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
// Check if content has changed
|
|
284
|
+
try {
|
|
285
|
+
const content = await readFile(filePath, 'utf-8');
|
|
286
|
+
const currentHash = generateContentHash(content);
|
|
287
|
+
if (currentHash !== existingHash) {
|
|
288
|
+
filesToParse.push(filePath);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
stats.filesSkipped++;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
stats.filesSkipped++;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Check for deleted files
|
|
299
|
+
for (const indexedFile of indexedFiles) {
|
|
300
|
+
if (!currentFileSet.has(indexedFile)) {
|
|
301
|
+
filesToDelete.push(indexedFile);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
// Phase 2: Handle deletions
|
|
305
|
+
if (filesToDelete.length > 0) {
|
|
306
|
+
onProgress?.({
|
|
307
|
+
phase: 'cleanup',
|
|
308
|
+
current: 0,
|
|
309
|
+
total: filesToDelete.length,
|
|
310
|
+
message: `Removing ${filesToDelete.length} deleted files...`,
|
|
311
|
+
});
|
|
312
|
+
for (const filePath of filesToDelete) {
|
|
313
|
+
const deleted = this.graph.deleteFileNodes(filePath);
|
|
314
|
+
stats.filesDeleted++;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// Phase 3: Parse changed files
|
|
318
|
+
if (filesToParse.length > 0) {
|
|
319
|
+
onProgress?.({
|
|
320
|
+
phase: 'parsing',
|
|
321
|
+
current: 0,
|
|
322
|
+
total: filesToParse.length,
|
|
323
|
+
message: `Parsing ${filesToParse.length} changed files...`,
|
|
324
|
+
});
|
|
325
|
+
const parseResults = await parseFiles(filesToParse, 8, (current, total) => {
|
|
326
|
+
onProgress?.({
|
|
327
|
+
phase: 'parsing',
|
|
328
|
+
current,
|
|
329
|
+
total,
|
|
330
|
+
currentFile: filesToParse[Math.min(current, filesToParse.length - 1)],
|
|
331
|
+
message: `Parsed ${current}/${total} changed files`,
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
// Phase 4: Store results
|
|
335
|
+
onProgress?.({
|
|
336
|
+
phase: 'storing',
|
|
337
|
+
current: 0,
|
|
338
|
+
total: parseResults.length,
|
|
339
|
+
message: 'Updating knowledge graph...',
|
|
340
|
+
});
|
|
341
|
+
for (let i = 0; i < parseResults.length; i++) {
|
|
342
|
+
const result = parseResults[i];
|
|
343
|
+
if (result.nodes.length === 0 && result.parseErrors.length > 0) {
|
|
344
|
+
stats.parseErrors += result.parseErrors.length;
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
stats.filesParsed++;
|
|
348
|
+
stats.nodesCreated += result.nodes.length;
|
|
349
|
+
stats.edgesCreated += result.edges.length;
|
|
350
|
+
if (result.language !== 'unknown') {
|
|
351
|
+
stats.languages[result.language] = (stats.languages[result.language] ?? 0) + 1;
|
|
352
|
+
}
|
|
353
|
+
if (result.parseErrors.length > 0) {
|
|
354
|
+
stats.parseErrors += result.parseErrors.length;
|
|
355
|
+
}
|
|
356
|
+
// Replace file data atomically
|
|
357
|
+
this.graph.replaceFileData(result.filePath, result.nodes, result.edges);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// Phase 5: Complete
|
|
361
|
+
stats.durationMs = Date.now() - startTime;
|
|
362
|
+
const changeCount = filesToParse.length + filesToDelete.length;
|
|
363
|
+
onProgress?.({
|
|
364
|
+
phase: 'complete',
|
|
365
|
+
current: changeCount,
|
|
366
|
+
total: stats.filesScanned,
|
|
367
|
+
message: changeCount > 0
|
|
368
|
+
? `Incremental index: ${stats.filesParsed} updated, ${stats.filesDeleted} deleted in ${stats.durationMs}ms`
|
|
369
|
+
: `No changes detected (${stats.filesScanned} files checked in ${stats.durationMs}ms)`,
|
|
370
|
+
});
|
|
371
|
+
return stats;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Index a single file (e.g., when file watcher detects a change).
|
|
375
|
+
*
|
|
376
|
+
* @param filePath - Absolute path to the changed file
|
|
377
|
+
* @returns Parse result, or null if file was skipped
|
|
378
|
+
*/
|
|
379
|
+
async indexFile(filePath) {
|
|
380
|
+
// Check if file should be ignored
|
|
381
|
+
const relPath = relative(this.config.projectRoot, filePath).replace(/\\/g, '/');
|
|
382
|
+
if (this.ig.ignores(relPath))
|
|
383
|
+
return null;
|
|
384
|
+
if (!isSupportedFile(filePath))
|
|
385
|
+
return null;
|
|
386
|
+
// Skip files that are too large (prevent OOM)
|
|
387
|
+
const fileStat = await stat(filePath).catch(() => null);
|
|
388
|
+
if (!fileStat || fileStat.size > MAX_FILE_SIZE_BYTES) {
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
try {
|
|
392
|
+
if (fileStat.size > this.config.maxFileSize)
|
|
393
|
+
return null;
|
|
394
|
+
if (fileStat.size === 0)
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
catch {
|
|
398
|
+
// File may have been deleted
|
|
399
|
+
this.graph.deleteFileNodes(filePath);
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
const result = await parseFile(filePath);
|
|
403
|
+
if (result.nodes.length > 0) {
|
|
404
|
+
this.graph.replaceFileData(filePath, result.nodes, result.edges);
|
|
405
|
+
}
|
|
406
|
+
return result;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Remove a file from the index (e.g., when file watcher detects deletion).
|
|
410
|
+
*
|
|
411
|
+
* @param filePath - Absolute path to the deleted file
|
|
412
|
+
* @returns Number of nodes removed
|
|
413
|
+
*/
|
|
414
|
+
removeFile(filePath) {
|
|
415
|
+
return this.graph.deleteFileNodes(filePath);
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Auto-detect the languages used in the project based on file extension distribution.
|
|
419
|
+
*
|
|
420
|
+
* @returns Sorted array of language names (most common first)
|
|
421
|
+
*/
|
|
422
|
+
async detectProjectLanguages() {
|
|
423
|
+
const files = await this.scanFiles();
|
|
424
|
+
const langCounts = {};
|
|
425
|
+
for (const file of files) {
|
|
426
|
+
const lang = detectLanguage(file);
|
|
427
|
+
if (lang) {
|
|
428
|
+
langCounts[lang] = (langCounts[lang] ?? 0) + 1;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return Object.entries(langCounts)
|
|
432
|
+
.sort((a, b) => b[1] - a[1])
|
|
433
|
+
.map(([lang]) => lang);
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Get the current indexing status — how many files are indexed vs how many exist.
|
|
437
|
+
*/
|
|
438
|
+
async getIndexStatus() {
|
|
439
|
+
const currentFiles = await this.scanFiles();
|
|
440
|
+
const indexedFiles = this.graph.getIndexedFiles();
|
|
441
|
+
const indexedSet = new Set(indexedFiles);
|
|
442
|
+
let staleCount = 0;
|
|
443
|
+
for (const filePath of currentFiles) {
|
|
444
|
+
if (!indexedSet.has(filePath)) {
|
|
445
|
+
staleCount++;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
// Check for deleted files still in index
|
|
449
|
+
const currentSet = new Set(currentFiles);
|
|
450
|
+
for (const indexedFile of indexedFiles) {
|
|
451
|
+
if (!currentSet.has(indexedFile)) {
|
|
452
|
+
staleCount++;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
const staleness = currentFiles.length > 0 ? staleCount / currentFiles.length : 0;
|
|
456
|
+
return {
|
|
457
|
+
indexedFiles: indexedFiles.length,
|
|
458
|
+
totalFiles: currentFiles.length,
|
|
459
|
+
staleness,
|
|
460
|
+
needsReindex: staleness > 0.1, // More than 10% stale
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
/** Validate the index against the filesystem. Returns files that are stale, missing, or orphaned. */
|
|
464
|
+
async validateIndex() {
|
|
465
|
+
const indexedFiles = this.graph.getIndexedFiles();
|
|
466
|
+
const diskFiles = await this.scanFiles();
|
|
467
|
+
const diskSet = new Set(diskFiles);
|
|
468
|
+
const indexSet = new Set(indexedFiles);
|
|
469
|
+
const missingFiles = [];
|
|
470
|
+
const staleFiles = [];
|
|
471
|
+
const unindexedFiles = [];
|
|
472
|
+
// Check indexed files against disk
|
|
473
|
+
for (const f of indexedFiles) {
|
|
474
|
+
if (!diskSet.has(f)) {
|
|
475
|
+
missingFiles.push(f);
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
// Check if file changed
|
|
479
|
+
try {
|
|
480
|
+
const content = readFileSync(f, 'utf-8');
|
|
481
|
+
const currentHash = (await import('./parser.js')).generateContentHash(content);
|
|
482
|
+
const indexedHash = this.graph.getFileHash(f);
|
|
483
|
+
if (indexedHash && currentHash !== indexedHash) {
|
|
484
|
+
staleFiles.push(f);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
catch {
|
|
488
|
+
staleFiles.push(f);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
// Check for unindexed files
|
|
493
|
+
for (const f of diskFiles) {
|
|
494
|
+
if (!indexSet.has(f)) {
|
|
495
|
+
unindexedFiles.push(f);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
return {
|
|
499
|
+
staleFiles,
|
|
500
|
+
missingFiles,
|
|
501
|
+
unindexedFiles,
|
|
502
|
+
healthy: staleFiles.length === 0 && missingFiles.length === 0 && unindexedFiles.length === 0,
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
//# sourceMappingURL=indexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../src/knowledge-graph/indexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
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
|
+
import type { GraphNode } from '../types.js';
|
|
15
|
+
import { KnowledgeGraph } from './graph.js';
|
|
16
|
+
/** PageRank configuration */
|
|
17
|
+
export interface PageRankConfig {
|
|
18
|
+
/** Damping factor (probability of following a link vs random jump). Default: 0.85 */
|
|
19
|
+
dampingFactor: number;
|
|
20
|
+
/** Maximum iterations before convergence. Default: 100 */
|
|
21
|
+
maxIterations: number;
|
|
22
|
+
/** Convergence threshold (stop when max change < epsilon). Default: 1e-6 */
|
|
23
|
+
epsilon: number;
|
|
24
|
+
}
|
|
25
|
+
/** Ranked node with its PageRank score */
|
|
26
|
+
export interface RankedNode {
|
|
27
|
+
node: GraphNode;
|
|
28
|
+
score: number;
|
|
29
|
+
/** Estimated token cost of this node's signature */
|
|
30
|
+
tokenCost: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* PageRank-based relevance ranking engine for the knowledge graph.
|
|
34
|
+
*
|
|
35
|
+
* Computes structural importance of each node based on the link structure
|
|
36
|
+
* of the codebase graph. Supports personalized PageRank to bias rankings
|
|
37
|
+
* toward nodes relevant to the current conversation or query.
|
|
38
|
+
*/
|
|
39
|
+
export declare class PageRankEngine {
|
|
40
|
+
private graph;
|
|
41
|
+
private config;
|
|
42
|
+
private cache;
|
|
43
|
+
constructor(graph: KnowledgeGraph, config?: Partial<PageRankConfig>);
|
|
44
|
+
/**
|
|
45
|
+
* Compute a hash of the current graph state for cache invalidation.
|
|
46
|
+
* Uses node/edge counts + a sample of recent update timestamps.
|
|
47
|
+
*/
|
|
48
|
+
private computeGraphHash;
|
|
49
|
+
/**
|
|
50
|
+
* Check if the cached PageRank scores are still valid.
|
|
51
|
+
*/
|
|
52
|
+
private isCacheValid;
|
|
53
|
+
/**
|
|
54
|
+
* Invalidate the PageRank cache (call when graph changes).
|
|
55
|
+
*/
|
|
56
|
+
invalidateCache(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Build a weighted adjacency list from graph edges.
|
|
59
|
+
*
|
|
60
|
+
* @returns Adjacency list: nodeId → [(targetId, weight)]
|
|
61
|
+
*/
|
|
62
|
+
private buildAdjacencyList;
|
|
63
|
+
/**
|
|
64
|
+
* Compute standard PageRank for all nodes in the graph.
|
|
65
|
+
*
|
|
66
|
+
* Uses the power iteration method with weighted edges.
|
|
67
|
+
*
|
|
68
|
+
* @returns Map of node ID → PageRank score
|
|
69
|
+
*/
|
|
70
|
+
computePageRank(): Map<string, number>;
|
|
71
|
+
/**
|
|
72
|
+
* Compute Personalized PageRank biased toward specific seed nodes.
|
|
73
|
+
*
|
|
74
|
+
* This is the key algorithm inspired by Aider's approach:
|
|
75
|
+
* instead of uniform random jumps, jumps are biased toward nodes
|
|
76
|
+
* mentioned in the current conversation or query.
|
|
77
|
+
*
|
|
78
|
+
* @param seedNodeIds - Node IDs to bias toward (e.g., nodes matching a query)
|
|
79
|
+
* @param seedWeight - How much to bias toward seeds (0-1, default 0.5)
|
|
80
|
+
* @returns Map of node ID → personalized PageRank score
|
|
81
|
+
*/
|
|
82
|
+
computePersonalizedPageRank(seedNodeIds: string[], seedWeight?: number): Map<string, number>;
|
|
83
|
+
/**
|
|
84
|
+
* Estimate the token cost of a node's signature representation.
|
|
85
|
+
* Rough estimate: ~4 characters per token.
|
|
86
|
+
*/
|
|
87
|
+
private estimateNodeTokenCost;
|
|
88
|
+
/**
|
|
89
|
+
* Get the top-N most important nodes ranked by PageRank.
|
|
90
|
+
*
|
|
91
|
+
* @param limit - Maximum number of nodes to return
|
|
92
|
+
* @param excludeTypes - Node types to exclude (e.g., ['file'] to skip file nodes)
|
|
93
|
+
* @returns Ranked nodes with scores and token costs
|
|
94
|
+
*/
|
|
95
|
+
getTopNodes(limit?: number, excludeTypes?: string[]): RankedNode[];
|
|
96
|
+
/**
|
|
97
|
+
* Get the most relevant nodes for a set of seed nodes (personalized).
|
|
98
|
+
*
|
|
99
|
+
* @param seedNodeIds - Seed node IDs to bias toward
|
|
100
|
+
* @param limit - Maximum number of nodes
|
|
101
|
+
* @param seedWeight - Bias weight (0-1)
|
|
102
|
+
* @param excludeTypes - Node types to exclude
|
|
103
|
+
*/
|
|
104
|
+
getRelevantNodes(seedNodeIds: string[], limit?: number, seedWeight?: number, excludeTypes?: string[]): RankedNode[];
|
|
105
|
+
/**
|
|
106
|
+
* Rank nodes by their scores, applying filters.
|
|
107
|
+
*/
|
|
108
|
+
private rankNodes;
|
|
109
|
+
/**
|
|
110
|
+
* Get nodes that fit within a token budget, ranked by importance.
|
|
111
|
+
*
|
|
112
|
+
* Greedily fills the budget with the highest-ranked nodes first.
|
|
113
|
+
*
|
|
114
|
+
* @param tokenBudget - Maximum tokens to use
|
|
115
|
+
* @param seedNodeIds - Optional seed nodes for personalized ranking
|
|
116
|
+
* @param excludeTypes - Node types to exclude
|
|
117
|
+
* @returns Ranked nodes fitting within budget
|
|
118
|
+
*/
|
|
119
|
+
getNodesWithinBudget(tokenBudget: number, seedNodeIds?: string[], excludeTypes?: string[]): RankedNode[];
|
|
120
|
+
/**
|
|
121
|
+
* Generate a compact repository map string within a token budget.
|
|
122
|
+
*
|
|
123
|
+
* Produces an Aider-style repo map that shows the most important
|
|
124
|
+
* symbols' signatures, organized by file. This is the primary
|
|
125
|
+
* output for token-efficient context.
|
|
126
|
+
*
|
|
127
|
+
* @param tokenBudget - Maximum tokens for the repo map
|
|
128
|
+
* @param seedNodeIds - Optional seed nodes for personalized ranking
|
|
129
|
+
* @returns Compact repo map string
|
|
130
|
+
*/
|
|
131
|
+
generateRepoMap(tokenBudget: number, seedNodeIds?: string[]): string;
|
|
132
|
+
/**
|
|
133
|
+
* Get a simple map of file paths → their top symbols.
|
|
134
|
+
* Useful for a table-of-contents view of the project.
|
|
135
|
+
*
|
|
136
|
+
* @param maxSymbolsPerFile - Max symbols to show per file (default 10)
|
|
137
|
+
* @returns Map of file path → symbol signatures
|
|
138
|
+
*/
|
|
139
|
+
getProjectTOC(maxSymbolsPerFile?: number): Map<string, string[]>;
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=pagerank.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagerank.d.ts","sourceRoot":"","sources":["../../src/knowledge-graph/pagerank.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAuB,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAM5C,6BAA6B;AAC7B,MAAM,WAAW,cAAc;IAC7B,qFAAqF;IACrF,aAAa,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,0CAA0C;AAC1C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;CACnB;AA6CD;;;;;;GAMG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,KAAK,CAA8B;gBAE/B,KAAK,EAAE,cAAc,EAAE,MAAM,GAAE,OAAO,CAAC,cAAc,CAAM;IASvE;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAMpB;;OAEG;IACH,eAAe,IAAI,IAAI;IAQvB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAmC1B;;;;;;OAMG;IACH,eAAe,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAuFtC;;;;;;;;;;OAUG;IACH,2BAA2B,CACzB,WAAW,EAAE,MAAM,EAAE,EACrB,UAAU,GAAE,MAAY,GACvB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAuFtB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;;;;;OAMG;IACH,WAAW,CACT,KAAK,GAAE,MAAW,EAClB,YAAY,GAAE,MAAM,EAAa,GAChC,UAAU,EAAE;IAKf;;;;;;;OAOG;IACH,gBAAgB,CACd,WAAW,EAAE,MAAM,EAAE,EACrB,KAAK,GAAE,MAAW,EAClB,UAAU,GAAE,MAAY,EACxB,YAAY,GAAE,MAAM,EAAa,GAChC,UAAU,EAAE;IAKf;;OAEG;IACH,OAAO,CAAC,SAAS;IAqCjB;;;;;;;;;OASG;IACH,oBAAoB,CAClB,WAAW,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,EAAE,EACtB,YAAY,GAAE,MAAM,EAAa,GAChC,UAAU,EAAE;IA6Cf;;;;;;;;;;OAUG;IACH,eAAe,CACb,WAAW,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,MAAM;IAoET;;;;;;OAMG;IACH,aAAa,CAAC,iBAAiB,GAAE,MAAW,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;CA2BrE"}
|