@echomem/mcp 1.4.27 → 1.4.29
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/codex-session-files.js +20 -0
- package/dist/forensics.js +1 -1
- package/dist/index.js +26 -10
- package/dist/migrate.js +24 -11
- package/dist/package-metadata.js +2 -0
- package/dist/setup-page/client-core.js +24 -24
- package/dist/setup-page/client-extraction.js +217 -76
- package/dist/setup-page/client-report-city.js +142 -8
- package/dist/setup-page/styles-extraction.js +37 -0
- package/dist/setup-page/styles-mvp.js +239 -7
- package/dist/setup-page/styles-website-alignment.js +8 -3
- package/dist/setup-preview.js +11 -0
- package/dist/setup.js +261 -35
- package/dist/v1-contract.js +10 -9
- package/package.json +1 -1
- package/templates/codex-skills/echomem-search/SKILL.md +3 -2
|
@@ -169,8 +169,111 @@ export const SETUP_PAGE_CLIENT_REPORT_CITY = String.raw ` /* ---------- ful
|
|
|
169
169
|
setScanMode(false);
|
|
170
170
|
setCityMode(false);
|
|
171
171
|
}
|
|
172
|
+
function formatReportEta(seconds) {
|
|
173
|
+
seconds = Math.max(1, Math.round(seconds));
|
|
174
|
+
if (seconds >= 3600) {
|
|
175
|
+
var hours = Math.floor(seconds / 3600);
|
|
176
|
+
var minutesAfterHours = Math.ceil((seconds % 3600) / 60);
|
|
177
|
+
return "About " + hours + "h" + (minutesAfterHours ? " " + minutesAfterHours + "m" : "") + " remaining";
|
|
178
|
+
}
|
|
179
|
+
if (seconds >= 60) {
|
|
180
|
+
var minutes = Math.floor(seconds / 60);
|
|
181
|
+
var secondsAfterMinutes = seconds % 60;
|
|
182
|
+
return "About " + minutes + "m " + secondsAfterMinutes + "s remaining";
|
|
183
|
+
}
|
|
184
|
+
return "About " + seconds + "s remaining";
|
|
185
|
+
}
|
|
186
|
+
function estimateReportRemaining(progress, overall, stage) {
|
|
187
|
+
void overall;
|
|
188
|
+
var now = Date.now();
|
|
189
|
+
var stageElapsed = Math.max(0, Number(progress.stageElapsedMs || 0) / 1000);
|
|
190
|
+
var stageDone = Math.max(0, Number(progress.stageDone || 0));
|
|
191
|
+
var stageTotal = Math.max(0, Number(progress.stageTotal || 0));
|
|
192
|
+
function tickExistingEstimate() {
|
|
193
|
+
if (reportEtaDisplaySeconds <= 0) {
|
|
194
|
+
return { seconds: 0, overdue: false, calibrating: true };
|
|
195
|
+
}
|
|
196
|
+
var sinceLast = reportEtaUpdatedAt ? Math.max(0, (now - reportEtaUpdatedAt) / 1000) : 0;
|
|
197
|
+
reportEtaDisplaySeconds = Math.max(0, reportEtaDisplaySeconds - sinceLast);
|
|
198
|
+
reportEtaUpdatedAt = now;
|
|
199
|
+
return {
|
|
200
|
+
seconds: reportEtaDisplaySeconds,
|
|
201
|
+
overdue: now >= reportEtaDeadline || reportEtaDisplaySeconds <= 0,
|
|
202
|
+
calibrating: false,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// The visual progress bands describe work completed, not wall-clock cost. In particular,
|
|
207
|
+
// reaching the 75% classification band does NOT mean only 25% of the time remains.
|
|
208
|
+
// Calibrate only from movement inside the expensive classification stage.
|
|
209
|
+
if (stage !== "classifying-repeated-context") {
|
|
210
|
+
return tickExistingEstimate();
|
|
211
|
+
}
|
|
212
|
+
if (reportEtaStage !== stage) {
|
|
213
|
+
reportEtaStage = stage;
|
|
214
|
+
reportEtaStageDone = stageDone;
|
|
215
|
+
reportEtaStageElapsed = stageElapsed;
|
|
216
|
+
reportEtaObservedRate = 0;
|
|
217
|
+
return { seconds: 0, overdue: false, calibrating: true };
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// The first canonical completions can be cache hits and arrive almost instantly. Treat the
|
|
221
|
+
// first observation as a baseline, then measure only later movement over real elapsed time.
|
|
222
|
+
if (stageDone > reportEtaStageDone && stageElapsed > reportEtaStageElapsed) {
|
|
223
|
+
var sampleElapsed = stageElapsed - reportEtaStageElapsed;
|
|
224
|
+
var sampleDone = stageDone - reportEtaStageDone;
|
|
225
|
+
if (sampleElapsed >= 2 && sampleDone > 0) {
|
|
226
|
+
var sampleRate = sampleDone / sampleElapsed;
|
|
227
|
+
reportEtaObservedRate = reportEtaObservedRate > 0
|
|
228
|
+
? reportEtaObservedRate * 0.65 + sampleRate * 0.35
|
|
229
|
+
: sampleRate;
|
|
230
|
+
reportEtaStageDone = stageDone;
|
|
231
|
+
reportEtaStageElapsed = stageElapsed;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (
|
|
235
|
+
reportEtaObservedRate <= 0 ||
|
|
236
|
+
!isFinite(reportEtaObservedRate)
|
|
237
|
+
) {
|
|
238
|
+
return { seconds: 0, overdue: false, calibrating: true };
|
|
239
|
+
}
|
|
240
|
+
if (stageTotal <= stageDone) return tickExistingEstimate();
|
|
241
|
+
|
|
242
|
+
// Add a safety margin for the tail of slower sessions plus final report reconciliation.
|
|
243
|
+
// This intentionally prefers a slightly early completion over a fake three-second promise.
|
|
244
|
+
var observedRemaining = ((stageTotal - stageDone) / reportEtaObservedRate) * 1.35 + 5;
|
|
245
|
+
observedRemaining = Math.min(15 * 60, Math.max(8, observedRemaining));
|
|
246
|
+
|
|
247
|
+
if (!reportEtaDeadline) {
|
|
248
|
+
reportEtaDeadline = now + observedRemaining * 1000;
|
|
249
|
+
reportEtaDisplaySeconds = observedRemaining;
|
|
250
|
+
} else {
|
|
251
|
+
var sinceLast = reportEtaUpdatedAt ? Math.max(0, (now - reportEtaUpdatedAt) / 1000) : 0;
|
|
252
|
+
var clockRemaining = Math.max(0, reportEtaDisplaySeconds - sinceLast);
|
|
253
|
+
// A faster observed rate may shorten the estimate. A slower sample never pushes the
|
|
254
|
+
// countdown back upward; passing the first deadline changes the copy to "Finishing up".
|
|
255
|
+
reportEtaDisplaySeconds = Math.min(clockRemaining, observedRemaining);
|
|
256
|
+
}
|
|
257
|
+
reportEtaUpdatedAt = now;
|
|
258
|
+
return {
|
|
259
|
+
seconds: Math.max(0, reportEtaDisplaySeconds),
|
|
260
|
+
overdue: now >= reportEtaDeadline || reportEtaDisplaySeconds <= 0,
|
|
261
|
+
calibrating: false,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
172
264
|
function renderLoading() {
|
|
173
265
|
var progress = reportEnvelope && reportEnvelope.kind === "scanning" ? (reportEnvelope.progress || {}) : {};
|
|
266
|
+
var scanId = String(reportEnvelope && reportEnvelope.scanId || "");
|
|
267
|
+
if (scanId !== reportEtaScanId) {
|
|
268
|
+
reportEtaScanId = scanId;
|
|
269
|
+
reportEtaDeadline = 0;
|
|
270
|
+
reportEtaDisplaySeconds = 0;
|
|
271
|
+
reportEtaUpdatedAt = 0;
|
|
272
|
+
reportEtaStage = "";
|
|
273
|
+
reportEtaStageDone = 0;
|
|
274
|
+
reportEtaStageElapsed = 0;
|
|
275
|
+
reportEtaObservedRate = 0;
|
|
276
|
+
}
|
|
174
277
|
var scannedValue = Number(progress.scanned);
|
|
175
278
|
var totalValue = Number(progress.total);
|
|
176
279
|
var scanned = isFinite(scannedValue) ? Math.max(0, scannedValue) : 0;
|
|
@@ -182,26 +285,48 @@ export const SETUP_PAGE_CLIENT_REPORT_CITY = String.raw ` /* ---------- ful
|
|
|
182
285
|
var overall = isFinite(overallValue) ? Math.min(1, Math.max(0, overallValue)) : 0;
|
|
183
286
|
var pct = Math.round(overall * 100);
|
|
184
287
|
var stage = String(progress.stage || "starting");
|
|
288
|
+
var stageDone = Math.max(0, Number(progress.stageDone || 0));
|
|
289
|
+
var stageTotal = Math.max(0, Number(progress.stageTotal || 0));
|
|
290
|
+
var stageElapsed = Math.max(0, Number(progress.stageElapsedMs || 0));
|
|
291
|
+
var beat = Math.floor(stageElapsed / 4500);
|
|
185
292
|
var progressText = "";
|
|
186
293
|
if (total > 0 && stage === "reading-transcripts") {
|
|
187
294
|
progressText = "Reading " + number(visibleScanned) + " of " + number(total) + " sessions…";
|
|
188
|
-
} else if (stage === "building-summary"
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
295
|
+
} else if (stage === "building-summary") {
|
|
296
|
+
var summaryBeats = [
|
|
297
|
+
"Organizing what Echo found…",
|
|
298
|
+
"Building the report summary…"
|
|
299
|
+
];
|
|
300
|
+
progressText = summaryBeats[beat % summaryBeats.length];
|
|
301
|
+
} else if (stage === "classifying-repeated-context") {
|
|
302
|
+
var analysisCount = stageTotal > 0
|
|
303
|
+
? " · " + number(Math.min(stageDone, stageTotal)) + " of " + number(stageTotal)
|
|
304
|
+
: "";
|
|
305
|
+
var analysisBeats = [
|
|
306
|
+
"Comparing context across sessions" + analysisCount + "…",
|
|
307
|
+
"Finding repeated context" + analysisCount + "…",
|
|
308
|
+
"Separating useful context from noise" + analysisCount + "…"
|
|
309
|
+
];
|
|
310
|
+
progressText = analysisBeats[beat % analysisBeats.length];
|
|
192
311
|
} else if (stage === "finalizing-report") {
|
|
193
|
-
progressText = "Preparing your report…";
|
|
312
|
+
progressText = beat % 2 === 0 ? "Checking the report totals…" : "Preparing your report…";
|
|
194
313
|
}
|
|
314
|
+
var etaState = estimateReportRemaining(progress, overall, stage);
|
|
315
|
+
var etaText = etaState.overdue
|
|
316
|
+
? "Taking a little longer than estimated…"
|
|
317
|
+
: (etaState.seconds > 0 ? formatReportEta(etaState.seconds) : "Estimating time remaining…");
|
|
195
318
|
var fill = document.getElementById("scan-load-fill");
|
|
196
319
|
var caption = document.getElementById("scan-load-caption");
|
|
320
|
+
var eta = document.getElementById("scan-load-eta");
|
|
197
321
|
if (app.className === "scanLoading" && fill) {
|
|
198
322
|
fill.style.width = pct + "%";
|
|
199
323
|
fill.parentElement.setAttribute("aria-valuenow", String(pct));
|
|
200
|
-
fill.parentElement.setAttribute("aria-valuetext", progressText || "Preparing session count");
|
|
324
|
+
fill.parentElement.setAttribute("aria-valuetext", (progressText || "Preparing session count") + " " + etaText);
|
|
201
325
|
if (caption) {
|
|
202
326
|
caption.textContent = progressText;
|
|
203
327
|
caption.hidden = !progressText;
|
|
204
328
|
}
|
|
329
|
+
if (eta) eta.textContent = etaText;
|
|
205
330
|
return;
|
|
206
331
|
}
|
|
207
332
|
setScanMode(true);
|
|
@@ -210,10 +335,19 @@ export const SETUP_PAGE_CLIENT_REPORT_CITY = String.raw ` /* ---------- ful
|
|
|
210
335
|
app.innerHTML =
|
|
211
336
|
setupJourney(1) +
|
|
212
337
|
'<section class="mvpReading" aria-labelledby="scanLoadingTitle">' +
|
|
213
|
-
'<
|
|
338
|
+
'<span class="mvpReadingMascot scanMascotFrames" aria-hidden="true">' +
|
|
339
|
+
'<img class="scanMascotFrame" src="/hud-assets/scan-loop/frame-01-ready.png" alt="" />' +
|
|
340
|
+
'<img class="scanMascotFrame" src="/hud-assets/scan-loop/frame-02-open.png" alt="" />' +
|
|
341
|
+
'<img class="scanMascotFrame" src="/hud-assets/scan-loop/frame-03-pull.png" alt="" />' +
|
|
342
|
+
'<img class="scanMascotFrame" src="/hud-assets/scan-loop/frame-04-read.png" alt="" />' +
|
|
343
|
+
'<img class="scanMascotFrame" src="/hud-assets/scan-loop/frame-04-read.png" alt="" />' +
|
|
344
|
+
'<img class="scanMascotFrame" src="/hud-assets/scan-loop/frame-05-file.png" alt="" />' +
|
|
345
|
+
'<img class="scanMascotFrame" src="/hud-assets/scan-loop/frame-06-close.png" alt="" />' +
|
|
346
|
+
'</span>' +
|
|
214
347
|
'<h2 id="scanLoadingTitle">Building your report…</h2>' +
|
|
215
348
|
'<p class="mvpReadingCount" id="scan-load-caption" aria-live="polite"' + (progressText ? "" : " hidden") + '>' + esc(progressText) + '</p>' +
|
|
216
|
-
'<
|
|
349
|
+
'<p class="mvpReadingEta" id="scan-load-eta">' + esc(etaText) + '</p>' +
|
|
350
|
+
'<div class="scanProgress mvpReadingProgress" role="progressbar" aria-labelledby="scanLoadingTitle" aria-valuemin="0" aria-valuemax="100" aria-valuenow="' + pct + '" aria-valuetext="' + esc((progressText || "Preparing session count") + " " + etaText) + '">' +
|
|
217
351
|
'<i id="scan-load-fill" class="scanProgressFill" style="width:' + pct + '%"></i>' +
|
|
218
352
|
'</div>' +
|
|
219
353
|
'</section>';
|
|
@@ -1462,6 +1462,43 @@ export const SETUP_PAGE_STYLES_EXTRACTION = String.raw ` /* ---- dashboard (p
|
|
|
1462
1462
|
.savedHeading strong {
|
|
1463
1463
|
font-variant-numeric: tabular-nums;
|
|
1464
1464
|
}
|
|
1465
|
+
.firstRecallStage {
|
|
1466
|
+
display: flex;
|
|
1467
|
+
flex-direction: column;
|
|
1468
|
+
gap: clamp(22px, 3vw, 34px);
|
|
1469
|
+
}
|
|
1470
|
+
.firstRecallStage .resultTop h2 {
|
|
1471
|
+
max-width: none;
|
|
1472
|
+
margin: 0;
|
|
1473
|
+
color: var(--echo-ink-text);
|
|
1474
|
+
font-family: var(--echo-font-brand);
|
|
1475
|
+
font-size: clamp(42px, 6vw, 72px);
|
|
1476
|
+
font-weight: 700;
|
|
1477
|
+
line-height: 0.96;
|
|
1478
|
+
letter-spacing: -0.045em;
|
|
1479
|
+
}
|
|
1480
|
+
.firstRecallStage .savedHeading {
|
|
1481
|
+
display: block;
|
|
1482
|
+
}
|
|
1483
|
+
.firstRecallStage .savedHeading .savedMain {
|
|
1484
|
+
color: var(--echo-ink-text);
|
|
1485
|
+
}
|
|
1486
|
+
.firstRecallStage .savedHeading strong {
|
|
1487
|
+
color: var(--echo-ink-primary);
|
|
1488
|
+
font-weight: 900;
|
|
1489
|
+
}
|
|
1490
|
+
.firstRecallStage .tryCard {
|
|
1491
|
+
margin-top: 0;
|
|
1492
|
+
}
|
|
1493
|
+
.firstRecallStage .tryCard > .tryTitle {
|
|
1494
|
+
margin-bottom: 0;
|
|
1495
|
+
color: var(--echo-ink-primary);
|
|
1496
|
+
font-size: clamp(26px, 3vw, 38px);
|
|
1497
|
+
line-height: 1.04;
|
|
1498
|
+
}
|
|
1499
|
+
.firstRecallStage .recallPromptPrimary {
|
|
1500
|
+
margin-top: 18px;
|
|
1501
|
+
}
|
|
1465
1502
|
.viewEchoLink {
|
|
1466
1503
|
color: var(--echo-ink-mute);
|
|
1467
1504
|
font-style: normal;
|
|
@@ -14,7 +14,8 @@ export const SETUP_PAGE_STYLES_MVP = String.raw `
|
|
|
14
14
|
width: 100%;
|
|
15
15
|
min-height: 100vh;
|
|
16
16
|
margin: 0;
|
|
17
|
-
padding: clamp(
|
|
17
|
+
padding: clamp(12px, 1.8vw, 24px) clamp(18px, 5vw, 64px) clamp(38px, 6vw, 72px);
|
|
18
|
+
display: block;
|
|
18
19
|
}
|
|
19
20
|
main > header { display: none; }
|
|
20
21
|
#app.state { color: transparent; }
|
|
@@ -24,11 +25,17 @@ export const SETUP_PAGE_STYLES_MVP = String.raw `
|
|
|
24
25
|
width: 100%;
|
|
25
26
|
min-height: calc(100vh - clamp(56px, 10vw, 128px));
|
|
26
27
|
}
|
|
28
|
+
body.readyMode #app:has(> .setupJourney),
|
|
29
|
+
body.scanMode #app:has(> .setupJourney),
|
|
30
|
+
body.extractMode #app:has(> .setupJourney) {
|
|
31
|
+
padding-top: 0 !important;
|
|
32
|
+
}
|
|
27
33
|
|
|
28
34
|
/* One calm map across local scan, account/Stripe, import, and first value. */
|
|
29
35
|
.setupJourney {
|
|
30
36
|
width: min(760px, 100%);
|
|
31
|
-
|
|
37
|
+
flex: 0 0 auto;
|
|
38
|
+
margin: 0 auto 14px;
|
|
32
39
|
color: var(--echo-ink-faint);
|
|
33
40
|
}
|
|
34
41
|
.setupJourney ol {
|
|
@@ -93,12 +100,13 @@ export const SETUP_PAGE_STYLES_MVP = String.raw `
|
|
|
93
100
|
color: white;
|
|
94
101
|
}
|
|
95
102
|
body.cityMode .setupJourney {
|
|
96
|
-
margin-top:
|
|
103
|
+
margin-top: 12px;
|
|
97
104
|
margin-bottom: 8px;
|
|
98
105
|
padding-inline: 18px;
|
|
99
106
|
}
|
|
100
|
-
|
|
101
|
-
|
|
107
|
+
#setupJourneySlot {
|
|
108
|
+
width: 100%;
|
|
109
|
+
flex: 0 0 auto;
|
|
102
110
|
}
|
|
103
111
|
|
|
104
112
|
/* Permission ------------------------------------------------------------ */
|
|
@@ -277,6 +285,56 @@ export const SETUP_PAGE_STYLES_MVP = String.raw `
|
|
|
277
285
|
.localAuthWelcomeStage.localAuthPassphraseStage .localAuthWelcome {
|
|
278
286
|
margin: clamp(24px, 5vh, 48px) auto 0;
|
|
279
287
|
}
|
|
288
|
+
body.readyMode #app.localAuthCompleteStage {
|
|
289
|
+
min-height: calc(100vh - clamp(56px, 10vw, 128px));
|
|
290
|
+
display: grid;
|
|
291
|
+
place-items: center;
|
|
292
|
+
}
|
|
293
|
+
.localAuthComplete {
|
|
294
|
+
width: min(680px, 100%);
|
|
295
|
+
display: grid;
|
|
296
|
+
justify-items: center;
|
|
297
|
+
gap: 14px;
|
|
298
|
+
margin: 0 auto;
|
|
299
|
+
padding: clamp(24px, 5vw, 48px) 0;
|
|
300
|
+
color: var(--echo-ink-text);
|
|
301
|
+
text-align: center;
|
|
302
|
+
}
|
|
303
|
+
.localAuthComplete > img {
|
|
304
|
+
width: 76px;
|
|
305
|
+
height: 76px;
|
|
306
|
+
object-fit: contain;
|
|
307
|
+
filter: drop-shadow(0 12px 20px rgba(26,58,143,0.18));
|
|
308
|
+
}
|
|
309
|
+
.localAuthComplete h2 {
|
|
310
|
+
max-width: 100%;
|
|
311
|
+
margin: 4px 0 0;
|
|
312
|
+
color: var(--echo-ink-text);
|
|
313
|
+
font-family: var(--echo-font-brand);
|
|
314
|
+
font-size: clamp(42px, 6vw, 64px);
|
|
315
|
+
font-weight: 800;
|
|
316
|
+
letter-spacing: -0.055em;
|
|
317
|
+
line-height: 0.98;
|
|
318
|
+
white-space: nowrap;
|
|
319
|
+
}
|
|
320
|
+
.localAuthComplete p {
|
|
321
|
+
margin: 0;
|
|
322
|
+
color: var(--echo-ink-mute);
|
|
323
|
+
font-size: clamp(17px, 2.2vw, 22px);
|
|
324
|
+
line-height: 1.45;
|
|
325
|
+
}
|
|
326
|
+
.localAuthComplete .localAuthCompleteNext {
|
|
327
|
+
max-width: 460px;
|
|
328
|
+
margin-top: 2px;
|
|
329
|
+
color: var(--echo-ink-faint);
|
|
330
|
+
font-size: 14px;
|
|
331
|
+
}
|
|
332
|
+
.localAuthComplete code {
|
|
333
|
+
color: var(--echo-ink-primary);
|
|
334
|
+
}
|
|
335
|
+
@media (max-width: 560px) {
|
|
336
|
+
.localAuthComplete h2 { white-space: normal; }
|
|
337
|
+
}
|
|
280
338
|
.localAuthWelcome {
|
|
281
339
|
width: min(440px, 100%);
|
|
282
340
|
gap: 14px;
|
|
@@ -481,8 +539,13 @@ export const SETUP_PAGE_STYLES_MVP = String.raw `
|
|
|
481
539
|
|
|
482
540
|
/* Reading --------------------------------------------------------------- */
|
|
483
541
|
.scanLoading {
|
|
484
|
-
display:
|
|
485
|
-
|
|
542
|
+
display: flex !important;
|
|
543
|
+
flex-direction: column;
|
|
544
|
+
align-items: center;
|
|
545
|
+
justify-content: flex-start;
|
|
546
|
+
}
|
|
547
|
+
.scanLoading .mvpReading {
|
|
548
|
+
margin-block: auto;
|
|
486
549
|
}
|
|
487
550
|
.mvpReading {
|
|
488
551
|
display: flex;
|
|
@@ -515,12 +578,45 @@ export const SETUP_PAGE_STYLES_MVP = String.raw `
|
|
|
515
578
|
display: block;
|
|
516
579
|
visibility: hidden;
|
|
517
580
|
}
|
|
581
|
+
.mvpReadingEta {
|
|
582
|
+
min-height: 17px;
|
|
583
|
+
margin: 5px 0 0;
|
|
584
|
+
color: var(--echo-ink-faint);
|
|
585
|
+
font: 600 12px/1.4 var(--echo-font-mono);
|
|
586
|
+
font-variant-numeric: tabular-nums;
|
|
587
|
+
}
|
|
518
588
|
.mvpReadingProgress {
|
|
519
589
|
width: min(260px, 100%);
|
|
520
590
|
height: 3px;
|
|
521
591
|
margin: 8px 0 0;
|
|
522
592
|
background: rgba(26,58,143,0.12);
|
|
523
593
|
}
|
|
594
|
+
.discoveryLoader {
|
|
595
|
+
width: 100%;
|
|
596
|
+
min-height: min(62vh, 620px);
|
|
597
|
+
display: grid;
|
|
598
|
+
place-items: center;
|
|
599
|
+
}
|
|
600
|
+
.discoverySpinner span {
|
|
601
|
+
display: block;
|
|
602
|
+
width: 26px;
|
|
603
|
+
height: 26px;
|
|
604
|
+
border: 3px solid rgba(26,58,143,0.16);
|
|
605
|
+
border-top-color: var(--echo-ink-primary);
|
|
606
|
+
border-radius: 50%;
|
|
607
|
+
animation: localAuthSpin 700ms linear infinite;
|
|
608
|
+
}
|
|
609
|
+
.extractionStartStage {
|
|
610
|
+
display: flex !important;
|
|
611
|
+
flex-direction: column;
|
|
612
|
+
align-items: center;
|
|
613
|
+
justify-content: flex-start;
|
|
614
|
+
}
|
|
615
|
+
.extractionStartStage .discoverySpinner {
|
|
616
|
+
display: grid;
|
|
617
|
+
flex: 1 1 auto;
|
|
618
|
+
place-items: center;
|
|
619
|
+
}
|
|
524
620
|
.reportMessageStage {
|
|
525
621
|
display: flex !important;
|
|
526
622
|
justify-content: center;
|
|
@@ -890,6 +986,112 @@ export const SETUP_PAGE_STYLES_MVP = String.raw `
|
|
|
890
986
|
text-transform: uppercase;
|
|
891
987
|
}
|
|
892
988
|
.planGateAccount .setupAccountChange { min-height: 34px; }
|
|
989
|
+
.readyUtilityNav {
|
|
990
|
+
position: fixed;
|
|
991
|
+
top: 20px;
|
|
992
|
+
left: 22px;
|
|
993
|
+
z-index: 20;
|
|
994
|
+
display: grid;
|
|
995
|
+
width: min(310px, calc(100vw - 44px));
|
|
996
|
+
gap: 2px;
|
|
997
|
+
border: 1px solid rgba(26,58,143,0.10);
|
|
998
|
+
border-radius: 24px;
|
|
999
|
+
background: rgba(255,255,255,0.78);
|
|
1000
|
+
padding: 6px;
|
|
1001
|
+
box-shadow: 0 8px 24px rgba(26,58,143,0.08);
|
|
1002
|
+
backdrop-filter: blur(12px);
|
|
1003
|
+
}
|
|
1004
|
+
.readyUtilityNav .planGateAccount {
|
|
1005
|
+
position: static;
|
|
1006
|
+
top: auto;
|
|
1007
|
+
left: auto;
|
|
1008
|
+
z-index: auto;
|
|
1009
|
+
width: 100%;
|
|
1010
|
+
max-width: 100%;
|
|
1011
|
+
}
|
|
1012
|
+
.readyUtilityNav .planGateAccount .setupAccountCard {
|
|
1013
|
+
display: grid;
|
|
1014
|
+
width: 100%;
|
|
1015
|
+
min-height: 44px;
|
|
1016
|
+
grid-template-columns: 70px minmax(0, 1fr) auto;
|
|
1017
|
+
align-items: center;
|
|
1018
|
+
gap: 10px;
|
|
1019
|
+
border: 0;
|
|
1020
|
+
border-radius: 16px;
|
|
1021
|
+
background: transparent;
|
|
1022
|
+
padding: 5px 8px;
|
|
1023
|
+
box-shadow: none;
|
|
1024
|
+
backdrop-filter: none;
|
|
1025
|
+
}
|
|
1026
|
+
.readyUtilityNav .setupAccountCopy { display: contents; }
|
|
1027
|
+
.readyUtilityNav .setupAccountCopy small {
|
|
1028
|
+
grid-column: 1;
|
|
1029
|
+
margin: 0;
|
|
1030
|
+
align-self: center;
|
|
1031
|
+
}
|
|
1032
|
+
.readyUtilityNav .setupAccountCopy strong {
|
|
1033
|
+
grid-column: 2;
|
|
1034
|
+
overflow: hidden;
|
|
1035
|
+
align-self: center;
|
|
1036
|
+
text-overflow: ellipsis;
|
|
1037
|
+
white-space: nowrap;
|
|
1038
|
+
}
|
|
1039
|
+
.readyUtilityNav .setupAccountChange { grid-column: 3; }
|
|
1040
|
+
.readyPlanNav {
|
|
1041
|
+
display: grid;
|
|
1042
|
+
width: 100%;
|
|
1043
|
+
min-height: 44px;
|
|
1044
|
+
grid-template-columns: 70px minmax(0, 1fr);
|
|
1045
|
+
align-items: center;
|
|
1046
|
+
gap: 10px;
|
|
1047
|
+
border: 0;
|
|
1048
|
+
border-radius: 16px;
|
|
1049
|
+
background: transparent;
|
|
1050
|
+
padding: 5px 8px;
|
|
1051
|
+
box-shadow: none;
|
|
1052
|
+
backdrop-filter: none;
|
|
1053
|
+
}
|
|
1054
|
+
.readyPlanNav:has(.setupPlanSlot.is-hidden) { display: none; }
|
|
1055
|
+
.readyPlanNavLabel {
|
|
1056
|
+
grid-column: 1;
|
|
1057
|
+
color: var(--echo-ink-faint);
|
|
1058
|
+
font: 700 8px/1 var(--echo-font-mono);
|
|
1059
|
+
letter-spacing: 0.1em;
|
|
1060
|
+
text-transform: uppercase;
|
|
1061
|
+
}
|
|
1062
|
+
.readyPlanNav .setupPlanSlot {
|
|
1063
|
+
grid-column: 2;
|
|
1064
|
+
min-width: 0;
|
|
1065
|
+
}
|
|
1066
|
+
.readyPlanNav .setupPlanConfirmed {
|
|
1067
|
+
display: grid;
|
|
1068
|
+
min-width: 0;
|
|
1069
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
1070
|
+
margin: 0;
|
|
1071
|
+
align-items: center;
|
|
1072
|
+
gap: 8px;
|
|
1073
|
+
border: 0;
|
|
1074
|
+
background: transparent;
|
|
1075
|
+
padding: 0;
|
|
1076
|
+
box-shadow: none;
|
|
1077
|
+
}
|
|
1078
|
+
.readyPlanNav .setupPlanConfirmedIcon,
|
|
1079
|
+
.readyPlanNav .setupPlanConfirmedCopy > span { display: none; }
|
|
1080
|
+
.readyPlanNav .setupPlanConfirmedCopy { min-width: 0; }
|
|
1081
|
+
.readyPlanNav .setupPlanConfirmedCopy strong {
|
|
1082
|
+
display: block;
|
|
1083
|
+
overflow: hidden;
|
|
1084
|
+
color: var(--echo-ink-mute);
|
|
1085
|
+
font-size: 13px;
|
|
1086
|
+
font-weight: 500;
|
|
1087
|
+
text-overflow: ellipsis;
|
|
1088
|
+
white-space: nowrap;
|
|
1089
|
+
}
|
|
1090
|
+
.readyPlanNav .textButton {
|
|
1091
|
+
min-height: 34px;
|
|
1092
|
+
padding: 0 9px;
|
|
1093
|
+
font-size: 11px;
|
|
1094
|
+
}
|
|
893
1095
|
|
|
894
1096
|
/* Found sessions: one message, one next action -------------------------- */
|
|
895
1097
|
.readyDecision.extractionReady {
|
|
@@ -951,6 +1153,7 @@ export const SETUP_PAGE_STYLES_MVP = String.raw `
|
|
|
951
1153
|
line-height: 1.45;
|
|
952
1154
|
text-align: left;
|
|
953
1155
|
}
|
|
1156
|
+
.extractionReady .readyHero .exSub:empty { display: none; }
|
|
954
1157
|
.extractionReady .proofStrip {
|
|
955
1158
|
order: 1;
|
|
956
1159
|
width: fit-content;
|
|
@@ -996,6 +1199,7 @@ export const SETUP_PAGE_STYLES_MVP = String.raw `
|
|
|
996
1199
|
color: var(--echo-ink-faint);
|
|
997
1200
|
font-size: 11px;
|
|
998
1201
|
}
|
|
1202
|
+
.extractionReady .ctaMeta:empty { display: none; }
|
|
999
1203
|
.extractionReady .ctaMeta .dataHandlingLink { font-size: inherit; }
|
|
1000
1204
|
.extractionReady .readyFoot { order: 4; }
|
|
1001
1205
|
.billingCommitmentSlot {
|
|
@@ -1257,6 +1461,34 @@ export const SETUP_PAGE_STYLES_MVP = String.raw `
|
|
|
1257
1461
|
letter-spacing: -0.06em;
|
|
1258
1462
|
}
|
|
1259
1463
|
.sessionPickerHead p { margin-top: 12px; font-size: 14px; }
|
|
1464
|
+
.sessionPickerSummary {
|
|
1465
|
+
display: flex;
|
|
1466
|
+
flex-wrap: wrap;
|
|
1467
|
+
align-items: center;
|
|
1468
|
+
gap: 8px;
|
|
1469
|
+
}
|
|
1470
|
+
.sessionPickerQuota strong {
|
|
1471
|
+
color: var(--echo-ink-text);
|
|
1472
|
+
font-weight: 750;
|
|
1473
|
+
}
|
|
1474
|
+
.sessionPickerUpgrade {
|
|
1475
|
+
display: inline-flex;
|
|
1476
|
+
min-height: 30px;
|
|
1477
|
+
align-items: center;
|
|
1478
|
+
justify-content: center;
|
|
1479
|
+
border: 1px solid rgba(26,58,143,0.22);
|
|
1480
|
+
border-radius: 999px;
|
|
1481
|
+
background: rgba(255,255,255,0.78);
|
|
1482
|
+
padding: 0 12px;
|
|
1483
|
+
color: var(--echo-ink-primary);
|
|
1484
|
+
font-size: 12px;
|
|
1485
|
+
font-weight: 750;
|
|
1486
|
+
line-height: 1;
|
|
1487
|
+
text-decoration: none;
|
|
1488
|
+
box-shadow: 0 4px 12px rgba(26,58,143,0.07);
|
|
1489
|
+
}
|
|
1490
|
+
.sessionPickerUpgrade:hover { background: var(--echo-paper-white); }
|
|
1491
|
+
.sessionPickerOrder { color: var(--echo-ink-faint); }
|
|
1260
1492
|
.sessionPickerClose {
|
|
1261
1493
|
border: 0;
|
|
1262
1494
|
background: rgba(255,255,255,0.72);
|
|
@@ -162,7 +162,12 @@ export const SETUP_PAGE_STYLES_WEBSITE_ALIGNMENT = String.raw `
|
|
|
162
162
|
filter: drop-shadow(0 12px 14px rgba(26,58,143,0.16));
|
|
163
163
|
animation: scanMascotFrame 4.2s linear infinite;
|
|
164
164
|
}
|
|
165
|
-
|
|
165
|
+
/* Keep the ready pose mounted underneath every animated frame. This prevents
|
|
166
|
+
a transparent flash at loop boundaries or while a later PNG is decoding. */
|
|
167
|
+
.scanMascotFrame:nth-child(1) {
|
|
168
|
+
opacity: 1;
|
|
169
|
+
animation: none;
|
|
170
|
+
}
|
|
166
171
|
.scanMascotFrame:nth-child(2) { animation-delay: 0.6s; }
|
|
167
172
|
.scanMascotFrame:nth-child(3) { animation-delay: 1.2s; }
|
|
168
173
|
.scanMascotFrame:nth-child(4) { animation-delay: 1.8s; }
|
|
@@ -170,8 +175,8 @@ export const SETUP_PAGE_STYLES_WEBSITE_ALIGNMENT = String.raw `
|
|
|
170
175
|
.scanMascotFrame:nth-child(6) { animation-delay: 3s; }
|
|
171
176
|
.scanMascotFrame:nth-child(7) { animation-delay: 3.6s; }
|
|
172
177
|
@keyframes scanMascotFrame {
|
|
173
|
-
0%, 14.
|
|
174
|
-
14.
|
|
178
|
+
0%, 14.4% { opacity: 1; }
|
|
179
|
+
14.5%, 100% { opacity: 0; }
|
|
175
180
|
}
|
|
176
181
|
.scanLoaderCopy { min-width: 0; }
|
|
177
182
|
.scanEyebrow {
|
package/dist/setup-preview.js
CHANGED
|
@@ -21,7 +21,9 @@ export const SETUP_PREVIEW_STATES = [
|
|
|
21
21
|
"auth-login",
|
|
22
22
|
"auth-login-pro",
|
|
23
23
|
"auth-otp",
|
|
24
|
+
"auth-complete",
|
|
24
25
|
"checkout-pro-selected",
|
|
26
|
+
"checkout-pro-stale",
|
|
25
27
|
"auth-unlock",
|
|
26
28
|
"auth-setup",
|
|
27
29
|
"extract-run",
|
|
@@ -252,6 +254,7 @@ function extractionPreviewBootstrap(options) {
|
|
|
252
254
|
connected = true;
|
|
253
255
|
billingStatus = ${JSON.stringify(billingStatus)};
|
|
254
256
|
setupPlanChoice = ${JSON.stringify(options.selectFree ? "free" : options.selectedPlanChoice || "")};
|
|
257
|
+
pendingCheckoutSessionId = ${JSON.stringify(options.checkoutPending ? "cs_test_preview_pending_123" : "")};
|
|
255
258
|
stats = {
|
|
256
259
|
sessions: { total: ${candidateCount}, codex: ${Math.ceil(candidateCount * 0.68)}, claudeCode: ${Math.floor(candidateCount * 0.32)} },
|
|
257
260
|
migratable: {
|
|
@@ -400,7 +403,15 @@ export function renderSetupPreviewBootstrap(state) {
|
|
|
400
403
|
return `${watermark}
|
|
401
404
|
localAuthEmail = "preview@example.com";
|
|
402
405
|
renderLocalOtp("Verification code sent. Check your email inbox.");`;
|
|
406
|
+
if (state === "auth-complete")
|
|
407
|
+
return `${watermark}
|
|
408
|
+
renderLocalLoginComplete();`;
|
|
403
409
|
if (state === "checkout-pro-selected")
|
|
410
|
+
return `${watermark}${extractionPreviewBootstrap({
|
|
411
|
+
plan: "free", paid: false, trialAvailable: true, trialUsed: false,
|
|
412
|
+
quotaLimit: 100, quotaRemaining: 100, selectedPlanChoice: "pro", checkoutPending: true,
|
|
413
|
+
})}`;
|
|
414
|
+
if (state === "checkout-pro-stale")
|
|
404
415
|
return `${watermark}${extractionPreviewBootstrap({
|
|
405
416
|
plan: "free", paid: false, trialAvailable: true, trialUsed: false,
|
|
406
417
|
quotaLimit: 100, quotaRemaining: 100, selectedPlanChoice: "pro",
|