@echomem/mcp 1.4.18 → 1.4.19

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.
@@ -4,67 +4,65 @@ export const SETUP_PAGE_CLIENT_LIFECYCLE = String.raw ` /* ---------- scan-
4
4
  setScanMode(false);
5
5
  setCityMode(false);
6
6
  setExtractMode(false);
7
- setReadyMode(false);
7
+ setReadyMode(true);
8
8
  setHead("Local file access", "Consent");
9
9
  app.className = "consentStage";
10
10
  app.innerHTML =
11
- '<section class="localConsent">' +
12
- '<p class="consentEyebrow">Local visualization</p>' +
13
- '<h2>Let Echo scan locally to build your Agent Doctor view?</h2>' +
14
- '<p>Echo reads local Codex and Claude Code history on this machine only, then turns it into a private usage visualization. Nothing from this scan leaves your device.</p>' +
15
- '<div class="consentActions">' +
16
- '<button type="button" class="primary" id="allowLocalScan">Continue with local scan</button>' +
17
- '<button type="button" class="textButton" id="declineLocalScan">Skip the insight for now</button>' +
11
+ '<section class="localConsent localConsentAccess">' +
12
+ '<div class="consentLead">' +
13
+ '<p class="consentEyebrow">Local history access / required</p>' +
14
+ '<h2 class="siteHeadline">Let Echo read your <strong>local coding history?</strong></h2>' +
15
+ '<p class="consentIntro">Echo needs this access to find your local Codex and Claude Code sessions, build your private usage report, and prepare conversations for memory extraction.</p>' +
16
+ '<div class="consentLocalMark"><img src="/hud-assets/echo-face-cutout.png" alt="" /><span><strong>Processed on this Mac</strong><small>This scan does not send transcripts to EchoMem.</small></span></div>' +
17
+ '</div>' +
18
+ '<div class="consentDecision">' +
19
+ '<div class="consentScopeHead"><strong>What this access does</strong><span>Local scan</span></div>' +
20
+ '<div class="consentScope" aria-label="What this permission allows">' +
21
+ '<div><span class="consentScopeNumber" aria-hidden="true">01</span><p><strong>Reads supported session logs</strong><small>Only local Codex and Claude Code history on this device.</small></p></div>' +
22
+ '<div><span class="consentScopeNumber" aria-hidden="true">02</span><p><strong>Builds the Agent Doctor report</strong><small>Usage patterns and visualizations are computed locally.</small></p></div>' +
23
+ '<div><span class="consentScopeNumber" aria-hidden="true">03</span><p><strong>Keeps transcripts on this device</strong><small>Nothing is uploaded unless you later select conversations for memory extraction.</small></p></div>' +
24
+ '</div>' +
25
+ '<label class="consentCheck"><input type="checkbox" id="localScanConsentCheck" /><span><strong>I understand and allow this local scan</strong><small>Required for Agent Doctor and to choose local conversations for extraction.</small></span></label>' +
26
+ '<div class="consentActions">' +
27
+ '<button type="button" class="primary" id="allowLocalScan" disabled>Allow local scan</button>' +
28
+ '<button type="button" class="textButton" id="declineLocalScan">Not now</button>' +
29
+ '</div>' +
30
+ '<p class="consentFine" id="consentStatus" role="status" aria-live="polite"></p>' +
18
31
  '</div>' +
19
- '<p class="consentFine" id="consentStatus"></p>' +
20
32
  '</section>';
21
33
  var allow = document.getElementById("allowLocalScan");
22
34
  if (allow) allow.onclick = allowLocalScan;
35
+ var consentCheck = document.getElementById("localScanConsentCheck");
36
+ if (consentCheck && allow) consentCheck.onchange = function () {
37
+ allow.disabled = !consentCheck.checked;
38
+ if (consentCheck.checked) setConsentStatus("");
39
+ };
23
40
  var decline = document.getElementById("declineLocalScan");
24
41
  if (decline) decline.onclick = declineLocalScan;
25
42
  }
26
- function setConsentStatus(message) {
43
+ function setConsentStatus(message, tone) {
27
44
  var node = document.getElementById("consentStatus");
28
- if (node) node.textContent = message || "";
45
+ if (node) {
46
+ node.textContent = message || "";
47
+ node.classList.toggle("is-required", tone === "required");
48
+ }
29
49
  }
30
50
  async function allowLocalScan() {
31
51
  setConsentStatus("Starting local scan...");
32
52
  try {
33
53
  await postJson("/report-consent", { allowed: true });
54
+ localHistoryConsentGranted = true;
34
55
  await showReport();
35
56
  } catch (error) {
36
57
  renderReportIssue("CONSENT_SAVE_FAILED", error && error.message ? error.message : "Could not start the local scan.");
37
58
  }
38
59
  }
39
60
  async function declineLocalScan() {
40
- setConsentStatus("Skipping Agent Doctor...");
61
+ localHistoryConsentGranted = false;
41
62
  try {
42
63
  await postJson("/report-consent", { allowed: false });
43
64
  } catch (_) {}
44
- renderLocalScanSkipped();
45
- }
46
- function renderLocalScanSkipped() {
47
- setScanMode(false);
48
- setCityMode(false);
49
- setExtractMode(false);
50
- setReadyMode(true);
51
- setHead("Agent Doctor skipped", connected ? "Signed in" : "Optional");
52
- app.className = "consentStage";
53
- app.innerHTML =
54
- '<section class="localConsent">' +
55
- '<p class="consentEyebrow">Visualization skipped</p>' +
56
- '<h2>No problem. Echo can still set up memory.</h2>' +
57
- '<p>We will skip Agent Doctor and continue with EchoMem setup.</p>' +
58
- '<div class="consentActions">' +
59
- '<button type="button" class="primary" data-connect-echo>' + (connected ? "Continue setup" : "Connect EchoMem") + '</button>' +
60
- '<button type="button" class="textButton" id="changeConsent">Go back</button>' +
61
- '</div>' +
62
- '<p class="consentFine" data-signin-help></p>' +
63
- '<a class="button secondary hidden" data-signin-fallback target="_blank" rel="noopener noreferrer">Open sign-in</a>' +
64
- '</section>';
65
- bindConnect();
66
- var change = document.getElementById("changeConsent");
67
- if (change) change.onclick = renderLocalScanConsent;
65
+ setConsentStatus("Local history access is required to continue setup. Nothing will be scanned or uploaded unless you allow it.", "required");
68
66
  }
69
67
  async function showReport() {
70
68
  if (reportPollStarted) return;
@@ -138,6 +136,12 @@ export const SETUP_PAGE_CLIENT_LIFECYCLE = String.raw ` /* ---------- scan-
138
136
  if (event.origin !== location.origin) return;
139
137
  var data = event.data || {};
140
138
  if (data.type === "echomem:connected" && data.nonce === nonce) {
139
+ if (!localHistoryConsentGranted) {
140
+ closeAuthWindow();
141
+ renderLocalScanConsent();
142
+ setConsentStatus("Local history access is required before you can connect EchoMem or continue setup.", "required");
143
+ return;
144
+ }
141
145
  connected = true;
142
146
  closeAuthWindow();
143
147
  void waitForStats();
@@ -152,7 +156,27 @@ export const SETUP_PAGE_CLIENT_LIFECYCLE = String.raw ` /* ---------- scan-
152
156
  // Older builds cached a report under the nonce. It is never an authority now; the current
153
157
  // server envelope and scan identity are the only inputs allowed to unlock personalized UI.
154
158
  try { sessionStorage.removeItem("echomem:setup-report:" + nonce); } catch (_) {}
159
+ var configLoaded = false;
160
+ var consentRequired = true;
161
+ var consentGranted = false;
162
+ // Learn the auth URL, connection state, and server-side consent gate before routing.
163
+ try {
164
+ var cfg = await getJson("/config");
165
+ configLoaded = true;
166
+ authUrl = cfg.authUrl || authUrl;
167
+ switchAccountUrl = cfg.switchAccountUrl || switchAccountUrl || authUrl;
168
+ connected = !!cfg.connected;
169
+ workspacePath = cfg.workspacePath || workspacePath;
170
+ consentRequired = cfg.consentRequired !== false;
171
+ consentGranted = cfg.consentGranted === true;
172
+ localHistoryConsentGranted = consentGranted;
173
+ } catch (_) {}
155
174
  if (params.get("connected") === "1") {
175
+ if (!configLoaded || (consentRequired && !consentGranted)) {
176
+ renderLocalScanConsent();
177
+ setConsentStatus("Local history access is required before you can connect EchoMem or continue setup.", "required");
178
+ return;
179
+ }
156
180
  connected = true;
157
181
  if (notifyOpenerConnected()) {
158
182
  // Popup flow: hand the main tab back control, then this popup closes.
@@ -169,13 +193,10 @@ export const SETUP_PAGE_CLIENT_LIFECYCLE = String.raw ` /* ---------- scan-
169
193
  }
170
194
  return;
171
195
  }
172
- // Learn the auth URL + connection state before asking for optional local file access.
173
- try {
174
- var cfg = await getJson("/config");
175
- authUrl = cfg.authUrl || authUrl;
176
- connected = !!cfg.connected;
177
- workspacePath = cfg.workspacePath || workspacePath;
178
- } catch (_) {}
196
+ if (consentGranted) {
197
+ await showReport();
198
+ return;
199
+ }
179
200
  renderLocalScanConsent();
180
201
  }
181
202
  __ECHO_SETUP_STARTUP__;