@rubytech/create-maxy-code 0.1.476 → 0.1.478
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/package.json +1 -1
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1704-data-portal-standing-audit.md +673 -0
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1704-data-portal-standing-audit-design.md +177 -0
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1820-cpu-triage-admin-tools-design.md +97 -0
- package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.js +44 -0
- package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.js.map +1 -1
- package/payload/platform/lib/storage-broker/dist/audit.d.ts +56 -0
- package/payload/platform/lib/storage-broker/dist/audit.d.ts.map +1 -1
- package/payload/platform/lib/storage-broker/dist/audit.js +34 -0
- package/payload/platform/lib/storage-broker/dist/audit.js.map +1 -1
- package/payload/platform/lib/storage-broker/src/__tests__/audit.test.ts +70 -1
- package/payload/platform/lib/storage-broker/src/audit.ts +111 -0
- package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +7 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js +72 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/tools/cpu-triage.d.ts +94 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/cpu-triage.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/cpu-triage.js +229 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/cpu-triage.js.map +1 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +2 -2
- package/payload/platform/plugins/docs/references/admin-ui.md +1 -1
- package/payload/platform/plugins/email/PLUGIN.md +2 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/confirm-sent-copy.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/confirm-sent-copy.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/confirm-sent-copy.test.js +92 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/confirm-sent-copy.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.js +112 -12
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-send-sent-copy.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-send-sent-copy.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-send-sent-copy.test.js +54 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-send-sent-copy.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js +170 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/sent-copy-note.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/sent-copy-note.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/sent-copy-note.test.js +86 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/sent-copy-note.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/sent-copy-sweep.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/sent-copy-sweep.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/sent-copy-sweep.test.js +164 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/sent-copy-sweep.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/sent-ledger.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/sent-ledger.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/sent-ledger.test.js +82 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/sent-ledger.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +95 -0
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js +223 -0
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/sent-copy-note.d.ts +18 -0
- package/payload/platform/plugins/email/mcp/dist/lib/sent-copy-note.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/sent-copy-note.js +59 -0
- package/payload/platform/plugins/email/mcp/dist/lib/sent-copy-note.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/sent-copy-sweep.d.ts +48 -0
- package/payload/platform/plugins/email/mcp/dist/lib/sent-copy-sweep.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/sent-copy-sweep.js +79 -0
- package/payload/platform/plugins/email/mcp/dist/lib/sent-copy-sweep.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/sent-ledger.d.ts +44 -0
- package/payload/platform/plugins/email/mcp/dist/lib/sent-ledger.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/sent-ledger.js +63 -0
- package/payload/platform/plugins/email/mcp/dist/lib/sent-ledger.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/scripts/sent-copy-sweep.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/scripts/sent-copy-sweep.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/scripts/sent-copy-sweep.js +55 -0
- package/payload/platform/plugins/email/mcp/dist/scripts/sent-copy-sweep.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.js +64 -13
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js +11 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-send.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-send.js +16 -3
- package/payload/platform/plugins/email/mcp/dist/tools/email-send.js.map +1 -1
- package/payload/platform/plugins/email/references/email-reference.md +36 -0
- package/payload/platform/plugins/scheduling/mcp/dist/__tests__/sent-sweep-throttle.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/__tests__/sent-sweep-throttle.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/__tests__/sent-sweep-throttle.test.js +18 -0
- package/payload/platform/plugins/scheduling/mcp/dist/__tests__/sent-sweep-throttle.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block-sqlite.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block-sqlite.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block-sqlite.test.js +150 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block-sqlite.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block.test.js +248 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +90 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +105 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/sent-sweep-throttle.d.ts +13 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/sent-sweep-throttle.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/sent-sweep-throttle.js +10 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/sent-sweep-throttle.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +53 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +88 -10
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
- package/payload/platform/scripts/cpu-triage-run.sh +117 -0
- package/payload/platform/scripts/cpu-triage.sh +332 -0
- package/payload/platform/services/claude-session-manager/dist/activity-range.d.ts +40 -0
- package/payload/platform/services/claude-session-manager/dist/activity-range.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/activity-range.js +68 -0
- package/payload/platform/services/claude-session-manager/dist/activity-range.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/activity-rows.d.ts +40 -8
- package/payload/platform/services/claude-session-manager/dist/activity-rows.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/activity-rows.js +74 -7
- package/payload/platform/services/claude-session-manager/dist/activity-rows.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +2 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +9 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/server/{chunk-56WJMBQQ.js → chunk-3XLLTG6R.js} +14 -0
- package/payload/server/{chunk-LBCMFD4O.js → chunk-XGNRSM57.js} +129 -37
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/activity.html +6 -6
- package/payload/server/public/assets/{AdminLoginScreens-DximwPlS.js → AdminLoginScreens-DR5eLF-a.js} +1 -1
- package/payload/server/public/assets/AdminShell-D9zaUxPd.js +2 -0
- package/payload/server/public/assets/{Checkbox-DM-eHqOS.js → Checkbox-DcbbAIe5.js} +1 -1
- package/payload/server/public/assets/activity-C9P5NjEZ.js +1 -0
- package/payload/server/public/assets/{admin-CAkDnGdk.js → admin-D2KLZnQW.js} +1 -1
- package/payload/server/public/assets/{browser-DXl8hOoi.js → browser-CDWqEiCD.js} +1 -1
- package/payload/server/public/assets/{calendar-DP6hn4-6.js → calendar-BG7fOpbB.js} +1 -1
- package/payload/server/public/assets/chat-RyH-WYQC.js +1 -0
- package/payload/server/public/assets/chevron-left-DmXCr6nB.js +1 -0
- package/payload/server/public/assets/data-BaY_LkLR.js +1 -0
- package/payload/server/public/assets/{graph-CHcYoEJ5.js → graph-DRloNic4.js} +1 -1
- package/payload/server/public/assets/{graph-labels-CZykslZM.js → graph-labels-DD-GqS4v.js} +1 -1
- package/payload/server/public/assets/{maximize-2-31AZEcMS.js → maximize-2-CzDaBugs.js} +1 -1
- package/payload/server/public/assets/{operator-BGGpdsO_.js → operator-BZeeyait.js} +1 -1
- package/payload/server/public/assets/{page-BloC6ygA.js → page-B0obcg3b.js} +1 -1
- package/payload/server/public/assets/{page-DOeiiqbR.js → page-ef-6rRPL.js} +1 -1
- package/payload/server/public/assets/{public-CGgO6IZv.js → public-9D3MMOkC.js} +1 -1
- package/payload/server/public/assets/{rotate-ccw-BlAi6iFg.js → rotate-ccw-DXEKUhXP.js} +1 -1
- package/payload/server/public/assets/tasks-BB0L7e5a.js +1 -0
- package/payload/server/public/assets/{time-entry-format-CiUUQdq7.js → time-entry-format-CsYAjplS.js} +1 -1
- package/payload/server/public/assets/{triangle-alert-CVqKuLoa.js → triangle-alert-0lSBIUg-.js} +1 -1
- package/payload/server/public/assets/{useCopyFeedback-ksyUe_g1.js → useCopyFeedback-jTBQ2h0V.js} +1 -1
- package/payload/server/public/assets/{useSelectionMode-BPrBkdTd.js → useSelectionMode-BooArySZ.js} +1 -1
- package/payload/server/public/assets/useSubAccountSwitcher-D9knHOKq.css +1 -0
- package/payload/server/public/assets/{useVoiceRecorder-CTXP8oTW.js → useVoiceRecorder-PUT8q_sm.js} +1 -1
- package/payload/server/public/browser.html +5 -5
- package/payload/server/public/calendar.html +6 -6
- package/payload/server/public/chat.html +12 -12
- package/payload/server/public/data.html +11 -11
- package/payload/server/public/graph.html +11 -11
- package/payload/server/public/index.html +14 -14
- package/payload/server/public/operator.html +14 -14
- package/payload/server/public/public.html +12 -12
- package/payload/server/public/tasks.html +5 -5
- package/payload/server/server.js +325 -77
- package/payload/server/{src-JYPKMWJR.js → src-XQ63FPRE.js} +3 -1
- package/payload/server/public/assets/AdminShell-BehbH-Oa.js +0 -2
- package/payload/server/public/assets/activity-hDwUeQd6.js +0 -1
- package/payload/server/public/assets/chat-DhOfVGYM.js +0 -1
- package/payload/server/public/assets/chevron-left-DYNBoLii.js +0 -1
- package/payload/server/public/assets/data-bq8fTo_s.js +0 -1
- package/payload/server/public/assets/tasks-C1giFRRL.js +0 -1
- package/payload/server/public/assets/useSubAccountSwitcher-K4kYeN6i.css +0 -1
- /package/payload/server/public/assets/{useSubAccountSwitcher-DzgzTRRn.js → useSubAccountSwitcher-BZnzc5C3.js} +0 -0
|
@@ -481,6 +481,19 @@ async function reconcilePages(deps) {
|
|
|
481
481
|
phantoms: [...regSet].filter((name) => !cfSet.has(name))
|
|
482
482
|
};
|
|
483
483
|
}
|
|
484
|
+
function reconcileDataPortal(objects, rows, nowMs) {
|
|
485
|
+
const objectKeys = new Set(objects.map((o) => o.key));
|
|
486
|
+
const rowKeys = new Set(rows.map((r) => r.objectKey));
|
|
487
|
+
const uningestedMs = rows.filter((r) => r.ingested === 0).map((r) => Date.parse(r.uploadedAt)).filter((ms) => !Number.isNaN(ms));
|
|
488
|
+
const oldestMs = uningestedMs.reduce((min, ms) => ms < min ? ms : min, Infinity);
|
|
489
|
+
return {
|
|
490
|
+
distinctObjects: objectKeys.size,
|
|
491
|
+
distinctRows: rowKeys.size,
|
|
492
|
+
orphanObjects: [...objectKeys].filter((k) => !rowKeys.has(k)),
|
|
493
|
+
phantomRows: [...rowKeys].filter((k) => !objectKeys.has(k)),
|
|
494
|
+
oldestUningestedHrs: uningestedMs.length === 0 ? null : (nowMs - oldestMs) / 36e5
|
|
495
|
+
};
|
|
496
|
+
}
|
|
484
497
|
|
|
485
498
|
// ../lib/storage-broker/src/remediate.ts
|
|
486
499
|
var STRIP_KEYS = [
|
|
@@ -523,6 +536,7 @@ export {
|
|
|
523
536
|
makeHousePagesExec,
|
|
524
537
|
reconcileStorage,
|
|
525
538
|
reconcilePages,
|
|
539
|
+
reconcileDataPortal,
|
|
526
540
|
validateMapping,
|
|
527
541
|
stripAccountWideTokens
|
|
528
542
|
};
|
|
@@ -2658,9 +2658,77 @@ var serve = (options, listeningListener) => {
|
|
|
2658
2658
|
};
|
|
2659
2659
|
|
|
2660
2660
|
// server/loop-registry.ts
|
|
2661
|
+
import { readFileSync } from "fs";
|
|
2661
2662
|
var TAG = "[loop-registry]";
|
|
2662
2663
|
var STALL_INTERVALS = 3;
|
|
2663
2664
|
var entries = /* @__PURE__ */ new Map();
|
|
2665
|
+
var defaultCpuIo = {
|
|
2666
|
+
ownCpuUs: () => {
|
|
2667
|
+
const u = process.cpuUsage();
|
|
2668
|
+
return u.user + u.system;
|
|
2669
|
+
},
|
|
2670
|
+
childCpuUs: (pid) => readPidCpuUs(pid)
|
|
2671
|
+
};
|
|
2672
|
+
var cpuIo = defaultCpuIo;
|
|
2673
|
+
function parsePidStatCpuUs(raw2) {
|
|
2674
|
+
const close = raw2.lastIndexOf(")");
|
|
2675
|
+
if (close === -1) return null;
|
|
2676
|
+
const after = raw2.slice(close + 2).split(" ");
|
|
2677
|
+
const utime = Number(after[11]);
|
|
2678
|
+
const stime = Number(after[12]);
|
|
2679
|
+
if (!Number.isFinite(utime) || !Number.isFinite(stime)) return null;
|
|
2680
|
+
return (utime + stime) / 100 * 1e6;
|
|
2681
|
+
}
|
|
2682
|
+
function readPidCpuUs(pid) {
|
|
2683
|
+
if (process.platform !== "linux") return null;
|
|
2684
|
+
try {
|
|
2685
|
+
return parsePidStatCpuUs(readFileSync(`/proc/${pid}/stat`, "utf8"));
|
|
2686
|
+
} catch {
|
|
2687
|
+
return null;
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
function sampleCpu(nowMs = Date.now()) {
|
|
2691
|
+
for (const e of entries.values()) {
|
|
2692
|
+
if (!e.cpuAttributable) {
|
|
2693
|
+
e.cpuPct = null;
|
|
2694
|
+
continue;
|
|
2695
|
+
}
|
|
2696
|
+
let childUs = 0;
|
|
2697
|
+
for (const pid of [...e.children]) {
|
|
2698
|
+
const us = cpuIo.childCpuUs(pid);
|
|
2699
|
+
if (us === null) {
|
|
2700
|
+
e.children.delete(pid);
|
|
2701
|
+
continue;
|
|
2702
|
+
}
|
|
2703
|
+
childUs += us;
|
|
2704
|
+
}
|
|
2705
|
+
e.lastChildCpuUs = Math.max(e.lastChildCpuUs, childUs);
|
|
2706
|
+
const totalUs = e.cumulativeCpuUs + e.lastChildCpuUs;
|
|
2707
|
+
const p = e.prior;
|
|
2708
|
+
if (p) {
|
|
2709
|
+
const wallUs = (nowMs - p.atMs) * 1e3;
|
|
2710
|
+
e.cpuPct = wallUs > 0 && totalUs >= p.cpuUs ? (totalUs - p.cpuUs) / wallUs * 100 : null;
|
|
2711
|
+
} else {
|
|
2712
|
+
e.cpuPct = null;
|
|
2713
|
+
}
|
|
2714
|
+
e.prior = { cpuUs: totalUs, atMs: nowMs };
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
var processPrior = null;
|
|
2718
|
+
function sampleProcessCpu(nowMs = Date.now()) {
|
|
2719
|
+
const cpuUs = cpuIo.ownCpuUs();
|
|
2720
|
+
let processPct = null;
|
|
2721
|
+
if (processPrior) {
|
|
2722
|
+
const wallUs = (nowMs - processPrior.atMs) * 1e3;
|
|
2723
|
+
if (wallUs > 0) processPct = (cpuUs - processPrior.cpuUs) / wallUs * 100;
|
|
2724
|
+
}
|
|
2725
|
+
processPrior = { cpuUs, atMs: nowMs };
|
|
2726
|
+
const rows = [...entries.values()];
|
|
2727
|
+
const measured = rows.filter((e) => e.cpuPct !== null);
|
|
2728
|
+
const attributedPct = measured.length === 0 ? null : measured.reduce((sum, e) => sum + (e.cpuPct ?? 0), 0);
|
|
2729
|
+
const unattributedPct = processPct === null || attributedPct === null ? null : Math.max(0, processPct - attributedPct);
|
|
2730
|
+
return { processPct, attributedPct, unattributedPct };
|
|
2731
|
+
}
|
|
2664
2732
|
function messageOf(err) {
|
|
2665
2733
|
return err instanceof Error ? err.message : String(err);
|
|
2666
2734
|
}
|
|
@@ -2682,6 +2750,7 @@ function finish(e, startedAt, cpuStart, cpuAttributable, note, err) {
|
|
|
2682
2750
|
e.lastOutcome = "ok";
|
|
2683
2751
|
e.lastError = null;
|
|
2684
2752
|
e.lastNote = typeof note === "string" && note.length > 0 ? note : null;
|
|
2753
|
+
e.lastSuccessMs = Date.now();
|
|
2685
2754
|
e.successCount += 1;
|
|
2686
2755
|
e.consecutiveFailures = 0;
|
|
2687
2756
|
}
|
|
@@ -2695,20 +2764,29 @@ function invoke(e) {
|
|
|
2695
2764
|
e.lastStartMs = Date.now();
|
|
2696
2765
|
const startedAt = e.lastStartMs;
|
|
2697
2766
|
const cpuStart = process.cpuUsage();
|
|
2767
|
+
const ownStartUs = cpuIo.ownCpuUs();
|
|
2768
|
+
const ctx = {
|
|
2769
|
+
child: (pid) => {
|
|
2770
|
+
if (typeof pid === "number" && Number.isFinite(pid)) e.children.add(pid);
|
|
2771
|
+
}
|
|
2772
|
+
};
|
|
2698
2773
|
let result;
|
|
2699
2774
|
try {
|
|
2700
|
-
result = e.spec.run();
|
|
2775
|
+
result = e.spec.run(ctx);
|
|
2701
2776
|
} catch (err) {
|
|
2777
|
+
e.cumulativeCpuUs += Math.max(0, cpuIo.ownCpuUs() - ownStartUs);
|
|
2702
2778
|
finish(e, startedAt, cpuStart, true, null, err);
|
|
2703
2779
|
return;
|
|
2704
2780
|
}
|
|
2705
2781
|
if (result instanceof Promise) {
|
|
2782
|
+
e.cpuAttributable = false;
|
|
2706
2783
|
result.then(
|
|
2707
2784
|
(note) => finish(e, startedAt, cpuStart, false, note, null),
|
|
2708
2785
|
(err) => finish(e, startedAt, cpuStart, false, null, err)
|
|
2709
2786
|
);
|
|
2710
2787
|
return;
|
|
2711
2788
|
}
|
|
2789
|
+
e.cumulativeCpuUs += Math.max(0, cpuIo.ownCpuUs() - ownStartUs);
|
|
2712
2790
|
finish(e, startedAt, cpuStart, true, result, null);
|
|
2713
2791
|
}
|
|
2714
2792
|
function registerLoop(spec) {
|
|
@@ -2719,6 +2797,7 @@ function registerLoop(spec) {
|
|
|
2719
2797
|
spec,
|
|
2720
2798
|
armedAtMs: Date.now(),
|
|
2721
2799
|
lastStartMs: null,
|
|
2800
|
+
lastSuccessMs: null,
|
|
2722
2801
|
lastDurationMs: null,
|
|
2723
2802
|
lastCpuMs: null,
|
|
2724
2803
|
lastOutcome: null,
|
|
@@ -2728,7 +2807,13 @@ function registerLoop(spec) {
|
|
|
2728
2807
|
successCount: 0,
|
|
2729
2808
|
consecutiveFailures: 0,
|
|
2730
2809
|
running: false,
|
|
2731
|
-
timers: []
|
|
2810
|
+
timers: [],
|
|
2811
|
+
cumulativeCpuUs: 0,
|
|
2812
|
+
cpuAttributable: true,
|
|
2813
|
+
children: /* @__PURE__ */ new Set(),
|
|
2814
|
+
lastChildCpuUs: 0,
|
|
2815
|
+
prior: null,
|
|
2816
|
+
cpuPct: null
|
|
2732
2817
|
};
|
|
2733
2818
|
entries.set(spec.name, e);
|
|
2734
2819
|
const interval = setInterval(() => invoke(e), spec.intervalMs);
|
|
@@ -2754,7 +2839,9 @@ function registerLoop(spec) {
|
|
|
2754
2839
|
};
|
|
2755
2840
|
}
|
|
2756
2841
|
function stateOf(e, nowMs) {
|
|
2757
|
-
if (e.lastStartMs === null)
|
|
2842
|
+
if (e.lastStartMs === null) {
|
|
2843
|
+
return nowMs - e.armedAtMs < e.spec.intervalMs ? "waiting" : "never-run";
|
|
2844
|
+
}
|
|
2758
2845
|
const overdue = nowMs - e.lastStartMs > e.spec.intervalMs * STALL_INTERVALS;
|
|
2759
2846
|
if (overdue) return "stalled";
|
|
2760
2847
|
if (e.running) return "running";
|
|
@@ -2774,8 +2861,11 @@ function listLoops(nowMs = Date.now()) {
|
|
|
2774
2861
|
detached: e.spec.detached === true,
|
|
2775
2862
|
armedAtMs: e.armedAtMs,
|
|
2776
2863
|
lastStartMs: e.lastStartMs,
|
|
2864
|
+
lastSuccessMs: e.lastSuccessMs,
|
|
2777
2865
|
lastDurationMs: e.lastDurationMs,
|
|
2778
2866
|
lastCpuMs: e.lastCpuMs,
|
|
2867
|
+
cpuPct: e.cpuPct,
|
|
2868
|
+
cpuAttributable: e.cpuAttributable,
|
|
2779
2869
|
lastOutcome: e.lastOutcome,
|
|
2780
2870
|
lastError: e.lastError,
|
|
2781
2871
|
lastNote: e.lastNote,
|
|
@@ -2794,7 +2884,7 @@ function armedCount() {
|
|
|
2794
2884
|
// app/lib/paths.ts
|
|
2795
2885
|
import { homedir } from "os";
|
|
2796
2886
|
import { resolve, join } from "path";
|
|
2797
|
-
import { existsSync, readFileSync } from "fs";
|
|
2887
|
+
import { existsSync, readFileSync as readFileSync2 } from "fs";
|
|
2798
2888
|
var configDirName = ".maxy";
|
|
2799
2889
|
var commercialMode = false;
|
|
2800
2890
|
var bundleMode = "none";
|
|
@@ -2810,7 +2900,7 @@ if (platformRoot) {
|
|
|
2810
2900
|
if (existsSync(brandPath)) {
|
|
2811
2901
|
let brand;
|
|
2812
2902
|
try {
|
|
2813
|
-
brand = JSON.parse(
|
|
2903
|
+
brand = JSON.parse(readFileSync2(brandPath, "utf-8"));
|
|
2814
2904
|
} catch (err) {
|
|
2815
2905
|
const detail = (err instanceof Error ? err.message : String(err)).slice(0, 160);
|
|
2816
2906
|
console.error(`[paths] error reason=brand-config-missing path=${brandPath} detail="parse failed: ${detail.replace(/"/g, "'")}"`);
|
|
@@ -2926,7 +3016,7 @@ function websockifyLog(event, fields = {}) {
|
|
|
2926
3016
|
|
|
2927
3017
|
// ../lib/admin-access-password/src/index.ts
|
|
2928
3018
|
import { scrypt, randomBytes, timingSafeEqual } from "crypto";
|
|
2929
|
-
import { existsSync as existsSync2, readFileSync as
|
|
3019
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3, writeFileSync, renameSync, unlinkSync, appendFileSync as appendFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
2930
3020
|
import { dirname } from "path";
|
|
2931
3021
|
var SCRYPT_N = 16384;
|
|
2932
3022
|
var SCRYPT_R = 8;
|
|
@@ -2982,7 +3072,7 @@ async function matchesHash(password, stored) {
|
|
|
2982
3072
|
}
|
|
2983
3073
|
function readUsers(usersFile) {
|
|
2984
3074
|
if (!existsSync2(usersFile)) return [];
|
|
2985
|
-
const raw2 =
|
|
3075
|
+
const raw2 = readFileSync3(usersFile, "utf-8").trim();
|
|
2986
3076
|
if (!raw2) return [];
|
|
2987
3077
|
const parsed = JSON.parse(raw2);
|
|
2988
3078
|
if (!Array.isArray(parsed)) throw new Error("users.json is not an array");
|
|
@@ -3054,7 +3144,7 @@ function accessStoreUnreadable(usersFile) {
|
|
|
3054
3144
|
}
|
|
3055
3145
|
function migrateLegacyRemotePassword(usersFile, legacyFile, ownerUserId, audit) {
|
|
3056
3146
|
if (!existsSync2(legacyFile)) return "noop-no-legacy";
|
|
3057
|
-
const legacy =
|
|
3147
|
+
const legacy = readFileSync3(legacyFile, "utf-8").trim();
|
|
3058
3148
|
const users = readUsers(usersFile);
|
|
3059
3149
|
const idx = users.findIndex((u) => u.userId === ownerUserId);
|
|
3060
3150
|
if (idx === -1) return "noop-no-owner";
|
|
@@ -3076,7 +3166,7 @@ function migrateLegacyRemotePassword(usersFile, legacyFile, ownerUserId, audit)
|
|
|
3076
3166
|
}
|
|
3077
3167
|
function readLegacyRemoteHash(legacyFile) {
|
|
3078
3168
|
if (!existsSync2(legacyFile)) return null;
|
|
3079
|
-
const raw2 =
|
|
3169
|
+
const raw2 = readFileSync3(legacyFile, "utf-8").trim();
|
|
3080
3170
|
return raw2.includes(":") ? raw2 : null;
|
|
3081
3171
|
}
|
|
3082
3172
|
|
|
@@ -3095,7 +3185,7 @@ function isPasswordValid(password) {
|
|
|
3095
3185
|
|
|
3096
3186
|
// app/lib/remote-auth.ts
|
|
3097
3187
|
import { scrypt as scrypt2, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2, createHmac } from "crypto";
|
|
3098
|
-
import { readFileSync as
|
|
3188
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "fs";
|
|
3099
3189
|
import { dirname as dirname2 } from "path";
|
|
3100
3190
|
var SCRYPT_N2 = 16384;
|
|
3101
3191
|
var SCRYPT_R2 = 8;
|
|
@@ -3141,7 +3231,7 @@ var cachedSecret = null;
|
|
|
3141
3231
|
function getSecret() {
|
|
3142
3232
|
if (cachedSecret) return cachedSecret;
|
|
3143
3233
|
try {
|
|
3144
|
-
const hex2 =
|
|
3234
|
+
const hex2 = readFileSync4(REMOTE_SESSION_SECRET_FILE, "utf-8").trim();
|
|
3145
3235
|
if (hex2.length === SECRET_BYTES * 2) {
|
|
3146
3236
|
cachedSecret = Buffer.from(hex2, "hex");
|
|
3147
3237
|
return cachedSecret;
|
|
@@ -3154,7 +3244,7 @@ function getSecret() {
|
|
|
3154
3244
|
writeFileSync2(REMOTE_SESSION_SECRET_FILE, fresh, { mode: 384, flag: "wx" });
|
|
3155
3245
|
} catch {
|
|
3156
3246
|
}
|
|
3157
|
-
const hex =
|
|
3247
|
+
const hex = readFileSync4(REMOTE_SESSION_SECRET_FILE, "utf-8").trim();
|
|
3158
3248
|
cachedSecret = Buffer.from(hex, "hex");
|
|
3159
3249
|
return cachedSecret;
|
|
3160
3250
|
}
|
|
@@ -3819,13 +3909,13 @@ function classifyHost(host, operatorDomains2, isPublicHost) {
|
|
|
3819
3909
|
import { watchFile } from "fs";
|
|
3820
3910
|
|
|
3821
3911
|
// app/lib/operator-domains.ts
|
|
3822
|
-
import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as
|
|
3912
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
3823
3913
|
import { dirname as dirname3, resolve as resolve3 } from "path";
|
|
3824
3914
|
var OPERATOR_DOMAINS_PATH = resolve3(MAXY_DIR, "operator-domains.json");
|
|
3825
3915
|
function loadOperatorDomains() {
|
|
3826
3916
|
if (!existsSync3(OPERATOR_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
|
|
3827
3917
|
try {
|
|
3828
|
-
const parsed = JSON.parse(
|
|
3918
|
+
const parsed = JSON.parse(readFileSync5(OPERATOR_DOMAINS_PATH, "utf-8"));
|
|
3829
3919
|
if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
|
|
3830
3920
|
return new Set(parsed.filter((h) => typeof h === "string"));
|
|
3831
3921
|
} catch {
|
|
@@ -3852,11 +3942,11 @@ function getOperatorDomains() {
|
|
|
3852
3942
|
|
|
3853
3943
|
// app/lib/claude-agent/account.ts
|
|
3854
3944
|
import { resolve as resolve4 } from "path";
|
|
3855
|
-
import { readFileSync as
|
|
3945
|
+
import { readFileSync as readFileSync7, readdirSync, existsSync as existsSync5, statSync } from "fs";
|
|
3856
3946
|
|
|
3857
3947
|
// ../lib/brand-templating/src/index.ts
|
|
3858
3948
|
import { join as join2 } from "path";
|
|
3859
|
-
import { existsSync as existsSync4, readFileSync as
|
|
3949
|
+
import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs";
|
|
3860
3950
|
var PLACEHOLDER = "{{productName}}";
|
|
3861
3951
|
var cachedProductName = null;
|
|
3862
3952
|
function brandJsonPath() {
|
|
@@ -3876,7 +3966,7 @@ function getBrandProductName() {
|
|
|
3876
3966
|
}
|
|
3877
3967
|
let parsed;
|
|
3878
3968
|
try {
|
|
3879
|
-
parsed = JSON.parse(
|
|
3969
|
+
parsed = JSON.parse(readFileSync6(path, "utf-8"));
|
|
3880
3970
|
} catch (err) {
|
|
3881
3971
|
throw new Error(
|
|
3882
3972
|
`[skill-loader] brand.json unreadable at ${path}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -3940,7 +4030,7 @@ function listValidAccounts() {
|
|
|
3940
4030
|
}
|
|
3941
4031
|
let config;
|
|
3942
4032
|
try {
|
|
3943
|
-
config = JSON.parse(
|
|
4033
|
+
config = JSON.parse(readFileSync7(configPath, "utf-8"));
|
|
3944
4034
|
} catch {
|
|
3945
4035
|
console.error(
|
|
3946
4036
|
`[platform] accounts-state CORRUPT-JSON id=${entry.name} \u2014 account.json failed to parse; treating as stub`
|
|
@@ -3959,7 +4049,7 @@ function resolveAccount() {
|
|
|
3959
4049
|
let usersJsonUserId = null;
|
|
3960
4050
|
if (existsSync5(USERS_FILE)) {
|
|
3961
4051
|
try {
|
|
3962
|
-
const raw2 =
|
|
4052
|
+
const raw2 = readFileSync7(USERS_FILE, "utf-8").trim();
|
|
3963
4053
|
if (raw2) {
|
|
3964
4054
|
const users = JSON.parse(raw2);
|
|
3965
4055
|
if (users.length > 0) {
|
|
@@ -3975,7 +4065,7 @@ function resolveAccount() {
|
|
|
3975
4065
|
if (!entry.isDirectory()) continue;
|
|
3976
4066
|
const configPath = resolve4(ACCOUNTS_DIR, entry.name, "account.json");
|
|
3977
4067
|
if (!existsSync5(configPath)) continue;
|
|
3978
|
-
const raw2 =
|
|
4068
|
+
const raw2 = readFileSync7(configPath, "utf-8");
|
|
3979
4069
|
let config;
|
|
3980
4070
|
try {
|
|
3981
4071
|
config = JSON.parse(raw2);
|
|
@@ -4010,7 +4100,7 @@ function resolveAccount() {
|
|
|
4010
4100
|
function readAgentFile(accountDir, agentName, filename) {
|
|
4011
4101
|
const filePath = resolve4(accountDir, "agents", agentName, filename);
|
|
4012
4102
|
if (!existsSync5(filePath)) return null;
|
|
4013
|
-
const raw2 =
|
|
4103
|
+
const raw2 = readFileSync7(filePath, "utf-8");
|
|
4014
4104
|
if (filename.endsWith(".md")) {
|
|
4015
4105
|
return substituteBrandPlaceholders(raw2, filePath);
|
|
4016
4106
|
}
|
|
@@ -4039,7 +4129,7 @@ function resolveDefaultAgentSlug(accountDir) {
|
|
|
4039
4129
|
}
|
|
4040
4130
|
let config;
|
|
4041
4131
|
try {
|
|
4042
|
-
config = JSON.parse(
|
|
4132
|
+
config = JSON.parse(readFileSync7(configPath, "utf-8"));
|
|
4043
4133
|
} catch (err) {
|
|
4044
4134
|
console.error("[agent-resolve] failed to read account.json:", err);
|
|
4045
4135
|
return null;
|
|
@@ -4114,14 +4204,14 @@ function resolveAgentConfig(accountDir, agentName) {
|
|
|
4114
4204
|
const knowledgeMtime = statSync(knowledgePath).mtimeMs;
|
|
4115
4205
|
const summaryMtime = statSync(summaryPath).mtimeMs;
|
|
4116
4206
|
if (summaryMtime >= knowledgeMtime) {
|
|
4117
|
-
knowledge =
|
|
4207
|
+
knowledge = readFileSync7(summaryPath, "utf-8");
|
|
4118
4208
|
} else {
|
|
4119
4209
|
console.warn(`[agent-config] ${agentName}: KNOWLEDGE-SUMMARY.md is stale (KNOWLEDGE.md is newer) \u2014 using full knowledge`);
|
|
4120
|
-
knowledge =
|
|
4210
|
+
knowledge = readFileSync7(knowledgePath, "utf-8");
|
|
4121
4211
|
}
|
|
4122
4212
|
knowledgeBaked = true;
|
|
4123
4213
|
} else if (hasKnowledge) {
|
|
4124
|
-
knowledge =
|
|
4214
|
+
knowledge = readFileSync7(knowledgePath, "utf-8");
|
|
4125
4215
|
knowledgeBaked = true;
|
|
4126
4216
|
}
|
|
4127
4217
|
let budget = null;
|
|
@@ -4215,7 +4305,7 @@ function getSessionKeyBySessionId(_sessionId) {
|
|
|
4215
4305
|
// app/lib/claude-agent/plugin-manifest.ts
|
|
4216
4306
|
import { resolve as resolve5, join as join3 } from "path";
|
|
4217
4307
|
import {
|
|
4218
|
-
readFileSync as
|
|
4308
|
+
readFileSync as readFileSync8,
|
|
4219
4309
|
writeFileSync as writeFileSync4,
|
|
4220
4310
|
readdirSync as readdirSync2,
|
|
4221
4311
|
existsSync as existsSync6,
|
|
@@ -4237,7 +4327,7 @@ function readBundleSubPlugins(bundlePath) {
|
|
|
4237
4327
|
if (!existsSync6(bundlePath)) return [];
|
|
4238
4328
|
let raw2;
|
|
4239
4329
|
try {
|
|
4240
|
-
raw2 =
|
|
4330
|
+
raw2 = readFileSync8(bundlePath, "utf-8");
|
|
4241
4331
|
} catch {
|
|
4242
4332
|
return [];
|
|
4243
4333
|
}
|
|
@@ -4310,8 +4400,8 @@ function reapDuplicateFlatPremiumSubs(bundles, stagingRoot, pluginsDir) {
|
|
|
4310
4400
|
const flatDir = resolve5(pluginsDir, sub);
|
|
4311
4401
|
const flatManifest = resolve5(flatDir, "PLUGIN.md");
|
|
4312
4402
|
if (!existsSync6(premiumManifest) || !existsSync6(flatManifest)) continue;
|
|
4313
|
-
const premiumSha = createHash2("sha256").update(
|
|
4314
|
-
const flatSha = createHash2("sha256").update(
|
|
4403
|
+
const premiumSha = createHash2("sha256").update(readFileSync8(premiumManifest)).digest("hex");
|
|
4404
|
+
const flatSha = createHash2("sha256").update(readFileSync8(flatManifest)).digest("hex");
|
|
4315
4405
|
if (isBundle) {
|
|
4316
4406
|
if (premiumSha === flatSha) {
|
|
4317
4407
|
try {
|
|
@@ -4373,7 +4463,7 @@ function reconcileEnabledPlugins(accountDir, config, accountId) {
|
|
|
4373
4463
|
const merged = [...currentSet];
|
|
4374
4464
|
const configPath = resolve5(accountDir, "account.json");
|
|
4375
4465
|
try {
|
|
4376
|
-
const raw2 =
|
|
4466
|
+
const raw2 = readFileSync8(configPath, "utf-8");
|
|
4377
4467
|
const parsed = JSON.parse(raw2);
|
|
4378
4468
|
parsed.enabledPlugins = merged;
|
|
4379
4469
|
writeFileSync4(configPath, JSON.stringify(parsed, null, 2) + "\n");
|
|
@@ -4409,7 +4499,7 @@ function cleanupLeakedPremiumSubs(accountDir, config, accountId) {
|
|
|
4409
4499
|
if (removed.length === 0) return;
|
|
4410
4500
|
const configPath = resolve5(accountDir, "account.json");
|
|
4411
4501
|
try {
|
|
4412
|
-
const raw2 =
|
|
4502
|
+
const raw2 = readFileSync8(configPath, "utf-8");
|
|
4413
4503
|
const parsed = JSON.parse(raw2);
|
|
4414
4504
|
parsed.enabledPlugins = kept;
|
|
4415
4505
|
writeFileSync4(configPath, JSON.stringify(parsed, null, 2) + "\n");
|
|
@@ -4460,7 +4550,7 @@ function requirePortEnv(envName, options = {}) {
|
|
|
4460
4550
|
// app/lib/neo4j-store.ts
|
|
4461
4551
|
import neo4j from "neo4j-driver";
|
|
4462
4552
|
import { randomUUID } from "crypto";
|
|
4463
|
-
import { readFileSync as
|
|
4553
|
+
import { readFileSync as readFileSync9, readdirSync as readdirSync3, existsSync as existsSync7, openSync, readSync, closeSync, statSync as statSync3 } from "fs";
|
|
4464
4554
|
import { resolve as resolve6 } from "path";
|
|
4465
4555
|
var PLATFORM_ROOT3 = process.env.MAXY_PLATFORM_ROOT ?? resolve6(process.cwd(), "..");
|
|
4466
4556
|
var driver = null;
|
|
@@ -4468,7 +4558,7 @@ function readPassword() {
|
|
|
4468
4558
|
if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
|
|
4469
4559
|
const passwordFile = resolve6(PLATFORM_ROOT3, "config/.neo4j-password");
|
|
4470
4560
|
try {
|
|
4471
|
-
return
|
|
4561
|
+
return readFileSync9(passwordFile, "utf-8").trim();
|
|
4472
4562
|
} catch {
|
|
4473
4563
|
throw new Error(
|
|
4474
4564
|
`Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`
|
|
@@ -5585,7 +5675,7 @@ function loadEnabledPluginProfileKeys(accountId) {
|
|
|
5585
5675
|
if (!existsSync7(accountFile)) return {};
|
|
5586
5676
|
let enabled;
|
|
5587
5677
|
try {
|
|
5588
|
-
const raw2 =
|
|
5678
|
+
const raw2 = readFileSync9(accountFile, "utf-8");
|
|
5589
5679
|
const parsed = JSON.parse(raw2);
|
|
5590
5680
|
enabled = Array.isArray(parsed.enabledPlugins) ? parsed.enabledPlugins.filter((p) => typeof p === "string") : [];
|
|
5591
5681
|
} catch (err) {
|
|
@@ -5600,7 +5690,7 @@ function loadEnabledPluginProfileKeys(accountId) {
|
|
|
5600
5690
|
if (!existsSync7(manifestPath)) continue;
|
|
5601
5691
|
let manifest;
|
|
5602
5692
|
try {
|
|
5603
|
-
manifest =
|
|
5693
|
+
manifest = readFileSync9(manifestPath, "utf-8");
|
|
5604
5694
|
} catch {
|
|
5605
5695
|
continue;
|
|
5606
5696
|
}
|
|
@@ -5858,11 +5948,11 @@ async function projectAgent(accountId, accountDir, slug) {
|
|
|
5858
5948
|
);
|
|
5859
5949
|
return;
|
|
5860
5950
|
}
|
|
5861
|
-
config = JSON.parse(
|
|
5951
|
+
config = JSON.parse(readFileSync9(configPath, "utf-8"));
|
|
5862
5952
|
for (const { filename, role } of AGENT_FILE_ROLES) {
|
|
5863
5953
|
const filePath = resolve6(agentDir, filename);
|
|
5864
5954
|
if (!existsSync7(filePath)) continue;
|
|
5865
|
-
const body =
|
|
5955
|
+
const body = readFileSync9(filePath, "utf-8");
|
|
5866
5956
|
presentRoles.push({ role, body, edge: ROLE_TO_EDGE[role] });
|
|
5867
5957
|
}
|
|
5868
5958
|
} catch (err) {
|
|
@@ -6112,6 +6202,8 @@ export {
|
|
|
6112
6202
|
Hono2 as Hono,
|
|
6113
6203
|
getRequestListener,
|
|
6114
6204
|
serve,
|
|
6205
|
+
sampleCpu,
|
|
6206
|
+
sampleProcessCpu,
|
|
6115
6207
|
registerLoop,
|
|
6116
6208
|
listLoops,
|
|
6117
6209
|
armedCount,
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Activity — Maxy</title>
|
|
7
7
|
<link rel="icon" href="/favicon.ico">
|
|
8
|
-
<script type="module" crossorigin src="/assets/activity-
|
|
8
|
+
<script type="module" crossorigin src="/assets/activity-C9P5NjEZ.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/chunk-TPjIAO9U.js">
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-
|
|
11
|
-
<link rel="modulepreload" crossorigin href="/assets/useSelectionMode-
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/AdminShell-
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/triangle-alert-
|
|
14
|
-
<link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-BZnzc5C3.js">
|
|
11
|
+
<link rel="modulepreload" crossorigin href="/assets/useSelectionMode-BooArySZ.js">
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/AdminShell-D9zaUxPd.js">
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/triangle-alert-0lSBIUg-.js">
|
|
14
|
+
<link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-D9knHOKq.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
17
17
|
<div id="root"></div>
|
package/payload/server/public/assets/{AdminLoginScreens-DximwPlS.js → AdminLoginScreens-DR5eLF-a.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{o as e}from"./chunk-TPjIAO9U.js";import{C as t,D as n,S as r,b as i,v as a}from"./useSubAccountSwitcher-DzgzTRRn.js";import{E as o}from"./useVoiceRecorder-CTXP8oTW.js";import{v as s,y as c}from"./AdminShell-BehbH-Oa.js";import{t as l}from"./Checkbox-DM-eHqOS.js";var u=`admin-landing-redirected`,d=`/graph`;function f(e){return e.variant===`operator`?!1:e.appState===`chat`&&!e.alreadyRedirected}var p=e(n(),1);function m(e=`admin`){let[n,r]=(0,p.useState)(`loading`),[i,a]=(0,p.useState)(``),[s,l]=(0,p.useState)(``),[m,h]=(0,p.useState)(``),[g,_]=(0,p.useState)(!1),[v,y]=(0,p.useState)(!1),[b,x]=(0,p.useState)(!1),[S,C]=(0,p.useState)(!1),[w,T]=(0,p.useState)(!1),[E,D]=(0,p.useState)(null),[O,k]=(0,p.useState)(null),[A,j]=(0,p.useState)(void 0),[M,N]=(0,p.useState)(null),[P,F]=(0,p.useState)(void 0),[I,L]=(0,p.useState)(null),[R,z]=(0,p.useState)(null),[B,V]=(0,p.useState)(void 0),H=(0,p.useRef)(void 0),[U,W]=(0,p.useState)(!1),[G,K]=(0,p.useState)(!0);(0,p.useEffect)(()=>{typeof window>`u`||fetch(`/api/remote-auth/status`).then(e=>e.ok?e.json():null).then(e=>{e?.configured&&W(!0)}).catch(()=>{})},[]);let q=(0,p.useRef)(null),J=(0,p.useRef)(null);(0,p.useEffect)(()=>{async function e(){let e=null;try{e=sessionStorage.getItem(`maxy-admin-session-key`)}catch{}if(!e)return!1;try{let t=await fetch(`/api/admin/session?session_key=${encodeURIComponent(e)}`);if(t.status===401){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}return!1}if(!t.ok)return!1;let n=await t.json();D(n.session_key),z(n.sessionId??null),j(n.businessName),N(n.role??null),F(n.userName===void 0?null:n.userName),L(n.avatar??null);let i=o(n.thinkingView);return H.current=i,V(i),r(`chat`),!0}catch(e){return console.error(`[admin] session restore failed:`,e),!1}}async function t(n=2){try{let i=await fetch(`/api/health`);if(!i.ok){if(n>0)return await new Promise(e=>setTimeout(e,1500)),t(n-1);console.error(`[admin] health check returned ${i.status} after retries`),r(`set-pin`);return}let a=await i.json();if(!a.pin_configured){r(`set-pin`);return}K(!!a.claude_authenticated);let o=!1;try{o=new URLSearchParams(window.location.search).get(`connect`)===`claude`}catch{}if(o){try{let e=new URL(window.location.href);e.searchParams.delete(`connect`),window.history.replaceState(null,``,e.pathname+e.search+e.hash)}catch{}if(!a.claude_authenticated){r(`connect-claude`);return}}if(await e())return;r(`enter-pin`)}catch(e){if(n>0)return await new Promise(e=>setTimeout(e,1500)),t(n-1);console.error(`[admin] health check failed:`,e),r(`set-pin`)}}t()},[]),(0,p.useEffect)(()=>{n===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&k(e)}).catch(()=>{})},[n]),(0,p.useEffect)(()=>{if(typeof window>`u`)return;let t=!1;try{t=sessionStorage.getItem(u)===`1`}catch{}if(f({appState:n,alreadyRedirected:t,variant:e})){try{sessionStorage.setItem(u,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${d}`),window.location.replace(d)}},[n,e]);let Y=(0,p.useRef)(null);(0,p.useEffect)(()=>{if(n!==`chat`)return;let e=setInterval(async()=>{try{let e=await fetch(`/api/health`);if(e.ok){let t=await e.json();K(t.auth_status!==`dead`&&t.auth_status!==`missing`)}}catch{}if(E)try{let e=await fetch(`/api/admin/session?session_key=${encodeURIComponent(E)}`);if(e.status!==401)return;let n=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;if(n===`remote-auth-required`){t(`heartbeat`,`/api/admin/session`);return}console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${n}`),Y.current?.()}catch{}},300*1e3);return()=>clearInterval(e)},[n,E]),(0,p.useEffect)(()=>{n===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&(K(!0),r(`enter-pin`))}).catch(()=>{})},[n]);async function X(e,n){y(!0);try{let i=await fetch(`/api/admin/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:e,...n?{accountId:n}:{}})});if(!i.ok){let e=await i.json().catch(()=>({}));if(i.status===401&&e?.code===`remote-auth-required`){t(`enter-pin`,`/api/admin/session`);return}h(e.error||`Invalid PIN`);return}let s=await i.json();D(s.session_key),z(s.sessionId??null),j(s.businessName),N(s.role??null),F(s.userName===void 0?null:s.userName),L(s.avatar??null);let c=o(s.thinkingView);H.current=c,V(c);try{sessionStorage.setItem(`maxy-admin-session-key`,s.session_key)}catch{}a(``),r(`chat`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}}let Z=(0,p.useCallback)(async e=>{if(e.preventDefault(),v)return;h(``);let n=s.trim();if(!n){h(`Please enter your name.`);return}if(i.length<4){h(`PIN must be at least 4 characters.`);return}let o=i;y(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:o,name:n})});if(!e.ok){let n=await e.json().catch(()=>({}));if(e.status===401&&n?.code===`remote-auth-required`){t(`set-pin`,`/api/onboarding/set-pin`);return}if(e.status===409){console.log(`[admin] PIN already configured — re-checking health`);try{let e=await fetch(`/api/health`);if(e.ok){let t=await e.json();t.pin_configured&&t.claude_authenticated?r(`enter-pin`):t.pin_configured?r(`connect-claude`):h(n.error||`Failed to set PIN.`)}else r(`enter-pin`)}catch{r(`enter-pin`)}return}h(n.error||`Failed to set PIN.`);return}let i=await fetch(`/api/health`);if((i.ok?await i.json():null)?.claude_authenticated){await X(o);return}a(``),r(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}},[i,v,s]),Q=(0,p.useCallback)(async e=>{e.preventDefault(),h(``),await X(i)},[i]),ee=(0,p.useCallback)(async()=>{T(!0);try{if(!await c())return console.warn(`[admin-ui] claude-disconnect not verified — credentials may persist; staying put`),!1;K(!1),D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(u)}catch{}return r(`connect-claude`),!0}finally{T(!1)}},[]),$=(0,p.useCallback)(()=>{D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(u)}catch{}a(``),h(``),r(`enter-pin`)},[]);return(0,p.useEffect)(()=>{Y.current=$},[$]),{appState:n,setAppState:r,pin:i,setPin:a,operatorName:s,setOperatorName:l,pinError:m,setPinError:h,showPin:g,setShowPin:_,pinLoading:v,authPolling:b,setAuthPolling:x,authLoading:S,setAuthLoading:C,disconnecting:w,cacheKey:E,setCacheKey:D,claudeInfo:O,setClaudeInfo:k,businessName:A,role:M,userName:P,userAvatar:I,sessionId:R,setSessionId:z,expandAll:B,setExpandAll:V,expandAllDefaultRef:H,remoteAuthEnabled:U,claudeConnected:G,pinInputRef:q,setPinFormRef:J,handleSetPin:Z,handleLogin:Q,handleDisconnect:ee,handleLogout:$}}var h=r();function g({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,p.useRef)([]);function s(e,r){r.key===`Backspace`?(r.preventDefault(),t[e]?n(t.slice(0,e)+t.slice(e+1)):e>0&&(n(t.slice(0,e-1)+t.slice(e)),o.current[e-1]?.focus())):r.key===`ArrowLeft`&&e>0?o.current[e-1]?.focus():r.key===`ArrowRight`&&e<5?o.current[e+1]?.focus():r.key===`Enter`&&(r.preventDefault(),r.currentTarget.form?.requestSubmit())}function c(e,i){let a=i.nativeEvent.data;if(!a||!/^\d$/.test(a))return;let s=t.split(``);for(s[e]=a;s.length<e;)s.push(``);let c=s.join(``).replace(/\D/g,``).slice(0,6);n(c),c.length===6?r?.(c):e<5&&o.current[e+1]?.focus()}function l(e){e.preventDefault();let t=e.clipboardData.getData(`text`).replace(/\D/g,``).slice(0,6);t&&(n(t),t.length===6?r?.(t):o.current[t.length]?.focus())}return(0,h.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,h.jsx)(`input`,{ref:t=>{o.current[r]=t,r===0&&e&&(e.current=t)},type:`text`,inputMode:`numeric`,className:`pin-box${t[r]?` pin-box-filled`:``}`,value:t[r]?i?t[r]:`•`:``,onKeyDown:e=>s(r,e),onInput:e=>c(r,e),onPaste:l,onFocus:e=>e.target.select(),autoFocus:a&&r===0,autoComplete:`off`,maxLength:1,"aria-label":`PIN digit ${r+1}`},r))})}function _(e){let{pin:t,setPin:n,showPin:r,setShowPin:o,pinLoading:c,pinError:u,pinInputRef:d,setPinFormRef:f,onSubmit:p,operatorName:m,setOperatorName:_}=e;return(0,h.jsx)(`div`,{className:`connect-page`,children:(0,h.jsxs)(`div`,{className:`connect-content`,children:[(0,h.jsx)(`img`,{src:i,alt:a.productName,className:`connect-logo connect-logo--maxy`}),!a.logoContainsName&&(0,h.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,a.productName]}),(0,h.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,a.productName,` who you are, then choose a PIN.`]}),(0,h.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,h.jsxs)(`div`,{className:`pin-input-row`,children:[(0,h.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:m,onChange:e=>_(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,h.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,h.jsxs)(`div`,{className:`pin-input-row`,children:[(0,h.jsx)(g,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r}),(0,h.jsx)(s,{variant:`send`,type:`submit`,disabled:!t||!m.trim(),loading:c,"aria-label":`Set PIN`,children:(0,h.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,h.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,h.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,h.jsx)(l,{checked:r,onChange:()=>o(e=>!e),label:`Show PIN`})]}),u&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:u})]})})}function v(e){let{pin:t,setPin:n,showPin:r,setShowPin:o,pinLoading:c,pinError:u,pinInputRef:d,onSubmit:f,remoteAuthEnabled:p,onSignOutRemote:m}=e;return(0,h.jsxs)(`div`,{className:`connect-page`,children:[p&&m&&(0,h.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:m,children:`Sign out`}),(0,h.jsxs)(`div`,{className:`connect-content`,children:[(0,h.jsx)(`img`,{src:i,alt:a.productName,className:`connect-logo connect-logo--maxy`}),!a.logoContainsName&&(0,h.jsx)(`h1`,{className:`connect-title`,children:a.productName}),(0,h.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,h.jsxs)(`div`,{className:`pin-input-row`,children:[(0,h.jsx)(g,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r,autoFocus:!0}),(0,h.jsx)(s,{variant:`send`,type:`submit`,disabled:!t,loading:c,children:(0,h.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,h.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,h.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,h.jsx)(`div`,{className:`pin-options`,children:(0,h.jsx)(l,{checked:r,onChange:()=>o(e=>!e),label:`Show PIN`})})]}),u&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:u})]})]})}function y(e){let{authPolling:t,setAuthPolling:n,authLoading:r,setAuthLoading:o,pinError:c,setPinError:l,setAppState:u}=e,[d,f]=(0,p.useState)(!1),[m,g]=(0,p.useState)(!1),[_,v]=(0,p.useState)(``),[y,b]=(0,p.useState)(``),[x,S]=(0,p.useState)(``);async function C(){S(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`paste-code`,code:y})})).json();e.accepted?(S(`Code submitted. Finishing sign-in…`),b(``)):S(e.error||`Could not submit code.`)}catch(e){console.error(`[admin] paste-code error:`,e),S(`Could not submit code.`)}}async function w(){g(!0),l(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`launch-browser`})})).json();e.launched?f(!0):e.error&&l(e.error)}catch(e){console.error(`[admin] browser launch error:`,e),l(`Could not launch browser.`)}g(!1)}async function T(){o(!0),l(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){n(!0),f(!0),o(!1),v(e.transport||``);for(let e=0;e<120;e++)if(await new Promise(e=>setTimeout(e,2e3)),(await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`wait`})})).json()).authenticated){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),u(`enter-pin`);return}l(`Timed out waiting for sign-in. Try again.`),n(!1)}else e.error&&l(e.error)}catch(e){console.error(`[admin] auth flow error:`,e),l(`Could not start auth flow.`)}o(!1)}async function E(){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),n(!1),l(``)}return t||d?(0,h.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,h.jsxs)(`header`,{className:`chat-header`,style:{paddingBottom:`12px`,flexShrink:0,position:`relative`,maxWidth:`680px`,width:`100%`,margin:`0 auto`,padding:`24px 20px 12px`},children:[t?(0,h.jsx)(`button`,{onClick:E,style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Cancel`,children:`✕`}):(0,h.jsx)(`button`,{onClick:()=>f(!1),style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Close browser`,children:`✕`}),(0,h.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,h.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,h.jsx)(`p`,{className:`chat-intro`,children:t?`Sign in and authorize in the browser below.`:`Open your email or prepare your accounts, then sign in.`}),!t&&(0,h.jsx)(`div`,{style:{marginTop:`12px`},children:(0,h.jsx)(s,{variant:`primary`,onClick:T,disabled:r,children:r?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})}),t&&_===`native`&&(0,h.jsxs)(`div`,{style:{marginTop:`14px`,maxWidth:`420px`,margin:`14px auto 0`,display:`flex`,flexDirection:`column`,gap:`8px`},children:[(0,h.jsx)(`label`,{style:{fontSize:`12px`,color:`#999`,lineHeight:1.4},children:`If the browser didn't finish sign-in, paste the code or full redirect URL from Claude's page:`}),(0,h.jsxs)(`div`,{style:{display:`flex`,gap:`8px`},children:[(0,h.jsx)(`input`,{type:`text`,value:y,onChange:e=>b(e.target.value),placeholder:`Paste code or redirect URL`,style:{flex:1,padding:`8px 10px`,fontSize:`13px`,border:`1px solid #ccc`,borderRadius:`6px`}}),(0,h.jsx)(s,{variant:`primary`,onClick:C,disabled:!y.trim(),children:`Submit`})]}),x&&(0,h.jsx)(`p`,{style:{fontSize:`12px`,color:`#999`,margin:0},children:x})]})]}),(0,h.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:(0,h.jsx)(`iframe`,{src:`/vnc-viewer.html`,style:{flex:1,width:`100%`,minHeight:0,border:`none`,background:`#111`,display:`block`},title:`Claude Sign-in`})}),c&&(0,h.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:c})]}):(0,h.jsx)(`div`,{className:`connect-page`,children:(0,h.jsxs)(`div`,{className:`connect-content`,children:[(0,h.jsxs)(`div`,{className:`connect-logos`,children:[(0,h.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,h.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,h.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,h.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,h.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,h.jsx)(`img`,{src:i,alt:a.productName,className:`connect-logo connect-logo--maxy`}),!a.logoContainsName&&(0,h.jsx)(`span`,{className:`connect-logo-label`,children:a.productName})]})]}),(0,h.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,a.productName]}),(0,h.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,h.jsx)(s,{variant:`primary`,onClick:T,disabled:r,children:r?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,h.jsx)(`p`,{style:{marginTop:`6px`,fontSize:`11px`,color:`#999`,maxWidth:`300px`,textAlign:`center`,lineHeight:`1.4`},children:`First time? You may need to sign into your email and Anthropic account in the browser before connecting.`}),(0,h.jsx)(`button`,{onClick:w,disabled:m,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:m?`Launching…`:`Open browser first`}),c&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:c})]})})}function b({auth:e}){return e.appState===`loading`?(0,h.jsx)(`div`,{className:`connect-page`}):e.appState===`set-pin`?(0,h.jsx)(_,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,setPinFormRef:e.setPinFormRef,onSubmit:e.handleSetPin,operatorName:e.operatorName,setOperatorName:e.setOperatorName}):e.appState===`connect-claude`?(0,h.jsx)(y,{authPolling:e.authPolling,setAuthPolling:e.setAuthPolling,authLoading:e.authLoading,setAuthLoading:e.setAuthLoading,pinError:e.pinError,setPinError:e.setPinError,setAppState:e.setAppState}):e.appState===`enter-pin`?(0,h.jsx)(v,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,onSubmit:e.handleLogin,remoteAuthEnabled:e.remoteAuthEnabled,onSignOutRemote:()=>{console.info(`[admin-ui] remote-auth sign-out → /__remote-auth/logout`),window.location.href=`/__remote-auth/logout`}}):null}export{m as n,b as t};
|
|
1
|
+
import{o as e}from"./chunk-TPjIAO9U.js";import{C as t,D as n,S as r,b as i,v as a}from"./useSubAccountSwitcher-BZnzc5C3.js";import{E as o}from"./useVoiceRecorder-PUT8q_sm.js";import{v as s,y as c}from"./AdminShell-D9zaUxPd.js";import{t as l}from"./Checkbox-DcbbAIe5.js";var u=`admin-landing-redirected`,d=`/graph`;function f(e){return e.variant===`operator`?!1:e.appState===`chat`&&!e.alreadyRedirected}var p=e(n(),1);function m(e=`admin`){let[n,r]=(0,p.useState)(`loading`),[i,a]=(0,p.useState)(``),[s,l]=(0,p.useState)(``),[m,h]=(0,p.useState)(``),[g,_]=(0,p.useState)(!1),[v,y]=(0,p.useState)(!1),[b,x]=(0,p.useState)(!1),[S,C]=(0,p.useState)(!1),[w,T]=(0,p.useState)(!1),[E,D]=(0,p.useState)(null),[O,k]=(0,p.useState)(null),[A,j]=(0,p.useState)(void 0),[M,N]=(0,p.useState)(null),[P,F]=(0,p.useState)(void 0),[I,L]=(0,p.useState)(null),[R,z]=(0,p.useState)(null),[B,V]=(0,p.useState)(void 0),H=(0,p.useRef)(void 0),[U,W]=(0,p.useState)(!1),[G,K]=(0,p.useState)(!0);(0,p.useEffect)(()=>{typeof window>`u`||fetch(`/api/remote-auth/status`).then(e=>e.ok?e.json():null).then(e=>{e?.configured&&W(!0)}).catch(()=>{})},[]);let q=(0,p.useRef)(null),J=(0,p.useRef)(null);(0,p.useEffect)(()=>{async function e(){let e=null;try{e=sessionStorage.getItem(`maxy-admin-session-key`)}catch{}if(!e)return!1;try{let t=await fetch(`/api/admin/session?session_key=${encodeURIComponent(e)}`);if(t.status===401){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}return!1}if(!t.ok)return!1;let n=await t.json();D(n.session_key),z(n.sessionId??null),j(n.businessName),N(n.role??null),F(n.userName===void 0?null:n.userName),L(n.avatar??null);let i=o(n.thinkingView);return H.current=i,V(i),r(`chat`),!0}catch(e){return console.error(`[admin] session restore failed:`,e),!1}}async function t(n=2){try{let i=await fetch(`/api/health`);if(!i.ok){if(n>0)return await new Promise(e=>setTimeout(e,1500)),t(n-1);console.error(`[admin] health check returned ${i.status} after retries`),r(`set-pin`);return}let a=await i.json();if(!a.pin_configured){r(`set-pin`);return}K(!!a.claude_authenticated);let o=!1;try{o=new URLSearchParams(window.location.search).get(`connect`)===`claude`}catch{}if(o){try{let e=new URL(window.location.href);e.searchParams.delete(`connect`),window.history.replaceState(null,``,e.pathname+e.search+e.hash)}catch{}if(!a.claude_authenticated){r(`connect-claude`);return}}if(await e())return;r(`enter-pin`)}catch(e){if(n>0)return await new Promise(e=>setTimeout(e,1500)),t(n-1);console.error(`[admin] health check failed:`,e),r(`set-pin`)}}t()},[]),(0,p.useEffect)(()=>{n===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&k(e)}).catch(()=>{})},[n]),(0,p.useEffect)(()=>{if(typeof window>`u`)return;let t=!1;try{t=sessionStorage.getItem(u)===`1`}catch{}if(f({appState:n,alreadyRedirected:t,variant:e})){try{sessionStorage.setItem(u,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${d}`),window.location.replace(d)}},[n,e]);let Y=(0,p.useRef)(null);(0,p.useEffect)(()=>{if(n!==`chat`)return;let e=setInterval(async()=>{try{let e=await fetch(`/api/health`);if(e.ok){let t=await e.json();K(t.auth_status!==`dead`&&t.auth_status!==`missing`)}}catch{}if(E)try{let e=await fetch(`/api/admin/session?session_key=${encodeURIComponent(E)}`);if(e.status!==401)return;let n=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;if(n===`remote-auth-required`){t(`heartbeat`,`/api/admin/session`);return}console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${n}`),Y.current?.()}catch{}},300*1e3);return()=>clearInterval(e)},[n,E]),(0,p.useEffect)(()=>{n===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&(K(!0),r(`enter-pin`))}).catch(()=>{})},[n]);async function X(e,n){y(!0);try{let i=await fetch(`/api/admin/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:e,...n?{accountId:n}:{}})});if(!i.ok){let e=await i.json().catch(()=>({}));if(i.status===401&&e?.code===`remote-auth-required`){t(`enter-pin`,`/api/admin/session`);return}h(e.error||`Invalid PIN`);return}let s=await i.json();D(s.session_key),z(s.sessionId??null),j(s.businessName),N(s.role??null),F(s.userName===void 0?null:s.userName),L(s.avatar??null);let c=o(s.thinkingView);H.current=c,V(c);try{sessionStorage.setItem(`maxy-admin-session-key`,s.session_key)}catch{}a(``),r(`chat`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}}let Z=(0,p.useCallback)(async e=>{if(e.preventDefault(),v)return;h(``);let n=s.trim();if(!n){h(`Please enter your name.`);return}if(i.length<4){h(`PIN must be at least 4 characters.`);return}let o=i;y(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:o,name:n})});if(!e.ok){let n=await e.json().catch(()=>({}));if(e.status===401&&n?.code===`remote-auth-required`){t(`set-pin`,`/api/onboarding/set-pin`);return}if(e.status===409){console.log(`[admin] PIN already configured — re-checking health`);try{let e=await fetch(`/api/health`);if(e.ok){let t=await e.json();t.pin_configured&&t.claude_authenticated?r(`enter-pin`):t.pin_configured?r(`connect-claude`):h(n.error||`Failed to set PIN.`)}else r(`enter-pin`)}catch{r(`enter-pin`)}return}h(n.error||`Failed to set PIN.`);return}let i=await fetch(`/api/health`);if((i.ok?await i.json():null)?.claude_authenticated){await X(o);return}a(``),r(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}},[i,v,s]),Q=(0,p.useCallback)(async e=>{e.preventDefault(),h(``),await X(i)},[i]),ee=(0,p.useCallback)(async()=>{T(!0);try{if(!await c())return console.warn(`[admin-ui] claude-disconnect not verified — credentials may persist; staying put`),!1;K(!1),D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(u)}catch{}return r(`connect-claude`),!0}finally{T(!1)}},[]),$=(0,p.useCallback)(()=>{D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(u)}catch{}a(``),h(``),r(`enter-pin`)},[]);return(0,p.useEffect)(()=>{Y.current=$},[$]),{appState:n,setAppState:r,pin:i,setPin:a,operatorName:s,setOperatorName:l,pinError:m,setPinError:h,showPin:g,setShowPin:_,pinLoading:v,authPolling:b,setAuthPolling:x,authLoading:S,setAuthLoading:C,disconnecting:w,cacheKey:E,setCacheKey:D,claudeInfo:O,setClaudeInfo:k,businessName:A,role:M,userName:P,userAvatar:I,sessionId:R,setSessionId:z,expandAll:B,setExpandAll:V,expandAllDefaultRef:H,remoteAuthEnabled:U,claudeConnected:G,pinInputRef:q,setPinFormRef:J,handleSetPin:Z,handleLogin:Q,handleDisconnect:ee,handleLogout:$}}var h=r();function g({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,p.useRef)([]);function s(e,r){r.key===`Backspace`?(r.preventDefault(),t[e]?n(t.slice(0,e)+t.slice(e+1)):e>0&&(n(t.slice(0,e-1)+t.slice(e)),o.current[e-1]?.focus())):r.key===`ArrowLeft`&&e>0?o.current[e-1]?.focus():r.key===`ArrowRight`&&e<5?o.current[e+1]?.focus():r.key===`Enter`&&(r.preventDefault(),r.currentTarget.form?.requestSubmit())}function c(e,i){let a=i.nativeEvent.data;if(!a||!/^\d$/.test(a))return;let s=t.split(``);for(s[e]=a;s.length<e;)s.push(``);let c=s.join(``).replace(/\D/g,``).slice(0,6);n(c),c.length===6?r?.(c):e<5&&o.current[e+1]?.focus()}function l(e){e.preventDefault();let t=e.clipboardData.getData(`text`).replace(/\D/g,``).slice(0,6);t&&(n(t),t.length===6?r?.(t):o.current[t.length]?.focus())}return(0,h.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,h.jsx)(`input`,{ref:t=>{o.current[r]=t,r===0&&e&&(e.current=t)},type:`text`,inputMode:`numeric`,className:`pin-box${t[r]?` pin-box-filled`:``}`,value:t[r]?i?t[r]:`•`:``,onKeyDown:e=>s(r,e),onInput:e=>c(r,e),onPaste:l,onFocus:e=>e.target.select(),autoFocus:a&&r===0,autoComplete:`off`,maxLength:1,"aria-label":`PIN digit ${r+1}`},r))})}function _(e){let{pin:t,setPin:n,showPin:r,setShowPin:o,pinLoading:c,pinError:u,pinInputRef:d,setPinFormRef:f,onSubmit:p,operatorName:m,setOperatorName:_}=e;return(0,h.jsx)(`div`,{className:`connect-page`,children:(0,h.jsxs)(`div`,{className:`connect-content`,children:[(0,h.jsx)(`img`,{src:i,alt:a.productName,className:`connect-logo connect-logo--maxy`}),!a.logoContainsName&&(0,h.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,a.productName]}),(0,h.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,a.productName,` who you are, then choose a PIN.`]}),(0,h.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,h.jsxs)(`div`,{className:`pin-input-row`,children:[(0,h.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:m,onChange:e=>_(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,h.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,h.jsxs)(`div`,{className:`pin-input-row`,children:[(0,h.jsx)(g,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r}),(0,h.jsx)(s,{variant:`send`,type:`submit`,disabled:!t||!m.trim(),loading:c,"aria-label":`Set PIN`,children:(0,h.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,h.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,h.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,h.jsx)(l,{checked:r,onChange:()=>o(e=>!e),label:`Show PIN`})]}),u&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:u})]})})}function v(e){let{pin:t,setPin:n,showPin:r,setShowPin:o,pinLoading:c,pinError:u,pinInputRef:d,onSubmit:f,remoteAuthEnabled:p,onSignOutRemote:m}=e;return(0,h.jsxs)(`div`,{className:`connect-page`,children:[p&&m&&(0,h.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:m,children:`Sign out`}),(0,h.jsxs)(`div`,{className:`connect-content`,children:[(0,h.jsx)(`img`,{src:i,alt:a.productName,className:`connect-logo connect-logo--maxy`}),!a.logoContainsName&&(0,h.jsx)(`h1`,{className:`connect-title`,children:a.productName}),(0,h.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,h.jsxs)(`div`,{className:`pin-input-row`,children:[(0,h.jsx)(g,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r,autoFocus:!0}),(0,h.jsx)(s,{variant:`send`,type:`submit`,disabled:!t,loading:c,children:(0,h.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,h.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,h.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,h.jsx)(`div`,{className:`pin-options`,children:(0,h.jsx)(l,{checked:r,onChange:()=>o(e=>!e),label:`Show PIN`})})]}),u&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:u})]})]})}function y(e){let{authPolling:t,setAuthPolling:n,authLoading:r,setAuthLoading:o,pinError:c,setPinError:l,setAppState:u}=e,[d,f]=(0,p.useState)(!1),[m,g]=(0,p.useState)(!1),[_,v]=(0,p.useState)(``),[y,b]=(0,p.useState)(``),[x,S]=(0,p.useState)(``);async function C(){S(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`paste-code`,code:y})})).json();e.accepted?(S(`Code submitted. Finishing sign-in…`),b(``)):S(e.error||`Could not submit code.`)}catch(e){console.error(`[admin] paste-code error:`,e),S(`Could not submit code.`)}}async function w(){g(!0),l(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`launch-browser`})})).json();e.launched?f(!0):e.error&&l(e.error)}catch(e){console.error(`[admin] browser launch error:`,e),l(`Could not launch browser.`)}g(!1)}async function T(){o(!0),l(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){n(!0),f(!0),o(!1),v(e.transport||``);for(let e=0;e<120;e++)if(await new Promise(e=>setTimeout(e,2e3)),(await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`wait`})})).json()).authenticated){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),u(`enter-pin`);return}l(`Timed out waiting for sign-in. Try again.`),n(!1)}else e.error&&l(e.error)}catch(e){console.error(`[admin] auth flow error:`,e),l(`Could not start auth flow.`)}o(!1)}async function E(){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),n(!1),l(``)}return t||d?(0,h.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,h.jsxs)(`header`,{className:`chat-header`,style:{paddingBottom:`12px`,flexShrink:0,position:`relative`,maxWidth:`680px`,width:`100%`,margin:`0 auto`,padding:`24px 20px 12px`},children:[t?(0,h.jsx)(`button`,{onClick:E,style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Cancel`,children:`✕`}):(0,h.jsx)(`button`,{onClick:()=>f(!1),style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Close browser`,children:`✕`}),(0,h.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,h.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,h.jsx)(`p`,{className:`chat-intro`,children:t?`Sign in and authorize in the browser below.`:`Open your email or prepare your accounts, then sign in.`}),!t&&(0,h.jsx)(`div`,{style:{marginTop:`12px`},children:(0,h.jsx)(s,{variant:`primary`,onClick:T,disabled:r,children:r?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})}),t&&_===`native`&&(0,h.jsxs)(`div`,{style:{marginTop:`14px`,maxWidth:`420px`,margin:`14px auto 0`,display:`flex`,flexDirection:`column`,gap:`8px`},children:[(0,h.jsx)(`label`,{style:{fontSize:`12px`,color:`#999`,lineHeight:1.4},children:`If the browser didn't finish sign-in, paste the code or full redirect URL from Claude's page:`}),(0,h.jsxs)(`div`,{style:{display:`flex`,gap:`8px`},children:[(0,h.jsx)(`input`,{type:`text`,value:y,onChange:e=>b(e.target.value),placeholder:`Paste code or redirect URL`,style:{flex:1,padding:`8px 10px`,fontSize:`13px`,border:`1px solid #ccc`,borderRadius:`6px`}}),(0,h.jsx)(s,{variant:`primary`,onClick:C,disabled:!y.trim(),children:`Submit`})]}),x&&(0,h.jsx)(`p`,{style:{fontSize:`12px`,color:`#999`,margin:0},children:x})]})]}),(0,h.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:(0,h.jsx)(`iframe`,{src:`/vnc-viewer.html`,style:{flex:1,width:`100%`,minHeight:0,border:`none`,background:`#111`,display:`block`},title:`Claude Sign-in`})}),c&&(0,h.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:c})]}):(0,h.jsx)(`div`,{className:`connect-page`,children:(0,h.jsxs)(`div`,{className:`connect-content`,children:[(0,h.jsxs)(`div`,{className:`connect-logos`,children:[(0,h.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,h.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,h.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,h.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,h.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,h.jsx)(`img`,{src:i,alt:a.productName,className:`connect-logo connect-logo--maxy`}),!a.logoContainsName&&(0,h.jsx)(`span`,{className:`connect-logo-label`,children:a.productName})]})]}),(0,h.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,a.productName]}),(0,h.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,h.jsx)(s,{variant:`primary`,onClick:T,disabled:r,children:r?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,h.jsx)(`p`,{style:{marginTop:`6px`,fontSize:`11px`,color:`#999`,maxWidth:`300px`,textAlign:`center`,lineHeight:`1.4`},children:`First time? You may need to sign into your email and Anthropic account in the browser before connecting.`}),(0,h.jsx)(`button`,{onClick:w,disabled:m,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:m?`Launching…`:`Open browser first`}),c&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:c})]})})}function b({auth:e}){return e.appState===`loading`?(0,h.jsx)(`div`,{className:`connect-page`}):e.appState===`set-pin`?(0,h.jsx)(_,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,setPinFormRef:e.setPinFormRef,onSubmit:e.handleSetPin,operatorName:e.operatorName,setOperatorName:e.setOperatorName}):e.appState===`connect-claude`?(0,h.jsx)(y,{authPolling:e.authPolling,setAuthPolling:e.setAuthPolling,authLoading:e.authLoading,setAuthLoading:e.setAuthLoading,pinError:e.pinError,setPinError:e.setPinError,setAppState:e.setAppState}):e.appState===`enter-pin`?(0,h.jsx)(v,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,onSubmit:e.handleLogin,remoteAuthEnabled:e.remoteAuthEnabled,onSignOutRemote:()=>{console.info(`[admin-ui] remote-auth sign-out → /__remote-auth/logout`),window.location.href=`/__remote-auth/logout`}}):null}export{m as n,b as t};
|