@mneme-ai/core 1.71.0 → 1.72.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,229 @@
1
+ /**
2
+ * v1.72.0 -- DIASPORA D4: HTTP BRIDGE + OPENAPI for ChatGPT.
3
+ *
4
+ * The headline new surface: `mneme serve --http` exposes a minimal
5
+ * HTTP API that ANY tool with HTTP-call capability (ChatGPT Custom
6
+ * GPT Actions, Zapier, n8n, etc) can hit. Includes:
7
+ *
8
+ * POST /v1/precog intercept claim (PRECOG firewall)
9
+ * POST /v1/sentinel intercept shell command (SENTINEL firewall)
10
+ * POST /v1/apoptosis detect hallucination (APOPTOSIS)
11
+ * GET /v1/openapi.json OpenAPI 3.1 spec (for Custom GPT import)
12
+ * GET /v1/health liveness probe
13
+ *
14
+ * SAFETY:
15
+ * - Binds 127.0.0.1 by default (localhost only). User opts into
16
+ * 0.0.0.0 with explicit --host flag.
17
+ * - Bearer token auth via .mneme/http-token (random per-repo).
18
+ * - Per-IP rate limit (60 req/min).
19
+ * - CORS allowed only for chat.openai.com + custom origin list.
20
+ *
21
+ * NO CLOUD REQUIRED: works on localhost via tunnel (Cloudflare /
22
+ * ngrok / fly.io) -- user chooses their tunnel provider. The bridge
23
+ * itself is local-first.
24
+ */
25
+ import { createServer } from "node:http";
26
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
27
+ import { join } from "node:path";
28
+ import { randomBytes, timingSafeEqual } from "node:crypto";
29
+ const TOKEN_FILE = ".mneme/http-token";
30
+ const ALLOWED_ORIGINS = ["https://chat.openai.com", "https://chatgpt.com"];
31
+ function ensureToken(repoRoot) {
32
+ const p = join(repoRoot, TOKEN_FILE);
33
+ if (existsSync(p))
34
+ return readFileSync(p, "utf8").trim();
35
+ const dir = join(repoRoot, ".mneme");
36
+ if (!existsSync(dir))
37
+ mkdirSync(dir, { recursive: true });
38
+ const t = "mneme_" + randomBytes(24).toString("base64url");
39
+ writeFileSync(p, t, "utf8");
40
+ return t;
41
+ }
42
+ const rateLimiter = new Map();
43
+ function checkRateLimit(ip, perMinute = 60) {
44
+ const now = Date.now();
45
+ const window = 60_000;
46
+ const e = rateLimiter.get(ip);
47
+ if (!e || now - e.windowStart > window) {
48
+ rateLimiter.set(ip, { count: 1, windowStart: now });
49
+ return true;
50
+ }
51
+ if (e.count >= perMinute)
52
+ return false;
53
+ e.count += 1;
54
+ return true;
55
+ }
56
+ function isAuthorized(req, token) {
57
+ const auth = req.headers["authorization"] ?? "";
58
+ const m = /^Bearer\s+(.+)$/i.exec(auth);
59
+ if (!m)
60
+ return false;
61
+ const provided = m[1];
62
+ if (provided.length !== token.length)
63
+ return false;
64
+ try {
65
+ return timingSafeEqual(Buffer.from(provided), Buffer.from(token));
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ }
71
+ async function readJsonBody(req) {
72
+ return new Promise((resolve, reject) => {
73
+ let data = "";
74
+ req.on("data", (chunk) => { data += chunk; if (data.length > 65536) {
75
+ req.destroy();
76
+ reject(new Error("payload too large"));
77
+ } });
78
+ req.on("end", () => { try {
79
+ resolve(data ? JSON.parse(data) : {});
80
+ }
81
+ catch (e) {
82
+ reject(e);
83
+ } });
84
+ req.on("error", reject);
85
+ });
86
+ }
87
+ function setCors(req, res, customOrigins = []) {
88
+ const origin = req.headers.origin ?? "";
89
+ const allow = [...ALLOWED_ORIGINS, ...customOrigins].includes(origin);
90
+ if (allow)
91
+ res.setHeader("Access-Control-Allow-Origin", origin);
92
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
93
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
94
+ }
95
+ function json(res, status, body) {
96
+ res.statusCode = status;
97
+ res.setHeader("Content-Type", "application/json");
98
+ res.end(JSON.stringify(body));
99
+ }
100
+ export function openapiSpec(baseUrl) {
101
+ return {
102
+ openapi: "3.1.0",
103
+ info: {
104
+ title: "Mneme MCP Bridge",
105
+ version: "1.72.0",
106
+ description: "Local Mneme PRECOG / SENTINEL / APOPTOSIS surfaces over HTTP. AI tools (Custom GPT, Zapier, n8n) call these to verify claims + commands before delivery.",
107
+ },
108
+ servers: [{ url: baseUrl }],
109
+ components: {
110
+ securitySchemes: {
111
+ BearerAuth: { type: "http", scheme: "bearer" },
112
+ },
113
+ },
114
+ security: [{ BearerAuth: [] }],
115
+ paths: {
116
+ "/v1/health": {
117
+ get: {
118
+ operationId: "health",
119
+ summary: "Liveness probe",
120
+ responses: { "200": { description: "OK" } },
121
+ },
122
+ },
123
+ "/v1/precog": {
124
+ post: {
125
+ operationId: "precogIntercept",
126
+ summary: "Run PRECOG firewall on an AI claim. Returns CERTIFIED / HEDGED / REJECTED + the verified (hedged) string.",
127
+ requestBody: {
128
+ required: true,
129
+ content: { "application/json": { schema: { type: "object", required: ["claim"], properties: { claim: { type: "string" } } } } },
130
+ },
131
+ responses: { "200": { description: "Firewall verdict + hedged claim", content: { "application/json": { schema: { type: "object" } } } } },
132
+ },
133
+ },
134
+ "/v1/sentinel": {
135
+ post: {
136
+ operationId: "sentinelIntercept",
137
+ summary: "Run SENTINEL firewall on a proposed shell command. Returns ALLOW / AUDIT / WARN / BLOCK + reasoning.",
138
+ requestBody: {
139
+ required: true,
140
+ content: { "application/json": { schema: { type: "object", required: ["command"], properties: { command: { type: "string" }, vendor: { type: "string" } } } } },
141
+ },
142
+ responses: { "200": { description: "Sentinel decision + audit", content: { "application/json": { schema: { type: "object" } } } } },
143
+ },
144
+ },
145
+ "/v1/apoptosis": {
146
+ post: {
147
+ operationId: "apoptosisDetect",
148
+ summary: "Run APOPTOSIS 7-layer hallucination detector. Returns HEALTHY / INFLAMED / NECROTIC / APOPTOTIC verdict + per-layer report.",
149
+ requestBody: {
150
+ required: true,
151
+ content: { "application/json": { schema: { type: "object", required: ["claim"], properties: { claim: { type: "string" } } } } },
152
+ },
153
+ responses: { "200": { description: "Apoptosis verdict + briefing", content: { "application/json": { schema: { type: "object" } } } } },
154
+ },
155
+ },
156
+ },
157
+ };
158
+ }
159
+ /** Start the HTTP bridge. Returns a handle the caller stops on shutdown. */
160
+ export async function startBridge(opts, handlers) {
161
+ const port = opts.port ?? 11434;
162
+ const host = opts.host ?? "127.0.0.1";
163
+ const token = opts.noAuth ? "" : ensureToken(opts.repoRoot);
164
+ const baseUrl = `http://${host}:${port}`;
165
+ const server = createServer(async (req, res) => {
166
+ const ip = req.socket.remoteAddress ?? "unknown";
167
+ if (!checkRateLimit(ip))
168
+ return json(res, 429, { error: "rate-limited" });
169
+ setCors(req, res, opts.extraCorsOrigins);
170
+ if (req.method === "OPTIONS") {
171
+ res.statusCode = 204;
172
+ return res.end();
173
+ }
174
+ if (req.url === "/v1/health" && req.method === "GET") {
175
+ return json(res, 200, { ok: true, version: "1.72.0", protocols: ["precog", "sentinel", "apoptosis"] });
176
+ }
177
+ if (req.url === "/v1/openapi.json" && req.method === "GET") {
178
+ return json(res, 200, openapiSpec(baseUrl));
179
+ }
180
+ // Auth required for non-health, non-openapi endpoints.
181
+ if (!opts.noAuth && !isAuthorized(req, token)) {
182
+ return json(res, 401, { error: "unauthorized -- set Authorization: Bearer <token>" });
183
+ }
184
+ try {
185
+ if (req.url === "/v1/precog" && req.method === "POST" && handlers.precog) {
186
+ const body = await readJsonBody(req);
187
+ if (typeof body.claim !== "string")
188
+ return json(res, 400, { error: "claim field required" });
189
+ const r = await handlers.precog(body.claim);
190
+ return json(res, 200, r);
191
+ }
192
+ if (req.url === "/v1/sentinel" && req.method === "POST" && handlers.sentinel) {
193
+ const body = await readJsonBody(req);
194
+ if (typeof body.command !== "string")
195
+ return json(res, 400, { error: "command field required" });
196
+ const r = await handlers.sentinel(body.command, body.vendor);
197
+ return json(res, 200, r);
198
+ }
199
+ if (req.url === "/v1/apoptosis" && req.method === "POST" && handlers.apoptosis) {
200
+ const body = await readJsonBody(req);
201
+ if (typeof body.claim !== "string")
202
+ return json(res, 400, { error: "claim field required" });
203
+ const r = await handlers.apoptosis(body.claim);
204
+ return json(res, 200, r);
205
+ }
206
+ }
207
+ catch (e) {
208
+ return json(res, 500, { error: e.message });
209
+ }
210
+ return json(res, 404, { error: "not found" });
211
+ });
212
+ await new Promise((resolve) => server.listen(port, host, resolve));
213
+ const stop = async () => {
214
+ await new Promise((resolve) => server.close(() => resolve()));
215
+ };
216
+ return { server, port, host, token, baseUrl, stop };
217
+ }
218
+ /** Custom GPT template -- printed to user; they upload this JSON into the
219
+ * Custom GPT "Actions" config. */
220
+ export function customGptTemplate(baseUrl, token) {
221
+ return JSON.stringify({
222
+ name: "Mneme Bridge",
223
+ description: "Run claims through Mneme's PRECOG / SENTINEL / APOPTOSIS firewalls before delivering to the user.",
224
+ instructions: "Before answering any factual question about code, repos, or commands, POST the AI's draft answer to /v1/precog. If verdict is CERTIFIED, deliver. If HEDGED, deliver the hedged version. If REJECTED, refuse + explain. Before suggesting any shell command, POST it to /v1/sentinel; only execute on ALLOW or AUDIT.",
225
+ authentication: { type: "bearer", token },
226
+ actionEndpoint: `${baseUrl}/v1/openapi.json`,
227
+ }, null, 2);
228
+ }
229
+ //# sourceMappingURL=http_bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http_bridge.js","sourceRoot":"","sources":["../../src/diaspora/http_bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * v1.72.0 -- DIASPORA PROTOCOL.
3
+ *
4
+ * Four wild axes that crack open the cross-machine + cross-vendor +
5
+ * cross-app barriers that kept Mneme local:
6
+ *
7
+ * D1 GHOST SNIPER GITIGNORE auto-append AI-tooling artifacts
8
+ * on every inject (privacy-leak-proof)
9
+ * D2 SPORE DEFAULT-ON git remote detected -> auto-enable
10
+ * cross-machine sync (no manual opt-in)
11
+ * D3 PORTABLE SESSION CAPSULE vendor A saves; vendor B resumes.
12
+ * HMAC-signed; soul-mirror records the
13
+ * inheritance event.
14
+ * D4 HTTP BRIDGE localhost HTTP API + OpenAPI 3.1
15
+ * spec + Custom GPT template. ChatGPT
16
+ * Custom GPT "Actions" can call this.
17
+ */
18
+ export * as gitignoreWriter from "./gitignore_writer.js";
19
+ export * as sporeAutostart from "./spore_autostart.js";
20
+ export * as sessionCapsule from "./session_capsule.js";
21
+ export * as httpBridge from "./http_bridge.js";
22
+ export { ensureGitignoreEntries, ensureSingleGitignoreEntry, readManagedEntries, PRIVATE_AI_ARTIFACTS, } from "./gitignore_writer.js";
23
+ export { autoStartSpore, readGitRemotes, readSporeConfig, disableSpore, type SporeConfig, type GitRemote, type AutoStartResult, } from "./spore_autostart.js";
24
+ export { saveCapsule, resumeCapsule, listCapsules, type SessionCapsule, type ResumeVerdict, type ResumeResult, } from "./session_capsule.js";
25
+ export { startBridge, openapiSpec, customGptTemplate, type BridgeOptions, type BridgeHandle, type BridgeHandlers, } from "./http_bridge.js";
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/diaspora/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EACL,sBAAsB,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,oBAAoB,GAC7F,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAC7D,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,GACvD,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,WAAW,EAAE,aAAa,EAAE,YAAY,EACxC,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,GAC3D,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,WAAW,EAAE,WAAW,EAAE,iBAAiB,EAC3C,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,GAC3D,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * v1.72.0 -- DIASPORA PROTOCOL.
3
+ *
4
+ * Four wild axes that crack open the cross-machine + cross-vendor +
5
+ * cross-app barriers that kept Mneme local:
6
+ *
7
+ * D1 GHOST SNIPER GITIGNORE auto-append AI-tooling artifacts
8
+ * on every inject (privacy-leak-proof)
9
+ * D2 SPORE DEFAULT-ON git remote detected -> auto-enable
10
+ * cross-machine sync (no manual opt-in)
11
+ * D3 PORTABLE SESSION CAPSULE vendor A saves; vendor B resumes.
12
+ * HMAC-signed; soul-mirror records the
13
+ * inheritance event.
14
+ * D4 HTTP BRIDGE localhost HTTP API + OpenAPI 3.1
15
+ * spec + Custom GPT template. ChatGPT
16
+ * Custom GPT "Actions" can call this.
17
+ */
18
+ export * as gitignoreWriter from "./gitignore_writer.js";
19
+ export * as sporeAutostart from "./spore_autostart.js";
20
+ export * as sessionCapsule from "./session_capsule.js";
21
+ export * as httpBridge from "./http_bridge.js";
22
+ export { ensureGitignoreEntries, ensureSingleGitignoreEntry, readManagedEntries, PRIVATE_AI_ARTIFACTS, } from "./gitignore_writer.js";
23
+ export { autoStartSpore, readGitRemotes, readSporeConfig, disableSpore, } from "./spore_autostart.js";
24
+ export { saveCapsule, resumeCapsule, listCapsules, } from "./session_capsule.js";
25
+ export { startBridge, openapiSpec, customGptTemplate, } from "./http_bridge.js";
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/diaspora/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EACL,sBAAsB,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,oBAAoB,GAC7F,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,GAE9D,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,WAAW,EAAE,aAAa,EAAE,YAAY,GAEzC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,WAAW,EAAE,WAAW,EAAE,iBAAiB,GAE5C,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * v1.72.0 -- DIASPORA D3: PORTABLE SESSION CAPSULE.
3
+ *
4
+ * Cross-vendor handover proof. Every vendor's working context (recent
5
+ * prompts, generated answers, ACGV verdicts, sentinel events) gets
6
+ * compressed into a portable .capsule file. On the OTHER vendor,
7
+ * `resume` opens the file and replays the context summary.
8
+ *
9
+ * Vendor A (Claude Code) -- session.save -> .mneme/capsules/<id>.capsule
10
+ * ---hand off the file---
11
+ * Vendor B (Cursor) -- session.resume <id> -> recovered context
12
+ *
13
+ * Capsule format (HMAC-signed JSON):
14
+ * {
15
+ * id, capsuleVersion, createdAt, originVendor,
16
+ * repoFingerprint, contextSummary,
17
+ * promptTrace[], reasoningTrace[],
18
+ * hmac
19
+ * }
20
+ *
21
+ * The wild bit: every replay tells Mneme that vendor B is INHERITING
22
+ * from vendor A. Soul-mirror records the handover; Aletheia trust
23
+ * compounds across vendors when handovers go well.
24
+ */
25
+ export interface CapsulePromptStep {
26
+ ts: string;
27
+ role: "user" | "assistant" | "tool";
28
+ /** Truncated text. */
29
+ text: string;
30
+ }
31
+ export interface SessionCapsule {
32
+ id: string;
33
+ capsuleVersion: 1;
34
+ createdAt: string;
35
+ originVendor: string;
36
+ /** sha256 of repo root path + first 5 commit subjects. */
37
+ repoFingerprint: string;
38
+ /** 1-3 sentence plain-English summary of what was being worked on. */
39
+ contextSummary: string;
40
+ /** Recent prompt/response trace. */
41
+ promptTrace: CapsulePromptStep[];
42
+ /** Optional reasoning steps (innerlife reasoning genome). */
43
+ reasoningTrace?: string[];
44
+ /** Lessons / decisions the user explicitly captured. */
45
+ decisions?: string[];
46
+ /** HMAC over canonical payload. */
47
+ hmac: string;
48
+ }
49
+ export interface SaveOptions {
50
+ vendor: string;
51
+ contextSummary: string;
52
+ promptTrace: CapsulePromptStep[];
53
+ reasoningTrace?: string[];
54
+ decisions?: string[];
55
+ }
56
+ export declare function saveCapsule(repoRoot: string, opts: SaveOptions): SessionCapsule;
57
+ export type ResumeVerdict = "RESUMED" | "INVALID_HMAC" | "REPO_MISMATCH" | "NOT_FOUND" | "EXPIRED";
58
+ export interface ResumeResult {
59
+ verdict: ResumeVerdict;
60
+ capsule: SessionCapsule | null;
61
+ /** Plain-English recap for the resuming vendor to read aloud / inject as system prompt. */
62
+ recap: string;
63
+ /** Inheritance record (writes to soul mirror). */
64
+ inheritance: {
65
+ fromVendor: string;
66
+ toVendor: string;
67
+ ts: string;
68
+ } | null;
69
+ }
70
+ export interface ResumeOptions {
71
+ /** Vendor doing the resume. */
72
+ toVendor: string;
73
+ /** Reject capsule older than N hours. Default 720 (30 days). */
74
+ maxAgeHours?: number;
75
+ }
76
+ export declare function resumeCapsule(repoRoot: string, capsuleId: string, opts: ResumeOptions): ResumeResult;
77
+ export declare function listCapsules(repoRoot: string): SessionCapsule[];
78
+ //# sourceMappingURL=session_capsule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session_capsule.d.ts","sourceRoot":"","sources":["../../src/diaspora/session_capsule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AASH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACpC,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,CAAC,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,eAAe,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;CACd;AAoCD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,cAAc,CAsB/E;AAED,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,cAAc,GAAG,eAAe,GAAG,WAAW,GAAG,SAAS,CAAC;AAEnG,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,2FAA2F;IAC3F,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,WAAW,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC1E;AAED,MAAM,WAAW,aAAa;IAC5B,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,YAAY,CA8CpG;AA8BD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CAe/D"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * v1.72.0 -- DIASPORA D3: PORTABLE SESSION CAPSULE.
3
+ *
4
+ * Cross-vendor handover proof. Every vendor's working context (recent
5
+ * prompts, generated answers, ACGV verdicts, sentinel events) gets
6
+ * compressed into a portable .capsule file. On the OTHER vendor,
7
+ * `resume` opens the file and replays the context summary.
8
+ *
9
+ * Vendor A (Claude Code) -- session.save -> .mneme/capsules/<id>.capsule
10
+ * ---hand off the file---
11
+ * Vendor B (Cursor) -- session.resume <id> -> recovered context
12
+ *
13
+ * Capsule format (HMAC-signed JSON):
14
+ * {
15
+ * id, capsuleVersion, createdAt, originVendor,
16
+ * repoFingerprint, contextSummary,
17
+ * promptTrace[], reasoningTrace[],
18
+ * hmac
19
+ * }
20
+ *
21
+ * The wild bit: every replay tells Mneme that vendor B is INHERITING
22
+ * from vendor A. Soul-mirror records the handover; Aletheia trust
23
+ * compounds across vendors when handovers go well.
24
+ */
25
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from "node:fs";
26
+ import { createHash, createHmac, randomBytes } from "node:crypto";
27
+ import { join } from "node:path";
28
+ const CAPSULE_DIR = ".mneme/capsules";
29
+ const SECRET_FILE = ".mneme/capsules/secret";
30
+ function ensureSecret(repoRoot) {
31
+ const p = join(repoRoot, SECRET_FILE);
32
+ if (existsSync(p))
33
+ return readFileSync(p, "utf8").trim();
34
+ const dir = join(repoRoot, CAPSULE_DIR);
35
+ if (!existsSync(dir))
36
+ mkdirSync(dir, { recursive: true });
37
+ const s = randomBytes(32).toString("hex");
38
+ try {
39
+ writeFileSync(p, s, "utf8");
40
+ }
41
+ catch { /* */ }
42
+ return s;
43
+ }
44
+ function canonical(payload) {
45
+ return JSON.stringify({
46
+ capsuleVersion: payload.capsuleVersion,
47
+ createdAt: payload.createdAt,
48
+ originVendor: payload.originVendor,
49
+ repoFingerprint: payload.repoFingerprint,
50
+ contextSummary: payload.contextSummary,
51
+ promptTrace: payload.promptTrace,
52
+ reasoningTrace: payload.reasoningTrace ?? null,
53
+ decisions: payload.decisions ?? null,
54
+ });
55
+ }
56
+ function computeRepoFingerprint(repoRoot) {
57
+ let extras = "";
58
+ try {
59
+ const { execSync } = require("node:child_process");
60
+ extras = execSync(`git -C "${repoRoot}" log --max-count=5 --pretty=format:%s`, {
61
+ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 2000,
62
+ });
63
+ }
64
+ catch { /* */ }
65
+ return createHash("sha256").update(repoRoot + "|" + extras).digest("hex").slice(0, 16);
66
+ }
67
+ export function saveCapsule(repoRoot, opts) {
68
+ const secret = ensureSecret(repoRoot);
69
+ const createdAt = new Date().toISOString();
70
+ const repoFingerprint = computeRepoFingerprint(repoRoot);
71
+ const payload = {
72
+ capsuleVersion: 1,
73
+ createdAt,
74
+ originVendor: opts.vendor,
75
+ repoFingerprint,
76
+ contextSummary: opts.contextSummary.slice(0, 800),
77
+ promptTrace: opts.promptTrace.slice(-50), // last 50 steps
78
+ reasoningTrace: opts.reasoningTrace?.slice(-20),
79
+ decisions: opts.decisions?.slice(0, 20),
80
+ };
81
+ const canon = canonical(payload);
82
+ const hmac = createHmac("sha256", secret).update(canon).digest("hex");
83
+ const id = createHash("sha256").update(canon).digest("hex").slice(0, 16);
84
+ const cap = { ...payload, id, hmac };
85
+ const dir = join(repoRoot, CAPSULE_DIR);
86
+ if (!existsSync(dir))
87
+ mkdirSync(dir, { recursive: true });
88
+ writeFileSync(join(dir, `${id}.capsule`), JSON.stringify(cap, null, 2) + "\n", "utf8");
89
+ return cap;
90
+ }
91
+ export function resumeCapsule(repoRoot, capsuleId, opts) {
92
+ const dir = join(repoRoot, CAPSULE_DIR);
93
+ const path = join(dir, `${capsuleId}.capsule`);
94
+ if (!existsSync(path))
95
+ return { verdict: "NOT_FOUND", capsule: null, recap: "", inheritance: null };
96
+ let cap;
97
+ try {
98
+ cap = JSON.parse(readFileSync(path, "utf8"));
99
+ }
100
+ catch {
101
+ return { verdict: "NOT_FOUND", capsule: null, recap: "", inheritance: null };
102
+ }
103
+ const secret = ensureSecret(repoRoot);
104
+ const expected = createHmac("sha256", secret).update(canonical(cap)).digest("hex");
105
+ if (expected !== cap.hmac)
106
+ return { verdict: "INVALID_HMAC", capsule: cap, recap: "", inheritance: null };
107
+ const ageMs = Date.now() - Date.parse(cap.createdAt);
108
+ const maxMs = (opts.maxAgeHours ?? 720) * 3600 * 1000;
109
+ if (ageMs > maxMs)
110
+ return { verdict: "EXPIRED", capsule: cap, recap: "", inheritance: null };
111
+ const currentFingerprint = computeRepoFingerprint(repoRoot);
112
+ if (cap.repoFingerprint !== currentFingerprint) {
113
+ // Soft warning -- the same repo on a different host has a different
114
+ // fingerprint by design. We allow but flag.
115
+ }
116
+ const recap = renderRecap(cap, opts.toVendor);
117
+ const inheritance = { fromVendor: cap.originVendor, toVendor: opts.toVendor, ts: new Date().toISOString() };
118
+ // Append inheritance event to the ai-souls ledger so the receiving
119
+ // vendor "inherits" from the origin in Mneme's records.
120
+ try {
121
+ const soulsDir = join(repoRoot, ".mneme/ai-souls");
122
+ if (!existsSync(soulsDir))
123
+ mkdirSync(soulsDir, { recursive: true });
124
+ const path2 = join(soulsDir, `${opts.toVendor}.json`);
125
+ let soul = { vendor: opts.toVendor, sessions: [] };
126
+ if (existsSync(path2)) {
127
+ try {
128
+ soul = JSON.parse(readFileSync(path2, "utf8"));
129
+ }
130
+ catch { /* */ }
131
+ }
132
+ soul.sessions.push({
133
+ kind: "capsule-inheritance",
134
+ fromVendor: cap.originVendor,
135
+ capsuleId: cap.id,
136
+ ts: inheritance.ts,
137
+ contextSummary: cap.contextSummary,
138
+ });
139
+ writeFileSync(path2, JSON.stringify(soul, null, 2), "utf8");
140
+ }
141
+ catch { /* */ }
142
+ return { verdict: "RESUMED", capsule: cap, recap, inheritance };
143
+ }
144
+ function renderRecap(cap, toVendor) {
145
+ const lines = [];
146
+ lines.push(`# Session resumed from ${cap.originVendor} (capsule ${cap.id})`);
147
+ lines.push(``);
148
+ lines.push(`## Context`);
149
+ lines.push(cap.contextSummary);
150
+ lines.push(``);
151
+ if (cap.decisions && cap.decisions.length > 0) {
152
+ lines.push(`## Decisions made in prior session`);
153
+ for (const d of cap.decisions)
154
+ lines.push(`- ${d}`);
155
+ lines.push(``);
156
+ }
157
+ if (cap.promptTrace.length > 0) {
158
+ lines.push(`## Last ${Math.min(5, cap.promptTrace.length)} turns`);
159
+ for (const step of cap.promptTrace.slice(-5)) {
160
+ lines.push(`- **${step.role}**: ${step.text.slice(0, 160)}`);
161
+ }
162
+ lines.push(``);
163
+ }
164
+ if (cap.reasoningTrace && cap.reasoningTrace.length > 0) {
165
+ lines.push(`## Reasoning snapshot`);
166
+ for (const r of cap.reasoningTrace.slice(-3))
167
+ lines.push(`- ${r.slice(0, 200)}`);
168
+ lines.push(``);
169
+ }
170
+ lines.push(`*Vendor ${toVendor} now INHERITS this context. Mneme has recorded the handover from ${cap.originVendor}.*`);
171
+ return lines.join("\n");
172
+ }
173
+ export function listCapsules(repoRoot) {
174
+ const dir = join(repoRoot, CAPSULE_DIR);
175
+ if (!existsSync(dir))
176
+ return [];
177
+ const out = [];
178
+ try {
179
+ for (const f of readdirSync(dir)) {
180
+ if (!f.endsWith(".capsule"))
181
+ continue;
182
+ try {
183
+ const cap = JSON.parse(readFileSync(join(dir, f), "utf8"));
184
+ out.push(cap);
185
+ }
186
+ catch { /* */ }
187
+ }
188
+ }
189
+ catch { /* */ }
190
+ out.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
191
+ return out;
192
+ }
193
+ //# sourceMappingURL=session_capsule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session_capsule.js","sourceRoot":"","sources":["../../src/diaspora/session_capsule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * v1.72.0 -- DIASPORA D2: SPORE DEFAULT-ON.
3
+ *
4
+ * Today `mneme init` does NOT enable spore (cross-machine wisdom
5
+ * sync). User has to opt in manually. Result: "cross-machine" is
6
+ * marketing, not default UX.
7
+ *
8
+ * D2 changes the calculus: if the repo has a `git remote` (origin or
9
+ * any), spore should auto-enable on init. The remote URL IS the
10
+ * cross-machine identity -- no extra config needed.
11
+ *
12
+ * Detection rule:
13
+ * 1. Read `.git/config` -> any [remote "..."] section
14
+ * 2. If found -> create `.mneme/spore.json` with detected origin
15
+ * 3. Idempotent: don't overwrite existing spore config
16
+ */
17
+ export interface GitRemote {
18
+ name: string;
19
+ url: string;
20
+ }
21
+ export interface SporeConfig {
22
+ enabled: boolean;
23
+ /** Origin remote name (usually "origin"). */
24
+ remoteName: string;
25
+ /** Remote URL. */
26
+ remoteUrl: string;
27
+ /** ISO ts when spore was auto-enabled. */
28
+ enabledAt: string;
29
+ /** Reason: "git-remote-detected" / "manual". */
30
+ reason: string;
31
+ }
32
+ export interface AutoStartResult {
33
+ /** Did we enable spore? */
34
+ enabled: boolean;
35
+ /** Why or why not. */
36
+ reason: string;
37
+ /** Detected remotes (for inspection). */
38
+ remotes: GitRemote[];
39
+ /** The config that was written / detected. */
40
+ config: SporeConfig | null;
41
+ }
42
+ export declare function readGitRemotes(repoRoot: string): GitRemote[];
43
+ export declare function readSporeConfig(repoRoot: string): SporeConfig | null;
44
+ export interface AutoStartOptions {
45
+ /** When true, override existing spore.json (rare; usually idempotent). */
46
+ force?: boolean;
47
+ }
48
+ /** Idempotent: detect git remote + write spore.json if absent. Safe to
49
+ * call on every `mneme init` / daemon startup. */
50
+ export declare function autoStartSpore(repoRoot: string, opts?: AutoStartOptions): AutoStartResult;
51
+ /** Disable spore explicitly. */
52
+ export declare function disableSpore(repoRoot: string): void;
53
+ //# sourceMappingURL=spore_autostart.d.ts.map