@mneme-ai/core 2.19.30 → 2.19.32
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/beacon/beacon.test.js +44 -0
- package/dist/beacon/beacon.test.js.map +1 -1
- package/dist/beacon/index.d.ts.map +1 -1
- package/dist/beacon/index.js +5 -1
- package/dist/beacon/index.js.map +1 -1
- package/dist/consciousness_fork/consciousness_fork.test.d.ts +2 -0
- package/dist/consciousness_fork/consciousness_fork.test.d.ts.map +1 -0
- package/dist/consciousness_fork/consciousness_fork.test.js +177 -0
- package/dist/consciousness_fork/consciousness_fork.test.js.map +1 -0
- package/dist/consciousness_fork/index.d.ts +129 -0
- package/dist/consciousness_fork/index.d.ts.map +1 -0
- package/dist/consciousness_fork/index.js +227 -0
- package/dist/consciousness_fork/index.js.map +1 -0
- package/dist/cosmic/aurelian_v1931.test.d.ts +2 -0
- package/dist/cosmic/aurelian_v1931.test.d.ts.map +1 -0
- package/dist/cosmic/aurelian_v1931.test.js +67 -0
- package/dist/cosmic/aurelian_v1931.test.js.map +1 -0
- package/dist/cosmic/aurelian_v1932.test.d.ts +2 -0
- package/dist/cosmic/aurelian_v1932.test.d.ts.map +1 -0
- package/dist/cosmic/aurelian_v1932.test.js +83 -0
- package/dist/cosmic/aurelian_v1932.test.js.map +1 -0
- package/dist/handoff_pwa/handoff_pwa.test.d.ts +2 -0
- package/dist/handoff_pwa/handoff_pwa.test.d.ts.map +1 -0
- package/dist/handoff_pwa/handoff_pwa.test.js +119 -0
- package/dist/handoff_pwa/handoff_pwa.test.js.map +1 -0
- package/dist/handoff_pwa/index.d.ts +81 -0
- package/dist/handoff_pwa/index.d.ts.map +1 -0
- package/dist/handoff_pwa/index.js +312 -0
- package/dist/handoff_pwa/index.js.map +1 -0
- package/dist/handoff_snapshot/handoff_snapshot.test.d.ts +2 -0
- package/dist/handoff_snapshot/handoff_snapshot.test.d.ts.map +1 -0
- package/dist/handoff_snapshot/handoff_snapshot.test.js +147 -0
- package/dist/handoff_snapshot/handoff_snapshot.test.js.map +1 -0
- package/dist/handoff_snapshot/index.d.ts +156 -0
- package/dist/handoff_snapshot/index.d.ts.map +1 -0
- package/dist/handoff_snapshot/index.js +261 -0
- package/dist/handoff_snapshot/index.js.map +1 -0
- package/dist/handoff_snapshot/system_e2e.test.d.ts +8 -0
- package/dist/handoff_snapshot/system_e2e.test.d.ts.map +1 -0
- package/dist/handoff_snapshot/system_e2e.test.js +211 -0
- package/dist/handoff_snapshot/system_e2e.test.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/pair_code/index.d.ts +107 -0
- package/dist/pair_code/index.d.ts.map +1 -0
- package/dist/pair_code/index.js +226 -0
- package/dist/pair_code/index.js.map +1 -0
- package/dist/pair_code/pair_code.test.d.ts +2 -0
- package/dist/pair_code/pair_code.test.d.ts.map +1 -0
- package/dist/pair_code/pair_code.test.js +197 -0
- package/dist/pair_code/pair_code.test.js.map +1 -0
- package/dist/synapse_sync/index.d.ts +142 -0
- package/dist/synapse_sync/index.d.ts.map +1 -0
- package/dist/synapse_sync/index.js +323 -0
- package/dist/synapse_sync/index.js.map +1 -0
- package/dist/synapse_sync/synapse_sync.test.d.ts +2 -0
- package/dist/synapse_sync/synapse_sync.test.d.ts.map +1 -0
- package/dist/synapse_sync/synapse_sync.test.js +363 -0
- package/dist/synapse_sync/synapse_sync.test.js.map +1 -0
- package/dist/truth_forensic_pipeline/index.d.ts +24 -0
- package/dist/truth_forensic_pipeline/index.d.ts.map +1 -1
- package/dist/truth_forensic_pipeline/index.js +110 -4
- package/dist/truth_forensic_pipeline/index.js.map +1 -1
- package/dist/truth_forensic_pipeline/truth_forensic_pipeline.test.js +83 -0
- package/dist/truth_forensic_pipeline/truth_forensic_pipeline.test.js.map +1 -1
- package/dist/whats_new.d.ts.map +1 -1
- package/dist/whats_new.js +16 -0
- package/dist/whats_new.js.map +1 -1
- package/dist/wrapper_genesis/index.d.ts.map +1 -1
- package/dist/wrapper_genesis/index.js +36 -0
- package/dist/wrapper_genesis/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.19.32 — MNEME HANDOFF PWA (the device-adaptive page the scanner lands on)
|
|
3
|
+
*
|
|
4
|
+
* "PWA ปลายทาง — Smart, Detect device. หน้าเดียว ฉลาดพอจะปรับตัว
|
|
5
|
+
* ตาม scanner: Android phone → Share to Gemini; Desktop → Open in
|
|
6
|
+
* Cursor / VS Code / Claude Code; iOS → Copy + Shortcut; Tablet →
|
|
7
|
+
* เหมือน Phone" — user spec, 2026-05-17
|
|
8
|
+
*
|
|
9
|
+
* v2.19.32 ships a pure-function HTML GENERATOR. Caller (BEACON HTTP
|
|
10
|
+
* server) embeds the envelope text + SAS emoji + pair code into a
|
|
11
|
+
* self-contained HTML page (no external CDN — works offline on LAN).
|
|
12
|
+
* The embedded JavaScript detects user-agent and renders the right
|
|
13
|
+
* set of action buttons.
|
|
14
|
+
*
|
|
15
|
+
* Action buttons by device:
|
|
16
|
+
*
|
|
17
|
+
* 📱 Android Phone:
|
|
18
|
+
* [📤 Share to Gemini app] (Web Share API → any AI app installed)
|
|
19
|
+
* [📤 Share to ChatGPT app]
|
|
20
|
+
* [📤 Share to Claude app]
|
|
21
|
+
* [📋 Copy to clipboard]
|
|
22
|
+
*
|
|
23
|
+
* 📱 iOS Phone (Web Share API limited):
|
|
24
|
+
* [📋 Copy to clipboard]
|
|
25
|
+
* [📲 Open Shortcut] (mneme://receive deep link)
|
|
26
|
+
*
|
|
27
|
+
* 💻 Desktop browser:
|
|
28
|
+
* [💻 Open in Cursor] (cursor:// deep link)
|
|
29
|
+
* [💻 Open in VS Code] (vscode:// deep link)
|
|
30
|
+
* [💻 Open in Claude Code] (claude-code:// deep link)
|
|
31
|
+
* [💻 Save to .mneme/] (download .json — CLI auto-detects)
|
|
32
|
+
* [📋 Copy to clipboard]
|
|
33
|
+
*
|
|
34
|
+
* 📱 Tablet: phone-like
|
|
35
|
+
*
|
|
36
|
+
* All buttons gracefully degrade: if Web Share unsupported → clipboard;
|
|
37
|
+
* if deep link unsupported → download .json + instructions.
|
|
38
|
+
*
|
|
39
|
+
* Composes onto:
|
|
40
|
+
* - v2.19.32 HANDOFF SNAPSHOT (envelope to embed)
|
|
41
|
+
* - v2.19.32 PAIR CODE (code displayed + SAS emoji)
|
|
42
|
+
* - v2.9 BEACON server (HTTP transport)
|
|
43
|
+
*
|
|
44
|
+
* Honest scope:
|
|
45
|
+
* - PURE FUNCTION HTML emitter. Single string returned.
|
|
46
|
+
* - No external CSS / JS / fonts — fully self-contained.
|
|
47
|
+
* - All user-supplied text HTML-escaped (defends against the v2.19.31
|
|
48
|
+
* XSS-via-payload class — reuses beacon's escape logic).
|
|
49
|
+
* - 24/7 safe: empty / missing fields render placeholders, never throw.
|
|
50
|
+
*/
|
|
51
|
+
export interface HandoffPwaInput {
|
|
52
|
+
/** Markdown body to embed (output of renderForChildVendor). */
|
|
53
|
+
body: string;
|
|
54
|
+
/** Pair code (e.g. "ZOZ-CAT") for display. */
|
|
55
|
+
pairCode: string;
|
|
56
|
+
/** SAS emoji array (4 emoji) for MITM verification. */
|
|
57
|
+
sasEmoji: string[];
|
|
58
|
+
/** ms until pair-code expires (display countdown). */
|
|
59
|
+
expiresInMs: number;
|
|
60
|
+
/** Optional title above the page. */
|
|
61
|
+
title?: string;
|
|
62
|
+
/** Optional parent device id for display. */
|
|
63
|
+
parentDeviceId?: string;
|
|
64
|
+
/** Optional list of vendor app names to offer "Share to" buttons for. */
|
|
65
|
+
shareTargets?: string[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Render a self-contained HTML page the BEACON server can serve at
|
|
69
|
+
* GET /pair/<code>. No external requests — works offline on LAN.
|
|
70
|
+
*/
|
|
71
|
+
export declare function generateHandoffPwaHtml(input: HandoffPwaInput): string;
|
|
72
|
+
export interface PwaStats {
|
|
73
|
+
htmlBytes: number;
|
|
74
|
+
hasEmoji: boolean;
|
|
75
|
+
embeddedBodyBytes: number;
|
|
76
|
+
}
|
|
77
|
+
export declare function computePwaStats(input: HandoffPwaInput, html: string): PwaStats;
|
|
78
|
+
export declare const HANDOFF_PWA_TUNABLES: Readonly<{
|
|
79
|
+
PROTOCOL_VERSION: 1;
|
|
80
|
+
}>;
|
|
81
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/handoff_pwa/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAIH,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AA+BD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CA8NrE;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAM9E;AAED,eAAO,MAAM,oBAAoB;;EAE/B,CAAC"}
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.19.32 — MNEME HANDOFF PWA (the device-adaptive page the scanner lands on)
|
|
3
|
+
*
|
|
4
|
+
* "PWA ปลายทาง — Smart, Detect device. หน้าเดียว ฉลาดพอจะปรับตัว
|
|
5
|
+
* ตาม scanner: Android phone → Share to Gemini; Desktop → Open in
|
|
6
|
+
* Cursor / VS Code / Claude Code; iOS → Copy + Shortcut; Tablet →
|
|
7
|
+
* เหมือน Phone" — user spec, 2026-05-17
|
|
8
|
+
*
|
|
9
|
+
* v2.19.32 ships a pure-function HTML GENERATOR. Caller (BEACON HTTP
|
|
10
|
+
* server) embeds the envelope text + SAS emoji + pair code into a
|
|
11
|
+
* self-contained HTML page (no external CDN — works offline on LAN).
|
|
12
|
+
* The embedded JavaScript detects user-agent and renders the right
|
|
13
|
+
* set of action buttons.
|
|
14
|
+
*
|
|
15
|
+
* Action buttons by device:
|
|
16
|
+
*
|
|
17
|
+
* 📱 Android Phone:
|
|
18
|
+
* [📤 Share to Gemini app] (Web Share API → any AI app installed)
|
|
19
|
+
* [📤 Share to ChatGPT app]
|
|
20
|
+
* [📤 Share to Claude app]
|
|
21
|
+
* [📋 Copy to clipboard]
|
|
22
|
+
*
|
|
23
|
+
* 📱 iOS Phone (Web Share API limited):
|
|
24
|
+
* [📋 Copy to clipboard]
|
|
25
|
+
* [📲 Open Shortcut] (mneme://receive deep link)
|
|
26
|
+
*
|
|
27
|
+
* 💻 Desktop browser:
|
|
28
|
+
* [💻 Open in Cursor] (cursor:// deep link)
|
|
29
|
+
* [💻 Open in VS Code] (vscode:// deep link)
|
|
30
|
+
* [💻 Open in Claude Code] (claude-code:// deep link)
|
|
31
|
+
* [💻 Save to .mneme/] (download .json — CLI auto-detects)
|
|
32
|
+
* [📋 Copy to clipboard]
|
|
33
|
+
*
|
|
34
|
+
* 📱 Tablet: phone-like
|
|
35
|
+
*
|
|
36
|
+
* All buttons gracefully degrade: if Web Share unsupported → clipboard;
|
|
37
|
+
* if deep link unsupported → download .json + instructions.
|
|
38
|
+
*
|
|
39
|
+
* Composes onto:
|
|
40
|
+
* - v2.19.32 HANDOFF SNAPSHOT (envelope to embed)
|
|
41
|
+
* - v2.19.32 PAIR CODE (code displayed + SAS emoji)
|
|
42
|
+
* - v2.9 BEACON server (HTTP transport)
|
|
43
|
+
*
|
|
44
|
+
* Honest scope:
|
|
45
|
+
* - PURE FUNCTION HTML emitter. Single string returned.
|
|
46
|
+
* - No external CSS / JS / fonts — fully self-contained.
|
|
47
|
+
* - All user-supplied text HTML-escaped (defends against the v2.19.31
|
|
48
|
+
* XSS-via-payload class — reuses beacon's escape logic).
|
|
49
|
+
* - 24/7 safe: empty / missing fields render placeholders, never throw.
|
|
50
|
+
*/
|
|
51
|
+
const PROTOCOL_VERSION = 1;
|
|
52
|
+
function escapeHtml(s) {
|
|
53
|
+
return String(s).replace(/[&<>"']/g, (c) => ({
|
|
54
|
+
"&": "&",
|
|
55
|
+
"<": "<",
|
|
56
|
+
">": ">",
|
|
57
|
+
"\"": """,
|
|
58
|
+
"'": "'",
|
|
59
|
+
}[c]));
|
|
60
|
+
}
|
|
61
|
+
const LS_RE = new RegExp("
", "g");
|
|
62
|
+
const PS_RE = new RegExp("
", "g");
|
|
63
|
+
function escapeJs(s) {
|
|
64
|
+
// For embedding into <script> string literal — escape backslash, quote,
|
|
65
|
+
// line terminators (\n / \r / U+2028 / U+2029) and </ to prevent
|
|
66
|
+
// </script> closure attack.
|
|
67
|
+
return String(s)
|
|
68
|
+
.replace(/\\/g, "\\\\")
|
|
69
|
+
.replace(/'/g, "\\'")
|
|
70
|
+
.replace(/\n/g, "\\n")
|
|
71
|
+
.replace(/\r/g, "\\r")
|
|
72
|
+
.replace(LS_RE, "\\u2028")
|
|
73
|
+
.replace(PS_RE, "\\u2029")
|
|
74
|
+
.replace(/<\//g, "<\\/");
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Render a self-contained HTML page the BEACON server can serve at
|
|
78
|
+
* GET /pair/<code>. No external requests — works offline on LAN.
|
|
79
|
+
*/
|
|
80
|
+
export function generateHandoffPwaHtml(input) {
|
|
81
|
+
const title = escapeHtml(input.title ?? "Mneme Handoff");
|
|
82
|
+
const pairCode = escapeHtml(input.pairCode);
|
|
83
|
+
const emoji = (Array.isArray(input.sasEmoji) && input.sasEmoji.length === 4)
|
|
84
|
+
? input.sasEmoji.map(escapeHtml).join(" ")
|
|
85
|
+
: "❓ ❓ ❓ ❓";
|
|
86
|
+
const body = escapeJs(input.body ?? "");
|
|
87
|
+
const parent = escapeHtml(input.parentDeviceId ?? "anonymous");
|
|
88
|
+
const expiresIn = Number.isFinite(input.expiresInMs) ? Math.max(0, Math.floor(input.expiresInMs / 1000)) : 0;
|
|
89
|
+
const shareTargets = (Array.isArray(input.shareTargets) && input.shareTargets.length > 0)
|
|
90
|
+
? input.shareTargets
|
|
91
|
+
: ["Gemini", "ChatGPT", "Claude"];
|
|
92
|
+
const shareTargetsJs = JSON.stringify(shareTargets.map(escapeJs));
|
|
93
|
+
return `<!DOCTYPE html>
|
|
94
|
+
<html lang="en">
|
|
95
|
+
<head>
|
|
96
|
+
<meta charset="utf-8">
|
|
97
|
+
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
|
|
98
|
+
<meta name="theme-color" content="#0f172a">
|
|
99
|
+
<title>${title}</title>
|
|
100
|
+
<style>
|
|
101
|
+
:root {
|
|
102
|
+
--bg: #0f172a;
|
|
103
|
+
--card: #1e293b;
|
|
104
|
+
--border: #334155;
|
|
105
|
+
--text: #e2e8f0;
|
|
106
|
+
--muted: #94a3b8;
|
|
107
|
+
--accent: #22d3ee;
|
|
108
|
+
--ok: #4ade80;
|
|
109
|
+
--warn: #fbbf24;
|
|
110
|
+
}
|
|
111
|
+
* { box-sizing: border-box; }
|
|
112
|
+
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
113
|
+
background: var(--bg); color: var(--text); min-height: 100vh; padding: 16px; }
|
|
114
|
+
.wrap { max-width: 720px; margin: 0 auto; }
|
|
115
|
+
h1 { font-size: 1.4rem; margin: 8px 0 4px; }
|
|
116
|
+
.sub { color: var(--muted); font-size: 0.85rem; margin-bottom: 16px; }
|
|
117
|
+
.card { background: var(--card); border: 1px solid var(--border); border-radius: 12px;
|
|
118
|
+
padding: 16px; margin: 12px 0; }
|
|
119
|
+
.pair { text-align: center; padding: 24px 16px; }
|
|
120
|
+
.pair-code { font-size: 2.6rem; letter-spacing: 0.15em; font-weight: 700;
|
|
121
|
+
color: var(--accent); margin: 8px 0; user-select: all; }
|
|
122
|
+
.sas { font-size: 2.2rem; letter-spacing: 0.2em; margin: 8px 0; }
|
|
123
|
+
.sas-label { color: var(--muted); font-size: 0.8rem; }
|
|
124
|
+
.countdown { color: var(--warn); font-weight: 600; }
|
|
125
|
+
.actions { display: grid; gap: 8px; margin-top: 12px; }
|
|
126
|
+
.btn { display: block; padding: 14px 16px; border-radius: 10px; border: 1px solid var(--border);
|
|
127
|
+
background: #0b1220; color: var(--text); text-decoration: none; cursor: pointer;
|
|
128
|
+
font-size: 1rem; text-align: left; transition: background 0.15s; }
|
|
129
|
+
.btn:hover { background: #172033; }
|
|
130
|
+
.btn-primary { background: var(--accent); color: #001821; border-color: var(--accent); font-weight: 600; }
|
|
131
|
+
.btn-primary:hover { filter: brightness(1.1); }
|
|
132
|
+
.body-preview { background: #020617; border: 1px solid var(--border); border-radius: 8px;
|
|
133
|
+
padding: 12px; font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
134
|
+
font-size: 0.8rem; white-space: pre-wrap; word-break: break-word; max-height: 260px;
|
|
135
|
+
overflow-y: auto; }
|
|
136
|
+
.toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
|
|
137
|
+
background: var(--ok); color: #001821; padding: 12px 20px; border-radius: 8px;
|
|
138
|
+
font-weight: 600; opacity: 0; transition: opacity 0.2s; pointer-events: none; }
|
|
139
|
+
.toast.show { opacity: 1; }
|
|
140
|
+
.footer { color: var(--muted); font-size: 0.75rem; text-align: center; margin-top: 24px; }
|
|
141
|
+
.footer a { color: var(--accent); }
|
|
142
|
+
</style>
|
|
143
|
+
</head>
|
|
144
|
+
<body>
|
|
145
|
+
<div class="wrap">
|
|
146
|
+
<h1>🧬 ${title}</h1>
|
|
147
|
+
<div class="sub">From parent: <strong>${parent}</strong></div>
|
|
148
|
+
|
|
149
|
+
<div class="card pair">
|
|
150
|
+
<div class="sas-label">Verify parent & child show SAME emoji:</div>
|
|
151
|
+
<div class="sas">${emoji}</div>
|
|
152
|
+
<div style="border-top: 1px solid var(--border); margin: 16px 0; padding-top: 12px;">
|
|
153
|
+
<div class="sas-label">Pair code (one-shot):</div>
|
|
154
|
+
<div class="pair-code">${pairCode}</div>
|
|
155
|
+
<div>⏱ expires in <span class="countdown" id="countdown">${expiresIn}s</span></div>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
<div class="card">
|
|
160
|
+
<h2 style="margin-top: 0;">Send the handoff to your AI tool</h2>
|
|
161
|
+
<div class="actions" id="actions">
|
|
162
|
+
<button class="btn" onclick="copyBody()">📋 Copy handoff to clipboard</button>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<div class="card">
|
|
167
|
+
<h2 style="margin-top: 0;">Preview</h2>
|
|
168
|
+
<div class="body-preview" id="preview"></div>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<div class="footer">
|
|
172
|
+
Mneme HANDOFF v${PROTOCOL_VERSION} · local-first · no external requests<br>
|
|
173
|
+
<a href="https://www.npmjs.com/package/mneme-ai">npmjs.com/mneme-ai</a>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
<div class="toast" id="toast">Copied</div>
|
|
178
|
+
|
|
179
|
+
<script>
|
|
180
|
+
(function() {
|
|
181
|
+
var BODY = '${body}';
|
|
182
|
+
var PAIR_CODE = '${escapeJs(input.pairCode)}';
|
|
183
|
+
var SHARE_TARGETS = ${shareTargetsJs};
|
|
184
|
+
|
|
185
|
+
var pre = document.getElementById('preview');
|
|
186
|
+
if (pre) pre.textContent = BODY;
|
|
187
|
+
|
|
188
|
+
var sec = ${expiresIn};
|
|
189
|
+
var cd = document.getElementById('countdown');
|
|
190
|
+
var timer = setInterval(function() {
|
|
191
|
+
sec--;
|
|
192
|
+
if (cd) cd.textContent = sec + 's';
|
|
193
|
+
if (sec <= 0) {
|
|
194
|
+
clearInterval(timer);
|
|
195
|
+
if (cd) { cd.textContent = 'EXPIRED'; cd.style.color = '#ef4444'; }
|
|
196
|
+
}
|
|
197
|
+
}, 1000);
|
|
198
|
+
|
|
199
|
+
var ua = (navigator.userAgent || '').toLowerCase();
|
|
200
|
+
var isAndroid = /android/.test(ua);
|
|
201
|
+
var isIOS = /iphone|ipad|ipod/.test(ua);
|
|
202
|
+
var isMobile = isAndroid || isIOS || /mobile/.test(ua);
|
|
203
|
+
var isTablet = /tablet|ipad/.test(ua);
|
|
204
|
+
var hasWebShare = typeof navigator.share === 'function';
|
|
205
|
+
var hasClipboard = !!(navigator.clipboard && navigator.clipboard.writeText);
|
|
206
|
+
|
|
207
|
+
var actions = document.getElementById('actions');
|
|
208
|
+
if (actions) actions.innerHTML = '';
|
|
209
|
+
|
|
210
|
+
function addBtn(label, onclick, primary) {
|
|
211
|
+
var b = document.createElement('button');
|
|
212
|
+
b.className = 'btn' + (primary ? ' btn-primary' : '');
|
|
213
|
+
b.textContent = label;
|
|
214
|
+
b.onclick = onclick;
|
|
215
|
+
if (actions) actions.appendChild(b);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function showToast(msg, color) {
|
|
219
|
+
var t = document.getElementById('toast');
|
|
220
|
+
if (!t) return;
|
|
221
|
+
t.textContent = msg;
|
|
222
|
+
if (color) t.style.background = color;
|
|
223
|
+
t.classList.add('show');
|
|
224
|
+
setTimeout(function() { t.classList.remove('show'); }, 1800);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
window.copyBody = function() {
|
|
228
|
+
if (hasClipboard) {
|
|
229
|
+
navigator.clipboard.writeText(BODY).then(function() {
|
|
230
|
+
showToast('✓ Copied — paste into your AI tool');
|
|
231
|
+
}).catch(function() {
|
|
232
|
+
fallbackCopy();
|
|
233
|
+
});
|
|
234
|
+
} else {
|
|
235
|
+
fallbackCopy();
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
function fallbackCopy() {
|
|
240
|
+
var ta = document.createElement('textarea');
|
|
241
|
+
ta.value = BODY;
|
|
242
|
+
ta.style.position = 'fixed'; ta.style.opacity = '0';
|
|
243
|
+
document.body.appendChild(ta);
|
|
244
|
+
ta.select();
|
|
245
|
+
try { document.execCommand('copy'); showToast('✓ Copied'); }
|
|
246
|
+
catch (e) { showToast('Copy failed — long-press preview', '#ef4444'); }
|
|
247
|
+
document.body.removeChild(ta);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (isMobile && hasWebShare) {
|
|
251
|
+
addBtn('📤 Share to AI app (Gemini / ChatGPT / Claude)', function() {
|
|
252
|
+
navigator.share({
|
|
253
|
+
title: 'Mneme Handoff',
|
|
254
|
+
text: BODY,
|
|
255
|
+
}).then(function() {
|
|
256
|
+
showToast('✓ Shared');
|
|
257
|
+
}).catch(function(err) {
|
|
258
|
+
if (err && err.name === 'AbortError') return;
|
|
259
|
+
showToast('Share failed — copy fallback', '#ef4444');
|
|
260
|
+
});
|
|
261
|
+
}, true);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (!isMobile) {
|
|
265
|
+
var deeplinks = [
|
|
266
|
+
{ label: '💻 Open in Cursor', url: 'cursor://anysphere.cursor-deeplink/prompt?text=' + encodeURIComponent(BODY) },
|
|
267
|
+
{ label: '💻 Open in VS Code', url: 'vscode://file//?text=' + encodeURIComponent(BODY) },
|
|
268
|
+
{ label: '💻 Open in Claude Code', url: 'claude-code://open?text=' + encodeURIComponent(BODY) },
|
|
269
|
+
{ label: '🧠 Open in Mneme CLI', url: 'mneme://receive?code=' + encodeURIComponent(PAIR_CODE) },
|
|
270
|
+
];
|
|
271
|
+
for (var i = 0; i < deeplinks.length; i++) {
|
|
272
|
+
(function(d) {
|
|
273
|
+
addBtn(d.label, function() {
|
|
274
|
+
window.location.href = d.url;
|
|
275
|
+
setTimeout(function() {
|
|
276
|
+
showToast('Opened deep link — if nothing happened, click Copy below', '#fbbf24');
|
|
277
|
+
}, 800);
|
|
278
|
+
});
|
|
279
|
+
})(deeplinks[i]);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
addBtn('💾 Download handoff.json', function() {
|
|
284
|
+
var blob = new Blob([BODY], { type: 'text/plain' });
|
|
285
|
+
var url = URL.createObjectURL(blob);
|
|
286
|
+
var a = document.createElement('a');
|
|
287
|
+
a.href = url;
|
|
288
|
+
a.download = 'mneme-handoff-' + PAIR_CODE + '.txt';
|
|
289
|
+
document.body.appendChild(a);
|
|
290
|
+
a.click();
|
|
291
|
+
document.body.removeChild(a);
|
|
292
|
+
URL.revokeObjectURL(url);
|
|
293
|
+
showToast('✓ Downloaded');
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
addBtn('📋 Copy to clipboard', window.copyBody, !isMobile);
|
|
297
|
+
})();
|
|
298
|
+
</script>
|
|
299
|
+
</body>
|
|
300
|
+
</html>`;
|
|
301
|
+
}
|
|
302
|
+
export function computePwaStats(input, html) {
|
|
303
|
+
return {
|
|
304
|
+
htmlBytes: html.length,
|
|
305
|
+
hasEmoji: Array.isArray(input.sasEmoji) && input.sasEmoji.length === 4,
|
|
306
|
+
embeddedBodyBytes: (input.body ?? "").length,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
export const HANDOFF_PWA_TUNABLES = Object.freeze({
|
|
310
|
+
PROTOCOL_VERSION,
|
|
311
|
+
});
|
|
312
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/handoff_pwa/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handoff_snapshot.test.d.ts","sourceRoot":"","sources":["../../src/handoff_snapshot/handoff_snapshot.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { captureSnapshot, verifyEnvelope, freshnessCheck, renderForChildVendor, computeSnapshotStats, formatSnapshotLine, HANDOFF_SNAPSHOT_TUNABLES, } from "./index.js";
|
|
3
|
+
const SECRET = "handoff-test-secret-77";
|
|
4
|
+
describe("v2.19.32 HANDOFF SNAPSHOT -- pure-function envelope composer", () => {
|
|
5
|
+
it("captureSnapshot returns a valid HMAC-signed envelope from minimal input", () => {
|
|
6
|
+
const env = captureSnapshot({
|
|
7
|
+
parentDeviceId: "parent-pc",
|
|
8
|
+
nowMs: 1_700_000_000_000,
|
|
9
|
+
secret: SECRET,
|
|
10
|
+
});
|
|
11
|
+
expect(env.v).toBe(HANDOFF_SNAPSHOT_TUNABLES.PROTOCOL_VERSION);
|
|
12
|
+
expect(env.envelopeId).toMatch(/^[0-9a-f]{16}$/);
|
|
13
|
+
expect(env.sig).toMatch(/^[0-9a-f]{64}$/);
|
|
14
|
+
expect(env.parentDeviceId).toBe("parent-pc");
|
|
15
|
+
expect(env.snapshotAtMs).toBe(1_700_000_000_000);
|
|
16
|
+
expect(verifyEnvelope(env, SECRET)).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
it("captureSnapshot is deterministic: same input + secret -> same sig", () => {
|
|
19
|
+
const input = {
|
|
20
|
+
parentDeviceId: "p1",
|
|
21
|
+
conversation: [{ role: "user", text: "hello", ts: 1000 }],
|
|
22
|
+
nowMs: 5000,
|
|
23
|
+
secret: SECRET,
|
|
24
|
+
};
|
|
25
|
+
const a = captureSnapshot(input);
|
|
26
|
+
const b = captureSnapshot(input);
|
|
27
|
+
expect(a.sig).toBe(b.sig);
|
|
28
|
+
expect(a.envelopeId).toBe(b.envelopeId);
|
|
29
|
+
});
|
|
30
|
+
it("captureSnapshot embeds conversation + git state + activity", () => {
|
|
31
|
+
const env = captureSnapshot({
|
|
32
|
+
parentDeviceId: "p1",
|
|
33
|
+
conversation: [
|
|
34
|
+
{ role: "user", text: "fix beacon bug", ts: 1000 },
|
|
35
|
+
{ role: "assistant", text: "found it on line 216", ts: 2000 },
|
|
36
|
+
],
|
|
37
|
+
activeIntent: "fixing BEACON BUG #1",
|
|
38
|
+
gitState: { branch: "main", dirty: " M beacon/index.ts", recentCommits: ["fix: bug #1"] },
|
|
39
|
+
recentActivity: [{ action: "mneme.truth.forensic", ts: 1500 }],
|
|
40
|
+
capabilities: { mnemeVersion: "2.19.32", toolFamilies: ["beacon", "synapse"] },
|
|
41
|
+
voiceDirective: "concise + technical",
|
|
42
|
+
mnemeDictionary: { "BEACON": "QR transfer subsystem" },
|
|
43
|
+
nowMs: 3000,
|
|
44
|
+
secret: SECRET,
|
|
45
|
+
});
|
|
46
|
+
expect(env.conversation.length).toBe(2);
|
|
47
|
+
expect(env.activeIntent).toBe("fixing BEACON BUG #1");
|
|
48
|
+
expect(env.gitState.branch).toBe("main");
|
|
49
|
+
expect(env.recentActivity.length).toBe(1);
|
|
50
|
+
expect(env.capabilities.mnemeVersion).toBe("2.19.32");
|
|
51
|
+
expect(env.voiceDirective).toBe("concise + technical");
|
|
52
|
+
expect(env.mnemeDictionary["BEACON"]).toBe("QR transfer subsystem");
|
|
53
|
+
expect(verifyEnvelope(env, SECRET)).toBe(true);
|
|
54
|
+
});
|
|
55
|
+
it("captureSnapshot is DEFENSIVE: bad input never throws", () => {
|
|
56
|
+
const bad = [
|
|
57
|
+
undefined, null, {}, { parentDeviceId: 123 }, { conversation: "not-an-array" },
|
|
58
|
+
{ conversation: [{ role: "alien", text: 99, ts: "x" }] },
|
|
59
|
+
{ gitState: "not-an-object" },
|
|
60
|
+
{ recentActivity: [null, undefined, "x", { action: 1 }] },
|
|
61
|
+
{ capabilities: 99 },
|
|
62
|
+
{ mnemeDictionary: "x" },
|
|
63
|
+
];
|
|
64
|
+
for (const b of bad) {
|
|
65
|
+
const env = captureSnapshot((b ?? {}));
|
|
66
|
+
expect(env.sig).toMatch(/^[0-9a-f]{64}$/);
|
|
67
|
+
expect(verifyEnvelope(env)).toBe(true);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
it("verifyEnvelope rejects tampered envelopes (one char change in sig)", () => {
|
|
71
|
+
const env = captureSnapshot({ parentDeviceId: "p", nowMs: 1, secret: SECRET });
|
|
72
|
+
const tampered = { ...env, sig: env.sig.slice(0, -1) + (env.sig.endsWith("a") ? "b" : "a") };
|
|
73
|
+
expect(verifyEnvelope(tampered, SECRET)).toBe(false);
|
|
74
|
+
});
|
|
75
|
+
it("verifyEnvelope rejects field mutation", () => {
|
|
76
|
+
const env = captureSnapshot({ parentDeviceId: "p", nowMs: 1, secret: SECRET });
|
|
77
|
+
const tampered = { ...env, parentDeviceId: "attacker" };
|
|
78
|
+
expect(verifyEnvelope(tampered, SECRET)).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
it("verifyEnvelope rejects wrong secret", () => {
|
|
81
|
+
const env = captureSnapshot({ parentDeviceId: "p", nowMs: 1, secret: SECRET });
|
|
82
|
+
expect(verifyEnvelope(env, "wrong-secret")).toBe(false);
|
|
83
|
+
});
|
|
84
|
+
it("verifyEnvelope rejects malformed envelopes", () => {
|
|
85
|
+
expect(verifyEnvelope(null)).toBe(false);
|
|
86
|
+
expect(verifyEnvelope({})).toBe(false);
|
|
87
|
+
expect(verifyEnvelope({ v: 99, sig: "x".repeat(64) })).toBe(false);
|
|
88
|
+
});
|
|
89
|
+
it("freshnessCheck: fresh / stale / expired / future_clock_skew bands", () => {
|
|
90
|
+
const env = captureSnapshot({ parentDeviceId: "p", nowMs: 1_000_000, secret: SECRET });
|
|
91
|
+
expect(freshnessCheck(env, 1_000_500).reason).toBe("fresh"); // 0.5s old
|
|
92
|
+
expect(freshnessCheck(env, 1_000_000 + 4 * 60 * 1000 + 30 * 1000).reason).toBe("stale"); // 4.5min
|
|
93
|
+
expect(freshnessCheck(env, 1_000_000 + 6 * 60 * 1000).reason).toBe("expired"); // 6min
|
|
94
|
+
expect(freshnessCheck(env, 1_000_000 - 5_000).reason).toBe("future_clock_skew"); // child behind 5s
|
|
95
|
+
});
|
|
96
|
+
it("renderForChildVendor produces valid markdown the receiving AI can paste", () => {
|
|
97
|
+
const env = captureSnapshot({
|
|
98
|
+
parentDeviceId: "macbook",
|
|
99
|
+
conversation: [{ role: "user", text: "what about phase D?", ts: 1000 }],
|
|
100
|
+
activeIntent: "discussing cross-device sync",
|
|
101
|
+
gitState: { branch: "main", recentCommits: ["feat: v2.19.31"] },
|
|
102
|
+
capabilities: { mnemeVersion: "2.19.32", toolFamilies: ["synapse"] },
|
|
103
|
+
nowMs: 2000,
|
|
104
|
+
secret: SECRET,
|
|
105
|
+
});
|
|
106
|
+
const md = renderForChildVendor(env);
|
|
107
|
+
expect(md).toContain("Mneme Handoff");
|
|
108
|
+
expect(md).toContain("macbook");
|
|
109
|
+
expect(md).toContain("phase D");
|
|
110
|
+
expect(md).toContain("discussing cross-device sync");
|
|
111
|
+
expect(md).toContain("feat: v2.19.31");
|
|
112
|
+
expect(md).toContain(env.envelopeId);
|
|
113
|
+
expect(md.length).toBeGreaterThan(100);
|
|
114
|
+
});
|
|
115
|
+
it("computeSnapshotStats reports byte size + turn count + age", () => {
|
|
116
|
+
const env = captureSnapshot({
|
|
117
|
+
parentDeviceId: "p",
|
|
118
|
+
conversation: [{ role: "user", text: "hi", ts: 1 }],
|
|
119
|
+
nowMs: 1000,
|
|
120
|
+
secret: SECRET,
|
|
121
|
+
});
|
|
122
|
+
const s = computeSnapshotStats(env, 5000);
|
|
123
|
+
expect(s.conversationTurns).toBe(1);
|
|
124
|
+
expect(s.totalBytes).toBeGreaterThan(0);
|
|
125
|
+
expect(s.ageMs).toBe(4000);
|
|
126
|
+
const line = formatSnapshotLine(s);
|
|
127
|
+
expect(line).toContain("SNAPSHOT");
|
|
128
|
+
expect(line).toContain(env.envelopeId);
|
|
129
|
+
});
|
|
130
|
+
it("24/7 RESILIENCE: 1000 random snapshots never crash", () => {
|
|
131
|
+
const rand = (n) => Math.floor(Math.random() * n);
|
|
132
|
+
for (let i = 0; i < 1000; i++) {
|
|
133
|
+
const env = captureSnapshot({
|
|
134
|
+
parentDeviceId: `p-${rand(100)}`,
|
|
135
|
+
conversation: Array.from({ length: rand(5) }, (_, j) => ({
|
|
136
|
+
role: ["user", "assistant", "system"][rand(3)],
|
|
137
|
+
text: `msg-${rand(10000)}`,
|
|
138
|
+
ts: rand(1_000_000),
|
|
139
|
+
})),
|
|
140
|
+
nowMs: rand(1_000_000),
|
|
141
|
+
secret: `s-${rand(50)}`,
|
|
142
|
+
});
|
|
143
|
+
expect(verifyEnvelope(env, env.parentDeviceId === "" ? undefined : undefined)).toBeDefined();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
//# sourceMappingURL=handoff_snapshot.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handoff_snapshot.test.js","sourceRoot":"","sources":["../../src/handoff_snapshot/handoff_snapshot.test.ts"],"names":[],"mappings":"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"}
|