memgrid 0.5.0 → 0.5.2
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/CHANGELOG.md +99 -80
- package/LICENSE +21 -21
- package/README.md +284 -251
- package/dist/claude-md.d.ts +4 -0
- package/dist/claude-md.d.ts.map +1 -0
- package/dist/claude-md.js +58 -0
- package/dist/claude-md.js.map +1 -0
- package/dist/hooks.d.ts +18 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +138 -0
- package/dist/hooks.js.map +1 -0
- package/dist/learn/index.d.ts.map +1 -1
- package/dist/learn/index.js +28 -9
- package/dist/learn/index.js.map +1 -1
- package/dist/memgrid.d.ts.map +1 -1
- package/dist/memgrid.js +39 -6
- package/dist/memgrid.js.map +1 -1
- package/dist/retrieve/index.d.ts +1 -1
- package/dist/retrieve/index.d.ts.map +1 -1
- package/dist/retrieve/index.js +17 -13
- package/dist/retrieve/index.js.map +1 -1
- package/dist/retrieve/semantic.d.ts.map +1 -1
- package/dist/retrieve/semantic.js +9 -7
- package/dist/retrieve/semantic.js.map +1 -1
- package/dist/scanner/composite.d.ts.map +1 -1
- package/dist/scanner/composite.js +1 -3
- package/dist/scanner/composite.js.map +1 -1
- package/dist/scanner/config.d.ts.map +1 -1
- package/dist/scanner/config.js +30 -8
- package/dist/scanner/config.js.map +1 -1
- package/dist/scanner/golang.d.ts.map +1 -1
- package/dist/scanner/golang.js +11 -6
- package/dist/scanner/golang.js.map +1 -1
- package/dist/scanner/javascript.d.ts.map +1 -1
- package/dist/scanner/javascript.js +9 -5
- package/dist/scanner/javascript.js.map +1 -1
- package/dist/scanner/markdown.d.ts.map +1 -1
- package/dist/scanner/markdown.js +8 -3
- package/dist/scanner/markdown.js.map +1 -1
- package/dist/scanner/python.d.ts.map +1 -1
- package/dist/scanner/python.js +7 -3
- package/dist/scanner/python.js.map +1 -1
- package/dist/scanner/rules.d.ts.map +1 -1
- package/dist/scanner/rules.js +17 -3
- package/dist/scanner/rules.js.map +1 -1
- package/dist/scanner/rust.d.ts.map +1 -1
- package/dist/scanner/rust.js +4 -2
- package/dist/scanner/rust.js.map +1 -1
- package/dist/scanner/sync.d.ts +50 -0
- package/dist/scanner/sync.d.ts.map +1 -0
- package/dist/scanner/sync.js +384 -0
- package/dist/scanner/sync.js.map +1 -0
- package/dist/scanner/typescript.d.ts.map +1 -1
- package/dist/scanner/typescript.js +93 -17
- package/dist/scanner/typescript.js.map +1 -1
- package/dist/serve/cli.js +15 -1
- package/dist/serve/cli.js.map +1 -1
- package/dist/serve/mcp-server.d.ts.map +1 -1
- package/dist/serve/mcp-server.js +27 -9
- package/dist/serve/mcp-server.js.map +1 -1
- package/dist/store/file-store.d.ts +5 -0
- package/dist/store/file-store.d.ts.map +1 -1
- package/dist/store/file-store.js +36 -8
- package/dist/store/file-store.js.map +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +64 -23
- package/dist/sync/index.js.map +1 -1
- package/package.json +64 -51
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental sync engine for MemGrid.
|
|
3
|
+
* Keeps the memory grid in sync with source code without full re-scan.
|
|
4
|
+
*
|
|
5
|
+
* Strategy:
|
|
6
|
+
* 1. Record file hashes at each sync (stored in mesh.json)
|
|
7
|
+
* 2. On next sync, compare current hashes → detect changed files
|
|
8
|
+
* 3. Incrementally re-scan only changed files
|
|
9
|
+
* 4. Fix associations broken by renamed/deleted methods
|
|
10
|
+
*/
|
|
11
|
+
import type { FileStore } from '../store/file-store.js';
|
|
12
|
+
export interface SyncResult {
|
|
13
|
+
scanned: number;
|
|
14
|
+
added: number;
|
|
15
|
+
updated: number;
|
|
16
|
+
removed: number;
|
|
17
|
+
associationsFixed: number;
|
|
18
|
+
elapsedMs: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class SyncEngine {
|
|
21
|
+
private store;
|
|
22
|
+
private projectRoot;
|
|
23
|
+
constructor(store: FileStore, projectRoot: string);
|
|
24
|
+
/**
|
|
25
|
+
* Incremental sync: detect changes, re-scan only changed files,
|
|
26
|
+
* fix broken associations.
|
|
27
|
+
*/
|
|
28
|
+
sync(): Promise<SyncResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Fix associations pointing to missing/stale units.
|
|
31
|
+
* Uses fuzzy matching by signature to reconnect renamed methods.
|
|
32
|
+
*/
|
|
33
|
+
private fixBrokenLinks;
|
|
34
|
+
/**
|
|
35
|
+
* Compute signature overlap between old ID and new signature.
|
|
36
|
+
* Higher score = more likely the same method was renamed.
|
|
37
|
+
*/
|
|
38
|
+
private signatureOverlap;
|
|
39
|
+
/**
|
|
40
|
+
* Scan specific files (not full project) for method units.
|
|
41
|
+
*/
|
|
42
|
+
private scanFiles;
|
|
43
|
+
private findAllSourceFiles;
|
|
44
|
+
private walkDir;
|
|
45
|
+
private findSourceDirs;
|
|
46
|
+
private fileHash;
|
|
47
|
+
private extractJsDoc;
|
|
48
|
+
private sanitizeId;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/scanner/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,WAAW,CAAS;gBAEhB,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM;IAKjD;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;IAsIjC;;;OAGG;YACW,cAAc;IA6E5B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAexB;;OAEG;YACW,SAAS;IAsGvB,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental sync engine for MemGrid.
|
|
3
|
+
* Keeps the memory grid in sync with source code without full re-scan.
|
|
4
|
+
*
|
|
5
|
+
* Strategy:
|
|
6
|
+
* 1. Record file hashes at each sync (stored in mesh.json)
|
|
7
|
+
* 2. On next sync, compare current hashes → detect changed files
|
|
8
|
+
* 3. Incrementally re-scan only changed files
|
|
9
|
+
* 4. Fix associations broken by renamed/deleted methods
|
|
10
|
+
*/
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import { createHash } from 'crypto';
|
|
14
|
+
import { Project } from 'ts-morph';
|
|
15
|
+
export class SyncEngine {
|
|
16
|
+
store;
|
|
17
|
+
projectRoot;
|
|
18
|
+
constructor(store, projectRoot) {
|
|
19
|
+
this.store = store;
|
|
20
|
+
this.projectRoot = projectRoot;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Incremental sync: detect changes, re-scan only changed files,
|
|
24
|
+
* fix broken associations.
|
|
25
|
+
*/
|
|
26
|
+
async sync() {
|
|
27
|
+
const start = Date.now();
|
|
28
|
+
const result = {
|
|
29
|
+
scanned: 0,
|
|
30
|
+
added: 0,
|
|
31
|
+
updated: 0,
|
|
32
|
+
removed: 0,
|
|
33
|
+
associationsFixed: 0,
|
|
34
|
+
elapsedMs: 0,
|
|
35
|
+
};
|
|
36
|
+
this.store.ensureDirs();
|
|
37
|
+
this.store.load();
|
|
38
|
+
const grid = this.store.getGrid();
|
|
39
|
+
const prevSnapshot = grid?.fileSnapshot || {};
|
|
40
|
+
// 1. Find all source files
|
|
41
|
+
const sourceFiles = this.findAllSourceFiles();
|
|
42
|
+
const currentSnapshot = {};
|
|
43
|
+
// 2. Detect changed files
|
|
44
|
+
const changedFiles = [];
|
|
45
|
+
const deletedFiles = [];
|
|
46
|
+
const newFiles = [];
|
|
47
|
+
for (const filePath of sourceFiles) {
|
|
48
|
+
const hash = this.fileHash(filePath);
|
|
49
|
+
currentSnapshot[filePath] = hash;
|
|
50
|
+
if (!prevSnapshot[filePath]) {
|
|
51
|
+
newFiles.push(filePath);
|
|
52
|
+
}
|
|
53
|
+
else if (prevSnapshot[filePath] !== hash) {
|
|
54
|
+
changedFiles.push(filePath);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
for (const prevFile of Object.keys(prevSnapshot)) {
|
|
58
|
+
if (!currentSnapshot[prevFile]) {
|
|
59
|
+
deletedFiles.push(prevFile);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 3. Incrementally re-scan changed + new files
|
|
63
|
+
const allChanged = [...newFiles, ...changedFiles];
|
|
64
|
+
result.scanned = allChanged.length;
|
|
65
|
+
if (allChanged.length > 0) {
|
|
66
|
+
const newUnits = await this.scanFiles(allChanged);
|
|
67
|
+
// Get existing units keyed by source file
|
|
68
|
+
const existingByFile = new Map();
|
|
69
|
+
const allUnits = await this.store.listUnits();
|
|
70
|
+
for (const unit of allUnits) {
|
|
71
|
+
if (!unit.source?.file)
|
|
72
|
+
continue;
|
|
73
|
+
if (!existingByFile.has(unit.source.file)) {
|
|
74
|
+
existingByFile.set(unit.source.file, []);
|
|
75
|
+
}
|
|
76
|
+
existingByFile.get(unit.source.file).push(unit);
|
|
77
|
+
}
|
|
78
|
+
// Merge: update matching units, add new ones
|
|
79
|
+
for (const filePath of allChanged) {
|
|
80
|
+
const existing = existingByFile.get(filePath) || [];
|
|
81
|
+
const scanned = newUnits.filter((u) => u.source?.file === filePath);
|
|
82
|
+
const scannedById = new Map();
|
|
83
|
+
for (const s of scanned)
|
|
84
|
+
scannedById.set(s.id, s);
|
|
85
|
+
// Update units with same ID
|
|
86
|
+
for (const ex of existing) {
|
|
87
|
+
const match = scannedById.get(ex.id);
|
|
88
|
+
if (match) {
|
|
89
|
+
// Update content but preserve meta
|
|
90
|
+
ex.summary = match.summary;
|
|
91
|
+
ex.content = match.content;
|
|
92
|
+
ex.signatures = match.signatures;
|
|
93
|
+
ex.source = match.source;
|
|
94
|
+
ex.meta.updated = new Date().toISOString();
|
|
95
|
+
this.store.saveUnit(ex);
|
|
96
|
+
result.updated++;
|
|
97
|
+
scannedById.delete(ex.id);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// Old unit no longer exists in file → mark stale
|
|
101
|
+
ex.meta.status = 'stale';
|
|
102
|
+
ex.meta.updated = new Date().toISOString();
|
|
103
|
+
this.store.saveUnit(ex);
|
|
104
|
+
result.removed++;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Add remaining as new units
|
|
108
|
+
for (const [id, unit] of scannedById) {
|
|
109
|
+
this.store.saveUnit(unit);
|
|
110
|
+
result.added++;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// 4. Handle deleted files — mark all their units as stale
|
|
115
|
+
for (const filePath of deletedFiles) {
|
|
116
|
+
const units = (await this.store.listUnits())
|
|
117
|
+
.filter((u) => u.source?.file === filePath);
|
|
118
|
+
for (const unit of units) {
|
|
119
|
+
unit.meta.status = 'stale';
|
|
120
|
+
unit.meta.updated = new Date().toISOString();
|
|
121
|
+
this.store.saveUnit(unit);
|
|
122
|
+
result.removed++;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// 5. Fix broken associations
|
|
126
|
+
result.associationsFixed = await this.fixBrokenLinks();
|
|
127
|
+
// 6. Update grid metadata with new snapshot
|
|
128
|
+
const updatedGrid = this.store.getGrid() || {
|
|
129
|
+
version: '0.1.0',
|
|
130
|
+
project: path.basename(this.projectRoot),
|
|
131
|
+
lastScanAt: new Date().toISOString(),
|
|
132
|
+
stats: { totalUnits: 0, activeUnits: 0, archivedUnits: 0, totalAssociations: 0 },
|
|
133
|
+
edgeIndex: {},
|
|
134
|
+
};
|
|
135
|
+
updatedGrid.lastScanAt = new Date().toISOString();
|
|
136
|
+
updatedGrid.fileSnapshot = currentSnapshot;
|
|
137
|
+
this.store.saveGrid(updatedGrid);
|
|
138
|
+
this.store.reload();
|
|
139
|
+
result.elapsedMs = Date.now() - start;
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Fix associations pointing to missing/stale units.
|
|
144
|
+
* Uses fuzzy matching by signature to reconnect renamed methods.
|
|
145
|
+
*/
|
|
146
|
+
async fixBrokenLinks() {
|
|
147
|
+
const allUnits = await this.store.listUnits();
|
|
148
|
+
const activeIds = new Set();
|
|
149
|
+
const sigIndex = new Map(); // signature → id
|
|
150
|
+
for (const unit of allUnits) {
|
|
151
|
+
if (unit.meta.status !== 'archived') {
|
|
152
|
+
activeIds.add(unit.id);
|
|
153
|
+
for (const sig of unit.signatures) {
|
|
154
|
+
sigIndex.set(sig.toLowerCase(), unit.id);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
let fixed = 0;
|
|
159
|
+
for (const unit of allUnits) {
|
|
160
|
+
if (unit.meta.status === 'archived')
|
|
161
|
+
continue;
|
|
162
|
+
const brokenAssociations = unit.associations.filter((a) => !activeIds.has(a.to));
|
|
163
|
+
if (brokenAssociations.length === 0)
|
|
164
|
+
continue;
|
|
165
|
+
const validAssociations = unit.associations.filter((a) => activeIds.has(a.to));
|
|
166
|
+
// Try to fix broken associations by signature matching
|
|
167
|
+
for (const broken of brokenAssociations) {
|
|
168
|
+
// Search for units that might be the renamed version
|
|
169
|
+
// by looking at units with same type and similar signatures
|
|
170
|
+
const candidates = allUnits.filter((u) => u.id !== unit.id &&
|
|
171
|
+
u.id !== broken.to &&
|
|
172
|
+
u.meta.status !== 'archived' &&
|
|
173
|
+
u.type === (broken.relation === 'calls' || broken.relation === 'belongs_to_module' ? 'method' : 'pattern') &&
|
|
174
|
+
u.signatures.length > 0);
|
|
175
|
+
// Fuzzy match: find candidate with highest signature overlap
|
|
176
|
+
let bestMatch = null;
|
|
177
|
+
let bestScore = 0;
|
|
178
|
+
for (const candidate of candidates) {
|
|
179
|
+
// Score based on text similarity of unit content
|
|
180
|
+
const score = this.signatureOverlap(broken.to, candidate.signatures.join(' '));
|
|
181
|
+
if (score > bestScore && score > 0.3) {
|
|
182
|
+
bestScore = score;
|
|
183
|
+
bestMatch = candidate;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (bestMatch) {
|
|
187
|
+
validAssociations.push({
|
|
188
|
+
...broken,
|
|
189
|
+
to: bestMatch.id,
|
|
190
|
+
weight: Math.max(0.3, broken.weight - 0.1), // Slightly lower confidence on repairs
|
|
191
|
+
});
|
|
192
|
+
fixed++;
|
|
193
|
+
}
|
|
194
|
+
// If no match found, the association is silently dropped
|
|
195
|
+
}
|
|
196
|
+
unit.associations = validAssociations;
|
|
197
|
+
this.store.saveUnit(unit);
|
|
198
|
+
}
|
|
199
|
+
return fixed;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Compute signature overlap between old ID and new signature.
|
|
203
|
+
* Higher score = more likely the same method was renamed.
|
|
204
|
+
*/
|
|
205
|
+
signatureOverlap(oldId, newSignature) {
|
|
206
|
+
const oldParts = oldId.replace(/^method_/, '').split('_');
|
|
207
|
+
const newParts = newSignature.toLowerCase().split(/[_\s.]+/);
|
|
208
|
+
let overlap = 0;
|
|
209
|
+
for (const part of oldParts) {
|
|
210
|
+
if (part.length < 3)
|
|
211
|
+
continue;
|
|
212
|
+
if (newParts.some((np) => np.includes(part) || part.includes(np))) {
|
|
213
|
+
overlap++;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return overlap / Math.max(oldParts.length, 1);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Scan specific files (not full project) for method units.
|
|
220
|
+
*/
|
|
221
|
+
async scanFiles(filePaths) {
|
|
222
|
+
const units = [];
|
|
223
|
+
const tsFiles = filePaths.filter((f) => f.endsWith('.ts') && !f.endsWith('.spec.ts') && !f.endsWith('.test.ts'));
|
|
224
|
+
if (tsFiles.length === 0)
|
|
225
|
+
return units;
|
|
226
|
+
// Reuse existing project with skipAddingFilesFromTsConfig for speed
|
|
227
|
+
// Only add the changed files, not the whole project
|
|
228
|
+
const project = new Project({
|
|
229
|
+
tsConfigFilePath: path.join(this.projectRoot, 'tsconfig.json'),
|
|
230
|
+
skipAddingFilesFromTsConfig: true, // Don't load everything — only what we add
|
|
231
|
+
skipFileDependencyResolution: true, // Skip type resolution for speed
|
|
232
|
+
});
|
|
233
|
+
for (const filePath of tsFiles) {
|
|
234
|
+
const absPath = path.resolve(this.projectRoot, filePath);
|
|
235
|
+
if (!fs.existsSync(absPath))
|
|
236
|
+
continue;
|
|
237
|
+
try {
|
|
238
|
+
const sourceFile = project.addSourceFileAtPath(absPath);
|
|
239
|
+
const relPath = filePath;
|
|
240
|
+
// Extract class methods
|
|
241
|
+
for (const cls of sourceFile.getClasses()) {
|
|
242
|
+
const className = cls.getName();
|
|
243
|
+
if (!className || cls.isAbstract())
|
|
244
|
+
continue;
|
|
245
|
+
for (const method of cls.getMethods()) {
|
|
246
|
+
const scope = method.getScope();
|
|
247
|
+
if (scope !== 'public' && scope !== undefined)
|
|
248
|
+
continue;
|
|
249
|
+
const methodName = method.getName();
|
|
250
|
+
const signature = `${className}.${methodName}`;
|
|
251
|
+
const params = method.getParameters().map((p) => `${p.getName()}: ${p.getType().getText()}`);
|
|
252
|
+
const unit = {
|
|
253
|
+
id: `method_${signature.toLowerCase().replace(/\./g, '_').replace(/[^a-z0-9_]/g, '_').replace(/_+/g, '_')}`,
|
|
254
|
+
type: 'method',
|
|
255
|
+
summary: `${signature} — ${this.extractJsDoc(method)}`,
|
|
256
|
+
source: {
|
|
257
|
+
file: relPath,
|
|
258
|
+
lines: `${method.getStartLineNumber()}-${method.getEndLineNumber()}`,
|
|
259
|
+
},
|
|
260
|
+
signatures: [signature],
|
|
261
|
+
content: {
|
|
262
|
+
description: this.extractJsDoc(method) || `${signature}()`,
|
|
263
|
+
inputs: params.length > 0 ? params.join(', ') : 'none',
|
|
264
|
+
outputs: method.getReturnType().getText(),
|
|
265
|
+
code_snippet: method.getText(),
|
|
266
|
+
},
|
|
267
|
+
associations: [],
|
|
268
|
+
meta: {
|
|
269
|
+
created: new Date().toISOString(),
|
|
270
|
+
updated: new Date().toISOString(),
|
|
271
|
+
confidence: 0.8,
|
|
272
|
+
usage_count: 0,
|
|
273
|
+
status: 'active',
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
units.push(unit);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// Extract exported functions
|
|
280
|
+
for (const func of sourceFile.getFunctions()) {
|
|
281
|
+
if (!func.isExported())
|
|
282
|
+
continue;
|
|
283
|
+
const funcName = func.getName();
|
|
284
|
+
if (!funcName)
|
|
285
|
+
continue;
|
|
286
|
+
const unit = {
|
|
287
|
+
id: `method_${this.sanitizeId(funcName)}`,
|
|
288
|
+
type: 'method',
|
|
289
|
+
summary: `${funcName}() — ${this.extractJsDoc(func)}`,
|
|
290
|
+
source: { file: relPath, lines: `${func.getStartLineNumber()}-${func.getEndLineNumber()}` },
|
|
291
|
+
signatures: [funcName],
|
|
292
|
+
content: {
|
|
293
|
+
description: this.extractJsDoc(func) || `${funcName}()`,
|
|
294
|
+
inputs: func.getParameters().map((p) => `${p.getName()}: ${p.getType().getText()}`).join(', ') || 'none',
|
|
295
|
+
outputs: func.getReturnType().getText(),
|
|
296
|
+
code_snippet: func.getText(),
|
|
297
|
+
},
|
|
298
|
+
associations: [],
|
|
299
|
+
meta: {
|
|
300
|
+
created: new Date().toISOString(),
|
|
301
|
+
updated: new Date().toISOString(),
|
|
302
|
+
confidence: 0.8,
|
|
303
|
+
usage_count: 0,
|
|
304
|
+
status: 'active',
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
units.push(unit);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
// Skip files with parse errors
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return units;
|
|
315
|
+
}
|
|
316
|
+
findAllSourceFiles() {
|
|
317
|
+
const files = [];
|
|
318
|
+
const srcDirs = this.findSourceDirs();
|
|
319
|
+
for (const dir of srcDirs) {
|
|
320
|
+
this.walkDir(dir, (filePath) => {
|
|
321
|
+
if (!filePath.endsWith('.ts'))
|
|
322
|
+
return;
|
|
323
|
+
if (filePath.endsWith('.spec.ts') || filePath.endsWith('.test.ts'))
|
|
324
|
+
return;
|
|
325
|
+
if (filePath.includes('node_modules') || filePath.includes('dist'))
|
|
326
|
+
return;
|
|
327
|
+
files.push(filePath);
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
return files;
|
|
331
|
+
}
|
|
332
|
+
walkDir(dir, callback) {
|
|
333
|
+
if (!fs.existsSync(dir))
|
|
334
|
+
return;
|
|
335
|
+
for (const entry of fs.readdirSync(dir)) {
|
|
336
|
+
const full = path.join(dir, entry);
|
|
337
|
+
if (fs.statSync(full).isDirectory()) {
|
|
338
|
+
this.walkDir(full, callback);
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
callback(full);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
findSourceDirs() {
|
|
346
|
+
const dirs = [];
|
|
347
|
+
const appsDir = path.join(this.projectRoot, 'apps');
|
|
348
|
+
if (fs.existsSync(appsDir)) {
|
|
349
|
+
for (const app of fs.readdirSync(appsDir)) {
|
|
350
|
+
const srcDir = path.join(appsDir, app, 'src');
|
|
351
|
+
if (fs.existsSync(srcDir))
|
|
352
|
+
dirs.push(srcDir);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const packagesDir = path.join(this.projectRoot, 'packages');
|
|
356
|
+
if (fs.existsSync(packagesDir)) {
|
|
357
|
+
for (const pkg of fs.readdirSync(packagesDir)) {
|
|
358
|
+
const srcDir = path.join(packagesDir, pkg, 'src');
|
|
359
|
+
if (fs.existsSync(srcDir))
|
|
360
|
+
dirs.push(srcDir);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return dirs;
|
|
364
|
+
}
|
|
365
|
+
fileHash(filePath) {
|
|
366
|
+
try {
|
|
367
|
+
const content = fs.readFileSync(filePath);
|
|
368
|
+
return createHash('sha256').update(content).digest('hex').slice(0, 16);
|
|
369
|
+
}
|
|
370
|
+
catch {
|
|
371
|
+
return '';
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
extractJsDoc(node) {
|
|
375
|
+
const jsDocs = node.getJsDocs?.();
|
|
376
|
+
if (jsDocs?.length > 0)
|
|
377
|
+
return jsDocs[0].getDescription().trim() || '';
|
|
378
|
+
return '';
|
|
379
|
+
}
|
|
380
|
+
sanitizeId(text) {
|
|
381
|
+
return text.replace(/[^a-zA-Z0-9_\-]/g, '_').replace(/_+/g, '_').toLowerCase();
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/scanner/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAanC,MAAM,OAAO,UAAU;IACb,KAAK,CAAY;IACjB,WAAW,CAAS;IAE5B,YAAY,KAAgB,EAAE,WAAmB;QAC/C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,MAAM,GAAe;YACzB,OAAO,EAAE,CAAC;YACV,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;YACV,iBAAiB,EAAE,CAAC;YACpB,SAAS,EAAE,CAAC;SACb,CAAC;QAEF,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACxB,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAElB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,YAAY,GAAI,IAAY,EAAE,YAAY,IAAI,EAAE,CAAC;QAEvD,2BAA2B;QAC3B,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,MAAM,eAAe,GAA2B,EAAE,CAAC;QAEnD,0BAA0B;QAC1B,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,KAAK,MAAM,QAAQ,IAAI,WAAW,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACrC,eAAe,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;YAEjC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC;iBAAM,IAAI,YAAY,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC3C,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC/B,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,+CAA+C;QAC/C,MAAM,UAAU,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,YAAY,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC;QAEnC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YAElD,0CAA0C;YAC1C,MAAM,cAAc,GAAG,IAAI,GAAG,EAAwB,CAAC;YACvD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YAC9C,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI;oBAAE,SAAS;gBACjC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1C,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC3C,CAAC;gBACD,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnD,CAAC;YAED,6CAA6C;YAC7C,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;gBAClC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACpD,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC;gBAEpE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;gBAClD,KAAK,MAAM,CAAC,IAAI,OAAO;oBAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;gBAElD,4BAA4B;gBAC5B,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;oBAC1B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;oBACrC,IAAI,KAAK,EAAE,CAAC;wBACV,mCAAmC;wBACnC,EAAE,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;wBAC3B,EAAE,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;wBAC3B,EAAE,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;wBACjC,EAAE,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;wBACzB,EAAE,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;wBAC3C,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;wBACxB,MAAM,CAAC,OAAO,EAAE,CAAC;wBACjB,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;oBAC5B,CAAC;yBAAM,CAAC;wBACN,iDAAiD;wBACjD,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;wBACzB,EAAE,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;wBAC3C,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;wBACxB,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,CAAC;gBACH,CAAC;gBAED,6BAA6B;gBAC7B,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC;oBACrC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;oBAC1B,MAAM,CAAC,KAAK,EAAE,CAAC;gBACjB,CAAC;YACH,CAAC;QACH,CAAC;QAED,0DAA0D;QAC1D,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;iBACzC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC;YAE9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;gBAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBAC7C,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC1B,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC;QACH,CAAC;QAED,6BAA6B;QAC7B,MAAM,CAAC,iBAAiB,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAEvD,4CAA4C;QAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI;YAC1C,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;YACxC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,KAAK,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE;YAChF,SAAS,EAAE,EAAE;SACd,CAAC;QAEF,WAAW,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACjD,WAAmB,CAAC,YAAY,GAAG,eAAe,CAAC;QAEpD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAEpB,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACtC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,cAAc;QAC1B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QAC9C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC,CAAC,iBAAiB;QAE7D,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBACpC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACvB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;oBAClC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU;gBAAE,SAAS;YAE9C,MAAM,kBAAkB,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CACjD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAC5B,CAAC;YAEF,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAE9C,MAAM,iBAAiB,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAC3B,CAAC;YAEF,uDAAuD;YACvD,KAAK,MAAM,MAAM,IAAI,kBAAkB,EAAE,CAAC;gBACxC,qDAAqD;gBACrD,4DAA4D;gBAC5D,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAChC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;oBAChB,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE;oBAClB,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU;oBAC5B,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;oBAC1G,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAC1B,CAAC;gBAEF,6DAA6D;gBAC7D,IAAI,SAAS,GAAsB,IAAI,CAAC;gBACxC,IAAI,SAAS,GAAG,CAAC,CAAC;gBAElB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;oBACnC,iDAAiD;oBACjD,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CACjC,MAAM,CAAC,EAAE,EACT,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAC/B,CAAC;oBAEF,IAAI,KAAK,GAAG,SAAS,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;wBACrC,SAAS,GAAG,KAAK,CAAC;wBAClB,SAAS,GAAG,SAAS,CAAC;oBACxB,CAAC;gBACH,CAAC;gBAED,IAAI,SAAS,EAAE,CAAC;oBACd,iBAAiB,CAAC,IAAI,CAAC;wBACrB,GAAG,MAAM;wBACT,EAAE,EAAE,SAAS,CAAC,EAAE;wBAChB,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,uCAAuC;qBACpF,CAAC,CAAC;oBACH,KAAK,EAAE,CAAC;gBACV,CAAC;gBACD,yDAAyD;YAC3D,CAAC;YAED,IAAI,CAAC,YAAY,GAAG,iBAAiB,CAAC;YACtC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACK,gBAAgB,CAAC,KAAa,EAAE,YAAoB;QAC1D,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAE7D,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAC9B,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBAClE,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS,CAAC,SAAmB;QACzC,MAAM,KAAK,GAAiB,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;QAEjH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAEvC,oEAAoE;QACpE,oDAAoD;QACpD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;YAC1B,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC;YAC9D,2BAA2B,EAAE,IAAI,EAAE,2CAA2C;YAC9E,4BAA4B,EAAE,IAAI,EAAE,iCAAiC;SACtE,CAAC,CAAC;QAEH,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YACzD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAS;YAEtC,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;gBACxD,MAAM,OAAO,GAAG,QAAQ,CAAC;gBAEzB,wBAAwB;gBACxB,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,EAAE,CAAC;oBAC1C,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;oBAChC,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC,UAAU,EAAE;wBAAE,SAAS;oBAE7C,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC;wBACtC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;wBAChC,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS;4BAAE,SAAS;wBAExD,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;wBACpC,MAAM,SAAS,GAAG,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;wBAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;wBAE7F,MAAM,IAAI,GAAe;4BACvB,EAAE,EAAE,UAAU,SAAS,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;4BAC3G,IAAI,EAAE,QAAQ;4BACd,OAAO,EAAE,GAAG,SAAS,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE;4BACtD,MAAM,EAAE;gCACN,IAAI,EAAE,OAAO;gCACb,KAAK,EAAE,GAAG,MAAM,CAAC,kBAAkB,EAAE,IAAI,MAAM,CAAC,gBAAgB,EAAE,EAAE;6BACrE;4BACD,UAAU,EAAE,CAAC,SAAS,CAAC;4BACvB,OAAO,EAAE;gCACP,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,GAAG,SAAS,IAAI;gCAC1D,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM;gCACtD,OAAO,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE;gCACzC,YAAY,EAAE,MAAM,CAAC,OAAO,EAAE;6BAC/B;4BACD,YAAY,EAAE,EAAE;4BAChB,IAAI,EAAE;gCACJ,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gCACjC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gCACjC,UAAU,EAAE,GAAG;gCACf,WAAW,EAAE,CAAC;gCACd,MAAM,EAAE,QAAQ;6BACjB;yBACF,CAAC;wBAEF,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACnB,CAAC;gBACH,CAAC;gBAED,6BAA6B;gBAC7B,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,YAAY,EAAE,EAAE,CAAC;oBAC7C,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;wBAAE,SAAS;oBACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;oBAChC,IAAI,CAAC,QAAQ;wBAAE,SAAS;oBAExB,MAAM,IAAI,GAAe;wBACvB,EAAE,EAAE,UAAU,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;wBACzC,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,GAAG,QAAQ,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE;wBACrD,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,kBAAkB,EAAE,IAAI,IAAI,CAAC,gBAAgB,EAAE,EAAE,EAAE;wBAC3F,UAAU,EAAE,CAAC,QAAQ,CAAC;wBACtB,OAAO,EAAE;4BACP,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,IAAI;4BACvD,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM;4BACxG,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE;4BACvC,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE;yBAC7B;wBACD,YAAY,EAAE,EAAE;wBAChB,IAAI,EAAE;4BACJ,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;4BACjC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;4BACjC,UAAU,EAAE,GAAG;4BACf,WAAW,EAAE,CAAC;4BACd,MAAM,EAAE,QAAQ;yBACjB;qBACF,CAAC;oBAEF,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,+BAA+B;YACjC,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,kBAAkB;QACxB,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAEtC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE;gBAC7B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;oBAAE,OAAO;gBACtC,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;oBAAE,OAAO;gBAC3E,IAAI,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;oBAAE,OAAO;gBAC3E,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,OAAO,CAAC,GAAW,EAAE,QAAoC;QAC/D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO;QAChC,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACnC,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;gBACpC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,IAAI,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAEO,cAAc;QACpB,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACpD,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,KAAK,MAAM,GAAG,IAAI,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC9C,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;oBAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QAC5D,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,KAAK,MAAM,GAAG,IAAI,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBAClD,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;oBAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,QAAQ,CAAC,QAAgB;QAC/B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC1C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,IAAS;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;QAClC,IAAI,MAAM,EAAE,MAAM,GAAG,CAAC;YAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QACvE,OAAO,EAAE,CAAC;IACZ,CAAC;IAEO,UAAU,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IACjF,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../src/scanner/typescript.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA2B,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,qBAAa,iBAAkB,YAAW,OAAO;IAC/C,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,WAAW,CAAS;gBAEhB,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM;IAKjD,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;
|
|
1
|
+
{"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../src/scanner/typescript.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA2B,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,qBAAa,iBAAkB,YAAW,OAAO;IAC/C,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,WAAW,CAAS;gBAEhB,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM;IAKjD,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAM9B,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;YAkCzC,cAAc;YAuId,SAAS;YAyFT,YAAY;YA8CZ,UAAU;IAwExB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,iBAAiB;IAsGzB,OAAO,CAAC,UAAU;IA4BlB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,mBAAmB;IAc3B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAuC1B,OAAO,CAAC,eAAe;IAqDvB,OAAO,CAAC,cAAc;CAkBvB"}
|
|
@@ -10,8 +10,7 @@ export class TypeScriptScanner {
|
|
|
10
10
|
this.projectRoot = projectRoot;
|
|
11
11
|
}
|
|
12
12
|
detect(projectRoot) {
|
|
13
|
-
return (fs.existsSync(path.join(projectRoot, 'tsconfig.json')) ||
|
|
14
|
-
this.findSourceDirs().length > 0);
|
|
13
|
+
return (fs.existsSync(path.join(projectRoot, 'tsconfig.json')) || this.findSourceDirs().length > 0);
|
|
15
14
|
}
|
|
16
15
|
async scan(options) {
|
|
17
16
|
const units = [];
|
|
@@ -61,7 +60,9 @@ export class TypeScriptScanner {
|
|
|
61
60
|
for (const sourceFile of project.getSourceFiles()) {
|
|
62
61
|
const filePath = path.relative(this.projectRoot, sourceFile.getFilePath());
|
|
63
62
|
// Skip test files, node_modules, dist, .next
|
|
64
|
-
if (filePath.includes('node_modules') ||
|
|
63
|
+
if (filePath.includes('node_modules') ||
|
|
64
|
+
filePath.includes('dist') ||
|
|
65
|
+
filePath.includes('.next'))
|
|
65
66
|
continue;
|
|
66
67
|
if (filePath.endsWith('.spec.ts') || filePath.endsWith('.test.ts'))
|
|
67
68
|
continue;
|
|
@@ -82,7 +83,11 @@ export class TypeScriptScanner {
|
|
|
82
83
|
});
|
|
83
84
|
const returnType = method.getReturnType().getText();
|
|
84
85
|
const unit = {
|
|
85
|
-
id: `method_${signature
|
|
86
|
+
id: `method_${signature
|
|
87
|
+
.toLowerCase()
|
|
88
|
+
.replace(/\./g, '_')
|
|
89
|
+
.replace(/[^a-z0-9_]/g, '_')
|
|
90
|
+
.replace(/_+/g, '_')}`,
|
|
86
91
|
type: 'method',
|
|
87
92
|
summary: `${signature} — ${this.extractJsDoc(method)}`,
|
|
88
93
|
source: {
|
|
@@ -168,10 +173,19 @@ export class TypeScriptScanner {
|
|
|
168
173
|
const body = section.split('\n').slice(1).join('\n').trim();
|
|
169
174
|
if (!title || body.length < 50)
|
|
170
175
|
continue;
|
|
171
|
-
const safeTitle = title
|
|
176
|
+
const safeTitle = title
|
|
177
|
+
.replace(/[^a-zA-Z0-9_-]/g, '_')
|
|
178
|
+
.replace(/_+/g, '_')
|
|
179
|
+
.slice(0, 50)
|
|
180
|
+
.toLowerCase();
|
|
172
181
|
if (!safeTitle || safeTitle === '_')
|
|
173
182
|
continue;
|
|
174
|
-
const safeFile = file
|
|
183
|
+
const safeFile = file
|
|
184
|
+
.replace('.md', '')
|
|
185
|
+
.replace(/[^a-zA-Z0-9_-]/g, '_')
|
|
186
|
+
.replace(/_+/g, '_')
|
|
187
|
+
.slice(0, 30)
|
|
188
|
+
.toLowerCase();
|
|
175
189
|
const unit = {
|
|
176
190
|
id: `rule_${safeFile}_${safeTitle}`,
|
|
177
191
|
type: 'pattern',
|
|
@@ -193,7 +207,12 @@ export class TypeScriptScanner {
|
|
|
193
207
|
units.push(unit);
|
|
194
208
|
}
|
|
195
209
|
// Also create a rule_trigger unit
|
|
196
|
-
const safeFile = file
|
|
210
|
+
const safeFile = file
|
|
211
|
+
.replace('.md', '')
|
|
212
|
+
.replace(/[^a-zA-Z0-9_-]/g, '_')
|
|
213
|
+
.replace(/_+/g, '_')
|
|
214
|
+
.slice(0, 30)
|
|
215
|
+
.toLowerCase();
|
|
197
216
|
const triggerUnit = {
|
|
198
217
|
id: `trigger_rule_${safeFile}`,
|
|
199
218
|
type: 'rule_trigger',
|
|
@@ -229,7 +248,7 @@ export class TypeScriptScanner {
|
|
|
229
248
|
for (const file of fs.readdirSync(dir)) {
|
|
230
249
|
if (!file.endsWith('.ts'))
|
|
231
250
|
continue;
|
|
232
|
-
if (file.startsWith(
|
|
251
|
+
if (file.startsWith('_TEMPLATE'))
|
|
233
252
|
continue;
|
|
234
253
|
const filePath = path.join(dir, file);
|
|
235
254
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
@@ -270,7 +289,17 @@ export class TypeScriptScanner {
|
|
|
270
289
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
271
290
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
272
291
|
const keyDeps = Object.entries(deps)
|
|
273
|
-
.filter(([name]) => [
|
|
292
|
+
.filter(([name]) => [
|
|
293
|
+
'next',
|
|
294
|
+
'react',
|
|
295
|
+
'nestjs',
|
|
296
|
+
'typeorm',
|
|
297
|
+
'chakra',
|
|
298
|
+
'zustand',
|
|
299
|
+
'swr',
|
|
300
|
+
'pnpm',
|
|
301
|
+
'typescript',
|
|
302
|
+
].some((k) => name.includes(k)))
|
|
274
303
|
.map(([name, ver]) => `${name}@${ver}`);
|
|
275
304
|
if (keyDeps.length > 0) {
|
|
276
305
|
units.push({
|
|
@@ -317,7 +346,10 @@ export class TypeScriptScanner {
|
|
|
317
346
|
return units;
|
|
318
347
|
}
|
|
319
348
|
sanitizeId(text) {
|
|
320
|
-
return text
|
|
349
|
+
return text
|
|
350
|
+
.replace(/[^a-zA-Z0-9_-]/g, '_')
|
|
351
|
+
.replace(/_+/g, '_')
|
|
352
|
+
.toLowerCase();
|
|
321
353
|
}
|
|
322
354
|
buildAssociations(units) {
|
|
323
355
|
const methodUnits = units.filter((u) => u.type === 'method');
|
|
@@ -480,7 +512,10 @@ export class TypeScriptScanner {
|
|
|
480
512
|
// Extract individual imported names
|
|
481
513
|
const namesStr = match[0].match(/\{([^}]*)\}/)?.[1] || '';
|
|
482
514
|
for (const n of namesStr.split(',')) {
|
|
483
|
-
const clean = n
|
|
515
|
+
const clean = n
|
|
516
|
+
.trim()
|
|
517
|
+
.split(/\s+as\s+/)[0]
|
|
518
|
+
.trim();
|
|
484
519
|
if (clean && clean.length > 2)
|
|
485
520
|
names.add(clean);
|
|
486
521
|
}
|
|
@@ -489,12 +524,53 @@ export class TypeScriptScanner {
|
|
|
489
524
|
}
|
|
490
525
|
isCommonKeyword(name) {
|
|
491
526
|
const keywords = new Set([
|
|
492
|
-
'if',
|
|
493
|
-
'
|
|
494
|
-
'
|
|
495
|
-
'
|
|
496
|
-
'
|
|
497
|
-
'
|
|
527
|
+
'if',
|
|
528
|
+
'for',
|
|
529
|
+
'let',
|
|
530
|
+
'var',
|
|
531
|
+
'new',
|
|
532
|
+
'try',
|
|
533
|
+
'const',
|
|
534
|
+
'typeof',
|
|
535
|
+
'instanceof',
|
|
536
|
+
'return',
|
|
537
|
+
'throw',
|
|
538
|
+
'await',
|
|
539
|
+
'async',
|
|
540
|
+
'while',
|
|
541
|
+
'switch',
|
|
542
|
+
'catch',
|
|
543
|
+
'finally',
|
|
544
|
+
'export',
|
|
545
|
+
'import',
|
|
546
|
+
'from',
|
|
547
|
+
'require',
|
|
548
|
+
'default',
|
|
549
|
+
'function',
|
|
550
|
+
'class',
|
|
551
|
+
'true',
|
|
552
|
+
'false',
|
|
553
|
+
'null',
|
|
554
|
+
'undefined',
|
|
555
|
+
'this',
|
|
556
|
+
'super',
|
|
557
|
+
'void',
|
|
558
|
+
'delete',
|
|
559
|
+
'map',
|
|
560
|
+
'filter',
|
|
561
|
+
'reduce',
|
|
562
|
+
'find',
|
|
563
|
+
'forEach',
|
|
564
|
+
'push',
|
|
565
|
+
'pop',
|
|
566
|
+
'slice',
|
|
567
|
+
'split',
|
|
568
|
+
'join',
|
|
569
|
+
'concat',
|
|
570
|
+
'sort',
|
|
571
|
+
'some',
|
|
572
|
+
'every',
|
|
573
|
+
'includes',
|
|
498
574
|
]);
|
|
499
575
|
return keywords.has(name);
|
|
500
576
|
}
|