mneme-ai 2.140.0 → 2.142.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.
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `mneme crucible` (v2.142.0) — the File-level Settlement Gate. Apply an AI's
3
+ * diff in a SHADOW git worktree, build/test it THERE, and only merge to the real
4
+ * tree if the shadow verification PASSES — signed receipt either way. A failing
5
+ * diff never touches your real disk.
6
+ *
7
+ * git diff > change.patch
8
+ * mneme crucible --diff change.patch --verify "npm test" # dry: report only
9
+ * mneme crucible --diff change.patch --verify "npm test" --merge # write real tree on PASS
10
+ *
11
+ * Exit 2 on ROLLBACK/REVIEW (not merged). HONEST: proves YOUR build/test passed
12
+ * in a shadow with the diff applied — not that the code is bug-free; it's a
13
+ * shadow (git worktree), not a security sandbox (pair with the HEPHAESTUS gate).
14
+ */
15
+ import type { Command } from "commander";
16
+ export declare function registerCrucibleCommands(program: Command): void;
17
+ //# sourceMappingURL=crucible.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crucible.d.ts","sourceRoot":"","sources":["../../src/commands/crucible.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAazC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkF/D"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * `mneme crucible` (v2.142.0) — the File-level Settlement Gate. Apply an AI's
3
+ * diff in a SHADOW git worktree, build/test it THERE, and only merge to the real
4
+ * tree if the shadow verification PASSES — signed receipt either way. A failing
5
+ * diff never touches your real disk.
6
+ *
7
+ * git diff > change.patch
8
+ * mneme crucible --diff change.patch --verify "npm test" # dry: report only
9
+ * mneme crucible --diff change.patch --verify "npm test" --merge # write real tree on PASS
10
+ *
11
+ * Exit 2 on ROLLBACK/REVIEW (not merged). HONEST: proves YOUR build/test passed
12
+ * in a shadow with the diff applied — not that the code is bug-free; it's a
13
+ * shadow (git worktree), not a security sandbox (pair with the HEPHAESTUS gate).
14
+ */
15
+ import { existsSync, readFileSync, writeFileSync, mkdtempSync, rmSync } from "node:fs";
16
+ import { join } from "node:path";
17
+ import { tmpdir } from "node:os";
18
+ import { spawnSync } from "node:child_process";
19
+ import { crucible, notary } from "@mneme-ai/core";
20
+ function out(s) { process.stdout.write(s + "\n"); }
21
+ function git(args, cwd) {
22
+ const r = spawnSync("git", args, { cwd, encoding: "utf8", shell: false, maxBuffer: 64 * 1024 * 1024 });
23
+ return { code: r.status ?? 1, out: (r.stdout ?? "") + (r.stderr ?? "") };
24
+ }
25
+ export function registerCrucibleCommands(program) {
26
+ program
27
+ .command("crucible")
28
+ .description("💎 CRUCIBLE — the File-level Settlement Gate. Apply an AI's diff in a SHADOW git worktree (shares .git, no full copy), build/test it THERE, and merge to your real tree ONLY if the shadow verification PASSES — signed receipt either way. A failing diff never touches your real disk. `mneme crucible --diff change.patch --verify \"npm test\" [--merge]`. Exit 2 if not merged. HONEST: proves YOUR build/test passed in a shadow with the diff applied — not bug-free code; it's a shadow (git worktree), not a security sandbox (pair with the command gate).")
29
+ .requiredOption("--diff <file>", "unified diff/patch to settle (use '-' for stdin)")
30
+ .requiredOption("--verify <cmd>", "build/test command to run IN the shadow (e.g. \"npm test\")")
31
+ .option("--merge", "on PASS, apply the diff to the REAL tree (default: report only)")
32
+ .option("--review", "even on PASS, hold for human merge (never auto-write)")
33
+ .option("--json", "JSON output (signed)")
34
+ .action((opts) => {
35
+ const cwd = process.cwd();
36
+ // read diff
37
+ let diffText = "";
38
+ try {
39
+ diffText = opts.diff === "-" ? readFileSync(0, "utf8") : (existsSync(opts.diff) ? readFileSync(opts.diff, "utf8") : "");
40
+ }
41
+ catch { /* */ }
42
+ if (!diffText.trim()) {
43
+ out("✗ empty diff");
44
+ process.exitCode = 2;
45
+ return;
46
+ }
47
+ // is this a git repo?
48
+ if (git(["rev-parse", "--is-inside-work-tree"], cwd).code !== 0) {
49
+ out("✗ not a git repository — CRUCIBLE needs git for the shadow worktree");
50
+ process.exitCode = 2;
51
+ return;
52
+ }
53
+ const plan = crucible.planSettlement(diffText);
54
+ const shadow = mkdtempSync(join(tmpdir(), "mneme-crucible-"));
55
+ const patchFile = join(shadow, "_mneme.patch");
56
+ let verify = { exitCode: 1 };
57
+ let stage = "init";
58
+ try {
59
+ // 1) shadow worktree at current HEAD (detached) — shares .git, cheap
60
+ stage = "worktree-add";
61
+ const wt = git(["worktree", "add", "--detach", shadow, "HEAD"], cwd);
62
+ if (wt.code !== 0) {
63
+ out(`✗ could not create shadow worktree: ${wt.out.slice(0, 200)}`);
64
+ process.exitCode = 2;
65
+ return;
66
+ }
67
+ // 2) apply the diff IN the shadow
68
+ stage = "apply";
69
+ writeFileSync(patchFile, diffText);
70
+ let ap = git(["apply", "--whitespace=nowarn", patchFile], shadow);
71
+ if (ap.code !== 0)
72
+ ap = git(["apply", "--3way", "--whitespace=nowarn", patchFile], shadow);
73
+ if (ap.code !== 0) {
74
+ verify = { exitCode: 1, output: "diff did not apply cleanly in the shadow:\n" + ap.out.slice(0, 400) };
75
+ }
76
+ else {
77
+ // 3) run the verify command IN the shadow
78
+ stage = "verify";
79
+ const t0 = Date.now();
80
+ const r = spawnSync(opts.verify, { cwd: shadow, encoding: "utf8", shell: true, maxBuffer: 64 * 1024 * 1024, timeout: 20 * 60 * 1000 });
81
+ verify = { exitCode: r.status ?? 1, durationMs: Date.now() - t0, output: ((r.stdout ?? "") + "\n" + (r.stderr ?? "")).slice(-4000) };
82
+ }
83
+ }
84
+ finally {
85
+ // 4) ALWAYS remove the shadow worktree (real tree untouched so far)
86
+ try {
87
+ git(["worktree", "remove", "--force", shadow], cwd);
88
+ }
89
+ catch { /* */ }
90
+ try {
91
+ if (existsSync(shadow))
92
+ rmSync(shadow, { recursive: true, force: true });
93
+ }
94
+ catch { /* */ }
95
+ try {
96
+ git(["worktree", "prune"], cwd);
97
+ }
98
+ catch { /* */ }
99
+ }
100
+ const decision = crucible.decideSettlement(verify, { requireHumanMerge: opts.review });
101
+ // 5) write the REAL tree ONLY on MERGE *and* explicit --merge
102
+ let realWritten = false;
103
+ if (decision.verdict === "MERGE" && opts.merge) {
104
+ const realPatch = join(tmpdir(), `mneme-merge-${process.pid}.patch`);
105
+ try {
106
+ writeFileSync(realPatch, diffText);
107
+ let ap = git(["apply", "--whitespace=nowarn", realPatch], cwd);
108
+ if (ap.code !== 0)
109
+ ap = git(["apply", "--3way", "--whitespace=nowarn", realPatch], cwd);
110
+ realWritten = ap.code === 0;
111
+ if (!realWritten)
112
+ decision.reason += " — but applying to the real tree failed (it changed since the shadow); re-run.";
113
+ }
114
+ catch { /* */ }
115
+ finally {
116
+ try {
117
+ rmSync(realPatch, { force: true });
118
+ }
119
+ catch { /* */ }
120
+ }
121
+ }
122
+ const body = { ...crucible.crucibleReceiptBody(diffText, verify, decision), realTreeWritten: realWritten, stage };
123
+ let receipt = null;
124
+ try {
125
+ receipt = notary.issueReceipt(cwd, { kind: "claim-verdict", subject: `crucible:${decision.verdict}`, payload: { verdict: decision.verdict, realTreeWritten: realWritten, exitCode: body.exitCode }, includePayload: true });
126
+ }
127
+ catch { /* */ }
128
+ if (opts.json) {
129
+ out(JSON.stringify({ ...body, decision, signed: receipt }, null, 2));
130
+ process.exitCode = decision.verdict === "MERGE" ? 0 : 2;
131
+ return;
132
+ }
133
+ const icon = decision.verdict === "MERGE" ? "🟢" : decision.verdict === "REVIEW" ? "🟡" : "🛑";
134
+ out(`${icon} CRUCIBLE — ${decision.verdict}`);
135
+ out(` shadow: ${plan.touchedPaths.length} file(s), +${plan.addedLines}/-${plan.removedLines} lines · verify exit ${body.exitCode}${body.durationMs ? ` (${body.durationMs}ms)` : ""}`);
136
+ out(` ${decision.reason}`);
137
+ if (decision.failureBrief)
138
+ out(` ↳ ${decision.failureBrief}`);
139
+ if (decision.verdict === "MERGE")
140
+ out(opts.merge ? (realWritten ? " ✅ merged to the real tree." : " ⚠ merge to real tree did not apply — re-run.") : " (dry-run — pass --merge to write the real tree; real tree untouched.)");
141
+ else
142
+ out(" ✋ real tree untouched.");
143
+ if (receipt)
144
+ out(" ✓ signed (verify offline with the NOTARY public key)");
145
+ process.exitCode = decision.verdict === "MERGE" ? 0 : 2;
146
+ });
147
+ }
148
+ //# sourceMappingURL=crucible.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crucible.js","sourceRoot":"","sources":["../../src/commands/crucible.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * `mneme haunt <file>` (v2.141.0) — "Code Haunting" / Git Telepathy. Surface the
3
+ * ghost of the commit that last touched a region: who changed it, when, the
4
+ * intent they recorded ("temporary fix" / "แก้ขัดไปก่อน"), the safeguards it
5
+ * lacks for the symptom you gave, and the team knowledge already shared about it.
6
+ *
7
+ * mneme haunt src/payment.ts --line 40-92 --symptom "slow under traffic peak"
8
+ * mneme haunt src/auth.ts # whole-file haunting
9
+ * mneme haunt src/payment.ts --json
10
+ *
11
+ * HONEST: surfaces + correlates REAL git facts + recorded intent — a candidate to
12
+ * look at, never a proven cause; UNKNOWN when there is no history.
13
+ */
14
+ import type { Command } from "commander";
15
+ export declare function registerHauntCommands(program: Command): void;
16
+ //# sourceMappingURL=haunt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"haunt.d.ts","sourceRoot":"","sources":["../../src/commands/haunt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuCzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8C5D"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * `mneme haunt <file>` (v2.141.0) — "Code Haunting" / Git Telepathy. Surface the
3
+ * ghost of the commit that last touched a region: who changed it, when, the
4
+ * intent they recorded ("temporary fix" / "แก้ขัดไปก่อน"), the safeguards it
5
+ * lacks for the symptom you gave, and the team knowledge already shared about it.
6
+ *
7
+ * mneme haunt src/payment.ts --line 40-92 --symptom "slow under traffic peak"
8
+ * mneme haunt src/auth.ts # whole-file haunting
9
+ * mneme haunt src/payment.ts --json
10
+ *
11
+ * HONEST: surfaces + correlates REAL git facts + recorded intent — a candidate to
12
+ * look at, never a proven cause; UNKNOWN when there is no history.
13
+ */
14
+ import { existsSync, readFileSync } from "node:fs";
15
+ import { join } from "node:path";
16
+ import { haunt, git, cortex, notary } from "@mneme-ai/core";
17
+ function out(s) { process.stdout.write(s + "\n"); }
18
+ function parseRange(s) {
19
+ if (!s)
20
+ return undefined;
21
+ const m = s.match(/^(\d+)\s*[-:,]\s*(\d+)$/);
22
+ if (m)
23
+ return { start: parseInt(m[1], 10), end: parseInt(m[2], 10) };
24
+ const one = s.match(/^(\d+)$/);
25
+ if (one) {
26
+ const n = parseInt(one[1], 10);
27
+ return { start: n, end: n };
28
+ }
29
+ return undefined;
30
+ }
31
+ function snippet(cwd, file, region) {
32
+ try {
33
+ const p = join(cwd, file);
34
+ if (!existsSync(p))
35
+ return "";
36
+ const lines = readFileSync(p, "utf8").split("\n");
37
+ if (region)
38
+ return lines.slice(Math.max(0, region.start - 1), region.end).join("\n");
39
+ return lines.slice(0, 160).join("\n");
40
+ }
41
+ catch {
42
+ return "";
43
+ }
44
+ }
45
+ /** Best-effort JIT knowledge pull from the Cortex (#2 Knowledge Osmosis). Total. */
46
+ function relatedKnowledge(cwd, file, symptom) {
47
+ try {
48
+ const p = join(cwd, ".mneme", "cortex", "store.json");
49
+ if (!existsSync(p))
50
+ return [];
51
+ const store = JSON.parse(readFileSync(p, "utf8"));
52
+ const base = file.split("/").pop()?.replace(/\.[a-z]+$/i, "") ?? file;
53
+ const query = `${base} ${file} ${symptom ?? ""}`.trim();
54
+ const hits = cortex.recall(store, query, 3) ?? [];
55
+ return hits.map((h) => ({ source: h.entry?.agent, value: h.entry?.value })).filter((k) => typeof k.value === "string" && k.value.length > 0);
56
+ }
57
+ catch {
58
+ return [];
59
+ }
60
+ }
61
+ export function registerHauntCommands(program) {
62
+ program
63
+ .command("haunt")
64
+ .description("👻 CODE HAUNTING (Git Telepathy) — when a region acts up, surface the ghost of the commit that last touched it: who changed it, when, the intent they recorded ('temporary fix' / 'แก้ขัดไปก่อน'), the safeguards it lacks for your symptom, and the team knowledge already shared about it — one plain-language report instead of a manual git-blame dig. Detects intent in EN + TH. HONEST: surfaces + correlates REAL git facts — a candidate to look at, never a proven cause; UNKNOWN when there's no history.")
65
+ .argument("<file>", "the file to investigate (repo-relative)")
66
+ .option("--line <a-b>", "line range to focus on (e.g. 40-92)")
67
+ .option("--symptom <text>", "the symptom from the alert (e.g. \"slow under traffic peak\")")
68
+ .option("--json", "JSON output (signed)")
69
+ .action(async (file, opts) => {
70
+ const cwd = process.cwd();
71
+ const region = parseRange(opts.line);
72
+ let blameLines = [];
73
+ let commits = [];
74
+ try {
75
+ const bl = await git.blame(cwd, file, region?.start, region?.end);
76
+ blameLines = bl.map((b) => ({ commitHash: b.commitHash, authorName: b.authorName, authorTime: b.authorTime, lineNumber: b.lineNumber, content: b.content }));
77
+ }
78
+ catch { /* */ }
79
+ try {
80
+ const cs = await git.readCommits({ cwd, paths: [file], maxCount: 10 });
81
+ commits = cs.map((c) => ({ hash: c.hash, authorName: c.authorName, authorDate: c.authorDate, subject: c.subject, body: c.body }));
82
+ }
83
+ catch { /* */ }
84
+ const report = haunt.buildHauntReport({
85
+ file, region, blame: blameLines, commits,
86
+ codeSnippet: snippet(cwd, file, region),
87
+ symptom: opts.symptom,
88
+ knowledge: relatedKnowledge(cwd, file, opts.symptom),
89
+ nowMs: Date.now(),
90
+ });
91
+ let receipt = null;
92
+ try {
93
+ receipt = notary.issueReceipt(cwd, { kind: "claim-verdict", subject: `haunt:${report.verdict}:${file}`, payload: { verdict: report.verdict, temporaryFix: report.intent.temporaryFix, risks: report.riskFlags.length }, includePayload: true });
94
+ }
95
+ catch { /* */ }
96
+ if (opts.json) {
97
+ out(JSON.stringify({ ...report, signed: receipt }, null, 2));
98
+ process.exitCode = report.verdict === "HAUNTED" ? 2 : 0;
99
+ return;
100
+ }
101
+ const icon = report.verdict === "HAUNTED" ? "👻" : report.verdict === "CLEAR" ? "🟢" : "❔";
102
+ out(`${icon} CODE HAUNTING — ${report.verdict}`);
103
+ out("");
104
+ out(report.narrative);
105
+ if (report.intent.signals.length) {
106
+ out("");
107
+ out("Recorded intent:");
108
+ for (const s of report.intent.signals)
109
+ out(` • [${s.label}] ${s.quote}`);
110
+ }
111
+ if (report.riskFlags.length) {
112
+ out("");
113
+ out("Missing safeguards (lexical signals — look, don't assume):");
114
+ for (const f of report.riskFlags)
115
+ out(` • ${f}`);
116
+ }
117
+ if (report.relatedKnowledge.length) {
118
+ out("");
119
+ out("💡 Team knowledge for this area:");
120
+ for (const k of report.relatedKnowledge)
121
+ out(` • ${k.source ? k.source + ": " : ""}${k.value}`);
122
+ }
123
+ out("");
124
+ out(` ${receipt ? "✓ signed (verify offline with the NOTARY public key) · " : ""}surfaced from real git history — a candidate, not a proven cause.`);
125
+ process.exitCode = report.verdict === "HAUNTED" ? 2 : 0;
126
+ });
127
+ }
128
+ //# sourceMappingURL=haunt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"haunt.js","sourceRoot":"","sources":["../../src/commands/haunt.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAkKA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0hNvD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoKA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA4hNvD"}
package/dist/index.js CHANGED
@@ -94,6 +94,8 @@ import { registerElleipsisCommands } from "./commands/elleipsis.js";
94
94
  import { registerSteleCommands } from "./commands/stele.js";
95
95
  import { registerAxiaCommands } from "./commands/axia.js";
96
96
  import { registerPceCommands } from "./commands/pce.js";
97
+ import { registerHauntCommands } from "./commands/haunt.js";
98
+ import { registerCrucibleCommands } from "./commands/crucible.js";
97
99
  import { attachRegretOracle } from "./commands/regret.js";
98
100
  import { registerTrustCommands } from "./commands/trust.js";
99
101
  import { registerNuclearCommands } from "./commands/nuclear-cli.js";
@@ -4741,6 +4743,8 @@ export async function run(argv) {
4741
4743
  registerSteleCommands(program);
4742
4744
  registerAxiaCommands(program);
4743
4745
  registerPceCommands(program);
4746
+ registerHauntCommands(program);
4747
+ registerCrucibleCommands(program);
4744
4748
  // ─── Trust calibrator (v1.31.0) -- per-subsystem precision/recall/band
4745
4749
  registerTrustCommands(program);
4746
4750
  // ─── Wisdom reactor (v1.33.0) -- five nuclear-physics formulas as Mneme metrics