mneme-ai 0.28.0 → 0.32.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/commands/adversarial.d.ts +14 -0
  2. package/dist/commands/adversarial.d.ts.map +1 -0
  3. package/dist/commands/adversarial.js +273 -0
  4. package/dist/commands/adversarial.js.map +1 -0
  5. package/dist/commands/black-sheep.smoke.test.d.ts +10 -0
  6. package/dist/commands/black-sheep.smoke.test.d.ts.map +1 -0
  7. package/dist/commands/black-sheep.smoke.test.js +186 -0
  8. package/dist/commands/black-sheep.smoke.test.js.map +1 -0
  9. package/dist/commands/bot.d.ts +47 -0
  10. package/dist/commands/bot.d.ts.map +1 -0
  11. package/dist/commands/bot.js +242 -0
  12. package/dist/commands/bot.js.map +1 -0
  13. package/dist/commands/bot.smoke.test.d.ts +2 -0
  14. package/dist/commands/bot.smoke.test.d.ts.map +1 -0
  15. package/dist/commands/bot.smoke.test.js +28 -0
  16. package/dist/commands/bot.smoke.test.js.map +1 -0
  17. package/dist/commands/bot.test.d.ts +2 -0
  18. package/dist/commands/bot.test.d.ts.map +1 -0
  19. package/dist/commands/bot.test.js +277 -0
  20. package/dist/commands/bot.test.js.map +1 -0
  21. package/dist/commands/completion.d.ts +65 -0
  22. package/dist/commands/completion.d.ts.map +1 -0
  23. package/dist/commands/completion.js +385 -0
  24. package/dist/commands/completion.js.map +1 -0
  25. package/dist/commands/completion.smoke.test.d.ts +2 -0
  26. package/dist/commands/completion.smoke.test.d.ts.map +1 -0
  27. package/dist/commands/completion.smoke.test.js +112 -0
  28. package/dist/commands/completion.smoke.test.js.map +1 -0
  29. package/dist/commands/completion.test.d.ts +2 -0
  30. package/dist/commands/completion.test.d.ts.map +1 -0
  31. package/dist/commands/completion.test.js +196 -0
  32. package/dist/commands/completion.test.js.map +1 -0
  33. package/dist/commands/counterfactual.d.ts +10 -0
  34. package/dist/commands/counterfactual.d.ts.map +1 -0
  35. package/dist/commands/counterfactual.js +191 -0
  36. package/dist/commands/counterfactual.js.map +1 -0
  37. package/dist/commands/dashboard.d.ts +37 -0
  38. package/dist/commands/dashboard.d.ts.map +1 -0
  39. package/dist/commands/dashboard.js +230 -0
  40. package/dist/commands/dashboard.js.map +1 -0
  41. package/dist/commands/dashboard.test.d.ts +2 -0
  42. package/dist/commands/dashboard.test.d.ts.map +1 -0
  43. package/dist/commands/dashboard.test.js +135 -0
  44. package/dist/commands/dashboard.test.js.map +1 -0
  45. package/dist/commands/influence.js +1 -0
  46. package/dist/commands/influence.js.map +1 -1
  47. package/dist/commands/org.d.ts +30 -0
  48. package/dist/commands/org.d.ts.map +1 -0
  49. package/dist/commands/org.js +349 -0
  50. package/dist/commands/org.js.map +1 -0
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +173 -1
  53. package/dist/index.js.map +1 -1
  54. package/package.json +5 -5
@@ -0,0 +1,14 @@
1
+ export interface AdversarialOptions {
2
+ cwd: string;
3
+ /** Number of probes (rounded down to multiple of 3). */
4
+ probes?: number;
5
+ /** Output markdown path; defaults to .mneme/adversarial-probes.md */
6
+ out?: string;
7
+ /** Path to a JSON responses file; switches to grading mode. */
8
+ grade?: string;
9
+ /** Deterministic seed. */
10
+ seed?: string;
11
+ json?: boolean;
12
+ }
13
+ export declare function adversarialCommand(opts: AdversarialOptions): Promise<number>;
14
+ //# sourceMappingURL=adversarial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adversarial.d.ts","sourceRoot":"","sources":["../../src/commands/adversarial.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAKD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlF"}
@@ -0,0 +1,273 @@
1
+ /**
2
+ * `mneme adversarial` — meta-evaluation of AI clients against repo memory.
3
+ *
4
+ * Two modes:
5
+ * default Generate a markdown probe bundle (paste into your AI client).
6
+ * --grade <file> Score a JSON responses file against the previously-generated bundle.
7
+ *
8
+ * --json shape (stable):
9
+ * When generating: { generatedAt, repo, probes, answerKey, outPath, answerKeyPath }
10
+ * When grading: { trustScore, totalProbes, correctProbes, perVariant, missed, summary }
11
+ */
12
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
13
+ import { dirname, join } from "node:path";
14
+ import kleur from "kleur";
15
+ import { git, store as storeNs, adversarial } from "@mneme-ai/core";
16
+ const { generateProbes, gradeResponses, renderProbeMarkdown, serializeAnswerKey, deserializeAnswerKey, } = adversarial;
17
+ import { dbPath, mnemeDir } from "../paths.js";
18
+ import { ui, pill } from "../ui.js";
19
+ import { iris } from "../iris/index.js";
20
+ const DEFAULT_OUT = "adversarial-probes.md";
21
+ const ANSWER_KEY_NAME = "adversarial-answer-key.json";
22
+ export async function adversarialCommand(opts) {
23
+ if (!(await git.isGitRepo(opts.cwd))) {
24
+ ui.error("Not in a git repo. Run `mneme init` first.");
25
+ return 1;
26
+ }
27
+ const meta = await git.getRepoMeta(opts.cwd);
28
+ if (opts.grade) {
29
+ return runGrade(opts, meta.rootPath);
30
+ }
31
+ return runGenerate(opts, meta.rootPath);
32
+ }
33
+ // ─── generate ──────────────────────────────────────────────────────────
34
+ function runGenerate(opts, repoRoot) {
35
+ const s = new storeNs.MnemeStore(dbPath(repoRoot));
36
+ let bundle;
37
+ try {
38
+ bundle = generateProbes(s, {
39
+ probes: opts.probes ?? 12,
40
+ seed: opts.seed,
41
+ repoName: deriveRepoName(repoRoot),
42
+ });
43
+ }
44
+ finally {
45
+ s.close();
46
+ }
47
+ const outPath = opts.out ?? join(mnemeDir(repoRoot), DEFAULT_OUT);
48
+ const answerKeyPath = join(mnemeDir(repoRoot), ANSWER_KEY_NAME);
49
+ if (bundle.probes.length === 0) {
50
+ if (opts.json) {
51
+ process.stdout.write(JSON.stringify({ generatedAt: bundle.generatedAt, probes: [], outPath: null }, null, 2) +
52
+ "\n");
53
+ return 0;
54
+ }
55
+ ui.banner();
56
+ process.stdout.write(iris.render({
57
+ headline: "🐑 Adversarial probes — no HTC abstracts available",
58
+ sections: [
59
+ {
60
+ tier: "lede",
61
+ lines: [
62
+ ` ${pill("HEADS UP", "warn")} ${kleur.gray("the HTC index has no abstracts yet. Probes need ~30-token summaries to mutate.")}`,
63
+ ],
64
+ },
65
+ {
66
+ tier: "sources",
67
+ title: "→ Try next",
68
+ lines: [
69
+ ` ${kleur.cyan("$")} ${kleur.bold("mneme htc-build")} ${kleur.gray("(generate Layer-1 abstracts first; takes a few minutes)")}`,
70
+ ` ${kleur.cyan("$")} ${kleur.bold("mneme adversarial")} ${kleur.gray("(re-run after htc-build completes)")}`,
71
+ ],
72
+ },
73
+ ],
74
+ }) + "\n");
75
+ return 0;
76
+ }
77
+ const md = renderProbeMarkdown(bundle);
78
+ writeWithMkdir(outPath, md);
79
+ writeWithMkdir(answerKeyPath, serializeAnswerKey(bundle));
80
+ if (opts.json) {
81
+ process.stdout.write(JSON.stringify({
82
+ generatedAt: bundle.generatedAt,
83
+ repo: bundle.repo,
84
+ probes: bundle.probes,
85
+ answerKey: bundle.answerKey,
86
+ outPath,
87
+ answerKeyPath,
88
+ }, null, 2) + "\n");
89
+ return 0;
90
+ }
91
+ // Iris terminal output.
92
+ const variantCounts = { truth: 0, "subtle-lie": 0, "wholesale-lie": 0 };
93
+ for (const v of Object.values(bundle.answerKey))
94
+ variantCounts[v]++;
95
+ const headline = `🐑 Adversarial probes generated — ${bundle.probes.length} questions in ${shortPath(outPath, repoRoot)}`;
96
+ const ledeLines = [
97
+ ` ${kleur.gray("repo:")} ${kleur.bold(bundle.repo.name ?? "(unnamed)")}`,
98
+ ` ${kleur.gray("HTC abstracts:")} ${kleur.bold(String(bundle.repo.commitsAvailable))}`,
99
+ ` ${kleur.gray("variants:")} ${kleur.green("truth")} ×${variantCounts.truth} · ${kleur.yellow("subtle-lie")} ×${variantCounts["subtle-lie"]} · ${kleur.red("wholesale-lie")} ×${variantCounts["wholesale-lie"]}`,
100
+ ];
101
+ const sampleLines = [];
102
+ for (const p of bundle.probes.slice(0, 5)) {
103
+ const claim = p.claim.length > 60 ? p.claim.slice(0, 57) + "..." : p.claim;
104
+ sampleLines.push(` ${kleur.gray(p.id)} ${kleur.bold(p.shortHash)} ${kleur.gray(claim)}`);
105
+ }
106
+ if (bundle.probes.length > 5) {
107
+ sampleLines.push(` ${kleur.gray(`… and ${bundle.probes.length - 5} more in ${outPath}`)}`);
108
+ }
109
+ const sections = [
110
+ { tier: "lede", title: "✦ Probe bundle", lines: ledeLines },
111
+ { tier: "key-facts", title: "◆ Sample probes", lines: sampleLines },
112
+ {
113
+ tier: "sources",
114
+ title: "→ Try next",
115
+ lines: [
116
+ ` ${kleur.cyan("$")} ${kleur.bold("# 1. Paste " + outPath + " into your AI client")}`,
117
+ ` ${kleur.cyan("$")} ${kleur.bold("# 2. Save the AI's verdicts as responses.json")}`,
118
+ ` ${kleur.cyan("$")} ${kleur.bold("mneme adversarial --grade responses.json")} ${kleur.gray("(compute trust score)")}`,
119
+ "",
120
+ ` ${kleur.gray("📘 How to read:")} the AI must answer ${kleur.green("`true`")} for genuine probes,`,
121
+ ` ${kleur.gray("`false` for lies. The AI's job on a fabricated claim is to refuse with reason.")}`,
122
+ ` ${kleur.gray("`uncertain` on a lie counts as a miss — a trustworthy AI commits to refusal.")}`,
123
+ ],
124
+ },
125
+ {
126
+ tier: "details",
127
+ title: "∎ Honest scope",
128
+ lines: [
129
+ ` ${kleur.gray("• This audits the AI client, not Mneme itself.")}`,
130
+ ` ${kleur.gray("• Probes are deliberately deceptive — that is the point.")}`,
131
+ ` ${kleur.gray("• Answer key persisted to: " + answerKeyPath)}`,
132
+ ],
133
+ },
134
+ ];
135
+ ui.banner();
136
+ process.stdout.write(iris.render({ headline, sections }) + "\n");
137
+ return 0;
138
+ }
139
+ // ─── grade ─────────────────────────────────────────────────────────────
140
+ function runGrade(opts, repoRoot) {
141
+ const answerKeyPath = join(mnemeDir(repoRoot), ANSWER_KEY_NAME);
142
+ let bundle;
143
+ try {
144
+ bundle = deserializeAnswerKey(readFileSync(answerKeyPath, "utf8"));
145
+ }
146
+ catch (err) {
147
+ ui.error(`No answer key at ${answerKeyPath} — run \`mneme adversarial\` first to generate one.`);
148
+ if (process.env.DEBUG)
149
+ process.stderr.write(String(err) + "\n");
150
+ return 1;
151
+ }
152
+ let raw;
153
+ try {
154
+ raw = readFileSync(opts.grade, "utf8");
155
+ }
156
+ catch (err) {
157
+ ui.error(`Could not read responses file: ${opts.grade} (${err.message})`);
158
+ return 1;
159
+ }
160
+ let parsed;
161
+ try {
162
+ parsed = JSON.parse(raw);
163
+ }
164
+ catch (err) {
165
+ ui.error(`Responses file is not valid JSON: ${err.message}`);
166
+ return 1;
167
+ }
168
+ const responses = (parsed.responses ?? []).map((r) => ({
169
+ id: String(r.id),
170
+ verdict: normalizeVerdict(String(r.verdict)),
171
+ note: r.note,
172
+ }));
173
+ const report = gradeResponses(bundle, { responses });
174
+ if (opts.json) {
175
+ process.stdout.write(JSON.stringify(report, null, 2) + "\n");
176
+ return 0;
177
+ }
178
+ const headline = `🎯 AI trust score: ${report.trustScore}% — caught ${report.correctProbes}/${report.totalProbes} contradictions`;
179
+ const verdictPill = report.trustScore >= 90
180
+ ? pill("TRUSTWORTHY", "ok")
181
+ : report.trustScore >= 70
182
+ ? pill("MOSTLY OK", "ok")
183
+ : report.trustScore >= 50
184
+ ? pill("SHAKY", "warn")
185
+ : pill("UNTRUSTED", "high");
186
+ const ledeLines = [
187
+ ` ${kleur.gray("verdict:")} ${verdictPill}`,
188
+ ` ${kleur.gray("score:")} ${kleur.bold(report.trustScore + "%")} ${kleur.gray(`(${report.correctProbes} of ${report.totalProbes})`)}`,
189
+ ` ${kleur.gray("truth:")} ${kleur.green(`${report.perVariant.truth.correct}/${report.perVariant.truth.total}`)} caught`,
190
+ ` ${kleur.gray("subtle-lie:")} ${kleur.yellow(`${report.perVariant["subtle-lie"].correct}/${report.perVariant["subtle-lie"].total}`)} caught`,
191
+ ` ${kleur.gray("wholesale:")} ${kleur.red(`${report.perVariant["wholesale-lie"].correct}/${report.perVariant["wholesale-lie"].total}`)} caught`,
192
+ ];
193
+ const missedLines = [];
194
+ for (const m of report.missed.slice(0, 8)) {
195
+ const v = labelForVariant(m.variant);
196
+ missedLines.push(` ${v} ${kleur.gray(m.id)} ${kleur.gray(`expected ${m.expected}, got ${m.got}`)}`);
197
+ missedLines.push(` ${kleur.gray(m.claim.slice(0, 80))}`);
198
+ }
199
+ if (report.missed.length > 8) {
200
+ missedLines.push(` ${kleur.gray(`… and ${report.missed.length - 8} more`)}`);
201
+ }
202
+ const sections = [
203
+ { tier: "lede", title: "✦ Trust grade", lines: ledeLines },
204
+ {
205
+ tier: "body",
206
+ title: "◆ Plain-English summary",
207
+ lines: [` ${kleur.gray(report.summary)}`],
208
+ },
209
+ ];
210
+ if (missedLines.length > 0) {
211
+ sections.push({
212
+ tier: "body",
213
+ title: `⚠ Missed probes (top ${Math.min(8, report.missed.length)})`,
214
+ lines: missedLines,
215
+ });
216
+ }
217
+ sections.push({
218
+ tier: "sources",
219
+ title: "→ Try next",
220
+ lines: [
221
+ ` ${kleur.cyan("$")} ${kleur.bold("mneme adversarial --probes 24")} ${kleur.gray("(re-test with a bigger sample)")}`,
222
+ "",
223
+ ` ${kleur.gray("📘 How to read:")} truth probes test recall — does the AI confirm real history?`,
224
+ ` ${kleur.gray("Subtle and wholesale probes test refusal — does it push back on contradictions?")}`,
225
+ ],
226
+ });
227
+ ui.banner();
228
+ process.stdout.write(iris.render({ headline, sections }) + "\n");
229
+ return 0;
230
+ }
231
+ // ─── helpers ───────────────────────────────────────────────────────────
232
+ function normalizeVerdict(v) {
233
+ const lower = v.trim().toLowerCase();
234
+ if (lower === "true" || lower === "yes" || lower === "verified")
235
+ return "true";
236
+ if (lower === "false" || lower === "no" || lower === "contradicted")
237
+ return "false";
238
+ return "uncertain";
239
+ }
240
+ function labelForVariant(v) {
241
+ switch (v) {
242
+ case "truth":
243
+ return kleur.green().bold("TRUTH ");
244
+ case "subtle-lie":
245
+ return kleur.yellow().bold("SUBTLE ");
246
+ case "wholesale-lie":
247
+ return kleur.red().bold("WHOLESALE");
248
+ }
249
+ }
250
+ function deriveRepoName(rootPath) {
251
+ const parts = rootPath.replace(/\\/g, "/").split("/").filter(Boolean);
252
+ return parts[parts.length - 1] ?? "this repository";
253
+ }
254
+ function shortPath(path, repoRoot) {
255
+ const norm = path.replace(/\\/g, "/");
256
+ const root = repoRoot.replace(/\\/g, "/");
257
+ if (norm.startsWith(root))
258
+ return norm.slice(root.length).replace(/^\/+/, "");
259
+ return path;
260
+ }
261
+ function writeWithMkdir(path, contents) {
262
+ const dir = dirname(path);
263
+ if (dir) {
264
+ try {
265
+ mkdirSync(dir, { recursive: true });
266
+ }
267
+ catch {
268
+ /* ignore */
269
+ }
270
+ }
271
+ writeFileSync(path, contents, "utf8");
272
+ }
273
+ //# sourceMappingURL=adversarial.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adversarial.js","sourceRoot":"","sources":["../../src/commands/adversarial.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * End-to-end CLI smoke tests for the v0.31.0 Black Sheep Edition commands:
3
+ * - mneme adversarial
4
+ * - mneme counterfactual
5
+ * - mneme org
6
+ *
7
+ * Skipped when `.mneme/mneme.db` is not populated (no index).
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=black-sheep.smoke.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"black-sheep.smoke.test.d.ts","sourceRoot":"","sources":["../../src/commands/black-sheep.smoke.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,186 @@
1
+ /**
2
+ * End-to-end CLI smoke tests for the v0.31.0 Black Sheep Edition commands:
3
+ * - mneme adversarial
4
+ * - mneme counterfactual
5
+ * - mneme org
6
+ *
7
+ * Skipped when `.mneme/mneme.db` is not populated (no index).
8
+ */
9
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
10
+ import { spawnSync } from "node:child_process";
11
+ import { existsSync, mkdtempSync, rmSync, writeFileSync, readFileSync } from "node:fs";
12
+ import { join } from "node:path";
13
+ import { tmpdir } from "node:os";
14
+ const REPO = process.cwd().replace(/\\/g, "/");
15
+ const CLI = join(REPO, "packages/cli/bin/mneme.js");
16
+ const DB = join(REPO, ".mneme/mneme.db");
17
+ const hasIndex = existsSync(DB) && existsSync(CLI);
18
+ const describeIfIndexed = hasIndex ? describe : describe.skip;
19
+ function runCli(args, extraEnv = {}) {
20
+ const r = spawnSync(process.execPath, [CLI, ...args], {
21
+ cwd: REPO,
22
+ encoding: "utf8",
23
+ env: { ...process.env, FORCE_COLOR: "0", NO_COLOR: "1", ...extraEnv },
24
+ windowsHide: true,
25
+ timeout: 120_000,
26
+ });
27
+ return { exitCode: r.status, stdout: r.stdout || "", stderr: r.stderr || "" };
28
+ }
29
+ describeIfIndexed("adversarial + counterfactual + org — end-to-end smoke", () => {
30
+ let tmp;
31
+ let fakeHome;
32
+ beforeEach(() => {
33
+ tmp = mkdtempSync(join(tmpdir(), "mneme-blacksheep-"));
34
+ fakeHome = mkdtempSync(join(tmpdir(), "mneme-bs-home-"));
35
+ });
36
+ afterEach(() => {
37
+ try {
38
+ rmSync(tmp, { recursive: true, force: true });
39
+ rmSync(fakeHome, { recursive: true, force: true });
40
+ }
41
+ catch {
42
+ /* ignore */
43
+ }
44
+ });
45
+ // ─── adversarial ─────────────────────────────────────────────────────
46
+ it("`mneme adversarial --probes 6` exits 0 (with or without HTC abstracts)", () => {
47
+ const out = join(tmp, "probes.md");
48
+ const r = runCli(["adversarial", "--probes", "6", "--out", out]);
49
+ expect(r.exitCode).toBe(0);
50
+ // Either:
51
+ // • file written (HTC populated), or
52
+ // • headline says "no HTC abstracts available" (HTC empty).
53
+ if (existsSync(out)) {
54
+ const md = readFileSync(out, "utf8");
55
+ expect(md).toContain("# Mneme adversarial probes");
56
+ }
57
+ else {
58
+ expect(r.stdout.toLowerCase()).toMatch(/no htc/);
59
+ }
60
+ });
61
+ it("`mneme adversarial --json` returns parseable JSON", () => {
62
+ const r = runCli(["adversarial", "--probes", "6", "--json", "--out", join(tmp, "j.md")]);
63
+ expect(r.exitCode).toBe(0);
64
+ const i = r.stdout.indexOf("{");
65
+ expect(i).toBeGreaterThanOrEqual(0);
66
+ const parsed = JSON.parse(r.stdout.slice(i));
67
+ expect(typeof parsed.generatedAt).toBe("string");
68
+ });
69
+ // ─── counterfactual ──────────────────────────────────────────────────
70
+ it("`mneme counterfactual` requires an email", () => {
71
+ const r = runCli(["counterfactual"]);
72
+ // commander emits its own usage error.
73
+ expect(r.exitCode).not.toBe(0);
74
+ });
75
+ it("`mneme counterfactual <email>` exits 0 (returns degenerate report on solo-author repos)", () => {
76
+ // Use whatever email is most likely to appear; fall back to a known-absent one.
77
+ // Either path must exit 0 with friendly text.
78
+ const r = runCli(["counterfactual", "patsa2561@gmail.com"]);
79
+ expect(r.exitCode).toBe(0);
80
+ // Output mentions "without" or "Counterfactual".
81
+ expect(r.stdout.toLowerCase()).toMatch(/counterfactual|without|solo|never/);
82
+ });
83
+ it("`mneme counterfactual <email> --json` returns parseable JSON with the expected shape", () => {
84
+ const r = runCli(["counterfactual", "patsa2561@gmail.com", "--json"]);
85
+ expect(r.exitCode).toBe(0);
86
+ const i = r.stdout.indexOf("{");
87
+ expect(i).toBeGreaterThanOrEqual(0);
88
+ const parsed = JSON.parse(r.stdout.slice(i));
89
+ expect(typeof parsed.authorEmail).toBe("string");
90
+ expect(typeof parsed.narrative).toBe("string");
91
+ expect(parsed.atrophy).toBeDefined();
92
+ expect(parsed.telepathy).toBeDefined();
93
+ });
94
+ it("counterfactual on a solo-author Mneme repo prints the narrative", () => {
95
+ // Capture the actual rendered output so we can document it.
96
+ const r = runCli(["counterfactual", "patsa2561@gmail.com"]);
97
+ expect(r.exitCode).toBe(0);
98
+ const out = r.stdout;
99
+ // Either solo-author "only contributor" path, or a real-author path —
100
+ // either way the headline + narrative must mention "without".
101
+ expect(out.toLowerCase()).toMatch(/without|only contributor|never contributed/);
102
+ // Should never use words like "rebuke" or "evaluate"; must include "Bayesian" or "what-if".
103
+ expect(out.toLowerCase()).not.toMatch(/replaceable|inferior|underperform/);
104
+ });
105
+ // ─── org ─────────────────────────────────────────────────────────────
106
+ it("`mneme org list` on a fresh home shows empty list with init hint", () => {
107
+ const r = runCli(["org", "list"], { HOME: fakeHome, USERPROFILE: fakeHome });
108
+ expect(r.exitCode).toBe(0);
109
+ expect(r.stdout.toLowerCase()).toMatch(/no orgs|init/);
110
+ });
111
+ it("`mneme org init <name> --json` creates a registry file", () => {
112
+ const r = runCli(["org", "init", "smoke-test", "--json"], {
113
+ HOME: fakeHome,
114
+ USERPROFILE: fakeHome,
115
+ });
116
+ expect(r.exitCode).toBe(0);
117
+ const i = r.stdout.indexOf("{");
118
+ expect(i).toBeGreaterThanOrEqual(0);
119
+ const parsed = JSON.parse(r.stdout.slice(i));
120
+ expect(parsed.name).toBe("smoke-test");
121
+ // File should exist on disk in the fake home.
122
+ expect(existsSync(join(fakeHome, ".mneme/orgs/smoke-test.json"))).toBe(true);
123
+ });
124
+ it("`mneme org add` then `mneme org status` reports indexed/missing", () => {
125
+ runCli(["org", "init", "smoke-add"], { HOME: fakeHome, USERPROFILE: fakeHome });
126
+ runCli(["org", "add", "smoke-add", REPO], { HOME: fakeHome, USERPROFILE: fakeHome });
127
+ const r = runCli(["org", "status", "smoke-add", "--json"], {
128
+ HOME: fakeHome,
129
+ USERPROFILE: fakeHome,
130
+ });
131
+ expect(r.exitCode).toBe(0);
132
+ const i = r.stdout.indexOf("{");
133
+ const parsed = JSON.parse(r.stdout.slice(i));
134
+ expect(parsed.repos.length).toBe(1);
135
+ expect(parsed.repos[0].indexed).toBe(true);
136
+ });
137
+ it("`mneme org` (default) on an empty registry exits 1 with helpful error", () => {
138
+ const r = runCli(["org"], { HOME: fakeHome, USERPROFILE: fakeHome });
139
+ expect(r.exitCode).toBe(1);
140
+ expect(r.stderr.toLowerCase()).toMatch(/no orgs/);
141
+ });
142
+ it("`mneme org` (default) runs cross-repo nervous-system on a registered org", () => {
143
+ runCli(["org", "init", "smoke-run"], { HOME: fakeHome, USERPROFILE: fakeHome });
144
+ runCli(["org", "add", "smoke-run", REPO], { HOME: fakeHome, USERPROFILE: fakeHome });
145
+ const r = runCli(["org", "smoke-run", "--json"], {
146
+ HOME: fakeHome,
147
+ USERPROFILE: fakeHome,
148
+ });
149
+ expect(r.exitCode).toBe(0);
150
+ const i = r.stdout.indexOf("{");
151
+ const parsed = JSON.parse(r.stdout.slice(i));
152
+ expect(parsed.org.name).toBe("smoke-run");
153
+ expect(parsed.org.reposIndexed).toBe(1);
154
+ expect(Array.isArray(parsed.crossRepoPairs)).toBe(true);
155
+ expect(Array.isArray(parsed.limits)).toBe(true);
156
+ });
157
+ // ─── adversarial grading round-trip ──────────────────────────────────
158
+ it("adversarial grading round-trips: generate → fake responses → grade", () => {
159
+ const out = join(tmp, "rt.md");
160
+ // First, generate (works only if HTC abstracts exist).
161
+ const gen = runCli(["adversarial", "--probes", "6", "--out", out, "--json"]);
162
+ expect(gen.exitCode).toBe(0);
163
+ const i = gen.stdout.indexOf("{");
164
+ const bundle = JSON.parse(gen.stdout.slice(i));
165
+ if (!Array.isArray(bundle.probes) || bundle.probes.length === 0) {
166
+ // No HTC → skip the grading half (still proves generate is well-formed).
167
+ return;
168
+ }
169
+ // Build a "perfect" responses file using the answer key.
170
+ const responses = {
171
+ responses: bundle.probes.map((p) => ({
172
+ id: p.id,
173
+ verdict: bundle.answerKey[p.id] === "truth" ? "true" : "false",
174
+ })),
175
+ };
176
+ const respPath = join(tmp, "rt-responses.json");
177
+ writeFileSync(respPath, JSON.stringify(responses), "utf8");
178
+ const grade = runCli(["adversarial", "--grade", respPath, "--json"]);
179
+ expect(grade.exitCode).toBe(0);
180
+ const j = grade.stdout.indexOf("{");
181
+ const report = JSON.parse(grade.stdout.slice(j));
182
+ expect(report.trustScore).toBe(100);
183
+ expect(report.correctProbes).toBe(bundle.probes.length);
184
+ });
185
+ });
186
+ //# sourceMappingURL=black-sheep.smoke.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"black-sheep.smoke.test.js","sourceRoot":"","sources":["../../src/commands/black-sheep.smoke.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * `mneme bot` — auto-comment on PRs / MRs across CI platforms.
3
+ *
4
+ * Detects the CI platform (GitHub / GitLab / Bitbucket), runs a chosen
5
+ * set of analyzers, assembles a single Markdown comment, and posts it.
6
+ *
7
+ * --dry-run prints the rendered comment without posting (and without
8
+ * needing a token). This is the default smoke path on a developer
9
+ * laptop — same code path, just no network call.
10
+ *
11
+ * Internal architecture:
12
+ * 1. Run analyzer subcommands as child processes with --json.
13
+ * 2. Hand their JSON to `bot.formatComment`.
14
+ * 3. Resolve the platform adapter (or honor --platform / --pr).
15
+ * 4. Post (or print, on --dry-run).
16
+ */
17
+ import { bot } from "@mneme-ai/core";
18
+ export type IncludeKind = "audit" | "atrophy" | "ghost" | "promise";
19
+ export interface BotOptions {
20
+ cwd: string;
21
+ /** Override the PR/MR number. */
22
+ pr?: number;
23
+ /** Override the platform — by default we auto-detect. */
24
+ platform?: bot.PlatformName;
25
+ /** Comma-separated analyzer list — defaults to "audit,atrophy". */
26
+ include?: string;
27
+ /** Print without posting. */
28
+ dryRun?: boolean;
29
+ /** Machine-readable output. */
30
+ json?: boolean;
31
+ /**
32
+ * Test seam — override the runner used to invoke `mneme <cmd> --json`.
33
+ * Defaults to spawning this same process executable.
34
+ */
35
+ runner?: AnalyzerRunner;
36
+ /**
37
+ * Test seam — override platform adapters (e.g. inject mock fetcher).
38
+ */
39
+ adapters?: bot.PlatformAdapter[];
40
+ }
41
+ export interface AnalyzerRunner {
42
+ /** Run a Mneme subcommand and return its parsed JSON. Returns null on failure. */
43
+ run(args: string[], cwd: string): unknown | null;
44
+ }
45
+ export declare function botCommand(opts: BotOptions): Promise<number>;
46
+ export declare function parseIncludes(raw: string | undefined): IncludeKind[];
47
+ //# sourceMappingURL=bot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../src/commands/bot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,GAAG,EAAyB,MAAM,gBAAgB,CAAC;AAG5D,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAIpE,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,iCAAiC;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yDAAyD;IACzD,QAAQ,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC;IAC5B,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+BAA+B;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;CAClD;AAqCD,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAgFlE;AAID,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,EAAE,CAapE"}