memgrid 0.5.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/CHANGELOG.md +80 -0
- package/LICENSE +21 -0
- package/README.md +251 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/learn/index.d.ts +44 -0
- package/dist/learn/index.d.ts.map +1 -0
- package/dist/learn/index.js +234 -0
- package/dist/learn/index.js.map +1 -0
- package/dist/memgrid.d.ts +50 -0
- package/dist/memgrid.d.ts.map +1 -0
- package/dist/memgrid.js +175 -0
- package/dist/memgrid.js.map +1 -0
- package/dist/retrieve/index.d.ts +27 -0
- package/dist/retrieve/index.d.ts.map +1 -0
- package/dist/retrieve/index.js +209 -0
- package/dist/retrieve/index.js.map +1 -0
- package/dist/retrieve/semantic.d.ts +67 -0
- package/dist/retrieve/semantic.d.ts.map +1 -0
- package/dist/retrieve/semantic.js +240 -0
- package/dist/retrieve/semantic.js.map +1 -0
- package/dist/scanner/composite.d.ts +27 -0
- package/dist/scanner/composite.d.ts.map +1 -0
- package/dist/scanner/composite.js +58 -0
- package/dist/scanner/composite.js.map +1 -0
- package/dist/scanner/config.d.ts +15 -0
- package/dist/scanner/config.d.ts.map +1 -0
- package/dist/scanner/config.js +167 -0
- package/dist/scanner/config.js.map +1 -0
- package/dist/scanner/golang.d.ts +19 -0
- package/dist/scanner/golang.d.ts.map +1 -0
- package/dist/scanner/golang.js +190 -0
- package/dist/scanner/golang.js.map +1 -0
- package/dist/scanner/index.d.ts +11 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +10 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/javascript.d.ts +20 -0
- package/dist/scanner/javascript.d.ts.map +1 -0
- package/dist/scanner/javascript.js +167 -0
- package/dist/scanner/javascript.js.map +1 -0
- package/dist/scanner/markdown.d.ts +17 -0
- package/dist/scanner/markdown.d.ts.map +1 -0
- package/dist/scanner/markdown.js +106 -0
- package/dist/scanner/markdown.js.map +1 -0
- package/dist/scanner/python.d.ts +19 -0
- package/dist/scanner/python.d.ts.map +1 -0
- package/dist/scanner/python.js +177 -0
- package/dist/scanner/python.js.map +1 -0
- package/dist/scanner/rules.d.ts +15 -0
- package/dist/scanner/rules.d.ts.map +1 -0
- package/dist/scanner/rules.js +86 -0
- package/dist/scanner/rules.js.map +1 -0
- package/dist/scanner/rust.d.ts +18 -0
- package/dist/scanner/rust.d.ts.map +1 -0
- package/dist/scanner/rust.js +178 -0
- package/dist/scanner/rust.js.map +1 -0
- package/dist/scanner/scanner.d.ts +33 -0
- package/dist/scanner/scanner.d.ts.map +1 -0
- package/dist/scanner/scanner.js +2 -0
- package/dist/scanner/scanner.js.map +1 -0
- package/dist/scanner/typescript.d.ts +28 -0
- package/dist/scanner/typescript.d.ts.map +1 -0
- package/dist/scanner/typescript.js +522 -0
- package/dist/scanner/typescript.js.map +1 -0
- package/dist/serve/cli.d.ts +3 -0
- package/dist/serve/cli.d.ts.map +1 -0
- package/dist/serve/cli.js +145 -0
- package/dist/serve/cli.js.map +1 -0
- package/dist/serve/mcp-server.d.ts +11 -0
- package/dist/serve/mcp-server.d.ts.map +1 -0
- package/dist/serve/mcp-server.js +276 -0
- package/dist/serve/mcp-server.js.map +1 -0
- package/dist/shared/constants.d.ts +2 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/constants.js +2 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/types.d.ts +99 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +3 -0
- package/dist/shared/types.js.map +1 -0
- package/dist/store/file-store.d.ts +62 -0
- package/dist/store/file-store.d.ts.map +1 -0
- package/dist/store/file-store.js +241 -0
- package/dist/store/file-store.js.map +1 -0
- package/dist/store/index.d.ts +3 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +2 -0
- package/dist/store/index.js.map +1 -0
- package/dist/sync/index.d.ts +56 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +580 -0
- package/dist/sync/index.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as crypto from 'crypto';
|
|
4
|
+
// ===== File hash utilities =====
|
|
5
|
+
function sha256(content) {
|
|
6
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
7
|
+
}
|
|
8
|
+
function buildSnapshot(projectRoot, files) {
|
|
9
|
+
const snapshot = {};
|
|
10
|
+
for (const file of files) {
|
|
11
|
+
const abs = path.join(projectRoot, file);
|
|
12
|
+
if (fs.existsSync(abs)) {
|
|
13
|
+
snapshot[file] = sha256(fs.readFileSync(abs, 'utf-8'));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return snapshot;
|
|
17
|
+
}
|
|
18
|
+
// ===== Fuzzy String Matching =====
|
|
19
|
+
/**
|
|
20
|
+
* Jaccard similarity on bigram token sets.
|
|
21
|
+
* Returns 0.0 ~ 1.0. Higher = more similar.
|
|
22
|
+
*/
|
|
23
|
+
function jaccardBigramSimilarity(a, b) {
|
|
24
|
+
const bigramsA = new Set();
|
|
25
|
+
const bigramsB = new Set();
|
|
26
|
+
for (let i = 0; i < a.length - 1; i++)
|
|
27
|
+
bigramsA.add(a.slice(i, i + 2));
|
|
28
|
+
for (let i = 0; i < b.length - 1; i++)
|
|
29
|
+
bigramsB.add(b.slice(i, i + 2));
|
|
30
|
+
if (bigramsA.size === 0 && bigramsB.size === 0)
|
|
31
|
+
return 1.0;
|
|
32
|
+
if (bigramsA.size === 0 || bigramsB.size === 0)
|
|
33
|
+
return 0.0;
|
|
34
|
+
let intersection = 0;
|
|
35
|
+
for (const bg of bigramsA) {
|
|
36
|
+
if (bigramsB.has(bg))
|
|
37
|
+
intersection++;
|
|
38
|
+
}
|
|
39
|
+
const union = bigramsA.size + bigramsB.size - intersection;
|
|
40
|
+
return intersection / union;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Dice coefficient for sequence similarity.
|
|
44
|
+
* Similar to difflib — better for medium-length signatures.
|
|
45
|
+
*/
|
|
46
|
+
function diceSimilarity(a, b) {
|
|
47
|
+
const bgA = new Set();
|
|
48
|
+
const bgB = new Set();
|
|
49
|
+
for (let i = 0; i < a.length - 1; i++)
|
|
50
|
+
bgA.add(a.slice(i, i + 2));
|
|
51
|
+
for (let i = 0; i < b.length - 1; i++)
|
|
52
|
+
bgB.add(b.slice(i, i + 2));
|
|
53
|
+
if (bgA.size === 0 || bgB.size === 0)
|
|
54
|
+
return 0;
|
|
55
|
+
let intersection = 0;
|
|
56
|
+
for (const bg of bgA) {
|
|
57
|
+
if (bgB.has(bg))
|
|
58
|
+
intersection++;
|
|
59
|
+
}
|
|
60
|
+
return (2 * intersection) / (bgA.size + bgB.size);
|
|
61
|
+
}
|
|
62
|
+
// ===== Sync Engine =====
|
|
63
|
+
export class SyncEngine {
|
|
64
|
+
store;
|
|
65
|
+
scanner;
|
|
66
|
+
projectRoot;
|
|
67
|
+
constructor(store, scanner, projectRoot) {
|
|
68
|
+
this.store = store;
|
|
69
|
+
this.scanner = scanner;
|
|
70
|
+
this.projectRoot = projectRoot;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Incremental sync: detect changed files → re-scan only those → repair associations.
|
|
74
|
+
*
|
|
75
|
+
* Phases:
|
|
76
|
+
* 1. Hash compare — compute current hashes vs fileSnapshot
|
|
77
|
+
* 2. Re-scan changed files → add/update units
|
|
78
|
+
* 3. Remove units from deleted files → mark stale
|
|
79
|
+
* 4. Repair broken associations via fuzzy match
|
|
80
|
+
* 5. Write updated mesh.json and fileSnapshot
|
|
81
|
+
*/
|
|
82
|
+
async sync(options) {
|
|
83
|
+
const t0 = Date.now();
|
|
84
|
+
const threshold = options.fuzzyThreshold ?? 0.45;
|
|
85
|
+
// Load cache
|
|
86
|
+
this.store.ensureDirs();
|
|
87
|
+
this.store.load();
|
|
88
|
+
const grid = this.store.getGrid();
|
|
89
|
+
const oldSnapshot = grid?.fileSnapshot ?? {};
|
|
90
|
+
// === Phase 1: Detect diffs ===
|
|
91
|
+
const sourceExts = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.py', '.go', '.rs', '.md']);
|
|
92
|
+
const testPatterns = ['.spec.', '.test.', '_test.'];
|
|
93
|
+
const skipDirs = new Set(['node_modules', 'dist', '.next', 'vendor', 'target', '__pycache__']);
|
|
94
|
+
const configFiles = ['package.json', 'pyproject.toml', 'go.mod', 'Cargo.toml', 'docker-compose.yml'];
|
|
95
|
+
const collectFiles = () => {
|
|
96
|
+
const files = [];
|
|
97
|
+
const collect = (dir) => {
|
|
98
|
+
if (!fs.existsSync(dir))
|
|
99
|
+
return;
|
|
100
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
101
|
+
const rel = path.relative(this.projectRoot, path.join(dir, entry.name));
|
|
102
|
+
if (entry.isDirectory()) {
|
|
103
|
+
if (!skipDirs.has(entry.name) && !entry.name.startsWith('.')) {
|
|
104
|
+
collect(path.join(dir, entry.name));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
const ext = path.extname(entry.name);
|
|
109
|
+
if (sourceExts.has(ext)) {
|
|
110
|
+
if (!testPatterns.some((p) => entry.name.includes(p))) {
|
|
111
|
+
files.push(rel);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if (configFiles.includes(entry.name)) {
|
|
115
|
+
files.push(rel);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
// Scan source dirs
|
|
121
|
+
['apps', 'packages', 'src', 'lib', 'cmd', 'internal', 'pkg', 'app'].forEach((d) => collect(path.join(this.projectRoot, d)));
|
|
122
|
+
// Rules
|
|
123
|
+
if (options.includeRules)
|
|
124
|
+
collect(path.join(this.projectRoot, '.claude', 'rules'));
|
|
125
|
+
// Examples
|
|
126
|
+
if (options.includeExamples)
|
|
127
|
+
collect(path.join(this.projectRoot, '.claude', 'examples'));
|
|
128
|
+
return files;
|
|
129
|
+
};
|
|
130
|
+
const currentFiles = collectFiles();
|
|
131
|
+
const newSnapshot = {};
|
|
132
|
+
const changedFiles = [];
|
|
133
|
+
const removedFiles = [];
|
|
134
|
+
for (const file of currentFiles) {
|
|
135
|
+
const abs = path.join(this.projectRoot, file);
|
|
136
|
+
const hash = sha256(fs.readFileSync(abs, 'utf-8'));
|
|
137
|
+
newSnapshot[file] = hash;
|
|
138
|
+
if (!oldSnapshot[file]) {
|
|
139
|
+
changedFiles.push(file); // new file
|
|
140
|
+
}
|
|
141
|
+
else if (oldSnapshot[file] !== hash) {
|
|
142
|
+
changedFiles.push(file); // modified
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Detected removed files
|
|
146
|
+
for (const oldFile of Object.keys(oldSnapshot)) {
|
|
147
|
+
if (!newSnapshot[oldFile]) {
|
|
148
|
+
removedFiles.push(oldFile);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// No changes — fast path
|
|
152
|
+
if (changedFiles.length === 0 && removedFiles.length === 0) {
|
|
153
|
+
return {
|
|
154
|
+
changedFiles: [],
|
|
155
|
+
removedFiles: [],
|
|
156
|
+
updatedUnits: 0,
|
|
157
|
+
staleUnits: 0,
|
|
158
|
+
repairedAssociations: 0,
|
|
159
|
+
brokenAssociations: 0,
|
|
160
|
+
elapsedMs: Date.now() - t0,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
// === Phase 2: Re-scan changed files ===
|
|
164
|
+
let updatedUnits = 0;
|
|
165
|
+
let staleUnits = 0;
|
|
166
|
+
if (changedFiles.length > 0) {
|
|
167
|
+
// Collect all existing units whose source file is in the changed set
|
|
168
|
+
const changedSet = new Set(changedFiles);
|
|
169
|
+
const allUnits = await this.store.listUnits({ includeArchived: false });
|
|
170
|
+
// Mark old units from changed files as stale (will be replaced or revived)
|
|
171
|
+
for (const unit of allUnits) {
|
|
172
|
+
if (unit.source?.file && changedSet.has(unit.source.file)) {
|
|
173
|
+
// Mark as stale — we'll try to match after re-scan
|
|
174
|
+
unit.meta.status = 'stale';
|
|
175
|
+
this.store.saveUnit(unit);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Now do a partial scan of changed files
|
|
179
|
+
// Strategy: fork the scanner's scan but only for changed files
|
|
180
|
+
// Since the scanner works at project level, we do a targeted approach
|
|
181
|
+
const scannedUnits = await this.scanChangedFiles(changedFiles);
|
|
182
|
+
// Merge: try fuzzy-match scanned units to existing stale ones
|
|
183
|
+
const staleUnits = allUnits.filter((u) => u.meta.status === 'stale');
|
|
184
|
+
for (const newUnit of scannedUnits) {
|
|
185
|
+
const matched = this.fuzzyMatchUnit(newUnit, staleUnits, threshold);
|
|
186
|
+
if (matched) {
|
|
187
|
+
// Update existing unit with new content
|
|
188
|
+
matched.summary = newUnit.summary;
|
|
189
|
+
matched.signatures = newUnit.signatures;
|
|
190
|
+
matched.content = newUnit.content;
|
|
191
|
+
matched.source = newUnit.source;
|
|
192
|
+
matched.meta.status = 'active';
|
|
193
|
+
matched.meta.updated = new Date().toISOString();
|
|
194
|
+
this.store.saveUnit(matched);
|
|
195
|
+
updatedUnits++;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// Completely new unit
|
|
199
|
+
this.store.saveUnit(newUnit);
|
|
200
|
+
updatedUnits++;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
} // end if (changedFiles.length > 0)
|
|
204
|
+
// Count how many stale units remain unmatched
|
|
205
|
+
this.store.reload();
|
|
206
|
+
const remainingStale = (await this.store.listUnits()).filter((u) => u.meta.status === 'stale' && u.source?.file && changedFiles.includes(u.source.file));
|
|
207
|
+
staleUnits = remainingStale.length;
|
|
208
|
+
// === Phase 3: Handle removed files ===
|
|
209
|
+
if (removedFiles.length > 0) {
|
|
210
|
+
const removedSet = new Set(removedFiles);
|
|
211
|
+
const allUnits = await this.store.listUnits();
|
|
212
|
+
for (const unit of allUnits) {
|
|
213
|
+
if (unit.source?.file && removedSet.has(unit.source.file)) {
|
|
214
|
+
unit.meta.status = 'stale';
|
|
215
|
+
this.store.saveUnit(unit);
|
|
216
|
+
staleUnits++;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// === Phase 4: Repair broken associations ===
|
|
221
|
+
const { repaired, broken } = await this.repairAssociations(threshold);
|
|
222
|
+
// === Phase 5: Update mesh.json ===
|
|
223
|
+
const allActiveUnits = await this.store.listUnits({ includeArchived: false });
|
|
224
|
+
this.updateGrid(allActiveUnits, newSnapshot);
|
|
225
|
+
return {
|
|
226
|
+
changedFiles,
|
|
227
|
+
removedFiles,
|
|
228
|
+
updatedUnits,
|
|
229
|
+
staleUnits,
|
|
230
|
+
repairedAssociations: repaired,
|
|
231
|
+
brokenAssociations: broken,
|
|
232
|
+
elapsedMs: Date.now() - t0,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Partial scan — only re-scan changed TypeScript/markdown files.
|
|
237
|
+
* Uses ts-morph for .ts files, inline parsing for .md / config.
|
|
238
|
+
*/
|
|
239
|
+
async scanChangedFiles(files) {
|
|
240
|
+
const units = [];
|
|
241
|
+
for (const file of files) {
|
|
242
|
+
const abs = path.join(this.projectRoot, file);
|
|
243
|
+
if (!fs.existsSync(abs))
|
|
244
|
+
continue;
|
|
245
|
+
if (file.endsWith('.ts')) {
|
|
246
|
+
// For TypeScript files, use ts-morph project (scoped to this file only)
|
|
247
|
+
const { Project } = await import('ts-morph');
|
|
248
|
+
const project = new Project();
|
|
249
|
+
try {
|
|
250
|
+
project.addSourceFileAtPath(abs);
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
continue; // parse error — skip
|
|
254
|
+
}
|
|
255
|
+
for (const sourceFile of project.getSourceFiles()) {
|
|
256
|
+
for (const cls of sourceFile.getClasses()) {
|
|
257
|
+
const className = cls.getName();
|
|
258
|
+
if (!className || cls.isAbstract())
|
|
259
|
+
continue;
|
|
260
|
+
for (const method of cls.getMethods()) {
|
|
261
|
+
const scope = method.getScope();
|
|
262
|
+
if (scope !== 'public' && scope !== undefined)
|
|
263
|
+
continue;
|
|
264
|
+
const methodName = method.getName();
|
|
265
|
+
const signature = `${className}.${methodName}`;
|
|
266
|
+
const params = method.getParameters().map((p) => `${p.getName()}: ${p.getType().getText()}`);
|
|
267
|
+
const returnType = method.getReturnType().getText();
|
|
268
|
+
units.push({
|
|
269
|
+
id: `method_${this.sanitizeId(signature)}`,
|
|
270
|
+
type: 'method',
|
|
271
|
+
summary: `${signature} — ${this.extractJsDoc(method)}`,
|
|
272
|
+
source: { file, lines: `${method.getStartLineNumber()}-${method.getEndLineNumber()}` },
|
|
273
|
+
signatures: [signature],
|
|
274
|
+
content: {
|
|
275
|
+
description: this.extractJsDoc(method) || `${signature}()`,
|
|
276
|
+
inputs: params.length > 0 ? params.join(', ') : 'none',
|
|
277
|
+
outputs: returnType,
|
|
278
|
+
code_snippet: method.getText(),
|
|
279
|
+
},
|
|
280
|
+
associations: [],
|
|
281
|
+
meta: {
|
|
282
|
+
created: new Date().toISOString(),
|
|
283
|
+
updated: new Date().toISOString(),
|
|
284
|
+
confidence: 0.8,
|
|
285
|
+
usage_count: 0,
|
|
286
|
+
status: 'active',
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// Exported functions
|
|
292
|
+
for (const func of sourceFile.getFunctions()) {
|
|
293
|
+
if (!func.isExported())
|
|
294
|
+
continue;
|
|
295
|
+
const funcName = func.getName();
|
|
296
|
+
if (!funcName)
|
|
297
|
+
continue;
|
|
298
|
+
const params = func.getParameters().map((p) => `${p.getName()}: ${p.getType().getText()}`);
|
|
299
|
+
const returnType = func.getReturnType().getText();
|
|
300
|
+
units.push({
|
|
301
|
+
id: `method_${this.sanitizeId(funcName)}`,
|
|
302
|
+
type: 'method',
|
|
303
|
+
summary: `${funcName}() — ${this.extractJsDoc(func)}`,
|
|
304
|
+
source: { file, lines: `${func.getStartLineNumber()}-${func.getEndLineNumber()}` },
|
|
305
|
+
signatures: [funcName],
|
|
306
|
+
content: {
|
|
307
|
+
description: this.extractJsDoc(func) || `${funcName}()`,
|
|
308
|
+
inputs: params.length > 0 ? params.join(', ') : 'none',
|
|
309
|
+
outputs: returnType,
|
|
310
|
+
code_snippet: func.getText().split('\n').slice(0, 10).join('\n'),
|
|
311
|
+
},
|
|
312
|
+
associations: [],
|
|
313
|
+
meta: {
|
|
314
|
+
created: new Date().toISOString(),
|
|
315
|
+
updated: new Date().toISOString(),
|
|
316
|
+
confidence: 0.8,
|
|
317
|
+
usage_count: 0,
|
|
318
|
+
status: 'active',
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if (file.endsWith('.py') || file.endsWith('.js') || file.endsWith('.go') || file.endsWith('.rs')) {
|
|
325
|
+
// Non-TS language files: only tracked via hash snapshot, full re-scan on next init.
|
|
326
|
+
// Incremental AST parsing for these languages requires language-specific parsers.
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
if (file.endsWith('.md') && file.startsWith('.claude/rules/')) {
|
|
330
|
+
// Rules — extract sections
|
|
331
|
+
const content = fs.readFileSync(abs, 'utf-8');
|
|
332
|
+
const sections = content.split(/^## /m).filter(Boolean);
|
|
333
|
+
const safeFile = path.basename(file).replace('.md', '').replace(/[^a-zA-Z0-9_\-]/g, '_').replace(/_+/g, '_').slice(0, 30).toLowerCase();
|
|
334
|
+
for (const section of sections) {
|
|
335
|
+
const title = section.split('\n')[0].trim();
|
|
336
|
+
const body = section.split('\n').slice(1).join('\n').trim();
|
|
337
|
+
if (!title || body.length < 50)
|
|
338
|
+
continue;
|
|
339
|
+
const safeTitle = title.replace(/[^a-zA-Z0-9_\-]/g, '_').replace(/_+/g, '_').slice(0, 50).toLowerCase();
|
|
340
|
+
if (!safeTitle || safeTitle === '_')
|
|
341
|
+
continue;
|
|
342
|
+
units.push({
|
|
343
|
+
id: `rule_${safeFile}_${safeTitle}`,
|
|
344
|
+
type: 'pattern',
|
|
345
|
+
summary: `${path.basename(file).replace('.md', '')}: ${title}`,
|
|
346
|
+
source: { file },
|
|
347
|
+
signatures: [title, path.basename(file).replace('.md', '').replace(/-/g, ' ')],
|
|
348
|
+
content: { description: body.slice(0, 500) },
|
|
349
|
+
associations: [],
|
|
350
|
+
meta: {
|
|
351
|
+
created: new Date().toISOString(),
|
|
352
|
+
updated: new Date().toISOString(),
|
|
353
|
+
confidence: 0.9,
|
|
354
|
+
usage_count: 0,
|
|
355
|
+
status: 'active',
|
|
356
|
+
},
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
// Rule trigger
|
|
360
|
+
units.push({
|
|
361
|
+
id: `trigger_rule_${safeFile}`,
|
|
362
|
+
type: 'rule_trigger',
|
|
363
|
+
summary: `When working on ${path.basename(file).replace('.md', '').replace(/-/g, ' ')} → load ${file}`,
|
|
364
|
+
source: { file },
|
|
365
|
+
signatures: [path.basename(file).replace('.md', '').replace(/-/g, ' ')],
|
|
366
|
+
content: {
|
|
367
|
+
description: `Load ${file} when working on relevant code`,
|
|
368
|
+
trigger: `Working on ${path.basename(file).replace('.md', '').replace(/-/g, ' ')} related code`,
|
|
369
|
+
action: `Load ${file}`,
|
|
370
|
+
},
|
|
371
|
+
associations: [],
|
|
372
|
+
meta: {
|
|
373
|
+
created: new Date().toISOString(),
|
|
374
|
+
updated: new Date().toISOString(),
|
|
375
|
+
confidence: 0.8,
|
|
376
|
+
usage_count: 0,
|
|
377
|
+
status: 'active',
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
if (file === 'package.json') {
|
|
382
|
+
const pkg = JSON.parse(fs.readFileSync(abs, 'utf-8'));
|
|
383
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
384
|
+
const keyDeps = Object.entries(deps)
|
|
385
|
+
.filter(([name]) => ['next', 'react', 'nestjs', 'typeorm', 'chakra', 'zustand', 'swr', 'pnpm', 'typescript'].some((k) => name.includes(k)))
|
|
386
|
+
.map(([name, ver]) => `${name}@${ver}`);
|
|
387
|
+
if (keyDeps.length > 0) {
|
|
388
|
+
units.push({
|
|
389
|
+
id: 'config_tech_stack',
|
|
390
|
+
type: 'config',
|
|
391
|
+
summary: `Tech stack: ${keyDeps.slice(0, 8).join(', ')}`,
|
|
392
|
+
source: { file: 'package.json' },
|
|
393
|
+
signatures: ['tech stack', 'dependencies', '技术栈'],
|
|
394
|
+
content: { description: `Key dependencies: ${keyDeps.join(', ')}` },
|
|
395
|
+
associations: [],
|
|
396
|
+
meta: {
|
|
397
|
+
created: new Date().toISOString(),
|
|
398
|
+
updated: new Date().toISOString(),
|
|
399
|
+
confidence: 0.95,
|
|
400
|
+
usage_count: 0,
|
|
401
|
+
status: 'active',
|
|
402
|
+
},
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return units;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Fuzzy-match a newly scanned unit against an existing stale unit.
|
|
411
|
+
* Returns the matching stale unit or null.
|
|
412
|
+
*
|
|
413
|
+
* Matching signals:
|
|
414
|
+
* 1. Same source file + high signature overlap (jaccard ≥ threshold)
|
|
415
|
+
* 2. Same source file + high summary similarity (dice ≥ threshold)
|
|
416
|
+
* 3. Same unit id (method was renamed but we kept same id pattern)
|
|
417
|
+
*/
|
|
418
|
+
fuzzyMatchUnit(newUnit, staleUnits, threshold) {
|
|
419
|
+
let bestMatch = null;
|
|
420
|
+
let bestScore = 0;
|
|
421
|
+
for (const stale of staleUnits) {
|
|
422
|
+
// Must be from the same file
|
|
423
|
+
if (stale.source?.file !== newUnit.source?.file)
|
|
424
|
+
continue;
|
|
425
|
+
let score = 0;
|
|
426
|
+
// Signal 1: Signature overlap
|
|
427
|
+
const newSigs = new Set(newUnit.signatures.map((s) => s.toLowerCase()));
|
|
428
|
+
const staleSigs = new Set(stale.signatures.map((s) => s.toLowerCase()));
|
|
429
|
+
let sigIntersection = 0;
|
|
430
|
+
for (const sig of staleSigs) {
|
|
431
|
+
if (newSigs.has(sig))
|
|
432
|
+
sigIntersection++;
|
|
433
|
+
}
|
|
434
|
+
const sigUnion = newSigs.size + staleSigs.size - sigIntersection;
|
|
435
|
+
if (sigUnion > 0) {
|
|
436
|
+
const sigScore = sigIntersection / sigUnion;
|
|
437
|
+
score = Math.max(score, sigScore * 1.2); // weight signatures higher
|
|
438
|
+
}
|
|
439
|
+
// Signal 2: Summary similarity
|
|
440
|
+
const summaryScore = diceSimilarity(newUnit.summary.toLowerCase(), stale.summary.toLowerCase());
|
|
441
|
+
score = Math.max(score, summaryScore);
|
|
442
|
+
// Signal 3: Unit id match (same "slot")
|
|
443
|
+
if (newUnit.id === stale.id) {
|
|
444
|
+
score = Math.max(score, 0.9); // strong signal
|
|
445
|
+
}
|
|
446
|
+
// Signal 4: Code snippet Jaccard content
|
|
447
|
+
if (newUnit.content.code_snippet && stale.content.code_snippet) {
|
|
448
|
+
const codeScore = jaccardBigramSimilarity(newUnit.content.code_snippet.toLowerCase(), stale.content.code_snippet.toLowerCase());
|
|
449
|
+
// Code similarity is weaker (could be different impl same signature)
|
|
450
|
+
score = Math.max(score, codeScore * 0.4);
|
|
451
|
+
}
|
|
452
|
+
if (score >= threshold && score > bestScore) {
|
|
453
|
+
bestScore = score;
|
|
454
|
+
bestMatch = stale;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return bestMatch;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Repair broken associations across all units.
|
|
461
|
+
*
|
|
462
|
+
* For each association whose target unit is stale/archived/missing:
|
|
463
|
+
* 1. Try fuzzy match against active units by signature
|
|
464
|
+
* 2. If match found → repair the link
|
|
465
|
+
* 3. If no match → reduce weight, mark for eventual removal
|
|
466
|
+
*/
|
|
467
|
+
async repairAssociations(threshold) {
|
|
468
|
+
const allUnits = await this.store.listUnits({ includeArchived: false });
|
|
469
|
+
const unitMap = new Map();
|
|
470
|
+
const activeById = new Map();
|
|
471
|
+
for (const unit of allUnits) {
|
|
472
|
+
unitMap.set(unit.id, unit);
|
|
473
|
+
if (unit.meta.status === 'active') {
|
|
474
|
+
activeById.set(unit.id, unit);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
// Build signature index of active units
|
|
478
|
+
const sigIndex = new Map(); // signature → unit id
|
|
479
|
+
for (const [id, unit] of activeById) {
|
|
480
|
+
for (const sig of unit.signatures) {
|
|
481
|
+
sigIndex.set(sig.toLowerCase(), id);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
let repaired = 0;
|
|
485
|
+
let broken = 0;
|
|
486
|
+
for (const unit of allUnits) {
|
|
487
|
+
const fixedAssociations = [];
|
|
488
|
+
for (const assoc of unit.associations) {
|
|
489
|
+
const target = unitMap.get(assoc.to);
|
|
490
|
+
if (target && (target.meta.status === 'active' || target.meta.status === 'archived')) {
|
|
491
|
+
// Target is still valid
|
|
492
|
+
fixedAssociations.push(assoc);
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
// Try to find a replacement
|
|
496
|
+
const replacement = this.findReplacementAssociation(assoc, activeById, sigIndex, threshold);
|
|
497
|
+
if (replacement) {
|
|
498
|
+
fixedAssociations.push(replacement);
|
|
499
|
+
repaired++;
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
// Keep it but reduce weight — will eventually be garbage collected
|
|
503
|
+
fixedAssociations.push({ ...assoc, weight: assoc.weight * 0.5 });
|
|
504
|
+
broken++;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
if (fixedAssociations.length !== unit.associations.length) {
|
|
508
|
+
unit.associations = fixedAssociations;
|
|
509
|
+
this.store.saveUnit(unit);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
return { repaired, broken };
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Find a replacement unit for a broken association.
|
|
516
|
+
* Strategy:
|
|
517
|
+
* 1. Search signature index for the original unit's summary keywords
|
|
518
|
+
* 2. Fuzzy match summaries against active units
|
|
519
|
+
* 3. Return best match above threshold
|
|
520
|
+
*/
|
|
521
|
+
findReplacementAssociation(old, activeById, sigIndex, threshold) {
|
|
522
|
+
// Try exact signature match first
|
|
523
|
+
const exact = sigIndex.get(old.to.toLowerCase());
|
|
524
|
+
if (exact && exact !== old.to) {
|
|
525
|
+
return { ...old, to: exact, weight: old.weight * 0.7 };
|
|
526
|
+
}
|
|
527
|
+
// Fuzzy search across active unit ids
|
|
528
|
+
let bestId = null;
|
|
529
|
+
let bestScore = 0;
|
|
530
|
+
for (const [id] of activeById) {
|
|
531
|
+
const score = diceSimilarity(old.to.toLowerCase(), id.toLowerCase());
|
|
532
|
+
if (score >= threshold && score > bestScore) {
|
|
533
|
+
bestScore = score;
|
|
534
|
+
bestId = id;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
if (bestId) {
|
|
538
|
+
return { ...old, to: bestId, weight: old.weight * bestScore };
|
|
539
|
+
}
|
|
540
|
+
return null;
|
|
541
|
+
}
|
|
542
|
+
updateGrid(units, fileSnapshot) {
|
|
543
|
+
const edgeIndex = {};
|
|
544
|
+
let totalAssociations = 0;
|
|
545
|
+
for (const unit of units) {
|
|
546
|
+
if (unit.meta.status === 'archived')
|
|
547
|
+
continue;
|
|
548
|
+
if (unit.associations.length > 0) {
|
|
549
|
+
edgeIndex[unit.id] = unit.associations;
|
|
550
|
+
totalAssociations += unit.associations.length;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
const grid = {
|
|
554
|
+
version: '0.1.0',
|
|
555
|
+
project: path.basename(this.projectRoot),
|
|
556
|
+
lastScanAt: new Date().toISOString(),
|
|
557
|
+
stats: {
|
|
558
|
+
totalUnits: units.length,
|
|
559
|
+
activeUnits: units.filter((u) => u.meta.status === 'active').length,
|
|
560
|
+
archivedUnits: units.filter((u) => u.meta.status === 'archived').length,
|
|
561
|
+
totalAssociations,
|
|
562
|
+
},
|
|
563
|
+
edgeIndex,
|
|
564
|
+
fileSnapshot,
|
|
565
|
+
};
|
|
566
|
+
this.store.saveGrid(grid);
|
|
567
|
+
}
|
|
568
|
+
// === Helpers (delegated to scanner where possible, copied for self-contained scan) ===
|
|
569
|
+
sanitizeId(text) {
|
|
570
|
+
return text.replace(/\./g, '_').replace(/[^a-zA-Z0-9_\-]/g, '_').replace(/_+/g, '_').toLowerCase();
|
|
571
|
+
}
|
|
572
|
+
extractJsDoc(node) {
|
|
573
|
+
const jsDocs = node.getJsDocs?.();
|
|
574
|
+
if (jsDocs && jsDocs.length > 0) {
|
|
575
|
+
return jsDocs[0].getDescription().trim() || '';
|
|
576
|
+
}
|
|
577
|
+
return '';
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "memgrid",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Project-level semantic memory system for AI coding agents. Replaces full-codebase context loading with a self-evolving knowledge-mesh.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"memgrid": "dist/serve/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"CHANGELOG.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"dev": "tsc --watch",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"cli": "node dist/serve/cli.js"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"ai",
|
|
25
|
+
"memory",
|
|
26
|
+
"claude-code",
|
|
27
|
+
"agent",
|
|
28
|
+
"coding-agent",
|
|
29
|
+
"knowledge-graph",
|
|
30
|
+
"semantic-memory",
|
|
31
|
+
"rag",
|
|
32
|
+
"context"
|
|
33
|
+
],
|
|
34
|
+
"author": "wenliangw",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/wenliangw/memgrid"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1",
|
|
42
|
+
"commander": "^13",
|
|
43
|
+
"minisearch": "^7",
|
|
44
|
+
"ts-morph": "^28"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^26",
|
|
48
|
+
"typescript": "^6",
|
|
49
|
+
"vitest": "^4"
|
|
50
|
+
}
|
|
51
|
+
}
|