@rubytech/create-sitedesk-code 0.1.340 → 0.1.341

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.
Files changed (36) hide show
  1. package/dist/__tests__/known-brand-hostnames.test.js +40 -0
  2. package/dist/__tests__/neo4j-teardown.test.js +55 -0
  3. package/dist/known-brands.js +24 -0
  4. package/dist/neo4j-teardown.js +45 -0
  5. package/dist/uninstall.js +89 -40
  6. package/package.json +1 -1
  7. package/payload/platform/config/brand.json +2 -1
  8. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +3 -1
  9. package/payload/platform/plugins/docs/references/admin-ui.md +2 -0
  10. package/payload/server/{chunk-NE7G5GT7.js → chunk-5BG6CHGH.js} +17 -0
  11. package/payload/server/maxy-edge.js +1 -1
  12. package/payload/server/public/assets/{AdminLoginScreens-CHTeh_Vu.js → AdminLoginScreens-Brx8CmXN.js} +1 -1
  13. package/payload/server/public/assets/{AdminShell-DjoP7YoA.js → AdminShell-CHZMDX2u.js} +1 -1
  14. package/payload/server/public/assets/{Checkbox-D58GsKoQ.js → Checkbox-aePjWzRH.js} +1 -1
  15. package/payload/server/public/assets/{OperatorConversations-CDdp2nVn.css → OperatorConversations-BMIZQR9t.css} +1 -1
  16. package/payload/server/public/assets/{OperatorConversations-RmqANYz8.js → OperatorConversations-DpjPPIOp.js} +1 -1
  17. package/payload/server/public/assets/{admin-LGICBqil.js → admin-DIDvfti6.js} +1 -1
  18. package/payload/server/public/assets/{browser-CRgweVtw.js → browser-Bp5kGgyr.js} +1 -1
  19. package/payload/server/public/assets/chat-C0IWx7FL.js +1 -0
  20. package/payload/server/public/assets/{data-CttrzhfL.js → data-RsMye_06.js} +1 -1
  21. package/payload/server/public/assets/{graph-CIBba84R.js → graph-Bnsvbnkf.js} +1 -1
  22. package/payload/server/public/assets/{graph-labels-Bi0fu8Ns.js → graph-labels-jduMtwXb.js} +1 -1
  23. package/payload/server/public/assets/{operator-mwkYv8g5.js → operator-9K-TElDd.js} +1 -1
  24. package/payload/server/public/assets/page-BT9hkXHm.js +30 -0
  25. package/payload/server/public/assets/{public-CiUboUwu.js → public-DvL1Zov1.js} +1 -1
  26. package/payload/server/public/brand/sitedesk-og-image.png +0 -0
  27. package/payload/server/public/browser.html +4 -4
  28. package/payload/server/public/chat.html +5 -5
  29. package/payload/server/public/data.html +4 -4
  30. package/payload/server/public/graph.html +6 -6
  31. package/payload/server/public/index.html +6 -6
  32. package/payload/server/public/operator.html +7 -7
  33. package/payload/server/public/public.html +5 -5
  34. package/payload/server/server.js +183 -26
  35. package/payload/server/public/assets/chat-CXPRTVW7.js +0 -1
  36. package/payload/server/public/assets/page-BpxHz1N-.js +0 -30
@@ -5,11 +5,11 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Data — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/data-CttrzhfL.js"></script>
8
+ <script type="module" crossorigin src="/assets/data-RsMye_06.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-Pqm5yXtL.js">
10
- <link rel="modulepreload" crossorigin href="/assets/OperatorConversations-RmqANYz8.js">
11
- <link rel="modulepreload" crossorigin href="/assets/graph-labels-Bi0fu8Ns.js">
12
- <link rel="stylesheet" crossorigin href="/assets/OperatorConversations-CDdp2nVn.css">
10
+ <link rel="modulepreload" crossorigin href="/assets/OperatorConversations-DpjPPIOp.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/graph-labels-jduMtwXb.js">
12
+ <link rel="stylesheet" crossorigin href="/assets/OperatorConversations-BMIZQR9t.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="root"></div>
@@ -5,13 +5,13 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Graph — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/graph-CIBba84R.js"></script>
8
+ <script type="module" crossorigin src="/assets/graph-Bnsvbnkf.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-Pqm5yXtL.js">
10
- <link rel="modulepreload" crossorigin href="/assets/OperatorConversations-RmqANYz8.js">
11
- <link rel="modulepreload" crossorigin href="/assets/graph-labels-Bi0fu8Ns.js">
12
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-DjoP7YoA.js">
13
- <link rel="modulepreload" crossorigin href="/assets/Checkbox-D58GsKoQ.js">
14
- <link rel="stylesheet" crossorigin href="/assets/OperatorConversations-CDdp2nVn.css">
10
+ <link rel="modulepreload" crossorigin href="/assets/OperatorConversations-DpjPPIOp.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/graph-labels-jduMtwXb.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-CHZMDX2u.js">
13
+ <link rel="modulepreload" crossorigin href="/assets/Checkbox-aePjWzRH.js">
14
+ <link rel="stylesheet" crossorigin href="/assets/OperatorConversations-BMIZQR9t.css">
15
15
  </head>
16
16
  <body>
17
17
  <div id="root"></div>
@@ -5,14 +5,14 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>SiteDesk</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/admin-LGICBqil.js"></script>
8
+ <script type="module" crossorigin src="/assets/admin-DIDvfti6.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-Pqm5yXtL.js">
10
- <link rel="modulepreload" crossorigin href="/assets/OperatorConversations-RmqANYz8.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-DjoP7YoA.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/OperatorConversations-DpjPPIOp.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-CHZMDX2u.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/admin-types-CJrGd46U.js">
13
- <link rel="modulepreload" crossorigin href="/assets/Checkbox-D58GsKoQ.js">
14
- <link rel="modulepreload" crossorigin href="/assets/AdminLoginScreens-CHTeh_Vu.js">
15
- <link rel="stylesheet" crossorigin href="/assets/OperatorConversations-CDdp2nVn.css">
13
+ <link rel="modulepreload" crossorigin href="/assets/Checkbox-aePjWzRH.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/AdminLoginScreens-Brx8CmXN.js">
15
+ <link rel="stylesheet" crossorigin href="/assets/OperatorConversations-BMIZQR9t.css">
16
16
  <link rel="stylesheet" crossorigin href="/assets/AdminLoginScreens-CWMpccrR.css">
17
17
  <link rel="stylesheet" href="/brand-defaults.css">
18
18
  </head>
@@ -5,16 +5,16 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Operator — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/operator-mwkYv8g5.js"></script>
8
+ <script type="module" crossorigin src="/assets/operator-9K-TElDd.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-Pqm5yXtL.js">
10
- <link rel="modulepreload" crossorigin href="/assets/OperatorConversations-RmqANYz8.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-DjoP7YoA.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/OperatorConversations-DpjPPIOp.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-CHZMDX2u.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/admin-types-CJrGd46U.js">
13
- <link rel="modulepreload" crossorigin href="/assets/Checkbox-D58GsKoQ.js">
14
- <link rel="modulepreload" crossorigin href="/assets/AdminLoginScreens-CHTeh_Vu.js">
13
+ <link rel="modulepreload" crossorigin href="/assets/Checkbox-aePjWzRH.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/AdminLoginScreens-Brx8CmXN.js">
15
15
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-Bf_JiD2A.js">
16
- <link rel="modulepreload" crossorigin href="/assets/page-BpxHz1N-.js">
17
- <link rel="stylesheet" crossorigin href="/assets/OperatorConversations-CDdp2nVn.css">
16
+ <link rel="modulepreload" crossorigin href="/assets/page-BT9hkXHm.js">
17
+ <link rel="stylesheet" crossorigin href="/assets/OperatorConversations-BMIZQR9t.css">
18
18
  <link rel="stylesheet" crossorigin href="/assets/AdminLoginScreens-CWMpccrR.css">
19
19
  </head>
20
20
  <body>
@@ -5,14 +5,14 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>SiteDesk</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/public-CiUboUwu.js"></script>
8
+ <script type="module" crossorigin src="/assets/public-DvL1Zov1.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-Pqm5yXtL.js">
10
- <link rel="modulepreload" crossorigin href="/assets/OperatorConversations-RmqANYz8.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-DjoP7YoA.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/OperatorConversations-DpjPPIOp.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-CHZMDX2u.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/admin-types-CJrGd46U.js">
13
13
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-Bf_JiD2A.js">
14
- <link rel="modulepreload" crossorigin href="/assets/page-BpxHz1N-.js">
15
- <link rel="stylesheet" crossorigin href="/assets/OperatorConversations-CDdp2nVn.css">
14
+ <link rel="modulepreload" crossorigin href="/assets/page-BT9hkXHm.js">
15
+ <link rel="stylesheet" crossorigin href="/assets/OperatorConversations-BMIZQR9t.css">
16
16
  <link rel="stylesheet" href="/brand-defaults.css">
17
17
  </head>
18
18
  <body class="public-surface">
@@ -105,7 +105,7 @@ import {
105
105
  vncLog,
106
106
  walkPremiumBundles,
107
107
  writeAdminUserAndPerson
108
- } from "./chunk-NE7G5GT7.js";
108
+ } from "./chunk-5BG6CHGH.js";
109
109
  import {
110
110
  __commonJS,
111
111
  __toESM
@@ -7501,6 +7501,16 @@ function managerBase(tag) {
7501
7501
  return `http://127.0.0.1:${port2}`;
7502
7502
  }
7503
7503
 
7504
+ // server/routes/activity-scan.ts
7505
+ function pickActivity(entries, grown, nowMs, concurrencyWindowMs) {
7506
+ const candidates = entries.filter((e) => grown.has(e.hex));
7507
+ if (candidates.length === 0) return null;
7508
+ let newest = candidates[0];
7509
+ for (const e of candidates) if (e.mtimeMs > newest.mtimeMs) newest = e;
7510
+ const count = candidates.filter((e) => nowMs - e.mtimeMs < concurrencyWindowMs).length;
7511
+ return { hex: newest.hex, lastEmitAt: newest.mtimeMs, count };
7512
+ }
7513
+
7504
7514
  // server/routes/whatsapp-reader.ts
7505
7515
  var app4 = new Hono();
7506
7516
  app4.get("/conversations", requireAdminSession, async (c) => {
@@ -7616,6 +7626,112 @@ function enrichAdminAttachments(turn) {
7616
7626
  const attachments = adminAttachmentsFromText(turn.text, resolve11(DATA_ROOT, "accounts", account.accountId, "uploads"));
7617
7627
  return attachments.length > 0 ? { ...turn, attachments } : turn;
7618
7628
  }
7629
+ var CONCURRENCY_WINDOW_MS = 3e5;
7630
+ var AGENT_JSONL_RE = /^agent-([0-9a-f]+)\.jsonl$/;
7631
+ function makeActivityCtx(opts) {
7632
+ return {
7633
+ subagentsDir: opts.subagentsDir,
7634
+ sessionKey: opts.sessionKey,
7635
+ grown: /* @__PURE__ */ new Set(),
7636
+ initialSize: /* @__PURE__ */ new Map(),
7637
+ metaSeen: /* @__PURE__ */ new Set(),
7638
+ emittedHex: null,
7639
+ emittedAt: 0,
7640
+ subagentFrames: 0,
7641
+ reconcileLogged: /* @__PURE__ */ new Set(),
7642
+ lastParentTurns: [],
7643
+ parentGrewThisTick: false,
7644
+ now: 0,
7645
+ sendEvent: opts.sendEvent,
7646
+ log: opts.log
7647
+ };
7648
+ }
7649
+ function openTaskKey(turns) {
7650
+ for (let i = turns.length - 1; i >= 0; i--) {
7651
+ const t = turns[i];
7652
+ if (t.kind === "tool-result") return null;
7653
+ if (t.kind === "tool-call" && t.name === "Task") {
7654
+ const desc = t.input && typeof t.input === "object" ? t.input.description : void 0;
7655
+ return typeof desc === "string" && desc ? desc : "task";
7656
+ }
7657
+ }
7658
+ return null;
7659
+ }
7660
+ function readSubagentMeta(dir, hex) {
7661
+ try {
7662
+ const m = JSON.parse(readFileSync13(join12(dir, `agent-${hex}.meta.json`), "utf8"));
7663
+ if (typeof m.agentType === "string" && typeof m.description === "string" && typeof m.toolUseId === "string") {
7664
+ return { agentType: m.agentType, description: m.description, toolUseId: m.toolUseId };
7665
+ }
7666
+ } catch {
7667
+ }
7668
+ return null;
7669
+ }
7670
+ function runActivityTick(c) {
7671
+ if (c.parentGrewThisTick && c.emittedHex !== null) {
7672
+ c.sendEvent("activity-clear", { reason: "parent-resumed" });
7673
+ c.log(`[webchat-activity] op=clear key=${c.sessionKey} reason=parent-resumed`);
7674
+ c.emittedHex = null;
7675
+ c.emittedAt = 0;
7676
+ c.grown.clear();
7677
+ c.initialSize.clear();
7678
+ c.subagentFrames = 0;
7679
+ c.parentGrewThisTick = false;
7680
+ return;
7681
+ }
7682
+ c.parentGrewThisTick = false;
7683
+ let names = [];
7684
+ try {
7685
+ names = readdirSync7(c.subagentsDir).filter((n) => AGENT_JSONL_RE.test(n));
7686
+ } catch {
7687
+ }
7688
+ const entries = [];
7689
+ for (const name of names) {
7690
+ const hex = name.replace(AGENT_JSONL_RE, "$1");
7691
+ let size = 0;
7692
+ let mtimeMs = 0;
7693
+ try {
7694
+ const st = statSync4(join12(c.subagentsDir, name));
7695
+ size = st.size;
7696
+ mtimeMs = st.mtimeMs;
7697
+ } catch {
7698
+ continue;
7699
+ }
7700
+ if (!c.initialSize.has(hex)) c.initialSize.set(hex, size);
7701
+ if (size > (c.initialSize.get(hex) ?? size)) c.grown.add(hex);
7702
+ entries.push({ hex, size, mtimeMs });
7703
+ }
7704
+ const openKey = openTaskKey(c.lastParentTurns);
7705
+ if (openKey && c.subagentFrames === 0 && !c.reconcileLogged.has(openKey)) {
7706
+ c.reconcileLogged.add(openKey);
7707
+ c.log(`[webchat-activity] op=reconcile-gap key=${c.sessionKey} toolUseId=${openKey} framesEmitted=0`);
7708
+ }
7709
+ const pick = pickActivity(entries, c.grown, c.now, CONCURRENCY_WINDOW_MS);
7710
+ if (!pick) return;
7711
+ const meta = readSubagentMeta(c.subagentsDir, pick.hex);
7712
+ if (!meta) return;
7713
+ if (!c.metaSeen.has(pick.hex)) {
7714
+ c.metaSeen.add(pick.hex);
7715
+ c.log(
7716
+ `[webchat-activity] op=subagent-seen key=${c.sessionKey} agent=${pick.hex} agentType=${meta.agentType} toolUseId=${meta.toolUseId}`
7717
+ );
7718
+ }
7719
+ if (pick.hex === c.emittedHex && pick.lastEmitAt === c.emittedAt) return;
7720
+ c.emittedHex = pick.hex;
7721
+ c.emittedAt = pick.lastEmitAt;
7722
+ c.subagentFrames += 1;
7723
+ c.sendEvent("activity", {
7724
+ kind: "subagent-activity",
7725
+ agentType: meta.agentType,
7726
+ description: meta.description,
7727
+ toolUseId: meta.toolUseId,
7728
+ lastEmitAt: pick.lastEmitAt,
7729
+ count: pick.count
7730
+ });
7731
+ c.log(
7732
+ `[webchat-activity] op=frame key=${c.sessionKey} agent=${pick.hex} lastEmitAt=${pick.lastEmitAt} ageMs=${c.now - pick.lastEmitAt}`
7733
+ );
7734
+ }
7619
7735
  app4.get("/stream", requireAdminSession, (c) => {
7620
7736
  const sessionId = c.req.query("sessionId") ?? "";
7621
7737
  const projectDir = c.req.query("projectDir") ?? "";
@@ -7647,6 +7763,25 @@ data: ${JSON.stringify(turn)}
7647
7763
  })();
7648
7764
  let offset = resumeOffset(lastEventId, fileEnd0);
7649
7765
  console.log(`[wa-stream] op=open conn=${connId} sessionId=${sessionId} channel=reader resume=${offset}`);
7766
+ const sessionKey = c.req.query("session_key") ?? "";
7767
+ const subagentsDir = resolve11(join12(projectDir, sessionId, "subagents"));
7768
+ console.log(
7769
+ `[webchat-activity] op=watch-subagents key=${sessionKey} dir=${subagentsDir} exists=${existsSync7(subagentsDir)}`
7770
+ );
7771
+ const actx = makeActivityCtx({
7772
+ subagentsDir,
7773
+ sessionKey,
7774
+ sendEvent: (name, obj) => {
7775
+ try {
7776
+ controller.enqueue(encoder.encode(`event: ${name}
7777
+ data: ${JSON.stringify(obj)}
7778
+
7779
+ `));
7780
+ } catch {
7781
+ }
7782
+ },
7783
+ log: (line) => console.log(line)
7784
+ });
7650
7785
  const queuedPendingSuppress = /* @__PURE__ */ new Map();
7651
7786
  const drain = () => {
7652
7787
  try {
@@ -7657,12 +7792,16 @@ data: ${JSON.stringify(turn)}
7657
7792
  let n = 0;
7658
7793
  for (const turn of parseTranscript(lines, queuedPendingSuppress)) {
7659
7794
  send(controller, enrichAdminAttachments(enrichDownloads(turn)), offset);
7795
+ actx.lastParentTurns.push(turn);
7660
7796
  if (turn.kind === "agent-error") {
7661
7797
  console.log(`[wa-stream] op=agent-error conn=${connId} sessionId=${sessionId} code=${turn.code} source=jsonl`);
7662
7798
  }
7663
7799
  n++;
7664
7800
  }
7665
- if (n > 0) console.log(`[wa-stream] op=drain conn=${connId} turns=${n}`);
7801
+ if (n > 0) {
7802
+ actx.parentGrewThisTick = true;
7803
+ console.log(`[wa-stream] op=drain conn=${connId} turns=${n}`);
7804
+ }
7666
7805
  } catch {
7667
7806
  }
7668
7807
  };
@@ -7673,6 +7812,7 @@ data: ${JSON.stringify(turn)}
7673
7812
  let n = 0;
7674
7813
  for (const turn of parseTranscript(buf.toString("utf8").split("\n"), queuedPendingSuppress)) {
7675
7814
  send(controller, enrichAdminAttachments(enrichDownloads(turn)), offset);
7815
+ actx.lastParentTurns.push(turn);
7676
7816
  if (turn.kind === "agent-error") {
7677
7817
  console.log(`[wa-stream] op=agent-error conn=${connId} sessionId=${sessionId} code=${turn.code} source=jsonl`);
7678
7818
  }
@@ -7690,7 +7830,12 @@ data: ${JSON.stringify(turn)}
7690
7830
  watcher = watch(jsonlPath, drain);
7691
7831
  } catch {
7692
7832
  }
7693
- const poll = setInterval(drain, 1e3);
7833
+ const tick = () => {
7834
+ drain();
7835
+ actx.now = Date.now();
7836
+ runActivityTick(actx);
7837
+ };
7838
+ const poll = setInterval(tick, 1e3);
7694
7839
  const heartbeat = setInterval(() => {
7695
7840
  try {
7696
7841
  controller.enqueue(encoder.encode(": ping\n\n"));
@@ -7702,6 +7847,9 @@ data: ${JSON.stringify(turn)}
7702
7847
  watcher?.close();
7703
7848
  clearInterval(poll);
7704
7849
  clearInterval(heartbeat);
7850
+ if (actx.emittedHex !== null) {
7851
+ console.log(`[webchat-activity] op=clear key=${sessionKey} reason=stream-close`);
7852
+ }
7705
7853
  console.log(`[wa-stream] op=close conn=${connId} ranMs=${Date.now() - startedAt} reason=client-abort`);
7706
7854
  try {
7707
7855
  controller.close();
@@ -20487,7 +20635,9 @@ var brandLoginOpts = {
20487
20635
  faviconPath: brandFaviconPath,
20488
20636
  displayFont: BRAND.defaultFonts?.display,
20489
20637
  bodyFont: BRAND.defaultFonts?.body,
20490
- logoContainsName: !!BRAND.logoContainsName
20638
+ logoContainsName: !!BRAND.logoContainsName,
20639
+ tagline: BRAND.tagline,
20640
+ ogCardPath: BRAND.assets?.ogCard ? `/brand/${BRAND.assets.ogCard}` : void 0
20491
20641
  };
20492
20642
  var ALIAS_DOMAINS_PATH = join29(homedir3(), BRAND.configDir, "alias-domains.json");
20493
20643
  function loadAliasDomains() {
@@ -20691,9 +20841,16 @@ app52.use("*", async (c, next) => {
20691
20841
  return c.text("Not found", 404);
20692
20842
  });
20693
20843
  var lastRemoteAuthDisplayName = "";
20694
- function resolveRemoteAuthOpts() {
20844
+ function originFrom(c) {
20845
+ const host = c.req.header("host");
20846
+ if (!host) return void 0;
20847
+ const proto = (c.req.header("x-forwarded-proto") ?? "https").split(",")[0].trim().toLowerCase() || "https";
20848
+ return `${proto}://${host}`;
20849
+ }
20850
+ function resolveRemoteAuthOpts(c) {
20851
+ const origin = originFrom(c);
20695
20852
  const defaultSlug = resolveDefaultSlug();
20696
- if (!defaultSlug) return brandLoginOpts;
20853
+ if (!defaultSlug) return { ...brandLoginOpts, origin };
20697
20854
  const branding = loadBrandingCache(defaultSlug);
20698
20855
  const source = branding?.name ? "branding-cache" : "brand.json";
20699
20856
  const displayName = branding?.name || BRAND.productName;
@@ -20702,9 +20859,9 @@ function resolveRemoteAuthOpts() {
20702
20859
  lastRemoteAuthDisplayName = displayName;
20703
20860
  }
20704
20861
  if (branding?.name) {
20705
- return { ...brandLoginOpts, productName: branding.name };
20862
+ return { ...brandLoginOpts, productName: branding.name, origin };
20706
20863
  }
20707
- return brandLoginOpts;
20864
+ return { ...brandLoginOpts, origin };
20708
20865
  }
20709
20866
  var MAX_LOGIN_BODY = 8 * 1024;
20710
20867
  app52.post("/__remote-auth/login", async (c) => {
@@ -20719,7 +20876,7 @@ app52.post("/__remote-auth/login", async (c) => {
20719
20876
  const rateLimited = checkRateLimit(client);
20720
20877
  if (rateLimited) {
20721
20878
  const remaining = parseInt(rateLimited.match(/(\d+)s/)?.[1] ?? "0", 10);
20722
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), lockoutSeconds: remaining || void 0 }), 200);
20879
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), lockoutSeconds: remaining || void 0 }), 200);
20723
20880
  }
20724
20881
  const body = await c.req.text();
20725
20882
  if (Buffer.byteLength(body) > MAX_LOGIN_BODY) {
@@ -20731,13 +20888,13 @@ app52.post("/__remote-auth/login", async (c) => {
20731
20888
  const redirect = rawRedirect.startsWith("/") && !rawRedirect.startsWith("//") ? rawRedirect : "/";
20732
20889
  if (!password) {
20733
20890
  console.error(`[remote-auth] login failed ip=${clientIp} why=empty-input hashBytes=0`);
20734
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), error: "Password is required", redirect }), 200);
20891
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), error: "Password is required", redirect }), 200);
20735
20892
  }
20736
20893
  const outcome = await verifyRemotePassword(password);
20737
20894
  if (!outcome.ok) {
20738
20895
  recordFailedAttempt(client);
20739
20896
  console.error(`[remote-auth] login failed ip=${clientIp} why=${outcome.why} hashBytes=${outcome.hashBytes}`);
20740
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), error: "Invalid credentials", redirect }), 200);
20897
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), error: "Invalid credentials", redirect }), 200);
20741
20898
  }
20742
20899
  clearRateLimit(client);
20743
20900
  const token = createRemoteSession();
@@ -20771,7 +20928,7 @@ app52.post("/__remote-auth/change-password", async (c) => {
20771
20928
  const rateLimited = checkRateLimit(client);
20772
20929
  if (rateLimited) {
20773
20930
  const remaining = parseInt(rateLimited.match(/(\d+)s/)?.[1] ?? "0", 10);
20774
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), lockoutSeconds: remaining || void 0 }), 200);
20931
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), lockoutSeconds: remaining || void 0 }), 200);
20775
20932
  }
20776
20933
  const body = await c.req.text();
20777
20934
  if (Buffer.byteLength(body) > MAX_LOGIN_BODY) {
@@ -20785,30 +20942,30 @@ app52.post("/__remote-auth/change-password", async (c) => {
20785
20942
  const redirect = rawRedirect.startsWith("/") && !rawRedirect.startsWith("//") ? rawRedirect : "/";
20786
20943
  if (!currentPassword || !newPassword || !confirmPassword) {
20787
20944
  console.error(`[remote-auth] change-password failed ip=${clientIp} why=empty-input hashBytes=0`);
20788
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "All fields are required", redirect }), 200);
20945
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "All fields are required", redirect }), 200);
20789
20946
  }
20790
20947
  const outcome = await verifyRemotePassword(currentPassword);
20791
20948
  if (!outcome.ok) {
20792
20949
  recordFailedAttempt(client);
20793
20950
  console.error(`[remote-auth] change-password failed ip=${clientIp} why=${outcome.why} hashBytes=${outcome.hashBytes}`);
20794
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Current password is incorrect", redirect }), 200);
20951
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Current password is incorrect", redirect }), 200);
20795
20952
  }
20796
20953
  const targetUserId = outcome.userId;
20797
20954
  if (newPassword !== confirmPassword) {
20798
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "New passwords do not match", redirect }), 200);
20955
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "New passwords do not match", redirect }), 200);
20799
20956
  }
20800
20957
  if (!isPasswordValid(newPassword)) {
20801
20958
  const reqs = validatePasswordStrength(newPassword);
20802
20959
  const failed = reqs.filter((r) => !r.met);
20803
20960
  return c.html(renderLoginPage({
20804
- ...resolveRemoteAuthOpts(),
20961
+ ...resolveRemoteAuthOpts(c),
20805
20962
  mode: "change",
20806
20963
  changeError: `Requirements not met: ${failed.map((r) => r.label.toLowerCase()).join(", ")}`,
20807
20964
  redirect
20808
20965
  }), 200);
20809
20966
  }
20810
20967
  if (targetUserId && await accessPasswordCollides(newPassword, USERS_FILE, targetUserId)) {
20811
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "That password is already in use by another admin. Choose a different one.", redirect }), 200);
20968
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "That password is already in use by another admin. Choose a different one.", redirect }), 200);
20812
20969
  }
20813
20970
  try {
20814
20971
  if (targetUserId) {
@@ -20818,17 +20975,17 @@ app52.post("/__remote-auth/change-password", async (c) => {
20818
20975
  }
20819
20976
  clearRateLimit(client);
20820
20977
  console.error(`[remote-auth] password changed ip=${clientIp} userId=${targetUserId ?? "legacy"}`);
20821
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), success: "Password changed successfully. Sign in with your new password.", redirect }), 200);
20978
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), success: "Password changed successfully. Sign in with your new password.", redirect }), 200);
20822
20979
  } catch (err) {
20823
20980
  console.error(`[remote-auth] change-password save failed: ${err}`);
20824
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
20981
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Failed to save password", redirect }), 200);
20825
20982
  }
20826
20983
  });
20827
20984
  app52.get("/__remote-auth/setup", (c) => {
20828
20985
  if (isRemoteAuthConfigured()) {
20829
20986
  return c.redirect("/");
20830
20987
  }
20831
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
20988
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup" }), 200);
20832
20989
  });
20833
20990
  app52.post("/__remote-auth/set-initial-password", async (c) => {
20834
20991
  if (isRemoteAuthConfigured()) {
@@ -20844,16 +21001,16 @@ app52.post("/__remote-auth/set-initial-password", async (c) => {
20844
21001
  if (!password || !confirmPassword) {
20845
21002
  const clientIp = c.var.clientIp || "unknown";
20846
21003
  console.error(`[remote-auth] set-initial-password failed ip=${clientIp} why=empty-input hashBytes=0`);
20847
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Both fields are required" }), 200);
21004
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Both fields are required" }), 200);
20848
21005
  }
20849
21006
  if (password !== confirmPassword) {
20850
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Passwords do not match" }), 200);
21007
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Passwords do not match" }), 200);
20851
21008
  }
20852
21009
  if (!isPasswordValid(password)) {
20853
21010
  const reqs = validatePasswordStrength(password);
20854
21011
  const failed = reqs.filter((r) => !r.met);
20855
21012
  return c.html(renderLoginPage({
20856
- ...resolveRemoteAuthOpts(),
21013
+ ...resolveRemoteAuthOpts(c),
20857
21014
  mode: "setup",
20858
21015
  setupError: `Requirements not met: ${failed.map((r) => r.label.toLowerCase()).join(", ")}`
20859
21016
  }), 200);
@@ -20862,10 +21019,10 @@ app52.post("/__remote-auth/set-initial-password", async (c) => {
20862
21019
  await setRemotePassword(password);
20863
21020
  const clientIp = c.var.clientIp || "unknown";
20864
21021
  console.error(`[remote-auth] initial password set ip=${clientIp}`);
20865
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "success" }), 200);
21022
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "success" }), 200);
20866
21023
  } catch (err) {
20867
21024
  console.error(`[remote-auth] initial password save failed: ${err}`);
20868
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
21025
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
20869
21026
  }
20870
21027
  });
20871
21028
  app52.get("/api/remote-auth/status", (c) => {
@@ -20951,7 +21108,7 @@ app52.use("*", async (c, next) => {
20951
21108
  if (respond === "401") {
20952
21109
  return c.json({ code: "remote-auth-required" }, 401);
20953
21110
  }
20954
- return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
21111
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), redirect: path2 }), 200);
20955
21112
  });
20956
21113
  app52.route("/api/health", health_default);
20957
21114
  app52.route("/api/chat", chatRoutes);
@@ -1 +0,0 @@
1
- import{B as e,S as t}from"./OperatorConversations-RmqANYz8.js";import"./admin-types-CJrGd46U.js";import"./AdminShell-DjoP7YoA.js";import{n}from"./page-BpxHz1N-.js";var r=e(),i=t();(0,r.createRoot)(document.getElementById(`root`)).render((0,i.jsx)(n,{}));