@rubytech/create-maxy-code 0.1.298 → 0.1.299

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 (139) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/cloudflare/references/manual-setup.md +33 -0
  3. package/payload/server/public/assets/AdminShell-Eo1RXZxq.js +1 -0
  4. package/payload/server/public/assets/{Checkbox-CVPUf_7I.js → Checkbox-DHnspkuk.js} +1 -1
  5. package/payload/server/public/assets/{Transcript-FYmq-mL1.js → Transcript-9FlneAzM.js} +1 -1
  6. package/payload/server/public/assets/admin-ORJGvOqo.js +1 -0
  7. package/payload/server/public/assets/{arc-DmR-LPIx.js → arc-CPOhuw1V.js} +1 -1
  8. package/payload/server/public/assets/architecture-YZFGNWBL-CQHotPO2.js +1 -0
  9. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-IVt2X8Dk.js → architectureDiagram-Q4EWVU46-BaR37f-j.js} +1 -1
  10. package/payload/server/public/assets/{audio-attachment-mime-DaInZ9sa.js → audio-attachment-mime-CFRERhV0.js} +1 -1
  11. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-CQDngnsc.js → blockDiagram-DXYQGD6D-Du7NMQfQ.js} +1 -1
  12. package/payload/server/public/assets/{browser-D_hZgtfv.js → browser--bCCzvRh.js} +1 -1
  13. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-BjV_YA-L.js → c4Diagram-AHTNJAMY-F3GnFLbs.js} +1 -1
  14. package/payload/server/public/assets/channel-DfO_IgSU.js +1 -0
  15. package/payload/server/public/assets/{chat-COcrNTJi.js → chat-DIrzZjdO.js} +1 -1
  16. package/payload/server/public/assets/{chunk-2KRD3SAO-BYqpHDvA.js → chunk-2KRD3SAO-SUv9UlAA.js} +1 -1
  17. package/payload/server/public/assets/{chunk-336JU56O-B0yBhSVq.js → chunk-336JU56O-DHUrM3QG.js} +2 -2
  18. package/payload/server/public/assets/chunk-426QAEUC-CBo-Lx7X.js +1 -0
  19. package/payload/server/public/assets/{chunk-4BX2VUAB-BeDVr5Tb.js → chunk-4BX2VUAB-D5iKMyHO.js} +1 -1
  20. package/payload/server/public/assets/{chunk-4TB4RGXK-BImQYhPF.js → chunk-4TB4RGXK-BahbQ7-Z.js} +1 -1
  21. package/payload/server/public/assets/{chunk-55IACEB6-DB18cH4S.js → chunk-55IACEB6-DfF9myIx.js} +1 -1
  22. package/payload/server/public/assets/{chunk-5FUZZQ4R-DrDSHQZv.js → chunk-5FUZZQ4R-jF6a9UVe.js} +1 -1
  23. package/payload/server/public/assets/{chunk-5PVQY5BW-CKX_LIok.js → chunk-5PVQY5BW-BOCI-roy.js} +1 -1
  24. package/payload/server/public/assets/{chunk-67CJDMHE-Ca9KwdQm.js → chunk-67CJDMHE-E5wGK0dP.js} +1 -1
  25. package/payload/server/public/assets/{chunk-7N4EOEYR-BDpzHOmv.js → chunk-7N4EOEYR-CtT0GsUT.js} +1 -1
  26. package/payload/server/public/assets/{chunk-AA7GKIK3-DXo9fZho.js → chunk-AA7GKIK3-CGUj8eo-.js} +1 -1
  27. package/payload/server/public/assets/{chunk-BSJP7CBP-CTqmM6qI.js → chunk-BSJP7CBP-OPAIjvSk.js} +1 -1
  28. package/payload/server/public/assets/{chunk-CIAEETIT-NufEId2j.js → chunk-CIAEETIT-S_D8FhIT.js} +1 -1
  29. package/payload/server/public/assets/{chunk-EDXVE4YY-D1zHB217.js → chunk-EDXVE4YY-CkD4AyZi.js} +1 -1
  30. package/payload/server/public/assets/{chunk-ENJZ2VHE-SFpdtszU.js → chunk-ENJZ2VHE-CmoK-c5f.js} +1 -1
  31. package/payload/server/public/assets/{chunk-FMBD7UC4-_4wtKsfc.js → chunk-FMBD7UC4-DcyogdNf.js} +1 -1
  32. package/payload/server/public/assets/{chunk-FOC6F5B3-565zaYb3.js → chunk-FOC6F5B3-8iNobZdv.js} +1 -1
  33. package/payload/server/public/assets/{chunk-ICPOFSXX-cYdq7RKF.js → chunk-ICPOFSXX-DeGZE9pw.js} +2 -2
  34. package/payload/server/public/assets/{chunk-K5T4RW27-CTZnA5fq.js → chunk-K5T4RW27-CkoKFdgU.js} +1 -1
  35. package/payload/server/public/assets/{chunk-KGLVRYIC-CeuKp7uR.js → chunk-KGLVRYIC-DyNP1efP.js} +1 -1
  36. package/payload/server/public/assets/{chunk-LIHQZDEY-DXkzlh3_.js → chunk-LIHQZDEY-WZPpo5Dd.js} +1 -1
  37. package/payload/server/public/assets/{chunk-ORNJ4GCN-DcZUCmgM.js → chunk-ORNJ4GCN-Cr7E0-Df.js} +1 -1
  38. package/payload/server/public/assets/{chunk-OYMX7WX6-B7JLCext.js → chunk-OYMX7WX6-BPjxo1Oc.js} +1 -1
  39. package/payload/server/public/assets/chunk-QZHKN3VN-CNlL2tiW.js +1 -0
  40. package/payload/server/public/assets/{chunk-U2HBQHQK-DWCeFwem.js → chunk-U2HBQHQK-CuDS7yVX.js} +1 -1
  41. package/payload/server/public/assets/{chunk-X2U36JSP-DGnHsoJ3.js → chunk-X2U36JSP-DEkde3xe.js} +1 -1
  42. package/payload/server/public/assets/{chunk-XPW4576I-CnU6DVpC.js → chunk-XPW4576I-BwRCuKyu.js} +1 -1
  43. package/payload/server/public/assets/{chunk-YZCP3GAM-sg4lGGJV.js → chunk-YZCP3GAM-DD9nUp-w.js} +1 -1
  44. package/payload/server/public/assets/{chunk-ZZ45TVLE-DtUoGmKE.js → chunk-ZZ45TVLE-BDH9b11G.js} +1 -1
  45. package/payload/server/public/assets/classDiagram-6PBFFD2Q-Bo-iLGpk.js +1 -0
  46. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-Bz7DNpvQ.js +1 -0
  47. package/payload/server/public/assets/clone-Bh_bM_44.js +1 -0
  48. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-C04wkJr7.js → cose-bilkent-S5V4N54A-CfeophtW.js} +1 -1
  49. package/payload/server/public/assets/{dagre-Dfj_jbTe.js → dagre-CVxEmku2.js} +1 -1
  50. package/payload/server/public/assets/{dagre-KV5264BT-Bd1VlhUJ.js → dagre-KV5264BT-TOuVLdjq.js} +1 -1
  51. package/payload/server/public/assets/{data-DkbQI40a.js → data-B8Waqy4Q.js} +1 -1
  52. package/payload/server/public/assets/{diagram-5BDNPKRD-Dqqyk8GE.js → diagram-5BDNPKRD-BJQnfJjx.js} +1 -1
  53. package/payload/server/public/assets/{diagram-G4DWMVQ6-Xk3WKR_U.js → diagram-G4DWMVQ6-CqK94J29.js} +1 -1
  54. package/payload/server/public/assets/{diagram-MMDJMWI5-CAdGL9U7.js → diagram-MMDJMWI5-BCnATv2X.js} +1 -1
  55. package/payload/server/public/assets/{diagram-TYMM5635-DY1iYQVY.js → diagram-TYMM5635-Cl3BUrVs.js} +1 -1
  56. package/payload/server/public/assets/{dist-Pgmncqde.js → dist-BXJR8AkG.js} +1 -1
  57. package/payload/server/public/assets/{erDiagram-SMLLAGMA-BJ5HYKeb.js → erDiagram-SMLLAGMA--Uw0kvib.js} +1 -1
  58. package/payload/server/public/assets/{file-download-BYJN3Kgm.js → file-download-Pk6cNtuB.js} +1 -1
  59. package/payload/server/public/assets/{flatten-DeFkSYLU.js → flatten-DtM0XAMt.js} +1 -1
  60. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-B-q6x5Q_.js → flowDiagram-DWJPFMVM-B_VGZIbJ.js} +1 -1
  61. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-DbjwY_bG.js → ganttDiagram-T4ZO3ILL-D-vdf1dC.js} +1 -1
  62. package/payload/server/public/assets/gitGraph-7Q5UKJZL-Ds2hoRX4.js +1 -0
  63. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-C3bLrOmb.js → gitGraphDiagram-UUTBAWPF-CpyAlvu3.js} +1 -1
  64. package/payload/server/public/assets/{graph-DmikPM4A.js → graph-D-VQpkaS.js} +1 -1
  65. package/payload/server/public/assets/{graph-labels-CtG6ckdG.js → graph-labels-cJvlyVxD.js} +1 -1
  66. package/payload/server/public/assets/{graphlib-BlOjhixq.js → graphlib-DaV4XyBp.js} +1 -1
  67. package/payload/server/public/assets/info-OMHHGYJF-BuX4gDTt.js +1 -0
  68. package/payload/server/public/assets/infoDiagram-42DDH7IO-pcFw8-8F.js +2 -0
  69. package/payload/server/public/assets/{isEmpty-Bn-Se8yT.js → isEmpty-D__iH1WQ.js} +1 -1
  70. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-B_DzwK8l.js → ishikawaDiagram-UXIWVN3A-_4NvfwwU.js} +1 -1
  71. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-COzTF-qc.js → journeyDiagram-VCZTEJTY-PJQ-tPWv.js} +1 -1
  72. package/payload/server/public/assets/{jsx-runtime-UQ0Z6nwN.js → jsx-runtime-B54kfC3e.js} +1 -1
  73. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-C2cOIZU6.js → kanban-definition-6JOO6SKY-asCNlyH4.js} +1 -1
  74. package/payload/server/public/assets/{line-Bwa6aUYZ.js → line-BSXr2IPU.js} +1 -1
  75. package/payload/server/public/assets/{linear-CgbkJiu6.js → linear-CSAKvvko.js} +1 -1
  76. package/payload/server/public/assets/{mermaid-parser.core-BFAF0BAk.js → mermaid-parser.core-DFxv-h16.js} +2 -2
  77. package/payload/server/public/assets/{mermaid.core-CMOXmawT.js → mermaid.core-Be34BFtA.js} +3 -3
  78. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-bu0QLO17.js → mindmap-definition-QFDTVHPH-IxwnMT2Q.js} +1 -1
  79. package/payload/server/public/assets/operator-DyLRFmNE.js +1 -0
  80. package/payload/server/public/assets/{ordinal-C-EimP2j.js → ordinal-BRQ5CzZY.js} +1 -1
  81. package/payload/server/public/assets/packet-4T2RLAQJ-9qQ2zAJ3.js +1 -0
  82. package/payload/server/public/assets/page-CFgywgGE.js +1 -0
  83. package/payload/server/public/assets/pie-ZZUOXDRM-aDbmozld.js +1 -0
  84. package/payload/server/public/assets/{pieDiagram-DEJITSTG-DQUe6W2Z.js → pieDiagram-DEJITSTG-DFqSnPPB.js} +1 -1
  85. package/payload/server/public/assets/{public-CSEIGhb4.js → public-_pD6yEQ6.js} +3 -3
  86. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-ChhcwVRA.js → quadrantDiagram-34T5L4WZ-1AB3hlEb.js} +1 -1
  87. package/payload/server/public/assets/radar-PYXPWWZC-CEm-iLey.js +1 -0
  88. package/payload/server/public/assets/{reduce-B0wq8DtH.js → reduce-CkcXOmmJ.js} +1 -1
  89. package/payload/server/public/assets/{requirementDiagram-MS252O5E-DwQXqTA9.js → requirementDiagram-MS252O5E-C2Zpzq3l.js} +1 -1
  90. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-zYqdptBM.js → sankeyDiagram-XADWPNL6-DkmhPhwS.js} +1 -1
  91. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-x2g84gb4.js → sequenceDiagram-FGHM5R23-1hQLpeZ1.js} +1 -1
  92. package/payload/server/public/assets/{src-CozP7LCe.js → src-CPkr6SrY.js} +1 -1
  93. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-CeUrqs2P.js → stateDiagram-FHFEXIEX-CBHIwm3f.js} +1 -1
  94. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DHGLsXgi.js +1 -0
  95. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-CL-c9XN5.js → timeline-definition-GMOUNBTQ-CLRWWipW.js} +1 -1
  96. package/payload/server/public/assets/treeView-SZITEDCU-DYa2gPJa.js +1 -0
  97. package/payload/server/public/assets/treemap-W4RFUUIX-D816ED1y.js +1 -0
  98. package/payload/server/public/assets/{useSelectionMode-C1_ky4B6.js → useSelectionMode-6fff2UIV.js} +1 -1
  99. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-By2HBDYr.js → vennDiagram-DHZGUBPP-ByFoQMek.js} +1 -1
  100. package/payload/server/public/assets/wardley-RL74JXVD-BniDWDlr.js +1 -0
  101. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-iahvFvIS.js → wardleyDiagram-NUSXRM2D-DIkXRSha.js} +1 -1
  102. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-33qqdRhI.js → xychartDiagram-5P7HB3ND-BNdEcN73.js} +1 -1
  103. package/payload/server/public/browser.html +6 -6
  104. package/payload/server/public/chat.html +8 -8
  105. package/payload/server/public/data.html +5 -5
  106. package/payload/server/public/graph.html +8 -8
  107. package/payload/server/public/index.html +10 -9
  108. package/payload/server/public/operator.html +24 -0
  109. package/payload/server/public/public.html +6 -6
  110. package/payload/server/server.js +289 -222
  111. package/payload/server/public/assets/AdminShell-BnhxfX97.js +0 -1
  112. package/payload/server/public/assets/admin-CF8K3hqE.js +0 -1
  113. package/payload/server/public/assets/architecture-YZFGNWBL-CjF2k79a.js +0 -1
  114. package/payload/server/public/assets/channel-gFnUr8f4.js +0 -1
  115. package/payload/server/public/assets/chunk-426QAEUC-BCmWl6vi.js +0 -1
  116. package/payload/server/public/assets/chunk-QZHKN3VN-CBWmDBHe.js +0 -1
  117. package/payload/server/public/assets/classDiagram-6PBFFD2Q-C_wlfUTz.js +0 -1
  118. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-Ltv5s3OY.js +0 -1
  119. package/payload/server/public/assets/clone-D0XoXc_v.js +0 -1
  120. package/payload/server/public/assets/gitGraph-7Q5UKJZL-DsUTwRUb.js +0 -1
  121. package/payload/server/public/assets/info-OMHHGYJF-BV9FyUXQ.js +0 -1
  122. package/payload/server/public/assets/infoDiagram-42DDH7IO-BpaHbiXO.js +0 -2
  123. package/payload/server/public/assets/packet-4T2RLAQJ-SXjQ83Vr.js +0 -1
  124. package/payload/server/public/assets/pie-ZZUOXDRM-q7TXebDD.js +0 -1
  125. package/payload/server/public/assets/radar-PYXPWWZC-CXKUHVMS.js +0 -1
  126. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-B27DBP9X.js +0 -1
  127. package/payload/server/public/assets/treeView-SZITEDCU-CWuFgUeJ.js +0 -1
  128. package/payload/server/public/assets/treemap-W4RFUUIX-gKO4rbgo.js +0 -1
  129. package/payload/server/public/assets/wardley-RL74JXVD-hDEw8pJN.js +0 -1
  130. /package/payload/server/public/assets/{_baseFor-BV-TyLWt.js → _baseFor-SRtUHe7G.js} +0 -0
  131. /package/payload/server/public/assets/{array-lqrvkwy7.js → array-BpsnM-Py.js} +0 -0
  132. /package/payload/server/public/assets/{chunk-CWOGyPgy.js → chunk-Pqm5yXtL.js} +0 -0
  133. /package/payload/server/public/assets/{cytoscape.esm-SmEOayFS.js → cytoscape.esm-D4Rl1H5h.js} +0 -0
  134. /package/payload/server/public/assets/{defaultLocale-Dl3Sud5K.js → defaultLocale-C7sQPl-O.js} +0 -0
  135. /package/payload/server/public/assets/{init-BukMwkmL.js → init-BydxaDEV.js} +0 -0
  136. /package/payload/server/public/assets/{katex-jl-BtNZi.js → katex-B0fVeDx4.js} +0 -0
  137. /package/payload/server/public/assets/{admin-CWMpccrR.css → page-CWMpccrR.css} +0 -0
  138. /package/payload/server/public/assets/{path-DPTRcLku.js → path-jlWYQ2i9.js} +0 -0
  139. /package/payload/server/public/assets/{rough.esm-VLpapkIG.js → rough.esm-c4PR5shF.js} +0 -0
@@ -1215,7 +1215,7 @@ var serveStatic = (options = { root: "" }) => {
1215
1215
 
1216
1216
  // server/index.ts
1217
1217
  import { readFileSync as readFileSync26, existsSync as existsSync26, watchFile } from "fs";
1218
- import { resolve as resolve28, join as join21, basename as basename8 } from "path";
1218
+ import { resolve as resolve29, join as join22, basename as basename8 } from "path";
1219
1219
  import { homedir as homedir3 } from "os";
1220
1220
  import { monitorEventLoopDelay } from "perf_hooks";
1221
1221
 
@@ -1244,6 +1244,21 @@ function isPublicPathAllowed(path2) {
1244
1244
  if (PUBLIC_ALLOWED_PREFIXES.some((prefix) => path2.startsWith(prefix))) return true;
1245
1245
  return AGENT_SLUG_PATTERN.test(path2);
1246
1246
  }
1247
+ function isOperatorHost(host) {
1248
+ return host.startsWith("operator.");
1249
+ }
1250
+
1251
+ // server/webchat-descriptor.ts
1252
+ import { resolve, join as join2 } from "path";
1253
+ function webchatGatewayUrl() {
1254
+ return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
1255
+ }
1256
+ function webchatServerPath() {
1257
+ return process.env.MAXY_WEBCHAT_CHANNEL_SERVER_PATH ?? resolve(process.env.MAXY_PLATFORM_ROOT ?? join2(__dirname, ".."), "services/webchat-channel/dist/server.js");
1258
+ }
1259
+ function webchatChannelDescriptor(key) {
1260
+ return { key, gatewayUrl: webchatGatewayUrl(), serverPath: webchatServerPath() };
1261
+ }
1247
1262
 
1248
1263
  // app/lib/claude-auth.ts
1249
1264
  import { readFileSync, writeFileSync } from "fs";
@@ -1794,7 +1809,7 @@ var credsSaveQueue = Promise.resolve();
1794
1809
  async function drainCredsSaveQueue(timeoutMs = 5e3) {
1795
1810
  console.error(`${TAG2} draining credential save queue\u2026`);
1796
1811
  const timer2 = new Promise(
1797
- (resolve29) => setTimeout(() => resolve29("timeout"), timeoutMs)
1812
+ (resolve30) => setTimeout(() => resolve30("timeout"), timeoutMs)
1798
1813
  );
1799
1814
  const result = await Promise.race([
1800
1815
  credsSaveQueue.then(() => "drained"),
@@ -1922,11 +1937,11 @@ async function createWaSocket(opts) {
1922
1937
  return sock;
1923
1938
  }
1924
1939
  async function waitForConnection(sock) {
1925
- return new Promise((resolve29, reject) => {
1940
+ return new Promise((resolve30, reject) => {
1926
1941
  const handler = (update) => {
1927
1942
  if (update.connection === "open") {
1928
1943
  sock.ev.off("connection.update", handler);
1929
- resolve29();
1944
+ resolve30();
1930
1945
  }
1931
1946
  if (update.connection === "close") {
1932
1947
  sock.ev.off("connection.update", handler);
@@ -2040,14 +2055,14 @@ ${inspected}`;
2040
2055
  return inspect2(err, INSPECT_OPTS2);
2041
2056
  }
2042
2057
  function withTimeout(label, promise, timeoutMs) {
2043
- return new Promise((resolve29, reject) => {
2058
+ return new Promise((resolve30, reject) => {
2044
2059
  const timer2 = setTimeout(() => {
2045
2060
  reject(new Error(`${label} timed out after ${timeoutMs}ms`));
2046
2061
  }, timeoutMs);
2047
2062
  promise.then(
2048
2063
  (value) => {
2049
2064
  clearTimeout(timer2);
2050
- resolve29(value);
2065
+ resolve30(value);
2051
2066
  },
2052
2067
  (err) => {
2053
2068
  clearTimeout(timer2);
@@ -2646,8 +2661,8 @@ async function persistWhatsAppMessage(input) {
2646
2661
  const { givenName, familyName } = splitName(input.pushName);
2647
2662
  const prev = sessionWriteLocks.get(input.cacheKey);
2648
2663
  let release;
2649
- const mine = new Promise((resolve29) => {
2650
- release = resolve29;
2664
+ const mine = new Promise((resolve30) => {
2665
+ release = resolve30;
2651
2666
  });
2652
2667
  const chained = (prev ?? Promise.resolve()).then(() => mine);
2653
2668
  sessionWriteLocks.set(input.cacheKey, chained);
@@ -2833,7 +2848,7 @@ async function ensureWhatsAppConversation(input) {
2833
2848
 
2834
2849
  // ../lib/account-enumeration/src/index.ts
2835
2850
  import { readdirSync, readFileSync as readFileSync3 } from "fs";
2836
- import { resolve } from "path";
2851
+ import { resolve as resolve2 } from "path";
2837
2852
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
2838
2853
  var cache = /* @__PURE__ */ new Map();
2839
2854
  function enumerateValidAccountIds(accountsDir) {
@@ -2852,7 +2867,7 @@ function enumerateValidAccountIds(accountsDir) {
2852
2867
  const valid = [];
2853
2868
  for (const name of names) {
2854
2869
  if (!UUID_RE.test(name)) continue;
2855
- const configPath2 = resolve(accountsDir, name, "account.json");
2870
+ const configPath2 = resolve2(accountsDir, name, "account.json");
2856
2871
  try {
2857
2872
  JSON.parse(readFileSync3(configPath2, "utf-8"));
2858
2873
  valid.push(name);
@@ -2871,7 +2886,7 @@ function getAccountsDirFromEnv() {
2871
2886
  "[graph-write] MAXY_PLATFORM_ROOT not set \u2014 cannot enforce accountId gate. Set MAXY_PLATFORM_ROOT in the spawning process or pass `accountsDir` explicitly."
2872
2887
  );
2873
2888
  }
2874
- return resolve(root, "..", "data/accounts");
2889
+ return resolve2(root, "..", "data/accounts");
2875
2890
  }
2876
2891
  function validateAccountIdEnv(envValue, diskIds) {
2877
2892
  if (!envValue) {
@@ -2910,7 +2925,7 @@ function resolvePlatformAccountId(accountsDir = ACCOUNTS_DIR) {
2910
2925
  // app/lib/whatsapp/inbound/media.ts
2911
2926
  import { randomUUID as randomUUID2 } from "crypto";
2912
2927
  import { writeFile, mkdir } from "fs/promises";
2913
- import { join as join2 } from "path";
2928
+ import { join as join3 } from "path";
2914
2929
  import {
2915
2930
  downloadMediaMessage,
2916
2931
  downloadContentFromMessage,
@@ -2996,7 +3011,7 @@ async function downloadInboundMedia(msg, sock, opts) {
2996
3011
  await mkdir(MEDIA_DIR, { recursive: true });
2997
3012
  const ext = mimeToExt(mimetype ?? "application/octet-stream");
2998
3013
  const filename = `${randomUUID2()}.${ext}`;
2999
- const filePath = join2(MEDIA_DIR, filename);
3014
+ const filePath = join3(MEDIA_DIR, filename);
3000
3015
  await writeFile(filePath, buffer);
3001
3016
  const sizeKB = (buffer.length / 1024).toFixed(0);
3002
3017
  console.error(`${TAG9} media downloaded type=${mimetype ?? "unknown"} size=${sizeKB}KB path=${filePath}`);
@@ -3727,11 +3742,11 @@ async function connectWithReconnect(conn) {
3727
3742
  console.error(
3728
3743
  `${TAG13} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
3729
3744
  );
3730
- await new Promise((resolve29) => {
3731
- const timer2 = setTimeout(resolve29, delay);
3745
+ await new Promise((resolve30) => {
3746
+ const timer2 = setTimeout(resolve30, delay);
3732
3747
  conn.abortController.signal.addEventListener("abort", () => {
3733
3748
  clearTimeout(timer2);
3734
- resolve29();
3749
+ resolve30();
3735
3750
  }, { once: true });
3736
3751
  });
3737
3752
  }
@@ -3739,16 +3754,16 @@ async function connectWithReconnect(conn) {
3739
3754
  }
3740
3755
  }
3741
3756
  function waitForDisconnectEvent(conn) {
3742
- return new Promise((resolve29) => {
3757
+ return new Promise((resolve30) => {
3743
3758
  if (!conn.sock) {
3744
- resolve29();
3759
+ resolve30();
3745
3760
  return;
3746
3761
  }
3747
3762
  const sock = conn.sock;
3748
3763
  const handler = (update) => {
3749
3764
  if (update.connection === "close") {
3750
3765
  sock.ev.off("connection.update", handler);
3751
- resolve29();
3766
+ resolve30();
3752
3767
  }
3753
3768
  };
3754
3769
  sock.ev.on("connection.update", handler);
@@ -4008,8 +4023,8 @@ async function handleInboundMessage(conn, msg) {
4008
4023
  const conversationKey = isGroup ? remoteJid : senderPhone;
4009
4024
  const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
4010
4025
  let resolvePending;
4011
- const sttPending = new Promise((resolve29) => {
4012
- resolvePending = resolve29;
4026
+ const sttPending = new Promise((resolve30) => {
4027
+ resolvePending = resolve30;
4013
4028
  });
4014
4029
  if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
4015
4030
  try {
@@ -4106,9 +4121,9 @@ async function handleInboundMessage(conn, msg) {
4106
4121
  import { spawnSync, execFileSync } from "child_process";
4107
4122
  import { createConnection } from "net";
4108
4123
  import { mkdirSync, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
4109
- import { resolve as resolve2 } from "path";
4110
- var PLATFORM_ROOT2 = process.env.MAXY_PLATFORM_ROOT ?? resolve2(process.cwd(), "..");
4111
- var VNC_SCRIPT = resolve2(PLATFORM_ROOT2, "scripts/vnc.sh");
4124
+ import { resolve as resolve3 } from "path";
4125
+ var PLATFORM_ROOT2 = process.env.MAXY_PLATFORM_ROOT ?? resolve3(process.cwd(), "..");
4126
+ var VNC_SCRIPT = resolve3(PLATFORM_ROOT2, "scripts/vnc.sh");
4112
4127
  var displayMode = process.env.DISPLAY_MODE ?? "virtual";
4113
4128
  if (displayMode === "native") {
4114
4129
  console.log(`[vnc] DISPLAY_MODE=native \u2014 local requests use desktop display, remote requests use VNC`);
@@ -4221,7 +4236,7 @@ function ensureLogDir() {
4221
4236
  mkdirSync(LOG_DIR, { recursive: true });
4222
4237
  }
4223
4238
  function logPath(name) {
4224
- return resolve2(LOG_DIR, `${name}.log`);
4239
+ return resolve3(LOG_DIR, `${name}.log`);
4225
4240
  }
4226
4241
  async function ensureVnc() {
4227
4242
  const up = await waitForPort(RFB_PORT, 1e3);
@@ -4300,7 +4315,7 @@ function killChromium() {
4300
4315
  }
4301
4316
  function writeChromiumWrapper() {
4302
4317
  mkdirSync(BIN_DIR, { recursive: true });
4303
- const wrapperPath = resolve2(BIN_DIR, "chromium");
4318
+ const wrapperPath = resolve3(BIN_DIR, "chromium");
4304
4319
  writeFileSync3(wrapperPath, `#!/bin/bash
4305
4320
  LOG="${LOG_DIR}/chromium.log"
4306
4321
  echo "==== [$(date)] chromium wrapper ====" >> "$LOG"
@@ -4400,20 +4415,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
4400
4415
 
4401
4416
  // server/routes/health.ts
4402
4417
  function checkPort(port2, timeoutMs = 500) {
4403
- return new Promise((resolve29) => {
4418
+ return new Promise((resolve30) => {
4404
4419
  const socket = createConnection2(port2, "127.0.0.1");
4405
4420
  socket.setTimeout(timeoutMs);
4406
4421
  socket.once("connect", () => {
4407
4422
  socket.destroy();
4408
- resolve29(true);
4423
+ resolve30(true);
4409
4424
  });
4410
4425
  socket.once("error", () => {
4411
4426
  socket.destroy();
4412
- resolve29(false);
4427
+ resolve30(false);
4413
4428
  });
4414
4429
  socket.once("timeout", () => {
4415
4430
  socket.destroy();
4416
- resolve29(false);
4431
+ resolve30(false);
4417
4432
  });
4418
4433
  });
4419
4434
  }
@@ -4483,9 +4498,9 @@ var health_default = app;
4483
4498
  import { randomUUID as randomUUID3 } from "crypto";
4484
4499
  import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
4485
4500
  import { realpathSync } from "fs";
4486
- import { resolve as resolve3, extname } from "path";
4487
- var PLATFORM_ROOT3 = process.env.MAXY_PLATFORM_ROOT ?? resolve3(process.cwd(), "../platform");
4488
- var ATTACHMENTS_ROOT = resolve3(PLATFORM_ROOT3, "..", "data/uploads");
4501
+ import { resolve as resolve4, extname } from "path";
4502
+ var PLATFORM_ROOT3 = process.env.MAXY_PLATFORM_ROOT ?? resolve4(process.cwd(), "../platform");
4503
+ var ATTACHMENTS_ROOT = resolve4(PLATFORM_ROOT3, "..", "data/uploads");
4489
4504
  var SUPPORTED_MIME_TYPES = /* @__PURE__ */ new Set([
4490
4505
  "image/jpeg",
4491
4506
  "image/png",
@@ -4512,11 +4527,11 @@ function assertSupportedMime(mimeType) {
4512
4527
  }
4513
4528
  async function writeAttachment(scope, filename, mimeType, sizeBytes, buffer) {
4514
4529
  const attachmentId = randomUUID3();
4515
- const dir = resolve3(ATTACHMENTS_ROOT, scope, attachmentId);
4530
+ const dir = resolve4(ATTACHMENTS_ROOT, scope, attachmentId);
4516
4531
  await mkdir2(dir, { recursive: true });
4517
4532
  const ext = extname(filename) || "";
4518
- const storagePath = resolve3(dir, `${attachmentId}${ext}`);
4519
- const metaPath = resolve3(dir, `${attachmentId}.meta.json`);
4533
+ const storagePath = resolve4(dir, `${attachmentId}${ext}`);
4534
+ const metaPath = resolve4(dir, `${attachmentId}.meta.json`);
4520
4535
  const meta = {
4521
4536
  attachmentId,
4522
4537
  scope,
@@ -4590,11 +4605,11 @@ async function storeComponentArtefact(accountId, attachmentId, mimeType, content
4590
4605
  `Component artefact exceeds the 50 MB limit (${(buffer.byteLength / 1024 / 1024).toFixed(1)} MB).`
4591
4606
  );
4592
4607
  }
4593
- const dir = resolve3(ATTACHMENTS_ROOT, accountId, attachmentId);
4608
+ const dir = resolve4(ATTACHMENTS_ROOT, accountId, attachmentId);
4594
4609
  await mkdir2(dir, { recursive: true });
4595
4610
  const ext = extname(filename) || (mimeType === "text/html" ? ".html" : ".md");
4596
- const storagePath = resolve3(dir, `${attachmentId}${ext}`);
4597
- const metaPath = resolve3(dir, `${attachmentId}.meta.json`);
4611
+ const storagePath = resolve4(dir, `${attachmentId}${ext}`);
4612
+ const metaPath = resolve4(dir, `${attachmentId}.meta.json`);
4598
4613
  const meta = {
4599
4614
  attachmentId,
4600
4615
  scope: accountId,
@@ -4611,7 +4626,7 @@ async function storeComponentArtefact(accountId, attachmentId, mimeType, content
4611
4626
  // app/lib/stt/voice-note.ts
4612
4627
  import { writeFile as writeFile3, mkdtemp, rm } from "fs/promises";
4613
4628
  import { tmpdir } from "os";
4614
- import { join as join3 } from "path";
4629
+ import { join as join4 } from "path";
4615
4630
  var TAG14 = "[voice]";
4616
4631
  var AUDIO_MIME_TYPES = /* @__PURE__ */ new Set([
4617
4632
  "audio/ogg",
@@ -4655,9 +4670,9 @@ async function transcribeVoiceNote(file, source) {
4655
4670
  let tempDir;
4656
4671
  let tempPath;
4657
4672
  try {
4658
- tempDir = await mkdtemp(join3(tmpdir(), "voice-"));
4673
+ tempDir = await mkdtemp(join4(tmpdir(), "voice-"));
4659
4674
  const ext = audioExtension(mimeType);
4660
- tempPath = join3(tempDir, `recording${ext}`);
4675
+ tempPath = join4(tempDir, `recording${ext}`);
4661
4676
  const buffer = Buffer.from(await file.arrayBuffer());
4662
4677
  await writeFile3(tempPath, buffer);
4663
4678
  } catch (err) {
@@ -4698,7 +4713,7 @@ async function transcribeVoiceNote(file, source) {
4698
4713
  }
4699
4714
 
4700
4715
  // app/lib/channel-pty-bridge/bridge.ts
4701
- import { resolve as resolve5 } from "path";
4716
+ import { resolve as resolve6 } from "path";
4702
4717
 
4703
4718
  // app/lib/channel-pty-bridge/manager-client.ts
4704
4719
  function managerBase() {
@@ -5150,7 +5165,7 @@ async function fanOut(subscribers, text, onError, tag) {
5150
5165
  // app/lib/whatsapp/outbound/send-document.ts
5151
5166
  import { realpathSync as realpathSync2 } from "fs";
5152
5167
  import { readFile, stat as stat2 } from "fs/promises";
5153
- import { resolve as resolve4, basename } from "path";
5168
+ import { resolve as resolve5, basename } from "path";
5154
5169
  var TAG16 = "[whatsapp:outbound]";
5155
5170
  var WHATSAPP_DOCUMENT_MAX_BYTES = 100 * 1024 * 1024;
5156
5171
  var lastDocumentOutboundAt = /* @__PURE__ */ new Map();
@@ -5181,7 +5196,7 @@ async function sendWhatsAppDocument(input) {
5181
5196
  if (!maxyAccountId || !platformRoot2) {
5182
5197
  return { ok: false, status: 400, error: "Cannot validate file path: missing account or platform context" };
5183
5198
  }
5184
- const accountDir = resolve4(platformRoot2, "..", "data/accounts", maxyAccountId);
5199
+ const accountDir = resolve5(platformRoot2, "..", "data/accounts", maxyAccountId);
5185
5200
  let resolvedPath;
5186
5201
  try {
5187
5202
  resolvedPath = realpathSync2(filePath);
@@ -5388,7 +5403,7 @@ async function ensureEntry(input) {
5388
5403
  });
5389
5404
  } else {
5390
5405
  console.error(`${tag} route role=${input.role} target=public-spawn senderId=${input.senderId}`);
5391
- const attachmentDir = resolve5(ATTACHMENTS_ROOT, "public", input.senderId);
5406
+ const attachmentDir = resolve6(ATTACHMENTS_ROOT, "public", input.senderId);
5392
5407
  spawned = await managerSpawn({
5393
5408
  senderId: input.senderId,
5394
5409
  role: input.role,
@@ -5520,12 +5535,12 @@ async function dispatchOnce(input) {
5520
5535
  });
5521
5536
  if (!entry) return { error: "spawn-failed" };
5522
5537
  entry.lastInboundAt = Date.now();
5523
- let resolve29;
5538
+ let resolve30;
5524
5539
  const turnPromise = new Promise((r) => {
5525
- resolve29 = r;
5540
+ resolve30 = r;
5526
5541
  });
5527
5542
  const listener = (text) => {
5528
- resolve29(text);
5543
+ resolve30(text);
5529
5544
  };
5530
5545
  entry.subscribers.add(listener);
5531
5546
  const writeAtMs = Date.now();
@@ -5895,7 +5910,7 @@ ${result.result.text}` : result.result.text;
5895
5910
  var chat_default = app2;
5896
5911
 
5897
5912
  // server/routes/whatsapp.ts
5898
- import { join as join6, resolve as resolve7 } from "path";
5913
+ import { join as join7, resolve as resolve8 } from "path";
5899
5914
  import { readdirSync as readdirSync3, readFileSync as readFileSync7, existsSync as existsSync5 } from "fs";
5900
5915
 
5901
5916
  // app/lib/whatsapp/login.ts
@@ -5903,10 +5918,10 @@ import { randomUUID as randomUUID6 } from "crypto";
5903
5918
 
5904
5919
  // app/lib/whatsapp/config-persist.ts
5905
5920
  import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync4 } from "fs";
5906
- import { resolve as resolve6, join as join4 } from "path";
5921
+ import { resolve as resolve7, join as join5 } from "path";
5907
5922
  var TAG18 = "[whatsapp:config]";
5908
5923
  function configPath(accountDir) {
5909
- return resolve6(accountDir, "account.json");
5924
+ return resolve7(accountDir, "account.json");
5910
5925
  }
5911
5926
  function readConfig(accountDir) {
5912
5927
  const path2 = configPath(accountDir);
@@ -6055,7 +6070,7 @@ function setPublicAgent(accountDir, slug) {
6055
6070
  if (!trimmed) {
6056
6071
  return { ok: false, error: "Agent slug cannot be empty." };
6057
6072
  }
6058
- const agentConfigPath = join4(accountDir, "agents", trimmed, "config.json");
6073
+ const agentConfigPath = join5(accountDir, "agents", trimmed, "config.json");
6059
6074
  if (!existsSync4(agentConfigPath)) {
6060
6075
  return { ok: false, error: `Agent "${trimmed}" not found \u2014 no config.json at ${agentConfigPath}. Check the agent slug and try again.` };
6061
6076
  }
@@ -6313,8 +6328,8 @@ async function startLogin(opts) {
6313
6328
  await clearAuth(authDir);
6314
6329
  let resolveCode = null;
6315
6330
  let rejectCode = null;
6316
- const codePromise = new Promise((resolve29, reject) => {
6317
- resolveCode = resolve29;
6331
+ const codePromise = new Promise((resolve30, reject) => {
6332
+ resolveCode = resolve30;
6318
6333
  rejectCode = reject;
6319
6334
  });
6320
6335
  const codeTimer = setTimeout(
@@ -6546,11 +6561,11 @@ function serializeWhatsAppSchema() {
6546
6561
 
6547
6562
  // app/lib/whatsapp/status-reconcile.ts
6548
6563
  import { readdirSync as readdirSync2 } from "fs";
6549
- import { join as join5 } from "path";
6564
+ import { join as join6 } from "path";
6550
6565
  var TAG20 = "[whatsapp:reconcile]";
6551
6566
  function listCredsAccountIds(credsRoot) {
6552
6567
  try {
6553
- return readdirSync2(credsRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && hasCredsSync(join5(credsRoot, e.name))).map((e) => e.name);
6568
+ return readdirSync2(credsRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && hasCredsSync(join6(credsRoot, e.name))).map((e) => e.name);
6554
6569
  } catch {
6555
6570
  return [];
6556
6571
  }
@@ -6565,7 +6580,7 @@ function reconcileCredsOnDisk(opts) {
6565
6580
  const entries = [];
6566
6581
  for (const accountId of listCredsAccountIds(credsRoot)) {
6567
6582
  if (liveAccountIds.has(accountId)) continue;
6568
- const authDir = join5(credsRoot, accountId);
6583
+ const authDir = join6(credsRoot, accountId);
6569
6584
  const selfPhone = readSelfId(authDir).e164 ?? void 0;
6570
6585
  const configured = accountDir ? isAccountConfigured(accountDir, accountId) : false;
6571
6586
  console.error(
@@ -6592,7 +6607,7 @@ app3.get("/status", (c) => {
6592
6607
  try {
6593
6608
  const live = getStatus();
6594
6609
  const liveIds = new Set(live.map((a) => a.accountId));
6595
- const credsRoot = join6(MAXY_DIR, "credentials", "whatsapp");
6610
+ const credsRoot = join7(MAXY_DIR, "credentials", "whatsapp");
6596
6611
  const accountDir = resolveAccount()?.accountDir ?? null;
6597
6612
  const reconciled = reconcileCredsOnDisk({ credsRoot, accountDir, liveAccountIds: liveIds });
6598
6613
  const accounts = [...live, ...reconciled];
@@ -6613,7 +6628,7 @@ app3.post("/login/start", async (c) => {
6613
6628
  if (!phone) {
6614
6629
  return c.json({ error: 'Missing required field "phone" (E.164, e.g. +441234567890).' }, 400);
6615
6630
  }
6616
- const authDir = join6(MAXY_DIR, "credentials", "whatsapp", accountId);
6631
+ const authDir = join7(MAXY_DIR, "credentials", "whatsapp", accountId);
6617
6632
  const accountDir = resolveAccount()?.accountDir ?? null;
6618
6633
  const result = await startLogin({ accountId, authDir, phone, accountDir, force });
6619
6634
  console.error(`${TAG21} login/start result account=${accountId} hasCode=${!!result.pairingCode}${result.selfPhone ? ` phone=${result.selfPhone}` : ""}`);
@@ -6711,14 +6726,14 @@ app3.post("/config", async (c) => {
6711
6726
  return c.json({ ok: true, slug: resolved?.slug ?? null, source: resolved?.source ?? null });
6712
6727
  }
6713
6728
  case "list-public-agents": {
6714
- const agentsDir = resolve7(account.accountDir, "agents");
6729
+ const agentsDir = resolve8(account.accountDir, "agents");
6715
6730
  const agents = [];
6716
6731
  if (existsSync5(agentsDir)) {
6717
6732
  try {
6718
6733
  const entries = readdirSync3(agentsDir, { withFileTypes: true });
6719
6734
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
6720
6735
  if (!entry.isDirectory() || entry.name === "admin") continue;
6721
- const configPath2 = resolve7(agentsDir, entry.name, "config.json");
6736
+ const configPath2 = resolve8(agentsDir, entry.name, "config.json");
6722
6737
  if (!existsSync5(configPath2)) continue;
6723
6738
  try {
6724
6739
  const config = JSON.parse(readFileSync7(configPath2, "utf-8"));
@@ -6991,11 +7006,11 @@ var whatsapp_default = app3;
6991
7006
 
6992
7007
  // server/routes/whatsapp-reader.ts
6993
7008
  import { readFileSync as readFileSync10, watch, statSync as statSync4, openSync, readSync, closeSync, existsSync as existsSync7, readdirSync as readdirSync6 } from "fs";
6994
- import { basename as basename2, dirname, join as join9, resolve as resolve9, sep as sep2 } from "path";
7009
+ import { basename as basename2, dirname, join as join10, resolve as resolve10, sep as sep2 } from "path";
6995
7010
 
6996
7011
  // server/routes/admin/sidebar-sessions.ts
6997
7012
  import { readdirSync as readdirSync4, readFileSync as readFileSync8, statSync as statSync2 } from "fs";
6998
- import { join as join7, resolve as resolve8 } from "path";
7013
+ import { join as join8, resolve as resolve9 } from "path";
6999
7014
  var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.jsonl$/i;
7000
7015
  var CLI_MARKER_PREFIXES = ["<local-command-", "<command-name>", "<command-message>"];
7001
7016
  var PUBLIC_ROLE = "public";
@@ -7014,7 +7029,7 @@ function enumerateJsonls(projectsRoot) {
7014
7029
  throw err;
7015
7030
  }
7016
7031
  for (const slug of slugs) {
7017
- const slugDir = join7(projectsRoot, slug);
7032
+ const slugDir = join8(projectsRoot, slug);
7018
7033
  let entries;
7019
7034
  try {
7020
7035
  entries = readdirSync4(slugDir, { withFileTypes: true });
@@ -7025,9 +7040,9 @@ function enumerateJsonls(projectsRoot) {
7025
7040
  }
7026
7041
  for (const entry of entries) {
7027
7042
  if (entry.isFile() && SESSION_ID_RE.test(entry.name)) {
7028
- out.push({ path: join7(slugDir, entry.name), isSubagent: false, archived: false });
7043
+ out.push({ path: join8(slugDir, entry.name), isSubagent: false, archived: false });
7029
7044
  } else if (entry.isDirectory() && entry.name === "subagents") {
7030
- const subDir = join7(slugDir, entry.name);
7045
+ const subDir = join8(slugDir, entry.name);
7031
7046
  let subEntries;
7032
7047
  try {
7033
7048
  subEntries = readdirSync4(subDir, { withFileTypes: true });
@@ -7038,11 +7053,11 @@ function enumerateJsonls(projectsRoot) {
7038
7053
  }
7039
7054
  for (const sub of subEntries) {
7040
7055
  if (sub.isFile() && SESSION_ID_RE.test(sub.name)) {
7041
- out.push({ path: join7(subDir, sub.name), isSubagent: true, archived: false });
7056
+ out.push({ path: join8(subDir, sub.name), isSubagent: true, archived: false });
7042
7057
  }
7043
7058
  }
7044
7059
  } else if (entry.isDirectory() && entry.name === "archive") {
7045
- const archiveDir = join7(slugDir, entry.name);
7060
+ const archiveDir = join8(slugDir, entry.name);
7046
7061
  let archiveEntries;
7047
7062
  try {
7048
7063
  archiveEntries = readdirSync4(archiveDir, { withFileTypes: true });
@@ -7053,7 +7068,7 @@ function enumerateJsonls(projectsRoot) {
7053
7068
  }
7054
7069
  for (const arc of archiveEntries) {
7055
7070
  if (arc.isFile() && SESSION_ID_RE.test(arc.name)) {
7056
- out.push({ path: join7(archiveDir, arc.name), isSubagent: false, archived: true });
7071
+ out.push({ path: join8(archiveDir, arc.name), isSubagent: false, archived: true });
7057
7072
  }
7058
7073
  }
7059
7074
  }
@@ -7086,7 +7101,7 @@ async function fetchLiveSessions() {
7086
7101
  function loadUserTitles(accountDir) {
7087
7102
  const out = /* @__PURE__ */ new Map();
7088
7103
  if (!accountDir) return out;
7089
- const path2 = join7(accountDir, "session-titles.json");
7104
+ const path2 = join8(accountDir, "session-titles.json");
7090
7105
  let raw;
7091
7106
  try {
7092
7107
  raw = readFileSync8(path2, "utf8");
@@ -7183,10 +7198,10 @@ app4.get("/", requireAdminSession, async (c) => {
7183
7198
  console.error("[admin-sessions-list] CLAUDE_CONFIG_DIR not set; returning empty list");
7184
7199
  return c.json({ sessions: [], accountId });
7185
7200
  }
7186
- const projectsRoot = join7(configDir2, "projects");
7201
+ const projectsRoot = join8(configDir2, "projects");
7187
7202
  const jsonls = enumerateJsonls(projectsRoot);
7188
7203
  const liveSessions = await fetchLiveSessions();
7189
- const accountDir = accountId ? resolve8(ACCOUNTS_DIR, accountId) : null;
7204
+ const accountDir = accountId ? resolve9(ACCOUNTS_DIR, accountId) : null;
7190
7205
  const userTitles = loadUserTitles(accountDir);
7191
7206
  const rows = [];
7192
7207
  const seenIds = /* @__PURE__ */ new Set();
@@ -7217,7 +7232,7 @@ app4.get("/", requireAdminSession, async (c) => {
7217
7232
  const pid = live ? liveSessions.get(sessionId) ?? null : null;
7218
7233
  const resolved = resolveTitle(body, sessionId, userTitles);
7219
7234
  titleSourceCounts[resolved.source] += 1;
7220
- const metaPath = join7(projectDir, `${sessionId}.meta.json`);
7235
+ const metaPath = join8(projectDir, `${sessionId}.meta.json`);
7221
7236
  const { bridgeIds, role, channel } = readSidecarMeta(metaPath);
7222
7237
  const resumable = !(role === PUBLIC_ROLE && channel === WEBCHAT_CHANNEL);
7223
7238
  rows.push({
@@ -7264,7 +7279,7 @@ function selectAdminChannelSessions(rows) {
7264
7279
  // app/lib/admin-identity/pin-validator.ts
7265
7280
  import { createHash as createHash2 } from "crypto";
7266
7281
  import { existsSync as existsSync6, readFileSync as readFileSync9, readdirSync as readdirSync5, statSync as statSync3 } from "fs";
7267
- import { join as join8 } from "path";
7282
+ import { join as join9 } from "path";
7268
7283
  function hashPin(pin) {
7269
7284
  return createHash2("sha256").update(pin).digest("hex");
7270
7285
  }
@@ -7298,13 +7313,13 @@ function scanForOrphanedAccountAdmins(users, accountsDir) {
7298
7313
  }
7299
7314
  for (const entry of entries) {
7300
7315
  if (entry.startsWith(".")) continue;
7301
- const accountDir = join8(accountsDir, entry);
7316
+ const accountDir = join9(accountsDir, entry);
7302
7317
  try {
7303
7318
  if (!statSync3(accountDir).isDirectory()) continue;
7304
7319
  } catch {
7305
7320
  continue;
7306
7321
  }
7307
- const accountJsonPath = join8(accountDir, "account.json");
7322
+ const accountJsonPath = join9(accountDir, "account.json");
7308
7323
  if (!existsSync6(accountJsonPath)) continue;
7309
7324
  try {
7310
7325
  const config = JSON.parse(readFileSync9(accountJsonPath, "utf-8"));
@@ -7484,13 +7499,13 @@ var app5 = new Hono();
7484
7499
  app5.get("/conversations", requireAdminSession, async (c) => {
7485
7500
  const cfg = claudeConfigDir();
7486
7501
  if (!cfg) return c.json({ conversations: [] });
7487
- const projectsRoot = join9(cfg, "projects");
7502
+ const projectsRoot = join10(cfg, "projects");
7488
7503
  const userTitles = loadUserTitles(ACCOUNTS_DIR ?? null);
7489
7504
  const rows = [];
7490
7505
  for (const { path: path2 } of enumerateJsonls(projectsRoot)) {
7491
7506
  const sessionId = basename2(path2).replace(/\.jsonl$/, "");
7492
7507
  const projectDir = dirname(path2);
7493
- const meta = readSidecarMeta(join9(projectDir, `${sessionId}.meta.json`));
7508
+ const meta = readSidecarMeta(join10(projectDir, `${sessionId}.meta.json`));
7494
7509
  if (meta.role !== "admin" || meta.channel !== "whatsapp" && meta.channel !== "telegram") continue;
7495
7510
  let body = "";
7496
7511
  try {
@@ -7577,11 +7592,11 @@ app5.get("/stream", requireAdminSession, (c) => {
7577
7592
  const sessionId = c.req.query("sessionId") ?? "";
7578
7593
  const projectDir = c.req.query("projectDir") ?? "";
7579
7594
  const cfg = claudeConfigDir();
7580
- const projectsRoot = cfg ? resolve9(join9(cfg, "projects")) : null;
7595
+ const projectsRoot = cfg ? resolve10(join10(cfg, "projects")) : null;
7581
7596
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
7582
7597
  return c.json({ error: "bad session reference" }, 400);
7583
7598
  }
7584
- const jsonlPath = resolve9(join9(projectDir, `${sessionId}.jsonl`));
7599
+ const jsonlPath = resolve10(join10(projectDir, `${sessionId}.jsonl`));
7585
7600
  if (!jsonlPath.startsWith(projectsRoot + sep2)) {
7586
7601
  return c.json({ error: "bad session reference" }, 400);
7587
7602
  }
@@ -7668,7 +7683,7 @@ var DIRECTIVE_NAME_RE = /^\d+-\d+\.txt$/;
7668
7683
  function directiveStoreDir(sessionId) {
7669
7684
  const account = resolveAccount();
7670
7685
  if (!account) return null;
7671
- return resolve9(account.accountDir, "logs", "prompt-optimiser-directives", sessionId);
7686
+ return resolve10(account.accountDir, "logs", "prompt-optimiser-directives", sessionId);
7672
7687
  }
7673
7688
  app5.get("/directives", requireAdminSession, (c) => {
7674
7689
  const sessionId = c.req.query("sessionId") ?? "";
@@ -7687,7 +7702,7 @@ app5.get("/directives", requireAdminSession, (c) => {
7687
7702
  const pid = Number(pidPart);
7688
7703
  let len = 0;
7689
7704
  try {
7690
- len = statSync4(join9(dir, name)).size;
7705
+ len = statSync4(join10(dir, name)).size;
7691
7706
  } catch {
7692
7707
  }
7693
7708
  return { name, secs, pid, ts: Number.isFinite(secs) ? new Date(secs * 1e3).toISOString() : null, len };
@@ -7702,7 +7717,7 @@ app5.get("/directive", requireAdminSession, (c) => {
7702
7717
  }
7703
7718
  const dir = directiveStoreDir(sessionId);
7704
7719
  if (!dir) return c.json({ error: "no account" }, 404);
7705
- const path2 = resolve9(join9(dir, name));
7720
+ const path2 = resolve10(join10(dir, name));
7706
7721
  if (!path2.startsWith(dir + sep2)) return c.json({ error: "bad reference" }, 400);
7707
7722
  let body;
7708
7723
  try {
@@ -7716,17 +7731,17 @@ var whatsapp_reader_default = app5;
7716
7731
 
7717
7732
  // server/routes/webchat.ts
7718
7733
  import { basename as basename3, dirname as dirname2 } from "path";
7719
- import { join as join10 } from "path";
7734
+ import { join as join11 } from "path";
7720
7735
  import { readFileSync as readFileSync11, renameSync, writeFileSync as writeFileSync5 } from "fs";
7721
7736
  var WEBCHAT_ADMIN_KEY = "webchat-admin";
7722
7737
  var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
7723
7738
  function locateSession(sessionId) {
7724
7739
  const cfg = claudeConfigDir();
7725
7740
  if (!cfg) return { projectDir: null, channel: null };
7726
- for (const { path: path2 } of enumerateJsonls(join10(cfg, "projects"))) {
7741
+ for (const { path: path2 } of enumerateJsonls(join11(cfg, "projects"))) {
7727
7742
  if (basename3(path2) === `${sessionId}.jsonl`) {
7728
7743
  const dir = dirname2(path2);
7729
- const meta = readSidecarMeta(join10(dir, `${sessionId}.meta.json`));
7744
+ const meta = readSidecarMeta(join11(dir, `${sessionId}.meta.json`));
7730
7745
  return { projectDir: dir, channel: meta.channel };
7731
7746
  }
7732
7747
  }
@@ -7958,7 +7973,7 @@ ${note}` : note;
7958
7973
  console.error(`[webchat:settings] op=${op} outcome=refused value=${value} reason=account-unresolved`);
7959
7974
  return c.json({ error: "account unresolved" }, 503);
7960
7975
  }
7961
- const accountJsonPath = join10(account.accountDir, "account.json");
7976
+ const accountJsonPath = join11(account.accountDir, "account.json");
7962
7977
  try {
7963
7978
  const parsed = JSON.parse(readFileSync11(accountJsonPath, "utf8"));
7964
7979
  if (op === "model") parsed.adminModel = value;
@@ -7998,7 +8013,7 @@ ${note}` : note;
7998
8013
  const cfg = claudeConfigDir();
7999
8014
  let projectDir = null;
8000
8015
  if (cfg) {
8001
- for (const { path: path2 } of enumerateJsonls(join10(cfg, "projects"))) {
8016
+ for (const { path: path2 } of enumerateJsonls(join11(cfg, "projects"))) {
8002
8017
  if (basename3(path2) === `${sessionId}.jsonl`) {
8003
8018
  projectDir = dirname2(path2);
8004
8019
  break;
@@ -8012,11 +8027,11 @@ ${note}` : note;
8012
8027
  }
8013
8028
 
8014
8029
  // server/routes/webchat-greeting.ts
8015
- import { resolve as resolve10 } from "path";
8030
+ import { resolve as resolve11 } from "path";
8016
8031
 
8017
8032
  // app/lib/claude-agent/specialist-roster.ts
8018
8033
  import { existsSync as existsSync8, readFileSync as readFileSync12, readdirSync as readdirSync7 } from "fs";
8019
- import { join as join11 } from "path";
8034
+ import { join as join12 } from "path";
8020
8035
  function field(fm, name) {
8021
8036
  const m = fm.match(new RegExp(`^${name}:\\s*(.*?)\\r?$`, "m"));
8022
8037
  if (!m) return null;
@@ -8035,7 +8050,7 @@ function readSpecialistRoster(specialistsDir) {
8035
8050
  if (!file.endsWith(".md")) continue;
8036
8051
  let raw;
8037
8052
  try {
8038
- raw = readFileSync12(join11(specialistsDir, file), "utf-8");
8053
+ raw = readFileSync12(join12(specialistsDir, file), "utf-8");
8039
8054
  } catch (err) {
8040
8055
  skipped.push({ file, reason: err instanceof Error ? err.message : String(err) });
8041
8056
  continue;
@@ -8117,7 +8132,7 @@ app6.get("/", requireAdminSession, async (c) => {
8117
8132
  let specialists = [];
8118
8133
  try {
8119
8134
  const roster = readSpecialistRoster(
8120
- resolve10(ACCOUNTS_DIR, accountId, "specialists", "agents")
8135
+ resolve11(ACCOUNTS_DIR, accountId, "specialists", "agents")
8121
8136
  );
8122
8137
  specialists = roster.specialists;
8123
8138
  for (const s of roster.skipped) {
@@ -8152,7 +8167,7 @@ var webchat_greeting_default = app6;
8152
8167
 
8153
8168
  // server/routes/telegram.ts
8154
8169
  import { homedir } from "os";
8155
- import { resolve as resolve11, join as join12 } from "path";
8170
+ import { resolve as resolve12, join as join13 } from "path";
8156
8171
  import { existsSync as existsSync9, readFileSync as readFileSync13 } from "fs";
8157
8172
 
8158
8173
  // app/lib/telegram/access-control.ts
@@ -8203,8 +8218,8 @@ function routeTelegramUpdate(input) {
8203
8218
  var TAG22 = "[telegram-inbound]";
8204
8219
  var DISPATCH_TIMEOUT_MS = 12e4;
8205
8220
  function configDirName() {
8206
- const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve11(process.cwd(), "..");
8207
- const brandPath = join12(platformRoot2, "config", "brand.json");
8221
+ const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve12(process.cwd(), "..");
8222
+ const brandPath = join13(platformRoot2, "config", "brand.json");
8208
8223
  if (existsSync9(brandPath)) {
8209
8224
  try {
8210
8225
  return JSON.parse(readFileSync13(brandPath, "utf-8")).configDir ?? ".maxy";
@@ -8215,7 +8230,7 @@ function configDirName() {
8215
8230
  }
8216
8231
  function secretPath(botType) {
8217
8232
  const filename = botType === "admin" ? ".telegram-admin-webhook-secret" : ".telegram-webhook-secret";
8218
- return resolve11(homedir(), configDirName(), filename);
8233
+ return resolve12(homedir(), configDirName(), filename);
8219
8234
  }
8220
8235
  async function sendTelegram(botToken, chatId, text) {
8221
8236
  try {
@@ -8311,7 +8326,7 @@ import { createHash as createHash3, randomUUID as randomUUID7 } from "crypto";
8311
8326
 
8312
8327
  // ../lib/admins-write/src/index.ts
8313
8328
  import { existsSync as existsSync10, readFileSync as readFileSync14, writeFileSync as writeFileSync6, renameSync as renameSync2, mkdirSync as mkdirSync2, readdirSync as readdirSync8, statSync as statSync5 } from "fs";
8314
- import { dirname as dirname3, join as join13 } from "path";
8329
+ import { dirname as dirname3, join as join14 } from "path";
8315
8330
  function logLine(input, result) {
8316
8331
  const userIdShort = input.userId.slice(0, 8);
8317
8332
  console.error(
@@ -8353,7 +8368,7 @@ function writeAdminEntry(input) {
8353
8368
  return result;
8354
8369
  }
8355
8370
  try {
8356
- const accountJsonPath = join13(input.accountDir, "account.json");
8371
+ const accountJsonPath = join14(input.accountDir, "account.json");
8357
8372
  if (!existsSync10(accountJsonPath)) {
8358
8373
  throw new Error(`account.json not found at ${accountJsonPath}`);
8359
8374
  }
@@ -8408,13 +8423,13 @@ function checkAdminAuthInvariant(input) {
8408
8423
  }
8409
8424
  for (const entry of entries) {
8410
8425
  if (entry.startsWith(".")) continue;
8411
- const accountDir = join13(input.accountsDir, entry);
8426
+ const accountDir = join14(input.accountsDir, entry);
8412
8427
  try {
8413
8428
  if (!statSync5(accountDir).isDirectory()) continue;
8414
8429
  } catch {
8415
8430
  continue;
8416
8431
  }
8417
- const accountJsonPath = join13(accountDir, "account.json");
8432
+ const accountJsonPath = join14(accountDir, "account.json");
8418
8433
  if (!existsSync10(accountJsonPath)) continue;
8419
8434
  let admins = [];
8420
8435
  try {
@@ -8703,8 +8718,8 @@ var onboarding_default = app8;
8703
8718
 
8704
8719
  // server/routes/client-error.ts
8705
8720
  import { appendFileSync, existsSync as existsSync12, renameSync as renameSync3, statSync as statSync6 } from "fs";
8706
- import { join as join14 } from "path";
8707
- var CLIENT_ERRORS_LOG = join14(LOG_DIR, "client-errors.log");
8721
+ import { join as join15 } from "path";
8722
+ var CLIENT_ERRORS_LOG = join15(LOG_DIR, "client-errors.log");
8708
8723
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
8709
8724
  var MAX_BODY_SIZE = 8 * 1024;
8710
8725
  var MAX_STACK_LEN = 2e3;
@@ -9030,16 +9045,16 @@ var session_default = app10;
9030
9045
 
9031
9046
  // server/routes/admin/logs.ts
9032
9047
  import { existsSync as existsSync14, readdirSync as readdirSync9, readFileSync as readFileSync16, statSync as statSync7 } from "fs";
9033
- import { resolve as resolve12, basename as basename4 } from "path";
9048
+ import { resolve as resolve13, basename as basename4 } from "path";
9034
9049
 
9035
9050
  // app/lib/logs-read-resolve.ts
9036
9051
  import { existsSync as existsSync13 } from "fs";
9037
- import { join as join15 } from "path";
9052
+ import { join as join16 } from "path";
9038
9053
  function resolveSessionLogPaths(filename, logDirs) {
9039
9054
  const tried = [filename];
9040
9055
  const hits = [];
9041
9056
  for (const dir of logDirs) {
9042
- const fullPath = join15(dir, filename);
9057
+ const fullPath = join16(dir, filename);
9043
9058
  if (existsSync13(fullPath)) {
9044
9059
  hits.push({ path: fullPath, dir });
9045
9060
  }
@@ -9057,7 +9072,7 @@ app11.get("/", async (c) => {
9057
9072
  const cacheKeyParam = c.req.query("cacheKey");
9058
9073
  const download = c.req.query("download") === "1";
9059
9074
  const account = resolveAccount();
9060
- const accountLogDir = account ? resolve12(account.accountDir, "logs") : null;
9075
+ const accountLogDir = account ? resolve13(account.accountDir, "logs") : null;
9061
9076
  const logDirs = [];
9062
9077
  if (accountLogDir) logDirs.push(accountLogDir);
9063
9078
  logDirs.push(LOG_DIR);
@@ -9065,7 +9080,7 @@ app11.get("/", async (c) => {
9065
9080
  const safe = basename4(fileParam);
9066
9081
  const searched = [];
9067
9082
  for (const dir of logDirs) {
9068
- const filePath = resolve12(dir, safe);
9083
+ const filePath = resolve13(dir, safe);
9069
9084
  searched.push(filePath);
9070
9085
  try {
9071
9086
  const buffer = readFileSync16(filePath);
@@ -9177,10 +9192,10 @@ app11.get("/", async (c) => {
9177
9192
  console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
9178
9193
  continue;
9179
9194
  }
9180
- files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync7(resolve12(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
9195
+ files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync7(resolve13(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
9181
9196
  seen.add(name);
9182
9197
  try {
9183
- const content = readFileSync16(resolve12(dir, name));
9198
+ const content = readFileSync16(resolve13(dir, name));
9184
9199
  const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
9185
9200
  logs[name] = tail.trim() || "(empty)";
9186
9201
  } catch (err) {
@@ -9220,7 +9235,7 @@ var claude_info_default = app12;
9220
9235
  // server/routes/admin/attachment.ts
9221
9236
  import { readFile as readFile2, readdir } from "fs/promises";
9222
9237
  import { existsSync as existsSync15 } from "fs";
9223
- import { resolve as resolve13 } from "path";
9238
+ import { resolve as resolve14 } from "path";
9224
9239
  var app13 = new Hono();
9225
9240
  app13.get("/:attachmentId", requireAdminSession, async (c) => {
9226
9241
  const attachmentId = c.req.param("attachmentId");
@@ -9232,11 +9247,11 @@ app13.get("/:attachmentId", requireAdminSession, async (c) => {
9232
9247
  if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(attachmentId)) {
9233
9248
  return new Response("Not found", { status: 404 });
9234
9249
  }
9235
- const dir = resolve13(ATTACHMENTS_ROOT, accountId, attachmentId);
9250
+ const dir = resolve14(ATTACHMENTS_ROOT, accountId, attachmentId);
9236
9251
  if (!existsSync15(dir)) {
9237
9252
  return new Response("Not found", { status: 404 });
9238
9253
  }
9239
- const metaPath = resolve13(dir, `${attachmentId}.meta.json`);
9254
+ const metaPath = resolve14(dir, `${attachmentId}.meta.json`);
9240
9255
  if (!existsSync15(metaPath)) {
9241
9256
  return new Response("Not found", { status: 404 });
9242
9257
  }
@@ -9251,7 +9266,7 @@ app13.get("/:attachmentId", requireAdminSession, async (c) => {
9251
9266
  if (!dataFile) {
9252
9267
  return new Response("Not found", { status: 404 });
9253
9268
  }
9254
- const filePath = resolve13(dir, dataFile);
9269
+ const filePath = resolve14(dir, dataFile);
9255
9270
  const buffer = await readFile2(filePath);
9256
9271
  return new Response(new Uint8Array(buffer), {
9257
9272
  headers: {
@@ -9264,13 +9279,13 @@ app13.get("/:attachmentId", requireAdminSession, async (c) => {
9264
9279
  var attachment_default = app13;
9265
9280
 
9266
9281
  // server/routes/admin/agents.ts
9267
- import { resolve as resolve14 } from "path";
9282
+ import { resolve as resolve15 } from "path";
9268
9283
  import { readdirSync as readdirSync10, readFileSync as readFileSync17, existsSync as existsSync16, rmSync } from "fs";
9269
9284
  var app14 = new Hono();
9270
9285
  app14.get("/", (c) => {
9271
9286
  const account = resolveAccount();
9272
9287
  if (!account) return c.json({ agents: [] });
9273
- const agentsDir = resolve14(account.accountDir, "agents");
9288
+ const agentsDir = resolve15(account.accountDir, "agents");
9274
9289
  if (!existsSync16(agentsDir)) return c.json({ agents: [] });
9275
9290
  const agents = [];
9276
9291
  try {
@@ -9278,7 +9293,7 @@ app14.get("/", (c) => {
9278
9293
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
9279
9294
  if (!entry.isDirectory()) continue;
9280
9295
  if (entry.name === "admin") continue;
9281
- const configPath2 = resolve14(agentsDir, entry.name, "config.json");
9296
+ const configPath2 = resolve15(agentsDir, entry.name, "config.json");
9282
9297
  if (!existsSync16(configPath2)) continue;
9283
9298
  try {
9284
9299
  const config = JSON.parse(readFileSync17(configPath2, "utf-8"));
@@ -9307,7 +9322,7 @@ app14.delete("/:slug", async (c) => {
9307
9322
  if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
9308
9323
  return c.json({ error: "Invalid agent slug" }, 400);
9309
9324
  }
9310
- const agentDir = resolve14(account.accountDir, "agents", slug);
9325
+ const agentDir = resolve15(account.accountDir, "agents", slug);
9311
9326
  if (!existsSync16(agentDir)) {
9312
9327
  return c.json({ error: "Agent not found" }, 404);
9313
9328
  }
@@ -9337,7 +9352,7 @@ app14.post("/:slug/project", async (c) => {
9337
9352
  if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
9338
9353
  return c.json({ error: "Invalid agent slug" }, 400);
9339
9354
  }
9340
- const agentDir = resolve14(account.accountDir, "agents", slug);
9355
+ const agentDir = resolve15(account.accountDir, "agents", slug);
9341
9356
  if (!existsSync16(agentDir)) {
9342
9357
  return c.json({ error: "Agent not found on disk" }, 404);
9343
9358
  }
@@ -10041,7 +10056,7 @@ var sessions_default = app15;
10041
10056
 
10042
10057
  // app/lib/claude-agent/spawn-context.ts
10043
10058
  import { existsSync as existsSync18, readFileSync as readFileSync18, readdirSync as readdirSync11, statSync as statSync8 } from "fs";
10044
- import { dirname as dirname4, resolve as resolve15, join as join16 } from "path";
10059
+ import { dirname as dirname4, resolve as resolve16, join as join17 } from "path";
10045
10060
  async function resolveOwnerProfileBlock(accountId, userId) {
10046
10061
  if (!userId) return { ok: false, reason: "missing-user-id" };
10047
10062
  try {
@@ -10070,8 +10085,8 @@ function frontmatterField(manifest, field2) {
10070
10085
  function extractPluginToolDescriptions(pluginDir) {
10071
10086
  const out = /* @__PURE__ */ new Map();
10072
10087
  const candidates = [
10073
- join16(pluginDir, "mcp/dist/index.js"),
10074
- join16(pluginDir, "mcp/src/index.ts")
10088
+ join17(pluginDir, "mcp/dist/index.js"),
10089
+ join17(pluginDir, "mcp/src/index.ts")
10075
10090
  ];
10076
10091
  let raw = null;
10077
10092
  for (const path2 of candidates) {
@@ -10126,24 +10141,24 @@ function parseSkillPathsFromFrontmatter(fm) {
10126
10141
  }
10127
10142
  function listPluginDirs() {
10128
10143
  const out = /* @__PURE__ */ new Map();
10129
- const platformPlugins = resolve15(PLATFORM_ROOT, "plugins");
10144
+ const platformPlugins = resolve16(PLATFORM_ROOT, "plugins");
10130
10145
  if (existsSync18(platformPlugins)) {
10131
10146
  for (const name of readdirSync11(platformPlugins)) {
10132
- const dir = join16(platformPlugins, name);
10147
+ const dir = join17(platformPlugins, name);
10133
10148
  try {
10134
10149
  if (statSync8(dir).isDirectory()) out.set(name, dir);
10135
10150
  } catch {
10136
10151
  }
10137
10152
  }
10138
10153
  }
10139
- const premiumRoot = resolve15(dirname4(PLATFORM_ROOT), "premium-plugins");
10154
+ const premiumRoot = resolve16(dirname4(PLATFORM_ROOT), "premium-plugins");
10140
10155
  if (existsSync18(premiumRoot)) {
10141
10156
  for (const bundle of readdirSync11(premiumRoot)) {
10142
- const bundlePlugins = join16(premiumRoot, bundle, "plugins");
10157
+ const bundlePlugins = join17(premiumRoot, bundle, "plugins");
10143
10158
  if (!existsSync18(bundlePlugins)) continue;
10144
10159
  try {
10145
10160
  for (const name of readdirSync11(bundlePlugins)) {
10146
- const dir = join16(bundlePlugins, name);
10161
+ const dir = join17(bundlePlugins, name);
10147
10162
  try {
10148
10163
  if (statSync8(dir).isDirectory()) out.set(name, dir);
10149
10164
  } catch {
@@ -10156,7 +10171,7 @@ function listPluginDirs() {
10156
10171
  return out;
10157
10172
  }
10158
10173
  function readEnabledPlugins(accountId) {
10159
- const accountFile = resolve15(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
10174
+ const accountFile = resolve16(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
10160
10175
  if (!existsSync18(accountFile)) return /* @__PURE__ */ new Set();
10161
10176
  try {
10162
10177
  const parsed = JSON.parse(readFileSync18(accountFile, "utf-8"));
@@ -10186,7 +10201,7 @@ function computeActivePlugins(accountId) {
10186
10201
  for (const name of Array.from(enabled).sort()) {
10187
10202
  const dir = pluginDirs.get(name);
10188
10203
  if (!dir) continue;
10189
- const fm = readFrontmatter(join16(dir, "PLUGIN.md"));
10204
+ const fm = readFrontmatter(join17(dir, "PLUGIN.md"));
10190
10205
  if (!fm) continue;
10191
10206
  const description = frontmatterField(`---
10192
10207
  ${fm}
@@ -10203,7 +10218,7 @@ ${fm}
10203
10218
  `plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
10204
10219
  );
10205
10220
  if (toolNames.length > 0 && descMap.size === 0) {
10206
- const hasSource = existsSync18(join16(dir, "mcp/dist/index.js")) || existsSync18(join16(dir, "mcp/src/index.ts"));
10221
+ const hasSource = existsSync18(join17(dir, "mcp/dist/index.js")) || existsSync18(join17(dir, "mcp/src/index.ts"));
10207
10222
  if (hasSource) {
10208
10223
  console.warn(
10209
10224
  `[spawn-context] WARN plugin=${name} mcp source present but tool-description regex matched zero entries \u2014 SDK upgrade may have changed the registration shape`
@@ -10213,7 +10228,7 @@ ${fm}
10213
10228
  const skillPaths = parseSkillPathsFromFrontmatter(fm);
10214
10229
  const skills = [];
10215
10230
  for (const relPath of skillPaths) {
10216
- const skillPath = join16(dir, relPath);
10231
+ const skillPath = join17(dir, relPath);
10217
10232
  const skillFm = readFrontmatter(skillPath);
10218
10233
  if (!skillFm) continue;
10219
10234
  const skillName = frontmatterField(`---
@@ -10229,7 +10244,7 @@ ${skillFm}
10229
10244
  return out;
10230
10245
  }
10231
10246
  function computeSpecialistDomains(accountId) {
10232
- const specialistsDir = resolve15(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
10247
+ const specialistsDir = resolve16(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
10233
10248
  if (!existsSync18(specialistsDir)) return [];
10234
10249
  let entries;
10235
10250
  try {
@@ -10257,7 +10272,7 @@ function computeSpecialistDomains(accountId) {
10257
10272
  const out = [];
10258
10273
  for (const file of entries.sort()) {
10259
10274
  if (!file.endsWith(".md")) continue;
10260
- const fm = readFrontmatter(join16(specialistsDir, file));
10275
+ const fm = readFrontmatter(join17(specialistsDir, file));
10261
10276
  if (!fm) continue;
10262
10277
  const wrapped = `---
10263
10278
  ${fm}
@@ -10275,7 +10290,7 @@ ${fm}
10275
10290
  return out;
10276
10291
  }
10277
10292
  function computeDormantPlugins(accountId) {
10278
- const accountFile = resolve15(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
10293
+ const accountFile = resolve16(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
10279
10294
  if (!existsSync18(accountFile)) return [];
10280
10295
  let enabled;
10281
10296
  try {
@@ -10290,7 +10305,7 @@ function computeDormantPlugins(accountId) {
10290
10305
  );
10291
10306
  return [];
10292
10307
  }
10293
- const pluginsDir = resolve15(PLATFORM_ROOT, "plugins");
10308
+ const pluginsDir = resolve16(PLATFORM_ROOT, "plugins");
10294
10309
  if (!existsSync18(pluginsDir)) return [];
10295
10310
  let entries;
10296
10311
  try {
@@ -10301,7 +10316,7 @@ function computeDormantPlugins(accountId) {
10301
10316
  const out = [];
10302
10317
  for (const name of entries) {
10303
10318
  if (enabled.has(name)) continue;
10304
- const manifestPath = resolve15(pluginsDir, name, "PLUGIN.md");
10319
+ const manifestPath = resolve16(pluginsDir, name, "PLUGIN.md");
10305
10320
  if (!existsSync18(manifestPath)) continue;
10306
10321
  let manifest;
10307
10322
  try {
@@ -10320,7 +10335,7 @@ function computeDormantPlugins(accountId) {
10320
10335
 
10321
10336
  // server/routes/admin/claude-sessions.ts
10322
10337
  import { existsSync as existsSync19, readFileSync as readFileSync19 } from "fs";
10323
- import { resolve as resolve16 } from "path";
10338
+ import { resolve as resolve17 } from "path";
10324
10339
  function readTunnelState(brandConfigDir) {
10325
10340
  const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
10326
10341
  if (!existsSync19(statePath)) return null;
@@ -10336,10 +10351,10 @@ function readTunnelState(brandConfigDir) {
10336
10351
  }
10337
10352
  }
10338
10353
  function resolveTunnelUrl() {
10339
- const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve16(process.cwd(), "..");
10354
+ const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve17(process.cwd(), "..");
10340
10355
  let brand;
10341
10356
  try {
10342
- brand = JSON.parse(readFileSync19(resolve16(platformRoot2, "config", "brand.json"), "utf-8"));
10357
+ brand = JSON.parse(readFileSync19(resolve17(platformRoot2, "config", "brand.json"), "utf-8"));
10343
10358
  } catch {
10344
10359
  return null;
10345
10360
  }
@@ -10584,15 +10599,15 @@ var events_default = app18;
10584
10599
  import { createReadStream as createReadStream2 } from "fs";
10585
10600
  import { readdir as readdir3, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
10586
10601
  import { realpathSync as realpathSync4 } from "fs";
10587
- import { basename as basename6, dirname as dirname5, join as join18, resolve as resolve19, sep as sep5 } from "path";
10602
+ import { basename as basename6, dirname as dirname5, join as join19, resolve as resolve20, sep as sep5 } from "path";
10588
10603
  import { Readable as Readable2 } from "stream";
10589
10604
 
10590
10605
  // app/lib/data-path.ts
10591
10606
  import { realpathSync as realpathSync3 } from "fs";
10592
- import { resolve as resolve17, normalize, sep as sep3, relative } from "path";
10593
- var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve17(process.cwd(), "../platform");
10594
- var DATA_ROOT = resolve17(PLATFORM_ROOT5, "..", "data");
10595
- var CLAUDE_UPLOADS_ROOT = process.env.CLAUDE_CONFIG_DIR ? resolve17(process.env.CLAUDE_CONFIG_DIR, "uploads") : null;
10607
+ import { resolve as resolve18, normalize, sep as sep3, relative } from "path";
10608
+ var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve18(process.cwd(), "../platform");
10609
+ var DATA_ROOT = resolve18(PLATFORM_ROOT5, "..", "data");
10610
+ var CLAUDE_UPLOADS_ROOT = process.env.CLAUDE_CONFIG_DIR ? resolve18(process.env.CLAUDE_CONFIG_DIR, "uploads") : null;
10596
10611
  var ACCOUNT_PARTITION_DIRS = /* @__PURE__ */ new Set(["uploads", "accounts"]);
10597
10612
  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;
10598
10613
  function crossesForeignAccountPartition(relPath, accountId) {
@@ -10605,7 +10620,7 @@ function crossesForeignAccountPartition(relPath, accountId) {
10605
10620
  }
10606
10621
  function resolveUnderRoot(raw, rootAbs, rootLabel) {
10607
10622
  const cleaned = normalize("/" + (raw ?? "").replace(/\\/g, "/")).replace(/^\/+/, "");
10608
- const absolute = resolve17(rootAbs, cleaned);
10623
+ const absolute = resolve18(rootAbs, cleaned);
10609
10624
  let rootReal;
10610
10625
  try {
10611
10626
  rootReal = realpathSync3(rootAbs);
@@ -10964,7 +10979,7 @@ async function cascadeDeleteDocument(params) {
10964
10979
 
10965
10980
  // app/lib/file-index.ts
10966
10981
  import * as fsp from "fs/promises";
10967
- import { resolve as resolve18, relative as relative2, join as join17, basename as basename5, extname as extname2, sep as sep4 } from "path";
10982
+ import { resolve as resolve19, relative as relative2, join as join18, basename as basename5, extname as extname2, sep as sep4 } from "path";
10968
10983
  import { tmpdir as tmpdir2 } from "os";
10969
10984
  import { execFile as execFile2 } from "child_process";
10970
10985
  import { promisify as promisify2 } from "util";
@@ -11035,7 +11050,7 @@ async function extractPdf(absolute) {
11035
11050
  return stdout.trim();
11036
11051
  }
11037
11052
  async function ocrPdf(absolute) {
11038
- const outPdf = join17(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
11053
+ const outPdf = join18(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
11039
11054
  try {
11040
11055
  await execFileAsync2(
11041
11056
  "ocrmypdf",
@@ -11097,7 +11112,7 @@ async function readDisplayName(absolute) {
11097
11112
  const stem = dot === -1 ? base : base.slice(0, dot);
11098
11113
  if (base === `${stem}.meta.json`) return null;
11099
11114
  try {
11100
- const raw = await fsp.readFile(join17(dir, `${stem}.meta.json`), "utf-8");
11115
+ const raw = await fsp.readFile(join18(dir, `${stem}.meta.json`), "utf-8");
11101
11116
  const meta = JSON.parse(raw);
11102
11117
  const dn = meta.displayName ?? meta.filename;
11103
11118
  return typeof dn === "string" && dn.length > 0 ? dn : null;
@@ -11117,7 +11132,7 @@ async function walkSubtree(root, dataRoot, out) {
11117
11132
  let clean = true;
11118
11133
  for (const entry of entries) {
11119
11134
  if (entry.isSymbolicLink()) continue;
11120
- const abs = join17(root, entry.name);
11135
+ const abs = join18(root, entry.name);
11121
11136
  if (entry.isDirectory()) {
11122
11137
  const sub = await walkSubtree(abs, dataRoot, out);
11123
11138
  if (!sub.clean) clean = false;
@@ -11272,8 +11287,8 @@ async function reconcileFileIndex(accountId, opts) {
11272
11287
  return withSession(opts, async (session) => {
11273
11288
  const walked = [];
11274
11289
  const subtreeRoots = [
11275
- resolve18(dataRoot, "uploads", accountId),
11276
- resolve18(dataRoot, "accounts", accountId)
11290
+ resolve19(dataRoot, "uploads", accountId),
11291
+ resolve19(dataRoot, "accounts", accountId)
11277
11292
  ];
11278
11293
  let clean = true;
11279
11294
  for (const root of subtreeRoots) {
@@ -11354,7 +11369,7 @@ async function reconcileFileIndexDebounced(accountId, opts) {
11354
11369
  async function indexFile(accountId, relativePath, opts) {
11355
11370
  const dataRoot = opts?.dataRoot ?? DATA_ROOT;
11356
11371
  const embed2 = opts?.embed ?? embed;
11357
- const absolute = resolve18(dataRoot, relativePath);
11372
+ const absolute = resolve19(dataRoot, relativePath);
11358
11373
  await withSession(opts, async (session) => {
11359
11374
  const st = await fsp.stat(absolute);
11360
11375
  const wf = {
@@ -11388,7 +11403,7 @@ async function dropFileIndex(accountId, relativePath, opts) {
11388
11403
  var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
11389
11404
  async function readMeta(absDir, baseName) {
11390
11405
  try {
11391
- const raw = await readFile4(join18(absDir, `${baseName}.meta.json`), "utf8");
11406
+ const raw = await readFile4(join19(absDir, `${baseName}.meta.json`), "utf8");
11392
11407
  const parsed = JSON.parse(raw);
11393
11408
  if (typeof parsed?.filename === "string") {
11394
11409
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -11399,7 +11414,7 @@ async function readMeta(absDir, baseName) {
11399
11414
  }
11400
11415
  async function readAccountNames() {
11401
11416
  const map = /* @__PURE__ */ new Map();
11402
- const accountsDir = resolve19(DATA_ROOT, "accounts");
11417
+ const accountsDir = resolve20(DATA_ROOT, "accounts");
11403
11418
  let names;
11404
11419
  try {
11405
11420
  names = await readdir3(accountsDir);
@@ -11408,7 +11423,7 @@ async function readAccountNames() {
11408
11423
  }
11409
11424
  for (const name of names) {
11410
11425
  if (!UUID_RE3.test(name)) continue;
11411
- const configPath2 = resolve19(accountsDir, name, "account.json");
11426
+ const configPath2 = resolve20(accountsDir, name, "account.json");
11412
11427
  try {
11413
11428
  const raw = await readFile4(configPath2, "utf8");
11414
11429
  const parsed = JSON.parse(raw);
@@ -11426,7 +11441,7 @@ async function readAccountNames() {
11426
11441
  }
11427
11442
  async function enrich(absolute, entry, accountNames) {
11428
11443
  if (entry.kind === "directory" && UUID_RE3.test(entry.name)) {
11429
- const meta = await readMeta(join18(absolute, entry.name), entry.name);
11444
+ const meta = await readMeta(join19(absolute, entry.name), entry.name);
11430
11445
  if (meta?.filename) {
11431
11446
  entry.displayName = meta.filename;
11432
11447
  entry.mimeType = meta.mimeType;
@@ -11524,7 +11539,7 @@ app19.get("/", requireAdminSession, async (c) => {
11524
11539
  continue;
11525
11540
  }
11526
11541
  try {
11527
- const entryPath = join18(absolute, name);
11542
+ const entryPath = join19(absolute, name);
11528
11543
  const s = await stat4(entryPath);
11529
11544
  entries.push({
11530
11545
  name,
@@ -11649,8 +11664,8 @@ app19.post("/upload", requireAdminSession, async (c) => {
11649
11664
  }
11650
11665
  const safeName = basename6(file.name).replace(/[\0/\\]/g, "_");
11651
11666
  const finalName = `${Date.now()}-${safeName}`;
11652
- const destDir = resolve19(DATA_ROOT, "uploads", accountId);
11653
- const destPath = resolve19(destDir, finalName);
11667
+ const destDir = resolve20(DATA_ROOT, "uploads", accountId);
11668
+ const destPath = resolve20(destDir, finalName);
11654
11669
  try {
11655
11670
  await mkdir3(destDir, { recursive: true });
11656
11671
  const dataRootReal = realpathSync4(DATA_ROOT);
@@ -11715,7 +11730,7 @@ app19.delete("/", requireAdminSession, async (c) => {
11715
11730
  }
11716
11731
  const dot = base.lastIndexOf(".");
11717
11732
  const stem = dot === -1 ? base : base.slice(0, dot);
11718
- const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join18(dirname5(absolute), `${stem}.meta.json`) : null;
11733
+ const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join19(dirname5(absolute), `${stem}.meta.json`) : null;
11719
11734
  await unlink2(absolute);
11720
11735
  if (sidecarPath) {
11721
11736
  try {
@@ -13764,7 +13779,7 @@ var graph_default_view_default = app25;
13764
13779
 
13765
13780
  // server/routes/admin/sidebar-artefacts.ts
13766
13781
  import { readdir as readdir4, stat as stat5 } from "fs/promises";
13767
- import { resolve as resolve20, relative as relative3, isAbsolute, sep as sep6, basename as basename7 } from "path";
13782
+ import { resolve as resolve21, relative as relative3, isAbsolute, sep as sep6, basename as basename7 } from "path";
13768
13783
  import { existsSync as existsSync20 } from "fs";
13769
13784
  var LIMIT = 50;
13770
13785
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
@@ -13784,7 +13799,7 @@ app26.get("/", requireAdminSession, async (c) => {
13784
13799
  if (accountFiles === null) {
13785
13800
  return c.json({ error: "Failed to load artefacts" }, 500);
13786
13801
  }
13787
- const accountDir = resolve20(ACCOUNTS_DIR, accountId);
13802
+ const accountDir = resolve21(ACCOUNTS_DIR, accountId);
13788
13803
  const agents = await fetchAgentTemplateRows(accountDir);
13789
13804
  const artefacts = [...accountFiles, ...agents].sort(
13790
13805
  (a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "")
@@ -13835,8 +13850,8 @@ async function fetchAccountFileArtefacts(accountId) {
13835
13850
  async function fetchAgentTemplateRows(accountDir) {
13836
13851
  const rows = [];
13837
13852
  for (const filename of ADMIN_AGENT_FILES) {
13838
- const overridePath = resolve20(accountDir, "agents", "admin", filename);
13839
- const bundledPath = resolve20(PLATFORM_ROOT, "templates", "agents", "admin", filename);
13853
+ const overridePath = resolve21(accountDir, "agents", "admin", filename);
13854
+ const bundledPath = resolve21(PLATFORM_ROOT, "templates", "agents", "admin", filename);
13840
13855
  const labelStem = filename.replace(/\.md$/, "");
13841
13856
  const row = await readAgentTemplateRow({
13842
13857
  id: `agent-template:admin:${filename}`,
@@ -13849,12 +13864,12 @@ async function fetchAgentTemplateRows(accountDir) {
13849
13864
  });
13850
13865
  if (row) rows.push(row);
13851
13866
  }
13852
- const overrideDir = resolve20(accountDir, "specialists", "agents");
13853
- const bundledDir = resolve20(PLATFORM_ROOT, "templates", "specialists", "agents");
13867
+ const overrideDir = resolve21(accountDir, "specialists", "agents");
13868
+ const bundledDir = resolve21(PLATFORM_ROOT, "templates", "specialists", "agents");
13854
13869
  const specialistNames = await unionSpecialistFilenames(overrideDir, bundledDir);
13855
13870
  for (const filename of specialistNames) {
13856
- const overridePath = resolve20(overrideDir, filename);
13857
- const bundledPath = resolve20(bundledDir, filename);
13871
+ const overridePath = resolve21(overrideDir, filename);
13872
+ const bundledPath = resolve21(bundledDir, filename);
13858
13873
  const row = await readAgentTemplateRow({
13859
13874
  id: `agent-template:specialist:${filename}`,
13860
13875
  displayName: filename.replace(/\.md$/, ""),
@@ -14062,6 +14077,36 @@ app29.post("/", requireAdminSession, async (c) => {
14062
14077
  var session_archive_default = app29;
14063
14078
 
14064
14079
  // server/routes/admin/session-rc-spawn.ts
14080
+ import { randomUUID as randomUUID9 } from "crypto";
14081
+ function resolveSpawnPlan(host, body, mintId = randomUUID9) {
14082
+ const operator = isOperatorHost(host);
14083
+ const resumeId = typeof body.sessionId === "string" && body.sessionId.length > 0 ? body.sessionId : void 0;
14084
+ const name = typeof body.name === "string" && body.name.length > 0 ? body.name : void 0;
14085
+ const webchatBind = resumeId === void 0 || operator;
14086
+ const kind = resumeId === void 0 ? "new" : "resume";
14087
+ const origin = operator ? "operator" : "admin";
14088
+ const payload = {};
14089
+ let sessionId;
14090
+ if (webchatBind) {
14091
+ sessionId = resumeId ?? mintId();
14092
+ const key = `session:${sessionId}`;
14093
+ payload.sessionId = sessionId;
14094
+ payload.role = "admin";
14095
+ payload.channel = "webchat";
14096
+ payload.senderId = key;
14097
+ payload.webchatChannel = webchatChannelDescriptor(key);
14098
+ if (name) payload.name = name;
14099
+ } else {
14100
+ sessionId = resumeId;
14101
+ payload.sessionId = resumeId;
14102
+ if (name) payload.name = name;
14103
+ }
14104
+ return { webchatBind, origin, kind, sessionId, payload };
14105
+ }
14106
+ function shapeWebchatResponse(sessionId, manager) {
14107
+ const outcome = typeof manager?.outcome === "string" ? manager.outcome : "bound";
14108
+ return { sessionId, outcome, target: `/chat?session=${sessionId}` };
14109
+ }
14065
14110
  var app30 = new Hono();
14066
14111
  app30.post("/", requireAdminSession, async (c) => {
14067
14112
  let body;
@@ -14070,19 +14115,26 @@ app30.post("/", requireAdminSession, async (c) => {
14070
14115
  } catch {
14071
14116
  body = {};
14072
14117
  }
14073
- const payload = {};
14074
- if (typeof body.sessionId === "string" && body.sessionId.length > 0) payload.sessionId = body.sessionId;
14075
- if (typeof body.name === "string" && body.name.length > 0) payload.name = body.name;
14118
+ const host = c.req.header("host") ?? "";
14119
+ const plan = resolveSpawnPlan(host, body);
14120
+ const spawnReqId = randomUUID9();
14121
+ console.log(
14122
+ `[chat-spawn] op=request spawnReqId=${spawnReqId} origin=${plan.origin} kind=${plan.kind} sessionId=${plan.kind === "new" ? "new" : plan.sessionId}`
14123
+ );
14124
+ if (plan.webchatBind) {
14125
+ console.log(`[chat-spawn] op=args spawnReqId=${spawnReqId} webchatChannel=present sessionId=${plan.sessionId}`);
14126
+ }
14076
14127
  let res;
14077
14128
  try {
14078
14129
  res = await fetch(`${managerBase3("session-rc-spawn:wrapper")}/rc-spawn`, {
14079
14130
  method: "POST",
14080
14131
  headers: { "content-type": "application/json" },
14081
- body: JSON.stringify(payload)
14132
+ body: JSON.stringify(plan.payload)
14082
14133
  });
14083
14134
  } catch (err) {
14084
14135
  const msg = err instanceof Error ? err.message : String(err);
14085
14136
  console.error(`[session-rc-spawn] manager-unreachable err=${msg}`);
14137
+ console.log(`[chat-spawn] op=exit spawnReqId=${spawnReqId} outcome=spawn-failed`);
14086
14138
  return c.json({ error: `session manager unreachable: ${msg}` }, 502);
14087
14139
  }
14088
14140
  const text = await res.text();
@@ -14093,8 +14145,18 @@ app30.post("/", requireAdminSession, async (c) => {
14093
14145
  }
14094
14146
  if (!res.ok) {
14095
14147
  console.error(`[session-rc-spawn] manager-error status=${res.status} body=${text.slice(0, 200)}`);
14148
+ console.log(`[chat-spawn] op=exit spawnReqId=${spawnReqId} outcome=spawn-failed`);
14096
14149
  return c.json(parsed ?? { error: text }, res.status);
14097
14150
  }
14151
+ if (plan.webchatBind) {
14152
+ const target = `/chat?session=${plan.sessionId}`;
14153
+ console.log(
14154
+ `[chat-spawn] op=acquired spawnReqId=${spawnReqId} pid=${parsed?.spawnedPid ?? "none"} sessionId=${plan.sessionId}`
14155
+ );
14156
+ console.log(`[chat-spawn] op=navigate spawnReqId=${spawnReqId} target=${target}`);
14157
+ console.log(`[chat-spawn] op=exit spawnReqId=${spawnReqId} outcome=bound`);
14158
+ return c.json(shapeWebchatResponse(plan.sessionId, parsed));
14159
+ }
14098
14160
  return c.json(parsed ?? {});
14099
14161
  });
14100
14162
  var session_rc_spawn_default = app30;
@@ -14222,10 +14284,10 @@ var system_stats_default = app31;
14222
14284
 
14223
14285
  // server/routes/admin/health.ts
14224
14286
  import { existsSync as existsSync21, readFileSync as readFileSync20 } from "fs";
14225
- import { resolve as resolve21, join as join19 } from "path";
14226
- var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve21(process.cwd(), "..");
14287
+ import { resolve as resolve22, join as join20 } from "path";
14288
+ var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve22(process.cwd(), "..");
14227
14289
  var brandHostname = "maxy";
14228
- var brandJsonPath = join19(PLATFORM_ROOT6, "config", "brand.json");
14290
+ var brandJsonPath = join20(PLATFORM_ROOT6, "config", "brand.json");
14229
14291
  if (existsSync21(brandJsonPath)) {
14230
14292
  try {
14231
14293
  const brand = JSON.parse(readFileSync20(brandJsonPath, "utf-8"));
@@ -14233,7 +14295,7 @@ if (existsSync21(brandJsonPath)) {
14233
14295
  } catch {
14234
14296
  }
14235
14297
  }
14236
- var VERSION_FILE = resolve21(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
14298
+ var VERSION_FILE = resolve22(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
14237
14299
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
14238
14300
  var PROBE_TIMEOUT_MS = 1e3;
14239
14301
  function readVersion() {
@@ -14289,7 +14351,7 @@ app32.get("/", async (c) => {
14289
14351
  var health_default2 = app32;
14290
14352
 
14291
14353
  // server/routes/admin/linkedin-ingest.ts
14292
- import { randomUUID as randomUUID9 } from "crypto";
14354
+ import { randomUUID as randomUUID10 } from "crypto";
14293
14355
  var TAG25 = "[linkedin-ingest-route]";
14294
14356
  var UUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
14295
14357
  var ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
@@ -14415,7 +14477,7 @@ app33.post("/", requireAdminSession, async (c) => {
14415
14477
  );
14416
14478
  const initialMessage = buildInitialMessage(envelope);
14417
14479
  const spawnStart = Date.now();
14418
- const sessionId = randomUUID9();
14480
+ const sessionId = randomUUID10();
14419
14481
  console.log(TAG25 + " route target=rc-spawn dispatchId=" + envelope.dispatchId + " sessionId=" + sessionId.slice(0, 8));
14420
14482
  const spawned = await managerRcSpawn({
14421
14483
  sessionId,
@@ -14781,13 +14843,13 @@ var admin_default = app39;
14781
14843
  // app/lib/access-gate.ts
14782
14844
  import neo4j4 from "neo4j-driver";
14783
14845
  import { readFileSync as readFileSync21 } from "fs";
14784
- import { resolve as resolve22 } from "path";
14785
- import { randomUUID as randomUUID10 } from "crypto";
14786
- var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve22(process.cwd(), "..");
14846
+ import { resolve as resolve23 } from "path";
14847
+ import { randomUUID as randomUUID11 } from "crypto";
14848
+ var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve23(process.cwd(), "..");
14787
14849
  var driver = null;
14788
14850
  function readPassword() {
14789
14851
  if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
14790
- const passwordFile = resolve22(PLATFORM_ROOT7, "config/.neo4j-password");
14852
+ const passwordFile = resolve23(PLATFORM_ROOT7, "config/.neo4j-password");
14791
14853
  try {
14792
14854
  return readFileSync21(passwordFile, "utf-8").trim();
14793
14855
  } catch {
@@ -14965,7 +15027,7 @@ async function consumeMagicTokenAndActivate(grantId) {
14965
15027
  }
14966
15028
  }
14967
15029
  async function generateNewMagicToken(grantId) {
14968
- const token = randomUUID10();
15030
+ const token = randomUUID11();
14969
15031
  const session = getSession3();
14970
15032
  try {
14971
15033
  const result = await session.run(
@@ -15077,9 +15139,9 @@ var verify_token_default = app40;
15077
15139
 
15078
15140
  // app/lib/access-email.ts
15079
15141
  import { spawn as spawn2 } from "child_process";
15080
- import { resolve as resolve23 } from "path";
15081
- var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT ?? resolve23(process.cwd(), "..");
15082
- var SEND_SCRIPT = resolve23(
15142
+ import { resolve as resolve24 } from "path";
15143
+ var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT ?? resolve24(process.cwd(), "..");
15144
+ var SEND_SCRIPT = resolve24(
15083
15145
  PLATFORM_ROOT8,
15084
15146
  "plugins",
15085
15147
  "email",
@@ -15222,7 +15284,7 @@ var access_default = app42;
15222
15284
 
15223
15285
  // server/routes/sites.ts
15224
15286
  import { existsSync as existsSync22, readFileSync as readFileSync22, realpathSync as realpathSync5, statSync as statSync9 } from "fs";
15225
- import { resolve as resolve24 } from "path";
15287
+ import { resolve as resolve25 } from "path";
15226
15288
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
15227
15289
  var MIME = {
15228
15290
  ".html": "text/html; charset=utf-8",
@@ -15279,8 +15341,8 @@ app43.get("/:rel{.*}", (c) => {
15279
15341
  }
15280
15342
  segments.push(seg);
15281
15343
  }
15282
- const rootDir = resolve24(account.accountDir, "sites");
15283
- let filePath = segments.length === 0 ? rootDir : resolve24(rootDir, ...segments);
15344
+ const rootDir = resolve25(account.accountDir, "sites");
15345
+ let filePath = segments.length === 0 ? rootDir : resolve25(rootDir, ...segments);
15284
15346
  if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
15285
15347
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
15286
15348
  return c.text("Forbidden", 403);
@@ -15300,7 +15362,7 @@ app43.get("/:rel{.*}", (c) => {
15300
15362
  return c.redirect(target, 301);
15301
15363
  }
15302
15364
  if (stat7?.isDirectory()) {
15303
- filePath = resolve24(filePath, "index.html");
15365
+ filePath = resolve25(filePath, "index.html");
15304
15366
  }
15305
15367
  if (!filePath.startsWith(rootDir + "/")) {
15306
15368
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
@@ -15438,7 +15500,7 @@ var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
15438
15500
 
15439
15501
  // app/lib/brand-config.ts
15440
15502
  import { existsSync as existsSync23, readFileSync as readFileSync24 } from "fs";
15441
- import { join as join20 } from "path";
15503
+ import { join as join21 } from "path";
15442
15504
  var cached2 = null;
15443
15505
  var cachedAttempted = false;
15444
15506
  function readBrandConfig() {
@@ -15446,7 +15508,7 @@ function readBrandConfig() {
15446
15508
  cachedAttempted = true;
15447
15509
  const platformRoot2 = process.env.MAXY_PLATFORM_ROOT;
15448
15510
  if (!platformRoot2) return null;
15449
- const brandPath = join20(platformRoot2, "config", "brand.json");
15511
+ const brandPath = join21(platformRoot2, "config", "brand.json");
15450
15512
  if (!existsSync23(brandPath)) return null;
15451
15513
  try {
15452
15514
  cached2 = JSON.parse(readFileSync24(brandPath, "utf-8"));
@@ -15937,14 +15999,14 @@ async function writeEvent(opts) {
15937
15999
  var visitor_event_default = app46;
15938
16000
 
15939
16001
  // server/routes/session.ts
15940
- import { resolve as resolve25 } from "path";
16002
+ import { resolve as resolve26 } from "path";
15941
16003
  import { existsSync as existsSync24, writeFileSync as writeFileSync9, mkdirSync as mkdirSync5 } from "fs";
15942
16004
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
15943
16005
  function writeBrandingCache(accountId, agentSlug, branding) {
15944
16006
  try {
15945
- const cacheDir = resolve25(MAXY_DIR, "branding-cache", accountId);
16007
+ const cacheDir = resolve26(MAXY_DIR, "branding-cache", accountId);
15946
16008
  mkdirSync5(cacheDir, { recursive: true });
15947
- writeFileSync9(resolve25(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
16009
+ writeFileSync9(resolve26(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
15948
16010
  } catch (err) {
15949
16011
  console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
15950
16012
  }
@@ -16032,8 +16094,8 @@ app47.post("/", async (c) => {
16032
16094
  }
16033
16095
  let agentConfig = null;
16034
16096
  if (account) {
16035
- const agentDir = resolve25(account.accountDir, "agents", agentSlug);
16036
- if (!existsSync24(agentDir) || !existsSync24(resolve25(agentDir, "config.json"))) {
16097
+ const agentDir = resolve26(account.accountDir, "agents", agentSlug);
16098
+ if (!existsSync24(agentDir) || !existsSync24(resolve26(agentDir, "config.json"))) {
16037
16099
  return c.json({ error: "Agent not found" }, 404);
16038
16100
  }
16039
16101
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -16313,7 +16375,7 @@ function startGraphHealthTimer() {
16313
16375
 
16314
16376
  // app/lib/file-watcher.ts
16315
16377
  import * as fsp2 from "fs/promises";
16316
- import { resolve as resolve26, sep as sep7 } from "path";
16378
+ import { resolve as resolve27, sep as sep7 } from "path";
16317
16379
  var ACCOUNT_UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16318
16380
  var DEFAULT_COALESCE_MS = 500;
16319
16381
  var ROOTS = ["uploads", "accounts"];
@@ -16332,7 +16394,7 @@ async function startFileWatcher(opts = {}) {
16332
16394
  const dropFn = opts.drop ?? dropFileIndex;
16333
16395
  for (const r of ROOTS) {
16334
16396
  try {
16335
- await fsp2.mkdir(resolve26(dataRoot, r), { recursive: true });
16397
+ await fsp2.mkdir(resolve27(dataRoot, r), { recursive: true });
16336
16398
  } catch (err) {
16337
16399
  console.error(
16338
16400
  `[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
@@ -16353,7 +16415,7 @@ async function startFileWatcher(opts = {}) {
16353
16415
  timers.set(relativePath, t);
16354
16416
  }
16355
16417
  async function runHook(relativePath, accountId) {
16356
- const absolute = resolve26(dataRoot, relativePath);
16418
+ const absolute = resolve27(dataRoot, relativePath);
16357
16419
  let exists = false;
16358
16420
  try {
16359
16421
  const st = await fsp2.stat(absolute);
@@ -16377,7 +16439,7 @@ async function startFileWatcher(opts = {}) {
16377
16439
  }
16378
16440
  }
16379
16441
  async function watchRoot(rootName) {
16380
- const absRoot = resolve26(dataRoot, rootName);
16442
+ const absRoot = resolve27(dataRoot, rootName);
16381
16443
  try {
16382
16444
  const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
16383
16445
  for await (const event of iter) {
@@ -17272,7 +17334,7 @@ function broadcastAdminShutdown(reason) {
17272
17334
  // ../lib/entitlement/src/index.ts
17273
17335
  import { createPublicKey, createHash as createHash5, verify as cryptoVerify } from "crypto";
17274
17336
  import { existsSync as existsSync25, readFileSync as readFileSync25, statSync as statSync10 } from "fs";
17275
- import { resolve as resolve27 } from "path";
17337
+ import { resolve as resolve28 } from "path";
17276
17338
 
17277
17339
  // ../lib/entitlement/src/canonicalize.ts
17278
17340
  function canonicalize(value) {
@@ -17307,7 +17369,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
17307
17369
  var GRACE_DAYS = 7;
17308
17370
  var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
17309
17371
  function pubkeyPath(brand) {
17310
- return resolve27(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
17372
+ return resolve28(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
17311
17373
  }
17312
17374
  var memo = null;
17313
17375
  function memoKey(mtimeMs, account) {
@@ -17319,7 +17381,7 @@ function resolveEntitlement(brand, account) {
17319
17381
  if (brand.commercialMode !== true) {
17320
17382
  return logResolved(implicitTrust(account), null);
17321
17383
  }
17322
- const entitlementPath = resolve27(brand.configDir, "entitlement.json");
17384
+ const entitlementPath = resolve28(brand.configDir, "entitlement.json");
17323
17385
  if (!existsSync25(entitlementPath)) {
17324
17386
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
17325
17387
  }
@@ -17510,7 +17572,7 @@ function clientFrom(c) {
17510
17572
  );
17511
17573
  }
17512
17574
  var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT || "";
17513
- var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join21(PLATFORM_ROOT9, "config", "brand.json") : "";
17575
+ var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join22(PLATFORM_ROOT9, "config", "brand.json") : "";
17514
17576
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
17515
17577
  if (BRAND_JSON_PATH && !existsSync26(BRAND_JSON_PATH)) {
17516
17578
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
@@ -17536,7 +17598,7 @@ var brandLoginOpts = {
17536
17598
  bodyFont: BRAND.defaultFonts?.body,
17537
17599
  logoContainsName: !!BRAND.logoContainsName
17538
17600
  };
17539
- var ALIAS_DOMAINS_PATH = join21(homedir3(), BRAND.configDir, "alias-domains.json");
17601
+ var ALIAS_DOMAINS_PATH = join22(homedir3(), BRAND.configDir, "alias-domains.json");
17540
17602
  function loadAliasDomains() {
17541
17603
  try {
17542
17604
  if (!existsSync26(ALIAS_DOMAINS_PATH)) return null;
@@ -17568,7 +17630,7 @@ var app48 = new Hono();
17568
17630
  var nativeFileFollowers = /* @__PURE__ */ new Map();
17569
17631
  var waGateway = new WaGateway({
17570
17632
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
17571
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve28(process.env.MAXY_PLATFORM_ROOT ?? join21(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
17633
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve29(process.env.MAXY_PLATFORM_ROOT ?? join22(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
17572
17634
  // Task 751 — file delivery on the native channel: resolve the platform
17573
17635
  // account + path validation here and funnel through the shared send core.
17574
17636
  sendDocument: async ({ senderId, accountId, filePath, caption }) => {
@@ -17584,7 +17646,7 @@ var waGateway = new WaGateway({
17584
17646
  caption,
17585
17647
  accountId,
17586
17648
  maxyAccountId,
17587
- platformRoot: resolve28(process.env.MAXY_PLATFORM_ROOT ?? join21(__dirname, ".."))
17649
+ platformRoot: resolve29(process.env.MAXY_PLATFORM_ROOT ?? join22(__dirname, ".."))
17588
17650
  });
17589
17651
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
17590
17652
  },
@@ -17623,8 +17685,8 @@ var waGateway = new WaGateway({
17623
17685
  app48.route("/", waGateway.routes());
17624
17686
  waGateway.startSweeper();
17625
17687
  var webchatGateway = new WebchatGateway({
17626
- gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
17627
- serverPath: process.env.MAXY_WEBCHAT_CHANNEL_SERVER_PATH ?? resolve28(process.env.MAXY_PLATFORM_ROOT ?? join21(__dirname, ".."), "services/webchat-channel/dist/server.js"),
17688
+ gatewayUrl: webchatGatewayUrl(),
17689
+ serverPath: webchatServerPath(),
17628
17690
  ensureChannelSession: async ({ accountId, key, role, gatewayUrl, serverPath, sessionId }) => {
17629
17691
  if (role !== "admin") {
17630
17692
  console.error(`[webchat:inbound] op=spawn-refused key=${key} role=${role} reason=public-path-not-wired`);
@@ -17965,8 +18027,8 @@ app48.get("/agent-assets/:slug/:filename", (c) => {
17965
18027
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
17966
18028
  return c.text("Not found", 404);
17967
18029
  }
17968
- const filePath = resolve28(account.accountDir, "agents", slug, "assets", filename);
17969
- const expectedDir = resolve28(account.accountDir, "agents", slug, "assets");
18030
+ const filePath = resolve29(account.accountDir, "agents", slug, "assets", filename);
18031
+ const expectedDir = resolve29(account.accountDir, "agents", slug, "assets");
17970
18032
  if (!filePath.startsWith(expectedDir + "/")) {
17971
18033
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
17972
18034
  return c.text("Forbidden", 403);
@@ -17995,8 +18057,8 @@ app48.get("/generated/:filename", (c) => {
17995
18057
  console.error(`[generated] serve file=${filename} status=404`);
17996
18058
  return c.text("Not found", 404);
17997
18059
  }
17998
- const filePath = resolve28(account.accountDir, "generated", filename);
17999
- const expectedDir = resolve28(account.accountDir, "generated");
18060
+ const filePath = resolve29(account.accountDir, "generated", filename);
18061
+ const expectedDir = resolve29(account.accountDir, "generated");
18000
18062
  if (!filePath.startsWith(expectedDir + "/")) {
18001
18063
  console.error(`[generated] serve file=${filename} status=403`);
18002
18064
  return c.text("Forbidden", 403);
@@ -18040,7 +18102,7 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
18040
18102
  function readInstalledVersion() {
18041
18103
  try {
18042
18104
  if (!PLATFORM_ROOT9) return "unknown";
18043
- const versionFile = join21(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
18105
+ const versionFile = join22(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
18044
18106
  if (!existsSync26(versionFile)) return "unknown";
18045
18107
  const content = readFileSync26(versionFile, "utf-8").trim();
18046
18108
  return content || "unknown";
@@ -18083,7 +18145,7 @@ var clientErrorReporterScript = `<script>
18083
18145
  function cachedHtml(file) {
18084
18146
  let html = htmlCache.get(file);
18085
18147
  if (!html) {
18086
- html = readFileSync26(resolve28(process.cwd(), "public", file), "utf-8");
18148
+ html = readFileSync26(resolve29(process.cwd(), "public", file), "utf-8");
18087
18149
  const productNameEsc = escapeHtml(BRAND.productName);
18088
18150
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
18089
18151
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -18099,11 +18161,11 @@ ${clientErrorReporterScript}
18099
18161
  }
18100
18162
  var brandedHtmlCache = /* @__PURE__ */ new Map();
18101
18163
  function loadBrandingCache(agentSlug) {
18102
- const configDir2 = join21(homedir3(), BRAND.configDir);
18164
+ const configDir2 = join22(homedir3(), BRAND.configDir);
18103
18165
  try {
18104
18166
  const accountId = getDefaultAccountId();
18105
18167
  if (!accountId) return null;
18106
- const cachePath = join21(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
18168
+ const cachePath = join22(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
18107
18169
  if (!existsSync26(cachePath)) return null;
18108
18170
  return JSON.parse(readFileSync26(cachePath, "utf-8"));
18109
18171
  } catch {
@@ -18150,6 +18212,10 @@ function agentUnavailableHtml() {
18150
18212
  }
18151
18213
  app48.get("/", (c) => {
18152
18214
  const host = (c.req.header("host") ?? "").split(":")[0];
18215
+ if (isOperatorHost(host)) {
18216
+ console.log(`[host-class] host=${host} class=operator served=operator.html`);
18217
+ return c.html(cachedHtml("operator.html"));
18218
+ }
18153
18219
  if (isPublicHost(host)) {
18154
18220
  const defaultSlug = resolveDefaultSlug();
18155
18221
  if (!defaultSlug) {
@@ -18162,6 +18228,7 @@ app48.get("/", (c) => {
18162
18228
  console.error(`[public-root] op=serve-default slug=${defaultSlug}`);
18163
18229
  return c.html(brandedPublicHtml(defaultSlug));
18164
18230
  }
18231
+ console.log(`[host-class] host=${host} class=admin served=index.html`);
18165
18232
  return c.html(cachedHtml("index.html"));
18166
18233
  });
18167
18234
  app48.get("/public", (c) => {
@@ -18193,7 +18260,7 @@ app48.use("/vnc-popout.html", logViewerFetch);
18193
18260
  app48.get("/vnc-popout.html", (c) => {
18194
18261
  let html = htmlCache.get("vnc-popout.html");
18195
18262
  if (!html) {
18196
- html = readFileSync26(resolve28(process.cwd(), "public", "vnc-popout.html"), "utf-8");
18263
+ html = readFileSync26(resolve29(process.cwd(), "public", "vnc-popout.html"), "utf-8");
18197
18264
  const name = escapeHtml(BRAND.productName);
18198
18265
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
18199
18266
  html = html.replace("</head>", ` ${brandScript}
@@ -18229,7 +18296,7 @@ app48.get("/g/:slug", (c) => {
18229
18296
  });
18230
18297
  app48.get("/graph", (c) => {
18231
18298
  const host = (c.req.header("host") ?? "").split(":")[0];
18232
- if (isPublicHost(host)) return c.text("Not found", 404);
18299
+ if (isPublicHost(host) || isOperatorHost(host)) return c.text("Not found", 404);
18233
18300
  return c.html(cachedHtml("graph.html"));
18234
18301
  });
18235
18302
  app48.get("/chat", (c) => {
@@ -18244,7 +18311,7 @@ app48.get("/data", (c) => {
18244
18311
  });
18245
18312
  app48.get("/browser", (c) => {
18246
18313
  const host = (c.req.header("host") ?? "").split(":")[0];
18247
- if (isPublicHost(host)) return c.text("Not found", 404);
18314
+ if (isPublicHost(host) || isOperatorHost(host)) return c.text("Not found", 404);
18248
18315
  return c.html(cachedHtml("browser.html"));
18249
18316
  });
18250
18317
  app48.get("/:slug", async (c, next) => {
@@ -18463,7 +18530,7 @@ if (bootAccountConfig?.whatsapp) {
18463
18530
  }
18464
18531
  init({
18465
18532
  configDir: configDirForWhatsApp,
18466
- platformRoot: resolve28(process.env.MAXY_PLATFORM_ROOT ?? join21(__dirname, "..")),
18533
+ platformRoot: resolve29(process.env.MAXY_PLATFORM_ROOT ?? join22(__dirname, "..")),
18467
18534
  accountConfig: bootAccountConfig,
18468
18535
  onMessage: async (msg) => {
18469
18536
  if (msg.isOwnerMirror) {