memgrid 0.5.0 → 0.5.1

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 (59) hide show
  1. package/CHANGELOG.md +88 -80
  2. package/LICENSE +21 -21
  3. package/README.md +251 -251
  4. package/dist/learn/index.d.ts.map +1 -1
  5. package/dist/learn/index.js +28 -9
  6. package/dist/learn/index.js.map +1 -1
  7. package/dist/memgrid.d.ts.map +1 -1
  8. package/dist/memgrid.js +39 -6
  9. package/dist/memgrid.js.map +1 -1
  10. package/dist/retrieve/index.d.ts +1 -1
  11. package/dist/retrieve/index.d.ts.map +1 -1
  12. package/dist/retrieve/index.js +17 -13
  13. package/dist/retrieve/index.js.map +1 -1
  14. package/dist/retrieve/semantic.d.ts.map +1 -1
  15. package/dist/retrieve/semantic.js +9 -7
  16. package/dist/retrieve/semantic.js.map +1 -1
  17. package/dist/scanner/composite.d.ts.map +1 -1
  18. package/dist/scanner/composite.js +1 -3
  19. package/dist/scanner/composite.js.map +1 -1
  20. package/dist/scanner/config.d.ts.map +1 -1
  21. package/dist/scanner/config.js +30 -8
  22. package/dist/scanner/config.js.map +1 -1
  23. package/dist/scanner/golang.d.ts.map +1 -1
  24. package/dist/scanner/golang.js +11 -6
  25. package/dist/scanner/golang.js.map +1 -1
  26. package/dist/scanner/javascript.d.ts.map +1 -1
  27. package/dist/scanner/javascript.js +9 -5
  28. package/dist/scanner/javascript.js.map +1 -1
  29. package/dist/scanner/markdown.d.ts.map +1 -1
  30. package/dist/scanner/markdown.js +8 -3
  31. package/dist/scanner/markdown.js.map +1 -1
  32. package/dist/scanner/python.d.ts.map +1 -1
  33. package/dist/scanner/python.js +7 -3
  34. package/dist/scanner/python.js.map +1 -1
  35. package/dist/scanner/rules.d.ts.map +1 -1
  36. package/dist/scanner/rules.js +17 -3
  37. package/dist/scanner/rules.js.map +1 -1
  38. package/dist/scanner/rust.d.ts.map +1 -1
  39. package/dist/scanner/rust.js +4 -2
  40. package/dist/scanner/rust.js.map +1 -1
  41. package/dist/scanner/sync.d.ts +50 -0
  42. package/dist/scanner/sync.d.ts.map +1 -0
  43. package/dist/scanner/sync.js +384 -0
  44. package/dist/scanner/sync.js.map +1 -0
  45. package/dist/scanner/typescript.d.ts.map +1 -1
  46. package/dist/scanner/typescript.js +93 -17
  47. package/dist/scanner/typescript.js.map +1 -1
  48. package/dist/serve/cli.js +1 -1
  49. package/dist/serve/mcp-server.d.ts.map +1 -1
  50. package/dist/serve/mcp-server.js +27 -9
  51. package/dist/serve/mcp-server.js.map +1 -1
  52. package/dist/store/file-store.d.ts +5 -0
  53. package/dist/store/file-store.d.ts.map +1 -1
  54. package/dist/store/file-store.js +36 -8
  55. package/dist/store/file-store.js.map +1 -1
  56. package/dist/sync/index.d.ts.map +1 -1
  57. package/dist/sync/index.js +64 -23
  58. package/dist/sync/index.js.map +1 -1
  59. package/package.json +64 -51
@@ -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":"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"}
@@ -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;IAO9B,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;YAkCzC,cAAc;YA8Hd,SAAS;YA2ET,YAAY;YA8CZ,UAAU;IAgExB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,iBAAiB;IAkGzB,OAAO,CAAC,UAAU;IA4BlB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,mBAAmB;IAc3B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,cAAc;CAkBvB"}
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') || filePath.includes('dist') || filePath.includes('.next'))
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.toLowerCase().replace(/\./g, '_').replace(/[^a-z0-9_]/g, '_').replace(/_+/g, '_')}`,
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.replace(/[^a-zA-Z0-9_\-]/g, '_').replace(/_+/g, '_').slice(0, 50).toLowerCase();
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.replace('.md', '').replace(/[^a-zA-Z0-9_\-]/g, '_').replace(/_+/g, '_').slice(0, 30).toLowerCase();
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.replace('.md', '').replace(/[^a-zA-Z0-9_\-]/g, '_').replace(/_+/g, '_').slice(0, 30).toLowerCase();
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("_TEMPLATE"))
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]) => ['next', 'react', 'nestjs', 'typeorm', 'chakra', 'zustand', 'swr', 'pnpm', 'typescript'].some((k) => name.includes(k)))
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.replace(/[^a-zA-Z0-9_\-]/g, "_").replace(/_+/g, "_").toLowerCase();
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.trim().split(/\s+as\s+/)[0].trim();
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', 'for', 'let', 'var', 'new', 'try', 'const', 'typeof', 'instanceof',
493
- 'return', 'throw', 'await', 'async', 'while', 'switch', 'catch', 'finally',
494
- 'export', 'import', 'from', 'require', 'default', 'function', 'class',
495
- 'true', 'false', 'null', 'undefined', 'this', 'super', 'void', 'delete',
496
- 'map', 'filter', 'reduce', 'find', 'forEach', 'push', 'pop', 'slice',
497
- 'split', 'join', 'concat', 'sort', 'some', 'every', 'includes',
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
  }