@rubytech/create-realagent-code 0.1.196 → 0.1.200

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 (99) hide show
  1. package/package.json +2 -2
  2. package/payload/platform/config/brand.json +3 -1
  3. package/payload/platform/plugins/admin/PLUGIN.md +3 -0
  4. package/payload/platform/plugins/admin/skills/investigate/SKILL.md +286 -0
  5. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +3736 -0
  6. package/payload/platform/plugins/admin/skills/superpowers-sprint/SKILL.md +361 -0
  7. package/payload/platform/plugins/admin/skills/task/SKILL.md +283 -0
  8. package/payload/platform/plugins/docs/references/admin-ui.md +4 -1
  9. package/payload/platform/plugins/docs/references/internals.md +0 -2
  10. package/payload/platform/plugins/docs/references/investigate-and-task-skills.md +9 -0
  11. package/payload/platform/plugins/docs/references/platform.md +1 -1
  12. package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
  13. package/payload/platform/scripts/check-architecture-skill-no-drift.mjs +67 -0
  14. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  15. package/payload/platform/services/claude-session-manager/dist/http-server.js +56 -0
  16. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  17. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +18 -0
  18. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
  19. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +25 -15
  20. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
  21. package/payload/platform/templates/agents/admin/IDENTITY.md +4 -0
  22. package/payload/platform/templates/agents/public/IDENTITY.md +1 -1
  23. package/payload/premium-plugins/real-agent/BUNDLE.md +1 -1
  24. package/payload/premium-plugins/real-agent/agents/compliance.md +1 -1
  25. package/payload/premium-plugins/real-agent/agents/listing-curator.md +3 -3
  26. package/payload/premium-plugins/real-agent/agents/negotiator.md +1 -1
  27. package/payload/premium-plugins/real-agent/agents/valuer.md +1 -1
  28. package/payload/server/public/assets/AdminShell-OJlDJakR.js +1 -0
  29. package/payload/server/public/assets/{Checkbox-DTxJvyG7.js → Checkbox-DE_tsDq_.js} +1 -1
  30. package/payload/server/public/assets/{admin-tKgLki8m.js → admin-DbQw1TyC.js} +1 -1
  31. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-CrQJbK3h.js → architectureDiagram-Q4EWVU46-DfZVWJVr.js} +1 -1
  32. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-BLCbhL8K.js → blockDiagram-DXYQGD6D-Cd9vcTYg.js} +1 -1
  33. package/payload/server/public/assets/{brand-lZz3OVIE.css → brand-Ed5R2W5J.css} +1 -1
  34. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-X34EilDe.js → c4Diagram-AHTNJAMY-zmNCfJ5F.js} +1 -1
  35. package/payload/server/public/assets/channel-DCJza6li.js +1 -0
  36. package/payload/server/public/assets/{chunk-336JU56O-CeRuGBQ2.js → chunk-336JU56O-DvHeoV7B.js} +2 -2
  37. package/payload/server/public/assets/{chunk-426QAEUC-CUZOrcMu.js → chunk-426QAEUC-IZknbXMM.js} +1 -1
  38. package/payload/server/public/assets/{chunk-4TB4RGXK-CdrIHRcy.js → chunk-4TB4RGXK-DN_qw6Oi.js} +1 -1
  39. package/payload/server/public/assets/{chunk-5FUZZQ4R-CenIbTIp.js → chunk-5FUZZQ4R-tt-46Rcq.js} +1 -1
  40. package/payload/server/public/assets/{chunk-5PVQY5BW-DGfzIUel.js → chunk-5PVQY5BW-Bl0mxmQP.js} +1 -1
  41. package/payload/server/public/assets/{chunk-EDXVE4YY-DSft5oIH.js → chunk-EDXVE4YY-v31HwKDb.js} +1 -1
  42. package/payload/server/public/assets/{chunk-ENJZ2VHE-Dn8FFfaI.js → chunk-ENJZ2VHE-D6T1RStj.js} +1 -1
  43. package/payload/server/public/assets/{chunk-ICPOFSXX-JrwcKV7r.js → chunk-ICPOFSXX-DVnIs_5A.js} +1 -1
  44. package/payload/server/public/assets/{chunk-OYMX7WX6-C0X2fcAm.js → chunk-OYMX7WX6-DiZNprr1.js} +1 -1
  45. package/payload/server/public/assets/{chunk-U2HBQHQK-DPdLe-f5.js → chunk-U2HBQHQK-Cy0qH3H0.js} +1 -1
  46. package/payload/server/public/assets/{chunk-X2U36JSP-Bw8pKkFu.js → chunk-X2U36JSP-wR3wBPyu.js} +1 -1
  47. package/payload/server/public/assets/{chunk-YZCP3GAM-DcAJR-EA.js → chunk-YZCP3GAM-BGOVJLky.js} +1 -1
  48. package/payload/server/public/assets/{chunk-ZZ45TVLE-DU374ZbR.js → chunk-ZZ45TVLE-14vtIjRh.js} +1 -1
  49. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DEo4goqG.js +1 -0
  50. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CoAVCeH7.js +1 -0
  51. package/payload/server/public/assets/clone-CLnBlH9n.js +1 -0
  52. package/payload/server/public/assets/{dagre-DisbqNSB.js → dagre-CG1l6rfK.js} +1 -1
  53. package/payload/server/public/assets/{dagre-KV5264BT-D_n7R7V9.js → dagre-KV5264BT-DKFDl1Nz.js} +1 -1
  54. package/payload/server/public/assets/data-b1v7Pjly.js +1 -0
  55. package/payload/server/public/assets/{diagram-5BDNPKRD-CJID_5OR.js → diagram-5BDNPKRD-PJd29fkg.js} +1 -1
  56. package/payload/server/public/assets/{diagram-G4DWMVQ6-ByepjvdE.js → diagram-G4DWMVQ6-Bz7_SWJH.js} +1 -1
  57. package/payload/server/public/assets/{diagram-MMDJMWI5-DTkAHPHE.js → diagram-MMDJMWI5-CmWknm9v.js} +1 -1
  58. package/payload/server/public/assets/{diagram-TYMM5635-CnVRa9NJ.js → diagram-TYMM5635-CLYRluM2.js} +1 -1
  59. package/payload/server/public/assets/{erDiagram-SMLLAGMA-CRAGu7nV.js → erDiagram-SMLLAGMA-EWVKGrgT.js} +1 -1
  60. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-BJusdlRz.js → flowDiagram-DWJPFMVM-CNtfJIG7.js} +1 -1
  61. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BFMOBBnF.js → ganttDiagram-T4ZO3ILL-SIlymJ6A.js} +1 -1
  62. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CGWEzh7u.js → gitGraphDiagram-UUTBAWPF-DWVl6CUl.js} +1 -1
  63. package/payload/server/public/assets/{graph-D-iQdRDk.js → graph-BOcblKu9.js} +2 -2
  64. package/payload/server/public/assets/{graph-labels-u2_3Eyfh.js → graph-labels-CH-Tffon.js} +1 -1
  65. package/payload/server/public/assets/{graphlib-DNUvypOi.js → graphlib-i-qJjJM7.js} +1 -1
  66. package/payload/server/public/assets/{infoDiagram-42DDH7IO-CBDrnRTc.js → infoDiagram-42DDH7IO-D66Yr_7b.js} +1 -1
  67. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-C7NwSQo_.js → ishikawaDiagram-UXIWVN3A-C4mQi7AB.js} +1 -1
  68. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-DSaP7A3F.js → journeyDiagram-VCZTEJTY-7Vp2UBlF.js} +1 -1
  69. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-DmixHCD4.js → kanban-definition-6JOO6SKY-nEDANSe9.js} +1 -1
  70. package/payload/server/public/assets/{line-CGGoTheL.js → line-BxGbTwly.js} +1 -1
  71. package/payload/server/public/assets/{mermaid-parser.core-BudFADW7.js → mermaid-parser.core-CAG4AdDd.js} +1 -1
  72. package/payload/server/public/assets/{mermaid.core-BBbdJxXY.js → mermaid.core-prtUaAsI.js} +3 -3
  73. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CUiD9km1.js → mindmap-definition-QFDTVHPH-Dvcph8zi.js} +1 -1
  74. package/payload/server/public/assets/{pieDiagram-DEJITSTG-BlAWpMr8.js → pieDiagram-DEJITSTG-C4qHs6Vb.js} +1 -1
  75. package/payload/server/public/assets/{public-CjeEF2vf.js → public-DIyn-De4.js} +3 -3
  76. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CXmIwc4W.js → quadrantDiagram-34T5L4WZ-I9Et2l2H.js} +1 -1
  77. package/payload/server/public/assets/{requirementDiagram-MS252O5E-D_7_OeMC.js → requirementDiagram-MS252O5E-DLKlY81v.js} +1 -1
  78. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-BKm_PqzT.js → sankeyDiagram-XADWPNL6-dX3pgMv_.js} +1 -1
  79. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-CBSR0Zst.js → sequenceDiagram-FGHM5R23-C4qTAl3F.js} +1 -1
  80. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-CHNpT69M.js → stateDiagram-FHFEXIEX-DzA0NObk.js} +1 -1
  81. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Dsgd5hEe.js +1 -0
  82. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-CxZoew5-.js → timeline-definition-GMOUNBTQ-D-DPUQCU.js} +1 -1
  83. package/payload/server/public/assets/{useSelectionMode-CwxXQzEI.js → useSelectionMode-C4HDuwDT.js} +1 -1
  84. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-CKJdFDcG.js → vennDiagram-DHZGUBPP-C_RwTsUi.js} +1 -1
  85. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-C-XBcm-g.js → wardleyDiagram-NUSXRM2D-BAftlsC2.js} +1 -1
  86. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-Crb-ZtaP.js → xychartDiagram-5P7HB3ND-C_tKMCMd.js} +1 -1
  87. package/payload/server/public/data.html +5 -5
  88. package/payload/server/public/graph.html +6 -6
  89. package/payload/server/public/index.html +6 -6
  90. package/payload/server/public/public.html +5 -5
  91. package/payload/server/server.js +404 -325
  92. package/payload/server/public/assets/AdminShell-DtABh34v.js +0 -1
  93. package/payload/server/public/assets/channel-ChZECiuj.js +0 -1
  94. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BpMBCYn6.js +0 -1
  95. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BU3HoIr1.js +0 -1
  96. package/payload/server/public/assets/clone-C3j5j6ku.js +0 -1
  97. package/payload/server/public/assets/data-DwY26t_T.js +0 -1
  98. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Kc8XO6yH.js +0 -1
  99. /package/payload/server/public/assets/{brand-CpGp9OyK.js → brand-CCOPpjM4.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 resolve23, join as join16, basename as basename6 } from "path";
819
+ import { readFileSync as readFileSync22, existsSync as existsSync22, watchFile } from "fs";
820
+ import { resolve as resolve23, 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
 
@@ -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") {
@@ -7966,13 +7966,13 @@ ${fm}
7966
7966
  }
7967
7967
  const skillPaths = parseSkillPathsFromFrontmatter(fm);
7968
7968
  const skills = [];
7969
- for (const relPath2 of skillPaths) {
7970
- const skillPath = join10(dir, relPath2);
7969
+ for (const relPath of skillPaths) {
7970
+ const skillPath = join10(dir, relPath);
7971
7971
  const skillFm = readFrontmatter(skillPath);
7972
7972
  if (!skillFm) continue;
7973
7973
  const skillName = frontmatterField(`---
7974
7974
  ${skillFm}
7975
- ---`, "name") ?? relPath2;
7975
+ ---`, "name") ?? relPath;
7976
7976
  const skillDesc = frontmatterField(`---
7977
7977
  ${skillFm}
7978
7978
  ---`, "description");
@@ -8391,8 +8391,8 @@ var DATA_ROOT = resolve12(PLATFORM_ROOT5, "..", "data");
8391
8391
  var CLAUDE_UPLOADS_ROOT = process.env.CLAUDE_CONFIG_DIR ? resolve12(process.env.CLAUDE_CONFIG_DIR, "uploads") : null;
8392
8392
  var ACCOUNT_PARTITION_DIRS = /* @__PURE__ */ new Set(["uploads", "accounts"]);
8393
8393
  var ACCOUNT_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
8394
- function crossesForeignAccountPartition(relPath2, accountId) {
8395
- const segs = relPath2.split("/").filter(Boolean);
8394
+ function crossesForeignAccountPartition(relPath, accountId) {
8395
+ const segs = relPath.split("/").filter(Boolean);
8396
8396
  if (segs.length < 2) return false;
8397
8397
  if (!ACCOUNT_PARTITION_DIRS.has(segs[0])) return false;
8398
8398
  const owner = segs[1];
@@ -8432,8 +8432,8 @@ function resolveUnderRoot(raw, rootAbs, rootLabel) {
8432
8432
  if (resolvedReal !== rootReal && !resolvedReal.startsWith(rootReal + sep2)) {
8433
8433
  return { ok: false, status: 403, error: `Path escapes ${rootLabel}`, resolved: resolvedReal };
8434
8434
  }
8435
- const relPath2 = relative(rootReal, resolvedReal) || ".";
8436
- return { ok: true, absolute: resolvedReal, dataRootReal: rootReal, relative: relPath2 };
8435
+ const relPath = relative(rootReal, resolvedReal) || ".";
8436
+ return { ok: true, absolute: resolvedReal, dataRootReal: rootReal, relative: relPath };
8437
8437
  }
8438
8438
  function resolveDataPath(raw) {
8439
8439
  return resolveUnderRoot(raw, DATA_ROOT, "DATA_ROOT");
@@ -8680,8 +8680,8 @@ async function restoreNode(params) {
8680
8680
 
8681
8681
  // app/lib/file-delete-cascade.ts
8682
8682
  var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
8683
- function parseAttachmentPath(relPath2) {
8684
- const segments = relPath2.split("/").filter(Boolean);
8683
+ function parseAttachmentPath(relPath) {
8684
+ const segments = relPath.split("/").filter(Boolean);
8685
8685
  if (segments.length !== 4) return null;
8686
8686
  if (segments[0] !== "uploads") return null;
8687
8687
  const accountId = segments[1];
@@ -9246,9 +9246,9 @@ async function enrich(absolute, entry, accountNames) {
9246
9246
  }
9247
9247
  }
9248
9248
  }
9249
- function buildDisplayPath(relPath2, accountNames) {
9250
- if (relPath2 === "." || relPath2 === "") return [];
9251
- return relPath2.split("/").filter(Boolean).map((seg) => {
9249
+ function buildDisplayPath(relPath, accountNames) {
9250
+ if (relPath === "." || relPath === "") return [];
9251
+ return relPath.split("/").filter(Boolean).map((seg) => {
9252
9252
  const dn = UUID_RE3.test(seg) ? accountNames.get(seg) : void 0;
9253
9253
  return dn ? { name: seg, displayName: dn } : { name: seg };
9254
9254
  });
@@ -9286,9 +9286,9 @@ app15.get("/", requireAdminSession, async (c) => {
9286
9286
  }
9287
9287
  return c.json({ error: resolution.error }, resolution.status);
9288
9288
  }
9289
- const { absolute, relative: relPath2 } = resolution;
9290
- if (crossesForeignAccountPartition(relPath2, accountId)) {
9291
- console.error(`[data] account-scope-blocked endpoint="/api/admin/files" path="${relPath2}" account=${accountId.slice(0, 8)}\u2026`);
9289
+ const { absolute, relative: relPath } = resolution;
9290
+ if (crossesForeignAccountPartition(relPath, accountId)) {
9291
+ console.error(`[data] account-scope-blocked endpoint="/api/admin/files" path="${relPath}" account=${accountId.slice(0, 8)}\u2026`);
9292
9292
  return c.json({ error: "Not found" }, 404);
9293
9293
  }
9294
9294
  try {
@@ -9297,7 +9297,7 @@ app15.get("/", requireAdminSession, async (c) => {
9297
9297
  return c.json({ error: "Path is not a directory \u2014 use /api/admin/files/download for files" }, 400);
9298
9298
  }
9299
9299
  const names = await readdir3(absolute);
9300
- const segs = relPath2.split("/").filter(Boolean);
9300
+ const segs = relPath.split("/").filter(Boolean);
9301
9301
  const isAccountParent = segs.length === 1 && (segs[0] === "accounts" || segs[0] === "uploads");
9302
9302
  const entries = [];
9303
9303
  for (const name of names) {
@@ -9328,17 +9328,17 @@ app15.get("/", requireAdminSession, async (c) => {
9328
9328
  const bKey = b.displayName ?? b.name;
9329
9329
  return aKey.localeCompare(bKey);
9330
9330
  });
9331
- const displayPath = buildDisplayPath(relPath2, accountNames);
9332
- console.error(`[data] file-list path="${relPath2}" entries=${entries.length}`);
9333
- return c.json({ path: relPath2, displayPath, entries });
9331
+ const displayPath = buildDisplayPath(relPath, accountNames);
9332
+ console.error(`[data] file-list path="${relPath}" entries=${entries.length}`);
9333
+ return c.json({ path: relPath, displayPath, entries });
9334
9334
  } catch (err) {
9335
9335
  const code = err.code;
9336
9336
  if (code === "ENOENT") {
9337
- console.error(`[data] file-list not-found path="${relPath2}"`);
9337
+ console.error(`[data] file-list not-found path="${relPath}"`);
9338
9338
  return c.json({ error: "Not found" }, 404);
9339
9339
  }
9340
9340
  const message = err instanceof Error ? err.message : String(err);
9341
- console.error(`[data] file-list error path="${relPath2}" err="${message}"`);
9341
+ console.error(`[data] file-list error path="${relPath}" err="${message}"`);
9342
9342
  return c.json({ error: message }, 500);
9343
9343
  }
9344
9344
  });
@@ -9362,16 +9362,16 @@ app15.get("/download", requireAdminSession, async (c) => {
9362
9362
  }
9363
9363
  return c.json({ error: resolution.error }, resolution.status);
9364
9364
  }
9365
- const { absolute, relative: relPath2 } = resolution;
9365
+ const { absolute, relative: relPath } = resolution;
9366
9366
  if (root === "claude-uploads") {
9367
- const attachmentId = relPath2.split("/").filter(Boolean)[0] ?? "";
9367
+ const attachmentId = relPath.split("/").filter(Boolean)[0] ?? "";
9368
9368
  const owned = await knowledgeDocOwnedByAccount(accountId, attachmentId);
9369
9369
  if (!owned) {
9370
9370
  console.error(`[data] account-scope-blocked root="claude-uploads" attachmentId="${attachmentId.slice(0, 8)}\u2026" account=${accountId.slice(0, 8)}\u2026`);
9371
9371
  return c.json({ error: "Not found" }, 404);
9372
9372
  }
9373
- } else if (crossesForeignAccountPartition(relPath2, accountId)) {
9374
- console.error(`[data] account-scope-blocked endpoint="/api/admin/files/download" path="${relPath2}" account=${accountId.slice(0, 8)}\u2026`);
9373
+ } else if (crossesForeignAccountPartition(relPath, accountId)) {
9374
+ console.error(`[data] account-scope-blocked endpoint="/api/admin/files/download" path="${relPath}" account=${accountId.slice(0, 8)}\u2026`);
9375
9375
  return c.json({ error: "Not found" }, 404);
9376
9376
  }
9377
9377
  try {
@@ -9383,7 +9383,7 @@ app15.get("/download", requireAdminSession, async (c) => {
9383
9383
  const mimeType = detectMimeType(absolute);
9384
9384
  const nodeStream = createReadStream2(absolute);
9385
9385
  const webStream = Readable2.toWeb(nodeStream);
9386
- console.error(`[data] file-download root="${root}" path="${relPath2}" size=${info.size}`);
9386
+ console.error(`[data] file-download root="${root}" path="${relPath}" size=${info.size}`);
9387
9387
  const safeQuotedName = filename.replace(/[\r\n"\\]/g, "_");
9388
9388
  const encodedName = encodeURIComponent(filename);
9389
9389
  return new Response(webStream, {
@@ -9398,11 +9398,11 @@ app15.get("/download", requireAdminSession, async (c) => {
9398
9398
  } catch (err) {
9399
9399
  const code = err.code;
9400
9400
  if (code === "ENOENT") {
9401
- console.error(`[data] file-download not-found path="${relPath2}"`);
9401
+ console.error(`[data] file-download not-found path="${relPath}"`);
9402
9402
  return c.json({ error: "Not found" }, 404);
9403
9403
  }
9404
9404
  const message = err instanceof Error ? err.message : String(err);
9405
- console.error(`[data] file-download error path="${relPath2}" err="${message}"`);
9405
+ console.error(`[data] file-download error path="${relPath}" err="${message}"`);
9406
9406
  return c.json({ error: message }, 500);
9407
9407
  }
9408
9408
  });
@@ -9483,15 +9483,15 @@ app15.delete("/", requireAdminSession, async (c) => {
9483
9483
  }
9484
9484
  return c.json({ error: resolution.error }, resolution.status);
9485
9485
  }
9486
- const { absolute, relative: relPath2 } = resolution;
9487
- if (crossesForeignAccountPartition(relPath2, accountId)) {
9488
- console.error(`[data] account-scope-blocked endpoint="DELETE /api/admin/files" path="${relPath2}" account=${accountId.slice(0, 8)}\u2026`);
9486
+ const { absolute, relative: relPath } = resolution;
9487
+ if (crossesForeignAccountPartition(relPath, accountId)) {
9488
+ console.error(`[data] account-scope-blocked endpoint="DELETE /api/admin/files" path="${relPath}" account=${accountId.slice(0, 8)}\u2026`);
9489
9489
  return c.json({ error: "Not found" }, 404);
9490
9490
  }
9491
9491
  const base = basename4(absolute);
9492
- const segments = relPath2.split("/").filter(Boolean);
9492
+ const segments = relPath.split("/").filter(Boolean);
9493
9493
  if (base === "account.json" || segments.includes(".git")) {
9494
- console.error(`[data] file-delete blocked path="${relPath2}" reason="protected"`);
9494
+ console.error(`[data] file-delete blocked path="${relPath}" reason="protected"`);
9495
9495
  return c.json({ error: "Protected file \u2014 refusing to delete" }, 403);
9496
9496
  }
9497
9497
  try {
@@ -9512,34 +9512,34 @@ app15.delete("/", requireAdminSession, async (c) => {
9512
9512
  } catch {
9513
9513
  }
9514
9514
  }
9515
- console.error(`[data] file-delete path="${relPath2}" bytes=${info.size}`);
9515
+ console.error(`[data] file-delete path="${relPath}" bytes=${info.size}`);
9516
9516
  try {
9517
- await dropFileIndex(accountId, relPath2);
9517
+ await dropFileIndex(accountId, relPath);
9518
9518
  } catch (err) {
9519
- console.error(`[data] file-delete index-drop-failed path="${relPath2}" err="${err instanceof Error ? err.message : String(err)}"`);
9519
+ console.error(`[data] file-delete index-drop-failed path="${relPath}" err="${err instanceof Error ? err.message : String(err)}"`);
9520
9520
  }
9521
- const parsed = parseAttachmentPath(relPath2);
9521
+ const parsed = parseAttachmentPath(relPath);
9522
9522
  if (parsed) {
9523
9523
  try {
9524
9524
  const { nodes } = await cascadeDeleteDocument({
9525
9525
  accountId,
9526
9526
  attachmentId: parsed.attachmentId
9527
9527
  });
9528
- console.error(`[data] file-delete graph-cascade path="${relPath2}" nodes=${nodes}`);
9528
+ console.error(`[data] file-delete graph-cascade path="${relPath}" nodes=${nodes}`);
9529
9529
  } catch (err) {
9530
9530
  const message = err instanceof Error ? err.message : String(err);
9531
- console.error(`[data] file-delete graph-cascade-failed path="${relPath2}" err="${message}"`);
9531
+ console.error(`[data] file-delete graph-cascade-failed path="${relPath}" err="${message}"`);
9532
9532
  }
9533
9533
  }
9534
9534
  return c.json({ ok: true });
9535
9535
  } catch (err) {
9536
9536
  const code = err.code;
9537
9537
  if (code === "ENOENT") {
9538
- console.error(`[data] file-delete not-found path="${relPath2}"`);
9538
+ console.error(`[data] file-delete not-found path="${relPath}"`);
9539
9539
  return c.json({ error: "Not found" }, 404);
9540
9540
  }
9541
9541
  const message = err instanceof Error ? err.message : String(err);
9542
- console.error(`[data] file-delete error path="${relPath2}" err="${message}"`);
9542
+ console.error(`[data] file-delete error path="${relPath}" err="${message}"`);
9543
9543
  return c.json({ error: message }, 500);
9544
9544
  }
9545
9545
  });
@@ -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(",");
@@ -11601,7 +11601,6 @@ async function fetchOutputArtefacts(accountId) {
11601
11601
  name: displayName ?? basename5(relativePath),
11602
11602
  kind: "output-file",
11603
11603
  updatedAt: modifiedAt,
11604
- editable: false,
11605
11604
  mimeType,
11606
11605
  downloadPath: relativePath,
11607
11606
  downloadRoot: "data"
@@ -11628,8 +11627,7 @@ async function fetchAgentTemplateRows(accountDir) {
11628
11627
  overridePath,
11629
11628
  overrideRoot: accountDir,
11630
11629
  bundledPath,
11631
- bundledRoot: PLATFORM_ROOT,
11632
- editable: true
11630
+ bundledRoot: PLATFORM_ROOT
11633
11631
  });
11634
11632
  if (row) rows.push(row);
11635
11633
  }
@@ -11646,8 +11644,7 @@ async function fetchAgentTemplateRows(accountDir) {
11646
11644
  overridePath,
11647
11645
  overrideRoot: accountDir,
11648
11646
  bundledPath,
11649
- bundledRoot: PLATFORM_ROOT,
11650
- editable: false
11647
+ bundledRoot: PLATFORM_ROOT
11651
11648
  });
11652
11649
  if (row) rows.push(row);
11653
11650
  }
@@ -11700,7 +11697,6 @@ async function readAgentTemplateRow(inp) {
11700
11697
  name: inp.displayName,
11701
11698
  kind: "agent-template",
11702
11699
  updatedAt: st.mtime.toISOString(),
11703
- editable: inp.editable,
11704
11700
  mimeType: "text/markdown",
11705
11701
  // Override paths live under <accountDir> (inside DATA_ROOT) and are
11706
11702
  // downloadable; bundled-fallback templates live under PLATFORM_ROOT
@@ -11724,83 +11720,13 @@ function isWithin(target, root) {
11724
11720
  }
11725
11721
  var sidebar_artefacts_default = app22;
11726
11722
 
11727
- // server/routes/admin/sidebar-artefact-save.ts
11728
- import { mkdir as mkdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
11729
- import { resolve as resolve16 } from "path";
11730
- var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
11731
- var app23 = new Hono();
11732
- app23.post("/", requireAdminSession, async (c) => {
11733
- const cacheKey = c.var.cacheKey;
11734
- const accountId = getAccountIdForSession(cacheKey);
11735
- if (!accountId) return c.json({ error: "Account not found for session" }, 401);
11736
- const body = await safeJson(c);
11737
- if (!body || typeof body.id !== "string" || typeof body.content !== "string") {
11738
- return c.json({ error: "id and content required" }, 400);
11739
- }
11740
- const accountDir = resolve16(ACCOUNTS_DIR, accountId);
11741
- const resolved = await resolveSavePath(body.id, accountDir);
11742
- if (resolved.kind === "reject") {
11743
- console.error(
11744
- `[admin/sidebar-artefact-save] auth-rejected reason=${resolved.reason} path=${body.id}`
11745
- );
11746
- return c.json({ error: resolved.reason }, resolved.status);
11747
- }
11748
- const start = Date.now();
11749
- try {
11750
- await writeFile5(resolved.path, body.content, "utf-8");
11751
- } catch (err) {
11752
- const message = err instanceof Error ? err.message : String(err);
11753
- console.error(
11754
- `[admin/sidebar-artefact-save] write-failed path=${relPath(resolved.path, accountDir)} error="${message}"`
11755
- );
11756
- return c.json({ error: "Write failed" }, 500);
11757
- }
11758
- let updatedAt = (/* @__PURE__ */ new Date()).toISOString();
11759
- try {
11760
- const st = await stat6(resolved.path);
11761
- updatedAt = st.mtime.toISOString();
11762
- } catch {
11763
- }
11764
- const ms = Date.now() - start;
11765
- console.log(
11766
- `[admin/sidebar-artefact-save] account=${accountId} path=${relPath(resolved.path, accountDir)} bytes=${body.content.length} ms=${ms}`
11767
- );
11768
- return c.json({ updatedAt });
11769
- });
11770
- async function resolveSavePath(id, accountDir) {
11771
- if (!id.startsWith("agent-template:")) {
11772
- return { kind: "reject", status: 400, reason: "invalid-id" };
11773
- }
11774
- const parts = id.split(":");
11775
- if (parts.length !== 3) return { kind: "reject", status: 400, reason: "invalid-id" };
11776
- const [, role, filename] = parts;
11777
- if (role === "specialist") {
11778
- return { kind: "reject", status: 403, reason: "specialist-write-blocked" };
11779
- }
11780
- if (role !== "admin" || !ADMIN_AGENT_FILES2.has(filename)) {
11781
- return { kind: "reject", status: 400, reason: "invalid-id" };
11782
- }
11783
- const parent = resolve16(accountDir, "agents", "admin");
11784
- await mkdir4(parent, { recursive: true });
11785
- try {
11786
- validateFilePathInAccount(parent, accountDir);
11787
- } catch {
11788
- return { kind: "reject", status: 400, reason: "containment-rejected" };
11789
- }
11790
- return { kind: "admin-template", path: resolve16(parent, filename) };
11791
- }
11792
- function relPath(absPath, root) {
11793
- return absPath.startsWith(root) ? absPath.slice(root.length + 1) : absPath;
11794
- }
11795
- var sidebar_artefact_save_default = app23;
11796
-
11797
11723
  // server/routes/admin/sidebar-sessions.ts
11798
11724
  import { readdirSync as readdirSync8, readFileSync as readFileSync14, statSync as statSync7 } from "fs";
11799
11725
  import { join as join13 } from "path";
11800
- var RC_URL_RE = /https:\/\/claude\.ai\/code\/session_[A-Za-z0-9_-]+/;
11801
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$/;
11802
11728
  var TITLE_MAX = 80;
11803
- var app24 = new Hono();
11729
+ var app23 = new Hono();
11804
11730
  function claudeConfigDir() {
11805
11731
  return process.env.CLAUDE_CONFIG_DIR ?? null;
11806
11732
  }
@@ -11846,8 +11772,8 @@ function enumerateJsonls(projectsRoot) {
11846
11772
  }
11847
11773
  return out;
11848
11774
  }
11849
- function liveSessionIdSet(configDir2) {
11850
- const out = /* @__PURE__ */ new Set();
11775
+ function sessionIdToPidMap(configDir2) {
11776
+ const out = /* @__PURE__ */ new Map();
11851
11777
  const sessionsDir = join13(configDir2, "sessions");
11852
11778
  let entries;
11853
11779
  try {
@@ -11856,7 +11782,11 @@ function liveSessionIdSet(configDir2) {
11856
11782
  return out;
11857
11783
  }
11858
11784
  for (const entry of entries) {
11859
- if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
11785
+ if (!entry.isFile()) continue;
11786
+ const m = entry.name.match(PID_FILE_RE);
11787
+ if (!m) continue;
11788
+ const pid = Number(m[1]);
11789
+ if (!Number.isFinite(pid) || pid <= 0) continue;
11860
11790
  let body;
11861
11791
  try {
11862
11792
  body = readFileSync14(join13(sessionsDir, entry.name), "utf8");
@@ -11871,7 +11801,7 @@ function liveSessionIdSet(configDir2) {
11871
11801
  }
11872
11802
  if (!parsed || typeof parsed !== "object") continue;
11873
11803
  const sid = parsed.sessionId;
11874
- if (typeof sid === "string" && sid.length > 0) out.add(sid);
11804
+ if (typeof sid === "string" && sid.length > 0) out.set(sid, pid);
11875
11805
  }
11876
11806
  return out;
11877
11807
  }
@@ -11895,22 +11825,24 @@ function firstUserMessage(body) {
11895
11825
  }
11896
11826
  return null;
11897
11827
  }
11898
- app24.get("/", requireAdminSession, async (c) => {
11828
+ app23.get("/", requireAdminSession, async (c) => {
11829
+ const accountId = process.env.ACCOUNT_ID ?? null;
11899
11830
  const configDir2 = claudeConfigDir();
11900
11831
  if (!configDir2) {
11901
11832
  console.error("[admin-sessions-list] CLAUDE_CONFIG_DIR not set; returning empty list");
11902
- return c.json({ sessions: [] });
11833
+ return c.json({ sessions: [], accountId });
11903
11834
  }
11904
11835
  const projectsRoot = join13(configDir2, "projects");
11905
11836
  const jsonls = enumerateJsonls(projectsRoot);
11906
- const liveIds = liveSessionIdSet(configDir2);
11837
+ const pidsBySession = sessionIdToPidMap(configDir2);
11907
11838
  const rows = [];
11908
11839
  const seenIds = /* @__PURE__ */ new Set();
11909
11840
  let liveCount = 0;
11910
- let rcCount = 0;
11911
11841
  let subagentCount = 0;
11912
11842
  for (const { path: path2, isSubagent } of jsonls) {
11913
- const base = path2.slice(path2.lastIndexOf("/") + 1);
11843
+ const lastSlash = path2.lastIndexOf("/");
11844
+ const base = path2.slice(lastSlash + 1);
11845
+ const projectDir = path2.slice(0, lastSlash);
11914
11846
  const sessionId = base.slice(0, -".jsonl".length);
11915
11847
  if (seenIds.has(sessionId)) {
11916
11848
  console.error(`[admin-sessions-list] duplicate-sessionId sessionId=${sessionId} path=${path2}`);
@@ -11925,29 +11857,175 @@ app24.get("/", requireAdminSession, async (c) => {
11925
11857
  } catch {
11926
11858
  continue;
11927
11859
  }
11928
- const urlMatch = body.match(RC_URL_RE);
11929
- const live = liveIds.has(sessionId);
11860
+ const pid = pidsBySession.get(sessionId) ?? null;
11861
+ const live = pid !== null;
11930
11862
  const title = firstUserMessage(body) ?? sessionId.slice(0, 8);
11931
- const row = {
11863
+ rows.push({
11932
11864
  sessionId,
11933
11865
  title,
11934
11866
  startedAt: new Date(mtimeMs).toISOString(),
11935
11867
  live,
11936
- isSubagent
11937
- };
11938
- if (urlMatch) row.rcUrl = urlMatch[0];
11939
- rows.push(row);
11868
+ isSubagent,
11869
+ pid,
11870
+ projectDir
11871
+ });
11940
11872
  if (live) liveCount += 1;
11941
- if (urlMatch) rcCount += 1;
11942
11873
  if (isSubagent) subagentCount += 1;
11943
11874
  }
11944
11875
  rows.sort((a, b) => a.startedAt < b.startedAt ? 1 : -1);
11945
11876
  console.log(
11946
- `[admin-sessions-list] rows=${rows.length} live=${liveCount} rc=${rcCount} subagents=${subagentCount}`
11877
+ `[admin-sessions-list] rows=${rows.length} live=${liveCount} subagents=${subagentCount} accountId=${accountId ? accountId.slice(0, 8) : "unset"}`
11947
11878
  );
11948
- return c.json({ sessions: rows });
11879
+ return c.json({ sessions: rows, accountId });
11949
11880
  });
11950
- var sidebar_sessions_default = app24;
11881
+ var sidebar_sessions_default = app23;
11882
+
11883
+ // server/routes/admin/session-delete.ts
11884
+ import { existsSync as existsSync17, readdirSync as readdirSync9, readFileSync as readFileSync15, unlinkSync as unlinkSync2 } from "fs";
11885
+ import { join as join14, resolve as resolve16 } from "path";
11886
+ var app24 = new Hono();
11887
+ 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;
11888
+ var PID_FILE_RE2 = /^([0-9]+)\.json$/;
11889
+ function findPidForSession(configDir2, sessionId) {
11890
+ const sessionsDir = join14(configDir2, "sessions");
11891
+ let entries;
11892
+ try {
11893
+ entries = readdirSync9(sessionsDir, { withFileTypes: true });
11894
+ } catch {
11895
+ return null;
11896
+ }
11897
+ for (const entry of entries) {
11898
+ if (!entry.isFile()) continue;
11899
+ const m = entry.name.match(PID_FILE_RE2);
11900
+ if (!m) continue;
11901
+ const pid = Number(m[1]);
11902
+ if (!Number.isFinite(pid) || pid <= 0) continue;
11903
+ let body;
11904
+ try {
11905
+ body = readFileSync15(join14(sessionsDir, entry.name), "utf8");
11906
+ } catch {
11907
+ continue;
11908
+ }
11909
+ let parsed;
11910
+ try {
11911
+ parsed = JSON.parse(body);
11912
+ } catch {
11913
+ continue;
11914
+ }
11915
+ if (!parsed || typeof parsed !== "object") continue;
11916
+ if (parsed.sessionId === sessionId) return pid;
11917
+ }
11918
+ return null;
11919
+ }
11920
+ function killBestEffort(pid) {
11921
+ try {
11922
+ process.kill(pid, "SIGTERM");
11923
+ return true;
11924
+ } catch {
11925
+ return false;
11926
+ }
11927
+ }
11928
+ app24.post("/", requireAdminSession, async (c) => {
11929
+ let body;
11930
+ try {
11931
+ body = await c.req.json();
11932
+ } catch {
11933
+ return c.json({ error: "invalid JSON body" }, 400);
11934
+ }
11935
+ const sessionId = typeof body.sessionId === "string" ? body.sessionId : "";
11936
+ const projectDir = typeof body.projectDir === "string" ? body.projectDir : "";
11937
+ if (!SESSION_ID_RE2.test(sessionId)) {
11938
+ return c.json({ error: "sessionId must be a v4 UUID" }, 400);
11939
+ }
11940
+ if (!projectDir) {
11941
+ return c.json({ error: "projectDir is required" }, 400);
11942
+ }
11943
+ const configDir2 = process.env.CLAUDE_CONFIG_DIR;
11944
+ if (!configDir2) {
11945
+ return c.json({ error: "CLAUDE_CONFIG_DIR not set" }, 500);
11946
+ }
11947
+ const projectsRoot = resolve16(join14(configDir2, "projects")) + "/";
11948
+ const resolvedProject = resolve16(projectDir) + "/";
11949
+ if (!resolvedProject.startsWith(projectsRoot)) {
11950
+ console.error(`[sessions-delete] reject reason=projectDir-outside-tree projectDir=${projectDir}`);
11951
+ return c.json({ error: "projectDir is not under CLAUDE_CONFIG_DIR/projects/" }, 400);
11952
+ }
11953
+ const jsonlPath = join14(projectDir, `${sessionId}.jsonl`);
11954
+ const sidecarPath = join14(projectDir, `${sessionId}.meta.json`);
11955
+ const pid = findPidForSession(configDir2, sessionId);
11956
+ let pidKilled;
11957
+ if (pid === null) {
11958
+ pidKilled = "absent";
11959
+ } else {
11960
+ pidKilled = killBestEffort(pid) ? "true" : "false";
11961
+ }
11962
+ let deleted = false;
11963
+ try {
11964
+ if (existsSync17(jsonlPath)) {
11965
+ unlinkSync2(jsonlPath);
11966
+ deleted = true;
11967
+ }
11968
+ } catch (err) {
11969
+ const msg = err instanceof Error ? err.message : String(err);
11970
+ console.error(`[sessions-delete] unlink-failed path=${jsonlPath} err=${msg}`);
11971
+ console.log(
11972
+ `[sessions-delete] sessionId=${sessionId} pidKilled=${pidKilled} jsonlPath=${jsonlPath} deleted=false`
11973
+ );
11974
+ return c.json({ error: `unlink failed: ${msg}` }, 500);
11975
+ }
11976
+ try {
11977
+ if (existsSync17(sidecarPath)) unlinkSync2(sidecarPath);
11978
+ } catch {
11979
+ }
11980
+ console.log(
11981
+ `[sessions-delete] sessionId=${sessionId} pidKilled=${pidKilled} jsonlPath=${jsonlPath} deleted=${deleted}`
11982
+ );
11983
+ return c.json({ deleted, pidKilled, jsonlPath });
11984
+ });
11985
+ var session_delete_default = app24;
11986
+
11987
+ // server/routes/admin/session-rc-spawn.ts
11988
+ var app25 = new Hono();
11989
+ function managerBase4() {
11990
+ const port2 = process.env.CLAUDE_SESSION_MANAGER_PORT;
11991
+ if (!port2) throw new Error("CLAUDE_SESSION_MANAGER_PORT is not set");
11992
+ return `http://127.0.0.1:${port2}`;
11993
+ }
11994
+ app25.post("/", requireAdminSession, async (c) => {
11995
+ let body;
11996
+ try {
11997
+ body = await c.req.json();
11998
+ } catch {
11999
+ body = {};
12000
+ }
12001
+ const payload = {};
12002
+ if (typeof body.sessionId === "string" && body.sessionId.length > 0) payload.sessionId = body.sessionId;
12003
+ if (typeof body.name === "string" && body.name.length > 0) payload.name = body.name;
12004
+ let res;
12005
+ try {
12006
+ res = await fetch(`${managerBase4()}/rc-spawn`, {
12007
+ method: "POST",
12008
+ headers: { "content-type": "application/json" },
12009
+ body: JSON.stringify(payload)
12010
+ });
12011
+ } catch (err) {
12012
+ const msg = err instanceof Error ? err.message : String(err);
12013
+ console.error(`[session-rc-spawn] manager-unreachable err=${msg}`);
12014
+ return c.json({ error: `session manager unreachable: ${msg}` }, 502);
12015
+ }
12016
+ const text = await res.text();
12017
+ let parsed = null;
12018
+ try {
12019
+ parsed = JSON.parse(text);
12020
+ } catch {
12021
+ }
12022
+ if (!res.ok) {
12023
+ console.error(`[session-rc-spawn] manager-error status=${res.status} body=${text.slice(0, 200)}`);
12024
+ return c.json(parsed ?? { error: text }, res.status);
12025
+ }
12026
+ return c.json(parsed ?? {});
12027
+ });
12028
+ var session_rc_spawn_default = app25;
11951
12029
 
11952
12030
  // server/routes/admin/system-stats.ts
11953
12031
  import { readFile as readFile5 } from "fs/promises";
@@ -12044,8 +12122,8 @@ async function sample() {
12044
12122
  if (process.platform === "linux") return sampleLinux();
12045
12123
  return sampleOsFallback();
12046
12124
  }
12047
- var app25 = new Hono();
12048
- app25.get("/", async (c) => {
12125
+ var app26 = new Hono();
12126
+ app26.get("/", async (c) => {
12049
12127
  const started = Date.now();
12050
12128
  if (!inflight) {
12051
12129
  inflight = sample().finally(() => {
@@ -12068,17 +12146,17 @@ app25.get("/", async (c) => {
12068
12146
  return c.json({ degraded: true, reason, sampledAtMs: Date.now() });
12069
12147
  }
12070
12148
  });
12071
- var system_stats_default = app25;
12149
+ var system_stats_default = app26;
12072
12150
 
12073
12151
  // server/routes/admin/health.ts
12074
- import { existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
12075
- import { resolve as resolve17, join as join14 } from "path";
12152
+ import { existsSync as existsSync18, readFileSync as readFileSync16 } from "fs";
12153
+ import { resolve as resolve17, join as join15 } from "path";
12076
12154
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve17(process.cwd(), "..");
12077
12155
  var brandHostname = "maxy";
12078
- var brandJsonPath = join14(PLATFORM_ROOT6, "config", "brand.json");
12079
- if (existsSync17(brandJsonPath)) {
12156
+ var brandJsonPath = join15(PLATFORM_ROOT6, "config", "brand.json");
12157
+ if (existsSync18(brandJsonPath)) {
12080
12158
  try {
12081
- const brand = JSON.parse(readFileSync15(brandJsonPath, "utf-8"));
12159
+ const brand = JSON.parse(readFileSync16(brandJsonPath, "utf-8"));
12082
12160
  if (brand.hostname) brandHostname = brand.hostname;
12083
12161
  } catch {
12084
12162
  }
@@ -12087,8 +12165,8 @@ var VERSION_FILE = resolve17(PLATFORM_ROOT6, `config/.${brandHostname}-version`)
12087
12165
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
12088
12166
  var PROBE_TIMEOUT_MS = 1e3;
12089
12167
  function readVersion() {
12090
- if (!existsSync17(VERSION_FILE)) return "unknown";
12091
- return readFileSync15(VERSION_FILE, "utf-8").trim() || "unknown";
12168
+ if (!existsSync18(VERSION_FILE)) return "unknown";
12169
+ return readFileSync16(VERSION_FILE, "utf-8").trim() || "unknown";
12092
12170
  }
12093
12171
  async function probeConversationDb() {
12094
12172
  let session;
@@ -12113,8 +12191,8 @@ async function probeConversationDb() {
12113
12191
  });
12114
12192
  }
12115
12193
  }
12116
- var app26 = new Hono();
12117
- app26.get("/", async (c) => {
12194
+ var app27 = new Hono();
12195
+ app27.get("/", async (c) => {
12118
12196
  const version = readVersion();
12119
12197
  const probe = await probeConversationDb();
12120
12198
  const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
@@ -12136,7 +12214,7 @@ app26.get("/", async (c) => {
12136
12214
  uptimeMs
12137
12215
  });
12138
12216
  });
12139
- var health_default2 = app26;
12217
+ var health_default2 = app27;
12140
12218
 
12141
12219
  // server/routes/admin/linkedin-ingest.ts
12142
12220
  var TAG20 = "[linkedin-ingest-route]";
@@ -12232,8 +12310,8 @@ function buildInitialMessage(env) {
12232
12310
  }
12233
12311
  return header;
12234
12312
  }
12235
- var app27 = new Hono();
12236
- app27.post("/", requireAdminSession, async (c) => {
12313
+ var app28 = new Hono();
12314
+ app28.post("/", requireAdminSession, async (c) => {
12237
12315
  let body;
12238
12316
  try {
12239
12317
  body = await c.req.json();
@@ -12287,7 +12365,7 @@ app27.post("/", requireAdminSession, async (c) => {
12287
12365
  );
12288
12366
  return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: claudeSessionId }, 202);
12289
12367
  });
12290
- var linkedin_ingest_default = app27;
12368
+ var linkedin_ingest_default = app28;
12291
12369
 
12292
12370
  // server/routes/admin/post-turn-context.ts
12293
12371
  import neo4j2 from "neo4j-driver";
@@ -12329,8 +12407,8 @@ function pruneProperties(raw) {
12329
12407
  }
12330
12408
  return out;
12331
12409
  }
12332
- var app28 = new Hono();
12333
- app28.get("/", async (c) => {
12410
+ var app29 = new Hono();
12411
+ app29.get("/", async (c) => {
12334
12412
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
12335
12413
  if (!isLoopbackAddr2(remoteAddr)) {
12336
12414
  console.error(`${TAG21} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -12390,7 +12468,7 @@ app28.get("/", async (c) => {
12390
12468
  await session.close();
12391
12469
  }
12392
12470
  });
12393
- var post_turn_context_default = app28;
12471
+ var post_turn_context_default = app29;
12394
12472
 
12395
12473
  // server/routes/admin/public-session-context.ts
12396
12474
  import neo4j3 from "neo4j-driver";
@@ -12432,8 +12510,8 @@ function pruneProperties2(raw) {
12432
12510
  }
12433
12511
  return out;
12434
12512
  }
12435
- var app29 = new Hono();
12436
- app29.get("/", async (c) => {
12513
+ var app30 = new Hono();
12514
+ app30.get("/", async (c) => {
12437
12515
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
12438
12516
  if (!isLoopbackAddr3(remoteAddr)) {
12439
12517
  console.error(`${TAG22} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -12492,15 +12570,15 @@ app29.get("/", async (c) => {
12492
12570
  await session.close();
12493
12571
  }
12494
12572
  });
12495
- var public_session_context_default = app29;
12573
+ var public_session_context_default = app30;
12496
12574
 
12497
12575
  // server/routes/admin/public-session-exit.ts
12498
12576
  var TAG23 = "[public-session-exit-route]";
12499
12577
  function isLoopbackAddr4(addr) {
12500
12578
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
12501
12579
  }
12502
- var app30 = new Hono();
12503
- app30.post("/", async (c) => {
12580
+ var app31 = new Hono();
12581
+ app31.post("/", async (c) => {
12504
12582
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
12505
12583
  if (!isLoopbackAddr4(remoteAddr)) {
12506
12584
  console.error(`${TAG23} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -12527,15 +12605,15 @@ app30.post("/", async (c) => {
12527
12605
  handlePublicSessionExit(sessionId);
12528
12606
  return c.json({ ok: true });
12529
12607
  });
12530
- var public_session_exit_default = app30;
12608
+ var public_session_exit_default = app31;
12531
12609
 
12532
12610
  // server/routes/admin/access-session-evict.ts
12533
12611
  var TAG24 = "[access-session-evict]";
12534
12612
  function isLoopbackAddr5(addr) {
12535
12613
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
12536
12614
  }
12537
- var app31 = new Hono();
12538
- app31.post("/", async (c) => {
12615
+ var app32 = new Hono();
12616
+ app32.post("/", async (c) => {
12539
12617
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
12540
12618
  if (!isLoopbackAddr5(remoteAddr)) {
12541
12619
  console.error(`${TAG24} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -12563,41 +12641,42 @@ app31.post("/", async (c) => {
12563
12641
  console.log(`${TAG24} grantId=${grantId} dropped=${dropped}`);
12564
12642
  return c.json({ ok: true, dropped });
12565
12643
  });
12566
- var access_session_evict_default = app31;
12644
+ var access_session_evict_default = app32;
12567
12645
 
12568
12646
  // server/routes/admin/index.ts
12569
- var app32 = new Hono();
12570
- app32.route("/session", session_default);
12571
- app32.route("/logs", logs_default);
12572
- app32.route("/claude-info", claude_info_default);
12573
- app32.route("/attachment", attachment_default);
12574
- app32.route("/agents", agents_default);
12575
- app32.route("/sessions", sessions_default);
12576
- app32.route("/claude-sessions", claude_sessions_default);
12577
- app32.route("/log-ingest", log_ingest_default);
12578
- app32.route("/events", events_default);
12579
- app32.route("/files", files_default);
12580
- app32.route("/graph-search", graph_search_default);
12581
- app32.route("/graph-subgraph", graph_subgraph_default);
12582
- app32.route("/graph-delete", graph_delete_default);
12583
- app32.route("/graph-restore", graph_restore_default);
12584
- app32.route("/graph-labels-in-graph", graph_labels_in_graph_default);
12585
- app32.route("/graph-default-view", graph_default_view_default);
12586
- app32.route("/sidebar-artefacts", sidebar_artefacts_default);
12587
- app32.route("/sidebar-artefact-save", sidebar_artefact_save_default);
12588
- app32.route("/sidebar-sessions", sidebar_sessions_default);
12589
- app32.route("/system-stats", system_stats_default);
12590
- app32.route("/health-brand", health_default2);
12591
- app32.route("/linkedin-ingest", linkedin_ingest_default);
12592
- app32.route("/post-turn-context", post_turn_context_default);
12593
- app32.route("/public-session-context", public_session_context_default);
12594
- app32.route("/public-session-exit", public_session_exit_default);
12595
- app32.route("/access-session-evict", access_session_evict_default);
12596
- var admin_default = app32;
12647
+ var app33 = new Hono();
12648
+ app33.route("/session", session_default);
12649
+ app33.route("/logs", logs_default);
12650
+ app33.route("/claude-info", claude_info_default);
12651
+ app33.route("/attachment", attachment_default);
12652
+ app33.route("/agents", agents_default);
12653
+ app33.route("/sessions", sessions_default);
12654
+ app33.route("/claude-sessions", claude_sessions_default);
12655
+ app33.route("/log-ingest", log_ingest_default);
12656
+ app33.route("/events", events_default);
12657
+ app33.route("/files", files_default);
12658
+ app33.route("/graph-search", graph_search_default);
12659
+ app33.route("/graph-subgraph", graph_subgraph_default);
12660
+ app33.route("/graph-delete", graph_delete_default);
12661
+ app33.route("/graph-restore", graph_restore_default);
12662
+ app33.route("/graph-labels-in-graph", graph_labels_in_graph_default);
12663
+ app33.route("/graph-default-view", graph_default_view_default);
12664
+ app33.route("/sidebar-artefacts", sidebar_artefacts_default);
12665
+ app33.route("/sidebar-sessions", sidebar_sessions_default);
12666
+ app33.route("/session-delete", session_delete_default);
12667
+ app33.route("/session-rc-spawn", session_rc_spawn_default);
12668
+ app33.route("/system-stats", system_stats_default);
12669
+ app33.route("/health-brand", health_default2);
12670
+ app33.route("/linkedin-ingest", linkedin_ingest_default);
12671
+ app33.route("/post-turn-context", post_turn_context_default);
12672
+ app33.route("/public-session-context", public_session_context_default);
12673
+ app33.route("/public-session-exit", public_session_exit_default);
12674
+ app33.route("/access-session-evict", access_session_evict_default);
12675
+ var admin_default = app33;
12597
12676
 
12598
12677
  // app/lib/access-gate.ts
12599
12678
  import neo4j4 from "neo4j-driver";
12600
- import { readFileSync as readFileSync16 } from "fs";
12679
+ import { readFileSync as readFileSync17 } from "fs";
12601
12680
  import { resolve as resolve18 } from "path";
12602
12681
  import { randomUUID as randomUUID8 } from "crypto";
12603
12682
  var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve18(process.cwd(), "..");
@@ -12606,7 +12685,7 @@ function readPassword() {
12606
12685
  if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
12607
12686
  const passwordFile = resolve18(PLATFORM_ROOT7, "config/.neo4j-password");
12608
12687
  try {
12609
- return readFileSync16(passwordFile, "utf-8").trim();
12688
+ return readFileSync17(passwordFile, "utf-8").trim();
12610
12689
  } catch {
12611
12690
  throw new Error(
12612
12691
  `Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`
@@ -12807,8 +12886,8 @@ async function generateNewMagicToken(grantId) {
12807
12886
  var TAG25 = "[access-verify]";
12808
12887
  var MINT_TAG = "[access-session-mint]";
12809
12888
  var COOKIE_NAME = "__access_session";
12810
- var app33 = new Hono();
12811
- app33.post("/", async (c) => {
12889
+ var app34 = new Hono();
12890
+ app34.post("/", async (c) => {
12812
12891
  const ip = c.var.clientIp || "unknown";
12813
12892
  let body;
12814
12893
  try {
@@ -12890,7 +12969,7 @@ app33.post("/", async (c) => {
12890
12969
  displayName: grant.displayName
12891
12970
  });
12892
12971
  });
12893
- var verify_token_default = app33;
12972
+ var verify_token_default = app34;
12894
12973
 
12895
12974
  // app/lib/access-email.ts
12896
12975
  import { spawn as spawn2 } from "child_process";
@@ -12953,9 +13032,9 @@ async function sendMagicLinkEmail(payload) {
12953
13032
 
12954
13033
  // server/routes/access/request-magic-link.ts
12955
13034
  var TAG26 = "[access-request-link]";
12956
- var app34 = new Hono();
13035
+ var app35 = new Hono();
12957
13036
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
12958
- app34.post("/", async (c) => {
13037
+ app35.post("/", async (c) => {
12959
13038
  let body;
12960
13039
  try {
12961
13040
  body = await c.req.json();
@@ -13029,16 +13108,16 @@ app34.post("/", async (c) => {
13029
13108
  );
13030
13109
  return c.json({ message: VISITOR_MESSAGE }, 200);
13031
13110
  });
13032
- var request_magic_link_default = app34;
13111
+ var request_magic_link_default = app35;
13033
13112
 
13034
13113
  // server/routes/access/index.ts
13035
- var app35 = new Hono();
13036
- app35.route("/verify-token", verify_token_default);
13037
- app35.route("/request-magic-link", request_magic_link_default);
13038
- var access_default = app35;
13114
+ var app36 = new Hono();
13115
+ app36.route("/verify-token", verify_token_default);
13116
+ app36.route("/request-magic-link", request_magic_link_default);
13117
+ var access_default = app36;
13039
13118
 
13040
13119
  // server/routes/sites.ts
13041
- import { existsSync as existsSync18, readFileSync as readFileSync17, realpathSync as realpathSync5, statSync as statSync8 } from "fs";
13120
+ import { existsSync as existsSync19, readFileSync as readFileSync18, realpathSync as realpathSync5, statSync as statSync8 } from "fs";
13042
13121
  import { resolve as resolve20 } from "path";
13043
13122
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
13044
13123
  var MIME = {
@@ -13070,8 +13149,8 @@ function getExt(p) {
13070
13149
  if (idx < p.lastIndexOf("/")) return "";
13071
13150
  return p.slice(idx).toLowerCase();
13072
13151
  }
13073
- var app36 = new Hono();
13074
- app36.get("/:rel{.*}", (c) => {
13152
+ var app37 = new Hono();
13153
+ app37.get("/:rel{.*}", (c) => {
13075
13154
  const reqPath = c.req.path;
13076
13155
  const rawRel = c.req.param("rel") ?? "";
13077
13156
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -13102,13 +13181,13 @@ app36.get("/:rel{.*}", (c) => {
13102
13181
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
13103
13182
  return c.text("Forbidden", 403);
13104
13183
  }
13105
- let stat8;
13184
+ let stat7;
13106
13185
  try {
13107
- stat8 = existsSync18(filePath) ? statSync8(filePath) : null;
13186
+ stat7 = existsSync19(filePath) ? statSync8(filePath) : null;
13108
13187
  } catch {
13109
- stat8 = null;
13188
+ stat7 = null;
13110
13189
  }
13111
- if (stat8?.isDirectory() && !reqPath.endsWith("/")) {
13190
+ if (stat7?.isDirectory() && !reqPath.endsWith("/")) {
13112
13191
  const search = new URL(c.req.url).search;
13113
13192
  const target = `${reqPath}/${search}`;
13114
13193
  console.log(
@@ -13116,14 +13195,14 @@ app36.get("/:rel{.*}", (c) => {
13116
13195
  );
13117
13196
  return c.redirect(target, 301);
13118
13197
  }
13119
- if (stat8?.isDirectory()) {
13198
+ if (stat7?.isDirectory()) {
13120
13199
  filePath = resolve20(filePath, "index.html");
13121
13200
  }
13122
13201
  if (!filePath.startsWith(rootDir + "/")) {
13123
13202
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
13124
13203
  return c.text("Forbidden", 403);
13125
13204
  }
13126
- if (!existsSync18(filePath)) {
13205
+ if (!existsSync19(filePath)) {
13127
13206
  console.error(`[sites] not-found path=${reqPath} status=404`);
13128
13207
  return c.text("Not found", 404);
13129
13208
  }
@@ -13142,7 +13221,7 @@ app36.get("/:rel{.*}", (c) => {
13142
13221
  }
13143
13222
  let body;
13144
13223
  try {
13145
- body = readFileSync17(realPath);
13224
+ body = readFileSync18(realPath);
13146
13225
  } catch (err) {
13147
13226
  const code = err?.code;
13148
13227
  if (code === "EISDIR") {
@@ -13174,11 +13253,11 @@ app36.get("/:rel{.*}", (c) => {
13174
13253
  "X-Content-Type-Options": "nosniff"
13175
13254
  });
13176
13255
  });
13177
- var sites_default = app36;
13256
+ var sites_default = app37;
13178
13257
 
13179
13258
  // app/lib/visitor-token.ts
13180
13259
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
13181
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync18, writeFileSync as writeFileSync6 } from "fs";
13260
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync19, writeFileSync as writeFileSync6 } from "fs";
13182
13261
  import { dirname as dirname4 } from "path";
13183
13262
  var TOKEN_PREFIX = "v1.";
13184
13263
  var SECRET_BYTES = 32;
@@ -13187,7 +13266,7 @@ var cachedSecret = null;
13187
13266
  function getSecret() {
13188
13267
  if (cachedSecret) return cachedSecret;
13189
13268
  try {
13190
- const hex2 = readFileSync18(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
13269
+ const hex2 = readFileSync19(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
13191
13270
  if (hex2.length === SECRET_BYTES * 2) {
13192
13271
  cachedSecret = Buffer.from(hex2, "hex");
13193
13272
  return cachedSecret;
@@ -13201,7 +13280,7 @@ function getSecret() {
13201
13280
  console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
13202
13281
  } catch {
13203
13282
  }
13204
- const hex = readFileSync18(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
13283
+ const hex = readFileSync19(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
13205
13284
  cachedSecret = Buffer.from(hex, "hex");
13206
13285
  return cachedSecret;
13207
13286
  }
@@ -13254,8 +13333,8 @@ var VISITOR_COOKIE_NAME = "mxy_v";
13254
13333
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
13255
13334
 
13256
13335
  // app/lib/brand-config.ts
13257
- import { existsSync as existsSync19, readFileSync as readFileSync19 } from "fs";
13258
- import { join as join15 } from "path";
13336
+ import { existsSync as existsSync20, readFileSync as readFileSync20 } from "fs";
13337
+ import { join as join16 } from "path";
13259
13338
  var cached2 = null;
13260
13339
  var cachedAttempted = false;
13261
13340
  function readBrandConfig() {
@@ -13263,10 +13342,10 @@ function readBrandConfig() {
13263
13342
  cachedAttempted = true;
13264
13343
  const platformRoot = process.env.MAXY_PLATFORM_ROOT;
13265
13344
  if (!platformRoot) return null;
13266
- const brandPath = join15(platformRoot, "config", "brand.json");
13267
- if (!existsSync19(brandPath)) return null;
13345
+ const brandPath = join16(platformRoot, "config", "brand.json");
13346
+ if (!existsSync20(brandPath)) return null;
13268
13347
  try {
13269
- cached2 = JSON.parse(readFileSync19(brandPath, "utf-8"));
13348
+ cached2 = JSON.parse(readFileSync20(brandPath, "utf-8"));
13270
13349
  return cached2;
13271
13350
  } catch {
13272
13351
  return null;
@@ -13274,7 +13353,7 @@ function readBrandConfig() {
13274
13353
  }
13275
13354
 
13276
13355
  // server/routes/visitor-consent.ts
13277
- var app37 = new Hono();
13356
+ var app38 = new Hono();
13278
13357
  var CONSENT_COOKIE_NAME = "mxy_consent";
13279
13358
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
13280
13359
  var DEFAULT_CONSENT_COPY = {
@@ -13319,17 +13398,17 @@ function siteSlugFromReferer(referer) {
13319
13398
  return "";
13320
13399
  }
13321
13400
  }
13322
- app37.options("/consent", (c) => {
13401
+ app38.options("/consent", (c) => {
13323
13402
  const origin = getOrigin(c);
13324
13403
  setCorsHeaders(c, origin);
13325
13404
  return c.body(null, 204);
13326
13405
  });
13327
- app37.options("/brand-config", (c) => {
13406
+ app38.options("/brand-config", (c) => {
13328
13407
  const origin = getOrigin(c);
13329
13408
  setCorsHeaders(c, origin);
13330
13409
  return c.body(null, 204);
13331
13410
  });
13332
- app37.post("/consent", async (c) => {
13411
+ app38.post("/consent", async (c) => {
13333
13412
  const origin = getOrigin(c);
13334
13413
  setCorsHeaders(c, origin);
13335
13414
  let raw;
@@ -13369,7 +13448,7 @@ app37.post("/consent", async (c) => {
13369
13448
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
13370
13449
  return c.body(null, 204);
13371
13450
  });
13372
- app37.get("/brand-config", (c) => {
13451
+ app38.get("/brand-config", (c) => {
13373
13452
  const origin = getOrigin(c);
13374
13453
  setCorsHeaders(c, origin);
13375
13454
  const brand = readBrandConfig();
@@ -13379,7 +13458,7 @@ app37.get("/brand-config", (c) => {
13379
13458
  c.header("Cache-Control", "public, max-age=300");
13380
13459
  return c.json({ consent: { copy, palette } });
13381
13460
  });
13382
- var visitor_consent_default = app37;
13461
+ var visitor_consent_default = app38;
13383
13462
 
13384
13463
  // server/routes/listings.ts
13385
13464
  function getCookie(headerValue, name) {
@@ -13406,8 +13485,8 @@ function appendConsentParams(pageUrl, token) {
13406
13485
  }
13407
13486
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
13408
13487
  var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
13409
- var app38 = new Hono();
13410
- app38.get("/:slug/click", async (c) => {
13488
+ var app39 = new Hono();
13489
+ app39.get("/:slug/click", async (c) => {
13411
13490
  const slug = c.req.param("slug") ?? "";
13412
13491
  const rawSession = c.req.query("session") ?? "";
13413
13492
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -13471,10 +13550,10 @@ app38.get("/:slug/click", async (c) => {
13471
13550
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
13472
13551
  return c.redirect(redirectUrl, 302);
13473
13552
  });
13474
- var listings_default = app38;
13553
+ var listings_default = app39;
13475
13554
 
13476
13555
  // server/routes/visitor-event.ts
13477
- var app39 = new Hono();
13556
+ var app40 = new Hono();
13478
13557
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
13479
13558
  var buckets = /* @__PURE__ */ new Map();
13480
13559
  var RATE_LIMIT = 60;
@@ -13541,12 +13620,12 @@ function originAllowed(origin, allowlist) {
13541
13620
  return false;
13542
13621
  }
13543
13622
  }
13544
- app39.options("/event", (c) => {
13623
+ app40.options("/event", (c) => {
13545
13624
  const origin = getOrigin2(c);
13546
13625
  setCorsHeaders2(c, origin);
13547
13626
  return c.body(null, 204);
13548
13627
  });
13549
- app39.post("/event", async (c) => {
13628
+ app40.post("/event", async (c) => {
13550
13629
  const origin = getOrigin2(c);
13551
13630
  setCorsHeaders2(c, origin);
13552
13631
  const ua = c.req.header("user-agent") ?? "";
@@ -13751,7 +13830,7 @@ async function writeEvent(opts) {
13751
13830
  );
13752
13831
  }
13753
13832
  }
13754
- var visitor_event_default = app39;
13833
+ var visitor_event_default = app40;
13755
13834
 
13756
13835
  // app/lib/graph-health.ts
13757
13836
  var HOUR_MS = 60 * 60 * 1e3;
@@ -13998,7 +14077,7 @@ function broadcastAdminShutdown(reason) {
13998
14077
 
13999
14078
  // ../lib/entitlement/src/index.ts
14000
14079
  import { createPublicKey, createHash as createHash4, verify as cryptoVerify } from "crypto";
14001
- import { existsSync as existsSync20, readFileSync as readFileSync20, statSync as statSync9 } from "fs";
14080
+ import { existsSync as existsSync21, readFileSync as readFileSync21, statSync as statSync9 } from "fs";
14002
14081
  import { resolve as resolve22 } from "path";
14003
14082
 
14004
14083
  // ../lib/entitlement/src/canonicalize.ts
@@ -14047,11 +14126,11 @@ function resolveEntitlement(brand, account) {
14047
14126
  return logResolved(implicitTrust(account), null);
14048
14127
  }
14049
14128
  const entitlementPath = resolve22(brand.configDir, "entitlement.json");
14050
- if (!existsSync20(entitlementPath)) {
14129
+ if (!existsSync21(entitlementPath)) {
14051
14130
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
14052
14131
  }
14053
- const stat8 = statSync9(entitlementPath);
14054
- const key = memoKey(stat8.mtimeMs, account);
14132
+ const stat7 = statSync9(entitlementPath);
14133
+ const key = memoKey(stat7.mtimeMs, account);
14055
14134
  if (memo && memo.key === key) {
14056
14135
  return memo.result;
14057
14136
  }
@@ -14062,7 +14141,7 @@ function resolveEntitlement(brand, account) {
14062
14141
  function verifyAndResolve(brand, entitlementPath, account) {
14063
14142
  let pubkeyPem;
14064
14143
  try {
14065
- pubkeyPem = readFileSync20(pubkeyPath(brand), "utf-8");
14144
+ pubkeyPem = readFileSync21(pubkeyPath(brand), "utf-8");
14066
14145
  } catch (err) {
14067
14146
  return logResolved(anonymousFallback("pubkey-missing"), {
14068
14147
  reason: "pubkey-missing"
@@ -14076,7 +14155,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
14076
14155
  }
14077
14156
  let envelope;
14078
14157
  try {
14079
- envelope = JSON.parse(readFileSync20(entitlementPath, "utf-8"));
14158
+ envelope = JSON.parse(readFileSync21(entitlementPath, "utf-8"));
14080
14159
  } catch {
14081
14160
  return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
14082
14161
  }
@@ -14237,14 +14316,14 @@ function clientFrom(c) {
14237
14316
  );
14238
14317
  }
14239
14318
  var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT || "";
14240
- var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join16(PLATFORM_ROOT9, "config", "brand.json") : "";
14319
+ var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join17(PLATFORM_ROOT9, "config", "brand.json") : "";
14241
14320
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
14242
- if (BRAND_JSON_PATH && !existsSync21(BRAND_JSON_PATH)) {
14321
+ if (BRAND_JSON_PATH && !existsSync22(BRAND_JSON_PATH)) {
14243
14322
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
14244
14323
  }
14245
- if (BRAND_JSON_PATH && existsSync21(BRAND_JSON_PATH)) {
14324
+ if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
14246
14325
  try {
14247
- const parsed = JSON.parse(readFileSync21(BRAND_JSON_PATH, "utf-8"));
14326
+ const parsed = JSON.parse(readFileSync22(BRAND_JSON_PATH, "utf-8"));
14248
14327
  BRAND = { ...BRAND, ...parsed };
14249
14328
  } catch (err) {
14250
14329
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -14263,11 +14342,11 @@ var brandLoginOpts = {
14263
14342
  bodyFont: BRAND.defaultFonts?.body,
14264
14343
  logoContainsName: !!BRAND.logoContainsName
14265
14344
  };
14266
- var ALIAS_DOMAINS_PATH = join16(homedir2(), BRAND.configDir, "alias-domains.json");
14345
+ var ALIAS_DOMAINS_PATH = join17(homedir2(), BRAND.configDir, "alias-domains.json");
14267
14346
  function loadAliasDomains() {
14268
14347
  try {
14269
- if (!existsSync21(ALIAS_DOMAINS_PATH)) return null;
14270
- const parsed = JSON.parse(readFileSync21(ALIAS_DOMAINS_PATH, "utf-8"));
14348
+ if (!existsSync22(ALIAS_DOMAINS_PATH)) return null;
14349
+ const parsed = JSON.parse(readFileSync22(ALIAS_DOMAINS_PATH, "utf-8"));
14271
14350
  if (!Array.isArray(parsed)) {
14272
14351
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
14273
14352
  return null;
@@ -14291,9 +14370,9 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
14291
14370
  function isPublicHost(host) {
14292
14371
  return host.startsWith("public.") || aliasDomains.has(host);
14293
14372
  }
14294
- var app40 = new Hono();
14295
- app40.use("*", clientIpMiddleware);
14296
- app40.use("*", async (c, next) => {
14373
+ var app41 = new Hono();
14374
+ app41.use("*", clientIpMiddleware);
14375
+ app41.use("*", async (c, next) => {
14297
14376
  await next();
14298
14377
  c.header("X-Content-Type-Options", "nosniff");
14299
14378
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
@@ -14303,7 +14382,7 @@ app40.use("*", async (c, next) => {
14303
14382
  );
14304
14383
  });
14305
14384
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
14306
- app40.use("*", async (c, next) => {
14385
+ app41.use("*", async (c, next) => {
14307
14386
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
14308
14387
  await next();
14309
14388
  return;
@@ -14336,7 +14415,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
14336
14415
  "/sites/"
14337
14416
  ];
14338
14417
  var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
14339
- app40.use("*", async (c, next) => {
14418
+ app41.use("*", async (c, next) => {
14340
14419
  const host = (c.req.header("host") ?? "").split(":")[0];
14341
14420
  if (!isPublicHost(host)) {
14342
14421
  await next();
@@ -14376,7 +14455,7 @@ function resolveRemoteAuthOpts() {
14376
14455
  return brandLoginOpts;
14377
14456
  }
14378
14457
  var MAX_LOGIN_BODY = 8 * 1024;
14379
- app40.post("/__remote-auth/login", async (c) => {
14458
+ app41.post("/__remote-auth/login", async (c) => {
14380
14459
  const client = clientFrom(c);
14381
14460
  const clientIp = client.ip || "unknown";
14382
14461
  if (!requestIsTlsTerminated(c)) {
@@ -14421,7 +14500,7 @@ app40.post("/__remote-auth/login", async (c) => {
14421
14500
  }
14422
14501
  });
14423
14502
  });
14424
- app40.get("/__remote-auth/logout", (c) => {
14503
+ app41.get("/__remote-auth/logout", (c) => {
14425
14504
  const client = clientFrom(c);
14426
14505
  const clientIp = client.ip || "unknown";
14427
14506
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -14434,7 +14513,7 @@ app40.get("/__remote-auth/logout", (c) => {
14434
14513
  }
14435
14514
  });
14436
14515
  });
14437
- app40.post("/__remote-auth/change-password", async (c) => {
14516
+ app41.post("/__remote-auth/change-password", async (c) => {
14438
14517
  const client = clientFrom(c);
14439
14518
  const clientIp = client.ip || "unknown";
14440
14519
  const rateLimited = checkRateLimit(client);
@@ -14485,13 +14564,13 @@ app40.post("/__remote-auth/change-password", async (c) => {
14485
14564
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
14486
14565
  }
14487
14566
  });
14488
- app40.get("/__remote-auth/setup", (c) => {
14567
+ app41.get("/__remote-auth/setup", (c) => {
14489
14568
  if (isRemoteAuthConfigured()) {
14490
14569
  return c.redirect("/");
14491
14570
  }
14492
14571
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
14493
14572
  });
14494
- app40.post("/__remote-auth/set-initial-password", async (c) => {
14573
+ app41.post("/__remote-auth/set-initial-password", async (c) => {
14495
14574
  if (isRemoteAuthConfigured()) {
14496
14575
  return c.redirect("/");
14497
14576
  }
@@ -14529,10 +14608,10 @@ app40.post("/__remote-auth/set-initial-password", async (c) => {
14529
14608
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
14530
14609
  }
14531
14610
  });
14532
- app40.get("/api/remote-auth/status", (c) => {
14611
+ app41.get("/api/remote-auth/status", (c) => {
14533
14612
  return c.json({ configured: isRemoteAuthConfigured() });
14534
14613
  });
14535
- app40.post("/api/remote-auth/set-password", async (c) => {
14614
+ app41.post("/api/remote-auth/set-password", async (c) => {
14536
14615
  let body;
14537
14616
  try {
14538
14617
  body = await c.req.json();
@@ -14563,9 +14642,9 @@ app40.post("/api/remote-auth/set-password", async (c) => {
14563
14642
  return c.json({ error: "Failed to save password" }, 500);
14564
14643
  }
14565
14644
  });
14566
- app40.route("/api/_client-error", client_error_default);
14645
+ app41.route("/api/_client-error", client_error_default);
14567
14646
  console.log("[client-error-route] mounted");
14568
- app40.use("*", async (c, next) => {
14647
+ app41.use("*", async (c, next) => {
14569
14648
  const host = (c.req.header("host") ?? "").split(":")[0];
14570
14649
  const path2 = c.req.path;
14571
14650
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
@@ -14598,12 +14677,12 @@ app40.use("*", async (c, next) => {
14598
14677
  console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
14599
14678
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
14600
14679
  });
14601
- app40.route("/api/health", health_default);
14602
- app40.route("/api/chat", chat_default);
14603
- app40.route("/api/whatsapp", whatsapp_default);
14604
- app40.route("/api/onboarding", onboarding_default);
14605
- app40.route("/api/admin", admin_default);
14606
- app40.route("/api/access", access_default);
14680
+ app41.route("/api/health", health_default);
14681
+ app41.route("/api/chat", chat_default);
14682
+ app41.route("/api/whatsapp", whatsapp_default);
14683
+ app41.route("/api/onboarding", onboarding_default);
14684
+ app41.route("/api/admin", admin_default);
14685
+ app41.route("/api/access", access_default);
14607
14686
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
14608
14687
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
14609
14688
  var IMAGE_MIME = {
@@ -14615,7 +14694,7 @@ var IMAGE_MIME = {
14615
14694
  ".svg": "image/svg+xml",
14616
14695
  ".ico": "image/x-icon"
14617
14696
  };
14618
- app40.get("/agent-assets/:slug/:filename", (c) => {
14697
+ app41.get("/agent-assets/:slug/:filename", (c) => {
14619
14698
  const slug = c.req.param("slug");
14620
14699
  const filename = c.req.param("filename");
14621
14700
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -14637,20 +14716,20 @@ app40.get("/agent-assets/:slug/:filename", (c) => {
14637
14716
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
14638
14717
  return c.text("Forbidden", 403);
14639
14718
  }
14640
- if (!existsSync21(filePath)) {
14719
+ if (!existsSync22(filePath)) {
14641
14720
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
14642
14721
  return c.text("Not found", 404);
14643
14722
  }
14644
14723
  const ext = "." + filename.split(".").pop()?.toLowerCase();
14645
14724
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
14646
14725
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
14647
- const body = readFileSync21(filePath);
14726
+ const body = readFileSync22(filePath);
14648
14727
  return c.body(body, 200, {
14649
14728
  "Content-Type": contentType,
14650
14729
  "Cache-Control": "public, max-age=3600"
14651
14730
  });
14652
14731
  });
14653
- app40.get("/generated/:filename", (c) => {
14732
+ app41.get("/generated/:filename", (c) => {
14654
14733
  const filename = c.req.param("filename");
14655
14734
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
14656
14735
  console.error(`[generated] serve file=${filename} status=403`);
@@ -14667,29 +14746,29 @@ app40.get("/generated/:filename", (c) => {
14667
14746
  console.error(`[generated] serve file=${filename} status=403`);
14668
14747
  return c.text("Forbidden", 403);
14669
14748
  }
14670
- if (!existsSync21(filePath)) {
14749
+ if (!existsSync22(filePath)) {
14671
14750
  console.error(`[generated] serve file=${filename} status=404`);
14672
14751
  return c.text("Not found", 404);
14673
14752
  }
14674
14753
  const ext = "." + filename.split(".").pop()?.toLowerCase();
14675
14754
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
14676
14755
  console.log(`[generated] serve file=${filename} status=200`);
14677
- const body = readFileSync21(filePath);
14756
+ const body = readFileSync22(filePath);
14678
14757
  return c.body(body, 200, {
14679
14758
  "Content-Type": contentType,
14680
14759
  "Cache-Control": "public, max-age=86400"
14681
14760
  });
14682
14761
  });
14683
- app40.route("/sites", sites_default);
14684
- app40.route("/listings", listings_default);
14685
- app40.route("/v", visitor_event_default);
14686
- app40.route("/v", visitor_consent_default);
14762
+ app41.route("/sites", sites_default);
14763
+ app41.route("/listings", listings_default);
14764
+ app41.route("/v", visitor_event_default);
14765
+ app41.route("/v", visitor_consent_default);
14687
14766
  var htmlCache = /* @__PURE__ */ new Map();
14688
14767
  var brandLogoPath = "/brand/maxy-monochrome.png";
14689
14768
  var brandIconPath = "/brand/maxy-monochrome.png";
14690
- if (BRAND_JSON_PATH && existsSync21(BRAND_JSON_PATH)) {
14769
+ if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
14691
14770
  try {
14692
- const fullBrand = JSON.parse(readFileSync21(BRAND_JSON_PATH, "utf-8"));
14771
+ const fullBrand = JSON.parse(readFileSync22(BRAND_JSON_PATH, "utf-8"));
14693
14772
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
14694
14773
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
14695
14774
  } catch {
@@ -14706,9 +14785,9 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
14706
14785
  function readInstalledVersion() {
14707
14786
  try {
14708
14787
  if (!PLATFORM_ROOT9) return "unknown";
14709
- const versionFile = join16(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
14710
- if (!existsSync21(versionFile)) return "unknown";
14711
- const content = readFileSync21(versionFile, "utf-8").trim();
14788
+ const versionFile = join17(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
14789
+ if (!existsSync22(versionFile)) return "unknown";
14790
+ const content = readFileSync22(versionFile, "utf-8").trim();
14712
14791
  return content || "unknown";
14713
14792
  } catch {
14714
14793
  return "unknown";
@@ -14749,7 +14828,7 @@ var clientErrorReporterScript = `<script>
14749
14828
  function cachedHtml(file) {
14750
14829
  let html = htmlCache.get(file);
14751
14830
  if (!html) {
14752
- html = readFileSync21(resolve23(process.cwd(), "public", file), "utf-8");
14831
+ html = readFileSync22(resolve23(process.cwd(), "public", file), "utf-8");
14753
14832
  const productNameEsc = escapeHtml(BRAND.productName);
14754
14833
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
14755
14834
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -14765,26 +14844,26 @@ ${clientErrorReporterScript}
14765
14844
  }
14766
14845
  var brandedHtmlCache = /* @__PURE__ */ new Map();
14767
14846
  function loadBrandingCache(agentSlug) {
14768
- const configDir2 = join16(homedir2(), BRAND.configDir);
14847
+ const configDir2 = join17(homedir2(), BRAND.configDir);
14769
14848
  try {
14770
- const accountJsonPath = join16(configDir2, "account.json");
14771
- if (!existsSync21(accountJsonPath)) return null;
14772
- const account = JSON.parse(readFileSync21(accountJsonPath, "utf-8"));
14849
+ const accountJsonPath = join17(configDir2, "account.json");
14850
+ if (!existsSync22(accountJsonPath)) return null;
14851
+ const account = JSON.parse(readFileSync22(accountJsonPath, "utf-8"));
14773
14852
  const accountId = account.accountId;
14774
14853
  if (!accountId) return null;
14775
- const cachePath = join16(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
14776
- if (!existsSync21(cachePath)) return null;
14777
- return JSON.parse(readFileSync21(cachePath, "utf-8"));
14854
+ const cachePath = join17(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
14855
+ if (!existsSync22(cachePath)) return null;
14856
+ return JSON.parse(readFileSync22(cachePath, "utf-8"));
14778
14857
  } catch {
14779
14858
  return null;
14780
14859
  }
14781
14860
  }
14782
14861
  function resolveDefaultSlug() {
14783
14862
  try {
14784
- const configDir2 = join16(homedir2(), BRAND.configDir);
14785
- const accountJsonPath = join16(configDir2, "account.json");
14786
- if (!existsSync21(accountJsonPath)) return null;
14787
- const account = JSON.parse(readFileSync21(accountJsonPath, "utf-8"));
14863
+ const configDir2 = join17(homedir2(), BRAND.configDir);
14864
+ const accountJsonPath = join17(configDir2, "account.json");
14865
+ if (!existsSync22(accountJsonPath)) return null;
14866
+ const account = JSON.parse(readFileSync22(accountJsonPath, "utf-8"));
14788
14867
  return account.defaultAgent || null;
14789
14868
  } catch {
14790
14869
  return null;
@@ -14820,7 +14899,7 @@ function brandedPublicHtml(agentSlug) {
14820
14899
  function escapeHtml(s) {
14821
14900
  return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
14822
14901
  }
14823
- app40.get("/", (c) => {
14902
+ app41.get("/", (c) => {
14824
14903
  const host = (c.req.header("host") ?? "").split(":")[0];
14825
14904
  if (isPublicHost(host)) {
14826
14905
  const defaultSlug = resolveDefaultSlug();
@@ -14828,12 +14907,12 @@ app40.get("/", (c) => {
14828
14907
  }
14829
14908
  return c.html(cachedHtml("index.html"));
14830
14909
  });
14831
- app40.get("/public", (c) => {
14910
+ app41.get("/public", (c) => {
14832
14911
  const host = (c.req.header("host") ?? "").split(":")[0];
14833
14912
  if (isPublicHost(host)) return c.text("Not found", 404);
14834
14913
  return c.html(cachedHtml("public.html"));
14835
14914
  });
14836
- app40.get("/chat", (c) => {
14915
+ app41.get("/chat", (c) => {
14837
14916
  const host = (c.req.header("host") ?? "").split(":")[0];
14838
14917
  if (isPublicHost(host)) return c.text("Not found", 404);
14839
14918
  return c.html(cachedHtml("public.html"));
@@ -14852,12 +14931,12 @@ async function logViewerFetch(c, next) {
14852
14931
  duration_ms: Date.now() - start
14853
14932
  });
14854
14933
  }
14855
- app40.use("/vnc-viewer.html", logViewerFetch);
14856
- app40.use("/vnc-popout.html", logViewerFetch);
14857
- app40.get("/vnc-popout.html", (c) => {
14934
+ app41.use("/vnc-viewer.html", logViewerFetch);
14935
+ app41.use("/vnc-popout.html", logViewerFetch);
14936
+ app41.get("/vnc-popout.html", (c) => {
14858
14937
  let html = htmlCache.get("vnc-popout.html");
14859
14938
  if (!html) {
14860
- html = readFileSync21(resolve23(process.cwd(), "public", "vnc-popout.html"), "utf-8");
14939
+ html = readFileSync22(resolve23(process.cwd(), "public", "vnc-popout.html"), "utf-8");
14861
14940
  const name = escapeHtml(BRAND.productName);
14862
14941
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
14863
14942
  html = html.replace("</head>", ` ${brandScript}
@@ -14867,7 +14946,7 @@ app40.get("/vnc-popout.html", (c) => {
14867
14946
  }
14868
14947
  return c.html(html);
14869
14948
  });
14870
- app40.post("/api/vnc/client-event", async (c) => {
14949
+ app41.post("/api/vnc/client-event", async (c) => {
14871
14950
  let body;
14872
14951
  try {
14873
14952
  body = await c.req.json();
@@ -14888,25 +14967,25 @@ app40.post("/api/vnc/client-event", async (c) => {
14888
14967
  });
14889
14968
  return c.json({ ok: true });
14890
14969
  });
14891
- app40.get("/g/:slug", (c) => {
14970
+ app41.get("/g/:slug", (c) => {
14892
14971
  return c.html(brandedPublicHtml());
14893
14972
  });
14894
- app40.get("/graph", (c) => {
14973
+ app41.get("/graph", (c) => {
14895
14974
  const host = (c.req.header("host") ?? "").split(":")[0];
14896
14975
  if (isPublicHost(host)) return c.text("Not found", 404);
14897
14976
  return c.html(cachedHtml("graph.html"));
14898
14977
  });
14899
- app40.get("/sessions", (c) => {
14978
+ app41.get("/sessions", (c) => {
14900
14979
  const host = (c.req.header("host") ?? "").split(":")[0];
14901
14980
  if (isPublicHost(host)) return c.text("Not found", 404);
14902
14981
  return c.html(cachedHtml("sessions.html"));
14903
14982
  });
14904
- app40.get("/data", (c) => {
14983
+ app41.get("/data", (c) => {
14905
14984
  const host = (c.req.header("host") ?? "").split(":")[0];
14906
14985
  if (isPublicHost(host)) return c.text("Not found", 404);
14907
14986
  return c.html(cachedHtml("data.html"));
14908
14987
  });
14909
- app40.get("/:slug", async (c, next) => {
14988
+ app41.get("/:slug", async (c, next) => {
14910
14989
  const slug = c.req.param("slug");
14911
14990
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
14912
14991
  const branding = loadBrandingCache(slug);
@@ -14916,15 +14995,15 @@ app40.get("/:slug", async (c, next) => {
14916
14995
  await next();
14917
14996
  });
14918
14997
  if (brandFaviconPath !== "/favicon.ico") {
14919
- app40.get("/favicon.ico", (c) => {
14998
+ app41.get("/favicon.ico", (c) => {
14920
14999
  c.header("Cache-Control", "public, max-age=300");
14921
15000
  return c.redirect(brandFaviconPath, 302);
14922
15001
  });
14923
15002
  }
14924
- app40.use("/*", serveStatic({ root: "./public" }));
15003
+ app41.use("/*", serveStatic({ root: "./public" }));
14925
15004
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
14926
15005
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
14927
- var httpServer = serve({ fetch: app40.fetch, port, hostname });
15006
+ var httpServer = serve({ fetch: app41.fetch, port, hostname });
14928
15007
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
14929
15008
  {
14930
15009
  const loopHist = monitorEventLoopDelay({ resolution: 50 });
@@ -14960,7 +15039,7 @@ for (const m of SUBAPP_MANIFEST) {
14960
15039
  }
14961
15040
  try {
14962
15041
  const registered = [];
14963
- for (const r of app40.routes ?? []) {
15042
+ for (const r of app41.routes ?? []) {
14964
15043
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
14965
15044
  if (AGENT_SLUG_PATTERN.test(r.path)) {
14966
15045
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -14982,8 +15061,8 @@ try {
14982
15061
  }
14983
15062
  (async () => {
14984
15063
  try {
14985
- if (!existsSync21(USERS_FILE)) return;
14986
- const usersRaw = readFileSync21(USERS_FILE, "utf-8").trim();
15064
+ if (!existsSync22(USERS_FILE)) return;
15065
+ const usersRaw = readFileSync22(USERS_FILE, "utf-8").trim();
14987
15066
  if (!usersRaw) return;
14988
15067
  const users = JSON.parse(usersRaw);
14989
15068
  const userId = users[0]?.userId;
@@ -15078,7 +15157,7 @@ if (bootAccountConfig?.whatsapp) {
15078
15157
  }
15079
15158
  init({
15080
15159
  configDir: configDirForWhatsApp,
15081
- platformRoot: resolve23(process.env.MAXY_PLATFORM_ROOT ?? join16(__dirname, "..")),
15160
+ platformRoot: resolve23(process.env.MAXY_PLATFORM_ROOT ?? join17(__dirname, "..")),
15082
15161
  accountConfig: bootAccountConfig,
15083
15162
  onMessage: async (msg) => {
15084
15163
  if (process.env.WHATSAPP_PTY_BRIDGE_ENABLED === "true" && msg.text && !msg.isOwnerMirror) {