@rubytech/create-maxy-code 0.1.198 → 0.1.203

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 (112) hide show
  1. package/package.json +2 -2
  2. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +3736 -0
  3. package/payload/platform/plugins/docs/references/admin-ui.md +3 -1
  4. package/payload/platform/scripts/check-architecture-skill-no-drift.mjs +67 -0
  5. package/payload/platform/scripts/check-no-esm-require.mjs +3 -0
  6. package/payload/platform/scripts/check-specialist-tool-surface.mjs +323 -0
  7. package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts.map +1 -1
  8. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js +7 -7
  9. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js.map +1 -1
  10. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +13 -0
  11. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  12. package/payload/platform/services/claude-session-manager/dist/http-server.js +126 -7
  13. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  14. package/payload/platform/services/claude-session-manager/dist/index.js +9 -1
  15. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  16. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.d.ts +2 -12
  17. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.d.ts.map +1 -1
  18. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.js +14 -67
  19. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.js.map +1 -1
  20. package/payload/platform/services/claude-session-manager/dist/jsonl-path.d.ts +6 -0
  21. package/payload/platform/services/claude-session-manager/dist/jsonl-path.d.ts.map +1 -1
  22. package/payload/platform/services/claude-session-manager/dist/jsonl-path.js +30 -0
  23. package/payload/platform/services/claude-session-manager/dist/jsonl-path.js.map +1 -1
  24. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  25. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +4 -0
  26. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  27. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +33 -3
  28. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
  29. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +88 -57
  30. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
  31. package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts +19 -0
  32. package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts.map +1 -1
  33. package/payload/platform/services/claude-session-manager/dist/session-sidecar.js +42 -0
  34. package/payload/platform/services/claude-session-manager/dist/session-sidecar.js.map +1 -1
  35. package/payload/platform/services/claude-session-manager/dist/systemd-spawn.d.ts +62 -0
  36. package/payload/platform/services/claude-session-manager/dist/systemd-spawn.d.ts.map +1 -0
  37. package/payload/platform/services/claude-session-manager/dist/systemd-spawn.js +173 -0
  38. package/payload/platform/services/claude-session-manager/dist/systemd-spawn.js.map +1 -0
  39. package/payload/platform/templates/agents/admin/IDENTITY.md +4 -0
  40. package/payload/platform/templates/agents/public/IDENTITY.md +1 -1
  41. package/payload/platform/templates/specialists/agents/coding-assistant.md +73 -0
  42. package/payload/server/public/assets/AdminShell-BcxEZnpu.js +1 -0
  43. package/payload/server/public/assets/{Checkbox-Bh3kwzxP.js → Checkbox-DL-HdT29.js} +1 -1
  44. package/payload/server/public/assets/{admin-BWzKAudL.js → admin-DMo5DWKH.js} +1 -1
  45. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-Boys2mT1.js → architectureDiagram-Q4EWVU46-BoUw4oYz.js} +1 -1
  46. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-CvHqp46r.js → blockDiagram-DXYQGD6D-DOscnO3m.js} +1 -1
  47. package/payload/server/public/assets/{brand-VQtREmts.css → brand-SZW-27T7.css} +1 -1
  48. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-DiNQ95F6.js → c4Diagram-AHTNJAMY-aZ1IuZ_F.js} +1 -1
  49. package/payload/server/public/assets/channel-CzcSNxDm.js +1 -0
  50. package/payload/server/public/assets/{chunk-336JU56O-9nS9-05M.js → chunk-336JU56O-DS3ksXBG.js} +2 -2
  51. package/payload/server/public/assets/{chunk-426QAEUC-B2__9lRY.js → chunk-426QAEUC-BLRn2STO.js} +1 -1
  52. package/payload/server/public/assets/{chunk-4TB4RGXK-R5F8rS0Z.js → chunk-4TB4RGXK-BrhOvJ01.js} +1 -1
  53. package/payload/server/public/assets/{chunk-5FUZZQ4R-B8HhJce-.js → chunk-5FUZZQ4R-BZZwZX5Q.js} +1 -1
  54. package/payload/server/public/assets/{chunk-5PVQY5BW-Bjb08lbL.js → chunk-5PVQY5BW-YXZKnPCz.js} +1 -1
  55. package/payload/server/public/assets/{chunk-EDXVE4YY-he0qCF3s.js → chunk-EDXVE4YY-DAMCJHKQ.js} +1 -1
  56. package/payload/server/public/assets/{chunk-ENJZ2VHE-BTArFW5l.js → chunk-ENJZ2VHE-DsD95Bqn.js} +1 -1
  57. package/payload/server/public/assets/{chunk-ICPOFSXX-CoyIL4q_.js → chunk-ICPOFSXX-DxtrRClx.js} +1 -1
  58. package/payload/server/public/assets/{chunk-OYMX7WX6-DjLEhNFe.js → chunk-OYMX7WX6-CN4kLK-H.js} +1 -1
  59. package/payload/server/public/assets/{chunk-U2HBQHQK-tac2uvW1.js → chunk-U2HBQHQK-BPTv3Oj1.js} +1 -1
  60. package/payload/server/public/assets/{chunk-X2U36JSP-DIWD9i88.js → chunk-X2U36JSP-DxBry33v.js} +1 -1
  61. package/payload/server/public/assets/{chunk-YZCP3GAM-Ac7ogADz.js → chunk-YZCP3GAM-BZ4N75oy.js} +1 -1
  62. package/payload/server/public/assets/{chunk-ZZ45TVLE-QgqDaY9-.js → chunk-ZZ45TVLE-Dqr161Q1.js} +1 -1
  63. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DFOM3vCn.js +1 -0
  64. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-HplDfaL1.js +1 -0
  65. package/payload/server/public/assets/clone-G-2rqnSR.js +1 -0
  66. package/payload/server/public/assets/{dagre-D6qN4nkK.js → dagre-DtZ0wKkH.js} +1 -1
  67. package/payload/server/public/assets/{dagre-KV5264BT-C6TRKOg0.js → dagre-KV5264BT-BPKhT-ZX.js} +1 -1
  68. package/payload/server/public/assets/{data-CaZbNF-j.js → data-D6IQdm0R.js} +1 -1
  69. package/payload/server/public/assets/{diagram-5BDNPKRD-BVk_J8Pt.js → diagram-5BDNPKRD-CATnafi7.js} +1 -1
  70. package/payload/server/public/assets/{diagram-G4DWMVQ6-BdV1IgwS.js → diagram-G4DWMVQ6-ChZYQfji.js} +1 -1
  71. package/payload/server/public/assets/{diagram-MMDJMWI5-OsvBkN6u.js → diagram-MMDJMWI5-DHW6kYd3.js} +1 -1
  72. package/payload/server/public/assets/{diagram-TYMM5635-BQmKPyrb.js → diagram-TYMM5635-CnS4Zci8.js} +1 -1
  73. package/payload/server/public/assets/{erDiagram-SMLLAGMA-ChEx5_3C.js → erDiagram-SMLLAGMA-DKYv2YWp.js} +1 -1
  74. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-B7sf6AG3.js → flowDiagram-DWJPFMVM-BWvoZWlh.js} +1 -1
  75. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-DbpSraax.js → ganttDiagram-T4ZO3ILL-CpCb-xKy.js} +1 -1
  76. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-BnxDElDh.js → gitGraphDiagram-UUTBAWPF-CvHrDKQ-.js} +1 -1
  77. package/payload/server/public/assets/{graph-CBP5yppq.js → graph-PkZKVkWD.js} +1 -1
  78. package/payload/server/public/assets/{graph-labels-BsZNScfa.js → graph-labels-CWJy0O4w.js} +1 -1
  79. package/payload/server/public/assets/{graphlib-Dux06enE.js → graphlib-DjnyHqGy.js} +1 -1
  80. package/payload/server/public/assets/{infoDiagram-42DDH7IO-BLWb6oKx.js → infoDiagram-42DDH7IO-D_MywcVn.js} +1 -1
  81. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-AFiRuE6G.js → ishikawaDiagram-UXIWVN3A-N9m-f-Eb.js} +1 -1
  82. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CxHBRGGu.js → journeyDiagram-VCZTEJTY-DE0q7uSM.js} +1 -1
  83. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-CGugF0N8.js → kanban-definition-6JOO6SKY-Dj5hb9Bq.js} +1 -1
  84. package/payload/server/public/assets/{line-COFloj-X.js → line-C6ph0i4M.js} +1 -1
  85. package/payload/server/public/assets/{mermaid-parser.core-CxXuCDQf.js → mermaid-parser.core-BrfmEvCA.js} +1 -1
  86. package/payload/server/public/assets/{mermaid.core-BRBNvNup.js → mermaid.core-DYnHKfDv.js} +3 -3
  87. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-DarW5Wwq.js → mindmap-definition-QFDTVHPH-DaSaZfhR.js} +1 -1
  88. package/payload/server/public/assets/{pieDiagram-DEJITSTG-CTokFAkN.js → pieDiagram-DEJITSTG-BAu9Ezbv.js} +1 -1
  89. package/payload/server/public/assets/{public-Bq-eOUu9.js → public-UKgkJxKv.js} +3 -3
  90. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-BNawkg3I.js → quadrantDiagram-34T5L4WZ-DRsbL1Xd.js} +1 -1
  91. package/payload/server/public/assets/{requirementDiagram-MS252O5E-CWnO56oR.js → requirementDiagram-MS252O5E-B9QcsXV6.js} +1 -1
  92. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-D9c-EZfV.js → sankeyDiagram-XADWPNL6-DsZbvIlD.js} +1 -1
  93. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-In5lxCT5.js → sequenceDiagram-FGHM5R23-BlT4O2N8.js} +1 -1
  94. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-CYb5js-u.js → stateDiagram-FHFEXIEX-JFgk1K3Y.js} +1 -1
  95. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-NXz27DaV.js +1 -0
  96. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Cje-BY9v.js → timeline-definition-GMOUNBTQ-DOsHw1ip.js} +1 -1
  97. package/payload/server/public/assets/{useSelectionMode-B_2EQ2CC.js → useSelectionMode-JDGvwvIk.js} +1 -1
  98. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-BqeuoPr1.js → vennDiagram-DHZGUBPP-CQWIhqZY.js} +1 -1
  99. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-DE7xAnoq.js → wardleyDiagram-NUSXRM2D-D5Fh7YVL.js} +1 -1
  100. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-JE4x8YEZ.js → xychartDiagram-5P7HB3ND-C-tINQEs.js} +1 -1
  101. package/payload/server/public/data.html +5 -5
  102. package/payload/server/public/graph.html +6 -6
  103. package/payload/server/public/index.html +6 -6
  104. package/payload/server/public/public.html +5 -5
  105. package/payload/server/server.js +566 -256
  106. package/payload/server/public/assets/AdminShell-DPk5UgEJ.js +0 -1
  107. package/payload/server/public/assets/channel-BgwH_qhE.js +0 -1
  108. package/payload/server/public/assets/classDiagram-6PBFFD2Q-CwdV1-c8.js +0 -1
  109. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CS_jtevB.js +0 -1
  110. package/payload/server/public/assets/clone-BTishuSs.js +0 -1
  111. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-z-TVJfRt.js +0 -1
  112. /package/payload/server/public/assets/{brand-CzeO4m4J.js → brand-SzZmKKjz.js} +0 -0
@@ -816,8 +816,8 @@ var serveStatic = (options = { root: "" }) => {
816
816
  };
817
817
 
818
818
  // server/index.ts
819
- import { readFileSync as readFileSync21, existsSync as existsSync21, watchFile } from "fs";
820
- import { resolve as resolve22, join as join16, basename as basename6 } from "path";
819
+ import { readFileSync as readFileSync22, existsSync as existsSync22, watchFile } from "fs";
820
+ import { resolve as resolve24, join as join17, basename as basename6 } from "path";
821
821
  import { homedir as homedir2 } from "os";
822
822
  import { monitorEventLoopDelay } from "perf_hooks";
823
823
 
@@ -1275,7 +1275,7 @@ var credsSaveQueue = Promise.resolve();
1275
1275
  async function drainCredsSaveQueue(timeoutMs = 5e3) {
1276
1276
  console.error(`${TAG2} draining credential save queue\u2026`);
1277
1277
  const timer2 = new Promise(
1278
- (resolve23) => setTimeout(() => resolve23("timeout"), timeoutMs)
1278
+ (resolve25) => setTimeout(() => resolve25("timeout"), timeoutMs)
1279
1279
  );
1280
1280
  const result = await Promise.race([
1281
1281
  credsSaveQueue.then(() => "drained"),
@@ -1403,11 +1403,11 @@ async function createWaSocket(opts) {
1403
1403
  return sock;
1404
1404
  }
1405
1405
  async function waitForConnection(sock) {
1406
- return new Promise((resolve23, reject) => {
1406
+ return new Promise((resolve25, reject) => {
1407
1407
  const handler = (update) => {
1408
1408
  if (update.connection === "open") {
1409
1409
  sock.ev.off("connection.update", handler);
1410
- resolve23();
1410
+ resolve25();
1411
1411
  }
1412
1412
  if (update.connection === "close") {
1413
1413
  sock.ev.off("connection.update", handler);
@@ -1521,14 +1521,14 @@ ${inspected}`;
1521
1521
  return inspect2(err, INSPECT_OPTS2);
1522
1522
  }
1523
1523
  function withTimeout(label, promise, timeoutMs) {
1524
- return new Promise((resolve23, reject) => {
1524
+ return new Promise((resolve25, reject) => {
1525
1525
  const timer2 = setTimeout(() => {
1526
1526
  reject(new Error(`${label} timed out after ${timeoutMs}ms`));
1527
1527
  }, timeoutMs);
1528
1528
  promise.then(
1529
1529
  (value) => {
1530
1530
  clearTimeout(timer2);
1531
- resolve23(value);
1531
+ resolve25(value);
1532
1532
  },
1533
1533
  (err) => {
1534
1534
  clearTimeout(timer2);
@@ -2063,8 +2063,8 @@ async function persistWhatsAppMessage(input) {
2063
2063
  const { givenName, familyName } = splitName(input.pushName);
2064
2064
  const prev = sessionWriteLocks.get(input.cacheKey);
2065
2065
  let release;
2066
- const mine = new Promise((resolve23) => {
2067
- release = resolve23;
2066
+ const mine = new Promise((resolve25) => {
2067
+ release = resolve25;
2068
2068
  });
2069
2069
  const chained = (prev ?? Promise.resolve()).then(() => mine);
2070
2070
  sessionWriteLocks.set(input.cacheKey, chained);
@@ -3100,11 +3100,11 @@ async function connectWithReconnect(conn) {
3100
3100
  console.error(
3101
3101
  `${TAG12} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
3102
3102
  );
3103
- await new Promise((resolve23) => {
3104
- const timer2 = setTimeout(resolve23, delay);
3103
+ await new Promise((resolve25) => {
3104
+ const timer2 = setTimeout(resolve25, delay);
3105
3105
  conn.abortController.signal.addEventListener("abort", () => {
3106
3106
  clearTimeout(timer2);
3107
- resolve23();
3107
+ resolve25();
3108
3108
  }, { once: true });
3109
3109
  });
3110
3110
  }
@@ -3112,16 +3112,16 @@ async function connectWithReconnect(conn) {
3112
3112
  }
3113
3113
  }
3114
3114
  function waitForDisconnectEvent(conn) {
3115
- return new Promise((resolve23) => {
3115
+ return new Promise((resolve25) => {
3116
3116
  if (!conn.sock) {
3117
- resolve23();
3117
+ resolve25();
3118
3118
  return;
3119
3119
  }
3120
3120
  const sock = conn.sock;
3121
3121
  const handler = (update) => {
3122
3122
  if (update.connection === "close") {
3123
3123
  sock.ev.off("connection.update", handler);
3124
- resolve23();
3124
+ resolve25();
3125
3125
  }
3126
3126
  };
3127
3127
  sock.ev.on("connection.update", handler);
@@ -3383,8 +3383,8 @@ async function handleInboundMessage(conn, msg) {
3383
3383
  const conversationKey = isGroup ? remoteJid : senderPhone;
3384
3384
  const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
3385
3385
  let resolvePending;
3386
- const sttPending = new Promise((resolve23) => {
3387
- resolvePending = resolve23;
3386
+ const sttPending = new Promise((resolve25) => {
3387
+ resolvePending = resolve25;
3388
3388
  });
3389
3389
  if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
3390
3390
  try {
@@ -3788,20 +3788,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
3788
3788
 
3789
3789
  // server/routes/health.ts
3790
3790
  function checkPort(port2, timeoutMs = 500) {
3791
- return new Promise((resolve23) => {
3791
+ return new Promise((resolve25) => {
3792
3792
  const socket = createConnection2(port2, "127.0.0.1");
3793
3793
  socket.setTimeout(timeoutMs);
3794
3794
  socket.once("connect", () => {
3795
3795
  socket.destroy();
3796
- resolve23(true);
3796
+ resolve25(true);
3797
3797
  });
3798
3798
  socket.once("error", () => {
3799
3799
  socket.destroy();
3800
- resolve23(false);
3800
+ resolve25(false);
3801
3801
  });
3802
3802
  socket.once("timeout", () => {
3803
3803
  socket.destroy();
3804
- resolve23(false);
3804
+ resolve25(false);
3805
3805
  });
3806
3806
  });
3807
3807
  }
@@ -4537,12 +4537,12 @@ async function dispatchOnce(input) {
4537
4537
  });
4538
4538
  if (!entry) return { error: "spawn-failed" };
4539
4539
  entry.lastInboundAt = Date.now();
4540
- let resolve23;
4540
+ let resolve25;
4541
4541
  const turnPromise = new Promise((r) => {
4542
- resolve23 = r;
4542
+ resolve25 = r;
4543
4543
  });
4544
4544
  const listener = (text) => {
4545
- resolve23(text);
4545
+ resolve25(text);
4546
4546
  };
4547
4547
  entry.subscribers.add(listener);
4548
4548
  const writeOk = await writeInput(entry, input.text);
@@ -4984,8 +4984,8 @@ async function startLogin(opts) {
4984
4984
  resetActiveLogin(accountId);
4985
4985
  let resolveQr = null;
4986
4986
  let rejectQr = null;
4987
- const qrPromise = new Promise((resolve23, reject) => {
4988
- resolveQr = resolve23;
4987
+ const qrPromise = new Promise((resolve25, reject) => {
4988
+ resolveQr = resolve25;
4989
4989
  rejectQr = reject;
4990
4990
  });
4991
4991
  const qrTimer = setTimeout(
@@ -7458,11 +7458,11 @@ app11.delete("/:id", requireAdminSession, async (c) => {
7458
7458
  const owned = await verifyConversationOwnership(sessionId, accountId);
7459
7459
  if (!owned) return c.json({ error: "Conversation not found" }, 404);
7460
7460
  const managerPort = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "admin-conversation-delete" });
7461
- const managerBase4 = `http://127.0.0.1:${managerPort}`;
7461
+ const managerBase5 = `http://127.0.0.1:${managerPort}`;
7462
7462
  const outcome = await cascadeAdminConversationDelete({
7463
7463
  sessionId,
7464
7464
  accountId,
7465
- managerBase: managerBase4
7465
+ managerBase: managerBase5
7466
7466
  });
7467
7467
  if (outcome.ok) return c.json({ ok: true, claudeSessionIds: outcome.claudeSessionIds });
7468
7468
  if (outcome.reason === "pty-still-alive") {
@@ -11159,7 +11159,7 @@ app18.post("/", requireAdminSession, async (c) => {
11159
11159
  return c.json({ error: "AdminConversation node is missing sessionId" }, 500);
11160
11160
  }
11161
11161
  const managerPort = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "graph-page-cascade" });
11162
- const managerBase4 = `http://127.0.0.1:${managerPort}`;
11162
+ const managerBase5 = `http://127.0.0.1:${managerPort}`;
11163
11163
  try {
11164
11164
  await session.close();
11165
11165
  } catch {
@@ -11167,7 +11167,7 @@ app18.post("/", requireAdminSession, async (c) => {
11167
11167
  const outcome = await cascadeAdminConversationDelete({
11168
11168
  sessionId,
11169
11169
  accountId,
11170
- managerBase: managerBase4
11170
+ managerBase: managerBase5
11171
11171
  });
11172
11172
  const elapsed2 = Date.now() - started;
11173
11173
  const labelSummary2 = preflightLabels.join(",");
@@ -11722,10 +11722,11 @@ var sidebar_artefacts_default = app22;
11722
11722
 
11723
11723
  // server/routes/admin/sidebar-sessions.ts
11724
11724
  import { readdirSync as readdirSync8, readFileSync as readFileSync14, statSync as statSync7 } from "fs";
11725
- import { join as join13 } from "path";
11726
- var RC_URL_RE = /https:\/\/claude\.ai\/code\/session_[A-Za-z0-9_-]+/;
11725
+ import { join as join13, resolve as resolve16 } from "path";
11727
11726
  var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.jsonl$/i;
11727
+ var PID_FILE_RE = /^([0-9]+)\.json$/;
11728
11728
  var TITLE_MAX = 80;
11729
+ var CLI_MARKER_PREFIXES = ["<local-command-", "<command-name>", "<command-message>"];
11729
11730
  var app23 = new Hono();
11730
11731
  function claudeConfigDir() {
11731
11732
  return process.env.CLAUDE_CONFIG_DIR ?? null;
@@ -11772,8 +11773,8 @@ function enumerateJsonls(projectsRoot) {
11772
11773
  }
11773
11774
  return out;
11774
11775
  }
11775
- function liveSessionIdSet(configDir2) {
11776
- const out = /* @__PURE__ */ new Set();
11776
+ function sessionIdToPidMap(configDir2) {
11777
+ const out = /* @__PURE__ */ new Map();
11777
11778
  const sessionsDir = join13(configDir2, "sessions");
11778
11779
  let entries;
11779
11780
  try {
@@ -11782,7 +11783,11 @@ function liveSessionIdSet(configDir2) {
11782
11783
  return out;
11783
11784
  }
11784
11785
  for (const entry of entries) {
11785
- if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
11786
+ if (!entry.isFile()) continue;
11787
+ const m = entry.name.match(PID_FILE_RE);
11788
+ if (!m) continue;
11789
+ const pid = Number(m[1]);
11790
+ if (!Number.isFinite(pid) || pid <= 0) continue;
11786
11791
  let body;
11787
11792
  try {
11788
11793
  body = readFileSync14(join13(sessionsDir, entry.name), "utf8");
@@ -11797,11 +11802,69 @@ function liveSessionIdSet(configDir2) {
11797
11802
  }
11798
11803
  if (!parsed || typeof parsed !== "object") continue;
11799
11804
  const sid = parsed.sessionId;
11800
- if (typeof sid === "string" && sid.length > 0) out.add(sid);
11805
+ if (typeof sid === "string" && sid.length > 0) out.set(sid, pid);
11801
11806
  }
11802
11807
  return out;
11803
11808
  }
11804
- function firstUserMessage(body) {
11809
+ function loadUserTitles(accountDir) {
11810
+ const out = /* @__PURE__ */ new Map();
11811
+ if (!accountDir) return out;
11812
+ const path2 = join13(accountDir, "session-titles.json");
11813
+ let raw;
11814
+ try {
11815
+ raw = readFileSync14(path2, "utf8");
11816
+ } catch {
11817
+ return out;
11818
+ }
11819
+ let parsed;
11820
+ try {
11821
+ parsed = JSON.parse(raw);
11822
+ } catch {
11823
+ return out;
11824
+ }
11825
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return out;
11826
+ for (const [sessionId, value] of Object.entries(parsed)) {
11827
+ if (!sessionId) continue;
11828
+ if (!value || typeof value !== "object") continue;
11829
+ const v = value;
11830
+ if (typeof v.title !== "string") continue;
11831
+ const trimmed = v.title.trim();
11832
+ if (!trimmed) continue;
11833
+ out.set(sessionId, trimmed);
11834
+ }
11835
+ return out;
11836
+ }
11837
+ function readBridgeIds(metaPath) {
11838
+ let raw;
11839
+ try {
11840
+ raw = readFileSync14(metaPath, "utf8");
11841
+ } catch {
11842
+ return [];
11843
+ }
11844
+ let parsed;
11845
+ try {
11846
+ parsed = JSON.parse(raw);
11847
+ } catch {
11848
+ return [];
11849
+ }
11850
+ if (!parsed || typeof parsed !== "object") return [];
11851
+ const ids = parsed.bridgeIds;
11852
+ if (!Array.isArray(ids)) return [];
11853
+ return ids.filter((b) => typeof b === "string" && b.length > 0);
11854
+ }
11855
+ function startsWithCliMarker(s) {
11856
+ for (const p of CLI_MARKER_PREFIXES) if (s.startsWith(p)) return true;
11857
+ return false;
11858
+ }
11859
+ function trimToTitle(raw) {
11860
+ const trimmed = raw.trim().replace(/\s+/g, " ");
11861
+ return trimmed.length > TITLE_MAX ? trimmed.slice(0, TITLE_MAX - 1) + "\u2026" : trimmed;
11862
+ }
11863
+ function resolveTitle(body, sessionId, userTitles) {
11864
+ const userTitle = userTitles.get(sessionId);
11865
+ if (userTitle) return { title: trimToTitle(userTitle), source: "user" };
11866
+ let aiTitle = null;
11867
+ let firstUserMessage = null;
11805
11868
  for (const line of body.split("\n")) {
11806
11869
  if (!line || line[0] !== "{") continue;
11807
11870
  let parsed;
@@ -11812,31 +11875,45 @@ function firstUserMessage(body) {
11812
11875
  }
11813
11876
  if (!parsed || typeof parsed !== "object") continue;
11814
11877
  const row = parsed;
11815
- if (row.type !== "user" || !row.message || row.message.role !== "user") continue;
11816
- const content = row.message.content;
11817
- if (typeof content !== "string") continue;
11818
- const trimmed = content.trim().replace(/\s+/g, " ");
11819
- if (!trimmed) continue;
11820
- return trimmed.length > TITLE_MAX ? trimmed.slice(0, TITLE_MAX - 1) + "\u2026" : trimmed;
11878
+ if (row.type === "ai-title" && typeof row.aiTitle === "string") {
11879
+ const t = row.aiTitle.trim();
11880
+ if (t) aiTitle = t;
11881
+ continue;
11882
+ }
11883
+ if (firstUserMessage === null && row.type === "user" && row.message && row.message.role === "user") {
11884
+ const content = row.message.content;
11885
+ if (typeof content !== "string") continue;
11886
+ const trimmed = content.trim();
11887
+ if (!trimmed) continue;
11888
+ if (startsWithCliMarker(trimmed)) continue;
11889
+ firstUserMessage = trimmed;
11890
+ }
11821
11891
  }
11822
- return null;
11892
+ if (aiTitle) return { title: trimToTitle(aiTitle), source: "ai" };
11893
+ if (firstUserMessage) return { title: trimToTitle(firstUserMessage), source: "first-message" };
11894
+ return { title: sessionId.slice(0, 8), source: "prefix" };
11823
11895
  }
11824
11896
  app23.get("/", requireAdminSession, async (c) => {
11897
+ const accountId = process.env.ACCOUNT_ID ?? null;
11825
11898
  const configDir2 = claudeConfigDir();
11826
11899
  if (!configDir2) {
11827
11900
  console.error("[admin-sessions-list] CLAUDE_CONFIG_DIR not set; returning empty list");
11828
- return c.json({ sessions: [] });
11901
+ return c.json({ sessions: [], accountId });
11829
11902
  }
11830
11903
  const projectsRoot = join13(configDir2, "projects");
11831
11904
  const jsonls = enumerateJsonls(projectsRoot);
11832
- const liveIds = liveSessionIdSet(configDir2);
11905
+ const pidsBySession = sessionIdToPidMap(configDir2);
11906
+ const accountDir = accountId ? resolve16(ACCOUNTS_DIR, accountId) : null;
11907
+ const userTitles = loadUserTitles(accountDir);
11833
11908
  const rows = [];
11834
11909
  const seenIds = /* @__PURE__ */ new Set();
11835
11910
  let liveCount = 0;
11836
- let rcCount = 0;
11837
11911
  let subagentCount = 0;
11912
+ const titleSourceCounts = { user: 0, ai: 0, "first-message": 0, prefix: 0 };
11838
11913
  for (const { path: path2, isSubagent } of jsonls) {
11839
- const base = path2.slice(path2.lastIndexOf("/") + 1);
11914
+ const lastSlash = path2.lastIndexOf("/");
11915
+ const base = path2.slice(lastSlash + 1);
11916
+ const projectDir = path2.slice(0, lastSlash);
11840
11917
  const sessionId = base.slice(0, -".jsonl".length);
11841
11918
  if (seenIds.has(sessionId)) {
11842
11919
  console.error(`[admin-sessions-list] duplicate-sessionId sessionId=${sessionId} path=${path2}`);
@@ -11851,30 +11928,261 @@ app23.get("/", requireAdminSession, async (c) => {
11851
11928
  } catch {
11852
11929
  continue;
11853
11930
  }
11854
- const urlMatch = body.match(RC_URL_RE);
11855
- const live = liveIds.has(sessionId);
11856
- const title = firstUserMessage(body) ?? sessionId.slice(0, 8);
11857
- const row = {
11931
+ const pid = pidsBySession.get(sessionId) ?? null;
11932
+ const live = pid !== null;
11933
+ const resolved = resolveTitle(body, sessionId, userTitles);
11934
+ titleSourceCounts[resolved.source] += 1;
11935
+ const bridgeIds = readBridgeIds(join13(projectDir, `${sessionId}.meta.json`));
11936
+ rows.push({
11858
11937
  sessionId,
11859
- title,
11938
+ title: resolved.title,
11939
+ titleSource: resolved.source,
11860
11940
  startedAt: new Date(mtimeMs).toISOString(),
11861
11941
  live,
11862
- isSubagent
11863
- };
11864
- if (urlMatch) row.rcUrl = urlMatch[0];
11865
- rows.push(row);
11942
+ isSubagent,
11943
+ pid,
11944
+ projectDir,
11945
+ bridgeIds
11946
+ });
11866
11947
  if (live) liveCount += 1;
11867
- if (urlMatch) rcCount += 1;
11868
11948
  if (isSubagent) subagentCount += 1;
11869
11949
  }
11870
11950
  rows.sort((a, b) => a.startedAt < b.startedAt ? 1 : -1);
11871
11951
  console.log(
11872
- `[admin-sessions-list] rows=${rows.length} live=${liveCount} rc=${rcCount} subagents=${subagentCount}`
11952
+ `[admin-sessions-list] rows=${rows.length} live=${liveCount} subagents=${subagentCount} titles user=${titleSourceCounts.user} ai=${titleSourceCounts.ai} first=${titleSourceCounts["first-message"]} prefix=${titleSourceCounts.prefix} accountId=${accountId ? accountId.slice(0, 8) : "unset"}`
11873
11953
  );
11874
- return c.json({ sessions: rows });
11954
+ return c.json({ sessions: rows, accountId });
11875
11955
  });
11876
11956
  var sidebar_sessions_default = app23;
11877
11957
 
11958
+ // server/routes/admin/session-delete.ts
11959
+ import { existsSync as existsSync17, readdirSync as readdirSync9, readFileSync as readFileSync15, unlinkSync as unlinkSync2 } from "fs";
11960
+ import { join as join14, resolve as resolve17 } from "path";
11961
+ var app24 = new Hono();
11962
+ var SESSION_ID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
11963
+ var PID_FILE_RE2 = /^([0-9]+)\.json$/;
11964
+ var SIGTERM_WAIT_MS = 2e3;
11965
+ var SIGKILL_WAIT_MS = 1e3;
11966
+ var POLL_INTERVAL_MS = 50;
11967
+ function findPidForSession(configDir2, sessionId) {
11968
+ const sessionsDir = join14(configDir2, "sessions");
11969
+ let entries;
11970
+ try {
11971
+ entries = readdirSync9(sessionsDir, { withFileTypes: true });
11972
+ } catch {
11973
+ return null;
11974
+ }
11975
+ for (const entry of entries) {
11976
+ if (!entry.isFile()) continue;
11977
+ const m = entry.name.match(PID_FILE_RE2);
11978
+ if (!m) continue;
11979
+ const pid = Number(m[1]);
11980
+ if (!Number.isFinite(pid) || pid <= 0) continue;
11981
+ let body;
11982
+ try {
11983
+ body = readFileSync15(join14(sessionsDir, entry.name), "utf8");
11984
+ } catch {
11985
+ continue;
11986
+ }
11987
+ let parsed;
11988
+ try {
11989
+ parsed = JSON.parse(body);
11990
+ } catch {
11991
+ continue;
11992
+ }
11993
+ if (!parsed || typeof parsed !== "object") continue;
11994
+ if (parsed.sessionId === sessionId) return pid;
11995
+ }
11996
+ return null;
11997
+ }
11998
+ function isPidAlive(pid) {
11999
+ try {
12000
+ process.kill(pid, 0);
12001
+ return true;
12002
+ } catch (err) {
12003
+ const code = err.code;
12004
+ if (code === "ESRCH") return false;
12005
+ return true;
12006
+ }
12007
+ }
12008
+ function sleep2(ms) {
12009
+ return new Promise((resolve25) => setTimeout(resolve25, ms));
12010
+ }
12011
+ function sendSignal(pid, signal) {
12012
+ try {
12013
+ process.kill(pid, signal);
12014
+ return true;
12015
+ } catch (err) {
12016
+ const code = err.code;
12017
+ if (code === "ESRCH") return true;
12018
+ return false;
12019
+ }
12020
+ }
12021
+ async function killAndWait(pid) {
12022
+ const startedAt = Date.now();
12023
+ let escalated = false;
12024
+ const termSent = sendSignal(pid, "SIGTERM");
12025
+ const termDeadline = Date.now() + SIGTERM_WAIT_MS;
12026
+ while (Date.now() < termDeadline) {
12027
+ if (!isPidAlive(pid)) {
12028
+ return {
12029
+ pidKilled: termSent ? "true" : "false",
12030
+ waitForExitMs: Date.now() - startedAt,
12031
+ escalatedToSIGKILL: false,
12032
+ exited: true
12033
+ };
12034
+ }
12035
+ await sleep2(POLL_INTERVAL_MS);
12036
+ }
12037
+ escalated = true;
12038
+ sendSignal(pid, "SIGKILL");
12039
+ const killDeadline = Date.now() + SIGKILL_WAIT_MS;
12040
+ while (Date.now() < killDeadline) {
12041
+ if (!isPidAlive(pid)) {
12042
+ return {
12043
+ pidKilled: "true",
12044
+ waitForExitMs: Date.now() - startedAt,
12045
+ escalatedToSIGKILL: true,
12046
+ exited: true
12047
+ };
12048
+ }
12049
+ await sleep2(POLL_INTERVAL_MS);
12050
+ }
12051
+ return {
12052
+ pidKilled: "false",
12053
+ waitForExitMs: Date.now() - startedAt,
12054
+ escalatedToSIGKILL: escalated,
12055
+ exited: false
12056
+ };
12057
+ }
12058
+ app24.post("/", requireAdminSession, async (c) => {
12059
+ let body;
12060
+ try {
12061
+ body = await c.req.json();
12062
+ } catch {
12063
+ return c.json({ error: "invalid JSON body" }, 400);
12064
+ }
12065
+ const sessionId = typeof body.sessionId === "string" ? body.sessionId : "";
12066
+ const projectDir = typeof body.projectDir === "string" ? body.projectDir : "";
12067
+ if (!SESSION_ID_RE2.test(sessionId)) {
12068
+ return c.json({ error: "sessionId must be a v4 UUID" }, 400);
12069
+ }
12070
+ if (!projectDir) {
12071
+ return c.json({ error: "projectDir is required" }, 400);
12072
+ }
12073
+ const configDir2 = process.env.CLAUDE_CONFIG_DIR;
12074
+ if (!configDir2) {
12075
+ return c.json({ error: "CLAUDE_CONFIG_DIR not set" }, 500);
12076
+ }
12077
+ const projectsRoot = resolve17(join14(configDir2, "projects")) + "/";
12078
+ const resolvedProject = resolve17(projectDir) + "/";
12079
+ if (!resolvedProject.startsWith(projectsRoot)) {
12080
+ console.error(`[sessions-delete] reject reason=projectDir-outside-tree projectDir=${projectDir}`);
12081
+ return c.json({ error: "projectDir is not under CLAUDE_CONFIG_DIR/projects/" }, 400);
12082
+ }
12083
+ const jsonlPath = join14(projectDir, `${sessionId}.jsonl`);
12084
+ const sidecarPath = join14(projectDir, `${sessionId}.meta.json`);
12085
+ const pid = findPidForSession(configDir2, sessionId);
12086
+ let pidKilled = "absent";
12087
+ let waitForExitMs = 0;
12088
+ let escalatedToSIGKILL = false;
12089
+ if (pid !== null) {
12090
+ const r = await killAndWait(pid);
12091
+ pidKilled = r.pidKilled;
12092
+ waitForExitMs = r.waitForExitMs;
12093
+ escalatedToSIGKILL = r.escalatedToSIGKILL;
12094
+ if (!r.exited) {
12095
+ console.error(
12096
+ `[sessions-delete] kill-failed sessionId=${sessionId} pid=${pid} waitForExit=${waitForExitMs} escalatedToSIGKILL=${escalatedToSIGKILL}`
12097
+ );
12098
+ return c.json(
12099
+ { error: "kill-failed", pid, waitForExitMs, escalatedToSIGKILL },
12100
+ 500
12101
+ );
12102
+ }
12103
+ }
12104
+ let deleted = false;
12105
+ try {
12106
+ if (existsSync17(jsonlPath)) {
12107
+ unlinkSync2(jsonlPath);
12108
+ deleted = true;
12109
+ }
12110
+ } catch (err) {
12111
+ const msg = err instanceof Error ? err.message : String(err);
12112
+ console.error(`[sessions-delete] unlink-failed path=${jsonlPath} err=${msg}`);
12113
+ console.log(
12114
+ `[sessions-delete] sessionId=${sessionId} pidKilled=${pidKilled} jsonlPath=${jsonlPath} deleted=false waitForExit=${waitForExitMs} escalatedToSIGKILL=${escalatedToSIGKILL}`
12115
+ );
12116
+ return c.json({ error: `unlink failed: ${msg}` }, 500);
12117
+ }
12118
+ try {
12119
+ if (existsSync17(sidecarPath)) unlinkSync2(sidecarPath);
12120
+ } catch {
12121
+ }
12122
+ if (pid !== null) {
12123
+ try {
12124
+ const pidFile = join14(configDir2, "sessions", `${pid}.json`);
12125
+ if (existsSync17(pidFile)) unlinkSync2(pidFile);
12126
+ } catch {
12127
+ }
12128
+ }
12129
+ if (existsSync17(jsonlPath)) {
12130
+ console.error(`[sessions-delete] resurrection jsonlPath=${jsonlPath} sessionId=${sessionId}`);
12131
+ return c.json(
12132
+ { error: "jsonl-resurrected", jsonlPath, pidKilled, waitForExitMs, escalatedToSIGKILL },
12133
+ 500
12134
+ );
12135
+ }
12136
+ console.log(
12137
+ `[sessions-delete] sessionId=${sessionId} pidKilled=${pidKilled} jsonlPath=${jsonlPath} deleted=${deleted} waitForExit=${waitForExitMs} escalatedToSIGKILL=${escalatedToSIGKILL}`
12138
+ );
12139
+ return c.json({ deleted, pidKilled, jsonlPath, waitForExitMs, escalatedToSIGKILL });
12140
+ });
12141
+ var session_delete_default = app24;
12142
+
12143
+ // server/routes/admin/session-rc-spawn.ts
12144
+ var app25 = new Hono();
12145
+ function managerBase4() {
12146
+ const port2 = process.env.CLAUDE_SESSION_MANAGER_PORT;
12147
+ if (!port2) throw new Error("CLAUDE_SESSION_MANAGER_PORT is not set");
12148
+ return `http://127.0.0.1:${port2}`;
12149
+ }
12150
+ app25.post("/", requireAdminSession, async (c) => {
12151
+ let body;
12152
+ try {
12153
+ body = await c.req.json();
12154
+ } catch {
12155
+ body = {};
12156
+ }
12157
+ const payload = {};
12158
+ if (typeof body.sessionId === "string" && body.sessionId.length > 0) payload.sessionId = body.sessionId;
12159
+ if (typeof body.name === "string" && body.name.length > 0) payload.name = body.name;
12160
+ let res;
12161
+ try {
12162
+ res = await fetch(`${managerBase4()}/rc-spawn`, {
12163
+ method: "POST",
12164
+ headers: { "content-type": "application/json" },
12165
+ body: JSON.stringify(payload)
12166
+ });
12167
+ } catch (err) {
12168
+ const msg = err instanceof Error ? err.message : String(err);
12169
+ console.error(`[session-rc-spawn] manager-unreachable err=${msg}`);
12170
+ return c.json({ error: `session manager unreachable: ${msg}` }, 502);
12171
+ }
12172
+ const text = await res.text();
12173
+ let parsed = null;
12174
+ try {
12175
+ parsed = JSON.parse(text);
12176
+ } catch {
12177
+ }
12178
+ if (!res.ok) {
12179
+ console.error(`[session-rc-spawn] manager-error status=${res.status} body=${text.slice(0, 200)}`);
12180
+ return c.json(parsed ?? { error: text }, res.status);
12181
+ }
12182
+ return c.json(parsed ?? {});
12183
+ });
12184
+ var session_rc_spawn_default = app25;
12185
+
11878
12186
  // server/routes/admin/system-stats.ts
11879
12187
  import { readFile as readFile5 } from "fs/promises";
11880
12188
  import { cpus, loadavg, totalmem, freemem } from "os";
@@ -11970,8 +12278,8 @@ async function sample() {
11970
12278
  if (process.platform === "linux") return sampleLinux();
11971
12279
  return sampleOsFallback();
11972
12280
  }
11973
- var app24 = new Hono();
11974
- app24.get("/", async (c) => {
12281
+ var app26 = new Hono();
12282
+ app26.get("/", async (c) => {
11975
12283
  const started = Date.now();
11976
12284
  if (!inflight) {
11977
12285
  inflight = sample().finally(() => {
@@ -11994,27 +12302,27 @@ app24.get("/", async (c) => {
11994
12302
  return c.json({ degraded: true, reason, sampledAtMs: Date.now() });
11995
12303
  }
11996
12304
  });
11997
- var system_stats_default = app24;
12305
+ var system_stats_default = app26;
11998
12306
 
11999
12307
  // server/routes/admin/health.ts
12000
- import { existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
12001
- import { resolve as resolve16, join as join14 } from "path";
12002
- var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve16(process.cwd(), "..");
12308
+ import { existsSync as existsSync18, readFileSync as readFileSync16 } from "fs";
12309
+ import { resolve as resolve18, join as join15 } from "path";
12310
+ var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve18(process.cwd(), "..");
12003
12311
  var brandHostname = "maxy";
12004
- var brandJsonPath = join14(PLATFORM_ROOT6, "config", "brand.json");
12005
- if (existsSync17(brandJsonPath)) {
12312
+ var brandJsonPath = join15(PLATFORM_ROOT6, "config", "brand.json");
12313
+ if (existsSync18(brandJsonPath)) {
12006
12314
  try {
12007
- const brand = JSON.parse(readFileSync15(brandJsonPath, "utf-8"));
12315
+ const brand = JSON.parse(readFileSync16(brandJsonPath, "utf-8"));
12008
12316
  if (brand.hostname) brandHostname = brand.hostname;
12009
12317
  } catch {
12010
12318
  }
12011
12319
  }
12012
- var VERSION_FILE = resolve16(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
12320
+ var VERSION_FILE = resolve18(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
12013
12321
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
12014
12322
  var PROBE_TIMEOUT_MS = 1e3;
12015
12323
  function readVersion() {
12016
- if (!existsSync17(VERSION_FILE)) return "unknown";
12017
- return readFileSync15(VERSION_FILE, "utf-8").trim() || "unknown";
12324
+ if (!existsSync18(VERSION_FILE)) return "unknown";
12325
+ return readFileSync16(VERSION_FILE, "utf-8").trim() || "unknown";
12018
12326
  }
12019
12327
  async function probeConversationDb() {
12020
12328
  let session;
@@ -12039,8 +12347,8 @@ async function probeConversationDb() {
12039
12347
  });
12040
12348
  }
12041
12349
  }
12042
- var app25 = new Hono();
12043
- app25.get("/", async (c) => {
12350
+ var app27 = new Hono();
12351
+ app27.get("/", async (c) => {
12044
12352
  const version = readVersion();
12045
12353
  const probe = await probeConversationDb();
12046
12354
  const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
@@ -12062,7 +12370,7 @@ app25.get("/", async (c) => {
12062
12370
  uptimeMs
12063
12371
  });
12064
12372
  });
12065
- var health_default2 = app25;
12373
+ var health_default2 = app27;
12066
12374
 
12067
12375
  // server/routes/admin/linkedin-ingest.ts
12068
12376
  var TAG20 = "[linkedin-ingest-route]";
@@ -12158,8 +12466,8 @@ function buildInitialMessage(env) {
12158
12466
  }
12159
12467
  return header;
12160
12468
  }
12161
- var app26 = new Hono();
12162
- app26.post("/", requireAdminSession, async (c) => {
12469
+ var app28 = new Hono();
12470
+ app28.post("/", requireAdminSession, async (c) => {
12163
12471
  let body;
12164
12472
  try {
12165
12473
  body = await c.req.json();
@@ -12213,7 +12521,7 @@ app26.post("/", requireAdminSession, async (c) => {
12213
12521
  );
12214
12522
  return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: claudeSessionId }, 202);
12215
12523
  });
12216
- var linkedin_ingest_default = app26;
12524
+ var linkedin_ingest_default = app28;
12217
12525
 
12218
12526
  // server/routes/admin/post-turn-context.ts
12219
12527
  import neo4j2 from "neo4j-driver";
@@ -12255,8 +12563,8 @@ function pruneProperties(raw) {
12255
12563
  }
12256
12564
  return out;
12257
12565
  }
12258
- var app27 = new Hono();
12259
- app27.get("/", async (c) => {
12566
+ var app29 = new Hono();
12567
+ app29.get("/", async (c) => {
12260
12568
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
12261
12569
  if (!isLoopbackAddr2(remoteAddr)) {
12262
12570
  console.error(`${TAG21} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -12316,7 +12624,7 @@ app27.get("/", async (c) => {
12316
12624
  await session.close();
12317
12625
  }
12318
12626
  });
12319
- var post_turn_context_default = app27;
12627
+ var post_turn_context_default = app29;
12320
12628
 
12321
12629
  // server/routes/admin/public-session-context.ts
12322
12630
  import neo4j3 from "neo4j-driver";
@@ -12358,8 +12666,8 @@ function pruneProperties2(raw) {
12358
12666
  }
12359
12667
  return out;
12360
12668
  }
12361
- var app28 = new Hono();
12362
- app28.get("/", async (c) => {
12669
+ var app30 = new Hono();
12670
+ app30.get("/", async (c) => {
12363
12671
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
12364
12672
  if (!isLoopbackAddr3(remoteAddr)) {
12365
12673
  console.error(`${TAG22} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -12418,15 +12726,15 @@ app28.get("/", async (c) => {
12418
12726
  await session.close();
12419
12727
  }
12420
12728
  });
12421
- var public_session_context_default = app28;
12729
+ var public_session_context_default = app30;
12422
12730
 
12423
12731
  // server/routes/admin/public-session-exit.ts
12424
12732
  var TAG23 = "[public-session-exit-route]";
12425
12733
  function isLoopbackAddr4(addr) {
12426
12734
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
12427
12735
  }
12428
- var app29 = new Hono();
12429
- app29.post("/", async (c) => {
12736
+ var app31 = new Hono();
12737
+ app31.post("/", async (c) => {
12430
12738
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
12431
12739
  if (!isLoopbackAddr4(remoteAddr)) {
12432
12740
  console.error(`${TAG23} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -12453,15 +12761,15 @@ app29.post("/", async (c) => {
12453
12761
  handlePublicSessionExit(sessionId);
12454
12762
  return c.json({ ok: true });
12455
12763
  });
12456
- var public_session_exit_default = app29;
12764
+ var public_session_exit_default = app31;
12457
12765
 
12458
12766
  // server/routes/admin/access-session-evict.ts
12459
12767
  var TAG24 = "[access-session-evict]";
12460
12768
  function isLoopbackAddr5(addr) {
12461
12769
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
12462
12770
  }
12463
- var app30 = new Hono();
12464
- app30.post("/", async (c) => {
12771
+ var app32 = new Hono();
12772
+ app32.post("/", async (c) => {
12465
12773
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
12466
12774
  if (!isLoopbackAddr5(remoteAddr)) {
12467
12775
  console.error(`${TAG24} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -12489,49 +12797,51 @@ app30.post("/", async (c) => {
12489
12797
  console.log(`${TAG24} grantId=${grantId} dropped=${dropped}`);
12490
12798
  return c.json({ ok: true, dropped });
12491
12799
  });
12492
- var access_session_evict_default = app30;
12800
+ var access_session_evict_default = app32;
12493
12801
 
12494
12802
  // server/routes/admin/index.ts
12495
- var app31 = new Hono();
12496
- app31.route("/session", session_default);
12497
- app31.route("/logs", logs_default);
12498
- app31.route("/claude-info", claude_info_default);
12499
- app31.route("/attachment", attachment_default);
12500
- app31.route("/agents", agents_default);
12501
- app31.route("/sessions", sessions_default);
12502
- app31.route("/claude-sessions", claude_sessions_default);
12503
- app31.route("/log-ingest", log_ingest_default);
12504
- app31.route("/events", events_default);
12505
- app31.route("/files", files_default);
12506
- app31.route("/graph-search", graph_search_default);
12507
- app31.route("/graph-subgraph", graph_subgraph_default);
12508
- app31.route("/graph-delete", graph_delete_default);
12509
- app31.route("/graph-restore", graph_restore_default);
12510
- app31.route("/graph-labels-in-graph", graph_labels_in_graph_default);
12511
- app31.route("/graph-default-view", graph_default_view_default);
12512
- app31.route("/sidebar-artefacts", sidebar_artefacts_default);
12513
- app31.route("/sidebar-sessions", sidebar_sessions_default);
12514
- app31.route("/system-stats", system_stats_default);
12515
- app31.route("/health-brand", health_default2);
12516
- app31.route("/linkedin-ingest", linkedin_ingest_default);
12517
- app31.route("/post-turn-context", post_turn_context_default);
12518
- app31.route("/public-session-context", public_session_context_default);
12519
- app31.route("/public-session-exit", public_session_exit_default);
12520
- app31.route("/access-session-evict", access_session_evict_default);
12521
- var admin_default = app31;
12803
+ var app33 = new Hono();
12804
+ app33.route("/session", session_default);
12805
+ app33.route("/logs", logs_default);
12806
+ app33.route("/claude-info", claude_info_default);
12807
+ app33.route("/attachment", attachment_default);
12808
+ app33.route("/agents", agents_default);
12809
+ app33.route("/sessions", sessions_default);
12810
+ app33.route("/claude-sessions", claude_sessions_default);
12811
+ app33.route("/log-ingest", log_ingest_default);
12812
+ app33.route("/events", events_default);
12813
+ app33.route("/files", files_default);
12814
+ app33.route("/graph-search", graph_search_default);
12815
+ app33.route("/graph-subgraph", graph_subgraph_default);
12816
+ app33.route("/graph-delete", graph_delete_default);
12817
+ app33.route("/graph-restore", graph_restore_default);
12818
+ app33.route("/graph-labels-in-graph", graph_labels_in_graph_default);
12819
+ app33.route("/graph-default-view", graph_default_view_default);
12820
+ app33.route("/sidebar-artefacts", sidebar_artefacts_default);
12821
+ app33.route("/sidebar-sessions", sidebar_sessions_default);
12822
+ app33.route("/session-delete", session_delete_default);
12823
+ app33.route("/session-rc-spawn", session_rc_spawn_default);
12824
+ app33.route("/system-stats", system_stats_default);
12825
+ app33.route("/health-brand", health_default2);
12826
+ app33.route("/linkedin-ingest", linkedin_ingest_default);
12827
+ app33.route("/post-turn-context", post_turn_context_default);
12828
+ app33.route("/public-session-context", public_session_context_default);
12829
+ app33.route("/public-session-exit", public_session_exit_default);
12830
+ app33.route("/access-session-evict", access_session_evict_default);
12831
+ var admin_default = app33;
12522
12832
 
12523
12833
  // app/lib/access-gate.ts
12524
12834
  import neo4j4 from "neo4j-driver";
12525
- import { readFileSync as readFileSync16 } from "fs";
12526
- import { resolve as resolve17 } from "path";
12835
+ import { readFileSync as readFileSync17 } from "fs";
12836
+ import { resolve as resolve19 } from "path";
12527
12837
  import { randomUUID as randomUUID8 } from "crypto";
12528
- var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve17(process.cwd(), "..");
12838
+ var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve19(process.cwd(), "..");
12529
12839
  var driver = null;
12530
12840
  function readPassword() {
12531
12841
  if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
12532
- const passwordFile = resolve17(PLATFORM_ROOT7, "config/.neo4j-password");
12842
+ const passwordFile = resolve19(PLATFORM_ROOT7, "config/.neo4j-password");
12533
12843
  try {
12534
- return readFileSync16(passwordFile, "utf-8").trim();
12844
+ return readFileSync17(passwordFile, "utf-8").trim();
12535
12845
  } catch {
12536
12846
  throw new Error(
12537
12847
  `Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`
@@ -12732,8 +13042,8 @@ async function generateNewMagicToken(grantId) {
12732
13042
  var TAG25 = "[access-verify]";
12733
13043
  var MINT_TAG = "[access-session-mint]";
12734
13044
  var COOKIE_NAME = "__access_session";
12735
- var app32 = new Hono();
12736
- app32.post("/", async (c) => {
13045
+ var app34 = new Hono();
13046
+ app34.post("/", async (c) => {
12737
13047
  const ip = c.var.clientIp || "unknown";
12738
13048
  let body;
12739
13049
  try {
@@ -12815,13 +13125,13 @@ app32.post("/", async (c) => {
12815
13125
  displayName: grant.displayName
12816
13126
  });
12817
13127
  });
12818
- var verify_token_default = app32;
13128
+ var verify_token_default = app34;
12819
13129
 
12820
13130
  // app/lib/access-email.ts
12821
13131
  import { spawn as spawn2 } from "child_process";
12822
- import { resolve as resolve18 } from "path";
12823
- var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT ?? resolve18(process.cwd(), "..");
12824
- var SEND_SCRIPT = resolve18(
13132
+ import { resolve as resolve20 } from "path";
13133
+ var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
13134
+ var SEND_SCRIPT = resolve20(
12825
13135
  PLATFORM_ROOT8,
12826
13136
  "plugins",
12827
13137
  "email",
@@ -12878,9 +13188,9 @@ async function sendMagicLinkEmail(payload) {
12878
13188
 
12879
13189
  // server/routes/access/request-magic-link.ts
12880
13190
  var TAG26 = "[access-request-link]";
12881
- var app33 = new Hono();
13191
+ var app35 = new Hono();
12882
13192
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
12883
- app33.post("/", async (c) => {
13193
+ app35.post("/", async (c) => {
12884
13194
  let body;
12885
13195
  try {
12886
13196
  body = await c.req.json();
@@ -12954,17 +13264,17 @@ app33.post("/", async (c) => {
12954
13264
  );
12955
13265
  return c.json({ message: VISITOR_MESSAGE }, 200);
12956
13266
  });
12957
- var request_magic_link_default = app33;
13267
+ var request_magic_link_default = app35;
12958
13268
 
12959
13269
  // server/routes/access/index.ts
12960
- var app34 = new Hono();
12961
- app34.route("/verify-token", verify_token_default);
12962
- app34.route("/request-magic-link", request_magic_link_default);
12963
- var access_default = app34;
13270
+ var app36 = new Hono();
13271
+ app36.route("/verify-token", verify_token_default);
13272
+ app36.route("/request-magic-link", request_magic_link_default);
13273
+ var access_default = app36;
12964
13274
 
12965
13275
  // server/routes/sites.ts
12966
- import { existsSync as existsSync18, readFileSync as readFileSync17, realpathSync as realpathSync5, statSync as statSync8 } from "fs";
12967
- import { resolve as resolve19 } from "path";
13276
+ import { existsSync as existsSync19, readFileSync as readFileSync18, realpathSync as realpathSync5, statSync as statSync8 } from "fs";
13277
+ import { resolve as resolve21 } from "path";
12968
13278
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
12969
13279
  var MIME = {
12970
13280
  ".html": "text/html; charset=utf-8",
@@ -12995,8 +13305,8 @@ function getExt(p) {
12995
13305
  if (idx < p.lastIndexOf("/")) return "";
12996
13306
  return p.slice(idx).toLowerCase();
12997
13307
  }
12998
- var app35 = new Hono();
12999
- app35.get("/:rel{.*}", (c) => {
13308
+ var app37 = new Hono();
13309
+ app37.get("/:rel{.*}", (c) => {
13000
13310
  const reqPath = c.req.path;
13001
13311
  const rawRel = c.req.param("rel") ?? "";
13002
13312
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -13021,15 +13331,15 @@ app35.get("/:rel{.*}", (c) => {
13021
13331
  }
13022
13332
  segments.push(seg);
13023
13333
  }
13024
- const rootDir = resolve19(account.accountDir, "sites");
13025
- let filePath = segments.length === 0 ? rootDir : resolve19(rootDir, ...segments);
13334
+ const rootDir = resolve21(account.accountDir, "sites");
13335
+ let filePath = segments.length === 0 ? rootDir : resolve21(rootDir, ...segments);
13026
13336
  if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
13027
13337
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
13028
13338
  return c.text("Forbidden", 403);
13029
13339
  }
13030
13340
  let stat7;
13031
13341
  try {
13032
- stat7 = existsSync18(filePath) ? statSync8(filePath) : null;
13342
+ stat7 = existsSync19(filePath) ? statSync8(filePath) : null;
13033
13343
  } catch {
13034
13344
  stat7 = null;
13035
13345
  }
@@ -13042,13 +13352,13 @@ app35.get("/:rel{.*}", (c) => {
13042
13352
  return c.redirect(target, 301);
13043
13353
  }
13044
13354
  if (stat7?.isDirectory()) {
13045
- filePath = resolve19(filePath, "index.html");
13355
+ filePath = resolve21(filePath, "index.html");
13046
13356
  }
13047
13357
  if (!filePath.startsWith(rootDir + "/")) {
13048
13358
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
13049
13359
  return c.text("Forbidden", 403);
13050
13360
  }
13051
- if (!existsSync18(filePath)) {
13361
+ if (!existsSync19(filePath)) {
13052
13362
  console.error(`[sites] not-found path=${reqPath} status=404`);
13053
13363
  return c.text("Not found", 404);
13054
13364
  }
@@ -13067,7 +13377,7 @@ app35.get("/:rel{.*}", (c) => {
13067
13377
  }
13068
13378
  let body;
13069
13379
  try {
13070
- body = readFileSync17(realPath);
13380
+ body = readFileSync18(realPath);
13071
13381
  } catch (err) {
13072
13382
  const code = err?.code;
13073
13383
  if (code === "EISDIR") {
@@ -13099,11 +13409,11 @@ app35.get("/:rel{.*}", (c) => {
13099
13409
  "X-Content-Type-Options": "nosniff"
13100
13410
  });
13101
13411
  });
13102
- var sites_default = app35;
13412
+ var sites_default = app37;
13103
13413
 
13104
13414
  // app/lib/visitor-token.ts
13105
13415
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
13106
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync18, writeFileSync as writeFileSync6 } from "fs";
13416
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync19, writeFileSync as writeFileSync6 } from "fs";
13107
13417
  import { dirname as dirname4 } from "path";
13108
13418
  var TOKEN_PREFIX = "v1.";
13109
13419
  var SECRET_BYTES = 32;
@@ -13112,7 +13422,7 @@ var cachedSecret = null;
13112
13422
  function getSecret() {
13113
13423
  if (cachedSecret) return cachedSecret;
13114
13424
  try {
13115
- const hex2 = readFileSync18(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
13425
+ const hex2 = readFileSync19(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
13116
13426
  if (hex2.length === SECRET_BYTES * 2) {
13117
13427
  cachedSecret = Buffer.from(hex2, "hex");
13118
13428
  return cachedSecret;
@@ -13126,7 +13436,7 @@ function getSecret() {
13126
13436
  console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
13127
13437
  } catch {
13128
13438
  }
13129
- const hex = readFileSync18(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
13439
+ const hex = readFileSync19(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
13130
13440
  cachedSecret = Buffer.from(hex, "hex");
13131
13441
  return cachedSecret;
13132
13442
  }
@@ -13179,8 +13489,8 @@ var VISITOR_COOKIE_NAME = "mxy_v";
13179
13489
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
13180
13490
 
13181
13491
  // app/lib/brand-config.ts
13182
- import { existsSync as existsSync19, readFileSync as readFileSync19 } from "fs";
13183
- import { join as join15 } from "path";
13492
+ import { existsSync as existsSync20, readFileSync as readFileSync20 } from "fs";
13493
+ import { join as join16 } from "path";
13184
13494
  var cached2 = null;
13185
13495
  var cachedAttempted = false;
13186
13496
  function readBrandConfig() {
@@ -13188,10 +13498,10 @@ function readBrandConfig() {
13188
13498
  cachedAttempted = true;
13189
13499
  const platformRoot = process.env.MAXY_PLATFORM_ROOT;
13190
13500
  if (!platformRoot) return null;
13191
- const brandPath = join15(platformRoot, "config", "brand.json");
13192
- if (!existsSync19(brandPath)) return null;
13501
+ const brandPath = join16(platformRoot, "config", "brand.json");
13502
+ if (!existsSync20(brandPath)) return null;
13193
13503
  try {
13194
- cached2 = JSON.parse(readFileSync19(brandPath, "utf-8"));
13504
+ cached2 = JSON.parse(readFileSync20(brandPath, "utf-8"));
13195
13505
  return cached2;
13196
13506
  } catch {
13197
13507
  return null;
@@ -13199,7 +13509,7 @@ function readBrandConfig() {
13199
13509
  }
13200
13510
 
13201
13511
  // server/routes/visitor-consent.ts
13202
- var app36 = new Hono();
13512
+ var app38 = new Hono();
13203
13513
  var CONSENT_COOKIE_NAME = "mxy_consent";
13204
13514
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
13205
13515
  var DEFAULT_CONSENT_COPY = {
@@ -13244,17 +13554,17 @@ function siteSlugFromReferer(referer) {
13244
13554
  return "";
13245
13555
  }
13246
13556
  }
13247
- app36.options("/consent", (c) => {
13557
+ app38.options("/consent", (c) => {
13248
13558
  const origin = getOrigin(c);
13249
13559
  setCorsHeaders(c, origin);
13250
13560
  return c.body(null, 204);
13251
13561
  });
13252
- app36.options("/brand-config", (c) => {
13562
+ app38.options("/brand-config", (c) => {
13253
13563
  const origin = getOrigin(c);
13254
13564
  setCorsHeaders(c, origin);
13255
13565
  return c.body(null, 204);
13256
13566
  });
13257
- app36.post("/consent", async (c) => {
13567
+ app38.post("/consent", async (c) => {
13258
13568
  const origin = getOrigin(c);
13259
13569
  setCorsHeaders(c, origin);
13260
13570
  let raw;
@@ -13294,7 +13604,7 @@ app36.post("/consent", async (c) => {
13294
13604
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
13295
13605
  return c.body(null, 204);
13296
13606
  });
13297
- app36.get("/brand-config", (c) => {
13607
+ app38.get("/brand-config", (c) => {
13298
13608
  const origin = getOrigin(c);
13299
13609
  setCorsHeaders(c, origin);
13300
13610
  const brand = readBrandConfig();
@@ -13304,7 +13614,7 @@ app36.get("/brand-config", (c) => {
13304
13614
  c.header("Cache-Control", "public, max-age=300");
13305
13615
  return c.json({ consent: { copy, palette } });
13306
13616
  });
13307
- var visitor_consent_default = app36;
13617
+ var visitor_consent_default = app38;
13308
13618
 
13309
13619
  // server/routes/listings.ts
13310
13620
  function getCookie(headerValue, name) {
@@ -13331,8 +13641,8 @@ function appendConsentParams(pageUrl, token) {
13331
13641
  }
13332
13642
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
13333
13643
  var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
13334
- var app37 = new Hono();
13335
- app37.get("/:slug/click", async (c) => {
13644
+ var app39 = new Hono();
13645
+ app39.get("/:slug/click", async (c) => {
13336
13646
  const slug = c.req.param("slug") ?? "";
13337
13647
  const rawSession = c.req.query("session") ?? "";
13338
13648
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -13396,10 +13706,10 @@ app37.get("/:slug/click", async (c) => {
13396
13706
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
13397
13707
  return c.redirect(redirectUrl, 302);
13398
13708
  });
13399
- var listings_default = app37;
13709
+ var listings_default = app39;
13400
13710
 
13401
13711
  // server/routes/visitor-event.ts
13402
- var app38 = new Hono();
13712
+ var app40 = new Hono();
13403
13713
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
13404
13714
  var buckets = /* @__PURE__ */ new Map();
13405
13715
  var RATE_LIMIT = 60;
@@ -13466,12 +13776,12 @@ function originAllowed(origin, allowlist) {
13466
13776
  return false;
13467
13777
  }
13468
13778
  }
13469
- app38.options("/event", (c) => {
13779
+ app40.options("/event", (c) => {
13470
13780
  const origin = getOrigin2(c);
13471
13781
  setCorsHeaders2(c, origin);
13472
13782
  return c.body(null, 204);
13473
13783
  });
13474
- app38.post("/event", async (c) => {
13784
+ app40.post("/event", async (c) => {
13475
13785
  const origin = getOrigin2(c);
13476
13786
  setCorsHeaders2(c, origin);
13477
13787
  const ua = c.req.header("user-agent") ?? "";
@@ -13676,7 +13986,7 @@ async function writeEvent(opts) {
13676
13986
  );
13677
13987
  }
13678
13988
  }
13679
- var visitor_event_default = app38;
13989
+ var visitor_event_default = app40;
13680
13990
 
13681
13991
  // app/lib/graph-health.ts
13682
13992
  var HOUR_MS = 60 * 60 * 1e3;
@@ -13761,7 +14071,7 @@ function startGraphHealthTimer() {
13761
14071
 
13762
14072
  // app/lib/file-watcher.ts
13763
14073
  import * as fsp2 from "fs/promises";
13764
- import { resolve as resolve20, sep as sep6 } from "path";
14074
+ import { resolve as resolve22, sep as sep6 } from "path";
13765
14075
  var ACCOUNT_UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
13766
14076
  var DEFAULT_COALESCE_MS = 500;
13767
14077
  var ROOTS = ["uploads", "accounts"];
@@ -13780,7 +14090,7 @@ async function startFileWatcher(opts = {}) {
13780
14090
  const dropFn = opts.drop ?? dropFileIndex;
13781
14091
  for (const r of ROOTS) {
13782
14092
  try {
13783
- await fsp2.mkdir(resolve20(dataRoot, r), { recursive: true });
14093
+ await fsp2.mkdir(resolve22(dataRoot, r), { recursive: true });
13784
14094
  } catch (err) {
13785
14095
  console.error(
13786
14096
  `[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
@@ -13801,7 +14111,7 @@ async function startFileWatcher(opts = {}) {
13801
14111
  timers.set(relativePath, t);
13802
14112
  }
13803
14113
  async function runHook(relativePath, accountId) {
13804
- const absolute = resolve20(dataRoot, relativePath);
14114
+ const absolute = resolve22(dataRoot, relativePath);
13805
14115
  let exists = false;
13806
14116
  try {
13807
14117
  const st = await fsp2.stat(absolute);
@@ -13825,7 +14135,7 @@ async function startFileWatcher(opts = {}) {
13825
14135
  }
13826
14136
  }
13827
14137
  async function watchRoot(rootName) {
13828
- const absRoot = resolve20(dataRoot, rootName);
14138
+ const absRoot = resolve22(dataRoot, rootName);
13829
14139
  try {
13830
14140
  const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
13831
14141
  for await (const event of iter) {
@@ -13923,8 +14233,8 @@ function broadcastAdminShutdown(reason) {
13923
14233
 
13924
14234
  // ../lib/entitlement/src/index.ts
13925
14235
  import { createPublicKey, createHash as createHash4, verify as cryptoVerify } from "crypto";
13926
- import { existsSync as existsSync20, readFileSync as readFileSync20, statSync as statSync9 } from "fs";
13927
- import { resolve as resolve21 } from "path";
14236
+ import { existsSync as existsSync21, readFileSync as readFileSync21, statSync as statSync9 } from "fs";
14237
+ import { resolve as resolve23 } from "path";
13928
14238
 
13929
14239
  // ../lib/entitlement/src/canonicalize.ts
13930
14240
  function canonicalize(value) {
@@ -13959,7 +14269,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
13959
14269
  var GRACE_DAYS = 7;
13960
14270
  var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
13961
14271
  function pubkeyPath(brand) {
13962
- return resolve21(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
14272
+ return resolve23(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
13963
14273
  }
13964
14274
  var memo = null;
13965
14275
  function memoKey(mtimeMs, account) {
@@ -13971,8 +14281,8 @@ function resolveEntitlement(brand, account) {
13971
14281
  if (brand.commercialMode !== true) {
13972
14282
  return logResolved(implicitTrust(account), null);
13973
14283
  }
13974
- const entitlementPath = resolve21(brand.configDir, "entitlement.json");
13975
- if (!existsSync20(entitlementPath)) {
14284
+ const entitlementPath = resolve23(brand.configDir, "entitlement.json");
14285
+ if (!existsSync21(entitlementPath)) {
13976
14286
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
13977
14287
  }
13978
14288
  const stat7 = statSync9(entitlementPath);
@@ -13987,7 +14297,7 @@ function resolveEntitlement(brand, account) {
13987
14297
  function verifyAndResolve(brand, entitlementPath, account) {
13988
14298
  let pubkeyPem;
13989
14299
  try {
13990
- pubkeyPem = readFileSync20(pubkeyPath(brand), "utf-8");
14300
+ pubkeyPem = readFileSync21(pubkeyPath(brand), "utf-8");
13991
14301
  } catch (err) {
13992
14302
  return logResolved(anonymousFallback("pubkey-missing"), {
13993
14303
  reason: "pubkey-missing"
@@ -14001,7 +14311,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
14001
14311
  }
14002
14312
  let envelope;
14003
14313
  try {
14004
- envelope = JSON.parse(readFileSync20(entitlementPath, "utf-8"));
14314
+ envelope = JSON.parse(readFileSync21(entitlementPath, "utf-8"));
14005
14315
  } catch {
14006
14316
  return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
14007
14317
  }
@@ -14162,14 +14472,14 @@ function clientFrom(c) {
14162
14472
  );
14163
14473
  }
14164
14474
  var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT || "";
14165
- var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join16(PLATFORM_ROOT9, "config", "brand.json") : "";
14475
+ var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join17(PLATFORM_ROOT9, "config", "brand.json") : "";
14166
14476
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
14167
- if (BRAND_JSON_PATH && !existsSync21(BRAND_JSON_PATH)) {
14477
+ if (BRAND_JSON_PATH && !existsSync22(BRAND_JSON_PATH)) {
14168
14478
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
14169
14479
  }
14170
- if (BRAND_JSON_PATH && existsSync21(BRAND_JSON_PATH)) {
14480
+ if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
14171
14481
  try {
14172
- const parsed = JSON.parse(readFileSync21(BRAND_JSON_PATH, "utf-8"));
14482
+ const parsed = JSON.parse(readFileSync22(BRAND_JSON_PATH, "utf-8"));
14173
14483
  BRAND = { ...BRAND, ...parsed };
14174
14484
  } catch (err) {
14175
14485
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -14188,11 +14498,11 @@ var brandLoginOpts = {
14188
14498
  bodyFont: BRAND.defaultFonts?.body,
14189
14499
  logoContainsName: !!BRAND.logoContainsName
14190
14500
  };
14191
- var ALIAS_DOMAINS_PATH = join16(homedir2(), BRAND.configDir, "alias-domains.json");
14501
+ var ALIAS_DOMAINS_PATH = join17(homedir2(), BRAND.configDir, "alias-domains.json");
14192
14502
  function loadAliasDomains() {
14193
14503
  try {
14194
- if (!existsSync21(ALIAS_DOMAINS_PATH)) return null;
14195
- const parsed = JSON.parse(readFileSync21(ALIAS_DOMAINS_PATH, "utf-8"));
14504
+ if (!existsSync22(ALIAS_DOMAINS_PATH)) return null;
14505
+ const parsed = JSON.parse(readFileSync22(ALIAS_DOMAINS_PATH, "utf-8"));
14196
14506
  if (!Array.isArray(parsed)) {
14197
14507
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
14198
14508
  return null;
@@ -14216,9 +14526,9 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
14216
14526
  function isPublicHost(host) {
14217
14527
  return host.startsWith("public.") || aliasDomains.has(host);
14218
14528
  }
14219
- var app39 = new Hono();
14220
- app39.use("*", clientIpMiddleware);
14221
- app39.use("*", async (c, next) => {
14529
+ var app41 = new Hono();
14530
+ app41.use("*", clientIpMiddleware);
14531
+ app41.use("*", async (c, next) => {
14222
14532
  await next();
14223
14533
  c.header("X-Content-Type-Options", "nosniff");
14224
14534
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
@@ -14228,7 +14538,7 @@ app39.use("*", async (c, next) => {
14228
14538
  );
14229
14539
  });
14230
14540
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
14231
- app39.use("*", async (c, next) => {
14541
+ app41.use("*", async (c, next) => {
14232
14542
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
14233
14543
  await next();
14234
14544
  return;
@@ -14261,7 +14571,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
14261
14571
  "/sites/"
14262
14572
  ];
14263
14573
  var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
14264
- app39.use("*", async (c, next) => {
14574
+ app41.use("*", async (c, next) => {
14265
14575
  const host = (c.req.header("host") ?? "").split(":")[0];
14266
14576
  if (!isPublicHost(host)) {
14267
14577
  await next();
@@ -14301,7 +14611,7 @@ function resolveRemoteAuthOpts() {
14301
14611
  return brandLoginOpts;
14302
14612
  }
14303
14613
  var MAX_LOGIN_BODY = 8 * 1024;
14304
- app39.post("/__remote-auth/login", async (c) => {
14614
+ app41.post("/__remote-auth/login", async (c) => {
14305
14615
  const client = clientFrom(c);
14306
14616
  const clientIp = client.ip || "unknown";
14307
14617
  if (!requestIsTlsTerminated(c)) {
@@ -14346,7 +14656,7 @@ app39.post("/__remote-auth/login", async (c) => {
14346
14656
  }
14347
14657
  });
14348
14658
  });
14349
- app39.get("/__remote-auth/logout", (c) => {
14659
+ app41.get("/__remote-auth/logout", (c) => {
14350
14660
  const client = clientFrom(c);
14351
14661
  const clientIp = client.ip || "unknown";
14352
14662
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -14359,7 +14669,7 @@ app39.get("/__remote-auth/logout", (c) => {
14359
14669
  }
14360
14670
  });
14361
14671
  });
14362
- app39.post("/__remote-auth/change-password", async (c) => {
14672
+ app41.post("/__remote-auth/change-password", async (c) => {
14363
14673
  const client = clientFrom(c);
14364
14674
  const clientIp = client.ip || "unknown";
14365
14675
  const rateLimited = checkRateLimit(client);
@@ -14410,13 +14720,13 @@ app39.post("/__remote-auth/change-password", async (c) => {
14410
14720
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
14411
14721
  }
14412
14722
  });
14413
- app39.get("/__remote-auth/setup", (c) => {
14723
+ app41.get("/__remote-auth/setup", (c) => {
14414
14724
  if (isRemoteAuthConfigured()) {
14415
14725
  return c.redirect("/");
14416
14726
  }
14417
14727
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
14418
14728
  });
14419
- app39.post("/__remote-auth/set-initial-password", async (c) => {
14729
+ app41.post("/__remote-auth/set-initial-password", async (c) => {
14420
14730
  if (isRemoteAuthConfigured()) {
14421
14731
  return c.redirect("/");
14422
14732
  }
@@ -14454,10 +14764,10 @@ app39.post("/__remote-auth/set-initial-password", async (c) => {
14454
14764
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
14455
14765
  }
14456
14766
  });
14457
- app39.get("/api/remote-auth/status", (c) => {
14767
+ app41.get("/api/remote-auth/status", (c) => {
14458
14768
  return c.json({ configured: isRemoteAuthConfigured() });
14459
14769
  });
14460
- app39.post("/api/remote-auth/set-password", async (c) => {
14770
+ app41.post("/api/remote-auth/set-password", async (c) => {
14461
14771
  let body;
14462
14772
  try {
14463
14773
  body = await c.req.json();
@@ -14488,9 +14798,9 @@ app39.post("/api/remote-auth/set-password", async (c) => {
14488
14798
  return c.json({ error: "Failed to save password" }, 500);
14489
14799
  }
14490
14800
  });
14491
- app39.route("/api/_client-error", client_error_default);
14801
+ app41.route("/api/_client-error", client_error_default);
14492
14802
  console.log("[client-error-route] mounted");
14493
- app39.use("*", async (c, next) => {
14803
+ app41.use("*", async (c, next) => {
14494
14804
  const host = (c.req.header("host") ?? "").split(":")[0];
14495
14805
  const path2 = c.req.path;
14496
14806
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
@@ -14523,12 +14833,12 @@ app39.use("*", async (c, next) => {
14523
14833
  console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
14524
14834
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
14525
14835
  });
14526
- app39.route("/api/health", health_default);
14527
- app39.route("/api/chat", chat_default);
14528
- app39.route("/api/whatsapp", whatsapp_default);
14529
- app39.route("/api/onboarding", onboarding_default);
14530
- app39.route("/api/admin", admin_default);
14531
- app39.route("/api/access", access_default);
14836
+ app41.route("/api/health", health_default);
14837
+ app41.route("/api/chat", chat_default);
14838
+ app41.route("/api/whatsapp", whatsapp_default);
14839
+ app41.route("/api/onboarding", onboarding_default);
14840
+ app41.route("/api/admin", admin_default);
14841
+ app41.route("/api/access", access_default);
14532
14842
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
14533
14843
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
14534
14844
  var IMAGE_MIME = {
@@ -14540,7 +14850,7 @@ var IMAGE_MIME = {
14540
14850
  ".svg": "image/svg+xml",
14541
14851
  ".ico": "image/x-icon"
14542
14852
  };
14543
- app39.get("/agent-assets/:slug/:filename", (c) => {
14853
+ app41.get("/agent-assets/:slug/:filename", (c) => {
14544
14854
  const slug = c.req.param("slug");
14545
14855
  const filename = c.req.param("filename");
14546
14856
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -14556,26 +14866,26 @@ app39.get("/agent-assets/:slug/:filename", (c) => {
14556
14866
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
14557
14867
  return c.text("Not found", 404);
14558
14868
  }
14559
- const filePath = resolve22(account.accountDir, "agents", slug, "assets", filename);
14560
- const expectedDir = resolve22(account.accountDir, "agents", slug, "assets");
14869
+ const filePath = resolve24(account.accountDir, "agents", slug, "assets", filename);
14870
+ const expectedDir = resolve24(account.accountDir, "agents", slug, "assets");
14561
14871
  if (!filePath.startsWith(expectedDir + "/")) {
14562
14872
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
14563
14873
  return c.text("Forbidden", 403);
14564
14874
  }
14565
- if (!existsSync21(filePath)) {
14875
+ if (!existsSync22(filePath)) {
14566
14876
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
14567
14877
  return c.text("Not found", 404);
14568
14878
  }
14569
14879
  const ext = "." + filename.split(".").pop()?.toLowerCase();
14570
14880
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
14571
14881
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
14572
- const body = readFileSync21(filePath);
14882
+ const body = readFileSync22(filePath);
14573
14883
  return c.body(body, 200, {
14574
14884
  "Content-Type": contentType,
14575
14885
  "Cache-Control": "public, max-age=3600"
14576
14886
  });
14577
14887
  });
14578
- app39.get("/generated/:filename", (c) => {
14888
+ app41.get("/generated/:filename", (c) => {
14579
14889
  const filename = c.req.param("filename");
14580
14890
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
14581
14891
  console.error(`[generated] serve file=${filename} status=403`);
@@ -14586,35 +14896,35 @@ app39.get("/generated/:filename", (c) => {
14586
14896
  console.error(`[generated] serve file=${filename} status=404`);
14587
14897
  return c.text("Not found", 404);
14588
14898
  }
14589
- const filePath = resolve22(account.accountDir, "generated", filename);
14590
- const expectedDir = resolve22(account.accountDir, "generated");
14899
+ const filePath = resolve24(account.accountDir, "generated", filename);
14900
+ const expectedDir = resolve24(account.accountDir, "generated");
14591
14901
  if (!filePath.startsWith(expectedDir + "/")) {
14592
14902
  console.error(`[generated] serve file=${filename} status=403`);
14593
14903
  return c.text("Forbidden", 403);
14594
14904
  }
14595
- if (!existsSync21(filePath)) {
14905
+ if (!existsSync22(filePath)) {
14596
14906
  console.error(`[generated] serve file=${filename} status=404`);
14597
14907
  return c.text("Not found", 404);
14598
14908
  }
14599
14909
  const ext = "." + filename.split(".").pop()?.toLowerCase();
14600
14910
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
14601
14911
  console.log(`[generated] serve file=${filename} status=200`);
14602
- const body = readFileSync21(filePath);
14912
+ const body = readFileSync22(filePath);
14603
14913
  return c.body(body, 200, {
14604
14914
  "Content-Type": contentType,
14605
14915
  "Cache-Control": "public, max-age=86400"
14606
14916
  });
14607
14917
  });
14608
- app39.route("/sites", sites_default);
14609
- app39.route("/listings", listings_default);
14610
- app39.route("/v", visitor_event_default);
14611
- app39.route("/v", visitor_consent_default);
14918
+ app41.route("/sites", sites_default);
14919
+ app41.route("/listings", listings_default);
14920
+ app41.route("/v", visitor_event_default);
14921
+ app41.route("/v", visitor_consent_default);
14612
14922
  var htmlCache = /* @__PURE__ */ new Map();
14613
14923
  var brandLogoPath = "/brand/maxy-monochrome.png";
14614
14924
  var brandIconPath = "/brand/maxy-monochrome.png";
14615
- if (BRAND_JSON_PATH && existsSync21(BRAND_JSON_PATH)) {
14925
+ if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
14616
14926
  try {
14617
- const fullBrand = JSON.parse(readFileSync21(BRAND_JSON_PATH, "utf-8"));
14927
+ const fullBrand = JSON.parse(readFileSync22(BRAND_JSON_PATH, "utf-8"));
14618
14928
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
14619
14929
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
14620
14930
  } catch {
@@ -14631,9 +14941,9 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
14631
14941
  function readInstalledVersion() {
14632
14942
  try {
14633
14943
  if (!PLATFORM_ROOT9) return "unknown";
14634
- const versionFile = join16(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
14635
- if (!existsSync21(versionFile)) return "unknown";
14636
- const content = readFileSync21(versionFile, "utf-8").trim();
14944
+ const versionFile = join17(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
14945
+ if (!existsSync22(versionFile)) return "unknown";
14946
+ const content = readFileSync22(versionFile, "utf-8").trim();
14637
14947
  return content || "unknown";
14638
14948
  } catch {
14639
14949
  return "unknown";
@@ -14674,7 +14984,7 @@ var clientErrorReporterScript = `<script>
14674
14984
  function cachedHtml(file) {
14675
14985
  let html = htmlCache.get(file);
14676
14986
  if (!html) {
14677
- html = readFileSync21(resolve22(process.cwd(), "public", file), "utf-8");
14987
+ html = readFileSync22(resolve24(process.cwd(), "public", file), "utf-8");
14678
14988
  const productNameEsc = escapeHtml(BRAND.productName);
14679
14989
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
14680
14990
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -14690,26 +15000,26 @@ ${clientErrorReporterScript}
14690
15000
  }
14691
15001
  var brandedHtmlCache = /* @__PURE__ */ new Map();
14692
15002
  function loadBrandingCache(agentSlug) {
14693
- const configDir2 = join16(homedir2(), BRAND.configDir);
15003
+ const configDir2 = join17(homedir2(), BRAND.configDir);
14694
15004
  try {
14695
- const accountJsonPath = join16(configDir2, "account.json");
14696
- if (!existsSync21(accountJsonPath)) return null;
14697
- const account = JSON.parse(readFileSync21(accountJsonPath, "utf-8"));
15005
+ const accountJsonPath = join17(configDir2, "account.json");
15006
+ if (!existsSync22(accountJsonPath)) return null;
15007
+ const account = JSON.parse(readFileSync22(accountJsonPath, "utf-8"));
14698
15008
  const accountId = account.accountId;
14699
15009
  if (!accountId) return null;
14700
- const cachePath = join16(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
14701
- if (!existsSync21(cachePath)) return null;
14702
- return JSON.parse(readFileSync21(cachePath, "utf-8"));
15010
+ const cachePath = join17(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
15011
+ if (!existsSync22(cachePath)) return null;
15012
+ return JSON.parse(readFileSync22(cachePath, "utf-8"));
14703
15013
  } catch {
14704
15014
  return null;
14705
15015
  }
14706
15016
  }
14707
15017
  function resolveDefaultSlug() {
14708
15018
  try {
14709
- const configDir2 = join16(homedir2(), BRAND.configDir);
14710
- const accountJsonPath = join16(configDir2, "account.json");
14711
- if (!existsSync21(accountJsonPath)) return null;
14712
- const account = JSON.parse(readFileSync21(accountJsonPath, "utf-8"));
15019
+ const configDir2 = join17(homedir2(), BRAND.configDir);
15020
+ const accountJsonPath = join17(configDir2, "account.json");
15021
+ if (!existsSync22(accountJsonPath)) return null;
15022
+ const account = JSON.parse(readFileSync22(accountJsonPath, "utf-8"));
14713
15023
  return account.defaultAgent || null;
14714
15024
  } catch {
14715
15025
  return null;
@@ -14745,7 +15055,7 @@ function brandedPublicHtml(agentSlug) {
14745
15055
  function escapeHtml(s) {
14746
15056
  return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
14747
15057
  }
14748
- app39.get("/", (c) => {
15058
+ app41.get("/", (c) => {
14749
15059
  const host = (c.req.header("host") ?? "").split(":")[0];
14750
15060
  if (isPublicHost(host)) {
14751
15061
  const defaultSlug = resolveDefaultSlug();
@@ -14753,12 +15063,12 @@ app39.get("/", (c) => {
14753
15063
  }
14754
15064
  return c.html(cachedHtml("index.html"));
14755
15065
  });
14756
- app39.get("/public", (c) => {
15066
+ app41.get("/public", (c) => {
14757
15067
  const host = (c.req.header("host") ?? "").split(":")[0];
14758
15068
  if (isPublicHost(host)) return c.text("Not found", 404);
14759
15069
  return c.html(cachedHtml("public.html"));
14760
15070
  });
14761
- app39.get("/chat", (c) => {
15071
+ app41.get("/chat", (c) => {
14762
15072
  const host = (c.req.header("host") ?? "").split(":")[0];
14763
15073
  if (isPublicHost(host)) return c.text("Not found", 404);
14764
15074
  return c.html(cachedHtml("public.html"));
@@ -14777,12 +15087,12 @@ async function logViewerFetch(c, next) {
14777
15087
  duration_ms: Date.now() - start
14778
15088
  });
14779
15089
  }
14780
- app39.use("/vnc-viewer.html", logViewerFetch);
14781
- app39.use("/vnc-popout.html", logViewerFetch);
14782
- app39.get("/vnc-popout.html", (c) => {
15090
+ app41.use("/vnc-viewer.html", logViewerFetch);
15091
+ app41.use("/vnc-popout.html", logViewerFetch);
15092
+ app41.get("/vnc-popout.html", (c) => {
14783
15093
  let html = htmlCache.get("vnc-popout.html");
14784
15094
  if (!html) {
14785
- html = readFileSync21(resolve22(process.cwd(), "public", "vnc-popout.html"), "utf-8");
15095
+ html = readFileSync22(resolve24(process.cwd(), "public", "vnc-popout.html"), "utf-8");
14786
15096
  const name = escapeHtml(BRAND.productName);
14787
15097
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
14788
15098
  html = html.replace("</head>", ` ${brandScript}
@@ -14792,7 +15102,7 @@ app39.get("/vnc-popout.html", (c) => {
14792
15102
  }
14793
15103
  return c.html(html);
14794
15104
  });
14795
- app39.post("/api/vnc/client-event", async (c) => {
15105
+ app41.post("/api/vnc/client-event", async (c) => {
14796
15106
  let body;
14797
15107
  try {
14798
15108
  body = await c.req.json();
@@ -14813,25 +15123,25 @@ app39.post("/api/vnc/client-event", async (c) => {
14813
15123
  });
14814
15124
  return c.json({ ok: true });
14815
15125
  });
14816
- app39.get("/g/:slug", (c) => {
15126
+ app41.get("/g/:slug", (c) => {
14817
15127
  return c.html(brandedPublicHtml());
14818
15128
  });
14819
- app39.get("/graph", (c) => {
15129
+ app41.get("/graph", (c) => {
14820
15130
  const host = (c.req.header("host") ?? "").split(":")[0];
14821
15131
  if (isPublicHost(host)) return c.text("Not found", 404);
14822
15132
  return c.html(cachedHtml("graph.html"));
14823
15133
  });
14824
- app39.get("/sessions", (c) => {
15134
+ app41.get("/sessions", (c) => {
14825
15135
  const host = (c.req.header("host") ?? "").split(":")[0];
14826
15136
  if (isPublicHost(host)) return c.text("Not found", 404);
14827
15137
  return c.html(cachedHtml("sessions.html"));
14828
15138
  });
14829
- app39.get("/data", (c) => {
15139
+ app41.get("/data", (c) => {
14830
15140
  const host = (c.req.header("host") ?? "").split(":")[0];
14831
15141
  if (isPublicHost(host)) return c.text("Not found", 404);
14832
15142
  return c.html(cachedHtml("data.html"));
14833
15143
  });
14834
- app39.get("/:slug", async (c, next) => {
15144
+ app41.get("/:slug", async (c, next) => {
14835
15145
  const slug = c.req.param("slug");
14836
15146
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
14837
15147
  const branding = loadBrandingCache(slug);
@@ -14841,15 +15151,15 @@ app39.get("/:slug", async (c, next) => {
14841
15151
  await next();
14842
15152
  });
14843
15153
  if (brandFaviconPath !== "/favicon.ico") {
14844
- app39.get("/favicon.ico", (c) => {
15154
+ app41.get("/favicon.ico", (c) => {
14845
15155
  c.header("Cache-Control", "public, max-age=300");
14846
15156
  return c.redirect(brandFaviconPath, 302);
14847
15157
  });
14848
15158
  }
14849
- app39.use("/*", serveStatic({ root: "./public" }));
15159
+ app41.use("/*", serveStatic({ root: "./public" }));
14850
15160
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
14851
15161
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
14852
- var httpServer = serve({ fetch: app39.fetch, port, hostname });
15162
+ var httpServer = serve({ fetch: app41.fetch, port, hostname });
14853
15163
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
14854
15164
  {
14855
15165
  const loopHist = monitorEventLoopDelay({ resolution: 50 });
@@ -14885,7 +15195,7 @@ for (const m of SUBAPP_MANIFEST) {
14885
15195
  }
14886
15196
  try {
14887
15197
  const registered = [];
14888
- for (const r of app39.routes ?? []) {
15198
+ for (const r of app41.routes ?? []) {
14889
15199
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
14890
15200
  if (AGENT_SLUG_PATTERN.test(r.path)) {
14891
15201
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -14907,8 +15217,8 @@ try {
14907
15217
  }
14908
15218
  (async () => {
14909
15219
  try {
14910
- if (!existsSync21(USERS_FILE)) return;
14911
- const usersRaw = readFileSync21(USERS_FILE, "utf-8").trim();
15220
+ if (!existsSync22(USERS_FILE)) return;
15221
+ const usersRaw = readFileSync22(USERS_FILE, "utf-8").trim();
14912
15222
  if (!usersRaw) return;
14913
15223
  const users = JSON.parse(usersRaw);
14914
15224
  const userId = users[0]?.userId;
@@ -15003,7 +15313,7 @@ if (bootAccountConfig?.whatsapp) {
15003
15313
  }
15004
15314
  init({
15005
15315
  configDir: configDirForWhatsApp,
15006
- platformRoot: resolve22(process.env.MAXY_PLATFORM_ROOT ?? join16(__dirname, "..")),
15316
+ platformRoot: resolve24(process.env.MAXY_PLATFORM_ROOT ?? join17(__dirname, "..")),
15007
15317
  accountConfig: bootAccountConfig,
15008
15318
  onMessage: async (msg) => {
15009
15319
  if (process.env.WHATSAPP_PTY_BRIDGE_ENABLED === "true" && msg.text && !msg.isOwnerMirror) {