@echomem/mcp 1.4.44 → 1.4.45
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 +28 -25
- package/dist/city/README.md +9 -0
- package/dist/city/echo-ai-city-only.html +2232 -0
- package/dist/city/echo-extraction-plate.html +330 -0
- package/dist/city/echo-face-cutout.png +0 -0
- package/dist/city/personality_stickers/bossy.png +0 -0
- package/dist/city/personality_stickers/ghosty.png +0 -0
- package/dist/city/personality_stickers/loopy.png +0 -0
- package/dist/city/personality_stickers/lusty.png +0 -0
- package/dist/city/personality_stickers/maxxy.png +0 -0
- package/dist/city/personality_stickers/tabby.png +0 -0
- package/dist/city/vendor/OrbitControls.js +1417 -0
- package/dist/city/vendor/RoundedBoxGeometry.js +155 -0
- package/dist/city/vendor/echo_general-file-21.riv +0 -0
- package/dist/city/vendor/rive.js +8139 -0
- package/dist/city/vendor/rive.wasm +0 -0
- package/dist/city/vendor/three.module.min.js +6 -0
- package/dist/context-analysis/claude-native-canonical.js +2 -2
- package/dist/context-analysis/vendored-canonical.js +2 -2
- package/dist/context-analysis/workspace-report.js +3 -3
- package/dist/forensics.js +1531 -0
- package/dist/hud/hooks.js +31 -43
- package/dist/index.js +79 -15
- package/dist/local-data-paths.js +38 -0
- package/dist/migrate.js +140 -70
- package/dist/report.js +721 -0
- package/dist/save-checkpoint-hook.js +1 -1
- package/dist/setup-page/client-core.js +372 -18
- package/dist/setup-page/client-extraction.js +204 -37
- package/dist/setup-page/client-lifecycle.js +101 -31
- package/dist/setup-page/client-report-audit.js +819 -0
- package/dist/setup-page/client-report-city.js +356 -0
- package/dist/setup-page/client-report.js +6 -0
- package/dist/setup-page/client.js +2 -0
- package/dist/setup-page/styles-city-report.js +880 -0
- package/dist/setup-page/styles-context-audit.js +470 -0
- package/dist/setup-page/styles-extraction.js +31 -1
- package/dist/setup-page/styles-foundation.js +89 -0
- package/dist/setup-page/styles-mvp.js +155 -10
- package/dist/setup-page/styles-website-alignment.js +204 -0
- package/dist/setup-page/styles.js +4 -0
- package/dist/setup-page.js +4 -4
- package/dist/setup-preview.js +212 -4
- package/dist/setup.js +702 -321
- package/dist/source-session.js +3 -9
- package/dist/v1-contract.js +8 -0
- package/package.json +7 -9
- package/dist/config-files.js +0 -63
- package/dist/local-jsonl.js +0 -87
- package/dist/onboarding-stats.js +0 -16
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Generated by splitting the previous inline setup page. Keep this source readable: it is emitted into one browser IIFE.
|
|
2
|
-
export const SETUP_PAGE_CLIENT_LIFECYCLE = String.raw ` /* ----------
|
|
3
|
-
function
|
|
2
|
+
export const SETUP_PAGE_CLIENT_LIFECYCLE = String.raw ` /* ---------- scan-first poll for the forensic report ---------- */
|
|
3
|
+
function renderLocalScanConsent() {
|
|
4
|
+
setScanMode(false);
|
|
5
|
+
setCityMode(false);
|
|
4
6
|
setExtractMode(false);
|
|
5
7
|
setReadyMode(true);
|
|
6
8
|
setHead("Local file access", "Consent");
|
|
@@ -12,15 +14,15 @@ export const SETUP_PAGE_CLIENT_LIFECYCLE = String.raw ` /* ---------- local
|
|
|
12
14
|
'<img class="mvpConsentEcho" src="/hud-assets/echo-face-cutout.png" alt="" />' +
|
|
13
15
|
'<div class="mvpConsentPitch">' +
|
|
14
16
|
'<h2 id="mvpConsentTitle">Start with the context you’ve already built.</h2>' +
|
|
15
|
-
'<p class="mvpConsentIntro">
|
|
17
|
+
'<p class="mvpConsentIntro">See what you keep re-explaining—and what’s worth carrying into future sessions.</p>' +
|
|
16
18
|
'</div>' +
|
|
17
19
|
'</div>' +
|
|
18
|
-
'<p class="mvpConsentTrustLine">Your history stays on
|
|
19
|
-
'<button type="button" class="primary mvpPrimary" id="
|
|
20
|
+
'<p class="mvpConsentTrustLine">Your history stays on your Mac until you choose what to import. ' + dataHandlingLink("Data handling") + '</p>' +
|
|
21
|
+
'<button type="button" class="primary mvpPrimary" id="allowLocalScan">Build my private report <span aria-hidden="true">→</span></button>' +
|
|
20
22
|
'<p class="consentFine" id="consentStatus" role="status" aria-live="polite"></p>' +
|
|
21
23
|
'</section>';
|
|
22
|
-
var allow = document.getElementById("
|
|
23
|
-
if (allow) allow.onclick =
|
|
24
|
+
var allow = document.getElementById("allowLocalScan");
|
|
25
|
+
if (allow) allow.onclick = allowLocalScan;
|
|
24
26
|
}
|
|
25
27
|
function setConsentStatus(message, tone) {
|
|
26
28
|
var node = document.getElementById("consentStatus");
|
|
@@ -29,26 +31,18 @@ export const SETUP_PAGE_CLIENT_LIFECYCLE = String.raw ` /* ---------- local
|
|
|
29
31
|
node.classList.toggle("is-required", tone === "required");
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
|
-
function
|
|
33
|
-
|
|
34
|
-
try { void refreshBillingStatus(); } catch (_) {}
|
|
35
|
-
void waitForStats();
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
rememberSetupPlanChoice("");
|
|
39
|
-
renderLocalLogin("");
|
|
40
|
-
}
|
|
41
|
-
async function allowLocalHistory() {
|
|
42
|
-
var allow = document.getElementById("allowLocalHistory");
|
|
34
|
+
async function allowLocalScan() {
|
|
35
|
+
var allow = document.getElementById("allowLocalScan");
|
|
43
36
|
if (allow) allow.disabled = true;
|
|
44
|
-
setConsentStatus("
|
|
37
|
+
setConsentStatus("Starting local scan...");
|
|
45
38
|
try {
|
|
46
|
-
await postJson("/
|
|
39
|
+
await postJson("/report-consent", { allowed: true }, 5000);
|
|
47
40
|
localHistoryConsentGranted = true;
|
|
48
|
-
|
|
41
|
+
await showReport();
|
|
49
42
|
} catch (error) {
|
|
50
43
|
// The localhost bridge may have accepted consent even if the browser loses the POST
|
|
51
|
-
// response while it swaps connections. Recover from the server's authoritative state
|
|
44
|
+
// response while it swaps connections. Recover from the server's authoritative state
|
|
45
|
+
// instead of leaving the user forever on "Starting local scan...".
|
|
52
46
|
try {
|
|
53
47
|
var configResponse = await fetchWithTimeout(
|
|
54
48
|
"/config?nonce=" + encodeURIComponent(nonce),
|
|
@@ -58,14 +52,80 @@ export const SETUP_PAGE_CLIENT_LIFECYCLE = String.raw ` /* ---------- local
|
|
|
58
52
|
var config = configResponse.ok ? await configResponse.json() : null;
|
|
59
53
|
if (config && config.consentGranted === true) {
|
|
60
54
|
localHistoryConsentGranted = true;
|
|
61
|
-
|
|
55
|
+
await showReport();
|
|
62
56
|
return;
|
|
63
57
|
}
|
|
64
58
|
} catch (_) {}
|
|
65
|
-
|
|
66
|
-
setConsentStatus(error && error.message ? error.message : "Could not save local-history access.", "required");
|
|
59
|
+
renderReportIssue("CONSENT_SAVE_FAILED", error && error.message ? error.message : "Could not start the local scan.");
|
|
67
60
|
}
|
|
68
61
|
}
|
|
62
|
+
async function showReport() {
|
|
63
|
+
if (reportPollStarted) return;
|
|
64
|
+
reportPollStarted = true;
|
|
65
|
+
if (!report) renderLoading();
|
|
66
|
+
try {
|
|
67
|
+
var fails = 0;
|
|
68
|
+
for (;;) {
|
|
69
|
+
if (decisionMade) return;
|
|
70
|
+
var res;
|
|
71
|
+
try {
|
|
72
|
+
res = await fetchWithTimeout("/report?nonce=" + encodeURIComponent(nonce), { credentials: "omit", cache: "no-store" }, 12000);
|
|
73
|
+
} catch (_) {
|
|
74
|
+
// Only a RUN of consecutive failures is a real bridge problem. A long scan that keeps
|
|
75
|
+
// answering valid 202 envelopes must never trip this.
|
|
76
|
+
fails++;
|
|
77
|
+
if (fails >= 8) { renderBridgeIssue(); return; }
|
|
78
|
+
await sleep(700);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (res.status === 403) {
|
|
82
|
+
renderReportIssue("SETUP_SESSION_INVALID", "This setup link is missing or has an invalid local session nonce.");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
var envelope;
|
|
86
|
+
try {
|
|
87
|
+
envelope = await res.json();
|
|
88
|
+
} catch (_) {
|
|
89
|
+
renderReportIssue("REPORT_RESPONSE_INVALID", "The local bridge returned a report response that could not be decoded.");
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
validateProductionReportEnvelope(envelope);
|
|
94
|
+
} catch (_) {
|
|
95
|
+
renderReportIssue("REPORT_SCHEMA_INVALID", "The local report failed its provenance or ledger consistency checks.");
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (res.status === 202 && envelope.kind === "scanning") {
|
|
99
|
+
fails = 0;
|
|
100
|
+
reportEnvelope = envelope;
|
|
101
|
+
scheduleReportToCity();
|
|
102
|
+
renderLoading();
|
|
103
|
+
await sleep(700);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (res.status === 200 && envelope.kind === "empty") {
|
|
107
|
+
renderEmptyReport();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (res.status === 200 && envelope.kind === "ready") {
|
|
111
|
+
reportEnvelope = envelope;
|
|
112
|
+
report = envelope.report;
|
|
113
|
+
try {
|
|
114
|
+
renderForensicReport();
|
|
115
|
+
} catch (_) {
|
|
116
|
+
renderReportIssue("RENDER_FAILED", "Your validated local report could not be rendered safely.");
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (envelope.kind === "failed") {
|
|
121
|
+
renderReportIssue(envelope.error.code, envelope.error.message);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
renderReportIssue("REPORT_STATE_MISMATCH", "The local bridge returned a report state that did not match its HTTP status.");
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
} finally { reportPollStarted = false; }
|
|
128
|
+
}
|
|
69
129
|
|
|
70
130
|
window.addEventListener("message", function (event) {
|
|
71
131
|
if (event.origin !== location.origin) return;
|
|
@@ -80,22 +140,27 @@ export const SETUP_PAGE_CLIENT_LIFECYCLE = String.raw ` /* ---------- local
|
|
|
80
140
|
rememberSetupPlanChoice("");
|
|
81
141
|
try { void refreshBillingStatus(); } catch (_) {}
|
|
82
142
|
void waitForStats();
|
|
143
|
+
} else if (data.type === "echomem:city-ready" && data.nonce === nonce) {
|
|
144
|
+
scheduleReportToCity();
|
|
145
|
+
} else if (data.type === "echomem:connect-click") {
|
|
146
|
+
onConnectClick();
|
|
83
147
|
}
|
|
84
148
|
});
|
|
85
149
|
async function init() {
|
|
86
150
|
if (!nonce) throw new Error("Missing setup nonce. Re-run echomem-mcp init.");
|
|
151
|
+
// Older builds cached a report under the nonce. It is never an authority now; the current
|
|
152
|
+
// server envelope and scan identity are the only inputs allowed to unlock personalized UI.
|
|
153
|
+
try { sessionStorage.removeItem("echomem:setup-report:" + nonce); } catch (_) {}
|
|
87
154
|
var configLoaded = false;
|
|
88
155
|
var consentRequired = true;
|
|
89
156
|
var consentGranted = false;
|
|
157
|
+
// Learn the connection state and server-side consent gate before routing.
|
|
90
158
|
try {
|
|
91
159
|
var cfg = await getJson("/config");
|
|
92
160
|
configLoaded = true;
|
|
93
161
|
connected = !!cfg.connected;
|
|
94
162
|
setupFlow = cfg.flow === "login" ? "login" : "onboarding";
|
|
95
163
|
workspacePath = cfg.workspacePath || workspacePath;
|
|
96
|
-
setupPlatform = cfg.platform || setupPlatform;
|
|
97
|
-
canOpenClaudeDesktop = !!(cfg.capabilities && cfg.capabilities.openClaudeDesktop);
|
|
98
|
-
canOpenAgentSessions = !!(cfg.capabilities && cfg.capabilities.openAgentSessions);
|
|
99
164
|
consentRequired = cfg.consentRequired !== false;
|
|
100
165
|
consentGranted = cfg.consentGranted === true;
|
|
101
166
|
localHistoryConsentGranted = consentGranted;
|
|
@@ -108,27 +173,32 @@ export const SETUP_PAGE_CLIENT_LIFECYCLE = String.raw ` /* ---------- local
|
|
|
108
173
|
if (!connected) rememberSetupPlanChoice("");
|
|
109
174
|
if (params.get("connected") === "1") {
|
|
110
175
|
if (!configLoaded || (consentRequired && !consentGranted)) {
|
|
111
|
-
|
|
176
|
+
renderLocalScanConsent();
|
|
112
177
|
setConsentStatus("Local history access is required before you can connect EchoMem or continue setup.", "required");
|
|
113
178
|
return;
|
|
114
179
|
}
|
|
115
180
|
connected = true;
|
|
116
181
|
if (notifyOpenerConnected()) {
|
|
182
|
+
// Popup flow: hand the main tab back control, then this popup closes.
|
|
117
183
|
setHead("EchoMem connected", "Done");
|
|
118
184
|
app.className = "notice";
|
|
119
185
|
app.innerHTML = '<h2 style="color:#203820">This device is connected</h2><p style="margin-top:10px">Returning to the local setup page...</p>';
|
|
186
|
+
// Fallback: if window.close() was blocked (auth opened as a tab, or the browser refused),
|
|
187
|
+
// this window would otherwise hang on "Returning..." forever. After a beat, take over here
|
|
188
|
+
// so the user always lands on the dashboard instead of a dead page.
|
|
120
189
|
setTimeout(function () { if (!window.closed) void waitForStats(); }, 1500);
|
|
121
190
|
} else {
|
|
191
|
+
// Same-tab fallback (popup was blocked): go straight to the extraction dashboard.
|
|
122
192
|
try { void refreshBillingStatus(); } catch (_) {}
|
|
123
193
|
void waitForStats();
|
|
124
194
|
}
|
|
125
195
|
return;
|
|
126
196
|
}
|
|
127
197
|
if (consentGranted) {
|
|
128
|
-
|
|
198
|
+
await showReport();
|
|
129
199
|
return;
|
|
130
200
|
}
|
|
131
|
-
|
|
201
|
+
renderLocalScanConsent();
|
|
132
202
|
}
|
|
133
203
|
__ECHO_SETUP_STARTUP__;
|
|
134
204
|
`;
|