smart-claude-memory-mcp 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +38 -0
- package/CHANGELOG.md +52 -0
- package/LICENSE +21 -0
- package/README.md +790 -0
- package/dist/chunker.js +33 -0
- package/dist/chunker.js.map +1 -0
- package/dist/config.js +23 -0
- package/dist/config.js.map +1 -0
- package/dist/curriculum/daemon.js +190 -0
- package/dist/curriculum/daemon.js.map +1 -0
- package/dist/curriculum/scanner.js +237 -0
- package/dist/curriculum/scanner.js.map +1 -0
- package/dist/index.js +429 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/migrations.js +128 -0
- package/dist/lib/migrations.js.map +1 -0
- package/dist/ollama.js +59 -0
- package/dist/ollama.js.map +1 -0
- package/dist/project-detect.js +102 -0
- package/dist/project-detect.js.map +1 -0
- package/dist/project.js +26 -0
- package/dist/project.js.map +1 -0
- package/dist/sleep/daemon.js +215 -0
- package/dist/sleep/daemon.js.map +1 -0
- package/dist/sleep/miner.js +285 -0
- package/dist/sleep/miner.js.map +1 -0
- package/dist/supabase.js +405 -0
- package/dist/supabase.js.map +1 -0
- package/dist/telemetry/emit.js +19 -0
- package/dist/telemetry/emit.js.map +1 -0
- package/dist/telemetry/pruner.js +141 -0
- package/dist/telemetry/pruner.js.map +1 -0
- package/dist/telemetry/types.js +2 -0
- package/dist/telemetry/types.js.map +1 -0
- package/dist/tools/backlog.js +599 -0
- package/dist/tools/backlog.js.map +1 -0
- package/dist/tools/batch-freeze-patterns.js +243 -0
- package/dist/tools/batch-freeze-patterns.js.map +1 -0
- package/dist/tools/bloat-audit.js +101 -0
- package/dist/tools/bloat-audit.js.map +1 -0
- package/dist/tools/checkpoint.js +259 -0
- package/dist/tools/checkpoint.js.map +1 -0
- package/dist/tools/compact.js +60 -0
- package/dist/tools/compact.js.map +1 -0
- package/dist/tools/conflict.js +102 -0
- package/dist/tools/conflict.js.map +1 -0
- package/dist/tools/curriculum.js +225 -0
- package/dist/tools/curriculum.js.map +1 -0
- package/dist/tools/frozen-cache.js +106 -0
- package/dist/tools/frozen-cache.js.map +1 -0
- package/dist/tools/health.js +368 -0
- package/dist/tools/health.js.map +1 -0
- package/dist/tools/hygiene.js +309 -0
- package/dist/tools/hygiene.js.map +1 -0
- package/dist/tools/image.js +107 -0
- package/dist/tools/image.js.map +1 -0
- package/dist/tools/list-global-patterns.js +101 -0
- package/dist/tools/list-global-patterns.js.map +1 -0
- package/dist/tools/orchestrator.js +113 -0
- package/dist/tools/orchestrator.js.map +1 -0
- package/dist/tools/policy.js +90 -0
- package/dist/tools/policy.js.map +1 -0
- package/dist/tools/refactor.js +220 -0
- package/dist/tools/refactor.js.map +1 -0
- package/dist/tools/save.js +42 -0
- package/dist/tools/save.js.map +1 -0
- package/dist/tools/search.js +189 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/setup.js +868 -0
- package/dist/tools/setup.js.map +1 -0
- package/dist/tools/shared-schemas.js +24 -0
- package/dist/tools/shared-schemas.js.map +1 -0
- package/dist/tools/skills.js +174 -0
- package/dist/tools/skills.js.map +1 -0
- package/dist/tools/sleep.js +239 -0
- package/dist/tools/sleep.js.map +1 -0
- package/dist/tools/sovereign-constitution.js +319 -0
- package/dist/tools/sovereign-constitution.js.map +1 -0
- package/dist/tools/summarize.js +55 -0
- package/dist/tools/summarize.js.map +1 -0
- package/dist/tools/sync.js +255 -0
- package/dist/tools/sync.js.map +1 -0
- package/dist/tools/system_dashboard.js +181 -0
- package/dist/tools/system_dashboard.js.map +1 -0
- package/dist/tools/update-rule.js +15 -0
- package/dist/tools/update-rule.js.map +1 -0
- package/dist/tools/verification.js +333 -0
- package/dist/tools/verification.js.map +1 -0
- package/dist/trajectory/daemon.js +270 -0
- package/dist/trajectory/daemon.js.map +1 -0
- package/dist/trajectory/stripper.js +124 -0
- package/dist/trajectory/stripper.js.map +1 -0
- package/dist/trajectory/summarizer.js +77 -0
- package/dist/trajectory/summarizer.js.map +1 -0
- package/dist/transactions/checkpoint.js +272 -0
- package/dist/transactions/checkpoint.js.map +1 -0
- package/dist/verification-gate.js +43 -0
- package/dist/verification-gate.js.map +1 -0
- package/dist/version.js +16 -0
- package/dist/version.js.map +1 -0
- package/hooks/README.md +54 -0
- package/hooks/md-policy.py +497 -0
- package/marketplace.json +13 -0
- package/package.json +66 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { readFile, stat } from "node:fs/promises";
|
|
2
|
+
import { basename, dirname, extname, join } from "node:path";
|
|
3
|
+
export const HARD_LIMIT = 750;
|
|
4
|
+
// ─── exclusion list ──────────────────────────────────────────────────────
|
|
5
|
+
// Auto-generated files that should never be subject to the line limit.
|
|
6
|
+
const EXCLUDE_EXACT_BASENAMES = new Set([
|
|
7
|
+
"types.ts", // Supabase-generated types
|
|
8
|
+
]);
|
|
9
|
+
const EXCLUDE_SUFFIXES = [
|
|
10
|
+
".arb", // Dart/Flutter localization bundles
|
|
11
|
+
".l10n.dart", // Flutter l10n outputs
|
|
12
|
+
".g.dart", // build_runner generated
|
|
13
|
+
".freezed.dart", // freezed generated
|
|
14
|
+
];
|
|
15
|
+
export function isExcluded(path) {
|
|
16
|
+
const name = basename(path);
|
|
17
|
+
if (EXCLUDE_EXACT_BASENAMES.has(name))
|
|
18
|
+
return true;
|
|
19
|
+
for (const suf of EXCLUDE_SUFFIXES) {
|
|
20
|
+
if (name.toLowerCase().endsWith(suf))
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const LANG_PARSERS = {
|
|
26
|
+
ts: parseTypeScriptLike,
|
|
27
|
+
tsx: parseTypeScriptLike,
|
|
28
|
+
js: parseTypeScriptLike,
|
|
29
|
+
jsx: parseTypeScriptLike,
|
|
30
|
+
py: parsePython,
|
|
31
|
+
dart: parseDart,
|
|
32
|
+
};
|
|
33
|
+
function extLang(path) {
|
|
34
|
+
return extname(path).replace(/^\./, "").toLowerCase();
|
|
35
|
+
}
|
|
36
|
+
function parseTypeScriptLike(text) {
|
|
37
|
+
const lines = text.split(/\r?\n/);
|
|
38
|
+
const re = /^(export\s+)?(default\s+)?(async\s+)?(function|class|const|let|var|type|interface|enum)\s+([A-Za-z_$][\w$]*)/;
|
|
39
|
+
const raw = [];
|
|
40
|
+
for (let i = 0; i < lines.length; i++) {
|
|
41
|
+
const line = lines[i];
|
|
42
|
+
if (/^\s/.test(line))
|
|
43
|
+
continue;
|
|
44
|
+
const m = line.match(re);
|
|
45
|
+
if (m) {
|
|
46
|
+
const kindRaw = m[4];
|
|
47
|
+
const kind = kindRaw === "function" || kindRaw === "class" || kindRaw === "type" ||
|
|
48
|
+
kindRaw === "interface" || kindRaw === "const" || kindRaw === "enum"
|
|
49
|
+
? kindRaw
|
|
50
|
+
: "other";
|
|
51
|
+
raw.push({ name: m[5], kind, exported: !!m[1], start_line: i + 1 });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return finishSymbols(raw, lines.length);
|
|
55
|
+
}
|
|
56
|
+
function parsePython(text) {
|
|
57
|
+
const lines = text.split(/\r?\n/);
|
|
58
|
+
const re = /^(class|def|async\s+def)\s+([A-Za-z_][\w]*)/;
|
|
59
|
+
const raw = [];
|
|
60
|
+
for (let i = 0; i < lines.length; i++) {
|
|
61
|
+
if (/^\s/.test(lines[i]))
|
|
62
|
+
continue;
|
|
63
|
+
const m = lines[i].match(re);
|
|
64
|
+
if (m) {
|
|
65
|
+
raw.push({
|
|
66
|
+
name: m[2],
|
|
67
|
+
kind: m[1].startsWith("class") ? "class" : "function",
|
|
68
|
+
exported: true,
|
|
69
|
+
start_line: i + 1,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return finishSymbols(raw, lines.length);
|
|
74
|
+
}
|
|
75
|
+
function parseDart(text) {
|
|
76
|
+
const lines = text.split(/\r?\n/);
|
|
77
|
+
const re = /^(?:abstract\s+|final\s+|sealed\s+|mixin\s+|extension\s+)?(class|enum|mixin|typedef)\s+([A-Za-z_][\w]*)/;
|
|
78
|
+
const fnRe = /^(?:static\s+|final\s+|const\s+)?(?:[\w<>?,\s]+\s+)?([A-Za-z_][\w]*)\s*\(/;
|
|
79
|
+
const raw = [];
|
|
80
|
+
for (let i = 0; i < lines.length; i++) {
|
|
81
|
+
if (/^\s/.test(lines[i]))
|
|
82
|
+
continue;
|
|
83
|
+
const line = lines[i];
|
|
84
|
+
const mCls = line.match(re);
|
|
85
|
+
if (mCls) {
|
|
86
|
+
raw.push({
|
|
87
|
+
name: mCls[2],
|
|
88
|
+
kind: mCls[1] === "class" || mCls[1] === "mixin" ? "class" : "type",
|
|
89
|
+
exported: true,
|
|
90
|
+
start_line: i + 1,
|
|
91
|
+
});
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const mFn = line.match(fnRe);
|
|
95
|
+
if (mFn && !["if", "for", "while", "switch", "return"].includes(mFn[1])) {
|
|
96
|
+
raw.push({ name: mFn[1], kind: "function", exported: true, start_line: i + 1 });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return finishSymbols(raw, lines.length);
|
|
100
|
+
}
|
|
101
|
+
function finishSymbols(raw, totalLines) {
|
|
102
|
+
return raw.map((s, i) => {
|
|
103
|
+
const end = i + 1 < raw.length ? raw[i + 1].start_line - 1 : totalLines;
|
|
104
|
+
return {
|
|
105
|
+
...s,
|
|
106
|
+
end_line: end,
|
|
107
|
+
lines: end - s.start_line + 1,
|
|
108
|
+
bucket: classifyBucket(s.name, s.kind),
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function classifyBucket(name, kind) {
|
|
113
|
+
if (kind === "type" || kind === "interface" || kind === "enum")
|
|
114
|
+
return "types";
|
|
115
|
+
const lower = name.toLowerCase();
|
|
116
|
+
if (/(util|helper|format|parse|normalize|validate|convert|serialize|deserialize|transform|assert|sanitize)/.test(lower)) {
|
|
117
|
+
return "utils";
|
|
118
|
+
}
|
|
119
|
+
if (/(service|manager|controller|handler|repository|store|provider|client|gateway|adapter)/.test(lower)) {
|
|
120
|
+
return "service";
|
|
121
|
+
}
|
|
122
|
+
return "main";
|
|
123
|
+
}
|
|
124
|
+
export function planRefactor(path, text) {
|
|
125
|
+
const currentLines = text.split(/\r?\n/).length;
|
|
126
|
+
const splitCount = Math.max(2, Math.ceil(currentLines / HARD_LIMIT));
|
|
127
|
+
const target = HARD_LIMIT;
|
|
128
|
+
const lang = extLang(path);
|
|
129
|
+
const parser = LANG_PARSERS[lang];
|
|
130
|
+
const base = basename(path, extname(path));
|
|
131
|
+
const dir = dirname(path);
|
|
132
|
+
const ext = extname(path);
|
|
133
|
+
if (!parser) {
|
|
134
|
+
return {
|
|
135
|
+
needed: true,
|
|
136
|
+
current_lines: currentLines,
|
|
137
|
+
target_limit: target,
|
|
138
|
+
split_count: splitCount,
|
|
139
|
+
suggested_files: [],
|
|
140
|
+
imports_to_add: [],
|
|
141
|
+
notes: [
|
|
142
|
+
`No symbol parser for '${lang}' files — provide the split plan manually.`,
|
|
143
|
+
`Target: split ${currentLines}-line file into ~${splitCount} files, each ≤ ${target} lines.`,
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
const symbols = parser(text);
|
|
148
|
+
if (symbols.length === 0) {
|
|
149
|
+
return {
|
|
150
|
+
needed: true,
|
|
151
|
+
current_lines: currentLines,
|
|
152
|
+
target_limit: target,
|
|
153
|
+
split_count: splitCount,
|
|
154
|
+
suggested_files: [],
|
|
155
|
+
imports_to_add: [],
|
|
156
|
+
notes: [
|
|
157
|
+
`Parser found no top-level symbols in ${basename(path)}. Likely a monolithic script — split by logical sections manually.`,
|
|
158
|
+
],
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// Group by bucket, then further subdivide any bucket exceeding the limit.
|
|
162
|
+
const buckets = { main: [], types: [], utils: [], service: [] };
|
|
163
|
+
for (const s of symbols)
|
|
164
|
+
buckets[s.bucket].push(s);
|
|
165
|
+
const parts = [];
|
|
166
|
+
const bucketOrder = ["main", "service", "utils", "types"];
|
|
167
|
+
for (const b of bucketOrder) {
|
|
168
|
+
const group = buckets[b];
|
|
169
|
+
if (group.length === 0)
|
|
170
|
+
continue;
|
|
171
|
+
let current = [];
|
|
172
|
+
let running = 0;
|
|
173
|
+
for (const s of group) {
|
|
174
|
+
if (running + s.lines > target && current.length > 0) {
|
|
175
|
+
parts.push({ role: b, symbols: current, lines: running });
|
|
176
|
+
current = [];
|
|
177
|
+
running = 0;
|
|
178
|
+
}
|
|
179
|
+
current.push(s);
|
|
180
|
+
running += s.lines;
|
|
181
|
+
}
|
|
182
|
+
if (current.length > 0)
|
|
183
|
+
parts.push({ role: b, symbols: current, lines: running });
|
|
184
|
+
}
|
|
185
|
+
// Ensure at least splitCount parts. If heuristic produced fewer, sub-divide the biggest.
|
|
186
|
+
while (parts.length < splitCount) {
|
|
187
|
+
const biggest = parts
|
|
188
|
+
.map((p, i) => ({ i, size: p.lines, count: p.symbols.length }))
|
|
189
|
+
.filter((x) => x.count > 1)
|
|
190
|
+
.sort((a, b) => b.size - a.size)[0];
|
|
191
|
+
if (!biggest)
|
|
192
|
+
break;
|
|
193
|
+
const half = Math.floor(parts[biggest.i].symbols.length / 2);
|
|
194
|
+
const left = parts[biggest.i].symbols.slice(0, half);
|
|
195
|
+
const right = parts[biggest.i].symbols.slice(half);
|
|
196
|
+
const leftLines = left.reduce((s, x) => s + x.lines, 0);
|
|
197
|
+
const rightLines = right.reduce((s, x) => s + x.lines, 0);
|
|
198
|
+
parts.splice(biggest.i, 1, { role: parts[biggest.i].role, symbols: left, lines: leftLines }, { role: parts[biggest.i].role, symbols: right, lines: rightLines });
|
|
199
|
+
}
|
|
200
|
+
const roleCounts = { main: 0, types: 0, utils: 0, service: 0 };
|
|
201
|
+
const suggested = parts.map((p) => {
|
|
202
|
+
roleCounts[p.role] += 1;
|
|
203
|
+
const n = roleCounts[p.role];
|
|
204
|
+
const suffix = p.role === "main" ? "" : `.${p.role}`;
|
|
205
|
+
const indexTag = n > 1 ? `.${n}` : "";
|
|
206
|
+
const fileName = `${base}${suffix}${indexTag}${ext}`;
|
|
207
|
+
return {
|
|
208
|
+
path: join(dir, fileName).replace(/\\/g, "/"),
|
|
209
|
+
role: p.role,
|
|
210
|
+
contains: p.symbols.map((s) => s.name),
|
|
211
|
+
estimated_lines: p.lines,
|
|
212
|
+
};
|
|
213
|
+
});
|
|
214
|
+
const mainFile = suggested.find((s) => s.role === "main") ?? suggested[0];
|
|
215
|
+
const importsToAdd = suggested
|
|
216
|
+
.filter((s) => s !== mainFile)
|
|
217
|
+
.map((s) => {
|
|
218
|
+
const names = s.contains.slice(0, 6).join(", ") + (s.contains.length > 6 ? ", ..." : "");
|
|
219
|
+
const rel = "./" + basename(s.path, ext);
|
|
220
|
+
return `In ${basename(mainFile.path)}: import { ${names} } from "${rel}";`;
|
|
221
|
+
});
|
|
222
|
+
const notes = [
|
|
223
|
+
`Heuristic split by name: types → *.types.*, utils/helpers → *.utils.*, service-layer → *.service.*.`,
|
|
224
|
+
`Cross-file references inside the original are not computed — review and add imports between split files as needed.`,
|
|
225
|
+
`Target: ${splitCount} files, each ≤ ${target} lines. Heuristic produced ${parts.length}.`,
|
|
226
|
+
];
|
|
227
|
+
return {
|
|
228
|
+
needed: true,
|
|
229
|
+
current_lines: currentLines,
|
|
230
|
+
target_limit: target,
|
|
231
|
+
split_count: splitCount,
|
|
232
|
+
suggested_files: suggested,
|
|
233
|
+
imports_to_add: importsToAdd,
|
|
234
|
+
notes,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
export async function checkCodeHygiene(args) {
|
|
238
|
+
const limit = HARD_LIMIT;
|
|
239
|
+
const summary = { ok: 0, grandfathered: 0, excluded: 0, over: 0, missing: 0 };
|
|
240
|
+
const files = await Promise.all(args.paths.map(async (p) => {
|
|
241
|
+
const name = basename(p);
|
|
242
|
+
try {
|
|
243
|
+
await stat(p);
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
summary.missing++;
|
|
247
|
+
return {
|
|
248
|
+
path: p,
|
|
249
|
+
name,
|
|
250
|
+
exists: false,
|
|
251
|
+
lines: 0,
|
|
252
|
+
over_limit: false,
|
|
253
|
+
grandfathered: false,
|
|
254
|
+
excluded: false,
|
|
255
|
+
split_count: 0,
|
|
256
|
+
status: "missing",
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
if (isExcluded(p)) {
|
|
260
|
+
summary.excluded++;
|
|
261
|
+
return {
|
|
262
|
+
path: p,
|
|
263
|
+
name,
|
|
264
|
+
exists: true,
|
|
265
|
+
lines: 0,
|
|
266
|
+
over_limit: false,
|
|
267
|
+
grandfathered: false,
|
|
268
|
+
excluded: true,
|
|
269
|
+
split_count: 0,
|
|
270
|
+
status: "excluded",
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
const text = await readFile(p, "utf8");
|
|
274
|
+
const lines = text.split(/\r?\n/).length;
|
|
275
|
+
const overLimit = lines > limit;
|
|
276
|
+
const splitCount = overLimit ? Math.max(2, Math.ceil(lines / limit)) : 1;
|
|
277
|
+
if (overLimit) {
|
|
278
|
+
summary.grandfathered++;
|
|
279
|
+
summary.over++;
|
|
280
|
+
const plan = planRefactor(p, text);
|
|
281
|
+
return {
|
|
282
|
+
path: p,
|
|
283
|
+
name,
|
|
284
|
+
exists: true,
|
|
285
|
+
lines,
|
|
286
|
+
over_limit: true,
|
|
287
|
+
grandfathered: true,
|
|
288
|
+
excluded: false,
|
|
289
|
+
split_count: splitCount,
|
|
290
|
+
status: "grandfathered",
|
|
291
|
+
refactor_plan: plan,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
summary.ok++;
|
|
295
|
+
return {
|
|
296
|
+
path: p,
|
|
297
|
+
name,
|
|
298
|
+
exists: true,
|
|
299
|
+
lines,
|
|
300
|
+
over_limit: false,
|
|
301
|
+
grandfathered: false,
|
|
302
|
+
excluded: false,
|
|
303
|
+
split_count: 1,
|
|
304
|
+
status: "ok",
|
|
305
|
+
};
|
|
306
|
+
}));
|
|
307
|
+
return { limit, files, summary };
|
|
308
|
+
}
|
|
309
|
+
//# sourceMappingURL=hygiene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hygiene.js","sourceRoot":"","sources":["../../src/tools/hygiene.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { readFile, stat, rm, mkdtemp } from "node:fs/promises";
|
|
2
|
+
import { resolve, extname, join, basename } from "node:path";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
import { captionImage, embed } from "../ollama.js";
|
|
6
|
+
import { upsertChunks, md5 } from "../supabase.js";
|
|
7
|
+
import { currentProjectId } from "../project.js";
|
|
8
|
+
// Formats Moondream's llama.cpp runner accepts natively.
|
|
9
|
+
const NATIVE_IMAGE_EXTS = new Set([".png", ".jpg", ".jpeg"]);
|
|
10
|
+
const MAGIC_TABLE = [
|
|
11
|
+
{ hex: "89504e47", ext: ".png" },
|
|
12
|
+
{ hex: "ffd8ff", ext: ".jpg" },
|
|
13
|
+
{ hex: "52494646", ext: ".webp" }, // also matches other RIFF containers; good enough for vision files
|
|
14
|
+
{ hex: "47494638", ext: ".gif" },
|
|
15
|
+
{ hex: "424d", ext: ".bmp" },
|
|
16
|
+
];
|
|
17
|
+
async function detectFormat(path) {
|
|
18
|
+
const extHint = extname(path).toLowerCase();
|
|
19
|
+
if (NATIVE_IMAGE_EXTS.has(extHint))
|
|
20
|
+
return extHint;
|
|
21
|
+
// Magic-number sniff — defends against mislabeled extensions.
|
|
22
|
+
const buf = await readFile(path);
|
|
23
|
+
const head = buf.subarray(0, 12).toString("hex");
|
|
24
|
+
for (const { hex, ext } of MAGIC_TABLE) {
|
|
25
|
+
if (head.startsWith(hex))
|
|
26
|
+
return ext;
|
|
27
|
+
}
|
|
28
|
+
return extHint || ".bin";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Convert any raster image to PNG via ffmpeg. Returns both the output PNG
|
|
32
|
+
* path AND the unique mkdtemp directory so the caller can wipe the whole
|
|
33
|
+
* directory in one recursive rm — no orphaned temp dirs.
|
|
34
|
+
*/
|
|
35
|
+
async function convertToPng(src) {
|
|
36
|
+
const dir = await mkdtemp(join(tmpdir(), "claude-mem-img-"));
|
|
37
|
+
const dest = join(dir, `${basename(src, extname(src))}.png`);
|
|
38
|
+
try {
|
|
39
|
+
execFileSync("ffmpeg", ["-hide_banner", "-loglevel", "error", "-y", "-i", src, "-frames:v", "1", dest], { stdio: "pipe" });
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
await rm(dir, { recursive: true, force: true }).catch(() => { });
|
|
43
|
+
throw new Error(`ffmpeg conversion of ${basename(src)} → png failed: ${e.message}. ` +
|
|
44
|
+
"Install ffmpeg and ensure it's on PATH, or pass a PNG/JPEG directly.");
|
|
45
|
+
}
|
|
46
|
+
return { path: dest, tempDir: dir };
|
|
47
|
+
}
|
|
48
|
+
export async function indexImage(args) {
|
|
49
|
+
const projectId = args.project_id ?? currentProjectId;
|
|
50
|
+
const abs = resolve(args.image_path);
|
|
51
|
+
const info = await stat(abs);
|
|
52
|
+
if (!info.isFile())
|
|
53
|
+
throw new Error(`Not a file: ${abs}`);
|
|
54
|
+
const fmt = await detectFormat(abs);
|
|
55
|
+
let toCaption = abs;
|
|
56
|
+
let tempDirToClean = null;
|
|
57
|
+
let convertedFrom = null;
|
|
58
|
+
if (!NATIVE_IMAGE_EXTS.has(fmt)) {
|
|
59
|
+
convertedFrom = fmt;
|
|
60
|
+
const converted = await convertToPng(abs);
|
|
61
|
+
toCaption = converted.path;
|
|
62
|
+
tempDirToClean = converted.tempDir;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const caption = await captionImage(toCaption, args.caption_prompt, {
|
|
66
|
+
model: args.vision_model,
|
|
67
|
+
});
|
|
68
|
+
if (!caption.trim())
|
|
69
|
+
throw new Error("Vision model returned an empty caption.");
|
|
70
|
+
const [vec] = await embed([caption]);
|
|
71
|
+
const fileHash = md5(caption);
|
|
72
|
+
await upsertChunks(projectId, [
|
|
73
|
+
{
|
|
74
|
+
content: caption,
|
|
75
|
+
file_origin: abs,
|
|
76
|
+
chunk_index: 0,
|
|
77
|
+
embedding: vec,
|
|
78
|
+
file_hash: fileHash,
|
|
79
|
+
metadata: {
|
|
80
|
+
type: "image",
|
|
81
|
+
image_path: abs,
|
|
82
|
+
bytes: info.size,
|
|
83
|
+
caption_chars: caption.length,
|
|
84
|
+
source_format: fmt,
|
|
85
|
+
converted_from: convertedFrom,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
]);
|
|
89
|
+
return {
|
|
90
|
+
action: "index_image",
|
|
91
|
+
project_id: projectId,
|
|
92
|
+
image_path: abs,
|
|
93
|
+
source_format: fmt,
|
|
94
|
+
converted_to_png: convertedFrom !== null,
|
|
95
|
+
caption_chars: caption.length,
|
|
96
|
+
caption_preview: caption.slice(0, 300),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
// Total Surgical Wipe — delete the unique mkdtemp directory recursively,
|
|
101
|
+
// which also removes the PNG inside. No orphaned temp artefacts.
|
|
102
|
+
if (tempDirToClean) {
|
|
103
|
+
await rm(tempDirToClean, { recursive: true, force: true }).catch(() => { });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/tools/image.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// MCP tool: list_global_patterns
|
|
2
|
+
//
|
|
3
|
+
// Browse-only enumeration of the reserved 'GLOBAL' Knowledge Vault.
|
|
4
|
+
// Pure SQL — no embedding work, no Ollama call. See ARCHITECTURE.md §4.3.1
|
|
5
|
+
// for the spec and acceptance criteria.
|
|
6
|
+
//
|
|
7
|
+
// Task 5: real SELECT against memory_chunks WHERE project_id='GLOBAL',
|
|
8
|
+
// optional jsonb @> filter via supabase-js `.contains()` (hits the
|
|
9
|
+
// GIN(jsonb_path_ops) index from migration 007), ORDER BY updated_at
|
|
10
|
+
// DESC, id DESC, paginated via inclusive `.range()`.
|
|
11
|
+
//
|
|
12
|
+
// NOTE on the recency column: memory_chunks has NO `created_at` column —
|
|
13
|
+
// `updated_at` is the only recency signal (set on insert via
|
|
14
|
+
// `default now()` and on upsert via the helper). We physically ORDER BY
|
|
15
|
+
// `updated_at` but surface it under the `created_at` response field to
|
|
16
|
+
// keep the public tool contract stable.
|
|
17
|
+
import { z } from "zod";
|
|
18
|
+
import { metadataFilterSchema } from "./shared-schemas.js";
|
|
19
|
+
import { supabase } from "../supabase.js";
|
|
20
|
+
export const listGlobalPatternsInputShape = {
|
|
21
|
+
metadata_filter: metadataFilterSchema,
|
|
22
|
+
limit: z
|
|
23
|
+
.number()
|
|
24
|
+
.int()
|
|
25
|
+
.positive()
|
|
26
|
+
.max(50)
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("Maximum rows to return. Default 10, hard cap 50 (mirrors search_memory)."),
|
|
29
|
+
offset: z
|
|
30
|
+
.number()
|
|
31
|
+
.int()
|
|
32
|
+
.nonnegative()
|
|
33
|
+
.optional()
|
|
34
|
+
.describe("Pagination offset. Default 0."),
|
|
35
|
+
include_content: z
|
|
36
|
+
.boolean()
|
|
37
|
+
.optional()
|
|
38
|
+
.describe("When true, each row includes the full `content` field; otherwise only a content_preview (≤120 chars) is returned. Default false (tiered output)."),
|
|
39
|
+
};
|
|
40
|
+
const MAX_LIMIT = 50;
|
|
41
|
+
const DEFAULT_LIMIT = 10;
|
|
42
|
+
const PREVIEW_CHARS = 120;
|
|
43
|
+
const GLOBAL_PROJECT_ID = "GLOBAL";
|
|
44
|
+
export async function listGlobalPatterns(args) {
|
|
45
|
+
const limit = Math.min(args.limit ?? DEFAULT_LIMIT, MAX_LIMIT);
|
|
46
|
+
const offset = args.offset ?? 0;
|
|
47
|
+
const includeContent = args.include_content ?? false;
|
|
48
|
+
let query = supabase
|
|
49
|
+
.from("memory_chunks")
|
|
50
|
+
.select("id, content, metadata, file_origin, updated_at", {
|
|
51
|
+
count: "exact",
|
|
52
|
+
})
|
|
53
|
+
.eq("project_id", GLOBAL_PROJECT_ID)
|
|
54
|
+
.order("updated_at", { ascending: false })
|
|
55
|
+
.order("id", { ascending: false })
|
|
56
|
+
.range(offset, offset + limit - 1);
|
|
57
|
+
if (args.metadata_filter && Object.keys(args.metadata_filter).length > 0) {
|
|
58
|
+
// @>-style JSONB containment: Supabase JS exposes this via the
|
|
59
|
+
// `contains` operator. Hits the existing GIN(jsonb_path_ops) index on
|
|
60
|
+
// memory_chunks.metadata.
|
|
61
|
+
query = query.contains("metadata", args.metadata_filter);
|
|
62
|
+
}
|
|
63
|
+
const { data, error, count } = await query;
|
|
64
|
+
if (error) {
|
|
65
|
+
throw new Error(`list_global_patterns SELECT failed: ${error.message}`);
|
|
66
|
+
}
|
|
67
|
+
const rows = (data ?? []).map((r) => {
|
|
68
|
+
const metadata = (r.metadata ?? {});
|
|
69
|
+
const content = (r.content ?? "");
|
|
70
|
+
const preview = content.length <= PREVIEW_CHARS
|
|
71
|
+
? content
|
|
72
|
+
: `${content.slice(0, PREVIEW_CHARS)}…`;
|
|
73
|
+
const row = {
|
|
74
|
+
id: r.id,
|
|
75
|
+
type: typeof metadata.type === "string" ? metadata.type : null,
|
|
76
|
+
global_rationale: typeof metadata.global_rationale === "string"
|
|
77
|
+
? metadata.global_rationale
|
|
78
|
+
: null,
|
|
79
|
+
created_at: r.updated_at,
|
|
80
|
+
file_origin: (r.file_origin ?? ""),
|
|
81
|
+
content_preview: preview,
|
|
82
|
+
};
|
|
83
|
+
if (includeContent) {
|
|
84
|
+
row.content = content;
|
|
85
|
+
}
|
|
86
|
+
return row;
|
|
87
|
+
});
|
|
88
|
+
const total = count ?? rows.length;
|
|
89
|
+
const summary = total === 0
|
|
90
|
+
? "GLOBAL vault is empty."
|
|
91
|
+
: `Returned ${rows.length} of ${total} GLOBAL row(s).`;
|
|
92
|
+
return {
|
|
93
|
+
project_id: "GLOBAL",
|
|
94
|
+
count: total,
|
|
95
|
+
results: rows,
|
|
96
|
+
limit,
|
|
97
|
+
offset,
|
|
98
|
+
summary,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=list-global-patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-global-patterns.js","sourceRoot":"","sources":["../../src/tools/list-global-patterns.ts"],"names":[],"mappings":"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"}
|