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.
- package/README.md +45 -0
- package/bin/mneme.js +2 -0
- package/dist/commands/adapt.d.ts +6 -0
- package/dist/commands/adapt.d.ts.map +1 -0
- package/dist/commands/adapt.js +219 -0
- package/dist/commands/adapt.js.map +1 -0
- package/dist/commands/ask.d.ts +8 -0
- package/dist/commands/ask.d.ts.map +1 -0
- package/dist/commands/ask.js +76 -0
- package/dist/commands/ask.js.map +1 -0
- package/dist/commands/blast.d.ts +8 -0
- package/dist/commands/blast.d.ts.map +1 -0
- package/dist/commands/blast.js +132 -0
- package/dist/commands/blast.js.map +1 -0
- package/dist/commands/clones.d.ts +19 -0
- package/dist/commands/clones.d.ts.map +1 -0
- package/dist/commands/clones.js +155 -0
- package/dist/commands/clones.js.map +1 -0
- package/dist/commands/conscience.d.ts +15 -0
- package/dist/commands/conscience.d.ts.map +1 -0
- package/dist/commands/conscience.js +202 -0
- package/dist/commands/conscience.js.map +1 -0
- package/dist/commands/correlate.d.ts +18 -0
- package/dist/commands/correlate.d.ts.map +1 -0
- package/dist/commands/correlate.js +173 -0
- package/dist/commands/correlate.js.map +1 -0
- package/dist/commands/echo.d.ts +16 -0
- package/dist/commands/echo.d.ts.map +1 -0
- package/dist/commands/echo.js +175 -0
- package/dist/commands/echo.js.map +1 -0
- package/dist/commands/genius.d.ts +13 -0
- package/dist/commands/genius.d.ts.map +1 -0
- package/dist/commands/genius.js +213 -0
- package/dist/commands/genius.js.map +1 -0
- package/dist/commands/heal.d.ts +22 -0
- package/dist/commands/heal.d.ts.map +1 -0
- package/dist/commands/heal.js +160 -0
- package/dist/commands/heal.js.map +1 -0
- package/dist/commands/index-cmd.d.ts +9 -0
- package/dist/commands/index-cmd.d.ts.map +1 -0
- package/dist/commands/index-cmd.js +74 -0
- package/dist/commands/index-cmd.js.map +1 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +34 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mcp.d.ts +4 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +10 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/palimpsest.d.ts +22 -0
- package/dist/commands/palimpsest.d.ts.map +1 -0
- package/dist/commands/palimpsest.js +164 -0
- package/dist/commands/palimpsest.js.map +1 -0
- package/dist/commands/status.d.ts +4 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +49 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/teach.d.ts +16 -0
- package/dist/commands/teach.d.ts.map +1 -0
- package/dist/commands/teach.js +237 -0
- package/dist/commands/teach.js.map +1 -0
- package/dist/commands/teach.test.d.ts +2 -0
- package/dist/commands/teach.test.d.ts.map +1 -0
- package/dist/commands/teach.test.js +44 -0
- package/dist/commands/teach.test.js.map +1 -0
- package/dist/commands/why.d.ts +12 -0
- package/dist/commands/why.d.ts.map +1 -0
- package/dist/commands/why.js +85 -0
- package/dist/commands/why.js.map +1 -0
- package/dist/commands/wild-features.d.ts +42 -0
- package/dist/commands/wild-features.d.ts.map +1 -0
- package/dist/commands/wild-features.js +483 -0
- package/dist/commands/wild-features.js.map +1 -0
- package/dist/commands/wild-stubs.d.ts +6 -0
- package/dist/commands/wild-stubs.d.ts.map +1 -0
- package/dist/commands/wild-stubs.js +112 -0
- package/dist/commands/wild-stubs.js.map +1 -0
- package/dist/commands/wisdom.d.ts +13 -0
- package/dist/commands/wisdom.d.ts.map +1 -0
- package/dist/commands/wisdom.js +94 -0
- package/dist/commands/wisdom.js.map +1 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +28 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +371 -0
- package/dist/index.js.map +1 -0
- package/dist/meditations.d.ts +24 -0
- package/dist/meditations.d.ts.map +1 -0
- package/dist/meditations.js +120 -0
- package/dist/meditations.js.map +1 -0
- package/dist/meditations.test.d.ts +2 -0
- package/dist/meditations.test.d.ts.map +1 -0
- package/dist/meditations.test.js +70 -0
- package/dist/meditations.test.js.map +1 -0
- package/dist/paths.d.ts +7 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +14 -0
- package/dist/paths.js.map +1 -0
- package/dist/ui.d.ts +12 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +30 -0
- package/dist/ui.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundle of mid-sized "wild" features — kept in one file because each one is
|
|
3
|
+
* small and they share helpers. Split into separate files when any of them
|
|
4
|
+
* crosses ~250 lines or grows non-trivial dependencies.
|
|
5
|
+
*
|
|
6
|
+
* • mneme runaway — entities that have grown silently over time
|
|
7
|
+
* • mneme mirror — onboarding dossier (5 PRs, 3 people, 2 incidents)
|
|
8
|
+
* • mneme rumor — tribal knowledge in commit text that should be docs
|
|
9
|
+
* • mneme fossil — files deleted from HEAD but still in git history
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
12
|
+
import { join, extname } from "node:path";
|
|
13
|
+
import kleur from "kleur";
|
|
14
|
+
import { git, store, util } from "@mneme-ai/core";
|
|
15
|
+
import { dbPath } from "../paths.js";
|
|
16
|
+
import { ui } from "../ui.js";
|
|
17
|
+
export async function runawayCommand(opts) {
|
|
18
|
+
if (!(await git.isGitRepo(opts.cwd))) {
|
|
19
|
+
ui.error("Not in a git repo. Run `mneme init` first.");
|
|
20
|
+
return 1;
|
|
21
|
+
}
|
|
22
|
+
const meta = await git.getRepoMeta(opts.cwd);
|
|
23
|
+
const s = new store.MnemeStore(dbPath(meta.rootPath));
|
|
24
|
+
// Score: a file's "runaway" score = number of distinct commits touching it
|
|
25
|
+
// weighted by how many of those commits ADDED lines. We approximate growth.
|
|
26
|
+
const rows = s.db
|
|
27
|
+
.prepare(`SELECT path,
|
|
28
|
+
COUNT(*) AS commits,
|
|
29
|
+
SUM(insertions) AS adds,
|
|
30
|
+
SUM(deletions) AS dels,
|
|
31
|
+
SUM(insertions) - SUM(deletions) AS net
|
|
32
|
+
FROM file_changes
|
|
33
|
+
GROUP BY path
|
|
34
|
+
HAVING commits >= 3
|
|
35
|
+
ORDER BY net DESC, commits DESC
|
|
36
|
+
LIMIT ?`)
|
|
37
|
+
.all(opts.topN ?? 15);
|
|
38
|
+
if (opts.json) {
|
|
39
|
+
process.stdout.write(JSON.stringify(rows, null, 2) + "\n");
|
|
40
|
+
s.close();
|
|
41
|
+
return 0;
|
|
42
|
+
}
|
|
43
|
+
ui.banner();
|
|
44
|
+
process.stdout.write(`${kleur.bold().cyan("Runaway abstractions")}\n`);
|
|
45
|
+
process.stdout.write(kleur.gray(` Files that grew silently over many commits — candidates for refactor.\n\n`));
|
|
46
|
+
if (rows.length === 0) {
|
|
47
|
+
ui.warn("No runaway files. Either repo is small or every file is well-bounded.");
|
|
48
|
+
s.close();
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
process.stdout.write(` ${"path".padEnd(50)} ${"commits".padStart(8)} ${"net+lines".padStart(11)}\n`);
|
|
52
|
+
process.stdout.write(` ${"-".repeat(50)} ${"-".repeat(8)} ${"-".repeat(11)}\n`);
|
|
53
|
+
for (const r of rows) {
|
|
54
|
+
const sign = r.net >= 0 ? "+" : "";
|
|
55
|
+
process.stdout.write(` ${r.path.padEnd(50).slice(0, 50)} ${String(r.commits).padStart(8)} ${(sign + r.net).padStart(11)}\n`);
|
|
56
|
+
}
|
|
57
|
+
process.stdout.write("\n" +
|
|
58
|
+
kleur.gray(" Tip: run `mneme why <file>` on the top runaway to learn the WHY before refactoring.") +
|
|
59
|
+
"\n");
|
|
60
|
+
s.close();
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
export async function mirrorCommand(opts) {
|
|
64
|
+
if (!(await git.isGitRepo(opts.cwd))) {
|
|
65
|
+
ui.error("Not in a git repo. Run `mneme init` first.");
|
|
66
|
+
return 1;
|
|
67
|
+
}
|
|
68
|
+
const meta = await git.getRepoMeta(opts.cwd);
|
|
69
|
+
const s = new store.MnemeStore(dbPath(meta.rootPath));
|
|
70
|
+
const all = util.loadAllCommits(s);
|
|
71
|
+
if (all.length === 0) {
|
|
72
|
+
ui.error("Memory is empty. Run `mneme index` first.");
|
|
73
|
+
s.close();
|
|
74
|
+
return 1;
|
|
75
|
+
}
|
|
76
|
+
// Top PRs by impact (file count × body richness).
|
|
77
|
+
const prs = all
|
|
78
|
+
.filter((c) => c.prNumber)
|
|
79
|
+
.map((c) => ({
|
|
80
|
+
number: c.prNumber,
|
|
81
|
+
hash: c.shortHash,
|
|
82
|
+
author: c.authorName,
|
|
83
|
+
date: c.authorDate.slice(0, 10),
|
|
84
|
+
subject: c.subject,
|
|
85
|
+
bodyLen: (c.body || "").length + (c.prBody || "").length,
|
|
86
|
+
fileCount: c.files.length,
|
|
87
|
+
score: c.files.length * 10 + Math.min(500, (c.body || "").length + (c.prBody || "").length),
|
|
88
|
+
}))
|
|
89
|
+
.sort((a, b) => b.score - a.score)
|
|
90
|
+
.slice(0, opts.topPrs ?? 5);
|
|
91
|
+
// Top people by author + co-occurrence.
|
|
92
|
+
const counts = new Map();
|
|
93
|
+
for (const c of all) {
|
|
94
|
+
const cur = counts.get(c.authorEmail) ??
|
|
95
|
+
{ name: c.authorName, commits: 0, files: new Set() };
|
|
96
|
+
cur.commits++;
|
|
97
|
+
for (const f of c.files)
|
|
98
|
+
cur.files.add(f);
|
|
99
|
+
counts.set(c.authorEmail, cur);
|
|
100
|
+
}
|
|
101
|
+
const people = Array.from(counts.entries())
|
|
102
|
+
.map(([email, v]) => ({
|
|
103
|
+
email,
|
|
104
|
+
name: v.name,
|
|
105
|
+
commits: v.commits,
|
|
106
|
+
filesTouched: v.files.size,
|
|
107
|
+
score: v.commits + v.files.size * 0.5,
|
|
108
|
+
}))
|
|
109
|
+
.sort((a, b) => b.score - a.score)
|
|
110
|
+
.slice(0, opts.topPeople ?? 3);
|
|
111
|
+
// Top incidents by stored severity + recency.
|
|
112
|
+
const incidents = s.db
|
|
113
|
+
.prepare(`SELECT id, title, occurred_at, severity FROM incidents
|
|
114
|
+
ORDER BY (CASE severity WHEN 'critical' THEN 4 WHEN 'error' THEN 3 WHEN 'warning' THEN 2 ELSE 1 END) DESC, occurred_at DESC
|
|
115
|
+
LIMIT ?`)
|
|
116
|
+
.all(opts.topIncidents ?? 2);
|
|
117
|
+
if (opts.json) {
|
|
118
|
+
process.stdout.write(JSON.stringify({ prs, people, incidents }, null, 2) + "\n");
|
|
119
|
+
s.close();
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
ui.banner();
|
|
123
|
+
process.stdout.write(`${kleur.bold().cyan("Onboarding dossier")} ${kleur.gray(meta.rootPath)}\n\n`);
|
|
124
|
+
process.stdout.write(`${kleur.bold().magenta("📖 PRs to read first")}\n`);
|
|
125
|
+
if (!prs.length)
|
|
126
|
+
process.stdout.write(` ${kleur.gray("(no PRs detected — likely a personal/solo repo)")}\n`);
|
|
127
|
+
for (const p of prs) {
|
|
128
|
+
process.stdout.write(` ${kleur.green("●")} PR #${p.number} ${kleur.gray(`[${p.date} · ${p.author}]`)}\n` +
|
|
129
|
+
` ${kleur.white(p.subject)}\n` +
|
|
130
|
+
` ${kleur.gray(`${p.fileCount} files · ${p.bodyLen} body chars`)}\n`);
|
|
131
|
+
}
|
|
132
|
+
process.stdout.write(`\n${kleur.bold().magenta("👥 People to talk to")}\n`);
|
|
133
|
+
for (const p of people) {
|
|
134
|
+
process.stdout.write(` ${kleur.cyan("◆")} ${kleur.bold(p.name)} ${kleur.gray(`<${p.email}>`)}\n` +
|
|
135
|
+
` ${kleur.gray(`${p.commits} commits · ${p.filesTouched} files touched`)}\n`);
|
|
136
|
+
}
|
|
137
|
+
process.stdout.write(`\n${kleur.bold().magenta("⚠️ Incidents to know about")}\n`);
|
|
138
|
+
if (!incidents.length)
|
|
139
|
+
process.stdout.write(` ${kleur.gray("(none indexed — run `mneme correlate` to import)")}\n`);
|
|
140
|
+
for (const i of incidents) {
|
|
141
|
+
process.stdout.write(` ${kleur.red("●")} ${kleur.bold(i.id)} ${kleur.gray(`[${i.occurred_at.slice(0, 10)} · ${i.severity}]`)}\n` +
|
|
142
|
+
` ${kleur.white(i.title)}\n`);
|
|
143
|
+
}
|
|
144
|
+
process.stdout.write("\n");
|
|
145
|
+
s.close();
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
export async function rumorCommand(opts) {
|
|
149
|
+
if (!(await git.isGitRepo(opts.cwd))) {
|
|
150
|
+
ui.error("Not in a git repo. Run `mneme init` first.");
|
|
151
|
+
return 1;
|
|
152
|
+
}
|
|
153
|
+
const meta = await git.getRepoMeta(opts.cwd);
|
|
154
|
+
const s = new store.MnemeStore(dbPath(meta.rootPath));
|
|
155
|
+
const all = util.loadAllCommits(s);
|
|
156
|
+
// Extract candidate "tribal" phrases from commits + PRs:
|
|
157
|
+
// capitalized noun-ish n-grams that appear in N+ commits but never in docs.
|
|
158
|
+
const minMentions = opts.minMentions ?? 4;
|
|
159
|
+
const phraseHits = new Map();
|
|
160
|
+
for (const c of all) {
|
|
161
|
+
const text = `${c.subject}\n${c.body}\n${c.prBody ?? ""}`;
|
|
162
|
+
for (const phrase of extractPhrases(text)) {
|
|
163
|
+
const cur = phraseHits.get(phrase) ?? { count: 0, samples: [] };
|
|
164
|
+
cur.count++;
|
|
165
|
+
if (cur.samples.length < 3)
|
|
166
|
+
cur.samples.push(c.shortHash);
|
|
167
|
+
phraseHits.set(phrase, cur);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Skip phrases already documented.
|
|
171
|
+
const docsCorpus = readDocsCorpus(meta.rootPath);
|
|
172
|
+
const candidates = Array.from(phraseHits.entries())
|
|
173
|
+
.filter(([phrase, v]) => v.count >= minMentions)
|
|
174
|
+
.filter(([phrase]) => !docsCorpus.toLowerCase().includes(phrase.toLowerCase()))
|
|
175
|
+
.map(([phrase, v]) => ({ phrase, count: v.count, samples: v.samples }))
|
|
176
|
+
.sort((a, b) => b.count - a.count)
|
|
177
|
+
.slice(0, 20);
|
|
178
|
+
if (opts.json) {
|
|
179
|
+
process.stdout.write(JSON.stringify(candidates, null, 2) + "\n");
|
|
180
|
+
s.close();
|
|
181
|
+
return 0;
|
|
182
|
+
}
|
|
183
|
+
ui.banner();
|
|
184
|
+
process.stdout.write(`${kleur.bold().cyan("Rumor")} ${kleur.gray("tribal phrases that no doc explains")}\n\n`);
|
|
185
|
+
if (candidates.length === 0) {
|
|
186
|
+
ui.success("No undocumented tribal phrases detected. Either the docs are great or the corpus is small.");
|
|
187
|
+
s.close();
|
|
188
|
+
return 0;
|
|
189
|
+
}
|
|
190
|
+
for (const c of candidates) {
|
|
191
|
+
process.stdout.write(` ${kleur.yellow("●")} ${kleur.bold(c.phrase)} ${kleur.gray(`(${c.count} commits)`)}\n` +
|
|
192
|
+
` ${kleur.gray(`samples: ${c.samples.join(", ")}`)}\n` +
|
|
193
|
+
` ${kleur.cyan("suggest:")} create docs/${slug(c.phrase)}.md\n`);
|
|
194
|
+
}
|
|
195
|
+
process.stdout.write("\n");
|
|
196
|
+
s.close();
|
|
197
|
+
return 0;
|
|
198
|
+
}
|
|
199
|
+
const PHRASE_RE = /\b([A-Z][A-Za-z0-9]+(?:[-_/][A-Za-z0-9]+){0,3})\b/g;
|
|
200
|
+
const COMMON = new Set([
|
|
201
|
+
"the", "a", "an", "and", "or", "of", "to", "in", "on", "for", "with",
|
|
202
|
+
"github", "gitlab", "merge", "fix", "fixed", "fixes", "feat", "feature",
|
|
203
|
+
"wip", "update", "updates", "updated", "chore", "docs", "test", "tests",
|
|
204
|
+
"refactor", "initial", "first", "i", "it", "this", "that", "main", "master",
|
|
205
|
+
"src", "app", "lib", "node", "node_modules", "package", "packages",
|
|
206
|
+
]);
|
|
207
|
+
function extractPhrases(text) {
|
|
208
|
+
const out = new Set();
|
|
209
|
+
for (const m of text.matchAll(PHRASE_RE)) {
|
|
210
|
+
const p = m[1];
|
|
211
|
+
if (p.length < 4 || p.length > 40)
|
|
212
|
+
continue;
|
|
213
|
+
if (COMMON.has(p.toLowerCase()))
|
|
214
|
+
continue;
|
|
215
|
+
if (/^\d+$/.test(p))
|
|
216
|
+
continue;
|
|
217
|
+
out.add(p);
|
|
218
|
+
}
|
|
219
|
+
return out;
|
|
220
|
+
}
|
|
221
|
+
function readDocsCorpus(repoRoot) {
|
|
222
|
+
const dirs = ["docs", "doc", "documentation"];
|
|
223
|
+
const parts = [];
|
|
224
|
+
for (const d of dirs) {
|
|
225
|
+
const dirPath = join(repoRoot, d);
|
|
226
|
+
if (existsSync(dirPath))
|
|
227
|
+
walkText(dirPath, parts);
|
|
228
|
+
}
|
|
229
|
+
// Top-level README / ARCHITECTURE / etc.
|
|
230
|
+
for (const f of ["README.md", "ARCHITECTURE.md", "ROADMAP.md", "CONTRIBUTING.md"]) {
|
|
231
|
+
const p = join(repoRoot, f);
|
|
232
|
+
if (existsSync(p)) {
|
|
233
|
+
try {
|
|
234
|
+
parts.push(readFileSync(p, "utf8"));
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
// ignore
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return parts.join("\n");
|
|
242
|
+
}
|
|
243
|
+
function walkText(dir, out, depth = 0) {
|
|
244
|
+
if (depth > 4)
|
|
245
|
+
return;
|
|
246
|
+
let entries;
|
|
247
|
+
try {
|
|
248
|
+
entries = readdirSync(dir);
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
for (const e of entries) {
|
|
254
|
+
const p = join(dir, e);
|
|
255
|
+
let st;
|
|
256
|
+
try {
|
|
257
|
+
st = statSync(p);
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
if (st.isDirectory())
|
|
263
|
+
walkText(p, out, depth + 1);
|
|
264
|
+
else if (st.isFile() && [".md", ".mdx", ".txt", ".rst"].includes(extname(e).toLowerCase())) {
|
|
265
|
+
try {
|
|
266
|
+
out.push(readFileSync(p, "utf8"));
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
// ignore
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function slug(s) {
|
|
275
|
+
return s
|
|
276
|
+
.toLowerCase()
|
|
277
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
278
|
+
.replace(/^-+|-+$/g, "");
|
|
279
|
+
}
|
|
280
|
+
export async function fossilCommand(opts) {
|
|
281
|
+
if (!(await git.isGitRepo(opts.cwd))) {
|
|
282
|
+
ui.error("Not in a git repo. Run `mneme init` first.");
|
|
283
|
+
return 1;
|
|
284
|
+
}
|
|
285
|
+
const meta = await git.getRepoMeta(opts.cwd);
|
|
286
|
+
// Find files deleted in repo history that are still in `git log` but absent from HEAD.
|
|
287
|
+
// Simpler signal: query file_changes for files where the latest event is a deletion.
|
|
288
|
+
// But we don't track change_kind reliably yet — fall back to spawning git directly.
|
|
289
|
+
const r = await git.execGit([
|
|
290
|
+
"log",
|
|
291
|
+
"--all",
|
|
292
|
+
"--diff-filter=D",
|
|
293
|
+
"--name-only",
|
|
294
|
+
"--pretty=format:::commit::%H::%aI::%an::%s",
|
|
295
|
+
], { cwd: meta.rootPath });
|
|
296
|
+
if (r.code !== 0) {
|
|
297
|
+
ui.error(`git log failed: ${r.stderr.trim()}`);
|
|
298
|
+
return 1;
|
|
299
|
+
}
|
|
300
|
+
const fossils = [];
|
|
301
|
+
let cur = null;
|
|
302
|
+
for (const line of r.stdout.split("\n")) {
|
|
303
|
+
if (line.startsWith("::commit::")) {
|
|
304
|
+
const parts = line.split("::");
|
|
305
|
+
cur = {
|
|
306
|
+
hash: parts[3] ?? "",
|
|
307
|
+
date: parts[4] ?? "",
|
|
308
|
+
author: parts[5] ?? "",
|
|
309
|
+
subject: parts.slice(6).join("::"),
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
else if (line.trim() && cur) {
|
|
313
|
+
fossils.push({
|
|
314
|
+
path: line.trim(),
|
|
315
|
+
deletedInCommit: cur.hash.slice(0, 8),
|
|
316
|
+
deletedAt: cur.date.slice(0, 10),
|
|
317
|
+
deletedBy: cur.author,
|
|
318
|
+
subject: cur.subject,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
// Dedup: keep first deletion event per path.
|
|
323
|
+
const seen = new Set();
|
|
324
|
+
const dedup = fossils.filter((f) => {
|
|
325
|
+
if (seen.has(f.path))
|
|
326
|
+
return false;
|
|
327
|
+
seen.add(f.path);
|
|
328
|
+
return true;
|
|
329
|
+
});
|
|
330
|
+
const top = dedup.slice(0, opts.topN ?? 20);
|
|
331
|
+
if (opts.json) {
|
|
332
|
+
process.stdout.write(JSON.stringify(top, null, 2) + "\n");
|
|
333
|
+
return 0;
|
|
334
|
+
}
|
|
335
|
+
ui.banner();
|
|
336
|
+
process.stdout.write(`${kleur.bold().cyan("Fossil")} ${kleur.gray("files deleted from HEAD that still live in history")}\n\n`);
|
|
337
|
+
if (top.length === 0) {
|
|
338
|
+
ui.success("No deleted files found in history.");
|
|
339
|
+
return 0;
|
|
340
|
+
}
|
|
341
|
+
for (const f of top) {
|
|
342
|
+
process.stdout.write(` ${kleur.gray("●")} ${kleur.bold(f.path)}\n` +
|
|
343
|
+
` ${kleur.gray(`deleted ${f.deletedAt} by ${f.deletedBy} in ${f.deletedInCommit}`)}\n` +
|
|
344
|
+
` ${kleur.white(f.subject)}\n`);
|
|
345
|
+
}
|
|
346
|
+
process.stdout.write("\n" +
|
|
347
|
+
kleur.gray(" Tip: `git show <commit>:<path>` to see the file's last state.") +
|
|
348
|
+
"\n");
|
|
349
|
+
return 0;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* `mneme ledger` — tamper-evident audit log derived from git history.
|
|
353
|
+
*
|
|
354
|
+
* For regulated industries (banks, exchanges, healthcare): every commit + author
|
|
355
|
+
* + linked ticket gets a hash-chained entry. Tampering with any entry breaks
|
|
356
|
+
* the chain — auditors can verify integrity in seconds.
|
|
357
|
+
*/
|
|
358
|
+
export async function ledgerCommand(opts) {
|
|
359
|
+
if (!(await git.isGitRepo(opts.cwd))) {
|
|
360
|
+
ui.error("Not in a git repo. Run `mneme init` first.");
|
|
361
|
+
return 1;
|
|
362
|
+
}
|
|
363
|
+
const meta = await git.getRepoMeta(opts.cwd);
|
|
364
|
+
const s = new store.MnemeStore(dbPath(meta.rootPath));
|
|
365
|
+
const commits = util.loadCommitsBetween(s, opts.since, opts.until);
|
|
366
|
+
if (commits.length === 0) {
|
|
367
|
+
ui.error("No commits in range.");
|
|
368
|
+
s.close();
|
|
369
|
+
return 1;
|
|
370
|
+
}
|
|
371
|
+
const entries = [];
|
|
372
|
+
let prevHash = "0".repeat(64);
|
|
373
|
+
for (let i = 0; i < commits.length; i++) {
|
|
374
|
+
const c = commits[i];
|
|
375
|
+
const stats = fileStats(s, c);
|
|
376
|
+
const canonical = [
|
|
377
|
+
String(i + 1),
|
|
378
|
+
c.hash,
|
|
379
|
+
c.authorName,
|
|
380
|
+
c.authorEmail,
|
|
381
|
+
c.authorDate,
|
|
382
|
+
c.committerDate,
|
|
383
|
+
c.subject,
|
|
384
|
+
c.body,
|
|
385
|
+
String(c.prNumber ?? ""),
|
|
386
|
+
JSON.stringify(c.issueRefs ?? []),
|
|
387
|
+
String(stats.filesChanged),
|
|
388
|
+
String(stats.insertions),
|
|
389
|
+
String(stats.deletions),
|
|
390
|
+
].join("");
|
|
391
|
+
const entryHash = await util.sha256Hex(prevHash, canonical);
|
|
392
|
+
entries.push({
|
|
393
|
+
seq: i + 1,
|
|
394
|
+
commitHash: c.hash,
|
|
395
|
+
shortHash: c.shortHash,
|
|
396
|
+
authorName: c.authorName,
|
|
397
|
+
authorEmail: c.authorEmail,
|
|
398
|
+
authoredAt: c.authorDate,
|
|
399
|
+
committedAt: c.committerDate,
|
|
400
|
+
subject: c.subject,
|
|
401
|
+
body: c.body,
|
|
402
|
+
prNumber: c.prNumber,
|
|
403
|
+
prTitle: c.prTitle,
|
|
404
|
+
issueRefs: c.issueRefs,
|
|
405
|
+
filesChanged: stats.filesChanged,
|
|
406
|
+
insertions: stats.insertions,
|
|
407
|
+
deletions: stats.deletions,
|
|
408
|
+
prevHash,
|
|
409
|
+
entryHash,
|
|
410
|
+
});
|
|
411
|
+
prevHash = entryHash;
|
|
412
|
+
}
|
|
413
|
+
const format = opts.format ?? "json";
|
|
414
|
+
let payload;
|
|
415
|
+
if (format === "json") {
|
|
416
|
+
payload = JSON.stringify({
|
|
417
|
+
ledgerVersion: 1,
|
|
418
|
+
repo: { rootPath: meta.rootPath, remote: meta.remoteUrl },
|
|
419
|
+
generatedAt: new Date().toISOString(),
|
|
420
|
+
range: { since: opts.since ?? null, until: opts.until ?? null },
|
|
421
|
+
entryCount: entries.length,
|
|
422
|
+
finalHash: prevHash,
|
|
423
|
+
entries,
|
|
424
|
+
}, null, 2);
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
const header = [
|
|
428
|
+
"seq",
|
|
429
|
+
"commit_hash",
|
|
430
|
+
"author_name",
|
|
431
|
+
"author_email",
|
|
432
|
+
"authored_at",
|
|
433
|
+
"subject",
|
|
434
|
+
"pr_number",
|
|
435
|
+
"files_changed",
|
|
436
|
+
"insertions",
|
|
437
|
+
"deletions",
|
|
438
|
+
"prev_hash",
|
|
439
|
+
"entry_hash",
|
|
440
|
+
].join(",");
|
|
441
|
+
const rows = entries.map((e) => [
|
|
442
|
+
e.seq,
|
|
443
|
+
e.commitHash,
|
|
444
|
+
csv(e.authorName),
|
|
445
|
+
e.authorEmail,
|
|
446
|
+
e.authoredAt,
|
|
447
|
+
csv(e.subject),
|
|
448
|
+
e.prNumber ?? "",
|
|
449
|
+
e.filesChanged,
|
|
450
|
+
e.insertions,
|
|
451
|
+
e.deletions,
|
|
452
|
+
e.prevHash,
|
|
453
|
+
e.entryHash,
|
|
454
|
+
].join(","));
|
|
455
|
+
payload = [header, ...rows].join("\n");
|
|
456
|
+
}
|
|
457
|
+
if (opts.out) {
|
|
458
|
+
const { writeFileSync } = await import("node:fs");
|
|
459
|
+
writeFileSync(opts.out, payload, "utf8");
|
|
460
|
+
ui.success(`Wrote ${entries.length} entries to ${opts.out} (${format})`);
|
|
461
|
+
ui.dim(`Final hash: ${prevHash}`);
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
process.stdout.write(payload + "\n");
|
|
465
|
+
}
|
|
466
|
+
s.close();
|
|
467
|
+
return 0;
|
|
468
|
+
}
|
|
469
|
+
function fileStats(s, c) {
|
|
470
|
+
const rows = s.db
|
|
471
|
+
.prepare(`SELECT SUM(insertions) AS ins, SUM(deletions) AS del, COUNT(*) AS n
|
|
472
|
+
FROM file_changes WHERE commit_hash = ?`)
|
|
473
|
+
.get(c.hash);
|
|
474
|
+
return {
|
|
475
|
+
filesChanged: rows.n ?? 0,
|
|
476
|
+
insertions: rows.ins ?? 0,
|
|
477
|
+
deletions: rows.del ?? 0,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
function csv(s) {
|
|
481
|
+
return `"${s.replace(/"/g, '""').replace(/\n/g, " ")}"`;
|
|
482
|
+
}
|
|
483
|
+
//# sourceMappingURL=wild-features.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wild-features.js","sourceRoot":"","sources":["../../src/commands/wild-features.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function oracleCommand(): Promise<number>;
|
|
2
|
+
export declare function conscienceCommand(): Promise<number>;
|
|
3
|
+
export declare function genomeCommand(): Promise<number>;
|
|
4
|
+
export declare function dialogueCommand(): Promise<number>;
|
|
5
|
+
export declare function tributeCommand(): Promise<number>;
|
|
6
|
+
//# sourceMappingURL=wild-stubs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wild-stubs.d.ts","sourceRoot":"","sources":["../../src/commands/wild-stubs.ts"],"names":[],"mappings":"AAaA,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAqBrD;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAqBzD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAqBrD;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAqBvD;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAwBtD"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stub CLI commands for the rest of the WILD ideas. Each prints a thoughtful
|
|
3
|
+
* design overview so users see the roadmap shape — not a "coming soon" lorem.
|
|
4
|
+
*
|
|
5
|
+
* • mneme oracle — historical risk analysis on a snippet
|
|
6
|
+
* • mneme conscience — review co-pilot from history
|
|
7
|
+
* • mneme genome — codebase fingerprint + ancestry
|
|
8
|
+
* • mneme dialogue — conversational chat over your repo
|
|
9
|
+
* • mneme tribute — "your codebase as a movie"
|
|
10
|
+
*/
|
|
11
|
+
import kleur from "kleur";
|
|
12
|
+
import { ui } from "../ui.js";
|
|
13
|
+
export async function oracleCommand() {
|
|
14
|
+
return printPlan("oracle", "Historical risk analysis on a code snippet", [
|
|
15
|
+
"Paste any function or commit diff. Mneme finds:",
|
|
16
|
+
" • Past incidents in this codebase rooted in similar patterns",
|
|
17
|
+
" • Commits whose diff fingerprint matches and what they triggered",
|
|
18
|
+
" • A risk score for shipping this exact change",
|
|
19
|
+
"",
|
|
20
|
+
"Example output:",
|
|
21
|
+
` ${kleur.gray("This `db.query(${user_input})` pattern caused SQLi-2023-04.")}`,
|
|
22
|
+
` ${kleur.gray("Three other PRs that shipped this pattern were reverted within 24h.")}`,
|
|
23
|
+
"",
|
|
24
|
+
"Implementation requires:",
|
|
25
|
+
" • An incident corpus (run `mneme correlate --source pager` first)",
|
|
26
|
+
" • Pattern fingerprinting (AST-shape hashes — uses tree-sitter)",
|
|
27
|
+
" • Risk scoring model (regression on your own history)",
|
|
28
|
+
], "WILD #4 · pessimism 3/5 · 2-week sprint when prioritized");
|
|
29
|
+
}
|
|
30
|
+
export async function conscienceCommand() {
|
|
31
|
+
return printPlan("conscience", "PR review co-pilot powered by your repo's own history", [
|
|
32
|
+
"When reviewing a PR, Mneme finds the historically most-similar PRs and",
|
|
33
|
+
"reports their fate. The reviewer sees:",
|
|
34
|
+
"",
|
|
35
|
+
` ${kleur.gray("This PR changes 4 of the same files as PR #98 (reverted within 48h")}`,
|
|
36
|
+
` ${kleur.gray("after INC-1287). 87% file overlap. Recommend caution.")}`,
|
|
37
|
+
"",
|
|
38
|
+
"Two surfaces planned:",
|
|
39
|
+
" • mneme conscience <pr-url> — CLI",
|
|
40
|
+
" • GitHub Action check — runs on every PR open",
|
|
41
|
+
" • Cursor side-panel — when MCP exposes it",
|
|
42
|
+
"",
|
|
43
|
+
"Hard part: the similarity must be more than file-overlap. Phase 2",
|
|
44
|
+
"embeddings on entity-level diffs are the right substrate.",
|
|
45
|
+
], "WILD #6 · pessimism 2/5 · ships after Phase 2 multi-language parsing");
|
|
46
|
+
}
|
|
47
|
+
export async function genomeCommand() {
|
|
48
|
+
return printPlan("genome", "Codebase fingerprint + ancestry detection", [
|
|
49
|
+
"A cryptographic signature derived from code + history. Detects:",
|
|
50
|
+
" • Forks of public repos (M&A due diligence)",
|
|
51
|
+
" • Plagiarism / license violations",
|
|
52
|
+
" • Abandoned ancestor branches",
|
|
53
|
+
"",
|
|
54
|
+
"Example output:",
|
|
55
|
+
` ${kleur.gray("This proprietary repo shares 87% genome with public repo `acme/foo`.")}`,
|
|
56
|
+
` ${kleur.gray("Likely forked at commit a1b2c3d on 2023-09-12.")}`,
|
|
57
|
+
"",
|
|
58
|
+
"How: locality-sensitive hash of entity embeddings + commit-graph shape.",
|
|
59
|
+
"Two genomes are compared in O(genome_size), not O(repo_size).",
|
|
60
|
+
"",
|
|
61
|
+
"Privacy: only the genome hash leaves the machine. Source code never does.",
|
|
62
|
+
], "WILD #9 · pessimism 4/5 · needs Phase 2 entity embeddings + LSH");
|
|
63
|
+
}
|
|
64
|
+
export async function dialogueCommand() {
|
|
65
|
+
return printPlan("dialogue", "Conversational memory — multi-turn chat over your repo", [
|
|
66
|
+
"A persistent REPL that holds state across queries. Existing `mneme ask`",
|
|
67
|
+
"is one-shot; this one remembers context.",
|
|
68
|
+
"",
|
|
69
|
+
"Example session:",
|
|
70
|
+
` ${kleur.cyan(">")} what broke last quarter?`,
|
|
71
|
+
` 3 incidents: INC-1287, INC-2025-04, GH-Actions-failure-03`,
|
|
72
|
+
` ${kleur.cyan(">")} show me the rollbacks`,
|
|
73
|
+
` 2 reverts: PR #501, PR #523. Both within 36h of incident.`,
|
|
74
|
+
` ${kleur.cyan(">")} who reviewed those?`,
|
|
75
|
+
` alice@ approved both. Consider asking her about Q4 patterns.`,
|
|
76
|
+
"",
|
|
77
|
+
"Implementation: thin wrapper over MCP with conversation memory.",
|
|
78
|
+
"The hard part is UX — when to forget, what to summarize, how to cite.",
|
|
79
|
+
], "WILD #11 · pessimism 2/5 · 1-week sprint when Phase 3 is mature");
|
|
80
|
+
}
|
|
81
|
+
export async function tributeCommand() {
|
|
82
|
+
return printPlan("tribute", "Your codebase as a 60-second movie", [
|
|
83
|
+
"Auto-generated D3 animation of a repo's life — designed to be shared on",
|
|
84
|
+
"Twitter when an engineer leaves, when a project crosses 5 years, when a",
|
|
85
|
+
"startup gets acquired.",
|
|
86
|
+
"",
|
|
87
|
+
"Frames:",
|
|
88
|
+
` ${kleur.gray("• initial commit (a single dot)")}`,
|
|
89
|
+
` ${kleur.gray("• first module emerges (cluster)")}`,
|
|
90
|
+
` ${kleur.gray("• first incident (red flash)")}`,
|
|
91
|
+
` ${kleur.gray("• big redesign (cluster reorganizes)")}`,
|
|
92
|
+
` ${kleur.gray("• bus-factor moment (single contributor leaves)")}`,
|
|
93
|
+
` ${kleur.gray("• current state (full graph)")}`,
|
|
94
|
+
"",
|
|
95
|
+
"Output: an MP4 / GIF / HTML embed. Free marketing for Mneme; real",
|
|
96
|
+
"emotional value for the team it's about.",
|
|
97
|
+
"",
|
|
98
|
+
"Builds on the Phase 4 graph viz — already shipped as `mneme web`.",
|
|
99
|
+
], "WILD #15 · pessimism 3/5 · ships as `mneme web --tribute --out movie.mp4`");
|
|
100
|
+
}
|
|
101
|
+
function printPlan(name, tagline, body, footer) {
|
|
102
|
+
ui.banner();
|
|
103
|
+
process.stdout.write(`${kleur.bold().magenta(`mneme ${name}`)} ${kleur.gray("(planned)")}\n`);
|
|
104
|
+
process.stdout.write(`${kleur.italic().cyan(tagline)}\n\n`);
|
|
105
|
+
for (const line of body)
|
|
106
|
+
process.stdout.write(` ${line}\n`);
|
|
107
|
+
process.stdout.write("\n");
|
|
108
|
+
process.stdout.write(` ${kleur.gray(footer)}\n`);
|
|
109
|
+
process.stdout.write(` ${kleur.gray("See WILD_IDEAS.md for the full catalog.")}\n`);
|
|
110
|
+
return Promise.resolve(0);
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=wild-stubs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wild-stubs.js","sourceRoot":"","sources":["../../src/commands/wild-stubs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface WisdomOptions {
|
|
2
|
+
/** Pick a specific meditation (1-indexed). Otherwise: meditation of the day. */
|
|
3
|
+
index?: number;
|
|
4
|
+
/** Print the entire canon. */
|
|
5
|
+
all?: boolean;
|
|
6
|
+
/** JSON output. */
|
|
7
|
+
json?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function wisdomCommand(opts: WisdomOptions): Promise<number>;
|
|
10
|
+
export declare function manifestoCommand(opts: {
|
|
11
|
+
json?: boolean;
|
|
12
|
+
}): Promise<number>;
|
|
13
|
+
//# sourceMappingURL=wisdom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wisdom.d.ts","sourceRoot":"","sources":["../../src/commands/wisdom.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,mBAAmB;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CA0CxE;AA6CD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BhF"}
|