mneme-ai 0.8.3

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 (107) hide show
  1. package/README.md +45 -0
  2. package/bin/mneme.js +2 -0
  3. package/dist/commands/adapt.d.ts +6 -0
  4. package/dist/commands/adapt.d.ts.map +1 -0
  5. package/dist/commands/adapt.js +219 -0
  6. package/dist/commands/adapt.js.map +1 -0
  7. package/dist/commands/ask.d.ts +8 -0
  8. package/dist/commands/ask.d.ts.map +1 -0
  9. package/dist/commands/ask.js +76 -0
  10. package/dist/commands/ask.js.map +1 -0
  11. package/dist/commands/blast.d.ts +8 -0
  12. package/dist/commands/blast.d.ts.map +1 -0
  13. package/dist/commands/blast.js +132 -0
  14. package/dist/commands/blast.js.map +1 -0
  15. package/dist/commands/clones.d.ts +19 -0
  16. package/dist/commands/clones.d.ts.map +1 -0
  17. package/dist/commands/clones.js +155 -0
  18. package/dist/commands/clones.js.map +1 -0
  19. package/dist/commands/conscience.d.ts +15 -0
  20. package/dist/commands/conscience.d.ts.map +1 -0
  21. package/dist/commands/conscience.js +202 -0
  22. package/dist/commands/conscience.js.map +1 -0
  23. package/dist/commands/correlate.d.ts +18 -0
  24. package/dist/commands/correlate.d.ts.map +1 -0
  25. package/dist/commands/correlate.js +173 -0
  26. package/dist/commands/correlate.js.map +1 -0
  27. package/dist/commands/echo.d.ts +16 -0
  28. package/dist/commands/echo.d.ts.map +1 -0
  29. package/dist/commands/echo.js +175 -0
  30. package/dist/commands/echo.js.map +1 -0
  31. package/dist/commands/genius.d.ts +13 -0
  32. package/dist/commands/genius.d.ts.map +1 -0
  33. package/dist/commands/genius.js +213 -0
  34. package/dist/commands/genius.js.map +1 -0
  35. package/dist/commands/heal.d.ts +22 -0
  36. package/dist/commands/heal.d.ts.map +1 -0
  37. package/dist/commands/heal.js +160 -0
  38. package/dist/commands/heal.js.map +1 -0
  39. package/dist/commands/index-cmd.d.ts +9 -0
  40. package/dist/commands/index-cmd.d.ts.map +1 -0
  41. package/dist/commands/index-cmd.js +74 -0
  42. package/dist/commands/index-cmd.js.map +1 -0
  43. package/dist/commands/init.d.ts +6 -0
  44. package/dist/commands/init.d.ts.map +1 -0
  45. package/dist/commands/init.js +34 -0
  46. package/dist/commands/init.js.map +1 -0
  47. package/dist/commands/mcp.d.ts +4 -0
  48. package/dist/commands/mcp.d.ts.map +1 -0
  49. package/dist/commands/mcp.js +10 -0
  50. package/dist/commands/mcp.js.map +1 -0
  51. package/dist/commands/palimpsest.d.ts +22 -0
  52. package/dist/commands/palimpsest.d.ts.map +1 -0
  53. package/dist/commands/palimpsest.js +164 -0
  54. package/dist/commands/palimpsest.js.map +1 -0
  55. package/dist/commands/status.d.ts +4 -0
  56. package/dist/commands/status.d.ts.map +1 -0
  57. package/dist/commands/status.js +49 -0
  58. package/dist/commands/status.js.map +1 -0
  59. package/dist/commands/teach.d.ts +16 -0
  60. package/dist/commands/teach.d.ts.map +1 -0
  61. package/dist/commands/teach.js +237 -0
  62. package/dist/commands/teach.js.map +1 -0
  63. package/dist/commands/teach.test.d.ts +2 -0
  64. package/dist/commands/teach.test.d.ts.map +1 -0
  65. package/dist/commands/teach.test.js +44 -0
  66. package/dist/commands/teach.test.js.map +1 -0
  67. package/dist/commands/why.d.ts +12 -0
  68. package/dist/commands/why.d.ts.map +1 -0
  69. package/dist/commands/why.js +85 -0
  70. package/dist/commands/why.js.map +1 -0
  71. package/dist/commands/wild-features.d.ts +42 -0
  72. package/dist/commands/wild-features.d.ts.map +1 -0
  73. package/dist/commands/wild-features.js +483 -0
  74. package/dist/commands/wild-features.js.map +1 -0
  75. package/dist/commands/wild-stubs.d.ts +6 -0
  76. package/dist/commands/wild-stubs.d.ts.map +1 -0
  77. package/dist/commands/wild-stubs.js +112 -0
  78. package/dist/commands/wild-stubs.js.map +1 -0
  79. package/dist/commands/wisdom.d.ts +13 -0
  80. package/dist/commands/wisdom.d.ts.map +1 -0
  81. package/dist/commands/wisdom.js +94 -0
  82. package/dist/commands/wisdom.js.map +1 -0
  83. package/dist/config.d.ts +26 -0
  84. package/dist/config.d.ts.map +1 -0
  85. package/dist/config.js +28 -0
  86. package/dist/config.js.map +1 -0
  87. package/dist/index.d.ts +2 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +371 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/meditations.d.ts +24 -0
  92. package/dist/meditations.d.ts.map +1 -0
  93. package/dist/meditations.js +120 -0
  94. package/dist/meditations.js.map +1 -0
  95. package/dist/meditations.test.d.ts +2 -0
  96. package/dist/meditations.test.d.ts.map +1 -0
  97. package/dist/meditations.test.js +70 -0
  98. package/dist/meditations.test.js.map +1 -0
  99. package/dist/paths.d.ts +7 -0
  100. package/dist/paths.d.ts.map +1 -0
  101. package/dist/paths.js +14 -0
  102. package/dist/paths.js.map +1 -0
  103. package/dist/ui.d.ts +12 -0
  104. package/dist/ui.d.ts.map +1 -0
  105. package/dist/ui.js +30 -0
  106. package/dist/ui.js.map +1 -0
  107. package/package.json +46 -0
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # mneme-ai
2
+
3
+ The Mneme CLI. **The memory layer of your codebase.**
4
+
5
+ ```bash
6
+ npm install -g mneme-ai
7
+ # or
8
+ npx -y mneme-ai init
9
+ ```
10
+
11
+ ## Commands
12
+
13
+ ```bash
14
+ mneme init # initialize Mneme in the current git repo
15
+ mneme index # index commits, PRs, embeddings
16
+ mneme ask "question" # natural-language search over git history
17
+ mneme why <file>:<line> # blame + RAG explanation
18
+ mneme status # what's indexed
19
+ mneme correlate # phase 3 — incident correlation
20
+ mneme mcp # run as an MCP server
21
+ mneme wisdom # daily meditation from the manifesto
22
+ mneme manifesto # full canon of meditations
23
+ ```
24
+
25
+ ## Connect to Claude Code / Cursor / Continue
26
+
27
+ ```json
28
+ {
29
+ "mcpServers": {
30
+ "mneme": {
31
+ "command": "npx",
32
+ "args": ["-y", "mneme-ai", "mcp"],
33
+ "cwd": "/abs/path/to/your/repo"
34
+ }
35
+ }
36
+ }
37
+ ```
38
+
39
+ ## Full documentation
40
+
41
+ → https://github.com/patsa2561-art/mneme-ai
42
+
43
+ ## License
44
+
45
+ MIT.
package/bin/mneme.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import("../dist/index.js").then((m) => m.run(process.argv));
@@ -0,0 +1,6 @@
1
+ export interface AdaptCommandOptions {
2
+ cwd: string;
3
+ json?: boolean;
4
+ }
5
+ export declare function adaptCommand(opts: AdaptCommandOptions): Promise<number>;
6
+ //# sourceMappingURL=adapt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapt.d.ts","sourceRoot":"","sources":["../../src/commands/adapt.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AASD,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoD7E"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * `mneme adapt` — the *mutant* feature.
3
+ *
4
+ * Mneme is honest that it works best with certain repo profiles. `adapt`
5
+ * inspects the current repo, classifies it, and prints the path of least
6
+ * resistance for getting value out of Mneme on THIS repo, today.
7
+ *
8
+ * Repo profile dimensions:
9
+ * • size (commits)
10
+ * • commit-message quality (mean subject length, generic-ratio)
11
+ * • PR / issue density
12
+ * • language breadth
13
+ * • incident corpus
14
+ * • entity index status
15
+ *
16
+ * Output: an ordered checklist of recommended commands plus a one-line
17
+ * positioning verdict ("research codebase", "early-stage product",
18
+ * "mature service", "dormant repo", etc.).
19
+ *
20
+ * Mneme is not one tool — it is a kit. `adapt` is how it figures out which
21
+ * piece to hand you first.
22
+ */
23
+ import kleur from "kleur";
24
+ import { git, store, util } from "@mneme-ai/core";
25
+ import { dbPath } from "../paths.js";
26
+ import { ui } from "../ui.js";
27
+ export async function adaptCommand(opts) {
28
+ if (!(await git.isGitRepo(opts.cwd))) {
29
+ ui.error("Not in a git repo.");
30
+ ui.dim("Mneme works on any git repo. To start one: `git init && git add . && git commit -m 'initial'`");
31
+ return 1;
32
+ }
33
+ const meta = await git.getRepoMeta(opts.cwd);
34
+ const s = new store.MnemeStore(dbPath(meta.rootPath));
35
+ const profile = await buildProfile(opts.cwd, s);
36
+ s.close();
37
+ if (opts.json) {
38
+ process.stdout.write(JSON.stringify(profile, null, 2) + "\n");
39
+ return 0;
40
+ }
41
+ ui.banner();
42
+ process.stdout.write(`${kleur.bold().cyan("Adapt")} ${kleur.gray(meta.rootPath)}\n\n`);
43
+ process.stdout.write(`${kleur.bold().magenta("Archetype")}\n`);
44
+ process.stdout.write(` ${kleur.bold(profile.archetype)}\n\n`);
45
+ process.stdout.write(`${kleur.bold().magenta("Signals")}\n`);
46
+ for (const [k, v] of Object.entries(profile.signals)) {
47
+ process.stdout.write(` ${kleur.gray(k.padEnd(22))} ${v}\n`);
48
+ }
49
+ process.stdout.write("\n");
50
+ if (profile.warnings.length) {
51
+ process.stdout.write(`${kleur.bold().yellow("Honest caveats")}\n`);
52
+ for (const w of profile.warnings) {
53
+ process.stdout.write(` ${kleur.yellow("!")} ${w}\n`);
54
+ }
55
+ process.stdout.write("\n");
56
+ }
57
+ process.stdout.write(`${kleur.bold().magenta("Recommended next commands")}\n`);
58
+ if (profile.recommendations.length === 0) {
59
+ process.stdout.write(` ${kleur.green("●")} you're set. Mneme has nothing to add right now.\n`);
60
+ }
61
+ else {
62
+ for (let i = 0; i < profile.recommendations.length; i++) {
63
+ const r = profile.recommendations[i];
64
+ process.stdout.write(` ${kleur.green(`${i + 1}.`)} ${kleur.bold(r.command)}\n` +
65
+ ` ${kleur.gray(r.reason)}\n`);
66
+ }
67
+ }
68
+ process.stdout.write("\n" + kleur.gray(" Adapt is deterministic — same repo state → same output. Re-run anytime.") + "\n");
69
+ return 0;
70
+ }
71
+ async function buildProfile(cwd, s) {
72
+ const recommendations = [];
73
+ const warnings = [];
74
+ const signals = {};
75
+ // 1. Are there commits in the working repo (not in store)?
76
+ const totalCommitsRaw = await git.execGit(["rev-list", "--all", "--count"], { cwd });
77
+ const totalCommits = totalCommitsRaw.code === 0 ? Number(totalCommitsRaw.stdout.trim()) : 0;
78
+ signals["commits in repo"] = totalCommits;
79
+ // 2. Index status
80
+ const indexedCommits = s.countCommits();
81
+ const indexedChunks = s.countChunks();
82
+ const indexedEntities = s.countEntities();
83
+ const indexedIncidents = s.db.prepare("SELECT COUNT(*) AS n FROM incidents").get();
84
+ const correlationCount = s.db.prepare("SELECT COUNT(*) AS n FROM correlations").get();
85
+ const synthesizedCount = s.countSynthesizedNotes();
86
+ signals["commits indexed"] = indexedCommits;
87
+ signals["entities indexed"] = indexedEntities;
88
+ signals["incidents indexed"] = indexedIncidents.n;
89
+ signals["correlations stored"] = correlationCount.n;
90
+ signals["synthesized notes"] = synthesizedCount;
91
+ // 3. Commit-message quality (sample first 200 indexed)
92
+ let avgSubjectLen = 0;
93
+ let genericRatio = 0;
94
+ let prRatio = 0;
95
+ if (indexedCommits > 0) {
96
+ const sample = util.loadAllCommits(s).slice(-200);
97
+ const subs = sample.map((c) => c.subject.trim());
98
+ avgSubjectLen = Math.round(subs.reduce((a, b) => a + b.length, 0) / subs.length);
99
+ const genericRe = /^(?:wip|update[sd]?|fix|fixed|fixes|tweak|misc|stuff|adjust|chore|cleanup|refactor)\.?$/i;
100
+ genericRatio = subs.filter((x) => genericRe.test(x)).length / subs.length;
101
+ prRatio = sample.filter((c) => c.prNumber).length / sample.length;
102
+ }
103
+ if (indexedCommits > 0) {
104
+ signals["avg subject length"] = avgSubjectLen;
105
+ signals["generic-msg ratio"] = (genericRatio * 100).toFixed(0) + "%";
106
+ signals["PR-tagged ratio"] = (prRatio * 100).toFixed(0) + "%";
107
+ }
108
+ // 4. Decide archetype + recommendations.
109
+ // Path 0: not initialized at all.
110
+ if (indexedCommits === 0) {
111
+ if (totalCommits === 0) {
112
+ return {
113
+ archetype: "Empty repo (no commits yet)",
114
+ signals,
115
+ recommendations: [
116
+ { command: "make a few commits with real messages", reason: "Mneme needs history to be useful." },
117
+ { command: "mneme init && mneme index", reason: "Run after you have ≥10 commits." },
118
+ ],
119
+ warnings: [
120
+ "Brand-new repos have no signal. Wait for ≥50 commits before judging Mneme's quality.",
121
+ ],
122
+ };
123
+ }
124
+ return {
125
+ archetype: "Indexed-not-yet repo",
126
+ signals,
127
+ recommendations: [
128
+ { command: "mneme init", reason: "Set up the local store." },
129
+ { command: "mneme index", reason: `Index the ${totalCommits} existing commits — this is the foundation.` },
130
+ ],
131
+ warnings: [],
132
+ };
133
+ }
134
+ // Path 1: tiny repo
135
+ if (indexedCommits < 30) {
136
+ warnings.push(`Only ${indexedCommits} commits indexed — Mneme's value compounds with history. Treat results as preview-quality.`);
137
+ }
138
+ // Path 2: poor commit messages.
139
+ if (genericRatio > 0.4 || avgSubjectLen < 25) {
140
+ recommendations.push({
141
+ command: "mneme heal",
142
+ reason: `${(genericRatio * 100).toFixed(0)}% of recent commit subjects are generic ("wip"/"fix"/"updated"). Heal synthesizes a WHY note from the diff so search can answer.`,
143
+ });
144
+ }
145
+ // Path 3: no Phase-2 entities yet.
146
+ if (indexedEntities === 0) {
147
+ recommendations.push({
148
+ command: "mneme entities",
149
+ reason: "No entity-level memory yet. Required before `mneme clones`, `mneme teach`, and richer answers about WHAT the code does.",
150
+ });
151
+ }
152
+ else {
153
+ recommendations.push({
154
+ command: "mneme clones --threshold 0.85",
155
+ reason: `${indexedEntities} entities indexed — surface near-duplicate functions ripe for refactor.`,
156
+ });
157
+ }
158
+ // Path 4: no incidents — recommend the manual path or pager.
159
+ if (indexedIncidents.n === 0) {
160
+ recommendations.push({
161
+ command: "mneme correlate --source manual --file ./incidents.json",
162
+ reason: "No incidents indexed. Even a small JSON list unlocks blast radius + conscience scoring.",
163
+ });
164
+ }
165
+ else if (correlationCount.n === 0) {
166
+ recommendations.push({
167
+ command: "mneme correlate --source pager --org X --project Y",
168
+ reason: `${indexedIncidents.n} incidents but 0 correlations — re-run correlate so the engine writes edges to the store.`,
169
+ });
170
+ }
171
+ // Path 5: lots of correlations — push viz + conscience + palimpsest.
172
+ if (correlationCount.n > 5) {
173
+ recommendations.push({
174
+ command: "mneme web",
175
+ reason: `${correlationCount.n} correlations — the temporal graph view becomes useful at this density.`,
176
+ });
177
+ recommendations.push({
178
+ command: "mneme conscience <changed-files>",
179
+ reason: "Use the historical graph as a pre-merge advisor for your next PR.",
180
+ });
181
+ }
182
+ // Path 6: solo project with no PR data — encourage GitHub PR fetcher.
183
+ if (prRatio < 0.05 && indexedCommits >= 50) {
184
+ recommendations.push({
185
+ command: "set GITHUB_TOKEN, then re-run `mneme index`",
186
+ reason: "No PR signal in commits. With a token, Mneme hydrates each commit with PR/issue body — the single biggest accuracy gain.",
187
+ });
188
+ }
189
+ // Path 7: mature repo — onboarding angle.
190
+ if (indexedCommits >= 200) {
191
+ recommendations.push({
192
+ command: "mneme mirror",
193
+ reason: "Mature codebase. Use the onboarding dossier when a new contributor joins.",
194
+ });
195
+ }
196
+ // Determine archetype.
197
+ let archetype = "Engineering codebase";
198
+ if (indexedCommits >= 1000)
199
+ archetype = "Mature, large codebase";
200
+ else if (indexedCommits >= 200)
201
+ archetype = "Active service / library";
202
+ else if (indexedCommits >= 50)
203
+ archetype = "Early-stage product";
204
+ else
205
+ archetype = "Young / personal repo";
206
+ if (genericRatio > 0.5)
207
+ archetype += " — sparse commit hygiene";
208
+ if (prRatio > 0.5)
209
+ archetype += " — PR-driven workflow";
210
+ if (correlationCount.n > 5)
211
+ archetype += " — incident-correlated";
212
+ return {
213
+ archetype,
214
+ signals,
215
+ recommendations,
216
+ warnings,
217
+ };
218
+ }
219
+ //# sourceMappingURL=adapt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapt.js","sourceRoot":"","sources":["../../src/commands/adapt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface AskCommandOptions {
2
+ cwd: string;
3
+ question: string;
4
+ topK?: number;
5
+ json?: boolean;
6
+ }
7
+ export declare function askCommand(opts: AskCommandOptions): Promise<number>;
8
+ //# sourceMappingURL=ask.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/commands/ask.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqCzE"}
@@ -0,0 +1,76 @@
1
+ import { git, retrieve, store } from "@mneme-ai/core";
2
+ import { resolveEmbedder } from "@mneme-ai/embeddings";
3
+ import { dbPath } from "../paths.js";
4
+ import { readConfig } from "../config.js";
5
+ import { ui } from "../ui.js";
6
+ import kleur from "kleur";
7
+ export async function askCommand(opts) {
8
+ if (!(await git.isGitRepo(opts.cwd))) {
9
+ ui.error("Not in a git repo. Run `mneme init` first.");
10
+ return 1;
11
+ }
12
+ const meta = await git.getRepoMeta(opts.cwd);
13
+ const cfg = readConfig(meta.rootPath);
14
+ const s = new store.MnemeStore(dbPath(meta.rootPath));
15
+ if (s.countCommits() === 0) {
16
+ ui.error("Memory is empty. Run `mneme index` first.");
17
+ s.close();
18
+ return 1;
19
+ }
20
+ const embedder = await resolveEmbedder({
21
+ provider: cfg.embeddings.provider,
22
+ model: cfg.embeddings.model,
23
+ baseUrl: cfg.embeddings.baseUrl,
24
+ });
25
+ const result = await retrieve.ask(opts.question, {
26
+ store: s,
27
+ embedder,
28
+ repo: meta,
29
+ topK: opts.topK ?? 8,
30
+ });
31
+ s.close();
32
+ if (opts.json) {
33
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
34
+ return 0;
35
+ }
36
+ printAskResult(result);
37
+ return 0;
38
+ }
39
+ function printAskResult(r) {
40
+ ui.banner();
41
+ process.stdout.write(`${kleur.bold().cyan("Q")} ${r.question}\n\n`);
42
+ process.stdout.write(`${kleur.bold().magenta("Summary")}\n${r.summary}\n\n`);
43
+ if (!r.searchResults.length)
44
+ return;
45
+ process.stdout.write(`${kleur.bold().magenta("Evidence")}\n`);
46
+ for (const sr of r.searchResults.slice(0, 6)) {
47
+ const c = sr.commit;
48
+ const date = c.authorDate.slice(0, 10);
49
+ const ref = c.prNumber ? `PR #${c.prNumber}` : c.shortHash;
50
+ const score = sr.score.toFixed(3);
51
+ process.stdout.write(` ${kleur.green("●")} ${kleur.bold(ref)} ${kleur.gray(`[${date} · ${c.authorName} · ${score}]`)}\n`);
52
+ process.stdout.write(` ${kleur.white(c.subject)}\n`);
53
+ if (c.body) {
54
+ const firstLine = c.body.split("\n")[0].trim();
55
+ if (firstLine)
56
+ process.stdout.write(` ${kleur.gray(truncate(firstLine, 120))}\n`);
57
+ }
58
+ if (c.files.length) {
59
+ const files = c.files.slice(0, 3).join(", ");
60
+ const more = c.files.length > 3 ? ` (+${c.files.length - 3})` : "";
61
+ process.stdout.write(` ${kleur.cyan("files:")} ${kleur.gray(files + more)}\n`);
62
+ }
63
+ process.stdout.write("\n");
64
+ }
65
+ if (r.citations.some((c) => c.url)) {
66
+ process.stdout.write(`${kleur.bold().magenta("Citations")}\n`);
67
+ for (const c of r.citations) {
68
+ if (c.url)
69
+ process.stdout.write(` ${kleur.gray("→")} ${c.url}\n`);
70
+ }
71
+ }
72
+ }
73
+ function truncate(s, n) {
74
+ return s.length <= n ? s : s.slice(0, n - 1) + "…";
75
+ }
76
+ //# sourceMappingURL=ask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask.js","sourceRoot":"","sources":["../../src/commands/ask.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface BlastCommandOptions {
2
+ cwd: string;
3
+ commit: string;
4
+ windowHours?: number;
5
+ json?: boolean;
6
+ }
7
+ export declare function blastCommand(opts: BlastCommandOptions): Promise<number>;
8
+ //# sourceMappingURL=blast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blast.d.ts","sourceRoot":"","sources":["../../src/commands/blast.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyG7E"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * `mneme blast <commit>` — predict what's at risk if this commit ships.
3
+ *
4
+ * Inverts the `correlate` engine direction: instead of "given an incident,
5
+ * which commits are likely the cause", we ask "given a commit, which past
6
+ * incidents share its file footprint, and what's the historical base-rate
7
+ * of incidents on the same files within the next 48 h?"
8
+ *
9
+ * Useful as a pre-merge gate (CI hook) or as a `git push` advisory.
10
+ */
11
+ import kleur from "kleur";
12
+ import { git, store } from "@mneme-ai/core";
13
+ import { dbPath } from "../paths.js";
14
+ import { ui } from "../ui.js";
15
+ export async function blastCommand(opts) {
16
+ if (!(await git.isGitRepo(opts.cwd))) {
17
+ ui.error("Not in a git repo. Run `mneme init` first.");
18
+ return 1;
19
+ }
20
+ const meta = await git.getRepoMeta(opts.cwd);
21
+ const s = new store.MnemeStore(dbPath(meta.rootPath));
22
+ // Resolve commit (accept short or long hash, or HEAD).
23
+ const target = await resolveCommit(opts.cwd, opts.commit);
24
+ if (!target) {
25
+ ui.error(`Could not resolve commit "${opts.commit}".`);
26
+ s.close();
27
+ return 1;
28
+ }
29
+ const commit = s.getCommit(target);
30
+ if (!commit) {
31
+ ui.error(`Commit ${target.slice(0, 8)} is not indexed. Run \`mneme index\`.`);
32
+ s.close();
33
+ return 1;
34
+ }
35
+ // Look up every past incident whose affected_files overlaps with this commit's files.
36
+ const allIncidents = loadAllIncidents(s);
37
+ const commitFiles = new Set(commit.files.map(normalizePath));
38
+ const matches = [];
39
+ for (const inc of allIncidents) {
40
+ const incFiles = new Set([...(inc.affectedFiles ?? [])].map(normalizePath));
41
+ const overlap = [...commitFiles].filter((f) => incFiles.has(f));
42
+ if (overlap.length > 0)
43
+ matches.push({ incident: inc, overlapFiles: overlap });
44
+ }
45
+ // Compute base-rate: of all PAST commits touching ANY file this commit touches,
46
+ // what fraction had an incident-correlation within `windowHours`?
47
+ const windowHours = opts.windowHours ?? 48;
48
+ const filesArray = Array.from(commitFiles);
49
+ let totalPriors = 0;
50
+ let triggeringPriors = 0;
51
+ if (filesArray.length > 0) {
52
+ const placeholders = filesArray.map(() => "?").join(",");
53
+ const priorRows = s.db
54
+ .prepare(`SELECT DISTINCT commit_hash FROM file_changes WHERE LOWER(REPLACE(path, '\\', '/')) IN (${placeholders})`)
55
+ .all(...filesArray);
56
+ totalPriors = priorRows.length;
57
+ if (totalPriors > 0) {
58
+ const corrRows = s.db
59
+ .prepare(`SELECT DISTINCT from_id FROM correlations
60
+ WHERE from_kind = 'commit' AND to_kind = 'incident' AND from_id IN (${priorRows.map(() => "?").join(",")})`)
61
+ .all(...priorRows.map((r) => r.commit_hash));
62
+ triggeringPriors = corrRows.length;
63
+ }
64
+ }
65
+ const baseRate = totalPriors === 0 ? 0 : triggeringPriors / totalPriors;
66
+ const verdict = baseRate >= 0.3 ? "HIGH" : baseRate >= 0.1 ? "MED" : "LOW";
67
+ if (opts.json) {
68
+ process.stdout.write(JSON.stringify({
69
+ commit: commit.shortHash,
70
+ windowHours,
71
+ baseRate,
72
+ verdict,
73
+ totalPriors,
74
+ triggeringPriors,
75
+ fileMatches: matches,
76
+ }, null, 2) + "\n");
77
+ s.close();
78
+ return 0;
79
+ }
80
+ ui.banner();
81
+ process.stdout.write(`${kleur.bold().cyan("Blast radius")} ${commit.shortHash} ${kleur.gray(`${commit.subject.slice(0, 60)}`)}\n\n`);
82
+ process.stdout.write(` ${kleur.bold("files changed")}: ${commit.files.length}\n`);
83
+ process.stdout.write(` ${kleur.bold("historical base rate")}: ${(baseRate * 100).toFixed(1)}% ` +
84
+ `${kleur.gray(`(${triggeringPriors} of ${totalPriors} prior commits on these files triggered an incident within ${windowHours}h)`)}\n`);
85
+ const color = verdict === "HIGH" ? kleur.red : verdict === "MED" ? kleur.yellow : kleur.green;
86
+ process.stdout.write(` ${kleur.bold("verdict")}: ${color(verdict)}\n\n`);
87
+ if (matches.length === 0) {
88
+ ui.success("No past incidents share files with this commit.");
89
+ }
90
+ else {
91
+ process.stdout.write(`${kleur.bold().magenta("Past incidents on overlapping files")}\n`);
92
+ for (const m of matches.slice(0, 10)) {
93
+ const date = m.incident.occurredAt.slice(0, 10);
94
+ process.stdout.write(` ${kleur.red("●")} ${kleur.bold(m.incident.id)} ${kleur.gray(`[${date} · ${m.incident.severity}]`)}\n` +
95
+ ` ${kleur.white(m.incident.title)}\n` +
96
+ ` ${kleur.gray(`overlap: ${m.overlapFiles.slice(0, 3).join(", ")}${m.overlapFiles.length > 3 ? " (+more)" : ""}`)}\n`);
97
+ }
98
+ if (matches.length > 10) {
99
+ process.stdout.write(kleur.gray(` …and ${matches.length - 10} more\n`));
100
+ }
101
+ }
102
+ s.close();
103
+ return 0;
104
+ }
105
+ async function resolveCommit(cwd, ref) {
106
+ const r = await git.execGit(["rev-parse", ref], { cwd });
107
+ if (r.code !== 0)
108
+ return null;
109
+ return r.stdout.trim();
110
+ }
111
+ function loadAllIncidents(s) {
112
+ const rows = s.db
113
+ .prepare("SELECT * FROM incidents ORDER BY occurred_at DESC")
114
+ .all();
115
+ return rows.map((r) => ({
116
+ id: String(r.id),
117
+ source: r.source,
118
+ externalId: r.external_id ? String(r.external_id) : undefined,
119
+ title: String(r.title),
120
+ occurredAt: String(r.occurred_at),
121
+ resolvedAt: r.resolved_at ? String(r.resolved_at) : undefined,
122
+ severity: r.severity,
123
+ affectedFiles: r.affected_files ? JSON.parse(String(r.affected_files)) : undefined,
124
+ stackFrames: r.stack_frames ? JSON.parse(String(r.stack_frames)) : undefined,
125
+ url: r.url ? String(r.url) : undefined,
126
+ metadata: r.metadata ? JSON.parse(String(r.metadata)) : undefined,
127
+ }));
128
+ }
129
+ function normalizePath(p) {
130
+ return p.replace(/\\/g, "/").replace(/^\.\//, "").toLowerCase();
131
+ }
132
+ //# sourceMappingURL=blast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blast.js","sourceRoot":"","sources":["../../src/commands/blast.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export interface IndexEntitiesOptions {
2
+ cwd: string;
3
+ embedBatchSize?: number;
4
+ }
5
+ /**
6
+ * `mneme entities` — parse repo, embed, persist.
7
+ */
8
+ export declare function entitiesCommand(opts: IndexEntitiesOptions): Promise<number>;
9
+ export interface ClonesCommandOptions {
10
+ cwd: string;
11
+ threshold?: number;
12
+ topN?: number;
13
+ json?: boolean;
14
+ }
15
+ /**
16
+ * `mneme clones` — detect semantic clones from indexed entities.
17
+ */
18
+ export declare function clonesCommand(opts: ClonesCommandOptions): Promise<number>;
19
+ //# sourceMappingURL=clones.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clones.d.ts","sourceRoot":"","sources":["../../src/commands/clones.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuGjF;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2D/E"}