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,243 @@
|
|
|
1
|
+
// batch_freeze_patterns — hydrate frozen-patterns.json from explicit globs
|
|
2
|
+
// AND/OR a markdown rule-file in a single MCP call. v1.1.3.
|
|
3
|
+
//
|
|
4
|
+
// Each on-disk entry is { pattern, source, added_at }. NO eager glob
|
|
5
|
+
// expansion: patterns are stored as-given. Dedup key is the trimmed,
|
|
6
|
+
// case-sensitive pattern string. First writer wins (an existing entry is
|
|
7
|
+
// skipped, not overwritten). Atomic write is delegated to writeFrozenCache
|
|
8
|
+
// (.tmp + rename).
|
|
9
|
+
import { readFile } from "node:fs/promises";
|
|
10
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
11
|
+
import { addFrozenPattern } from "../supabase.js";
|
|
12
|
+
import { currentProjectId, slugify } from "../project.js";
|
|
13
|
+
import { loadFrozenCache, writeFrozenCache, } from "./frozen-cache.js";
|
|
14
|
+
const DEFAULT_SECTION = "## Frozen Patterns";
|
|
15
|
+
/**
|
|
16
|
+
* Pull pattern strings out of a markdown section. Strict, no NLP:
|
|
17
|
+
* - locate the first line that exactly matches `section` (after rstrip)
|
|
18
|
+
* - read until the next markdown heading (line starting with `#`) or EOF
|
|
19
|
+
* - strip leading list markers (`-`, `*`, `+`, or `1.`/`2.`/...) + space
|
|
20
|
+
* - strip surrounding backticks (single or triple)
|
|
21
|
+
* - reject empty results and lines containing an unescaped space
|
|
22
|
+
*/
|
|
23
|
+
function extractFromMarkdown(body, section) {
|
|
24
|
+
const lines = body.split(/\r?\n/);
|
|
25
|
+
const target = section.trimEnd();
|
|
26
|
+
let i = 0;
|
|
27
|
+
let found = false;
|
|
28
|
+
for (; i < lines.length; i++) {
|
|
29
|
+
if (lines[i].replace(/\s+$/, "") === target) {
|
|
30
|
+
found = true;
|
|
31
|
+
i++;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (!found)
|
|
36
|
+
return { found: false, raw: [], skipped: 0 };
|
|
37
|
+
const raw = [];
|
|
38
|
+
let skipped = 0;
|
|
39
|
+
for (; i < lines.length; i++) {
|
|
40
|
+
const line = lines[i];
|
|
41
|
+
// Stop at the next markdown heading.
|
|
42
|
+
if (/^#/.test(line))
|
|
43
|
+
break;
|
|
44
|
+
const trimmed = line.trim();
|
|
45
|
+
if (!trimmed)
|
|
46
|
+
continue;
|
|
47
|
+
if (trimmed.startsWith("<!--"))
|
|
48
|
+
continue;
|
|
49
|
+
// Strip leading list markers: `-`, `*`, `+`, or numeric `1.` / `2.`.
|
|
50
|
+
let candidate = trimmed.replace(/^([-*+]|\d+\.)\s+/, "");
|
|
51
|
+
// Strip surrounding triple or single backticks.
|
|
52
|
+
candidate = candidate.replace(/^```+|```+$/g, "").replace(/^`+|`+$/g, "");
|
|
53
|
+
candidate = candidate.trim();
|
|
54
|
+
if (!candidate) {
|
|
55
|
+
skipped++;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// Reject obvious non-paths: contains an unescaped space (anything that
|
|
59
|
+
// looks like a sentence, not a glob/path).
|
|
60
|
+
if (/(?<!\\)\s/.test(candidate)) {
|
|
61
|
+
skipped++;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
raw.push(candidate);
|
|
65
|
+
}
|
|
66
|
+
return { found: true, raw, skipped };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Validate one already-extracted pattern. Returns the cleaned string if it
|
|
70
|
+
* passes, or null if it should be skipped. (extractFromMarkdown already
|
|
71
|
+
* applies these checks; this is the same gate for `paths` array entries so
|
|
72
|
+
* inline callers can't bypass them.)
|
|
73
|
+
*/
|
|
74
|
+
function validatePattern(p) {
|
|
75
|
+
const trimmed = p.replace(/^`+|`+$/g, "").trim();
|
|
76
|
+
if (!trimmed)
|
|
77
|
+
return null;
|
|
78
|
+
if (/(?<!\\)\s/.test(trimmed))
|
|
79
|
+
return null;
|
|
80
|
+
return trimmed;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Resolve a workspace-relative path for the `source` field of a rule-file
|
|
84
|
+
* provenance. Falls back to the as-given string if the relative form would
|
|
85
|
+
* escape the workspace (i.e. starts with `..`).
|
|
86
|
+
*/
|
|
87
|
+
function workspaceRelative(filePath) {
|
|
88
|
+
try {
|
|
89
|
+
const abs = isAbsolute(filePath) ? filePath : resolve(filePath);
|
|
90
|
+
const rel = relative(process.cwd(), abs).replace(/\\/g, "/");
|
|
91
|
+
if (rel && !rel.startsWith(".."))
|
|
92
|
+
return rel;
|
|
93
|
+
return filePath.replace(/\\/g, "/");
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return filePath;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export async function batchFreezePatterns(args) {
|
|
100
|
+
const projectId = args.project_id ?? currentProjectId;
|
|
101
|
+
const dryRun = args.dry_run ?? false;
|
|
102
|
+
const section = args.section ?? DEFAULT_SECTION;
|
|
103
|
+
if ((!args.paths || args.paths.length === 0) && !args.from_rule_file) {
|
|
104
|
+
return {
|
|
105
|
+
action: "batch_freeze_patterns",
|
|
106
|
+
project_id: projectId,
|
|
107
|
+
added: 0,
|
|
108
|
+
deduped: 0,
|
|
109
|
+
skipped: 0,
|
|
110
|
+
source: "none",
|
|
111
|
+
dry_run: dryRun,
|
|
112
|
+
error: "At least one of `paths` or `from_rule_file` must be provided.",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const candidates = [];
|
|
116
|
+
let skipped = 0;
|
|
117
|
+
let resolvedSource = "";
|
|
118
|
+
let sectionMissing = false;
|
|
119
|
+
if (args.paths && args.paths.length > 0) {
|
|
120
|
+
const inlineSource = args.source_tag ?? "inline";
|
|
121
|
+
for (const raw of args.paths) {
|
|
122
|
+
const ok = validatePattern(raw);
|
|
123
|
+
if (!ok) {
|
|
124
|
+
skipped++;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
candidates.push({ pattern: ok, source: inlineSource });
|
|
128
|
+
}
|
|
129
|
+
resolvedSource = inlineSource;
|
|
130
|
+
}
|
|
131
|
+
if (args.from_rule_file) {
|
|
132
|
+
const rulePath = args.from_rule_file;
|
|
133
|
+
const ruleSource = args.source_tag ?? workspaceRelative(rulePath);
|
|
134
|
+
let body;
|
|
135
|
+
try {
|
|
136
|
+
body = await readFile(rulePath, "utf8");
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
return {
|
|
140
|
+
action: "batch_freeze_patterns",
|
|
141
|
+
project_id: projectId,
|
|
142
|
+
added: 0,
|
|
143
|
+
deduped: 0,
|
|
144
|
+
skipped: 0,
|
|
145
|
+
source: ruleSource,
|
|
146
|
+
dry_run: dryRun,
|
|
147
|
+
error: `Failed to read rule file: ${e.message}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
const ext = extractFromMarkdown(body, section);
|
|
151
|
+
if (!ext.found) {
|
|
152
|
+
sectionMissing = true;
|
|
153
|
+
resolvedSource = ruleSource;
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
for (const pat of ext.raw) {
|
|
157
|
+
candidates.push({ pattern: pat, source: ruleSource });
|
|
158
|
+
}
|
|
159
|
+
skipped += ext.skipped;
|
|
160
|
+
// Rule file source label trumps inline if both supplied (more
|
|
161
|
+
// descriptive). Inline source is still attached per-candidate above.
|
|
162
|
+
resolvedSource = ruleSource;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (sectionMissing && candidates.length === 0) {
|
|
166
|
+
return {
|
|
167
|
+
action: "batch_freeze_patterns",
|
|
168
|
+
project_id: projectId,
|
|
169
|
+
added: 0,
|
|
170
|
+
deduped: 0,
|
|
171
|
+
skipped: 0,
|
|
172
|
+
source: resolvedSource,
|
|
173
|
+
dry_run: dryRun,
|
|
174
|
+
error: "section not found",
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
// Compute the prospective new cache.
|
|
178
|
+
const cache = await loadFrozenCache();
|
|
179
|
+
const key = slugify(projectId);
|
|
180
|
+
const bucket = (cache.projects[key] ??= []);
|
|
181
|
+
const existingPatterns = new Set(bucket.map((e) => e.pattern));
|
|
182
|
+
let added = 0;
|
|
183
|
+
let deduped = 0;
|
|
184
|
+
const newPatterns = [];
|
|
185
|
+
const newEntries = [];
|
|
186
|
+
const now = Date.now();
|
|
187
|
+
// Track patterns staged in *this* batch so the second occurrence in the
|
|
188
|
+
// same call counts as a dedup, not a second add.
|
|
189
|
+
const batchSeen = new Set();
|
|
190
|
+
for (const c of candidates) {
|
|
191
|
+
if (existingPatterns.has(c.pattern) || batchSeen.has(c.pattern)) {
|
|
192
|
+
deduped++;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
batchSeen.add(c.pattern);
|
|
196
|
+
const entry = {
|
|
197
|
+
pattern: c.pattern,
|
|
198
|
+
source: c.source,
|
|
199
|
+
added_at: now,
|
|
200
|
+
};
|
|
201
|
+
newEntries.push(entry);
|
|
202
|
+
newPatterns.push(c.pattern);
|
|
203
|
+
added++;
|
|
204
|
+
}
|
|
205
|
+
if (dryRun) {
|
|
206
|
+
return {
|
|
207
|
+
action: "batch_freeze_patterns",
|
|
208
|
+
project_id: projectId,
|
|
209
|
+
added,
|
|
210
|
+
deduped,
|
|
211
|
+
skipped,
|
|
212
|
+
source: resolvedSource || "none",
|
|
213
|
+
dry_run: true,
|
|
214
|
+
patterns: newPatterns,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
// Persist: append new entries to the cache, atomic-write, and mirror to
|
|
218
|
+
// Supabase so the existing freeze_file/unfreeze_file flow stays consistent.
|
|
219
|
+
if (newEntries.length > 0) {
|
|
220
|
+
bucket.push(...newEntries);
|
|
221
|
+
await writeFrozenCache(cache);
|
|
222
|
+
for (const e of newEntries) {
|
|
223
|
+
try {
|
|
224
|
+
await addFrozenPattern(projectId, e.pattern, `batch_freeze_patterns: ${e.source}`);
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// Supabase mirror is best-effort. Cache (read by the hook) is
|
|
228
|
+
// authoritative for blocking; if the network is down the freeze
|
|
229
|
+
// still takes effect on disk.
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
action: "batch_freeze_patterns",
|
|
235
|
+
project_id: projectId,
|
|
236
|
+
added,
|
|
237
|
+
deduped,
|
|
238
|
+
skipped,
|
|
239
|
+
source: resolvedSource || "none",
|
|
240
|
+
dry_run: false,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=batch-freeze-patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-freeze-patterns.js","sourceRoot":"","sources":["../../src/tools/batch-freeze-patterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as os from "os";
|
|
4
|
+
export const BLOAT_THRESHOLD = 10000;
|
|
5
|
+
export function estimateTokens(text) {
|
|
6
|
+
if (!text)
|
|
7
|
+
return 0;
|
|
8
|
+
return Math.ceil(text.length / 4);
|
|
9
|
+
}
|
|
10
|
+
async function fileExists(p) {
|
|
11
|
+
try {
|
|
12
|
+
await fs.access(p);
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async function readSafe(p) {
|
|
20
|
+
try {
|
|
21
|
+
return await fs.readFile(p, "utf-8");
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return "";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function resolveHiddenMemory(workspaceAbs) {
|
|
28
|
+
try {
|
|
29
|
+
const home = os.homedir();
|
|
30
|
+
const isWin = process.platform === "win32";
|
|
31
|
+
let encoded = workspaceAbs.replace(/[:\\/ ]/g, "-");
|
|
32
|
+
if (isWin)
|
|
33
|
+
encoded = encoded.toLowerCase();
|
|
34
|
+
const primary = path.join(home, ".claude", "projects", encoded, "memory", "MEMORY.md");
|
|
35
|
+
if (await fileExists(primary))
|
|
36
|
+
return primary;
|
|
37
|
+
// Fallback scan
|
|
38
|
+
const projectsDir = path.join(home, ".claude", "projects");
|
|
39
|
+
const basename = path.basename(workspaceAbs).toLowerCase();
|
|
40
|
+
try {
|
|
41
|
+
const entries = await fs.readdir(projectsDir, { withFileTypes: true });
|
|
42
|
+
for (const e of entries) {
|
|
43
|
+
if (!e.isDirectory())
|
|
44
|
+
continue;
|
|
45
|
+
if (!e.name.toLowerCase().includes(basename))
|
|
46
|
+
continue;
|
|
47
|
+
const cand = path.join(projectsDir, e.name, "memory", "MEMORY.md");
|
|
48
|
+
if (await fileExists(cand))
|
|
49
|
+
return cand;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
/* ignore */
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export async function auditBloat(workspace) {
|
|
62
|
+
const claudeMdPath = path.join(workspace, "CLAUDE.md");
|
|
63
|
+
const claudeMd = await readSafe(claudeMdPath);
|
|
64
|
+
const claudeMdTokens = estimateTokens(claudeMd);
|
|
65
|
+
const claudeMdBloated = claudeMdTokens > BLOAT_THRESHOLD;
|
|
66
|
+
const hiddenMemoryPath = await resolveHiddenMemory(workspace);
|
|
67
|
+
const hiddenMemory = hiddenMemoryPath ? await readSafe(hiddenMemoryPath) : "";
|
|
68
|
+
const hiddenMemoryTokens = estimateTokens(hiddenMemory);
|
|
69
|
+
const hiddenMemoryBloated = hiddenMemoryTokens > BLOAT_THRESHOLD;
|
|
70
|
+
const bloat_audit = {
|
|
71
|
+
threshold: BLOAT_THRESHOLD,
|
|
72
|
+
claude_md: { path: claudeMdPath, tokens: claudeMdTokens, bloated: claudeMdBloated },
|
|
73
|
+
hidden_memory: {
|
|
74
|
+
path: hiddenMemoryPath,
|
|
75
|
+
tokens: hiddenMemoryTokens,
|
|
76
|
+
bloated: hiddenMemoryBloated,
|
|
77
|
+
found: hiddenMemoryPath !== null,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
const anyBloated = claudeMdBloated || hiddenMemoryBloated;
|
|
81
|
+
if (!anyBloated)
|
|
82
|
+
return { bloat_audit, sovereign_purge_recommendation: null };
|
|
83
|
+
const recommendation = {
|
|
84
|
+
id: "sovereign_purge",
|
|
85
|
+
description: `Bloat detected (CLAUDE.md=${claudeMdTokens} tokens, hidden MEMORY.md=${hiddenMemoryTokens} tokens; threshold=${BLOAT_THRESHOLD}). Auto-purge will safely migrate legacy content to Supabase vectors and reset files to the clean DNA v2.1 baseline.`,
|
|
86
|
+
bloat_audit,
|
|
87
|
+
agent_protocol: "ASK_USER_THEN_EXECUTE",
|
|
88
|
+
steps: [
|
|
89
|
+
"Ask the user for explicit YES/NO permission before doing anything.",
|
|
90
|
+
"On YES: (a) mkdir -p docs/scm-memory/ (b) move CLAUDE.md -> docs/scm-memory/legacy_claude.md (c) if hidden MEMORY.md exists, copy it to docs/scm-memory/legacy_memory.md (d) call sync_local_memory({ force: true }) so the legacy files are vectorized into Supabase (e) call ensureSovereignConstitution({ force: true }) to regenerate a fresh v2.1 CLAUDE.md (f) report a 2-line synthesis to the user.",
|
|
91
|
+
"On NO: do nothing this session; the recommendation will resurface next init_project.",
|
|
92
|
+
],
|
|
93
|
+
legacy_targets: {
|
|
94
|
+
claude_md: claudeMdPath,
|
|
95
|
+
hidden_memory: hiddenMemoryPath,
|
|
96
|
+
},
|
|
97
|
+
destination: path.join(workspace, "docs", "scm-memory"),
|
|
98
|
+
};
|
|
99
|
+
return { bloat_audit, sovereign_purge_recommendation: recommendation };
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=bloat-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bloat-audit.js","sourceRoot":"","sources":["../../src/tools/bloat-audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// MCP tool wrappers for Transactional Workflow Checkpoints
|
|
2
|
+
// (Agentic OS 2026 / Mission 4 / Phase B).
|
|
3
|
+
//
|
|
4
|
+
// Four handlers that wrap the pure service layer in
|
|
5
|
+
// src/transactions/checkpoint.ts and add the MCP-shaped envelope:
|
|
6
|
+
//
|
|
7
|
+
// * checkpoint_create — openCheckpoint() + cloud_backlog.metadata stamp
|
|
8
|
+
// when this is a root checkpoint tied to a backlog
|
|
9
|
+
// task. The stamp populates
|
|
10
|
+
// cloud_backlog.metadata.checkpoint_root_id, which
|
|
11
|
+
// archive_done_backlog (014) joins on to populate
|
|
12
|
+
// archive_backlog.chunk_id at archive time.
|
|
13
|
+
// * checkpoint_commit — commitCheckpoint()
|
|
14
|
+
// * checkpoint_rollback — rollbackCheckpoint() + structured [M4] rollback
|
|
15
|
+
// signal log. No separate signals table — the
|
|
16
|
+
// miner's LEFT JOIN over workflow_checkpoints
|
|
17
|
+
// picks rolledback rows directly.
|
|
18
|
+
// * checkpoint_list — listCheckpoints() with safe limit bounds.
|
|
19
|
+
//
|
|
20
|
+
// Style mirrors src/tools/compact.ts (handler + input shape exports) and
|
|
21
|
+
// src/tools/sleep.ts (project_id resolution via currentProjectId default).
|
|
22
|
+
// Zero `any`, zero TODO, zero placeholders.
|
|
23
|
+
import { z } from "zod";
|
|
24
|
+
import { supabase } from "../supabase.js";
|
|
25
|
+
import { currentProjectId } from "../project.js";
|
|
26
|
+
import { openCheckpoint, commitCheckpoint, rollbackCheckpoint, listCheckpoints, } from "../transactions/checkpoint.js";
|
|
27
|
+
// ─── shared project_id helper ───────────────────────────────────────────────
|
|
28
|
+
function resolveProjectId(explicit) {
|
|
29
|
+
if (typeof explicit === "string" && explicit.trim().length > 0) {
|
|
30
|
+
return explicit;
|
|
31
|
+
}
|
|
32
|
+
return currentProjectId;
|
|
33
|
+
}
|
|
34
|
+
// ─── checkpoint_create ──────────────────────────────────────────────────────
|
|
35
|
+
export const checkpointCreateInputShape = {
|
|
36
|
+
project_id: z
|
|
37
|
+
.string()
|
|
38
|
+
.optional()
|
|
39
|
+
.describe(`Project namespace. Defaults to the slugified current working directory ('${currentProjectId}').`),
|
|
40
|
+
skill_id: z
|
|
41
|
+
.number()
|
|
42
|
+
.int()
|
|
43
|
+
.positive()
|
|
44
|
+
.nullable()
|
|
45
|
+
.optional()
|
|
46
|
+
.describe("agent_skills.id when this checkpoint is anchoring a step of a JIT-retrieved skill. NULL when the workflow is ad-hoc."),
|
|
47
|
+
step_index: z
|
|
48
|
+
.number()
|
|
49
|
+
.int()
|
|
50
|
+
.nonnegative()
|
|
51
|
+
.optional()
|
|
52
|
+
.default(0)
|
|
53
|
+
.describe("Zero-based ordinal of this step within the workflow. Default 0 (root step)."),
|
|
54
|
+
step_label: z
|
|
55
|
+
.string()
|
|
56
|
+
.min(1)
|
|
57
|
+
.describe("Short human-readable label for the step (e.g. 'edit-and-typecheck', 'run-migration'). Required."),
|
|
58
|
+
parent_id: z
|
|
59
|
+
.number()
|
|
60
|
+
.int()
|
|
61
|
+
.positive()
|
|
62
|
+
.nullable()
|
|
63
|
+
.optional()
|
|
64
|
+
.describe("workflow_checkpoints.id of the prior step in the chain. NULL = root step of the workflow."),
|
|
65
|
+
backlog_task_id: z
|
|
66
|
+
.number()
|
|
67
|
+
.int()
|
|
68
|
+
.positive()
|
|
69
|
+
.optional()
|
|
70
|
+
.describe("cloud_backlog.id this workflow services. When provided AND parent_id is null, this checkpoint becomes the root and its id is stamped into cloud_backlog.metadata.checkpoint_root_id so archive_done_backlog can populate archive_backlog.chunk_id at archive time."),
|
|
71
|
+
};
|
|
72
|
+
const checkpointCreateSchema = z.object(checkpointCreateInputShape);
|
|
73
|
+
/**
|
|
74
|
+
* Stamp metadata.checkpoint_root_id onto a cloud_backlog row via a
|
|
75
|
+
* read-modify-write. We avoid jsonb_set RPC plumbing (would require a new
|
|
76
|
+
* SECURITY DEFINER fn) — the row count is always 1 here, so the round-trip
|
|
77
|
+
* cost is negligible and the code stays portable.
|
|
78
|
+
*
|
|
79
|
+
* Returns true if the row was stamped, false if the row was not found or
|
|
80
|
+
* the project_id didn't match (defensive guard against cross-tenant
|
|
81
|
+
* stamping).
|
|
82
|
+
*/
|
|
83
|
+
async function stampCheckpointRootIdOnBacklog(projectId, backlogTaskId, checkpointId) {
|
|
84
|
+
const { data: row, error: loadErr } = await supabase
|
|
85
|
+
.from("cloud_backlog")
|
|
86
|
+
.select("id, project_id, metadata")
|
|
87
|
+
.eq("id", backlogTaskId)
|
|
88
|
+
.eq("project_id", projectId)
|
|
89
|
+
.maybeSingle();
|
|
90
|
+
if (loadErr) {
|
|
91
|
+
throw new Error(`[M4] stampCheckpointRootIdOnBacklog: lookup failed: ${loadErr.message}`);
|
|
92
|
+
}
|
|
93
|
+
if (!row) {
|
|
94
|
+
// No matching row — log and report not-stamped; this is not a hard error
|
|
95
|
+
// (caller may have passed a stale id; we don't want to fail the
|
|
96
|
+
// checkpoint that was already inserted).
|
|
97
|
+
console.log(`[M4] stamp skipped: cloud_backlog id=${backlogTaskId} not found in project=${projectId}`);
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
const existing = row.metadata && typeof row.metadata === "object" && !Array.isArray(row.metadata)
|
|
101
|
+
? row.metadata
|
|
102
|
+
: {};
|
|
103
|
+
const nextMetadata = {
|
|
104
|
+
...existing,
|
|
105
|
+
checkpoint_root_id: checkpointId,
|
|
106
|
+
};
|
|
107
|
+
const { error: updateErr } = await supabase
|
|
108
|
+
.from("cloud_backlog")
|
|
109
|
+
.update({ metadata: nextMetadata })
|
|
110
|
+
.eq("id", backlogTaskId)
|
|
111
|
+
.eq("project_id", projectId);
|
|
112
|
+
if (updateErr) {
|
|
113
|
+
throw new Error(`[M4] stampCheckpointRootIdOnBacklog: update failed: ${updateErr.message}`);
|
|
114
|
+
}
|
|
115
|
+
console.log(`[M4] stamped checkpoint_root_id=${checkpointId} on cloud_backlog.id=${backlogTaskId}`);
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
export async function checkpointCreateHandler(args) {
|
|
119
|
+
const parsed = checkpointCreateSchema.parse(args);
|
|
120
|
+
const projectId = resolveProjectId(parsed.project_id);
|
|
121
|
+
const skillId = parsed.skill_id === undefined || parsed.skill_id === null ? null : parsed.skill_id;
|
|
122
|
+
const parentId = parsed.parent_id === undefined || parsed.parent_id === null ? null : parsed.parent_id;
|
|
123
|
+
const stepIndex = parsed.step_index ?? 0;
|
|
124
|
+
const opened = await openCheckpoint({
|
|
125
|
+
projectId,
|
|
126
|
+
skillId,
|
|
127
|
+
stepIndex,
|
|
128
|
+
stepLabel: parsed.step_label,
|
|
129
|
+
parentId,
|
|
130
|
+
});
|
|
131
|
+
let backlogStamped = false;
|
|
132
|
+
// Stamp only when this is a ROOT checkpoint (parentId is null) AND a
|
|
133
|
+
// backlog task id was supplied. Non-root checkpoints inherit their root
|
|
134
|
+
// via the parent_id chain; restamping a non-root would break the join.
|
|
135
|
+
if (parentId === null && parsed.backlog_task_id !== undefined) {
|
|
136
|
+
backlogStamped = await stampCheckpointRootIdOnBacklog(projectId, parsed.backlog_task_id, opened.id);
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
checkpoint_id: opened.id,
|
|
140
|
+
status: "open",
|
|
141
|
+
backlog_stamped: backlogStamped,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// ─── checkpoint_commit ──────────────────────────────────────────────────────
|
|
145
|
+
export const checkpointCommitInputShape = {
|
|
146
|
+
project_id: z
|
|
147
|
+
.string()
|
|
148
|
+
.optional()
|
|
149
|
+
.describe(`Project namespace. Defaults to the slugified current working directory ('${currentProjectId}').`),
|
|
150
|
+
checkpoint_id: z
|
|
151
|
+
.number()
|
|
152
|
+
.int()
|
|
153
|
+
.positive()
|
|
154
|
+
.describe("workflow_checkpoints.id to mark committed."),
|
|
155
|
+
source_chunk_id: z
|
|
156
|
+
.number()
|
|
157
|
+
.int()
|
|
158
|
+
.positive()
|
|
159
|
+
.describe("memory_chunks.id whose trajectory_summaries entry is the replay anchor. Required — committed rows MUST pin a chunk."),
|
|
160
|
+
};
|
|
161
|
+
const checkpointCommitSchema = z.object(checkpointCommitInputShape);
|
|
162
|
+
export async function checkpointCommitHandler(args) {
|
|
163
|
+
const parsed = checkpointCommitSchema.parse(args);
|
|
164
|
+
const projectId = resolveProjectId(parsed.project_id);
|
|
165
|
+
const committed = await commitCheckpoint({
|
|
166
|
+
projectId,
|
|
167
|
+
checkpointId: parsed.checkpoint_id,
|
|
168
|
+
sourceChunkId: parsed.source_chunk_id,
|
|
169
|
+
});
|
|
170
|
+
return {
|
|
171
|
+
checkpoint_id: committed.id,
|
|
172
|
+
status: "committed",
|
|
173
|
+
source_chunk_id: committed.sourceChunkId,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
// ─── checkpoint_rollback ────────────────────────────────────────────────────
|
|
177
|
+
export const checkpointRollbackInputShape = {
|
|
178
|
+
project_id: z
|
|
179
|
+
.string()
|
|
180
|
+
.optional()
|
|
181
|
+
.describe(`Project namespace. Defaults to the slugified current working directory ('${currentProjectId}').`),
|
|
182
|
+
checkpoint_id: z
|
|
183
|
+
.number()
|
|
184
|
+
.int()
|
|
185
|
+
.positive()
|
|
186
|
+
.describe("workflow_checkpoints.id to mark rolledback."),
|
|
187
|
+
reason: z
|
|
188
|
+
.string()
|
|
189
|
+
.min(1)
|
|
190
|
+
.describe("Non-empty human-readable reason persisted to workflow_checkpoints.rollback_reason and surfaced to the M3 miner as a negative signal."),
|
|
191
|
+
};
|
|
192
|
+
const checkpointRollbackSchema = z.object(checkpointRollbackInputShape);
|
|
193
|
+
export async function checkpointRollbackHandler(args) {
|
|
194
|
+
const parsed = checkpointRollbackSchema.parse(args);
|
|
195
|
+
const projectId = resolveProjectId(parsed.project_id);
|
|
196
|
+
const r = await rollbackCheckpoint({
|
|
197
|
+
projectId,
|
|
198
|
+
checkpointId: parsed.checkpoint_id,
|
|
199
|
+
reason: parsed.reason,
|
|
200
|
+
});
|
|
201
|
+
// M3 signal: emit a structured log line. The miner reads
|
|
202
|
+
// workflow_checkpoints directly (no separate signals table); this log is
|
|
203
|
+
// purely operational visibility so a human can grep rollback churn.
|
|
204
|
+
const anchor = r.restoredFrom
|
|
205
|
+
? `parent=${r.restoredFrom.checkpointId} source_chunk_id=${r.restoredFrom.sourceChunkId}`
|
|
206
|
+
: "no_replay_anchor";
|
|
207
|
+
console.log(`[M4] rollback_signal: project=${projectId} id=${r.id} reason=${parsed.reason} ${anchor}`);
|
|
208
|
+
return {
|
|
209
|
+
checkpoint_id: r.id,
|
|
210
|
+
status: "rolledback",
|
|
211
|
+
restored_from: r.restoredFrom
|
|
212
|
+
? {
|
|
213
|
+
checkpoint_id: r.restoredFrom.checkpointId,
|
|
214
|
+
source_chunk_id: r.restoredFrom.sourceChunkId,
|
|
215
|
+
}
|
|
216
|
+
: null,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
// ─── checkpoint_list ────────────────────────────────────────────────────────
|
|
220
|
+
export const checkpointListInputShape = {
|
|
221
|
+
project_id: z
|
|
222
|
+
.string()
|
|
223
|
+
.optional()
|
|
224
|
+
.describe(`Project namespace. Defaults to the slugified current working directory ('${currentProjectId}').`),
|
|
225
|
+
status: z
|
|
226
|
+
.enum(["open", "committed", "rolledback"])
|
|
227
|
+
.optional()
|
|
228
|
+
.describe("Lifecycle filter. Omit to surface all states."),
|
|
229
|
+
skill_id: z
|
|
230
|
+
.number()
|
|
231
|
+
.int()
|
|
232
|
+
.positive()
|
|
233
|
+
.optional()
|
|
234
|
+
.describe("Filter by agent_skills.id. Omit to surface checkpoints regardless of skill linkage."),
|
|
235
|
+
limit: z
|
|
236
|
+
.number()
|
|
237
|
+
.int()
|
|
238
|
+
.positive()
|
|
239
|
+
.max(100)
|
|
240
|
+
.optional()
|
|
241
|
+
.default(20)
|
|
242
|
+
.describe("Hard cap on rows returned. Default 20, max 100."),
|
|
243
|
+
};
|
|
244
|
+
const checkpointListSchema = z.object(checkpointListInputShape);
|
|
245
|
+
export async function checkpointListHandler(args) {
|
|
246
|
+
const parsed = checkpointListSchema.parse(args);
|
|
247
|
+
const projectId = resolveProjectId(parsed.project_id);
|
|
248
|
+
const limit = parsed.limit ?? 20;
|
|
249
|
+
const status = parsed.status;
|
|
250
|
+
const skillId = parsed.skill_id === undefined || parsed.skill_id === null ? undefined : parsed.skill_id;
|
|
251
|
+
const rows = await listCheckpoints({
|
|
252
|
+
projectId,
|
|
253
|
+
status,
|
|
254
|
+
skillId,
|
|
255
|
+
limit,
|
|
256
|
+
});
|
|
257
|
+
return { count: rows.length, checkpoints: rows };
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=checkpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/tools/checkpoint.ts"],"names":[],"mappings":"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"}
|