@rubytech/create-maxy-code 0.1.188 → 0.1.190

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 (141) hide show
  1. package/dist/index.js +129 -38
  2. package/package.json +1 -1
  3. package/payload/platform/lib/graph-search/dist/index.d.ts +12 -0
  4. package/payload/platform/lib/graph-search/dist/index.d.ts.map +1 -1
  5. package/payload/platform/lib/graph-search/dist/index.js +4 -1
  6. package/payload/platform/lib/graph-search/dist/index.js.map +1 -1
  7. package/payload/platform/lib/graph-search/src/index.ts +4 -2
  8. package/payload/platform/neo4j/schema.cypher +16 -1
  9. package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
  10. package/payload/platform/plugins/admin/PLUGIN.md +3 -5
  11. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-authoring-skill-gate.test.d.ts +2 -0
  12. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-authoring-skill-gate.test.d.ts.map +1 -0
  13. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-authoring-skill-gate.test.js +79 -0
  14. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-authoring-skill-gate.test.js.map +1 -0
  15. package/payload/platform/plugins/admin/mcp/dist/index.js +21 -95
  16. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  17. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.d.ts +9 -0
  18. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.d.ts.map +1 -1
  19. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js +47 -0
  20. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js.map +1 -1
  21. package/payload/platform/plugins/admin/skills/file-presentation/SKILL.md +6 -12
  22. package/payload/platform/plugins/admin/skills/professional-document/SKILL.md +1 -1
  23. package/payload/platform/plugins/docs/references/admin-ui.md +1 -2
  24. package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
  25. package/payload/platform/plugins/docs/references/voice-mirror-guide.md +2 -0
  26. package/payload/platform/plugins/memory/.claude-plugin/plugin.json +1 -1
  27. package/payload/platform/plugins/memory/PLUGIN.md +4 -1
  28. package/payload/platform/plugins/memory/mcp/dist/index.js +63 -0
  29. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  30. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-lookup-by-name.test.d.ts +2 -0
  31. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-lookup-by-name.test.d.ts.map +1 -0
  32. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-lookup-by-name.test.js +135 -0
  33. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-lookup-by-name.test.js.map +1 -0
  34. package/payload/platform/plugins/memory/mcp/dist/tools/memory-lookup-by-name.d.ts +16 -0
  35. package/payload/platform/plugins/memory/mcp/dist/tools/memory-lookup-by-name.d.ts.map +1 -0
  36. package/payload/platform/plugins/memory/mcp/dist/tools/memory-lookup-by-name.js +56 -0
  37. package/payload/platform/plugins/memory/mcp/dist/tools/memory-lookup-by-name.js.map +1 -0
  38. package/payload/platform/plugins/scheduling/PLUGIN.md +1 -1
  39. package/payload/platform/plugins/scheduling/mcp/dist/index.js +1 -1
  40. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  41. package/payload/platform/scripts/identity-forbidden-token-check.mjs +6 -5
  42. package/payload/platform/scripts/setup-account.sh +6 -1
  43. package/payload/platform/scripts/smoke-boot-services.sh +1 -0
  44. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -1
  45. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  46. package/payload/platform/services/claude-session-manager/dist/config.d.ts +4 -0
  47. package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
  48. package/payload/platform/services/claude-session-manager/dist/config.js +6 -1
  49. package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
  50. package/payload/platform/services/claude-session-manager/dist/index.js +1 -0
  51. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  52. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +4 -0
  53. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
  54. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +8 -2
  55. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
  56. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
  57. package/payload/platform/services/claude-session-manager/dist/system-prompt.js +7 -9
  58. package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
  59. package/payload/platform/templates/agents/admin/IDENTITY.md +14 -1
  60. package/payload/platform/templates/specialists/agents/content-producer.md +2 -2
  61. package/payload/platform/templates/specialists/agents/database-operator.md +1 -1
  62. package/payload/platform/templates/specialists/agents/librarian.md +1 -0
  63. package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
  64. package/payload/premium-plugins/writer-craft/skills/voice-mirror/SKILL.md +6 -0
  65. package/payload/server/public/assets/{Checkbox-ChWmQ7if.js → Checkbox-g2WZRfCt.js} +1 -1
  66. package/payload/server/public/assets/{admin-BLi_fAKQ.js → admin-Cv2A5vnQ.js} +53 -53
  67. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DSqzB21V.js → architectureDiagram-Q4EWVU46-BVKxPUIS.js} +1 -1
  68. package/payload/server/public/assets/{blockDiagram-DXYQGD6D--otTO_UB.js → blockDiagram-DXYQGD6D-BpD-1G1V.js} +1 -1
  69. package/payload/server/public/assets/brand-BQW2DYy_.css +1 -0
  70. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CBszqa9W.js → c4Diagram-AHTNJAMY-CFl9Dr6U.js} +1 -1
  71. package/payload/server/public/assets/channel-BTEFjudQ.js +1 -0
  72. package/payload/server/public/assets/{chunk-336JU56O-ClAJP2KY.js → chunk-336JU56O-B2Uc6pEC.js} +2 -2
  73. package/payload/server/public/assets/{chunk-426QAEUC-CgLucS4H.js → chunk-426QAEUC-CcIGcm29.js} +1 -1
  74. package/payload/server/public/assets/{chunk-4TB4RGXK-BvOX6mSk.js → chunk-4TB4RGXK-Dvf5uiFR.js} +1 -1
  75. package/payload/server/public/assets/{chunk-5FUZZQ4R-uyN4XtrW.js → chunk-5FUZZQ4R-DUQR1rF9.js} +1 -1
  76. package/payload/server/public/assets/{chunk-5PVQY5BW-B6xHEzh2.js → chunk-5PVQY5BW-OTvNug7K.js} +1 -1
  77. package/payload/server/public/assets/{chunk-EDXVE4YY-9objw8tW.js → chunk-EDXVE4YY-CRAsAWbD.js} +1 -1
  78. package/payload/server/public/assets/{chunk-ENJZ2VHE-pQpbHIJL.js → chunk-ENJZ2VHE-BNllMoi_.js} +1 -1
  79. package/payload/server/public/assets/{chunk-ICPOFSXX-qS23jC3x.js → chunk-ICPOFSXX-vTeVS4qd.js} +1 -1
  80. package/payload/server/public/assets/{chunk-OYMX7WX6-C9YUwGqp.js → chunk-OYMX7WX6-BdSFcvNa.js} +1 -1
  81. package/payload/server/public/assets/{chunk-U2HBQHQK-D_pYedRJ.js → chunk-U2HBQHQK-BpFXup4D.js} +1 -1
  82. package/payload/server/public/assets/{chunk-X2U36JSP-nxf6GHD-.js → chunk-X2U36JSP-DF-6QHx4.js} +1 -1
  83. package/payload/server/public/assets/{chunk-YZCP3GAM-DqKT124V.js → chunk-YZCP3GAM-CKgDoLRT.js} +1 -1
  84. package/payload/server/public/assets/{chunk-ZZ45TVLE-CLwvpbvu.js → chunk-ZZ45TVLE-B0ACvZCZ.js} +1 -1
  85. package/payload/server/public/assets/classDiagram-6PBFFD2Q-ClkdniKF.js +1 -0
  86. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-kjJetfh2.js +1 -0
  87. package/payload/server/public/assets/clone-BllVm2iY.js +1 -0
  88. package/payload/server/public/assets/{dagre-COCXt23n.js → dagre-3yl9rfxR.js} +1 -1
  89. package/payload/server/public/assets/{dagre-KV5264BT-DmuVMrt4.js → dagre-KV5264BT-D-Ux4uwL.js} +1 -1
  90. package/payload/server/public/assets/data-DIa-MKNj.js +1 -0
  91. package/payload/server/public/assets/{diagram-5BDNPKRD-DOiLSgj_.js → diagram-5BDNPKRD-D-MOMikl.js} +1 -1
  92. package/payload/server/public/assets/{diagram-G4DWMVQ6-quY6PSZQ.js → diagram-G4DWMVQ6-DKdFcnhf.js} +1 -1
  93. package/payload/server/public/assets/{diagram-MMDJMWI5-tN2yiz0C.js → diagram-MMDJMWI5-ajamR766.js} +1 -1
  94. package/payload/server/public/assets/{diagram-TYMM5635-CjrRQNQ0.js → diagram-TYMM5635-D2Pbk2Kk.js} +1 -1
  95. package/payload/server/public/assets/{erDiagram-SMLLAGMA-CrNNMxkA.js → erDiagram-SMLLAGMA-v3o948pk.js} +1 -1
  96. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CCUsJph7.js → flowDiagram-DWJPFMVM-byC1a6GE.js} +1 -1
  97. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-18276bri.js → ganttDiagram-T4ZO3ILL-Dybzs-Sw.js} +1 -1
  98. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CsLsKMjN.js → gitGraphDiagram-UUTBAWPF-DvzXYLuW.js} +1 -1
  99. package/payload/server/public/assets/graph-Y5y3kw6J.js +1 -0
  100. package/payload/server/public/assets/graph-labels-BIRCh328.js +1 -0
  101. package/payload/server/public/assets/{graphlib-CmtUzIni.js → graphlib-DvH_spaA.js} +1 -1
  102. package/payload/server/public/assets/{infoDiagram-42DDH7IO-Dny_ZNz3.js → infoDiagram-42DDH7IO-C2FeU8nE.js} +1 -1
  103. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-kUhIUQE-.js → ishikawaDiagram-UXIWVN3A-CpY5W64P.js} +1 -1
  104. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-DekMvAKB.js → journeyDiagram-VCZTEJTY-ymMAQVdm.js} +1 -1
  105. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-st0HNZZo.js → kanban-definition-6JOO6SKY-_NX9hNK3.js} +1 -1
  106. package/payload/server/public/assets/{lib-Ca7uCvl9.js → lib-BEvO-mE0.js} +1 -1
  107. package/payload/server/public/assets/{line-BaNk-I7J.js → line-Dz7zKWX-.js} +1 -1
  108. package/payload/server/public/assets/{mermaid-parser.core-CRCHYQ_F.js → mermaid-parser.core-BCWd1en6.js} +1 -1
  109. package/payload/server/public/assets/{mermaid.core-BaIYEciF.js → mermaid.core-gSoFkVoN.js} +3 -3
  110. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-D4u4KU2v.js → mindmap-definition-QFDTVHPH-QuIyK2bd.js} +1 -1
  111. package/payload/server/public/assets/page-BCCqlOmj.js +1 -0
  112. package/payload/server/public/assets/{page-DayPduMN.js → page-DwNvJOvr.js} +3 -3
  113. package/payload/server/public/assets/{pieDiagram-DEJITSTG-BItWEilY.js → pieDiagram-DEJITSTG-DHK0yy7U.js} +1 -1
  114. package/payload/server/public/assets/{public-Dze4yArS.js → public-BnS9zREj.js} +3 -3
  115. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CeWDBvmH.js → quadrantDiagram-34T5L4WZ-wK1jwWo5.js} +1 -1
  116. package/payload/server/public/assets/{requirementDiagram-MS252O5E-CcosjedW.js → requirementDiagram-MS252O5E-W_mH85_d.js} +1 -1
  117. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-DNGeFpUj.js → sankeyDiagram-XADWPNL6-nGAM-YLQ.js} +1 -1
  118. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-Cqy_deB6.js → sequenceDiagram-FGHM5R23-SMfUCwBH.js} +1 -1
  119. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-2yoAqEsA.js → stateDiagram-FHFEXIEX-CYKXFirH.js} +1 -1
  120. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-B9ZwM8kx.js +1 -0
  121. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Dmeghpw1.js → timeline-definition-GMOUNBTQ-DethbNFa.js} +1 -1
  122. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-TX5D-Zzp.js → vennDiagram-DHZGUBPP-BUlJTe9Z.js} +1 -1
  123. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-B7mcpl5E.js → wardleyDiagram-NUSXRM2D-CL1TvZ7j.js} +1 -1
  124. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-DH77CxKf.js → xychartDiagram-5P7HB3ND-Cav10l-Z.js} +1 -1
  125. package/payload/server/public/data.html +5 -5
  126. package/payload/server/public/graph.html +6 -6
  127. package/payload/server/public/index.html +8 -8
  128. package/payload/server/public/public.html +5 -5
  129. package/payload/server/server-init.cjs +12 -2
  130. package/payload/server/server.js +586 -292
  131. package/payload/server/public/assets/brand-DzacFNMk.css +0 -1
  132. package/payload/server/public/assets/channel-C-SJYogg.js +0 -1
  133. package/payload/server/public/assets/classDiagram-6PBFFD2Q-OBkxl5to.js +0 -1
  134. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CkTyus-1.js +0 -1
  135. package/payload/server/public/assets/clone-VufdPzJ-.js +0 -1
  136. package/payload/server/public/assets/data-TlJbMIfa.js +0 -1
  137. package/payload/server/public/assets/graph-D2Yvni5R.js +0 -1
  138. package/payload/server/public/assets/graph-labels-uksnCgSC.js +0 -1
  139. package/payload/server/public/assets/page-QQmuB04w.js +0 -1
  140. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Dc5siYvu.js +0 -1
  141. /package/payload/server/public/assets/{brand-Djtb-tLQ.js → brand-BGvv6AYI.js} +0 -0
@@ -756,8 +756,8 @@ var serveStatic = (options = { root: "" }) => {
756
756
  );
757
757
  let stats = getStats(path2);
758
758
  if (stats && stats.isDirectory()) {
759
- const indexFile = options.index ?? "index.html";
760
- path2 = join(path2, indexFile);
759
+ const indexFile2 = options.index ?? "index.html";
760
+ path2 = join(path2, indexFile2);
761
761
  stats = getStats(path2);
762
762
  }
763
763
  if (!stats) {
@@ -816,7 +816,7 @@ var serveStatic = (options = { root: "" }) => {
816
816
 
817
817
  // server/index.ts
818
818
  import { readFileSync as readFileSync20, existsSync as existsSync23, watchFile } from "fs";
819
- import { resolve as resolve22, join as join14, basename as basename5 } from "path";
819
+ import { resolve as resolve23, join as join15, basename as basename5 } from "path";
820
820
  import { homedir as homedir2 } from "os";
821
821
  import { monitorEventLoopDelay } from "perf_hooks";
822
822
 
@@ -1274,7 +1274,7 @@ var credsSaveQueue = Promise.resolve();
1274
1274
  async function drainCredsSaveQueue(timeoutMs = 5e3) {
1275
1275
  console.error(`${TAG2} draining credential save queue\u2026`);
1276
1276
  const timer2 = new Promise(
1277
- (resolve23) => setTimeout(() => resolve23("timeout"), timeoutMs)
1277
+ (resolve24) => setTimeout(() => resolve24("timeout"), timeoutMs)
1278
1278
  );
1279
1279
  const result = await Promise.race([
1280
1280
  credsSaveQueue.then(() => "drained"),
@@ -1402,11 +1402,11 @@ async function createWaSocket(opts) {
1402
1402
  return sock;
1403
1403
  }
1404
1404
  async function waitForConnection(sock) {
1405
- return new Promise((resolve23, reject) => {
1405
+ return new Promise((resolve24, reject) => {
1406
1406
  const handler = (update) => {
1407
1407
  if (update.connection === "open") {
1408
1408
  sock.ev.off("connection.update", handler);
1409
- resolve23();
1409
+ resolve24();
1410
1410
  }
1411
1411
  if (update.connection === "close") {
1412
1412
  sock.ev.off("connection.update", handler);
@@ -1520,14 +1520,14 @@ ${inspected}`;
1520
1520
  return inspect2(err, INSPECT_OPTS2);
1521
1521
  }
1522
1522
  function withTimeout(label, promise, timeoutMs) {
1523
- return new Promise((resolve23, reject) => {
1523
+ return new Promise((resolve24, reject) => {
1524
1524
  const timer2 = setTimeout(() => {
1525
1525
  reject(new Error(`${label} timed out after ${timeoutMs}ms`));
1526
1526
  }, timeoutMs);
1527
1527
  promise.then(
1528
1528
  (value) => {
1529
1529
  clearTimeout(timer2);
1530
- resolve23(value);
1530
+ resolve24(value);
1531
1531
  },
1532
1532
  (err) => {
1533
1533
  clearTimeout(timer2);
@@ -2062,8 +2062,8 @@ async function persistWhatsAppMessage(input) {
2062
2062
  const { givenName, familyName } = splitName(input.pushName);
2063
2063
  const prev = sessionWriteLocks.get(input.cacheKey);
2064
2064
  let release;
2065
- const mine = new Promise((resolve23) => {
2066
- release = resolve23;
2065
+ const mine = new Promise((resolve24) => {
2066
+ release = resolve24;
2067
2067
  });
2068
2068
  const chained = (prev ?? Promise.resolve()).then(() => mine);
2069
2069
  sessionWriteLocks.set(input.cacheKey, chained);
@@ -3099,11 +3099,11 @@ async function connectWithReconnect(conn) {
3099
3099
  console.error(
3100
3100
  `${TAG12} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
3101
3101
  );
3102
- await new Promise((resolve23) => {
3103
- const timer2 = setTimeout(resolve23, delay);
3102
+ await new Promise((resolve24) => {
3103
+ const timer2 = setTimeout(resolve24, delay);
3104
3104
  conn.abortController.signal.addEventListener("abort", () => {
3105
3105
  clearTimeout(timer2);
3106
- resolve23();
3106
+ resolve24();
3107
3107
  }, { once: true });
3108
3108
  });
3109
3109
  }
@@ -3111,16 +3111,16 @@ async function connectWithReconnect(conn) {
3111
3111
  }
3112
3112
  }
3113
3113
  function waitForDisconnectEvent(conn) {
3114
- return new Promise((resolve23) => {
3114
+ return new Promise((resolve24) => {
3115
3115
  if (!conn.sock) {
3116
- resolve23();
3116
+ resolve24();
3117
3117
  return;
3118
3118
  }
3119
3119
  const sock = conn.sock;
3120
3120
  const handler = (update) => {
3121
3121
  if (update.connection === "close") {
3122
3122
  sock.ev.off("connection.update", handler);
3123
- resolve23();
3123
+ resolve24();
3124
3124
  }
3125
3125
  };
3126
3126
  sock.ev.on("connection.update", handler);
@@ -3382,8 +3382,8 @@ async function handleInboundMessage(conn, msg) {
3382
3382
  const conversationKey = isGroup ? remoteJid : senderPhone;
3383
3383
  const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
3384
3384
  let resolvePending;
3385
- const sttPending = new Promise((resolve23) => {
3386
- resolvePending = resolve23;
3385
+ const sttPending = new Promise((resolve24) => {
3386
+ resolvePending = resolve24;
3387
3387
  });
3388
3388
  if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
3389
3389
  try {
@@ -3787,20 +3787,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
3787
3787
 
3788
3788
  // server/routes/health.ts
3789
3789
  function checkPort(port2, timeoutMs = 500) {
3790
- return new Promise((resolve23) => {
3790
+ return new Promise((resolve24) => {
3791
3791
  const socket = createConnection2(port2, "127.0.0.1");
3792
3792
  socket.setTimeout(timeoutMs);
3793
3793
  socket.once("connect", () => {
3794
3794
  socket.destroy();
3795
- resolve23(true);
3795
+ resolve24(true);
3796
3796
  });
3797
3797
  socket.once("error", () => {
3798
3798
  socket.destroy();
3799
- resolve23(false);
3799
+ resolve24(false);
3800
3800
  });
3801
3801
  socket.once("timeout", () => {
3802
3802
  socket.destroy();
3803
- resolve23(false);
3803
+ resolve24(false);
3804
3804
  });
3805
3805
  });
3806
3806
  }
@@ -3865,9 +3865,9 @@ var health_default = app;
3865
3865
 
3866
3866
  // app/lib/attachments.ts
3867
3867
  import { randomUUID as randomUUID3 } from "crypto";
3868
- import { mkdir as mkdir2, readFile, stat as stat2, writeFile as writeFile2 } from "fs/promises";
3868
+ import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
3869
3869
  import { realpathSync } from "fs";
3870
- import { resolve as resolve3, extname, basename } from "path";
3870
+ import { resolve as resolve3, extname } from "path";
3871
3871
  var PLATFORM_ROOT3 = process.env.MAXY_PLATFORM_ROOT ?? resolve3(process.cwd(), "../platform");
3872
3872
  var ATTACHMENTS_ROOT = resolve3(PLATFORM_ROOT3, "..", "data/uploads");
3873
3873
  var SUPPORTED_MIME_TYPES = /* @__PURE__ */ new Set([
@@ -3957,18 +3957,6 @@ function validateFilePathInAccount(filePath, accountDir) {
3957
3957
  }
3958
3958
  return resolved;
3959
3959
  }
3960
- async function storeGeneratedFile(accountId, filePath) {
3961
- const fileStat = await stat2(filePath);
3962
- if (fileStat.size > MAX_FILE_SIZE_BYTES) {
3963
- throw new Error(
3964
- `File exceeds the 50 MB limit (${(fileStat.size / 1024 / 1024).toFixed(1)} MB).`
3965
- );
3966
- }
3967
- const filename = basename(filePath);
3968
- const mimeType = detectMimeType(filePath);
3969
- const buffer = await readFile(filePath);
3970
- return writeAttachment(accountId, filename, mimeType, fileStat.size, buffer);
3971
- }
3972
3960
  async function storeComponentArtefact(accountId, attachmentId, mimeType, content, filename) {
3973
3961
  const buffer = Buffer.from(content, "utf-8");
3974
3962
  if (buffer.byteLength > MAX_FILE_SIZE_BYTES) {
@@ -4548,12 +4536,12 @@ async function dispatchOnce(input) {
4548
4536
  });
4549
4537
  if (!entry) return { error: "spawn-failed" };
4550
4538
  entry.lastInboundAt = Date.now();
4551
- let resolve23;
4539
+ let resolve24;
4552
4540
  const turnPromise = new Promise((r) => {
4553
- resolve23 = r;
4541
+ resolve24 = r;
4554
4542
  });
4555
4543
  const listener = (text) => {
4556
- resolve23(text);
4544
+ resolve24(text);
4557
4545
  };
4558
4546
  entry.subscribers.add(listener);
4559
4547
  const writeOk = await writeInput(entry, input.text);
@@ -4887,8 +4875,8 @@ ${lines}]`;
4887
4875
  var chat_default = app2;
4888
4876
 
4889
4877
  // server/routes/whatsapp.ts
4890
- import { join as join5, resolve as resolve6, basename as basename2 } from "path";
4891
- import { readFile as readFile2, stat as stat3 } from "fs/promises";
4878
+ import { join as join5, resolve as resolve6, basename } from "path";
4879
+ import { readFile, stat as stat2 } from "fs/promises";
4892
4880
  import { realpathSync as realpathSync2, readdirSync as readdirSync2, readFileSync as readFileSync6, existsSync as existsSync4 } from "fs";
4893
4881
 
4894
4882
  // app/lib/whatsapp/login.ts
@@ -4995,8 +4983,8 @@ async function startLogin(opts) {
4995
4983
  resetActiveLogin(accountId);
4996
4984
  let resolveQr = null;
4997
4985
  let rejectQr = null;
4998
- const qrPromise = new Promise((resolve23, reject) => {
4999
- resolveQr = resolve23;
4986
+ const qrPromise = new Promise((resolve24, reject) => {
4987
+ resolveQr = resolve24;
5000
4988
  rejectQr = reject;
5001
4989
  });
5002
4990
  const qrTimer = setTimeout(
@@ -5820,12 +5808,12 @@ app3.post("/send-document", async (c) => {
5820
5808
  console.error(`${TAG17} send-document path error: ${String(err)}`);
5821
5809
  return c.json({ error: String(err) }, 500);
5822
5810
  }
5823
- const fileStat = await stat3(resolvedPath);
5811
+ const fileStat = await stat2(resolvedPath);
5824
5812
  if (fileStat.size > MAX_FILE_SIZE_BYTES) {
5825
5813
  return c.json({ error: `File exceeds 50 MB limit (${(fileStat.size / 1024 / 1024).toFixed(1)} MB)` }, 400);
5826
5814
  }
5827
- const buffer = Buffer.from(await readFile2(resolvedPath));
5828
- const filename = basename2(resolvedPath);
5815
+ const buffer = Buffer.from(await readFile(resolvedPath));
5816
+ const filename = basename(resolvedPath);
5829
5817
  const mimetype = detectMimeType(resolvedPath);
5830
5818
  const sock = getSocket(accountId);
5831
5819
  if (!sock) {
@@ -6781,7 +6769,7 @@ var session_default = app6;
6781
6769
 
6782
6770
  // server/routes/admin/logs.ts
6783
6771
  import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync10, statSync as statSync5 } from "fs";
6784
- import { resolve as resolve7, basename as basename3 } from "path";
6772
+ import { resolve as resolve7, basename as basename2 } from "path";
6785
6773
 
6786
6774
  // app/lib/logs-read-resolve.ts
6787
6775
  import { existsSync as existsSync9 } from "fs";
@@ -6813,7 +6801,7 @@ app7.get("/", async (c) => {
6813
6801
  if (accountLogDir) logDirs.push(accountLogDir);
6814
6802
  logDirs.push(LOG_DIR);
6815
6803
  if (fileParam) {
6816
- const safe = basename3(fileParam);
6804
+ const safe = basename2(fileParam);
6817
6805
  const searched = [];
6818
6806
  for (const dir of logDirs) {
6819
6807
  const filePath = resolve7(dir, safe);
@@ -6883,7 +6871,7 @@ app7.get("/", async (c) => {
6883
6871
  if (hit) {
6884
6872
  console.info(`[admin/logs] resolved cacheKey=${cacheKeySlice} sessionId=${sessionIdSlice} via=${primaryId === cacheKey ? "cacheKey" : primaryId === sessionKeyFromConv ? "reverse-lookup" : "sessionId-fallback"}`);
6885
6873
  try {
6886
- const filename = basename3(hit.path);
6874
+ const filename = basename2(hit.path);
6887
6875
  const buffer = readFileSync10(hit.path);
6888
6876
  const onDiskBytes = statSync5(hit.path).size;
6889
6877
  const headers = {
@@ -6969,7 +6957,7 @@ app8.get("/", (c) => {
6969
6957
  var claude_info_default = app8;
6970
6958
 
6971
6959
  // server/routes/admin/attachment.ts
6972
- import { readFile as readFile3, readdir } from "fs/promises";
6960
+ import { readFile as readFile2, readdir } from "fs/promises";
6973
6961
  import { existsSync as existsSync11 } from "fs";
6974
6962
  import { resolve as resolve8 } from "path";
6975
6963
  var app9 = new Hono();
@@ -6993,7 +6981,7 @@ app9.get("/:attachmentId", requireAdminSession, async (c) => {
6993
6981
  }
6994
6982
  let meta;
6995
6983
  try {
6996
- meta = JSON.parse(await readFile3(metaPath, "utf-8"));
6984
+ meta = JSON.parse(await readFile2(metaPath, "utf-8"));
6997
6985
  } catch {
6998
6986
  return new Response("Not found", { status: 404 });
6999
6987
  }
@@ -7003,7 +6991,7 @@ app9.get("/:attachmentId", requireAdminSession, async (c) => {
7003
6991
  return new Response("Not found", { status: 404 });
7004
6992
  }
7005
6993
  const filePath = resolve8(dir, dataFile);
7006
- const buffer = await readFile3(filePath);
6994
+ const buffer = await readFile2(filePath);
7007
6995
  return new Response(new Uint8Array(buffer), {
7008
6996
  headers: {
7009
6997
  "Content-Type": meta.mimeType,
@@ -8016,10 +8004,10 @@ function computeSpecialistDomains(accountId) {
8016
8004
  const resolveDesc = (qualified) => {
8017
8005
  if (!qualified.startsWith("mcp__")) return void 0;
8018
8006
  const rest = qualified.slice(5);
8019
- const sep4 = rest.indexOf("__");
8020
- if (sep4 < 0) return void 0;
8021
- const plugin = rest.slice(0, sep4);
8022
- const tool = rest.slice(sep4 + 2);
8007
+ const sep6 = rest.indexOf("__");
8008
+ if (sep6 < 0) return void 0;
8009
+ const plugin = rest.slice(0, sep6);
8010
+ const tool = rest.slice(sep6 + 2);
8023
8011
  let map = descByPlugin.get(plugin);
8024
8012
  if (!map) {
8025
8013
  const dir = pluginDirs.get(plugin);
@@ -8398,9 +8386,9 @@ var events_default = app14;
8398
8386
 
8399
8387
  // server/routes/admin/files.ts
8400
8388
  import { createReadStream as createReadStream2 } from "fs";
8401
- import { readdir as readdir2, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
8389
+ import { readdir as readdir3, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
8402
8390
  import { realpathSync as realpathSync4 } from "fs";
8403
- import { basename as basename4, dirname as dirname3, join as join11, resolve as resolve13, sep as sep3 } from "path";
8391
+ import { basename as basename4, dirname as dirname3, join as join12, resolve as resolve14, sep as sep4 } from "path";
8404
8392
  import { Readable as Readable2 } from "stream";
8405
8393
 
8406
8394
  // app/lib/data-path.ts
@@ -8408,6 +8396,16 @@ import { realpathSync as realpathSync3 } from "fs";
8408
8396
  import { resolve as resolve12, normalize, sep as sep2, relative } from "path";
8409
8397
  var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve12(process.cwd(), "../platform");
8410
8398
  var DATA_ROOT = resolve12(PLATFORM_ROOT5, "..", "data");
8399
+ var ACCOUNT_PARTITION_DIRS = /* @__PURE__ */ new Set(["uploads", "accounts"]);
8400
+ 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;
8401
+ function crossesForeignAccountPartition(relPath2, accountId) {
8402
+ const segs = relPath2.split("/").filter(Boolean);
8403
+ if (segs.length < 2) return false;
8404
+ if (!ACCOUNT_PARTITION_DIRS.has(segs[0])) return false;
8405
+ const owner = segs[1];
8406
+ if (!ACCOUNT_UUID_RE.test(owner)) return false;
8407
+ return owner !== accountId;
8408
+ }
8411
8409
  function resolveDataPath(raw) {
8412
8410
  const cleaned = normalize("/" + (raw ?? "").replace(/\\/g, "/")).replace(/^\/+/, "");
8413
8411
  const absolute = resolve12(DATA_ROOT, cleaned);
@@ -8758,11 +8756,291 @@ async function cascadeDeleteDocument(params) {
8758
8756
  }
8759
8757
  }
8760
8758
 
8759
+ // app/lib/file-index.ts
8760
+ import * as fsp from "fs/promises";
8761
+ import { resolve as resolve13, relative as relative2, join as join11, basename as basename3, extname as extname2, sep as sep3 } from "path";
8762
+ import { execFile as execFile2 } from "child_process";
8763
+ import { promisify as promisify2 } from "util";
8764
+ var execFileAsync2 = promisify2(execFile2);
8765
+ var CONTENT_CAP = 1e5;
8766
+ var RECONCILE_DEBOUNCE_MS = 1e4;
8767
+ var lastReconcileAt = /* @__PURE__ */ new Map();
8768
+ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
8769
+ ".txt",
8770
+ ".md",
8771
+ ".markdown",
8772
+ ".csv",
8773
+ ".tsv",
8774
+ ".json",
8775
+ ".jsonl",
8776
+ ".log",
8777
+ ".yaml",
8778
+ ".yml",
8779
+ ".xml",
8780
+ ".toml",
8781
+ ".ini",
8782
+ ".env",
8783
+ ".sql",
8784
+ ".sh",
8785
+ ".py",
8786
+ ".js",
8787
+ ".ts",
8788
+ ".tsx",
8789
+ ".jsx",
8790
+ ".css",
8791
+ ".svg",
8792
+ ".rtf"
8793
+ ]);
8794
+ var HTML_EXTENSIONS = /* @__PURE__ */ new Set([".html", ".htm"]);
8795
+ var MIME_BY_EXT2 = {
8796
+ ".pdf": "application/pdf",
8797
+ ".txt": "text/plain",
8798
+ ".md": "text/markdown",
8799
+ ".markdown": "text/markdown",
8800
+ ".csv": "text/csv",
8801
+ ".json": "application/json",
8802
+ ".html": "text/html",
8803
+ ".htm": "text/html",
8804
+ ".png": "image/png",
8805
+ ".jpg": "image/jpeg",
8806
+ ".jpeg": "image/jpeg",
8807
+ ".gif": "image/gif",
8808
+ ".webp": "image/webp"
8809
+ };
8810
+ function mimeForExt(ext) {
8811
+ return MIME_BY_EXT2[ext.toLowerCase()] ?? "application/octet-stream";
8812
+ }
8813
+ async function extractPdf(absolute) {
8814
+ const { stdout } = await execFileAsync2("pdftotext", [absolute, "-"], {
8815
+ maxBuffer: 10 * 1024 * 1024
8816
+ });
8817
+ return stdout.trim();
8818
+ }
8819
+ function stripHtml(html) {
8820
+ return html.replace(/<script[\s\S]*?<\/script>/gi, " ").replace(/<style[\s\S]*?<\/style>/gi, " ").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
8821
+ }
8822
+ async function extractFileContent(absolute) {
8823
+ const ext = extname2(absolute).toLowerCase();
8824
+ try {
8825
+ if (ext === ".pdf") return (await extractPdf(absolute)).slice(0, CONTENT_CAP);
8826
+ if (HTML_EXTENSIONS.has(ext)) {
8827
+ const raw = await fsp.readFile(absolute, "utf-8");
8828
+ return stripHtml(raw).slice(0, CONTENT_CAP);
8829
+ }
8830
+ if (TEXT_EXTENSIONS.has(ext)) {
8831
+ const raw = await fsp.readFile(absolute, "utf-8");
8832
+ return raw.slice(0, CONTENT_CAP);
8833
+ }
8834
+ return "";
8835
+ } catch (err) {
8836
+ const msg = err instanceof Error ? err.message : String(err);
8837
+ console.error(`[file-index] extract-failed path="${relative2(DATA_ROOT, absolute)}" err="${msg}"`);
8838
+ return "";
8839
+ }
8840
+ }
8841
+ async function readDisplayName(absolute) {
8842
+ const dir = absolute.slice(0, absolute.length - basename3(absolute).length);
8843
+ const base = basename3(absolute);
8844
+ const dot = base.lastIndexOf(".");
8845
+ const stem = dot === -1 ? base : base.slice(0, dot);
8846
+ if (base === `${stem}.meta.json`) return null;
8847
+ try {
8848
+ const raw = await fsp.readFile(join11(dir, `${stem}.meta.json`), "utf-8");
8849
+ const meta = JSON.parse(raw);
8850
+ const dn = meta.displayName ?? meta.filename;
8851
+ return typeof dn === "string" && dn.length > 0 ? dn : null;
8852
+ } catch {
8853
+ return null;
8854
+ }
8855
+ }
8856
+ async function walkSubtree(root, dataRoot, out) {
8857
+ let entries;
8858
+ try {
8859
+ entries = await fsp.readdir(root, { withFileTypes: true });
8860
+ } catch (err) {
8861
+ if (err.code === "ENOENT") return { clean: true };
8862
+ console.error(`[file-index] walk-error dir="${relative2(dataRoot, root)}" err="${err.message}"`);
8863
+ return { clean: false };
8864
+ }
8865
+ let clean = true;
8866
+ for (const entry of entries) {
8867
+ if (entry.isSymbolicLink()) continue;
8868
+ const abs = join11(root, entry.name);
8869
+ if (entry.isDirectory()) {
8870
+ const sub = await walkSubtree(abs, dataRoot, out);
8871
+ if (!sub.clean) clean = false;
8872
+ } else if (entry.isFile()) {
8873
+ try {
8874
+ const st = await fsp.stat(abs);
8875
+ out.push({
8876
+ absolute: abs,
8877
+ relativePath: relative2(dataRoot, abs).split(sep3).join("/"),
8878
+ sizeBytes: st.size,
8879
+ modifiedAt: st.mtime.toISOString()
8880
+ });
8881
+ } catch (err) {
8882
+ console.error(`[file-index] stat-error path="${relative2(dataRoot, abs)}" err="${err.message}"`);
8883
+ clean = false;
8884
+ }
8885
+ }
8886
+ }
8887
+ return { clean };
8888
+ }
8889
+ async function upsertFileArtifact(session, f) {
8890
+ await session.run(
8891
+ `MERGE (f:FileArtifact {accountId: $accountId, relativePath: $relativePath})
8892
+ SET f.name = $name,
8893
+ f.displayName = $displayName,
8894
+ f.mimeType = $mimeType,
8895
+ f.sizeBytes = $sizeBytes,
8896
+ f.modifiedAt = $modifiedAt,
8897
+ f.content = $content,
8898
+ f.embedding = $embedding`,
8899
+ f
8900
+ );
8901
+ }
8902
+ async function buildArtifact(accountId, wf, embed2) {
8903
+ const name = basename3(wf.absolute);
8904
+ const content = await extractFileContent(wf.absolute);
8905
+ const displayName = await readDisplayName(wf.absolute);
8906
+ const embedInput = `${name}
8907
+ ${content}`.slice(0, CONTENT_CAP);
8908
+ let embedding = null;
8909
+ const embedStart = Date.now();
8910
+ try {
8911
+ embedding = await embed2(embedInput);
8912
+ } catch (err) {
8913
+ console.error(`[file-index] embed-failed path="${wf.relativePath}" err="${err.message}"`);
8914
+ }
8915
+ console.error(
8916
+ `[file-index] index-file account=${accountId} path="${wf.relativePath}" chars=${content.length} embed-ms=${Date.now() - embedStart}`
8917
+ );
8918
+ return {
8919
+ accountId,
8920
+ relativePath: wf.relativePath,
8921
+ name,
8922
+ displayName,
8923
+ mimeType: mimeForExt(extname2(wf.absolute)),
8924
+ sizeBytes: wf.sizeBytes,
8925
+ modifiedAt: wf.modifiedAt,
8926
+ content,
8927
+ embedding
8928
+ };
8929
+ }
8930
+ async function withSession(opts, fn) {
8931
+ if (opts?.session) return fn(opts.session);
8932
+ const session = getSession();
8933
+ try {
8934
+ return await fn(session);
8935
+ } finally {
8936
+ await session.close();
8937
+ }
8938
+ }
8939
+ async function reconcileFileIndex(accountId, opts) {
8940
+ const dataRoot = opts?.dataRoot ?? DATA_ROOT;
8941
+ const embed2 = opts?.embed ?? embed;
8942
+ const t0 = Date.now();
8943
+ return withSession(opts, async (session) => {
8944
+ const walked = [];
8945
+ const subtreeRoots = [
8946
+ resolve13(dataRoot, "uploads", accountId),
8947
+ resolve13(dataRoot, "accounts", accountId)
8948
+ ];
8949
+ let clean = true;
8950
+ for (const root of subtreeRoots) {
8951
+ const r = await walkSubtree(root, dataRoot, walked);
8952
+ if (!r.clean) clean = false;
8953
+ }
8954
+ const existing = /* @__PURE__ */ new Map();
8955
+ const existingRes = await session.run(
8956
+ `MATCH (f:FileArtifact {accountId: $accountId})
8957
+ RETURN f.relativePath AS relativePath, f.sizeBytes AS sizeBytes,
8958
+ f.modifiedAt AS modifiedAt, f.embedding IS NOT NULL AS hasEmbedding`,
8959
+ { accountId }
8960
+ );
8961
+ for (const rec of existingRes.records) {
8962
+ existing.set(rec.get("relativePath"), {
8963
+ sizeBytes: typeof rec.get("sizeBytes")?.toNumber === "function" ? rec.get("sizeBytes").toNumber() : Number(rec.get("sizeBytes")),
8964
+ modifiedAt: rec.get("modifiedAt"),
8965
+ hasEmbedding: rec.get("hasEmbedding") === true
8966
+ });
8967
+ }
8968
+ let upserted = 0;
8969
+ let skipped = 0;
8970
+ for (const wf of walked) {
8971
+ const prior = existing.get(wf.relativePath);
8972
+ const unchanged = prior && prior.sizeBytes === wf.sizeBytes && prior.modifiedAt === wf.modifiedAt && prior.hasEmbedding;
8973
+ if (unchanged) {
8974
+ skipped++;
8975
+ continue;
8976
+ }
8977
+ await upsertFileArtifact(session, await buildArtifact(accountId, wf, embed2));
8978
+ upserted++;
8979
+ }
8980
+ let pruned = 0;
8981
+ if (clean) {
8982
+ const foundPaths = walked.map((w) => w.relativePath);
8983
+ const pruneRes = await session.run(
8984
+ `MATCH (f:FileArtifact {accountId: $accountId})
8985
+ WHERE NOT f.relativePath IN $foundPaths
8986
+ DETACH DELETE f
8987
+ RETURN count(f) AS pruned`,
8988
+ { accountId, foundPaths }
8989
+ );
8990
+ const c = pruneRes.records[0]?.get("pruned");
8991
+ pruned = typeof c?.toNumber === "function" ? c.toNumber() : Number(c ?? 0);
8992
+ }
8993
+ console.error(
8994
+ `[file-index] reconcile account=${accountId} walked=${walked.length} upserted=${upserted} skipped=${skipped} pruned=${pruned} clean=${clean} ms=${Date.now() - t0}`
8995
+ );
8996
+ return { walked: walked.length, upserted, skipped, pruned };
8997
+ });
8998
+ }
8999
+ async function reconcileFileIndexDebounced(accountId, opts) {
9000
+ const now = Date.now();
9001
+ const last = lastReconcileAt.get(accountId) ?? 0;
9002
+ if (now - last < RECONCILE_DEBOUNCE_MS) return;
9003
+ lastReconcileAt.set(accountId, now);
9004
+ try {
9005
+ await reconcileFileIndex(accountId, opts);
9006
+ } catch (err) {
9007
+ console.error(`[file-index] reconcile-failed account=${accountId} err="${err.message}"`);
9008
+ }
9009
+ }
9010
+ async function indexFile(accountId, relativePath, opts) {
9011
+ const dataRoot = opts?.dataRoot ?? DATA_ROOT;
9012
+ const embed2 = opts?.embed ?? embed;
9013
+ const absolute = resolve13(dataRoot, relativePath);
9014
+ await withSession(opts, async (session) => {
9015
+ const st = await fsp.stat(absolute);
9016
+ const wf = {
9017
+ absolute,
9018
+ relativePath,
9019
+ sizeBytes: st.size,
9020
+ modifiedAt: st.mtime.toISOString()
9021
+ };
9022
+ await upsertFileArtifact(session, await buildArtifact(accountId, wf, embed2));
9023
+ });
9024
+ }
9025
+ async function dropFileIndex(accountId, relativePath, opts) {
9026
+ await withSession(opts, async (session) => {
9027
+ const res = await session.run(
9028
+ `MATCH (f:FileArtifact {accountId: $accountId, relativePath: $relativePath})
9029
+ DETACH DELETE f
9030
+ RETURN count(f) AS dropped`,
9031
+ { accountId, relativePath }
9032
+ );
9033
+ const c = res.records[0]?.get("dropped");
9034
+ const dropped = typeof c?.toNumber === "function" ? c.toNumber() : Number(c ?? 0);
9035
+ console.error(`[file-index] drop account=${accountId} path="${relativePath}" dropped=${dropped}`);
9036
+ });
9037
+ }
9038
+
8761
9039
  // server/routes/admin/files.ts
8762
9040
  var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
8763
9041
  async function readMeta(absDir, baseName) {
8764
9042
  try {
8765
- const raw = await readFile4(join11(absDir, `${baseName}.meta.json`), "utf8");
9043
+ const raw = await readFile4(join12(absDir, `${baseName}.meta.json`), "utf8");
8766
9044
  const parsed = JSON.parse(raw);
8767
9045
  if (typeof parsed?.filename === "string") {
8768
9046
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -8773,16 +9051,16 @@ async function readMeta(absDir, baseName) {
8773
9051
  }
8774
9052
  async function readAccountNames() {
8775
9053
  const map = /* @__PURE__ */ new Map();
8776
- const accountsDir = resolve13(DATA_ROOT, "accounts");
9054
+ const accountsDir = resolve14(DATA_ROOT, "accounts");
8777
9055
  let names;
8778
9056
  try {
8779
- names = await readdir2(accountsDir);
9057
+ names = await readdir3(accountsDir);
8780
9058
  } catch {
8781
9059
  return map;
8782
9060
  }
8783
9061
  for (const name of names) {
8784
9062
  if (!UUID_RE3.test(name)) continue;
8785
- const configPath2 = resolve13(accountsDir, name, "account.json");
9063
+ const configPath2 = resolve14(accountsDir, name, "account.json");
8786
9064
  try {
8787
9065
  const raw = await readFile4(configPath2, "utf8");
8788
9066
  const parsed = JSON.parse(raw);
@@ -8800,7 +9078,7 @@ async function readAccountNames() {
8800
9078
  }
8801
9079
  async function enrich(absolute, entry, accountNames) {
8802
9080
  if (entry.kind === "directory" && UUID_RE3.test(entry.name)) {
8803
- const meta = await readMeta(join11(absolute, entry.name), entry.name);
9081
+ const meta = await readMeta(join12(absolute, entry.name), entry.name);
8804
9082
  if (meta?.filename) {
8805
9083
  entry.displayName = meta.filename;
8806
9084
  entry.mimeType = meta.mimeType;
@@ -8852,14 +9130,14 @@ app15.get("/", requireAdminSession, async (c) => {
8852
9130
  if (!info.isDirectory()) {
8853
9131
  return c.json({ error: "Path is not a directory \u2014 use /api/admin/files/download for files" }, 400);
8854
9132
  }
8855
- const names = await readdir2(absolute);
9133
+ const names = await readdir3(absolute);
8856
9134
  const entries = [];
8857
9135
  for (const name of names) {
8858
9136
  if (UUID_RE3.test(name.replace(/\.meta\.json$/, "")) && name.endsWith(".meta.json")) {
8859
9137
  continue;
8860
9138
  }
8861
9139
  try {
8862
- const entryPath = join11(absolute, name);
9140
+ const entryPath = join12(absolute, name);
8863
9141
  const s = await stat4(entryPath);
8864
9142
  entries.push({
8865
9143
  name,
@@ -8895,7 +9173,8 @@ app15.get("/", requireAdminSession, async (c) => {
8895
9173
  });
8896
9174
  app15.get("/download", requireAdminSession, async (c) => {
8897
9175
  const cacheKey = c.var.cacheKey;
8898
- if (!getAccountIdForSession(cacheKey)) {
9176
+ const accountId = getAccountIdForSession(cacheKey);
9177
+ if (!accountId) {
8899
9178
  console.error(`[data] auth-rejected endpoint="/api/admin/files/download" reason="no account for session"`);
8900
9179
  return c.json({ error: "Account not found for session" }, 401);
8901
9180
  }
@@ -8909,6 +9188,10 @@ app15.get("/download", requireAdminSession, async (c) => {
8909
9188
  return c.json({ error: resolution.error }, resolution.status);
8910
9189
  }
8911
9190
  const { absolute, relative: relPath2 } = resolution;
9191
+ if (crossesForeignAccountPartition(relPath2, accountId)) {
9192
+ console.error(`[data] account-scope-blocked endpoint="/api/admin/files/download" path="${relPath2}" account=${accountId.slice(0, 8)}\u2026`);
9193
+ return c.json({ error: "Not found" }, 404);
9194
+ }
8912
9195
  try {
8913
9196
  const info = await stat4(absolute);
8914
9197
  if (!info.isFile()) {
@@ -8973,13 +9256,13 @@ app15.post("/upload", requireAdminSession, async (c) => {
8973
9256
  }
8974
9257
  const safeName = basename4(file.name).replace(/[\0/\\]/g, "_");
8975
9258
  const finalName = `${Date.now()}-${safeName}`;
8976
- const destDir = resolve13(DATA_ROOT, "uploads", accountId);
8977
- const destPath = resolve13(destDir, finalName);
9259
+ const destDir = resolve14(DATA_ROOT, "uploads", accountId);
9260
+ const destPath = resolve14(destDir, finalName);
8978
9261
  try {
8979
9262
  await mkdir3(destDir, { recursive: true });
8980
9263
  const dataRootReal = realpathSync4(DATA_ROOT);
8981
9264
  const destDirReal = realpathSync4(destDir);
8982
- if (destDirReal !== dataRootReal && !destDirReal.startsWith(dataRootReal + sep3)) {
9265
+ if (destDirReal !== dataRootReal && !destDirReal.startsWith(dataRootReal + sep4)) {
8983
9266
  console.error(`[data] path-traversal-blocked requested="uploads/${accountId}" resolved="${destDirReal}"`);
8984
9267
  return c.json({ error: "Upload destination escapes DATA_ROOT" }, 403);
8985
9268
  }
@@ -8992,6 +9275,9 @@ app15.post("/upload", requireAdminSession, async (c) => {
8992
9275
  }
8993
9276
  const relativeDest = `uploads/${accountId}/${finalName}`;
8994
9277
  console.error(`[data] file-upload filename="${safeName}" size=${file.size} dest="${relativeDest}"`);
9278
+ void indexFile(accountId, relativeDest).catch((err) => {
9279
+ console.error(`[data] file-upload index-failed dest="${relativeDest}" err="${err instanceof Error ? err.message : String(err)}"`);
9280
+ });
8995
9281
  return c.json({
8996
9282
  path: relativeDest,
8997
9283
  filename: finalName,
@@ -9032,7 +9318,7 @@ app15.delete("/", requireAdminSession, async (c) => {
9032
9318
  }
9033
9319
  const dot = base.lastIndexOf(".");
9034
9320
  const stem = dot === -1 ? base : base.slice(0, dot);
9035
- const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join11(dirname3(absolute), `${stem}.meta.json`) : null;
9321
+ const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join12(dirname3(absolute), `${stem}.meta.json`) : null;
9036
9322
  await unlink2(absolute);
9037
9323
  if (sidecarPath) {
9038
9324
  try {
@@ -9041,6 +9327,11 @@ app15.delete("/", requireAdminSession, async (c) => {
9041
9327
  }
9042
9328
  }
9043
9329
  console.error(`[data] file-delete path="${relPath2}" bytes=${info.size}`);
9330
+ try {
9331
+ await dropFileIndex(accountId, relPath2);
9332
+ } catch (err) {
9333
+ console.error(`[data] file-delete index-drop-failed path="${relPath2}" err="${err instanceof Error ? err.message : String(err)}"`);
9334
+ }
9044
9335
  const parsed = parseAttachmentPath(relPath2);
9045
9336
  if (parsed) {
9046
9337
  try {
@@ -9860,6 +10151,9 @@ app16.get("/", requireAdminSession, async (c) => {
9860
10151
  }
9861
10152
  const wantsBodyFulltext = !wildcard && labels.some((l) => CONVERSATION_PARENT_LABELS.has(l));
9862
10153
  const forwardedLabels = wildcard ? void 0 : wantsBodyFulltext ? Array.from(/* @__PURE__ */ new Set([...labels, ...MESSAGE_FAMILY_LABELS])) : labels;
10154
+ if (labels.includes("FileArtifact")) {
10155
+ await reconcileFileIndexDebounced(accountId);
10156
+ }
9863
10157
  const started = Date.now();
9864
10158
  const session = getSession();
9865
10159
  try {
@@ -11064,43 +11358,38 @@ var WRITE_CYPHER = `
11064
11358
  `;
11065
11359
  var graph_default_view_default = app21;
11066
11360
 
11067
- // server/routes/admin/file-attach.ts
11068
- var app22 = new Hono();
11069
- app22.post("/", async (c) => {
11070
- try {
11071
- const body = await c.req.json();
11072
- const { filePath, accountId } = body;
11073
- if (!filePath || !accountId) {
11074
- return c.json({ error: "Missing required fields: filePath, accountId" }, 400);
11075
- }
11076
- const attachment = await storeGeneratedFile(accountId, filePath);
11077
- console.error(
11078
- `[admin:file-attach] stored path=${filePath} id=${attachment.attachmentId} filename=${JSON.stringify(attachment.filename)} size=${attachment.sizeBytes} mime=${attachment.mimeType}`
11079
- );
11080
- return c.json({
11081
- attachmentId: attachment.attachmentId,
11082
- filename: attachment.filename,
11083
- sizeBytes: attachment.sizeBytes,
11084
- mimeType: attachment.mimeType
11085
- });
11086
- } catch (err) {
11087
- const message = err instanceof Error ? err.message : String(err);
11088
- console.error(`[admin:file-attach] error: ${message}`);
11089
- return c.json({ error: message }, 500);
11090
- }
11091
- });
11092
- var file_attach_default = app22;
11093
-
11094
11361
  // server/routes/admin/sidebar-artefacts.ts
11095
11362
  import neo4j2 from "neo4j-driver";
11096
- import { readFile as readFile5, readdir as readdir3, stat as stat5 } from "fs/promises";
11097
- import { resolve as resolve14, relative as relative2, isAbsolute } from "path";
11363
+ import { readFile as readFile5, readdir as readdir4, stat as stat5 } from "fs/promises";
11364
+ import { resolve as resolve15, relative as relative3, isAbsolute, sep as sep5 } from "path";
11098
11365
  import { existsSync as existsSync16 } from "fs";
11099
11366
  var LIMIT = 50;
11100
11367
  var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
11101
11368
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
11102
- var app23 = new Hono();
11103
- app23.get("/", requireAdminSession, async (c) => {
11369
+ function toDataRootRelPath(absPath) {
11370
+ if (absPath !== DATA_ROOT && !absPath.startsWith(DATA_ROOT + sep5)) return null;
11371
+ return relative3(DATA_ROOT, absPath);
11372
+ }
11373
+ async function resolveDocAbsPath(accountId, attachmentId) {
11374
+ if (!attachmentId) return null;
11375
+ const accountDir = resolve15(ATTACHMENTS_ROOT, accountId);
11376
+ const dir = resolve15(accountDir, attachmentId);
11377
+ try {
11378
+ validateFilePathInAccount(dir, accountDir);
11379
+ } catch {
11380
+ return null;
11381
+ }
11382
+ try {
11383
+ const entries = await readdir4(dir);
11384
+ const dataFile = entries.find((f) => !f.endsWith(".meta.json"));
11385
+ if (!dataFile) return null;
11386
+ return resolve15(dir, dataFile);
11387
+ } catch {
11388
+ return null;
11389
+ }
11390
+ }
11391
+ var app22 = new Hono();
11392
+ app22.get("/", requireAdminSession, async (c) => {
11104
11393
  const cacheKey = c.var.cacheKey;
11105
11394
  const accountId = getAccountIdForSession(cacheKey);
11106
11395
  if (!accountId) {
@@ -11111,7 +11400,7 @@ app23.get("/", requireAdminSession, async (c) => {
11111
11400
  if (docs === null) {
11112
11401
  return c.json({ error: "Failed to load artefacts" }, 500);
11113
11402
  }
11114
- const accountDir = resolve14(ACCOUNTS_DIR, accountId);
11403
+ const accountDir = resolve15(ACCOUNTS_DIR, accountId);
11115
11404
  const agents = await fetchAgentTemplateRows(accountDir);
11116
11405
  const artefacts = [...docs, ...agents].sort(
11117
11406
  (a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "")
@@ -11152,6 +11441,7 @@ async function fetchKnowledgeDocs(accountId) {
11152
11441
  }
11153
11442
  return Promise.all(metas.map(async (m) => {
11154
11443
  const { content, skipReason } = await readArtefactContent(accountId, m.attachmentId, m.mimeType, m.name);
11444
+ const absPath = await resolveDocAbsPath(accountId, m.attachmentId);
11155
11445
  return {
11156
11446
  id: m.id,
11157
11447
  name: m.name,
@@ -11160,7 +11450,8 @@ async function fetchKnowledgeDocs(accountId) {
11160
11450
  content,
11161
11451
  editable: skipReason === null,
11162
11452
  mimeType: m.mimeType,
11163
- skipReason
11453
+ skipReason,
11454
+ downloadPath: absPath ? toDataRootRelPath(absPath) : null
11164
11455
  };
11165
11456
  }));
11166
11457
  }
@@ -11174,8 +11465,8 @@ async function readArtefactContent(accountId, attachmentId, mimeType, displayNam
11174
11465
  logSkip(displayName, "non-text-mime", mimeType);
11175
11466
  return { content: "", skipReason: "non-text-mime" };
11176
11467
  }
11177
- const accountDir = resolve14(ATTACHMENTS_ROOT, accountId);
11178
- const dir = resolve14(accountDir, attachmentId);
11468
+ const accountDir = resolve15(ATTACHMENTS_ROOT, accountId);
11469
+ const dir = resolve15(accountDir, attachmentId);
11179
11470
  try {
11180
11471
  validateFilePathInAccount(dir, accountDir);
11181
11472
  } catch {
@@ -11183,13 +11474,13 @@ async function readArtefactContent(accountId, attachmentId, mimeType, displayNam
11183
11474
  return { content: "", skipReason: "containment-rejected" };
11184
11475
  }
11185
11476
  try {
11186
- const entries = await readdir3(dir);
11477
+ const entries = await readdir4(dir);
11187
11478
  const dataFile = entries.find((f) => !f.endsWith(".meta.json"));
11188
11479
  if (!dataFile) {
11189
11480
  logSkip(displayName, "missing-on-disk", mimeType);
11190
11481
  return { content: "", skipReason: "missing-on-disk" };
11191
11482
  }
11192
- return { content: await readFile5(resolve14(dir, dataFile), "utf-8"), skipReason: null };
11483
+ return { content: await readFile5(resolve15(dir, dataFile), "utf-8"), skipReason: null };
11193
11484
  } catch (err) {
11194
11485
  const message = err instanceof Error ? err.message : String(err);
11195
11486
  console.error(`[admin/sidebar-artefacts] read-failed attachmentId=${attachmentId.slice(0, 8)} error="${message}"`);
@@ -11205,8 +11496,8 @@ function logSkip(name, reason, mimeType) {
11205
11496
  async function fetchAgentTemplateRows(accountDir) {
11206
11497
  const rows = [];
11207
11498
  for (const filename of ADMIN_AGENT_FILES) {
11208
- const overridePath = resolve14(accountDir, "agents", "admin", filename);
11209
- const bundledPath = resolve14(PLATFORM_ROOT, "templates", "agents", "admin", filename);
11499
+ const overridePath = resolve15(accountDir, "agents", "admin", filename);
11500
+ const bundledPath = resolve15(PLATFORM_ROOT, "templates", "agents", "admin", filename);
11210
11501
  const labelStem = filename.replace(/\.md$/, "");
11211
11502
  const row = await readAgentTemplateRow({
11212
11503
  id: `agent-template:admin:${filename}`,
@@ -11220,12 +11511,12 @@ async function fetchAgentTemplateRows(accountDir) {
11220
11511
  });
11221
11512
  if (row) rows.push(row);
11222
11513
  }
11223
- const overrideDir = resolve14(accountDir, "specialists", "agents");
11224
- const bundledDir = resolve14(PLATFORM_ROOT, "templates", "specialists", "agents");
11514
+ const overrideDir = resolve15(accountDir, "specialists", "agents");
11515
+ const bundledDir = resolve15(PLATFORM_ROOT, "templates", "specialists", "agents");
11225
11516
  const specialistNames = await unionSpecialistFilenames(overrideDir, bundledDir);
11226
11517
  for (const filename of specialistNames) {
11227
- const overridePath = resolve14(overrideDir, filename);
11228
- const bundledPath = resolve14(bundledDir, filename);
11518
+ const overridePath = resolve15(overrideDir, filename);
11519
+ const bundledPath = resolve15(bundledDir, filename);
11229
11520
  const row = await readAgentTemplateRow({
11230
11521
  id: `agent-template:specialist:${filename}`,
11231
11522
  displayName: filename.replace(/\.md$/, ""),
@@ -11245,7 +11536,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
11245
11536
  for (const dir of [overrideDir, bundledDir]) {
11246
11537
  if (!existsSync16(dir)) continue;
11247
11538
  try {
11248
- const entries = await readdir3(dir);
11539
+ const entries = await readdir4(dir);
11249
11540
  for (const entry of entries) {
11250
11541
  if (entry.endsWith(".md")) names.add(entry);
11251
11542
  }
@@ -11292,7 +11583,11 @@ async function readAgentTemplateRow(inp) {
11292
11583
  content,
11293
11584
  editable: inp.editable,
11294
11585
  mimeType: "text/markdown",
11295
- skipReason: null
11586
+ skipReason: null,
11587
+ // Override paths live under <accountDir> (inside DATA_ROOT) and are
11588
+ // downloadable; bundled-fallback templates live under PLATFORM_ROOT
11589
+ // (outside DATA_ROOT) → null, so the client shows "not downloadable".
11590
+ downloadPath: toDataRootRelPath(chosenPath)
11296
11591
  };
11297
11592
  } catch (err) {
11298
11593
  const message = err instanceof Error ? err.message : String(err);
@@ -11303,19 +11598,19 @@ async function readAgentTemplateRow(inp) {
11303
11598
  }
11304
11599
  }
11305
11600
  function isWithin(target, root) {
11306
- const rel = relative2(root, target);
11601
+ const rel = relative3(root, target);
11307
11602
  return !rel.startsWith("..") && !isAbsolute(rel);
11308
11603
  }
11309
- var sidebar_artefacts_default = app23;
11604
+ var sidebar_artefacts_default = app22;
11310
11605
 
11311
11606
  // server/routes/admin/sidebar-artefact-save.ts
11312
- import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
11313
- import { resolve as resolve15 } from "path";
11607
+ import { mkdir as mkdir4, readdir as readdir5, stat as stat6, writeFile as writeFile5 } from "fs/promises";
11608
+ import { resolve as resolve16 } from "path";
11314
11609
  import { existsSync as existsSync17 } from "fs";
11315
11610
  var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
11316
11611
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
11317
- var app24 = new Hono();
11318
- app24.post("/", requireAdminSession, async (c) => {
11612
+ var app23 = new Hono();
11613
+ app23.post("/", requireAdminSession, async (c) => {
11319
11614
  const cacheKey = c.var.cacheKey;
11320
11615
  const accountId = getAccountIdForSession(cacheKey);
11321
11616
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -11323,7 +11618,7 @@ app24.post("/", requireAdminSession, async (c) => {
11323
11618
  if (!body || typeof body.id !== "string" || typeof body.content !== "string") {
11324
11619
  return c.json({ error: "id and content required" }, 400);
11325
11620
  }
11326
- const accountDir = resolve15(ACCOUNTS_DIR, accountId);
11621
+ const accountDir = resolve16(ACCOUNTS_DIR, accountId);
11327
11622
  const resolved = await resolveSavePath(body.id, accountId, accountDir);
11328
11623
  if (resolved.kind === "heal-race") {
11329
11624
  c.header("Retry-After", "2");
@@ -11368,17 +11663,17 @@ async function resolveSavePath(id, accountId, accountDir) {
11368
11663
  if (role !== "admin" || !ADMIN_AGENT_FILES2.has(filename)) {
11369
11664
  return { kind: "reject", status: 400, reason: "invalid-id" };
11370
11665
  }
11371
- const parent = resolve15(accountDir, "agents", "admin");
11666
+ const parent = resolve16(accountDir, "agents", "admin");
11372
11667
  await mkdir4(parent, { recursive: true });
11373
11668
  try {
11374
11669
  validateFilePathInAccount(parent, accountDir);
11375
11670
  } catch {
11376
11671
  return { kind: "reject", status: 400, reason: "containment-rejected" };
11377
11672
  }
11378
- return { kind: "admin-template", path: resolve15(parent, filename) };
11673
+ return { kind: "admin-template", path: resolve16(parent, filename) };
11379
11674
  }
11380
11675
  if (UUID_RE4.test(id)) {
11381
- const dir = resolve15(ATTACHMENTS_ROOT, accountId, id);
11676
+ const dir = resolve16(ATTACHMENTS_ROOT, accountId, id);
11382
11677
  if (!existsSync17(dir)) {
11383
11678
  const attShort = id.slice(0, 8);
11384
11679
  if (isHealPending(accountId, id)) {
@@ -11411,31 +11706,31 @@ async function resolveSavePath(id, accountId, accountDir) {
11411
11706
  }
11412
11707
  }
11413
11708
  try {
11414
- validateFilePathInAccount(dir, resolve15(ATTACHMENTS_ROOT, accountId));
11709
+ validateFilePathInAccount(dir, resolve16(ATTACHMENTS_ROOT, accountId));
11415
11710
  } catch {
11416
11711
  return { kind: "reject", status: 400, reason: "containment-rejected" };
11417
11712
  }
11418
- const entries = await readdir4(dir);
11713
+ const entries = await readdir5(dir);
11419
11714
  const dataFile = entries.find((f) => !f.endsWith(".meta.json"));
11420
11715
  if (!dataFile) {
11421
11716
  return { kind: "reject", status: 400, reason: "not-found" };
11422
11717
  }
11423
- return { kind: "knowledge-doc", path: resolve15(dir, dataFile) };
11718
+ return { kind: "knowledge-doc", path: resolve16(dir, dataFile) };
11424
11719
  }
11425
11720
  return { kind: "reject", status: 400, reason: "invalid-id" };
11426
11721
  }
11427
11722
  function relPath(absPath, root) {
11428
11723
  return absPath.startsWith(root) ? absPath.slice(root.length + 1) : absPath;
11429
11724
  }
11430
- var sidebar_artefact_save_default = app24;
11725
+ var sidebar_artefact_save_default = app23;
11431
11726
 
11432
11727
  // server/routes/admin/sidebar-artefact-content.ts
11433
- import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
11728
+ import { readFile as readFile6, readdir as readdir6 } from "fs/promises";
11434
11729
  import { existsSync as existsSync18 } from "fs";
11435
- import { resolve as resolve16 } from "path";
11730
+ import { resolve as resolve17 } from "path";
11436
11731
  var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
11437
- var app25 = new Hono();
11438
- app25.get("/", requireAdminSession, async (c) => {
11732
+ var app24 = new Hono();
11733
+ app24.get("/", requireAdminSession, async (c) => {
11439
11734
  const cacheKey = c.var.cacheKey;
11440
11735
  const accountId = getAccountIdForSession(cacheKey);
11441
11736
  if (!accountId) return new Response("Unauthorized", { status: 401 });
@@ -11444,26 +11739,26 @@ app25.get("/", requireAdminSession, async (c) => {
11444
11739
  console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
11445
11740
  return new Response("Not found", { status: 404 });
11446
11741
  }
11447
- const dir = resolve16(ATTACHMENTS_ROOT, accountId, id);
11742
+ const dir = resolve17(ATTACHMENTS_ROOT, accountId, id);
11448
11743
  if (!existsSync18(dir)) {
11449
11744
  console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
11450
11745
  return new Response("Not found", { status: 404 });
11451
11746
  }
11452
11747
  let meta;
11453
11748
  try {
11454
- meta = JSON.parse(await readFile6(resolve16(dir, `${id}.meta.json`), "utf-8"));
11749
+ meta = JSON.parse(await readFile6(resolve17(dir, `${id}.meta.json`), "utf-8"));
11455
11750
  } catch {
11456
11751
  console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
11457
11752
  return new Response("Not found", { status: 404 });
11458
11753
  }
11459
- const entries = await readdir5(dir);
11754
+ const entries = await readdir6(dir);
11460
11755
  const dataFile = entries.find((f) => !f.endsWith(".meta.json"));
11461
11756
  if (!dataFile) {
11462
11757
  console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
11463
11758
  return new Response("Not found", { status: 404 });
11464
11759
  }
11465
11760
  const start = Date.now();
11466
- const buffer = await readFile6(resolve16(dir, dataFile));
11761
+ const buffer = await readFile6(resolve17(dir, dataFile));
11467
11762
  const ms = Date.now() - start;
11468
11763
  console.log(
11469
11764
  `[admin/sidebar-artefact-content] account=${accountId} id=${id.slice(0, 8)} mime=${meta.mimeType} bytes=${buffer.length} ms=${ms}`
@@ -11476,7 +11771,7 @@ app25.get("/", requireAdminSession, async (c) => {
11476
11771
  }
11477
11772
  });
11478
11773
  });
11479
- var sidebar_artefact_content_default = app25;
11774
+ var sidebar_artefact_content_default = app24;
11480
11775
 
11481
11776
  // server/routes/admin/system-stats.ts
11482
11777
  import { readFile as readFile7 } from "fs/promises";
@@ -11573,8 +11868,8 @@ async function sample() {
11573
11868
  if (process.platform === "linux") return sampleLinux();
11574
11869
  return sampleOsFallback();
11575
11870
  }
11576
- var app26 = new Hono();
11577
- app26.get("/", async (c) => {
11871
+ var app25 = new Hono();
11872
+ app25.get("/", async (c) => {
11578
11873
  const started = Date.now();
11579
11874
  if (!inflight) {
11580
11875
  inflight = sample().finally(() => {
@@ -11597,14 +11892,14 @@ app26.get("/", async (c) => {
11597
11892
  return c.json({ degraded: true, reason, sampledAtMs: Date.now() });
11598
11893
  }
11599
11894
  });
11600
- var system_stats_default = app26;
11895
+ var system_stats_default = app25;
11601
11896
 
11602
11897
  // server/routes/admin/health.ts
11603
11898
  import { existsSync as existsSync19, readFileSync as readFileSync14 } from "fs";
11604
- import { resolve as resolve17, join as join12 } from "path";
11605
- var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve17(process.cwd(), "..");
11899
+ import { resolve as resolve18, join as join13 } from "path";
11900
+ var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve18(process.cwd(), "..");
11606
11901
  var brandHostname = "maxy";
11607
- var brandJsonPath = join12(PLATFORM_ROOT6, "config", "brand.json");
11902
+ var brandJsonPath = join13(PLATFORM_ROOT6, "config", "brand.json");
11608
11903
  if (existsSync19(brandJsonPath)) {
11609
11904
  try {
11610
11905
  const brand = JSON.parse(readFileSync14(brandJsonPath, "utf-8"));
@@ -11612,7 +11907,7 @@ if (existsSync19(brandJsonPath)) {
11612
11907
  } catch {
11613
11908
  }
11614
11909
  }
11615
- var VERSION_FILE = resolve17(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
11910
+ var VERSION_FILE = resolve18(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
11616
11911
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
11617
11912
  var PROBE_TIMEOUT_MS = 1e3;
11618
11913
  function readVersion() {
@@ -11642,8 +11937,8 @@ async function probeConversationDb() {
11642
11937
  });
11643
11938
  }
11644
11939
  }
11645
- var app27 = new Hono();
11646
- app27.get("/", async (c) => {
11940
+ var app26 = new Hono();
11941
+ app26.get("/", async (c) => {
11647
11942
  const version = readVersion();
11648
11943
  const probe = await probeConversationDb();
11649
11944
  const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
@@ -11665,7 +11960,7 @@ app27.get("/", async (c) => {
11665
11960
  uptimeMs
11666
11961
  });
11667
11962
  });
11668
- var health_default2 = app27;
11963
+ var health_default2 = app26;
11669
11964
 
11670
11965
  // server/routes/admin/linkedin-ingest.ts
11671
11966
  var TAG20 = "[linkedin-ingest-route]";
@@ -11761,8 +12056,8 @@ function buildInitialMessage(env) {
11761
12056
  }
11762
12057
  return header;
11763
12058
  }
11764
- var app28 = new Hono();
11765
- app28.post("/", requireAdminSession, async (c) => {
12059
+ var app27 = new Hono();
12060
+ app27.post("/", requireAdminSession, async (c) => {
11766
12061
  let body;
11767
12062
  try {
11768
12063
  body = await c.req.json();
@@ -11816,7 +12111,7 @@ app28.post("/", requireAdminSession, async (c) => {
11816
12111
  );
11817
12112
  return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: claudeSessionId }, 202);
11818
12113
  });
11819
- var linkedin_ingest_default = app28;
12114
+ var linkedin_ingest_default = app27;
11820
12115
 
11821
12116
  // server/routes/admin/post-turn-context.ts
11822
12117
  import neo4j3 from "neo4j-driver";
@@ -11858,8 +12153,8 @@ function pruneProperties(raw) {
11858
12153
  }
11859
12154
  return out;
11860
12155
  }
11861
- var app29 = new Hono();
11862
- app29.get("/", async (c) => {
12156
+ var app28 = new Hono();
12157
+ app28.get("/", async (c) => {
11863
12158
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
11864
12159
  if (!isLoopbackAddr2(remoteAddr)) {
11865
12160
  console.error(`${TAG21} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -11919,7 +12214,7 @@ app29.get("/", async (c) => {
11919
12214
  await session.close();
11920
12215
  }
11921
12216
  });
11922
- var post_turn_context_default = app29;
12217
+ var post_turn_context_default = app28;
11923
12218
 
11924
12219
  // server/routes/admin/public-session-context.ts
11925
12220
  import neo4j4 from "neo4j-driver";
@@ -11961,8 +12256,8 @@ function pruneProperties2(raw) {
11961
12256
  }
11962
12257
  return out;
11963
12258
  }
11964
- var app30 = new Hono();
11965
- app30.get("/", async (c) => {
12259
+ var app29 = new Hono();
12260
+ app29.get("/", async (c) => {
11966
12261
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
11967
12262
  if (!isLoopbackAddr3(remoteAddr)) {
11968
12263
  console.error(`${TAG22} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -12021,15 +12316,15 @@ app30.get("/", async (c) => {
12021
12316
  await session.close();
12022
12317
  }
12023
12318
  });
12024
- var public_session_context_default = app30;
12319
+ var public_session_context_default = app29;
12025
12320
 
12026
12321
  // server/routes/admin/public-session-exit.ts
12027
12322
  var TAG23 = "[public-session-exit-route]";
12028
12323
  function isLoopbackAddr4(addr) {
12029
12324
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
12030
12325
  }
12031
- var app31 = new Hono();
12032
- app31.post("/", async (c) => {
12326
+ var app30 = new Hono();
12327
+ app30.post("/", async (c) => {
12033
12328
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
12034
12329
  if (!isLoopbackAddr4(remoteAddr)) {
12035
12330
  console.error(`${TAG23} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -12056,15 +12351,15 @@ app31.post("/", async (c) => {
12056
12351
  handlePublicSessionExit(sessionId);
12057
12352
  return c.json({ ok: true });
12058
12353
  });
12059
- var public_session_exit_default = app31;
12354
+ var public_session_exit_default = app30;
12060
12355
 
12061
12356
  // server/routes/admin/access-session-evict.ts
12062
12357
  var TAG24 = "[access-session-evict]";
12063
12358
  function isLoopbackAddr5(addr) {
12064
12359
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
12065
12360
  }
12066
- var app32 = new Hono();
12067
- app32.post("/", async (c) => {
12361
+ var app31 = new Hono();
12362
+ app31.post("/", async (c) => {
12068
12363
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
12069
12364
  if (!isLoopbackAddr5(remoteAddr)) {
12070
12365
  console.error(`${TAG24} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -12092,49 +12387,48 @@ app32.post("/", async (c) => {
12092
12387
  console.log(`${TAG24} grantId=${grantId} dropped=${dropped}`);
12093
12388
  return c.json({ ok: true, dropped });
12094
12389
  });
12095
- var access_session_evict_default = app32;
12390
+ var access_session_evict_default = app31;
12096
12391
 
12097
12392
  // server/routes/admin/index.ts
12098
- var app33 = new Hono();
12099
- app33.route("/session", session_default);
12100
- app33.route("/logs", logs_default);
12101
- app33.route("/claude-info", claude_info_default);
12102
- app33.route("/attachment", attachment_default);
12103
- app33.route("/agents", agents_default);
12104
- app33.route("/sessions", sessions_default);
12105
- app33.route("/claude-sessions", claude_sessions_default);
12106
- app33.route("/log-ingest", log_ingest_default);
12107
- app33.route("/events", events_default);
12108
- app33.route("/files", files_default);
12109
- app33.route("/graph-search", graph_search_default);
12110
- app33.route("/graph-subgraph", graph_subgraph_default);
12111
- app33.route("/graph-delete", graph_delete_default);
12112
- app33.route("/graph-restore", graph_restore_default);
12113
- app33.route("/graph-labels-in-graph", graph_labels_in_graph_default);
12114
- app33.route("/graph-default-view", graph_default_view_default);
12115
- app33.route("/file-attach", file_attach_default);
12116
- app33.route("/sidebar-artefacts", sidebar_artefacts_default);
12117
- app33.route("/sidebar-artefact-save", sidebar_artefact_save_default);
12118
- app33.route("/sidebar-artefact-content", sidebar_artefact_content_default);
12119
- app33.route("/system-stats", system_stats_default);
12120
- app33.route("/health-brand", health_default2);
12121
- app33.route("/linkedin-ingest", linkedin_ingest_default);
12122
- app33.route("/post-turn-context", post_turn_context_default);
12123
- app33.route("/public-session-context", public_session_context_default);
12124
- app33.route("/public-session-exit", public_session_exit_default);
12125
- app33.route("/access-session-evict", access_session_evict_default);
12126
- var admin_default = app33;
12393
+ var app32 = new Hono();
12394
+ app32.route("/session", session_default);
12395
+ app32.route("/logs", logs_default);
12396
+ app32.route("/claude-info", claude_info_default);
12397
+ app32.route("/attachment", attachment_default);
12398
+ app32.route("/agents", agents_default);
12399
+ app32.route("/sessions", sessions_default);
12400
+ app32.route("/claude-sessions", claude_sessions_default);
12401
+ app32.route("/log-ingest", log_ingest_default);
12402
+ app32.route("/events", events_default);
12403
+ app32.route("/files", files_default);
12404
+ app32.route("/graph-search", graph_search_default);
12405
+ app32.route("/graph-subgraph", graph_subgraph_default);
12406
+ app32.route("/graph-delete", graph_delete_default);
12407
+ app32.route("/graph-restore", graph_restore_default);
12408
+ app32.route("/graph-labels-in-graph", graph_labels_in_graph_default);
12409
+ app32.route("/graph-default-view", graph_default_view_default);
12410
+ app32.route("/sidebar-artefacts", sidebar_artefacts_default);
12411
+ app32.route("/sidebar-artefact-save", sidebar_artefact_save_default);
12412
+ app32.route("/sidebar-artefact-content", sidebar_artefact_content_default);
12413
+ app32.route("/system-stats", system_stats_default);
12414
+ app32.route("/health-brand", health_default2);
12415
+ app32.route("/linkedin-ingest", linkedin_ingest_default);
12416
+ app32.route("/post-turn-context", post_turn_context_default);
12417
+ app32.route("/public-session-context", public_session_context_default);
12418
+ app32.route("/public-session-exit", public_session_exit_default);
12419
+ app32.route("/access-session-evict", access_session_evict_default);
12420
+ var admin_default = app32;
12127
12421
 
12128
12422
  // app/lib/access-gate.ts
12129
12423
  import neo4j5 from "neo4j-driver";
12130
12424
  import { readFileSync as readFileSync15 } from "fs";
12131
- import { resolve as resolve18 } from "path";
12425
+ import { resolve as resolve19 } from "path";
12132
12426
  import { randomUUID as randomUUID8 } from "crypto";
12133
- var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve18(process.cwd(), "..");
12427
+ var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve19(process.cwd(), "..");
12134
12428
  var driver = null;
12135
12429
  function readPassword() {
12136
12430
  if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
12137
- const passwordFile = resolve18(PLATFORM_ROOT7, "config/.neo4j-password");
12431
+ const passwordFile = resolve19(PLATFORM_ROOT7, "config/.neo4j-password");
12138
12432
  try {
12139
12433
  return readFileSync15(passwordFile, "utf-8").trim();
12140
12434
  } catch {
@@ -12337,8 +12631,8 @@ async function generateNewMagicToken(grantId) {
12337
12631
  var TAG25 = "[access-verify]";
12338
12632
  var MINT_TAG = "[access-session-mint]";
12339
12633
  var COOKIE_NAME = "__access_session";
12340
- var app34 = new Hono();
12341
- app34.post("/", async (c) => {
12634
+ var app33 = new Hono();
12635
+ app33.post("/", async (c) => {
12342
12636
  const ip = c.var.clientIp || "unknown";
12343
12637
  let body;
12344
12638
  try {
@@ -12420,13 +12714,13 @@ app34.post("/", async (c) => {
12420
12714
  displayName: grant.displayName
12421
12715
  });
12422
12716
  });
12423
- var verify_token_default = app34;
12717
+ var verify_token_default = app33;
12424
12718
 
12425
12719
  // app/lib/access-email.ts
12426
12720
  import { spawn as spawn2 } from "child_process";
12427
- import { resolve as resolve19 } from "path";
12428
- var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT ?? resolve19(process.cwd(), "..");
12429
- var SEND_SCRIPT = resolve19(
12721
+ import { resolve as resolve20 } from "path";
12722
+ var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
12723
+ var SEND_SCRIPT = resolve20(
12430
12724
  PLATFORM_ROOT8,
12431
12725
  "plugins",
12432
12726
  "email",
@@ -12483,9 +12777,9 @@ async function sendMagicLinkEmail(payload) {
12483
12777
 
12484
12778
  // server/routes/access/request-magic-link.ts
12485
12779
  var TAG26 = "[access-request-link]";
12486
- var app35 = new Hono();
12780
+ var app34 = new Hono();
12487
12781
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
12488
- app35.post("/", async (c) => {
12782
+ app34.post("/", async (c) => {
12489
12783
  let body;
12490
12784
  try {
12491
12785
  body = await c.req.json();
@@ -12559,17 +12853,17 @@ app35.post("/", async (c) => {
12559
12853
  );
12560
12854
  return c.json({ message: VISITOR_MESSAGE }, 200);
12561
12855
  });
12562
- var request_magic_link_default = app35;
12856
+ var request_magic_link_default = app34;
12563
12857
 
12564
12858
  // server/routes/access/index.ts
12565
- var app36 = new Hono();
12566
- app36.route("/verify-token", verify_token_default);
12567
- app36.route("/request-magic-link", request_magic_link_default);
12568
- var access_default = app36;
12859
+ var app35 = new Hono();
12860
+ app35.route("/verify-token", verify_token_default);
12861
+ app35.route("/request-magic-link", request_magic_link_default);
12862
+ var access_default = app35;
12569
12863
 
12570
12864
  // server/routes/sites.ts
12571
12865
  import { existsSync as existsSync20, readFileSync as readFileSync16, realpathSync as realpathSync5, statSync as statSync7 } from "fs";
12572
- import { resolve as resolve20 } from "path";
12866
+ import { resolve as resolve21 } from "path";
12573
12867
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
12574
12868
  var MIME = {
12575
12869
  ".html": "text/html; charset=utf-8",
@@ -12600,8 +12894,8 @@ function getExt(p) {
12600
12894
  if (idx < p.lastIndexOf("/")) return "";
12601
12895
  return p.slice(idx).toLowerCase();
12602
12896
  }
12603
- var app37 = new Hono();
12604
- app37.get("/:rel{.*}", (c) => {
12897
+ var app36 = new Hono();
12898
+ app36.get("/:rel{.*}", (c) => {
12605
12899
  const reqPath = c.req.path;
12606
12900
  const rawRel = c.req.param("rel") ?? "";
12607
12901
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -12626,8 +12920,8 @@ app37.get("/:rel{.*}", (c) => {
12626
12920
  }
12627
12921
  segments.push(seg);
12628
12922
  }
12629
- const rootDir = resolve20(account.accountDir, "sites");
12630
- let filePath = segments.length === 0 ? rootDir : resolve20(rootDir, ...segments);
12923
+ const rootDir = resolve21(account.accountDir, "sites");
12924
+ let filePath = segments.length === 0 ? rootDir : resolve21(rootDir, ...segments);
12631
12925
  if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
12632
12926
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
12633
12927
  return c.text("Forbidden", 403);
@@ -12647,7 +12941,7 @@ app37.get("/:rel{.*}", (c) => {
12647
12941
  return c.redirect(target, 301);
12648
12942
  }
12649
12943
  if (stat7?.isDirectory()) {
12650
- filePath = resolve20(filePath, "index.html");
12944
+ filePath = resolve21(filePath, "index.html");
12651
12945
  }
12652
12946
  if (!filePath.startsWith(rootDir + "/")) {
12653
12947
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
@@ -12704,7 +12998,7 @@ app37.get("/:rel{.*}", (c) => {
12704
12998
  "X-Content-Type-Options": "nosniff"
12705
12999
  });
12706
13000
  });
12707
- var sites_default = app37;
13001
+ var sites_default = app36;
12708
13002
 
12709
13003
  // app/lib/visitor-token.ts
12710
13004
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
@@ -12785,7 +13079,7 @@ var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
12785
13079
 
12786
13080
  // app/lib/brand-config.ts
12787
13081
  import { existsSync as existsSync21, readFileSync as readFileSync18 } from "fs";
12788
- import { join as join13 } from "path";
13082
+ import { join as join14 } from "path";
12789
13083
  var cached2 = null;
12790
13084
  var cachedAttempted = false;
12791
13085
  function readBrandConfig() {
@@ -12793,7 +13087,7 @@ function readBrandConfig() {
12793
13087
  cachedAttempted = true;
12794
13088
  const platformRoot = process.env.MAXY_PLATFORM_ROOT;
12795
13089
  if (!platformRoot) return null;
12796
- const brandPath = join13(platformRoot, "config", "brand.json");
13090
+ const brandPath = join14(platformRoot, "config", "brand.json");
12797
13091
  if (!existsSync21(brandPath)) return null;
12798
13092
  try {
12799
13093
  cached2 = JSON.parse(readFileSync18(brandPath, "utf-8"));
@@ -12804,7 +13098,7 @@ function readBrandConfig() {
12804
13098
  }
12805
13099
 
12806
13100
  // server/routes/visitor-consent.ts
12807
- var app38 = new Hono();
13101
+ var app37 = new Hono();
12808
13102
  var CONSENT_COOKIE_NAME = "mxy_consent";
12809
13103
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
12810
13104
  var DEFAULT_CONSENT_COPY = {
@@ -12849,17 +13143,17 @@ function siteSlugFromReferer(referer) {
12849
13143
  return "";
12850
13144
  }
12851
13145
  }
12852
- app38.options("/consent", (c) => {
13146
+ app37.options("/consent", (c) => {
12853
13147
  const origin = getOrigin(c);
12854
13148
  setCorsHeaders(c, origin);
12855
13149
  return c.body(null, 204);
12856
13150
  });
12857
- app38.options("/brand-config", (c) => {
13151
+ app37.options("/brand-config", (c) => {
12858
13152
  const origin = getOrigin(c);
12859
13153
  setCorsHeaders(c, origin);
12860
13154
  return c.body(null, 204);
12861
13155
  });
12862
- app38.post("/consent", async (c) => {
13156
+ app37.post("/consent", async (c) => {
12863
13157
  const origin = getOrigin(c);
12864
13158
  setCorsHeaders(c, origin);
12865
13159
  let raw;
@@ -12899,7 +13193,7 @@ app38.post("/consent", async (c) => {
12899
13193
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
12900
13194
  return c.body(null, 204);
12901
13195
  });
12902
- app38.get("/brand-config", (c) => {
13196
+ app37.get("/brand-config", (c) => {
12903
13197
  const origin = getOrigin(c);
12904
13198
  setCorsHeaders(c, origin);
12905
13199
  const brand = readBrandConfig();
@@ -12909,7 +13203,7 @@ app38.get("/brand-config", (c) => {
12909
13203
  c.header("Cache-Control", "public, max-age=300");
12910
13204
  return c.json({ consent: { copy, palette } });
12911
13205
  });
12912
- var visitor_consent_default = app38;
13206
+ var visitor_consent_default = app37;
12913
13207
 
12914
13208
  // server/routes/listings.ts
12915
13209
  function getCookie(headerValue, name) {
@@ -12930,14 +13224,14 @@ function appendConsentParams(pageUrl, token) {
12930
13224
  const hashIdx = pageUrl.indexOf("#");
12931
13225
  const hash = hashIdx >= 0 ? pageUrl.slice(hashIdx) : "";
12932
13226
  const base = hashIdx >= 0 ? pageUrl.slice(0, hashIdx) : pageUrl;
12933
- const sep4 = base.indexOf("?") >= 0 ? "&" : "?";
12934
- return base + sep4 + `consent=needed&v=${encodeURIComponent(token)}` + hash;
13227
+ const sep6 = base.indexOf("?") >= 0 ? "&" : "?";
13228
+ return base + sep6 + `consent=needed&v=${encodeURIComponent(token)}` + hash;
12935
13229
  }
12936
13230
  }
12937
13231
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
12938
13232
  var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
12939
- var app39 = new Hono();
12940
- app39.get("/:slug/click", async (c) => {
13233
+ var app38 = new Hono();
13234
+ app38.get("/:slug/click", async (c) => {
12941
13235
  const slug = c.req.param("slug") ?? "";
12942
13236
  const rawSession = c.req.query("session") ?? "";
12943
13237
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -13001,10 +13295,10 @@ app39.get("/:slug/click", async (c) => {
13001
13295
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
13002
13296
  return c.redirect(redirectUrl, 302);
13003
13297
  });
13004
- var listings_default = app39;
13298
+ var listings_default = app38;
13005
13299
 
13006
13300
  // server/routes/visitor-event.ts
13007
- var app40 = new Hono();
13301
+ var app39 = new Hono();
13008
13302
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
13009
13303
  var buckets = /* @__PURE__ */ new Map();
13010
13304
  var RATE_LIMIT = 60;
@@ -13071,12 +13365,12 @@ function originAllowed(origin, allowlist) {
13071
13365
  return false;
13072
13366
  }
13073
13367
  }
13074
- app40.options("/event", (c) => {
13368
+ app39.options("/event", (c) => {
13075
13369
  const origin = getOrigin2(c);
13076
13370
  setCorsHeaders2(c, origin);
13077
13371
  return c.body(null, 204);
13078
13372
  });
13079
- app40.post("/event", async (c) => {
13373
+ app39.post("/event", async (c) => {
13080
13374
  const origin = getOrigin2(c);
13081
13375
  setCorsHeaders2(c, origin);
13082
13376
  const ua = c.req.header("user-agent") ?? "";
@@ -13281,7 +13575,7 @@ async function writeEvent(opts) {
13281
13575
  );
13282
13576
  }
13283
13577
  }
13284
- var visitor_event_default = app40;
13578
+ var visitor_event_default = app39;
13285
13579
 
13286
13580
  // app/lib/graph-health.ts
13287
13581
  var HOUR_MS = 60 * 60 * 1e3;
@@ -13426,7 +13720,7 @@ function broadcastAdminShutdown(reason) {
13426
13720
  // ../lib/entitlement/src/index.ts
13427
13721
  import { createPublicKey, createHash as createHash4, verify as cryptoVerify } from "crypto";
13428
13722
  import { existsSync as existsSync22, readFileSync as readFileSync19, statSync as statSync8 } from "fs";
13429
- import { resolve as resolve21 } from "path";
13723
+ import { resolve as resolve22 } from "path";
13430
13724
 
13431
13725
  // ../lib/entitlement/src/canonicalize.ts
13432
13726
  function canonicalize(value) {
@@ -13461,7 +13755,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
13461
13755
  var GRACE_DAYS = 7;
13462
13756
  var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
13463
13757
  function pubkeyPath(brand) {
13464
- return resolve21(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
13758
+ return resolve22(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
13465
13759
  }
13466
13760
  var memo = null;
13467
13761
  function memoKey(mtimeMs, account) {
@@ -13473,7 +13767,7 @@ function resolveEntitlement(brand, account) {
13473
13767
  if (brand.commercialMode !== true) {
13474
13768
  return logResolved(implicitTrust(account), null);
13475
13769
  }
13476
- const entitlementPath = resolve21(brand.configDir, "entitlement.json");
13770
+ const entitlementPath = resolve22(brand.configDir, "entitlement.json");
13477
13771
  if (!existsSync22(entitlementPath)) {
13478
13772
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
13479
13773
  }
@@ -13664,7 +13958,7 @@ function clientFrom(c) {
13664
13958
  );
13665
13959
  }
13666
13960
  var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT || "";
13667
- var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join14(PLATFORM_ROOT9, "config", "brand.json") : "";
13961
+ var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join15(PLATFORM_ROOT9, "config", "brand.json") : "";
13668
13962
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
13669
13963
  if (BRAND_JSON_PATH && !existsSync23(BRAND_JSON_PATH)) {
13670
13964
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
@@ -13690,7 +13984,7 @@ var brandLoginOpts = {
13690
13984
  bodyFont: BRAND.defaultFonts?.body,
13691
13985
  logoContainsName: !!BRAND.logoContainsName
13692
13986
  };
13693
- var ALIAS_DOMAINS_PATH = join14(homedir2(), BRAND.configDir, "alias-domains.json");
13987
+ var ALIAS_DOMAINS_PATH = join15(homedir2(), BRAND.configDir, "alias-domains.json");
13694
13988
  function loadAliasDomains() {
13695
13989
  try {
13696
13990
  if (!existsSync23(ALIAS_DOMAINS_PATH)) return null;
@@ -13718,9 +14012,9 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
13718
14012
  function isPublicHost(host) {
13719
14013
  return host.startsWith("public.") || aliasDomains.has(host);
13720
14014
  }
13721
- var app41 = new Hono();
13722
- app41.use("*", clientIpMiddleware);
13723
- app41.use("*", async (c, next) => {
14015
+ var app40 = new Hono();
14016
+ app40.use("*", clientIpMiddleware);
14017
+ app40.use("*", async (c, next) => {
13724
14018
  await next();
13725
14019
  c.header("X-Content-Type-Options", "nosniff");
13726
14020
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
@@ -13730,7 +14024,7 @@ app41.use("*", async (c, next) => {
13730
14024
  );
13731
14025
  });
13732
14026
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
13733
- app41.use("*", async (c, next) => {
14027
+ app40.use("*", async (c, next) => {
13734
14028
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
13735
14029
  await next();
13736
14030
  return;
@@ -13763,7 +14057,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
13763
14057
  "/sites/"
13764
14058
  ];
13765
14059
  var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
13766
- app41.use("*", async (c, next) => {
14060
+ app40.use("*", async (c, next) => {
13767
14061
  const host = (c.req.header("host") ?? "").split(":")[0];
13768
14062
  if (!isPublicHost(host)) {
13769
14063
  await next();
@@ -13803,7 +14097,7 @@ function resolveRemoteAuthOpts() {
13803
14097
  return brandLoginOpts;
13804
14098
  }
13805
14099
  var MAX_LOGIN_BODY = 8 * 1024;
13806
- app41.post("/__remote-auth/login", async (c) => {
14100
+ app40.post("/__remote-auth/login", async (c) => {
13807
14101
  const client = clientFrom(c);
13808
14102
  const clientIp = client.ip || "unknown";
13809
14103
  if (!requestIsTlsTerminated(c)) {
@@ -13848,7 +14142,7 @@ app41.post("/__remote-auth/login", async (c) => {
13848
14142
  }
13849
14143
  });
13850
14144
  });
13851
- app41.get("/__remote-auth/logout", (c) => {
14145
+ app40.get("/__remote-auth/logout", (c) => {
13852
14146
  const client = clientFrom(c);
13853
14147
  const clientIp = client.ip || "unknown";
13854
14148
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -13861,7 +14155,7 @@ app41.get("/__remote-auth/logout", (c) => {
13861
14155
  }
13862
14156
  });
13863
14157
  });
13864
- app41.post("/__remote-auth/change-password", async (c) => {
14158
+ app40.post("/__remote-auth/change-password", async (c) => {
13865
14159
  const client = clientFrom(c);
13866
14160
  const clientIp = client.ip || "unknown";
13867
14161
  const rateLimited = checkRateLimit(client);
@@ -13912,13 +14206,13 @@ app41.post("/__remote-auth/change-password", async (c) => {
13912
14206
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
13913
14207
  }
13914
14208
  });
13915
- app41.get("/__remote-auth/setup", (c) => {
14209
+ app40.get("/__remote-auth/setup", (c) => {
13916
14210
  if (isRemoteAuthConfigured()) {
13917
14211
  return c.redirect("/");
13918
14212
  }
13919
14213
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
13920
14214
  });
13921
- app41.post("/__remote-auth/set-initial-password", async (c) => {
14215
+ app40.post("/__remote-auth/set-initial-password", async (c) => {
13922
14216
  if (isRemoteAuthConfigured()) {
13923
14217
  return c.redirect("/");
13924
14218
  }
@@ -13956,10 +14250,10 @@ app41.post("/__remote-auth/set-initial-password", async (c) => {
13956
14250
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
13957
14251
  }
13958
14252
  });
13959
- app41.get("/api/remote-auth/status", (c) => {
14253
+ app40.get("/api/remote-auth/status", (c) => {
13960
14254
  return c.json({ configured: isRemoteAuthConfigured() });
13961
14255
  });
13962
- app41.post("/api/remote-auth/set-password", async (c) => {
14256
+ app40.post("/api/remote-auth/set-password", async (c) => {
13963
14257
  let body;
13964
14258
  try {
13965
14259
  body = await c.req.json();
@@ -13990,9 +14284,9 @@ app41.post("/api/remote-auth/set-password", async (c) => {
13990
14284
  return c.json({ error: "Failed to save password" }, 500);
13991
14285
  }
13992
14286
  });
13993
- app41.route("/api/_client-error", client_error_default);
14287
+ app40.route("/api/_client-error", client_error_default);
13994
14288
  console.log("[client-error-route] mounted");
13995
- app41.use("*", async (c, next) => {
14289
+ app40.use("*", async (c, next) => {
13996
14290
  const host = (c.req.header("host") ?? "").split(":")[0];
13997
14291
  const path2 = c.req.path;
13998
14292
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
@@ -14025,12 +14319,12 @@ app41.use("*", async (c, next) => {
14025
14319
  console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
14026
14320
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
14027
14321
  });
14028
- app41.route("/api/health", health_default);
14029
- app41.route("/api/chat", chat_default);
14030
- app41.route("/api/whatsapp", whatsapp_default);
14031
- app41.route("/api/onboarding", onboarding_default);
14032
- app41.route("/api/admin", admin_default);
14033
- app41.route("/api/access", access_default);
14322
+ app40.route("/api/health", health_default);
14323
+ app40.route("/api/chat", chat_default);
14324
+ app40.route("/api/whatsapp", whatsapp_default);
14325
+ app40.route("/api/onboarding", onboarding_default);
14326
+ app40.route("/api/admin", admin_default);
14327
+ app40.route("/api/access", access_default);
14034
14328
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
14035
14329
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
14036
14330
  var IMAGE_MIME = {
@@ -14042,7 +14336,7 @@ var IMAGE_MIME = {
14042
14336
  ".svg": "image/svg+xml",
14043
14337
  ".ico": "image/x-icon"
14044
14338
  };
14045
- app41.get("/agent-assets/:slug/:filename", (c) => {
14339
+ app40.get("/agent-assets/:slug/:filename", (c) => {
14046
14340
  const slug = c.req.param("slug");
14047
14341
  const filename = c.req.param("filename");
14048
14342
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -14058,8 +14352,8 @@ app41.get("/agent-assets/:slug/:filename", (c) => {
14058
14352
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
14059
14353
  return c.text("Not found", 404);
14060
14354
  }
14061
- const filePath = resolve22(account.accountDir, "agents", slug, "assets", filename);
14062
- const expectedDir = resolve22(account.accountDir, "agents", slug, "assets");
14355
+ const filePath = resolve23(account.accountDir, "agents", slug, "assets", filename);
14356
+ const expectedDir = resolve23(account.accountDir, "agents", slug, "assets");
14063
14357
  if (!filePath.startsWith(expectedDir + "/")) {
14064
14358
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
14065
14359
  return c.text("Forbidden", 403);
@@ -14077,7 +14371,7 @@ app41.get("/agent-assets/:slug/:filename", (c) => {
14077
14371
  "Cache-Control": "public, max-age=3600"
14078
14372
  });
14079
14373
  });
14080
- app41.get("/generated/:filename", (c) => {
14374
+ app40.get("/generated/:filename", (c) => {
14081
14375
  const filename = c.req.param("filename");
14082
14376
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
14083
14377
  console.error(`[generated] serve file=${filename} status=403`);
@@ -14088,8 +14382,8 @@ app41.get("/generated/:filename", (c) => {
14088
14382
  console.error(`[generated] serve file=${filename} status=404`);
14089
14383
  return c.text("Not found", 404);
14090
14384
  }
14091
- const filePath = resolve22(account.accountDir, "generated", filename);
14092
- const expectedDir = resolve22(account.accountDir, "generated");
14385
+ const filePath = resolve23(account.accountDir, "generated", filename);
14386
+ const expectedDir = resolve23(account.accountDir, "generated");
14093
14387
  if (!filePath.startsWith(expectedDir + "/")) {
14094
14388
  console.error(`[generated] serve file=${filename} status=403`);
14095
14389
  return c.text("Forbidden", 403);
@@ -14107,10 +14401,10 @@ app41.get("/generated/:filename", (c) => {
14107
14401
  "Cache-Control": "public, max-age=86400"
14108
14402
  });
14109
14403
  });
14110
- app41.route("/sites", sites_default);
14111
- app41.route("/listings", listings_default);
14112
- app41.route("/v", visitor_event_default);
14113
- app41.route("/v", visitor_consent_default);
14404
+ app40.route("/sites", sites_default);
14405
+ app40.route("/listings", listings_default);
14406
+ app40.route("/v", visitor_event_default);
14407
+ app40.route("/v", visitor_consent_default);
14114
14408
  var htmlCache = /* @__PURE__ */ new Map();
14115
14409
  var brandLogoPath = "/brand/maxy-monochrome.png";
14116
14410
  var brandIconPath = "/brand/maxy-monochrome.png";
@@ -14133,7 +14427,7 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
14133
14427
  function readInstalledVersion() {
14134
14428
  try {
14135
14429
  if (!PLATFORM_ROOT9) return "unknown";
14136
- const versionFile = join14(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
14430
+ const versionFile = join15(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
14137
14431
  if (!existsSync23(versionFile)) return "unknown";
14138
14432
  const content = readFileSync20(versionFile, "utf-8").trim();
14139
14433
  return content || "unknown";
@@ -14176,7 +14470,7 @@ var clientErrorReporterScript = `<script>
14176
14470
  function cachedHtml(file) {
14177
14471
  let html = htmlCache.get(file);
14178
14472
  if (!html) {
14179
- html = readFileSync20(resolve22(process.cwd(), "public", file), "utf-8");
14473
+ html = readFileSync20(resolve23(process.cwd(), "public", file), "utf-8");
14180
14474
  const productNameEsc = escapeHtml(BRAND.productName);
14181
14475
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
14182
14476
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -14192,14 +14486,14 @@ ${clientErrorReporterScript}
14192
14486
  }
14193
14487
  var brandedHtmlCache = /* @__PURE__ */ new Map();
14194
14488
  function loadBrandingCache(agentSlug) {
14195
- const configDir2 = join14(homedir2(), BRAND.configDir);
14489
+ const configDir2 = join15(homedir2(), BRAND.configDir);
14196
14490
  try {
14197
- const accountJsonPath = join14(configDir2, "account.json");
14491
+ const accountJsonPath = join15(configDir2, "account.json");
14198
14492
  if (!existsSync23(accountJsonPath)) return null;
14199
14493
  const account = JSON.parse(readFileSync20(accountJsonPath, "utf-8"));
14200
14494
  const accountId = account.accountId;
14201
14495
  if (!accountId) return null;
14202
- const cachePath = join14(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
14496
+ const cachePath = join15(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
14203
14497
  if (!existsSync23(cachePath)) return null;
14204
14498
  return JSON.parse(readFileSync20(cachePath, "utf-8"));
14205
14499
  } catch {
@@ -14208,8 +14502,8 @@ function loadBrandingCache(agentSlug) {
14208
14502
  }
14209
14503
  function resolveDefaultSlug() {
14210
14504
  try {
14211
- const configDir2 = join14(homedir2(), BRAND.configDir);
14212
- const accountJsonPath = join14(configDir2, "account.json");
14505
+ const configDir2 = join15(homedir2(), BRAND.configDir);
14506
+ const accountJsonPath = join15(configDir2, "account.json");
14213
14507
  if (!existsSync23(accountJsonPath)) return null;
14214
14508
  const account = JSON.parse(readFileSync20(accountJsonPath, "utf-8"));
14215
14509
  return account.defaultAgent || null;
@@ -14247,7 +14541,7 @@ function brandedPublicHtml(agentSlug) {
14247
14541
  function escapeHtml(s) {
14248
14542
  return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
14249
14543
  }
14250
- app41.get("/", (c) => {
14544
+ app40.get("/", (c) => {
14251
14545
  const host = (c.req.header("host") ?? "").split(":")[0];
14252
14546
  if (isPublicHost(host)) {
14253
14547
  const defaultSlug = resolveDefaultSlug();
@@ -14255,12 +14549,12 @@ app41.get("/", (c) => {
14255
14549
  }
14256
14550
  return c.html(cachedHtml("index.html"));
14257
14551
  });
14258
- app41.get("/public", (c) => {
14552
+ app40.get("/public", (c) => {
14259
14553
  const host = (c.req.header("host") ?? "").split(":")[0];
14260
14554
  if (isPublicHost(host)) return c.text("Not found", 404);
14261
14555
  return c.html(cachedHtml("public.html"));
14262
14556
  });
14263
- app41.get("/chat", (c) => {
14557
+ app40.get("/chat", (c) => {
14264
14558
  const host = (c.req.header("host") ?? "").split(":")[0];
14265
14559
  if (isPublicHost(host)) return c.text("Not found", 404);
14266
14560
  return c.html(cachedHtml("public.html"));
@@ -14279,12 +14573,12 @@ async function logViewerFetch(c, next) {
14279
14573
  duration_ms: Date.now() - start
14280
14574
  });
14281
14575
  }
14282
- app41.use("/vnc-viewer.html", logViewerFetch);
14283
- app41.use("/vnc-popout.html", logViewerFetch);
14284
- app41.get("/vnc-popout.html", (c) => {
14576
+ app40.use("/vnc-viewer.html", logViewerFetch);
14577
+ app40.use("/vnc-popout.html", logViewerFetch);
14578
+ app40.get("/vnc-popout.html", (c) => {
14285
14579
  let html = htmlCache.get("vnc-popout.html");
14286
14580
  if (!html) {
14287
- html = readFileSync20(resolve22(process.cwd(), "public", "vnc-popout.html"), "utf-8");
14581
+ html = readFileSync20(resolve23(process.cwd(), "public", "vnc-popout.html"), "utf-8");
14288
14582
  const name = escapeHtml(BRAND.productName);
14289
14583
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
14290
14584
  html = html.replace("</head>", ` ${brandScript}
@@ -14294,7 +14588,7 @@ app41.get("/vnc-popout.html", (c) => {
14294
14588
  }
14295
14589
  return c.html(html);
14296
14590
  });
14297
- app41.post("/api/vnc/client-event", async (c) => {
14591
+ app40.post("/api/vnc/client-event", async (c) => {
14298
14592
  let body;
14299
14593
  try {
14300
14594
  body = await c.req.json();
@@ -14315,25 +14609,25 @@ app41.post("/api/vnc/client-event", async (c) => {
14315
14609
  });
14316
14610
  return c.json({ ok: true });
14317
14611
  });
14318
- app41.get("/g/:slug", (c) => {
14612
+ app40.get("/g/:slug", (c) => {
14319
14613
  return c.html(brandedPublicHtml());
14320
14614
  });
14321
- app41.get("/graph", (c) => {
14615
+ app40.get("/graph", (c) => {
14322
14616
  const host = (c.req.header("host") ?? "").split(":")[0];
14323
14617
  if (isPublicHost(host)) return c.text("Not found", 404);
14324
14618
  return c.html(cachedHtml("graph.html"));
14325
14619
  });
14326
- app41.get("/sessions", (c) => {
14620
+ app40.get("/sessions", (c) => {
14327
14621
  const host = (c.req.header("host") ?? "").split(":")[0];
14328
14622
  if (isPublicHost(host)) return c.text("Not found", 404);
14329
14623
  return c.html(cachedHtml("sessions.html"));
14330
14624
  });
14331
- app41.get("/data", (c) => {
14625
+ app40.get("/data", (c) => {
14332
14626
  const host = (c.req.header("host") ?? "").split(":")[0];
14333
14627
  if (isPublicHost(host)) return c.text("Not found", 404);
14334
14628
  return c.html(cachedHtml("data.html"));
14335
14629
  });
14336
- app41.get("/:slug", async (c, next) => {
14630
+ app40.get("/:slug", async (c, next) => {
14337
14631
  const slug = c.req.param("slug");
14338
14632
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
14339
14633
  const branding = loadBrandingCache(slug);
@@ -14343,15 +14637,15 @@ app41.get("/:slug", async (c, next) => {
14343
14637
  await next();
14344
14638
  });
14345
14639
  if (brandFaviconPath !== "/favicon.ico") {
14346
- app41.get("/favicon.ico", (c) => {
14640
+ app40.get("/favicon.ico", (c) => {
14347
14641
  c.header("Cache-Control", "public, max-age=300");
14348
14642
  return c.redirect(brandFaviconPath, 302);
14349
14643
  });
14350
14644
  }
14351
- app41.use("/*", serveStatic({ root: "./public" }));
14645
+ app40.use("/*", serveStatic({ root: "./public" }));
14352
14646
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
14353
14647
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
14354
- var httpServer = serve({ fetch: app41.fetch, port, hostname });
14648
+ var httpServer = serve({ fetch: app40.fetch, port, hostname });
14355
14649
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
14356
14650
  {
14357
14651
  const loopHist = monitorEventLoopDelay({ resolution: 50 });
@@ -14387,7 +14681,7 @@ for (const m of SUBAPP_MANIFEST) {
14387
14681
  }
14388
14682
  try {
14389
14683
  const registered = [];
14390
- for (const r of app41.routes ?? []) {
14684
+ for (const r of app40.routes ?? []) {
14391
14685
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
14392
14686
  if (AGENT_SLUG_PATTERN.test(r.path)) {
14393
14687
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -14502,7 +14796,7 @@ if (bootAccountConfig?.whatsapp) {
14502
14796
  }
14503
14797
  init({
14504
14798
  configDir: configDirForWhatsApp,
14505
- platformRoot: resolve22(process.env.MAXY_PLATFORM_ROOT ?? join14(__dirname, "..")),
14799
+ platformRoot: resolve23(process.env.MAXY_PLATFORM_ROOT ?? join15(__dirname, "..")),
14506
14800
  accountConfig: bootAccountConfig,
14507
14801
  onMessage: async (msg) => {
14508
14802
  if (process.env.WHATSAPP_PTY_BRIDGE_ENABLED === "true" && msg.text && !msg.isOwnerMirror) {