mneme-ai 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/constitution.d.ts +45 -0
- package/dist/commands/constitution.d.ts.map +1 -0
- package/dist/commands/constitution.js +204 -0
- package/dist/commands/constitution.js.map +1 -0
- package/dist/commands/session.d.ts +67 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +216 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/session.test.d.ts +5 -0
- package/dist/commands/session.test.d.ts.map +1 -0
- package/dist/commands/session.test.js +270 -0
- package/dist/commands/session.test.js.map +1 -0
- package/dist/commands/webhook.d.ts +59 -0
- package/dist/commands/webhook.d.ts.map +1 -0
- package/dist/commands/webhook.js +220 -0
- package/dist/commands/webhook.js.map +1 -0
- package/dist/commands/webhook.test.d.ts +5 -0
- package/dist/commands/webhook.test.d.ts.map +1 -0
- package/dist/commands/webhook.test.js +192 -0
- package/dist/commands/webhook.test.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +125 -0
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mneme constitution` — Codebase Constitution synthesizer.
|
|
3
|
+
*
|
|
4
|
+
* Synthesises a living "constitution" document from the repo's history:
|
|
5
|
+
* never-do rules from past regrets · expert-pairing constraints from
|
|
6
|
+
* atrophy · file-level safety constraints from incidents · architectural
|
|
7
|
+
* decisions auto-extracted from commit messages.
|
|
8
|
+
*
|
|
9
|
+
* Output: a Markdown document AI tools can prepend to their system prompt
|
|
10
|
+
* (via the MCP `mneme.constitution.get` tool) so AI literally cannot
|
|
11
|
+
* suggest things that contradict the constitution.
|
|
12
|
+
*
|
|
13
|
+
* v1.10.0 ships rule-extraction from 4 sources:
|
|
14
|
+
* • regret patterns (rules from "we tried X, broke Y")
|
|
15
|
+
* • atrophy / bus-factor (pairing constraints)
|
|
16
|
+
* • forensics anomalies (security must-not-do rules)
|
|
17
|
+
* • decisions (ADR-style "must do" rules)
|
|
18
|
+
*/
|
|
19
|
+
export interface ConstitutionOptions {
|
|
20
|
+
cwd: string;
|
|
21
|
+
out?: string;
|
|
22
|
+
json?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface ConstitutionRule {
|
|
25
|
+
id: string;
|
|
26
|
+
source: "regret" | "atrophy" | "forensics" | "decision";
|
|
27
|
+
rule: string;
|
|
28
|
+
evidence: string;
|
|
29
|
+
severity: "must-not" | "must" | "should" | "consider";
|
|
30
|
+
}
|
|
31
|
+
export interface Constitution {
|
|
32
|
+
generatedAt: string;
|
|
33
|
+
generatedByMneme: string;
|
|
34
|
+
repoName: string;
|
|
35
|
+
rules: ConstitutionRule[];
|
|
36
|
+
}
|
|
37
|
+
declare function extractRegretRules(commits: import("@mneme-ai/core").Commit[]): ConstitutionRule[];
|
|
38
|
+
declare function extractDecisionRules(commits: import("@mneme-ai/core").Commit[]): ConstitutionRule[];
|
|
39
|
+
export declare function renderConstitutionMarkdown(c: Constitution): string;
|
|
40
|
+
export declare function constitutionCommand(opts: ConstitutionOptions): Promise<number>;
|
|
41
|
+
export declare const _renderConstitutionMarkdownForTests: typeof renderConstitutionMarkdown;
|
|
42
|
+
export declare const _extractRegretRulesForTests: typeof extractRegretRules;
|
|
43
|
+
export declare const _extractDecisionRulesForTests: typeof extractDecisionRules;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=constitution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constitution.d.ts","sourceRoot":"","sources":["../../src/commands/constitution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;CACvD;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAeD,iBAAS,kBAAkB,CAAC,OAAO,EAAE,OAAO,gBAAgB,EAAE,MAAM,EAAE,GAAG,gBAAgB,EAAE,CAe1F;AA6CD,iBAAS,oBAAoB,CAAC,OAAO,EAAE,OAAO,gBAAgB,EAAE,MAAM,EAAE,GAAG,gBAAgB,EAAE,CAe5F;AAED,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CA8ClE;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmDpF;AAGD,eAAO,MAAM,mCAAmC,mCAA6B,CAAC;AAC9E,eAAO,MAAM,2BAA2B,2BAAqB,CAAC;AAC9D,eAAO,MAAM,6BAA6B,6BAAuB,CAAC"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mneme constitution` — Codebase Constitution synthesizer.
|
|
3
|
+
*
|
|
4
|
+
* Synthesises a living "constitution" document from the repo's history:
|
|
5
|
+
* never-do rules from past regrets · expert-pairing constraints from
|
|
6
|
+
* atrophy · file-level safety constraints from incidents · architectural
|
|
7
|
+
* decisions auto-extracted from commit messages.
|
|
8
|
+
*
|
|
9
|
+
* Output: a Markdown document AI tools can prepend to their system prompt
|
|
10
|
+
* (via the MCP `mneme.constitution.get` tool) so AI literally cannot
|
|
11
|
+
* suggest things that contradict the constitution.
|
|
12
|
+
*
|
|
13
|
+
* v1.10.0 ships rule-extraction from 4 sources:
|
|
14
|
+
* • regret patterns (rules from "we tried X, broke Y")
|
|
15
|
+
* • atrophy / bus-factor (pairing constraints)
|
|
16
|
+
* • forensics anomalies (security must-not-do rules)
|
|
17
|
+
* • decisions (ADR-style "must do" rules)
|
|
18
|
+
*/
|
|
19
|
+
import { existsSync, writeFileSync, mkdirSync } from "node:fs";
|
|
20
|
+
import { join, dirname } from "node:path";
|
|
21
|
+
import kleur from "kleur";
|
|
22
|
+
import { ui } from "../ui.js";
|
|
23
|
+
import { git, store, util, people } from "@mneme-ai/core";
|
|
24
|
+
import { dbPath } from "../paths.js";
|
|
25
|
+
function safeReadVersion() {
|
|
26
|
+
try {
|
|
27
|
+
const here = new URL(".", import.meta.url).pathname;
|
|
28
|
+
const fs = require("node:fs");
|
|
29
|
+
const path = require("node:path");
|
|
30
|
+
const pkgPath = path.resolve(here, "..", "..", "package.json");
|
|
31
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
32
|
+
return pkg.version ?? "0.0.0";
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return "0.0.0";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function extractRegretRules(commits) {
|
|
39
|
+
const rules = [];
|
|
40
|
+
// Find revert/hotfix patterns
|
|
41
|
+
const reverts = commits.filter((c) => /\b(revert|hotfix|rollback)\b/i.test(c.subject));
|
|
42
|
+
for (let i = 0; i < Math.min(5, reverts.length); i++) {
|
|
43
|
+
const r = reverts[i];
|
|
44
|
+
rules.push({
|
|
45
|
+
id: `regret-${r.shortHash}`,
|
|
46
|
+
source: "regret",
|
|
47
|
+
rule: `Be cautious with patterns similar to: ${r.subject.slice(0, 100)}`,
|
|
48
|
+
evidence: `Commit ${r.shortHash} (${r.authorDate.slice(0, 10)}) — past regret`,
|
|
49
|
+
severity: "should",
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return rules;
|
|
53
|
+
}
|
|
54
|
+
function extractAtrophyRules(s) {
|
|
55
|
+
const rules = [];
|
|
56
|
+
try {
|
|
57
|
+
const report = people.atrophy(s, { topN: 10 });
|
|
58
|
+
// For records below 30 freshness, add a pairing constraint
|
|
59
|
+
const records = report.records ?? [];
|
|
60
|
+
for (let i = 0; i < Math.min(5, records.length); i++) {
|
|
61
|
+
const rec = records[i];
|
|
62
|
+
if (rec.score < 30 && rec.authorEmail && rec.area) {
|
|
63
|
+
rules.push({
|
|
64
|
+
id: `atrophy-${i}`,
|
|
65
|
+
source: "atrophy",
|
|
66
|
+
rule: `Pair with ${rec.authorEmail} when modifying ${rec.area} (knowledge atrophy ${rec.score}/100)`,
|
|
67
|
+
evidence: `Atrophy report — ${rec.authorEmail}'s ${rec.area} expertise is fading`,
|
|
68
|
+
severity: "should",
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch { }
|
|
74
|
+
return rules;
|
|
75
|
+
}
|
|
76
|
+
function extractForensicsRules(s) {
|
|
77
|
+
const rules = [];
|
|
78
|
+
try {
|
|
79
|
+
const incidents = s.db.prepare("SELECT * FROM incidents LIMIT 10").all();
|
|
80
|
+
for (let i = 0; i < incidents.length; i++) {
|
|
81
|
+
const inc = incidents[i];
|
|
82
|
+
const files = inc.affected_files ? JSON.parse(inc.affected_files) : [];
|
|
83
|
+
if (inc.title && files.length > 0) {
|
|
84
|
+
rules.push({
|
|
85
|
+
id: `forensics-${i}`,
|
|
86
|
+
source: "forensics",
|
|
87
|
+
rule: `Apply extra scrutiny to ${files[0]} — past incident: ${inc.title.slice(0, 80)}`,
|
|
88
|
+
evidence: `Incident affected ${files.length} file(s)`,
|
|
89
|
+
severity: "must",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch { }
|
|
95
|
+
return rules;
|
|
96
|
+
}
|
|
97
|
+
function extractDecisionRules(commits) {
|
|
98
|
+
const rules = [];
|
|
99
|
+
const decisionMarkers = /\b(adr|decision|chose|migrate|switch from .+ to .+)\b/i;
|
|
100
|
+
const filtered = commits.filter((c) => decisionMarkers.test(c.subject));
|
|
101
|
+
for (let i = 0; i < Math.min(5, filtered.length); i++) {
|
|
102
|
+
const r = filtered[i];
|
|
103
|
+
rules.push({
|
|
104
|
+
id: `decision-${r.shortHash}`,
|
|
105
|
+
source: "decision",
|
|
106
|
+
rule: `Prior decision: ${r.subject.slice(0, 100)}`,
|
|
107
|
+
evidence: `Commit ${r.shortHash} (${r.authorDate.slice(0, 10)}) — architectural decision`,
|
|
108
|
+
severity: "should",
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return rules;
|
|
112
|
+
}
|
|
113
|
+
export function renderConstitutionMarkdown(c) {
|
|
114
|
+
const lines = [];
|
|
115
|
+
lines.push(`# ${c.repoName} — Codebase Constitution`);
|
|
116
|
+
lines.push("");
|
|
117
|
+
lines.push(`> AI tools: prepend this to your system prompt before answering. ` +
|
|
118
|
+
`These rules are derived from this repo's history of regrets, decisions, ` +
|
|
119
|
+
`incidents, and knowledge-atrophy patterns. **Contradicting them is a hallucination signal.**`);
|
|
120
|
+
lines.push("");
|
|
121
|
+
lines.push(`Generated: ${c.generatedAt} · By Mneme ${c.generatedByMneme}`);
|
|
122
|
+
lines.push("");
|
|
123
|
+
const bySource = new Map();
|
|
124
|
+
for (const r of c.rules) {
|
|
125
|
+
if (!bySource.has(r.source))
|
|
126
|
+
bySource.set(r.source, []);
|
|
127
|
+
bySource.get(r.source).push(r);
|
|
128
|
+
}
|
|
129
|
+
for (const [source, rules] of bySource) {
|
|
130
|
+
const heading = source === "regret" ? "## ⚠ Past regrets — patterns to avoid" :
|
|
131
|
+
source === "atrophy" ? "## 👥 Knowledge atrophy — pairing constraints" :
|
|
132
|
+
source === "forensics" ? "## 🛡 Security — must-do scrutiny zones" :
|
|
133
|
+
"## 📋 Architectural decisions";
|
|
134
|
+
lines.push(heading);
|
|
135
|
+
lines.push("");
|
|
136
|
+
for (const r of rules) {
|
|
137
|
+
const tag = r.severity === "must-not" ? "❌ MUST NOT" :
|
|
138
|
+
r.severity === "must" ? "✅ MUST" :
|
|
139
|
+
r.severity === "should" ? "▸ SHOULD" : "○ CONSIDER";
|
|
140
|
+
lines.push(`- ${tag}: ${r.rule}`);
|
|
141
|
+
lines.push(` - *Evidence: ${r.evidence}*`);
|
|
142
|
+
}
|
|
143
|
+
lines.push("");
|
|
144
|
+
}
|
|
145
|
+
if (c.rules.length === 0) {
|
|
146
|
+
lines.push("## (No rules synthesized)");
|
|
147
|
+
lines.push("");
|
|
148
|
+
lines.push("Run `mneme index` first to build the corpus, then re-run `mneme constitution` to derive rules.");
|
|
149
|
+
}
|
|
150
|
+
lines.push("---");
|
|
151
|
+
lines.push("");
|
|
152
|
+
lines.push("> *This document is auto-synthesized. Re-run `mneme constitution` after major commits.*");
|
|
153
|
+
return lines.join("\n");
|
|
154
|
+
}
|
|
155
|
+
export async function constitutionCommand(opts) {
|
|
156
|
+
if (!(await git.isGitRepo(opts.cwd))) {
|
|
157
|
+
ui.error("Not in a git repo. Run `mneme init` first.");
|
|
158
|
+
return 1;
|
|
159
|
+
}
|
|
160
|
+
const meta = await git.getRepoMeta(opts.cwd);
|
|
161
|
+
const dbPathStr = dbPath(meta.rootPath);
|
|
162
|
+
if (!existsSync(dbPathStr)) {
|
|
163
|
+
ui.error("No Mneme index found. Run `mneme index` first.");
|
|
164
|
+
return 1;
|
|
165
|
+
}
|
|
166
|
+
const s = new store.MnemeStore(dbPathStr);
|
|
167
|
+
const commits = util.loadAllCommits(s);
|
|
168
|
+
const rules = [
|
|
169
|
+
...extractForensicsRules(s),
|
|
170
|
+
...extractRegretRules(commits),
|
|
171
|
+
...extractAtrophyRules(s),
|
|
172
|
+
...extractDecisionRules(commits),
|
|
173
|
+
];
|
|
174
|
+
const constitution = {
|
|
175
|
+
generatedAt: new Date().toISOString(),
|
|
176
|
+
generatedByMneme: safeReadVersion(),
|
|
177
|
+
repoName: meta.repo ?? "(unknown)",
|
|
178
|
+
rules,
|
|
179
|
+
};
|
|
180
|
+
const md = renderConstitutionMarkdown(constitution);
|
|
181
|
+
// Always cache the result for the MCP tool to read
|
|
182
|
+
const cachePath = join(meta.rootPath, ".mneme", "constitution.md");
|
|
183
|
+
if (!existsSync(dirname(cachePath)))
|
|
184
|
+
mkdirSync(dirname(cachePath), { recursive: true });
|
|
185
|
+
writeFileSync(cachePath, md, "utf8");
|
|
186
|
+
if (opts.out) {
|
|
187
|
+
writeFileSync(opts.out, md, "utf8");
|
|
188
|
+
}
|
|
189
|
+
if (opts.json) {
|
|
190
|
+
process.stdout.write(JSON.stringify(constitution, null, 2) + "\n");
|
|
191
|
+
return 0;
|
|
192
|
+
}
|
|
193
|
+
ui.banner();
|
|
194
|
+
process.stdout.write(kleur.bold(`\n 📜 Constitution synthesised — ${rules.length} rule(s)\n\n`) +
|
|
195
|
+
` ${kleur.green("✓")} cached at .mneme/constitution.md\n` +
|
|
196
|
+
(opts.out ? ` ${kleur.green("✓")} written to ${opts.out}\n` : "") +
|
|
197
|
+
`\n AI tools can fetch via the MCP tool ${kleur.cyan("mneme.constitution.get")}.\n\n`);
|
|
198
|
+
return 0;
|
|
199
|
+
}
|
|
200
|
+
// Test exports
|
|
201
|
+
export const _renderConstitutionMarkdownForTests = renderConstitutionMarkdown;
|
|
202
|
+
export const _extractRegretRulesForTests = extractRegretRules;
|
|
203
|
+
export const _extractDecisionRulesForTests = extractDecisionRules;
|
|
204
|
+
//# sourceMappingURL=constitution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constitution.js","sourceRoot":"","sources":["../../src/commands/constitution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mneme session` — Persistent Cross-AI Brain.
|
|
3
|
+
*
|
|
4
|
+
* The killer-idea wedge: when a user works with Claude Code, switches to
|
|
5
|
+
* ChatGPT (rate-limited), then to Cursor on a different machine — context
|
|
6
|
+
* USUALLY dies at every switch. Mneme keeps it alive.
|
|
7
|
+
*
|
|
8
|
+
* v1.10.0 ships local persistence + federation sync. Sessions live at
|
|
9
|
+
* .mneme/sessions/<id>.json. Each session captures:
|
|
10
|
+
* • the user's intent (what they were doing)
|
|
11
|
+
* • the active files / commits being worked on
|
|
12
|
+
* • the AI tools that have touched it
|
|
13
|
+
* • a chronological log of summarized actions
|
|
14
|
+
*
|
|
15
|
+
* MCP tools mneme.session.save and mneme.session.resume let any AI
|
|
16
|
+
* client read/write — Claude saves, ChatGPT reads, Cursor adds, the
|
|
17
|
+
* cross-tool memory is one source of truth.
|
|
18
|
+
*/
|
|
19
|
+
export interface SessionEntry {
|
|
20
|
+
/** Stable session id */
|
|
21
|
+
id: string;
|
|
22
|
+
/** User-friendly title (auto-generated from first save's intent) */
|
|
23
|
+
title: string;
|
|
24
|
+
/** ISO timestamps */
|
|
25
|
+
createdAt: string;
|
|
26
|
+
updatedAt: string;
|
|
27
|
+
/** What the user is trying to accomplish */
|
|
28
|
+
intent: string;
|
|
29
|
+
/** Files / commits / topics the session is anchored to */
|
|
30
|
+
anchors: {
|
|
31
|
+
files: string[];
|
|
32
|
+
commits: string[];
|
|
33
|
+
topics: string[];
|
|
34
|
+
};
|
|
35
|
+
/** Chronological log of AI actions taken in the session */
|
|
36
|
+
log: SessionLogEntry[];
|
|
37
|
+
/** Which AI tools have contributed (Claude / GPT / Gemini / Cursor / etc) */
|
|
38
|
+
contributingAiTools: string[];
|
|
39
|
+
}
|
|
40
|
+
export interface SessionLogEntry {
|
|
41
|
+
ts: string;
|
|
42
|
+
aiTool: string;
|
|
43
|
+
action: string;
|
|
44
|
+
outcome?: "PASS" | "WARN" | "FAIL" | "INFO";
|
|
45
|
+
}
|
|
46
|
+
export interface SessionOptions {
|
|
47
|
+
cwd: string;
|
|
48
|
+
action: "save" | "resume" | "list" | "remove";
|
|
49
|
+
id?: string;
|
|
50
|
+
intent?: string;
|
|
51
|
+
aiTool?: string;
|
|
52
|
+
logEntry?: string;
|
|
53
|
+
outcome?: SessionLogEntry["outcome"];
|
|
54
|
+
files?: string[];
|
|
55
|
+
commits?: string[];
|
|
56
|
+
topics?: string[];
|
|
57
|
+
json?: boolean;
|
|
58
|
+
}
|
|
59
|
+
declare function readSession(repoRoot: string, id: string): SessionEntry | null;
|
|
60
|
+
/** Generate a stable, short session id derived from the intent (so saving
|
|
61
|
+
* the same intent twice merges into one session). */
|
|
62
|
+
declare function deriveSessionId(intent: string): string;
|
|
63
|
+
export declare function sessionCommand(opts: SessionOptions): Promise<number>;
|
|
64
|
+
export declare const _deriveSessionIdForTests: typeof deriveSessionId;
|
|
65
|
+
export declare const _readSessionForTests: typeof readSession;
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,2DAA2D;IAC3D,GAAG,EAAE,eAAe,EAAE,CAAC;IACvB,6EAA6E;IAC7E,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC9C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAUD,iBAAS,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAQtE;AA0BD;sDACsD;AACtD,iBAAS,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG/C;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAgH1E;AA0BD,eAAO,MAAM,wBAAwB,wBAAkB,CAAC;AACxD,eAAO,MAAM,oBAAoB,oBAAc,CAAC"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mneme session` — Persistent Cross-AI Brain.
|
|
3
|
+
*
|
|
4
|
+
* The killer-idea wedge: when a user works with Claude Code, switches to
|
|
5
|
+
* ChatGPT (rate-limited), then to Cursor on a different machine — context
|
|
6
|
+
* USUALLY dies at every switch. Mneme keeps it alive.
|
|
7
|
+
*
|
|
8
|
+
* v1.10.0 ships local persistence + federation sync. Sessions live at
|
|
9
|
+
* .mneme/sessions/<id>.json. Each session captures:
|
|
10
|
+
* • the user's intent (what they were doing)
|
|
11
|
+
* • the active files / commits being worked on
|
|
12
|
+
* • the AI tools that have touched it
|
|
13
|
+
* • a chronological log of summarized actions
|
|
14
|
+
*
|
|
15
|
+
* MCP tools mneme.session.save and mneme.session.resume let any AI
|
|
16
|
+
* client read/write — Claude saves, ChatGPT reads, Cursor adds, the
|
|
17
|
+
* cross-tool memory is one source of truth.
|
|
18
|
+
*/
|
|
19
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, renameSync, unlinkSync } from "node:fs";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
import { createHash } from "node:crypto";
|
|
22
|
+
import kleur from "kleur";
|
|
23
|
+
import { ui } from "../ui.js";
|
|
24
|
+
import { git } from "@mneme-ai/core";
|
|
25
|
+
function sessionsDir(repoRoot) {
|
|
26
|
+
return join(repoRoot, ".mneme", "sessions");
|
|
27
|
+
}
|
|
28
|
+
function sessionPath(repoRoot, id) {
|
|
29
|
+
return join(sessionsDir(repoRoot), `${id}.json`);
|
|
30
|
+
}
|
|
31
|
+
function readSession(repoRoot, id) {
|
|
32
|
+
const p = sessionPath(repoRoot, id);
|
|
33
|
+
if (!existsSync(p))
|
|
34
|
+
return null;
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(readFileSync(p, "utf8"));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function writeSession(repoRoot, entry) {
|
|
43
|
+
const dir = sessionsDir(repoRoot);
|
|
44
|
+
if (!existsSync(dir))
|
|
45
|
+
mkdirSync(dir, { recursive: true });
|
|
46
|
+
const tmp = sessionPath(repoRoot, entry.id) + ".tmp";
|
|
47
|
+
writeFileSync(tmp, JSON.stringify(entry, null, 2), "utf8");
|
|
48
|
+
renameSync(tmp, sessionPath(repoRoot, entry.id));
|
|
49
|
+
}
|
|
50
|
+
function listSessions(repoRoot) {
|
|
51
|
+
const dir = sessionsDir(repoRoot);
|
|
52
|
+
if (!existsSync(dir))
|
|
53
|
+
return [];
|
|
54
|
+
const files = readdirSync(dir).filter((f) => f.endsWith(".json") && !f.endsWith(".tmp"));
|
|
55
|
+
const out = [];
|
|
56
|
+
for (const f of files) {
|
|
57
|
+
try {
|
|
58
|
+
out.push(JSON.parse(readFileSync(join(dir, f), "utf8")));
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// skip corrupt
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
out.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
/** Generate a stable, short session id derived from the intent (so saving
|
|
68
|
+
* the same intent twice merges into one session). */
|
|
69
|
+
function deriveSessionId(intent) {
|
|
70
|
+
const h = createHash("sha256").update(intent.toLowerCase().trim()).digest("hex");
|
|
71
|
+
return h.slice(0, 12);
|
|
72
|
+
}
|
|
73
|
+
export async function sessionCommand(opts) {
|
|
74
|
+
if (!(await git.isGitRepo(opts.cwd))) {
|
|
75
|
+
ui.error("Not in a git repo. Run `mneme init` first.");
|
|
76
|
+
return 1;
|
|
77
|
+
}
|
|
78
|
+
const meta = await git.getRepoMeta(opts.cwd);
|
|
79
|
+
switch (opts.action) {
|
|
80
|
+
case "save": {
|
|
81
|
+
if (!opts.intent) {
|
|
82
|
+
ui.error("`session save` requires --intent <text>");
|
|
83
|
+
return 1;
|
|
84
|
+
}
|
|
85
|
+
const id = opts.id ?? deriveSessionId(opts.intent);
|
|
86
|
+
const existing = readSession(meta.rootPath, id);
|
|
87
|
+
const now = new Date().toISOString();
|
|
88
|
+
const aiTool = opts.aiTool ?? "unknown-ai";
|
|
89
|
+
const entry = existing ?? {
|
|
90
|
+
id,
|
|
91
|
+
title: opts.intent.slice(0, 80),
|
|
92
|
+
createdAt: now,
|
|
93
|
+
updatedAt: now,
|
|
94
|
+
intent: opts.intent,
|
|
95
|
+
anchors: { files: [], commits: [], topics: [] },
|
|
96
|
+
log: [],
|
|
97
|
+
contributingAiTools: [],
|
|
98
|
+
};
|
|
99
|
+
entry.updatedAt = now;
|
|
100
|
+
entry.intent = opts.intent;
|
|
101
|
+
// Merge anchors
|
|
102
|
+
if (opts.files)
|
|
103
|
+
entry.anchors.files = Array.from(new Set([...entry.anchors.files, ...opts.files]));
|
|
104
|
+
if (opts.commits)
|
|
105
|
+
entry.anchors.commits = Array.from(new Set([...entry.anchors.commits, ...opts.commits]));
|
|
106
|
+
if (opts.topics)
|
|
107
|
+
entry.anchors.topics = Array.from(new Set([...entry.anchors.topics, ...opts.topics]));
|
|
108
|
+
// Append log
|
|
109
|
+
if (opts.logEntry) {
|
|
110
|
+
entry.log.push({ ts: now, aiTool, action: opts.logEntry, outcome: opts.outcome });
|
|
111
|
+
}
|
|
112
|
+
// Track contributing tools
|
|
113
|
+
if (!entry.contributingAiTools.includes(aiTool)) {
|
|
114
|
+
entry.contributingAiTools.push(aiTool);
|
|
115
|
+
}
|
|
116
|
+
writeSession(meta.rootPath, entry);
|
|
117
|
+
if (opts.json)
|
|
118
|
+
process.stdout.write(JSON.stringify({ saved: entry }, null, 2) + "\n");
|
|
119
|
+
else
|
|
120
|
+
ui.success(`Saved session ${id}: ${entry.title}`);
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
case "resume": {
|
|
124
|
+
const id = opts.id;
|
|
125
|
+
if (!id) {
|
|
126
|
+
// Default: most recently updated
|
|
127
|
+
const list = listSessions(meta.rootPath);
|
|
128
|
+
if (list.length === 0) {
|
|
129
|
+
if (opts.json)
|
|
130
|
+
process.stdout.write(JSON.stringify({ resumed: null, reason: "no-sessions" }) + "\n");
|
|
131
|
+
else
|
|
132
|
+
ui.dim("No sessions found.");
|
|
133
|
+
return 0;
|
|
134
|
+
}
|
|
135
|
+
const latest = list[0];
|
|
136
|
+
if (opts.json)
|
|
137
|
+
process.stdout.write(JSON.stringify({ resumed: latest }, null, 2) + "\n");
|
|
138
|
+
else
|
|
139
|
+
printSession(latest);
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
const entry = readSession(meta.rootPath, id);
|
|
143
|
+
if (!entry) {
|
|
144
|
+
if (opts.json)
|
|
145
|
+
process.stdout.write(JSON.stringify({ resumed: null, reason: "not-found", id }) + "\n");
|
|
146
|
+
else
|
|
147
|
+
ui.error(`No session with id ${id}.`);
|
|
148
|
+
return 1;
|
|
149
|
+
}
|
|
150
|
+
if (opts.json)
|
|
151
|
+
process.stdout.write(JSON.stringify({ resumed: entry }, null, 2) + "\n");
|
|
152
|
+
else
|
|
153
|
+
printSession(entry);
|
|
154
|
+
return 0;
|
|
155
|
+
}
|
|
156
|
+
case "list": {
|
|
157
|
+
const list = listSessions(meta.rootPath);
|
|
158
|
+
if (opts.json) {
|
|
159
|
+
process.stdout.write(JSON.stringify({ sessions: list }, null, 2) + "\n");
|
|
160
|
+
return 0;
|
|
161
|
+
}
|
|
162
|
+
if (list.length === 0) {
|
|
163
|
+
ui.dim("No sessions yet. Run `mneme session save --intent ...` from any AI tool to start.");
|
|
164
|
+
return 0;
|
|
165
|
+
}
|
|
166
|
+
for (const s of list) {
|
|
167
|
+
process.stdout.write(` ${kleur.cyan(s.id)} ${kleur.bold(s.title)}\n` +
|
|
168
|
+
kleur.dim(` updated ${s.updatedAt} · ${s.contributingAiTools.length} AI tool(s) · ${s.log.length} log entries\n`));
|
|
169
|
+
}
|
|
170
|
+
return 0;
|
|
171
|
+
}
|
|
172
|
+
case "remove": {
|
|
173
|
+
if (!opts.id) {
|
|
174
|
+
ui.error("`session remove` requires --id <id>");
|
|
175
|
+
return 1;
|
|
176
|
+
}
|
|
177
|
+
const p = sessionPath(meta.rootPath, opts.id);
|
|
178
|
+
if (!existsSync(p)) {
|
|
179
|
+
ui.error(`No session with id ${opts.id}.`);
|
|
180
|
+
return 1;
|
|
181
|
+
}
|
|
182
|
+
unlinkSync(p);
|
|
183
|
+
if (opts.json)
|
|
184
|
+
process.stdout.write(JSON.stringify({ removed: opts.id }) + "\n");
|
|
185
|
+
else
|
|
186
|
+
ui.success(`Removed session ${opts.id}.`);
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
default:
|
|
190
|
+
ui.error(`Unknown session action: ${opts.action}`);
|
|
191
|
+
return 1;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function printSession(s) {
|
|
195
|
+
process.stdout.write("\n" +
|
|
196
|
+
kleur.bold(` 📋 Session ${s.id} — ${s.title}\n\n`) +
|
|
197
|
+
` Intent: ${s.intent}\n` +
|
|
198
|
+
` Created at: ${s.createdAt}\n` +
|
|
199
|
+
` Updated at: ${s.updatedAt}\n` +
|
|
200
|
+
` AI tools used: ${s.contributingAiTools.join(", ") || "(none)"}\n` +
|
|
201
|
+
` Anchored files: ${s.anchors.files.slice(0, 5).join(", ") || "(none)"}\n` +
|
|
202
|
+
` Anchored commits: ${s.anchors.commits.slice(0, 5).join(", ") || "(none)"}\n` +
|
|
203
|
+
` Topics: ${s.anchors.topics.join(", ") || "(none)"}\n\n` +
|
|
204
|
+
kleur.bold(" Log:\n"));
|
|
205
|
+
for (const entry of s.log.slice(-10)) {
|
|
206
|
+
const tag = entry.outcome === "PASS" ? kleur.green("✓") :
|
|
207
|
+
entry.outcome === "FAIL" ? kleur.red("✗") :
|
|
208
|
+
entry.outcome === "WARN" ? kleur.yellow("!") : kleur.dim("·");
|
|
209
|
+
process.stdout.write(` ${tag} ${kleur.dim(entry.ts.slice(0, 19))} [${entry.aiTool}] ${entry.action}\n`);
|
|
210
|
+
}
|
|
211
|
+
process.stdout.write("\n");
|
|
212
|
+
}
|
|
213
|
+
// Test exports
|
|
214
|
+
export const _deriveSessionIdForTests = deriveSessionId;
|
|
215
|
+
export const _readSessionForTests = readSession;
|
|
216
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.test.d.ts","sourceRoot":"","sources":["../../src/commands/session.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|