@rubytech/create-maxy-code 0.1.308 → 0.1.309

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 (179) hide show
  1. package/dist/__tests__/claude-ptys-slice.test.js +1 -1
  2. package/dist/__tests__/cloudflared-slice.test.js +1 -1
  3. package/dist/__tests__/macos-darwin-branch.test.js +4 -6
  4. package/package.json +1 -1
  5. package/payload/platform/lib/admin-access-password/__tests__/index.test.ts +28 -0
  6. package/payload/platform/lib/admin-access-password/dist/index.d.ts +9 -0
  7. package/payload/platform/lib/admin-access-password/dist/index.d.ts.map +1 -1
  8. package/payload/platform/lib/admin-access-password/dist/index.js +26 -0
  9. package/payload/platform/lib/admin-access-password/dist/index.js.map +1 -1
  10. package/payload/platform/lib/admin-access-password/src/index.ts +24 -0
  11. package/payload/platform/lib/models/dist/index.d.ts +7 -0
  12. package/payload/platform/lib/models/dist/index.d.ts.map +1 -1
  13. package/payload/platform/lib/models/dist/index.js +10 -0
  14. package/payload/platform/lib/models/dist/index.js.map +1 -1
  15. package/payload/platform/lib/models/src/index.ts +10 -0
  16. package/payload/platform/plugins/admin/mcp/dist/index.js +4 -1
  17. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  18. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +21 -1
  19. package/payload/platform/plugins/docs/references/admin-ui.md +20 -0
  20. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +1 -0
  21. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  22. package/payload/platform/services/claude-session-manager/dist/http-server.js +11 -0
  23. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  24. package/payload/server/{chunk-FBGIHWWM.js → chunk-J6WDAWFJ.js} +20 -0
  25. package/payload/server/maxy-edge.js +1 -1
  26. package/payload/server/public/assets/AccessGate-CU4Qw6M6.js +1 -0
  27. package/payload/server/public/assets/AdminLoginScreens-DUpRIM1h.js +1 -0
  28. package/payload/server/public/assets/AdminShell-DkoQSsqo.js +1 -0
  29. package/payload/server/public/assets/{Checkbox-8elc7oXU.js → Checkbox-DMA1hVhn.js} +1 -1
  30. package/payload/server/public/assets/OperatorConversations-BIHiyyxU.js +1 -0
  31. package/payload/server/public/assets/admin-BHvOMcCh.js +1 -0
  32. package/payload/server/public/assets/{arc-DxSm8tli.js → arc-Dl9QFDgW.js} +1 -1
  33. package/payload/server/public/assets/architecture-YZFGNWBL-Crq5RSDG.js +1 -0
  34. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-7JSAh0vL.js → architectureDiagram-Q4EWVU46-CNLQUVi9.js} +1 -1
  35. package/payload/server/public/assets/{audio-attachment-mime-DzbKNqbH.js → audio-attachment-mime-DOBET-W1.js} +3 -3
  36. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DLoVmHKD.js → blockDiagram-DXYQGD6D-B-QxfVjk.js} +1 -1
  37. package/payload/server/public/assets/brand-4F9ZXBF8.css +1 -0
  38. package/payload/server/public/assets/{brand-Dh5UlVO2.js → brand-C7kj0USi.js} +1 -1
  39. package/payload/server/public/assets/browser-eLSiC7_b.js +1 -0
  40. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-Nv1G0o9P.js → c4Diagram-AHTNJAMY-NuYFvPDU.js} +1 -1
  41. package/payload/server/public/assets/channel-KT66MFN2.js +1 -0
  42. package/payload/server/public/assets/chat-DedpVKUl.js +1 -0
  43. package/payload/server/public/assets/{chunk-2KRD3SAO-BpqPMhoA.js → chunk-2KRD3SAO-l5VL1KQm.js} +1 -1
  44. package/payload/server/public/assets/{chunk-336JU56O-DgXHlVU_.js → chunk-336JU56O-C5gVznC2.js} +2 -2
  45. package/payload/server/public/assets/chunk-426QAEUC-CWMiOm8Y.js +1 -0
  46. package/payload/server/public/assets/{chunk-4BX2VUAB-nwyZSZH8.js → chunk-4BX2VUAB-BtMVz_Sq.js} +1 -1
  47. package/payload/server/public/assets/{chunk-4TB4RGXK-Tfxz9LHX.js → chunk-4TB4RGXK-C8-dmCuT.js} +1 -1
  48. package/payload/server/public/assets/{chunk-55IACEB6-6FMJQGXG.js → chunk-55IACEB6-C5gWvEJW.js} +1 -1
  49. package/payload/server/public/assets/{chunk-5FUZZQ4R-g2FgZF3D.js → chunk-5FUZZQ4R-BZ7VZoAC.js} +1 -1
  50. package/payload/server/public/assets/{chunk-5PVQY5BW-DtLwXsPH.js → chunk-5PVQY5BW-C_ajQOGC.js} +1 -1
  51. package/payload/server/public/assets/{chunk-67CJDMHE-K91CP5ZU.js → chunk-67CJDMHE-BJOR2dwK.js} +1 -1
  52. package/payload/server/public/assets/{chunk-7N4EOEYR-BGpCQhqK.js → chunk-7N4EOEYR-DvZLpquX.js} +1 -1
  53. package/payload/server/public/assets/{chunk-AA7GKIK3-jkDbInck.js → chunk-AA7GKIK3-h5tVsPlW.js} +1 -1
  54. package/payload/server/public/assets/{chunk-BSJP7CBP-mDosdzGs.js → chunk-BSJP7CBP-DLOF2-m3.js} +1 -1
  55. package/payload/server/public/assets/{chunk-CIAEETIT-DhBxewpQ.js → chunk-CIAEETIT-CQRQMPCf.js} +1 -1
  56. package/payload/server/public/assets/{chunk-EDXVE4YY-B7c-9Emg.js → chunk-EDXVE4YY-K9-EfuM2.js} +1 -1
  57. package/payload/server/public/assets/{chunk-ENJZ2VHE-Cqhhncox.js → chunk-ENJZ2VHE-DVoy6NvU.js} +1 -1
  58. package/payload/server/public/assets/{chunk-FMBD7UC4-BpDq6wj1.js → chunk-FMBD7UC4-CQn_2o2b.js} +1 -1
  59. package/payload/server/public/assets/{chunk-FOC6F5B3-Ds02-ktu.js → chunk-FOC6F5B3-CuN73goS.js} +1 -1
  60. package/payload/server/public/assets/{chunk-ICPOFSXX-BTX5POFr.js → chunk-ICPOFSXX-CKhl9J-H.js} +2 -2
  61. package/payload/server/public/assets/{chunk-K5T4RW27-Du1PXXBU.js → chunk-K5T4RW27-CBskuQmq.js} +1 -1
  62. package/payload/server/public/assets/{chunk-KGLVRYIC-siasOAf8.js → chunk-KGLVRYIC-Chtjt8xK.js} +1 -1
  63. package/payload/server/public/assets/{chunk-LIHQZDEY-xf1rbZtf.js → chunk-LIHQZDEY-EOBiBNSH.js} +1 -1
  64. package/payload/server/public/assets/{chunk-ORNJ4GCN-DeTLQ_LD.js → chunk-ORNJ4GCN-uPPq-5MN.js} +1 -1
  65. package/payload/server/public/assets/{chunk-OYMX7WX6-DQ7_oVJn.js → chunk-OYMX7WX6-BRzbxJOT.js} +1 -1
  66. package/payload/server/public/assets/chunk-QZHKN3VN-DCzpF46A.js +1 -0
  67. package/payload/server/public/assets/{chunk-U2HBQHQK-CXmFUKgn.js → chunk-U2HBQHQK-Bndyn5nF.js} +1 -1
  68. package/payload/server/public/assets/{chunk-X2U36JSP-Bj8-8Wkz.js → chunk-X2U36JSP-BspGBHXW.js} +1 -1
  69. package/payload/server/public/assets/{chunk-XPW4576I-Con3TXqt.js → chunk-XPW4576I-HgXQ2k9h.js} +1 -1
  70. package/payload/server/public/assets/{chunk-YZCP3GAM-Dx8BHGWf.js → chunk-YZCP3GAM-C7oTyCnw.js} +1 -1
  71. package/payload/server/public/assets/{chunk-ZZ45TVLE-Dp4Q5Y-f.js → chunk-ZZ45TVLE-CufWa7QL.js} +1 -1
  72. package/payload/server/public/assets/classDiagram-6PBFFD2Q-QOU4HzJJ.js +1 -0
  73. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DcOUai3Z.js +1 -0
  74. package/payload/server/public/assets/clone-CHh05KN-.js +1 -0
  75. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-pZiCv69E.js → cose-bilkent-S5V4N54A-BM3yEbF-.js} +1 -1
  76. package/payload/server/public/assets/{dagre-CLqhEgbL.js → dagre-C7WHNZO8.js} +1 -1
  77. package/payload/server/public/assets/{dagre-KV5264BT-BCxE8iyk.js → dagre-KV5264BT-bcZx3l06.js} +1 -1
  78. package/payload/server/public/assets/data-BcoBY39U.js +1 -0
  79. package/payload/server/public/assets/{diagram-5BDNPKRD-slUEdZzz.js → diagram-5BDNPKRD-B7VotaMF.js} +1 -1
  80. package/payload/server/public/assets/{diagram-G4DWMVQ6-DPcraMfu.js → diagram-G4DWMVQ6-CWWvEsFx.js} +1 -1
  81. package/payload/server/public/assets/{diagram-MMDJMWI5-DR6luhGK.js → diagram-MMDJMWI5-DYHVkTYJ.js} +1 -1
  82. package/payload/server/public/assets/{diagram-TYMM5635-Jap1B4wA.js → diagram-TYMM5635-CHeB6Ama.js} +1 -1
  83. package/payload/server/public/assets/{dist-Dbh7HrZX.js → dist-CjjtmoWL.js} +1 -1
  84. package/payload/server/public/assets/{erDiagram-SMLLAGMA-DJKUs2hO.js → erDiagram-SMLLAGMA-C9gog8QP.js} +1 -1
  85. package/payload/server/public/assets/{flatten-Cl1Bc3dR.js → flatten-QcJDm7yK.js} +1 -1
  86. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-C8W-ZZ9W.js → flowDiagram-DWJPFMVM-B2O9lKTh.js} +1 -1
  87. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-DYCX4Xu2.js → ganttDiagram-T4ZO3ILL-DEa4AwbR.js} +1 -1
  88. package/payload/server/public/assets/gitGraph-7Q5UKJZL-BC-u4jgy.js +1 -0
  89. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CZu_fpgS.js → gitGraphDiagram-UUTBAWPF-BjXPQpBL.js} +1 -1
  90. package/payload/server/public/assets/{graph-DKSjcpmR.js → graph-C7Hye_vp.js} +2 -2
  91. package/payload/server/public/assets/{graph-labels-CVWPQgBV.js → graph-labels-YYgGsEVd.js} +1 -1
  92. package/payload/server/public/assets/{graphlib-Bdp7TA4y.js → graphlib-CBevn2DP.js} +1 -1
  93. package/payload/server/public/assets/info-OMHHGYJF-DPUetTz-.js +1 -0
  94. package/payload/server/public/assets/infoDiagram-42DDH7IO-q2dl09-M.js +2 -0
  95. package/payload/server/public/assets/{isEmpty-D1pGOD1J.js → isEmpty-BO6BAEn7.js} +1 -1
  96. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-B7KfIX6z.js → ishikawaDiagram-UXIWVN3A-CPLfpvqv.js} +1 -1
  97. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CSDwBfhF.js → journeyDiagram-VCZTEJTY-CTHe8MiD.js} +1 -1
  98. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-CWzcEKTr.js → kanban-definition-6JOO6SKY-Bm9h1O3Y.js} +1 -1
  99. package/payload/server/public/assets/{line-BNQSlbYn.js → line-C31b0rtY.js} +1 -1
  100. package/payload/server/public/assets/{linear-BN6kGN93.js → linear-Cfm_8_pU.js} +1 -1
  101. package/payload/server/public/assets/{mermaid-parser.core-CcFhkElq.js → mermaid-parser.core-B3tGwOcE.js} +2 -2
  102. package/payload/server/public/assets/{mermaid.core-BsIeJ7Cc.js → mermaid.core-BM3s85ZW.js} +3 -3
  103. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CQVzj6D_.js → mindmap-definition-QFDTVHPH-CaGv_mIB.js} +1 -1
  104. package/payload/server/public/assets/operator-WsXhcbBF.js +1 -0
  105. package/payload/server/public/assets/{ordinal-CBZeH4Yp.js → ordinal-jLCwuvYg.js} +1 -1
  106. package/payload/server/public/assets/packet-4T2RLAQJ-BcfR-ZwA.js +1 -0
  107. package/payload/server/public/assets/page-BhHTnqv4.js +1 -0
  108. package/payload/server/public/assets/pie-ZZUOXDRM-BiKgZdNB.js +1 -0
  109. package/payload/server/public/assets/{pieDiagram-DEJITSTG-DnrQ9fyn.js → pieDiagram-DEJITSTG-BhAXps4u.js} +1 -1
  110. package/payload/server/public/assets/public-ViXjC_dA.js +6 -0
  111. package/payload/server/public/assets/public-next-BKECyMz2.js +1 -0
  112. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-BQWlCyWi.js → quadrantDiagram-34T5L4WZ-BWtTdNs8.js} +1 -1
  113. package/payload/server/public/assets/radar-PYXPWWZC-nvCjiW_J.js +1 -0
  114. package/payload/server/public/assets/{reduce-PuPlFPRX.js → reduce-Dmi_NdVH.js} +1 -1
  115. package/payload/server/public/assets/{requirementDiagram-MS252O5E-Du_vZhU1.js → requirementDiagram-MS252O5E-CWU0qCcP.js} +1 -1
  116. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-Cf6Z8GPQ.js → sankeyDiagram-XADWPNL6-DYvutQld.js} +1 -1
  117. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-CS8GVol8.js → sequenceDiagram-FGHM5R23-Cir0hBWS.js} +1 -1
  118. package/payload/server/public/assets/{src-BoaldmnP.js → src-CwB968DO.js} +1 -1
  119. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-Bv1NW2F1.js → stateDiagram-FHFEXIEX-Be-h8YSS.js} +1 -1
  120. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CAnmjSj7.js +1 -0
  121. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-ClGYAsr0.js → timeline-definition-GMOUNBTQ-C3C4Wuyk.js} +1 -1
  122. package/payload/server/public/assets/treeView-SZITEDCU-BinXCVyM.js +1 -0
  123. package/payload/server/public/assets/treemap-W4RFUUIX-CSmh20Ze.js +1 -0
  124. package/payload/server/public/assets/{useSelectionMode-FIodJKzS.js → useSelectionMode-CG_Iel5F.js} +1 -1
  125. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-C2wTcxQT.js → vennDiagram-DHZGUBPP-mDclw0Sa.js} +1 -1
  126. package/payload/server/public/assets/wardley-RL74JXVD-BiCmRKWx.js +1 -0
  127. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-D86-ivEx.js → wardleyDiagram-NUSXRM2D-mvk-YA9g.js} +1 -1
  128. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-Ba5WAN8P.js → xychartDiagram-5P7HB3ND-9M7k1hmD.js} +1 -1
  129. package/payload/server/public/browser.html +8 -8
  130. package/payload/server/public/chat.html +11 -11
  131. package/payload/server/public/data.html +7 -7
  132. package/payload/server/public/graph.html +10 -10
  133. package/payload/server/public/index.html +10 -10
  134. package/payload/server/public/operator.html +13 -13
  135. package/payload/server/public/public-next.html +24 -0
  136. package/payload/server/public/public.html +9 -8
  137. package/payload/server/server.js +819 -614
  138. package/dist/__tests__/onboarding-state-readback.test.js +0 -61
  139. package/dist/__tests__/rss-sampler-installer.test.js +0 -27
  140. package/dist/onboarding-readback.js +0 -27
  141. package/payload/server/public/assets/AdminLoginScreens-BZIA9Z6o.js +0 -1
  142. package/payload/server/public/assets/AdminShell-iazLHsk7.js +0 -1
  143. package/payload/server/public/assets/admin-BEx6o3fa.js +0 -1
  144. package/payload/server/public/assets/architecture-YZFGNWBL-6g9jRVgc.js +0 -1
  145. package/payload/server/public/assets/brand-CmMZe4RK.css +0 -1
  146. package/payload/server/public/assets/browser-D16sPVkI.js +0 -1
  147. package/payload/server/public/assets/channel-BgQLJanG.js +0 -1
  148. package/payload/server/public/assets/chat-x4PnXhkd.js +0 -1
  149. package/payload/server/public/assets/chunk-426QAEUC-Dr_XVuUq.js +0 -1
  150. package/payload/server/public/assets/chunk-QZHKN3VN-DF4o9HRJ.js +0 -1
  151. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DAbPKU6u.js +0 -1
  152. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BKuFQLcv.js +0 -1
  153. package/payload/server/public/assets/clone-DnNHGhNe.js +0 -1
  154. package/payload/server/public/assets/data-DqG45sq0.js +0 -1
  155. package/payload/server/public/assets/file-download-BvGS7Qmi.js +0 -1
  156. package/payload/server/public/assets/gitGraph-7Q5UKJZL-g7mvu6IY.js +0 -1
  157. package/payload/server/public/assets/info-OMHHGYJF-DZqJuIkB.js +0 -1
  158. package/payload/server/public/assets/infoDiagram-42DDH7IO-cGfGccHz.js +0 -2
  159. package/payload/server/public/assets/operator-Cnzbhdh2.js +0 -1
  160. package/payload/server/public/assets/packet-4T2RLAQJ-Hn8rlHpy.js +0 -1
  161. package/payload/server/public/assets/page-CH8JQkQN.js +0 -1
  162. package/payload/server/public/assets/pie-ZZUOXDRM-BPGWVqBm.js +0 -1
  163. package/payload/server/public/assets/public-CA90VhI9.js +0 -6
  164. package/payload/server/public/assets/radar-PYXPWWZC-DMdLrj3E.js +0 -1
  165. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BGUCxPmp.js +0 -1
  166. package/payload/server/public/assets/treeView-SZITEDCU-CWxofUbI.js +0 -1
  167. package/payload/server/public/assets/treemap-W4RFUUIX-Cfgb_ZG0.js +0 -1
  168. package/payload/server/public/assets/wardley-RL74JXVD-B45olYjj.js +0 -1
  169. /package/payload/server/public/assets/{file-download-qc_xy7Az.css → OperatorConversations-qc_xy7Az.css} +0 -0
  170. /package/payload/server/public/assets/{_baseFor-brRjpUOX.js → _baseFor-D8P3gUw3.js} +0 -0
  171. /package/payload/server/public/assets/{array-BGFCBI0e.js → array-CLwNaqU1.js} +0 -0
  172. /package/payload/server/public/assets/{chunk-Pqm5yXtL.js → chunk-CAM3fms7.js} +0 -0
  173. /package/payload/server/public/assets/{cytoscape.esm-TvRJ2tGX.js → cytoscape.esm-mZ4wTuB7.js} +0 -0
  174. /package/payload/server/public/assets/{defaultLocale-CRZydyG6.js → defaultLocale-D_VMtRaY.js} +0 -0
  175. /package/payload/server/public/assets/{init-B8gtcn7T.js → init-vVpfz1D6.js} +0 -0
  176. /package/payload/server/public/assets/{katex-RxgSu_dy.js → katex-DaHGEgm7.js} +0 -0
  177. /package/payload/server/public/assets/{path-DZF-JdEe.js → path-CuyvWNAH.js} +0 -0
  178. /package/payload/server/public/assets/{preload-helper-CQ36nxok.js → preload-helper-TKOBYGYD.js} +0 -0
  179. /package/payload/server/public/assets/{rough.esm-6CnTHTkH.js → rough.esm-JX0wREDd.js} +0 -0
@@ -25,6 +25,7 @@ import {
25
25
  VISITOR_TOKEN_SECRET_FILE,
26
26
  VNC_DISPLAY,
27
27
  WEBSOCKIFY_PORT,
28
+ accessPasswordCollides,
28
29
  autoDeliverPremiumPlugins,
29
30
  bindVisitorToGroup,
30
31
  canAccessAdmin,
@@ -109,7 +110,7 @@ import {
109
110
  vncLog,
110
111
  walkPremiumBundles,
111
112
  writeAdminUserAndPerson
112
- } from "./chunk-FBGIHWWM.js";
113
+ } from "./chunk-J6WDAWFJ.js";
113
114
  import {
114
115
  __commonJS,
115
116
  __toESM
@@ -1227,7 +1228,7 @@ var serveStatic = (options = { root: "" }) => {
1227
1228
 
1228
1229
  // server/index.ts
1229
1230
  import { readFileSync as readFileSync27, existsSync as existsSync28, watchFile } from "fs";
1230
- import { resolve as resolve30, join as join24, basename as basename8 } from "path";
1231
+ import { resolve as resolve31, join as join25, basename as basename9 } from "path";
1231
1232
  import { homedir as homedir3 } from "os";
1232
1233
  import { monitorEventLoopDelay } from "perf_hooks";
1233
1234
 
@@ -1875,7 +1876,7 @@ var credsSaveQueue = Promise.resolve();
1875
1876
  async function drainCredsSaveQueue(timeoutMs = 5e3) {
1876
1877
  console.error(`${TAG2} draining credential save queue\u2026`);
1877
1878
  const timer2 = new Promise(
1878
- (resolve31) => setTimeout(() => resolve31("timeout"), timeoutMs)
1879
+ (resolve32) => setTimeout(() => resolve32("timeout"), timeoutMs)
1879
1880
  );
1880
1881
  const result = await Promise.race([
1881
1882
  credsSaveQueue.then(() => "drained"),
@@ -2003,11 +2004,11 @@ async function createWaSocket(opts) {
2003
2004
  return sock;
2004
2005
  }
2005
2006
  async function waitForConnection(sock) {
2006
- return new Promise((resolve31, reject) => {
2007
+ return new Promise((resolve32, reject) => {
2007
2008
  const handler = (update) => {
2008
2009
  if (update.connection === "open") {
2009
2010
  sock.ev.off("connection.update", handler);
2010
- resolve31();
2011
+ resolve32();
2011
2012
  }
2012
2013
  if (update.connection === "close") {
2013
2014
  sock.ev.off("connection.update", handler);
@@ -2121,14 +2122,14 @@ ${inspected}`;
2121
2122
  return inspect2(err, INSPECT_OPTS2);
2122
2123
  }
2123
2124
  function withTimeout(label, promise, timeoutMs) {
2124
- return new Promise((resolve31, reject) => {
2125
+ return new Promise((resolve32, reject) => {
2125
2126
  const timer2 = setTimeout(() => {
2126
2127
  reject(new Error(`${label} timed out after ${timeoutMs}ms`));
2127
2128
  }, timeoutMs);
2128
2129
  promise.then(
2129
2130
  (value) => {
2130
2131
  clearTimeout(timer2);
2131
- resolve31(value);
2132
+ resolve32(value);
2132
2133
  },
2133
2134
  (err) => {
2134
2135
  clearTimeout(timer2);
@@ -3012,8 +3013,8 @@ async function persistWhatsAppMessage(input) {
3012
3013
  const { givenName, familyName } = splitName(input.pushName);
3013
3014
  const prev = sessionWriteLocks.get(input.cacheKey);
3014
3015
  let release;
3015
- const mine = new Promise((resolve31) => {
3016
- release = resolve31;
3016
+ const mine = new Promise((resolve32) => {
3017
+ release = resolve32;
3017
3018
  });
3018
3019
  const chained = (prev ?? Promise.resolve()).then(() => mine);
3019
3020
  sessionWriteLocks.set(input.cacheKey, chained);
@@ -4093,11 +4094,11 @@ async function connectWithReconnect(conn) {
4093
4094
  console.error(
4094
4095
  `${TAG13} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
4095
4096
  );
4096
- await new Promise((resolve31) => {
4097
- const timer2 = setTimeout(resolve31, delay);
4097
+ await new Promise((resolve32) => {
4098
+ const timer2 = setTimeout(resolve32, delay);
4098
4099
  conn.abortController.signal.addEventListener("abort", () => {
4099
4100
  clearTimeout(timer2);
4100
- resolve31();
4101
+ resolve32();
4101
4102
  }, { once: true });
4102
4103
  });
4103
4104
  }
@@ -4105,16 +4106,16 @@ async function connectWithReconnect(conn) {
4105
4106
  }
4106
4107
  }
4107
4108
  function waitForDisconnectEvent(conn) {
4108
- return new Promise((resolve31) => {
4109
+ return new Promise((resolve32) => {
4109
4110
  if (!conn.sock) {
4110
- resolve31();
4111
+ resolve32();
4111
4112
  return;
4112
4113
  }
4113
4114
  const sock = conn.sock;
4114
4115
  const handler = (update) => {
4115
4116
  if (update.connection === "close") {
4116
4117
  sock.ev.off("connection.update", handler);
4117
- resolve31();
4118
+ resolve32();
4118
4119
  }
4119
4120
  };
4120
4121
  sock.ev.on("connection.update", handler);
@@ -4374,8 +4375,8 @@ async function handleInboundMessage(conn, msg) {
4374
4375
  const conversationKey = isGroup ? remoteJid : senderPhone;
4375
4376
  const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
4376
4377
  let resolvePending;
4377
- const sttPending = new Promise((resolve31) => {
4378
- resolvePending = resolve31;
4378
+ const sttPending = new Promise((resolve32) => {
4379
+ resolvePending = resolve32;
4379
4380
  });
4380
4381
  if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
4381
4382
  try {
@@ -4769,20 +4770,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
4769
4770
 
4770
4771
  // server/routes/health.ts
4771
4772
  function checkPort(port2, timeoutMs = 500) {
4772
- return new Promise((resolve31) => {
4773
+ return new Promise((resolve32) => {
4773
4774
  const socket = createConnection2(port2, "127.0.0.1");
4774
4775
  socket.setTimeout(timeoutMs);
4775
4776
  socket.once("connect", () => {
4776
4777
  socket.destroy();
4777
- resolve31(true);
4778
+ resolve32(true);
4778
4779
  });
4779
4780
  socket.once("error", () => {
4780
4781
  socket.destroy();
4781
- resolve31(false);
4782
+ resolve32(false);
4782
4783
  });
4783
4784
  socket.once("timeout", () => {
4784
4785
  socket.destroy();
4785
- resolve31(false);
4786
+ resolve32(false);
4786
4787
  });
4787
4788
  });
4788
4789
  }
@@ -5175,8 +5176,8 @@ function webchatTurnTimeoutMs() {
5175
5176
  return Number(process.env.WEBCHAT_TURN_TIMEOUT_MS ?? String(2 * 6e4));
5176
5177
  }
5177
5178
  function createChatRoutes(deps) {
5178
- const app50 = new Hono();
5179
- app50.post("/", async (c) => {
5179
+ const app51 = new Hono();
5180
+ app51.post("/", async (c) => {
5180
5181
  console.log(`[chat-route] entered route=public method=POST`);
5181
5182
  const contentType = c.req.header("content-type") ?? "";
5182
5183
  const account = resolveAccount();
@@ -5399,7 +5400,7 @@ ${result.result.text}` : result.result.text;
5399
5400
  }
5400
5401
  });
5401
5402
  });
5402
- return app50;
5403
+ return app51;
5403
5404
  }
5404
5405
 
5405
5406
  // server/routes/whatsapp.ts
@@ -5821,8 +5822,8 @@ async function startLogin(opts) {
5821
5822
  await clearAuth(authDir);
5822
5823
  let resolveCode = null;
5823
5824
  let rejectCode = null;
5824
- const codePromise = new Promise((resolve31, reject) => {
5825
- resolveCode = resolve31;
5825
+ const codePromise = new Promise((resolve32, reject) => {
5826
+ resolveCode = resolve32;
5826
5827
  rejectCode = reject;
5827
5828
  });
5828
5829
  const codeTimer = setTimeout(
@@ -7442,18 +7443,199 @@ app4.get("/directive", requireAdminSession, (c) => {
7442
7443
  });
7443
7444
  var whatsapp_reader_default = app4;
7444
7445
 
7446
+ // server/routes/public-reader.ts
7447
+ import { statSync as statSync5, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, watch as watch2 } from "fs";
7448
+ import { basename as basename3, dirname as dirname2, join as join11, resolve as resolve12, sep as sep4 } from "path";
7449
+
7450
+ // app/lib/whatsapp-reader/delivered-kinds.ts
7451
+ var PUBLIC_DELIVERED_KINDS = /* @__PURE__ */ new Set([
7452
+ "operator-inbound",
7453
+ "agent-reply",
7454
+ "agent-reply-document",
7455
+ "agent-error"
7456
+ ]);
7457
+ function isDeliveredKind(kind, set) {
7458
+ return set.has(kind);
7459
+ }
7460
+
7461
+ // app/lib/public-reader/filter-delivered.ts
7462
+ function filterDeliveredFrames(lines) {
7463
+ const turns = [];
7464
+ let dropped = 0;
7465
+ for (const turn of parseTranscript(lines)) {
7466
+ if (isDeliveredKind(turn.kind, PUBLIC_DELIVERED_KINDS)) turns.push(turn);
7467
+ else dropped++;
7468
+ }
7469
+ return { turns, dropped };
7470
+ }
7471
+
7472
+ // app/lib/public-reader/resolve-visitor-session.ts
7473
+ function resolveVisitorSession(rows, visitorPersonId) {
7474
+ const matches = rows.filter(
7475
+ (r) => r.role === "public" && r.channel === "webchat" && r.personId === visitorPersonId
7476
+ );
7477
+ if (matches.length === 0) return null;
7478
+ return matches.reduce(
7479
+ (best, r) => (r.startedAt ?? "") > (best.startedAt ?? "") ? r : best
7480
+ );
7481
+ }
7482
+
7483
+ // server/routes/public-reader.ts
7484
+ var app5 = new Hono();
7485
+ var TAG20 = "[public-webchat]";
7486
+ function parseAccessSessionId(cookieHeader) {
7487
+ if (!cookieHeader) return null;
7488
+ const part = cookieHeader.split(";").map((p) => p.trim()).find((p) => p.startsWith("__access_session="));
7489
+ return part ? part.slice("__access_session=".length) : null;
7490
+ }
7491
+ function resolveVisitor(c) {
7492
+ const id = parseAccessSessionId(c.req.header("cookie"));
7493
+ const session = id ? getAccessSession(id) : null;
7494
+ return session && session.personId ? { personId: session.personId } : null;
7495
+ }
7496
+ function enumeratePublicRows() {
7497
+ const cfg = claudeConfigDir();
7498
+ if (!cfg) return [];
7499
+ const rows = [];
7500
+ for (const { path: path2 } of enumerateJsonls(join11(cfg, "projects"))) {
7501
+ const sessionId = basename3(path2).replace(/\.jsonl$/, "");
7502
+ const projectDir = dirname2(path2);
7503
+ const meta = readSidecarMeta(join11(projectDir, `${sessionId}.meta.json`));
7504
+ rows.push({
7505
+ sessionId,
7506
+ projectDir,
7507
+ role: meta.role,
7508
+ channel: meta.channel,
7509
+ personId: meta.personId,
7510
+ senderId: meta.senderId,
7511
+ startedAt: meta.startedAt
7512
+ });
7513
+ }
7514
+ return rows;
7515
+ }
7516
+ app5.get("/session", (c) => {
7517
+ const visitor = resolveVisitor(c);
7518
+ if (!visitor) {
7519
+ console.error(`${TAG20} op=reader-refused reason=no-grant path=/session`);
7520
+ return c.json({ error: "gate-required" }, 401);
7521
+ }
7522
+ const found = resolveVisitorSession(enumeratePublicRows(), visitor.personId);
7523
+ if (found) {
7524
+ console.log(`${TAG20} op=session-resume key=${(found.senderId ?? "").slice(0, 8)} sessionId=${found.sessionId.slice(0, 8)}`);
7525
+ return c.json({ sessionId: found.sessionId, projectDir: found.projectDir, sessionKey: found.senderId });
7526
+ }
7527
+ const sessionKey = crypto.randomUUID();
7528
+ console.log(`${TAG20} op=session-new key=${sessionKey.slice(0, 8)}`);
7529
+ return c.json({ sessionId: null, projectDir: null, sessionKey });
7530
+ });
7531
+ function readFrom2(path2, from) {
7532
+ const end = statSync5(path2).size;
7533
+ if (end <= from) return { buf: Buffer.alloc(0), end: from };
7534
+ const fd = openSync2(path2, "r");
7535
+ try {
7536
+ const buf = Buffer.alloc(end - from);
7537
+ readSync2(fd, buf, 0, buf.length, from);
7538
+ return { buf, end };
7539
+ } finally {
7540
+ closeSync2(fd);
7541
+ }
7542
+ }
7543
+ app5.get("/stream", (c) => {
7544
+ const visitor = resolveVisitor(c);
7545
+ if (!visitor) {
7546
+ console.error(`${TAG20} op=reader-refused reason=no-grant path=/stream`);
7547
+ return c.json({ error: "gate-required" }, 401);
7548
+ }
7549
+ const sessionId = c.req.query("sessionId") ?? "";
7550
+ const projectDir = c.req.query("projectDir") ?? "";
7551
+ const cfg = claudeConfigDir();
7552
+ const projectsRoot = cfg ? resolve12(join11(cfg, "projects")) : null;
7553
+ if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
7554
+ return c.json({ error: "bad session reference" }, 400);
7555
+ }
7556
+ const jsonlPath = resolve12(join11(projectDir, `${sessionId}.jsonl`));
7557
+ if (!jsonlPath.startsWith(projectsRoot + sep4)) {
7558
+ return c.json({ error: "bad session reference" }, 400);
7559
+ }
7560
+ const meta = readSidecarMeta(join11(projectDir, `${sessionId}.meta.json`));
7561
+ if (!(meta.role === "public" && meta.channel === "webchat" && meta.personId === visitor.personId)) {
7562
+ console.error(`${TAG20} op=reader-refused reason=not-owner sessionId=${sessionId.slice(0, 8)}`);
7563
+ return c.json({ error: "forbidden" }, 403);
7564
+ }
7565
+ const senderShort = (meta.senderId ?? "").slice(0, 8);
7566
+ const encoder = new TextEncoder();
7567
+ console.log(`${TAG20} op=reader-open key=${senderShort} mode=delivered-only sessionId=${sessionId.slice(0, 8)}`);
7568
+ const send = (controller, turn, id) => controller.enqueue(encoder.encode(`id: ${id}
7569
+ data: ${JSON.stringify(turn)}
7570
+
7571
+ `));
7572
+ const readable = new ReadableStream({
7573
+ start(controller) {
7574
+ let offset = 0;
7575
+ const emit = (lines) => {
7576
+ const { turns, dropped } = filterDeliveredFrames(lines);
7577
+ for (const turn of turns) send(controller, turn, offset);
7578
+ if (dropped > 0) console.log(`${TAG20} op=reader-filtered key=${senderShort} dropped=${dropped}`);
7579
+ };
7580
+ try {
7581
+ const { buf, end } = readFrom2(jsonlPath, 0);
7582
+ offset = end;
7583
+ emit(buf.toString("utf8").split("\n"));
7584
+ } catch {
7585
+ controller.enqueue(encoder.encode('event: error\ndata: "read-failed"\n\n'));
7586
+ }
7587
+ const drain = () => {
7588
+ try {
7589
+ const { buf, end } = readFrom2(jsonlPath, offset);
7590
+ if (end <= offset) return;
7591
+ const { lines, nextOffset } = splitNewLines(buf, offset);
7592
+ offset = nextOffset;
7593
+ emit(lines);
7594
+ } catch {
7595
+ }
7596
+ };
7597
+ let watcher = null;
7598
+ try {
7599
+ watcher = watch2(jsonlPath, drain);
7600
+ } catch {
7601
+ }
7602
+ const poll = setInterval(drain, 1e3);
7603
+ const heartbeat = setInterval(() => {
7604
+ try {
7605
+ controller.enqueue(encoder.encode(": ping\n\n"));
7606
+ } catch {
7607
+ }
7608
+ }, 2e4);
7609
+ c.req.raw.signal.addEventListener("abort", () => {
7610
+ watcher?.close();
7611
+ clearInterval(poll);
7612
+ clearInterval(heartbeat);
7613
+ console.log(`${TAG20} op=reader-close key=${senderShort}`);
7614
+ try {
7615
+ controller.close();
7616
+ } catch {
7617
+ }
7618
+ });
7619
+ }
7620
+ });
7621
+ return new Response(readable, {
7622
+ headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive" }
7623
+ });
7624
+ });
7625
+ var public_reader_default = app5;
7626
+
7445
7627
  // server/routes/webchat.ts
7446
- import { basename as basename3, dirname as dirname2 } from "path";
7447
- import { join as join12 } from "path";
7628
+ import { basename as basename4, dirname as dirname3 } from "path";
7629
+ import { join as join13 } from "path";
7448
7630
  import { existsSync as existsSync8, readdirSync as readdirSync7, readFileSync as readFileSync13, renameSync as renameSync2, writeFileSync as writeFileSync6 } from "fs";
7449
7631
 
7450
7632
  // server/canonical-webchat-override.ts
7451
7633
  import { readFileSync as readFileSync12, writeFileSync as writeFileSync5, renameSync } from "fs";
7452
- import { join as join11 } from "path";
7634
+ import { join as join12 } from "path";
7453
7635
  var FILE = "canonical-webchat-session.json";
7454
7636
  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}$/;
7455
7637
  function canonicalOverridePath(accountDir) {
7456
- return join11(accountDir, FILE);
7638
+ return join12(accountDir, FILE);
7457
7639
  }
7458
7640
  function readCanonicalOverrideId(accountDir) {
7459
7641
  try {
@@ -7488,10 +7670,10 @@ var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9
7488
7670
  function locateSession(sessionId) {
7489
7671
  const cfg = claudeConfigDir();
7490
7672
  if (!cfg) return { projectDir: null, channel: null };
7491
- for (const { path: path2 } of enumerateJsonls(join12(cfg, "projects"))) {
7492
- if (basename3(path2) === `${sessionId}.jsonl`) {
7493
- const dir = dirname2(path2);
7494
- const meta = readSidecarMeta(join12(dir, `${sessionId}.meta.json`));
7673
+ for (const { path: path2 } of enumerateJsonls(join13(cfg, "projects"))) {
7674
+ if (basename4(path2) === `${sessionId}.jsonl`) {
7675
+ const dir = dirname3(path2);
7676
+ const meta = readSidecarMeta(join13(dir, `${sessionId}.meta.json`));
7495
7677
  return { projectDir: dir, channel: meta.channel };
7496
7678
  }
7497
7679
  }
@@ -7500,7 +7682,7 @@ function locateSession(sessionId) {
7500
7682
  function locateSidecar(sessionId) {
7501
7683
  const cfg = claudeConfigDir();
7502
7684
  if (!cfg) return null;
7503
- const projectsRoot = join12(cfg, "projects");
7685
+ const projectsRoot = join13(cfg, "projects");
7504
7686
  let slugs;
7505
7687
  try {
7506
7688
  slugs = readdirSync7(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
@@ -7508,7 +7690,7 @@ function locateSidecar(sessionId) {
7508
7690
  return null;
7509
7691
  }
7510
7692
  for (const slug of slugs) {
7511
- const metaPath = join12(projectsRoot, slug, `${sessionId}.meta.json`);
7693
+ const metaPath = join13(projectsRoot, slug, `${sessionId}.meta.json`);
7512
7694
  if (existsSync8(metaPath)) {
7513
7695
  return { channel: readSidecarMeta(metaPath).channel };
7514
7696
  }
@@ -7606,8 +7788,8 @@ async function reapplyLeversViaManager() {
7606
7788
  }
7607
7789
  }
7608
7790
  function createWebchatRoutes(deps) {
7609
- const app50 = new Hono();
7610
- app50.post("/send", requireAdminSession, async (c) => {
7791
+ const app51 = new Hono();
7792
+ app51.post("/send", requireAdminSession, async (c) => {
7611
7793
  let accountId;
7612
7794
  try {
7613
7795
  accountId = resolvePlatformAccountId();
@@ -7738,7 +7920,7 @@ ${note}` : note;
7738
7920
  }
7739
7921
  return c.json({ ok: true });
7740
7922
  });
7741
- app50.post("/settings", requireAdminSession, async (c) => {
7923
+ app51.post("/settings", requireAdminSession, async (c) => {
7742
7924
  const body = await c.req.json().catch(() => null);
7743
7925
  const op = body?.op;
7744
7926
  const value = body?.value;
@@ -7760,7 +7942,7 @@ ${note}` : note;
7760
7942
  console.error(`[webchat:settings] op=${op} outcome=refused value=${value} reason=account-unresolved`);
7761
7943
  return c.json({ error: "account unresolved" }, 503);
7762
7944
  }
7763
- const accountJsonPath = join12(account.accountDir, "account.json");
7945
+ const accountJsonPath = join13(account.accountDir, "account.json");
7764
7946
  try {
7765
7947
  const parsed = JSON.parse(readFileSync13(accountJsonPath, "utf8"));
7766
7948
  if (op === "model") parsed.adminModel = value;
@@ -7778,7 +7960,7 @@ ${note}` : note;
7778
7960
  console.log(`[webchat:settings] op=${op} outcome=accepted value=${value} settingsApplied=${settingsApplied}`);
7779
7961
  return c.json({ ok: true, settingsApplied });
7780
7962
  });
7781
- app50.get("/session", requireAdminSession, async (c) => {
7963
+ app51.get("/session", requireAdminSession, async (c) => {
7782
7964
  let accountId;
7783
7965
  try {
7784
7966
  accountId = resolvePlatformAccountId();
@@ -7807,9 +7989,9 @@ ${note}` : note;
7807
7989
  const cfg = claudeConfigDir();
7808
7990
  let projectDir = null;
7809
7991
  if (cfg) {
7810
- for (const { path: path2 } of enumerateJsonls(join12(cfg, "projects"))) {
7811
- if (basename3(path2) === `${sessionId}.jsonl`) {
7812
- projectDir = dirname2(path2);
7992
+ for (const { path: path2 } of enumerateJsonls(join13(cfg, "projects"))) {
7993
+ if (basename4(path2) === `${sessionId}.jsonl`) {
7994
+ projectDir = dirname3(path2);
7813
7995
  break;
7814
7996
  }
7815
7997
  }
@@ -7817,15 +7999,15 @@ ${note}` : note;
7817
7999
  const indicators = await fetchComposerIndicators(sessionId);
7818
8000
  return c.json({ sessionId, projectDir, ...indicators, ...readLevers(account) });
7819
8001
  });
7820
- return app50;
8002
+ return app51;
7821
8003
  }
7822
8004
 
7823
8005
  // server/routes/webchat-greeting.ts
7824
- import { resolve as resolve12 } from "path";
8006
+ import { resolve as resolve13 } from "path";
7825
8007
 
7826
8008
  // app/lib/claude-agent/specialist-roster.ts
7827
8009
  import { existsSync as existsSync9, readFileSync as readFileSync14, readdirSync as readdirSync8 } from "fs";
7828
- import { join as join13 } from "path";
8010
+ import { join as join14 } from "path";
7829
8011
  function field(fm, name) {
7830
8012
  const m = fm.match(new RegExp(`^${name}:\\s*(.*?)\\r?$`, "m"));
7831
8013
  if (!m) return null;
@@ -7844,7 +8026,7 @@ function readSpecialistRoster(specialistsDir) {
7844
8026
  if (!file.endsWith(".md")) continue;
7845
8027
  let raw;
7846
8028
  try {
7847
- raw = readFileSync14(join13(specialistsDir, file), "utf-8");
8029
+ raw = readFileSync14(join14(specialistsDir, file), "utf-8");
7848
8030
  } catch (err) {
7849
8031
  skipped.push({ file, reason: err instanceof Error ? err.message : String(err) });
7850
8032
  continue;
@@ -7885,8 +8067,8 @@ var TASKS_CYPHER = `
7885
8067
  WITH t ORDER BY coalesce(t.createdAt, '') ASC
7886
8068
  WITH collect({ taskId: t.taskId, name: t.name, status: t.status }) AS all
7887
8069
  RETURN all[0..${TASK_ITEMS_CAP}] AS items, size(all) AS total`;
7888
- var app5 = new Hono();
7889
- app5.get("/", requireAdminSession, async (c) => {
8070
+ var app6 = new Hono();
8071
+ app6.get("/", requireAdminSession, async (c) => {
7890
8072
  const cacheKey = c.var.cacheKey;
7891
8073
  const accountId = getAccountIdForSession(cacheKey);
7892
8074
  if (!accountId) {
@@ -7926,7 +8108,7 @@ app5.get("/", requireAdminSession, async (c) => {
7926
8108
  let specialists = [];
7927
8109
  try {
7928
8110
  const roster = readSpecialistRoster(
7929
- resolve12(ACCOUNTS_DIR, accountId, "specialists", "agents")
8111
+ resolve13(ACCOUNTS_DIR, accountId, "specialists", "agents")
7930
8112
  );
7931
8113
  specialists = roster.specialists;
7932
8114
  for (const s of roster.skipped) {
@@ -7957,15 +8139,15 @@ function r2n(value) {
7957
8139
  }
7958
8140
  return Number(value ?? 0);
7959
8141
  }
7960
- var webchat_greeting_default = app5;
8142
+ var webchat_greeting_default = app6;
7961
8143
 
7962
8144
  // server/routes/telegram.ts
7963
8145
  import { homedir } from "os";
7964
- import { resolve as resolve14, join as join14 } from "path";
8146
+ import { resolve as resolve15, join as join15 } from "path";
7965
8147
  import { existsSync as existsSync10, readFileSync as readFileSync15 } from "fs";
7966
8148
 
7967
8149
  // app/lib/channel-pty-bridge/bridge.ts
7968
- import { resolve as resolve13 } from "path";
8150
+ import { resolve as resolve14 } from "path";
7969
8151
 
7970
8152
  // app/lib/channel-pty-bridge/manager-client.ts
7971
8153
  function managerBase2() {
@@ -8086,7 +8268,7 @@ function classifyTimeout(ndjson, writeAtMs) {
8086
8268
 
8087
8269
  // app/lib/channel-pty-bridge/public-session-end-review.ts
8088
8270
  import { randomUUID as randomUUID7 } from "crypto";
8089
- var TAG20 = "[public-session-review]";
8271
+ var TAG21 = "[public-session-review]";
8090
8272
  var CONSUMED_CAP = 500;
8091
8273
  var consumed = /* @__PURE__ */ new Set();
8092
8274
  function consumeOnce(sessionId) {
@@ -8113,7 +8295,7 @@ async function fetchJsonl(sessionId) {
8113
8295
  return await res.text();
8114
8296
  } catch (err) {
8115
8297
  console.error(
8116
- `${TAG20} jsonl-fetch-failed sessionId=${sessionId} err="${err instanceof Error ? err.message : String(err)}"`
8298
+ `${TAG21} jsonl-fetch-failed sessionId=${sessionId} err="${err instanceof Error ? err.message : String(err)}"`
8117
8299
  );
8118
8300
  return null;
8119
8301
  }
@@ -8137,7 +8319,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
8137
8319
  const res = await fetch(url);
8138
8320
  if (!res.ok) {
8139
8321
  console.error(
8140
- `${TAG20} prior-writes-fetch-failed sliceToken=${sliceToken.slice(0, 8)} status=${res.status}`
8322
+ `${TAG21} prior-writes-fetch-failed sliceToken=${sliceToken.slice(0, 8)} status=${res.status}`
8141
8323
  );
8142
8324
  return [];
8143
8325
  }
@@ -8145,7 +8327,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
8145
8327
  return Array.isArray(body.writes) ? body.writes : [];
8146
8328
  } catch (err) {
8147
8329
  console.error(
8148
- `${TAG20} prior-writes-fetch-threw sliceToken=${sliceToken.slice(0, 8)} err="${err instanceof Error ? err.message : String(err)}"`
8330
+ `${TAG21} prior-writes-fetch-threw sliceToken=${sliceToken.slice(0, 8)} err="${err instanceof Error ? err.message : String(err)}"`
8149
8331
  );
8150
8332
  return [];
8151
8333
  }
@@ -8174,7 +8356,7 @@ function composeInitialMessage(input) {
8174
8356
  }
8175
8357
  async function dispatchReviewer(input, initialMessage) {
8176
8358
  const sessionId = randomUUID7();
8177
- console.log(`${TAG20} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
8359
+ console.log(`${TAG21} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
8178
8360
  const spawned = await managerRcSpawn({
8179
8361
  sessionId,
8180
8362
  initialMessage,
@@ -8194,21 +8376,21 @@ async function firePublicSessionEndReview(input) {
8194
8376
  const dispatchedAt = Date.now();
8195
8377
  if (consumed.has(input.sessionId)) {
8196
8378
  console.log(
8197
- `${TAG20} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
8379
+ `${TAG21} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
8198
8380
  );
8199
8381
  return;
8200
8382
  }
8201
8383
  const jsonl = await fetchJsonl(input.sessionId);
8202
8384
  if (!jsonl) {
8203
8385
  console.log(
8204
- `${TAG20} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-jsonl-missing`
8386
+ `${TAG21} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-jsonl-missing`
8205
8387
  );
8206
8388
  return;
8207
8389
  }
8208
8390
  const operatorTurns = countOperatorTurns(jsonl);
8209
8391
  if (operatorTurns === 0) {
8210
8392
  console.log(
8211
- `${TAG20} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-no-turns`
8393
+ `${TAG21} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-no-turns`
8212
8394
  );
8213
8395
  return;
8214
8396
  }
@@ -8222,19 +8404,19 @@ async function firePublicSessionEndReview(input) {
8222
8404
  });
8223
8405
  if (!consumeOnce(input.sessionId)) {
8224
8406
  console.log(
8225
- `${TAG20} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
8407
+ `${TAG21} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
8226
8408
  );
8227
8409
  return;
8228
8410
  }
8229
8411
  const dispatched = await dispatchReviewer(input, initialMessage);
8230
8412
  if (!dispatched.ok) {
8231
8413
  console.error(
8232
- `${TAG20} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-spawn-failed reason=${dispatched.reason}`
8414
+ `${TAG21} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-spawn-failed reason=${dispatched.reason}`
8233
8415
  );
8234
8416
  return;
8235
8417
  }
8236
8418
  console.log(
8237
- `${TAG20} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=dispatched managerSessionId=${dispatched.managerSessionId} operatorTurns=${operatorTurns} priorWrites=${priorWrites.length} ms=${Date.now() - dispatchedAt}`
8419
+ `${TAG21} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=dispatched managerSessionId=${dispatched.managerSessionId} operatorTurns=${operatorTurns} priorWrites=${priorWrites.length} ms=${Date.now() - dispatchedAt}`
8238
8420
  );
8239
8421
  }
8240
8422
 
@@ -8405,7 +8587,7 @@ async function fanOut(subscribers, text, onError, tag) {
8405
8587
  }
8406
8588
 
8407
8589
  // app/lib/whatsapp/inbound/file-delivery-bridge.ts
8408
- var TAG21 = "[whatsapp-adaptor]";
8590
+ var TAG22 = "[whatsapp-adaptor]";
8409
8591
  var SEND_USER_FILE = "SendUserFile";
8410
8592
  var WHATSAPP_SEND_DOCUMENT = "whatsapp-send-document";
8411
8593
  function platformRoot() {
@@ -8440,7 +8622,7 @@ function makeWhatsAppFileDelivery(entry) {
8440
8622
  maxyAccountId = resolvePlatformAccountId();
8441
8623
  } catch (err) {
8442
8624
  console.error(
8443
- `${TAG21} file-delivery reject reason=account-unresolved sender=${entry.senderId} message=${err instanceof Error ? err.message : String(err)}`
8625
+ `${TAG22} file-delivery reject reason=account-unresolved sender=${entry.senderId} message=${err instanceof Error ? err.message : String(err)}`
8444
8626
  );
8445
8627
  return;
8446
8628
  }
@@ -8457,7 +8639,7 @@ function makeWhatsAppFileDelivery(entry) {
8457
8639
  if (!result.ok) {
8458
8640
  failedFiles.push(files[i]);
8459
8641
  console.error(
8460
- `${TAG21} file-delivery reject reason=send-failed sender=${entry.senderId} status=${result.status} message=${result.error}`
8642
+ `${TAG22} file-delivery reject reason=send-failed sender=${entry.senderId} status=${result.status} message=${result.error}`
8461
8643
  );
8462
8644
  }
8463
8645
  }
@@ -8474,7 +8656,7 @@ function makeWhatsAppFileDelivery(entry) {
8474
8656
  const sid = entry.sessionId.slice(0, 8);
8475
8657
  for (const file of failed) {
8476
8658
  console.error(
8477
- `${TAG21} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${SEND_USER_FILE} file=${file}`
8659
+ `${TAG22} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${SEND_USER_FILE} file=${file}`
8478
8660
  );
8479
8661
  }
8480
8662
  const okAt = documentOutboundAt(entry.senderId);
@@ -8485,13 +8667,13 @@ function makeWhatsAppFileDelivery(entry) {
8485
8667
  if (!delivered) {
8486
8668
  const fileField = call.filePath !== void 0 ? ` file=${call.filePath}` : "";
8487
8669
  console.error(
8488
- `${TAG21} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
8670
+ `${TAG22} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
8489
8671
  );
8490
8672
  }
8491
8673
  }
8492
8674
  if (firedTools.includes(SEND_USER_FILE) && attempts === 0 && !documentWentOut) {
8493
8675
  console.error(
8494
- `${TAG21} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${SEND_USER_FILE}`
8676
+ `${TAG22} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${SEND_USER_FILE}`
8495
8677
  );
8496
8678
  }
8497
8679
  }
@@ -8562,7 +8744,7 @@ async function ensureEntry(input) {
8562
8744
  });
8563
8745
  } else {
8564
8746
  console.error(`${tag} route role=${input.role} target=public-spawn senderId=${input.senderId}`);
8565
- const attachmentDir = resolve13(DATA_ROOT, "accounts", input.accountId, "uploads", "public", input.senderId);
8747
+ const attachmentDir = resolve14(DATA_ROOT, "accounts", input.accountId, "uploads", "public", input.senderId);
8566
8748
  spawned = await managerSpawn({
8567
8749
  senderId: input.senderId,
8568
8750
  role: input.role,
@@ -8694,12 +8876,12 @@ async function dispatchOnce(input) {
8694
8876
  });
8695
8877
  if (!entry) return { error: "spawn-failed" };
8696
8878
  entry.lastInboundAt = Date.now();
8697
- let resolve31;
8879
+ let resolve32;
8698
8880
  const turnPromise = new Promise((r) => {
8699
- resolve31 = r;
8881
+ resolve32 = r;
8700
8882
  });
8701
8883
  const listener = (text) => {
8702
- resolve31(text);
8884
+ resolve32(text);
8703
8885
  };
8704
8886
  entry.subscribers.add(listener);
8705
8887
  const writeAtMs = Date.now();
@@ -8846,11 +9028,11 @@ function routeTelegramUpdate(input) {
8846
9028
  }
8847
9029
 
8848
9030
  // server/routes/telegram.ts
8849
- var TAG22 = "[telegram-inbound]";
9031
+ var TAG23 = "[telegram-inbound]";
8850
9032
  var DISPATCH_TIMEOUT_MS = 12e4;
8851
9033
  function configDirName() {
8852
- const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve14(process.cwd(), "..");
8853
- const brandPath = join14(platformRoot2, "config", "brand.json");
9034
+ const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve15(process.cwd(), "..");
9035
+ const brandPath = join15(platformRoot2, "config", "brand.json");
8854
9036
  if (existsSync10(brandPath)) {
8855
9037
  try {
8856
9038
  return JSON.parse(readFileSync15(brandPath, "utf-8")).configDir ?? ".maxy";
@@ -8861,7 +9043,7 @@ function configDirName() {
8861
9043
  }
8862
9044
  function secretPath(botType) {
8863
9045
  const filename = botType === "admin" ? ".telegram-admin-webhook-secret" : ".telegram-webhook-secret";
8864
- return resolve14(homedir(), configDirName(), filename);
9046
+ return resolve15(homedir(), configDirName(), filename);
8865
9047
  }
8866
9048
  async function sendTelegram(botToken, chatId, text) {
8867
9049
  try {
@@ -8876,23 +9058,23 @@ async function sendTelegram(botToken, chatId, text) {
8876
9058
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
8877
9059
  }
8878
9060
  }
8879
- var app6 = new Hono();
8880
- app6.post("/", async (c) => {
9061
+ var app7 = new Hono();
9062
+ app7.post("/", async (c) => {
8881
9063
  const botParam = c.req.query("bot");
8882
9064
  const botType = botParam === "admin" ? "admin" : botParam === "public" ? "public" : null;
8883
9065
  if (!botType) {
8884
- console.error(`${TAG22} op=reject reason=missing-bot-param`);
9066
+ console.error(`${TAG23} op=reject reason=missing-bot-param`);
8885
9067
  return c.json({ ok: false }, 400);
8886
9068
  }
8887
9069
  const sp = secretPath(botType);
8888
9070
  if (!existsSync10(sp)) {
8889
- console.error(`${TAG22} op=reject reason=no-secret-file botType=${botType}`);
9071
+ console.error(`${TAG23} op=reject reason=no-secret-file botType=${botType}`);
8890
9072
  return c.json({ ok: false }, 401);
8891
9073
  }
8892
9074
  const expected = readFileSync15(sp, "utf-8").trim();
8893
9075
  const got = c.req.header("x-telegram-bot-api-secret-token") ?? "";
8894
9076
  if (got !== expected) {
8895
- console.error(`${TAG22} op=reject reason=bad-secret botType=${botType}`);
9077
+ console.error(`${TAG23} op=reject reason=bad-secret botType=${botType}`);
8896
9078
  return c.json({ ok: false }, 401);
8897
9079
  }
8898
9080
  let update;
@@ -8903,25 +9085,25 @@ app6.post("/", async (c) => {
8903
9085
  }
8904
9086
  const account = resolveAccount();
8905
9087
  if (!account) {
8906
- console.error(`${TAG22} op=reject reason=no-account`);
9088
+ console.error(`${TAG23} op=reject reason=no-account`);
8907
9089
  return c.json({ ok: true }, 200);
8908
9090
  }
8909
9091
  const decision = routeTelegramUpdate({ update, botType, config: account.config.telegram ?? {} });
8910
9092
  if (decision.kind === "ignore") {
8911
- console.error(`${TAG22} op=ignore reason=${decision.reason}`);
9093
+ console.error(`${TAG23} op=ignore reason=${decision.reason}`);
8912
9094
  return c.json({ ok: true }, 200);
8913
9095
  }
8914
9096
  if (decision.kind === "denied") {
8915
- console.error(`${TAG22} op=denied reason=${decision.reason} agentType=${decision.agentType}`);
9097
+ console.error(`${TAG23} op=denied reason=${decision.reason} agentType=${decision.agentType}`);
8916
9098
  return c.json({ ok: true }, 200);
8917
9099
  }
8918
9100
  const role = decision.agentType === "admin" ? "admin" : "public";
8919
9101
  const agentSlug = role === "admin" ? "admin" : resolveDefaultAgentSlug(account.accountDir);
8920
9102
  if (!agentSlug) {
8921
- console.error(`${TAG22} op=reject reason=no-default-agent`);
9103
+ console.error(`${TAG23} op=reject reason=no-default-agent`);
8922
9104
  return c.json({ ok: true }, 200);
8923
9105
  }
8924
- console.error(`${TAG22} op=update accountId=${account.accountId} from=${decision.senderId}`);
9106
+ console.error(`${TAG23} op=update accountId=${account.accountId} from=${decision.senderId}`);
8925
9107
  const botToken = botType === "admin" ? account.config.telegram?.adminBotToken : account.config.telegram?.publicBotToken;
8926
9108
  const { senderId, chatId, text } = decision;
8927
9109
  void (async () => {
@@ -8935,29 +9117,29 @@ app6.post("/", async (c) => {
8935
9117
  timeoutMs: DISPATCH_TIMEOUT_MS
8936
9118
  });
8937
9119
  if ("error" in result) {
8938
- console.error(`${TAG22} op=dispatch-failed from=${senderId} error=${result.error}`);
9120
+ console.error(`${TAG23} op=dispatch-failed from=${senderId} error=${result.error}`);
8939
9121
  return;
8940
9122
  }
8941
9123
  if (!botToken) {
8942
9124
  const reason = account.config.telegram ? "no-bot-token" : "no-telegram-config";
8943
- console.error(`${TAG22} op=reply-dropped reason=${reason} botType=${botType}`);
9125
+ console.error(`${TAG23} op=reply-dropped reason=${reason} botType=${botType}`);
8944
9126
  return;
8945
9127
  }
8946
9128
  const sent = await sendTelegram(botToken, chatId, result.turnText);
8947
- console.error(`${TAG22} op=reply-sent from=${senderId} ok=${sent.ok}${sent.ok ? "" : ` error=${sent.error}`}`);
9129
+ console.error(`${TAG23} op=reply-sent from=${senderId} ok=${sent.ok}${sent.ok ? "" : ` error=${sent.error}`}`);
8948
9130
  })();
8949
9131
  return c.json({ ok: true }, 200);
8950
9132
  });
8951
- var telegram_default = app6;
9133
+ var telegram_default = app7;
8952
9134
 
8953
9135
  // server/routes/onboarding.ts
8954
9136
  import { spawn, spawnSync as spawnSync2, execFileSync as execFileSync2 } from "child_process";
8955
- import { openSync as openSync2, closeSync as closeSync2, writeFileSync as writeFileSync8, writeSync, existsSync as existsSync12, readFileSync as readFileSync17, unlinkSync } from "fs";
9137
+ import { openSync as openSync3, closeSync as closeSync3, writeFileSync as writeFileSync8, writeSync, existsSync as existsSync12, readFileSync as readFileSync17, unlinkSync } from "fs";
8956
9138
  import { createHash as createHash3, randomUUID as randomUUID8 } from "crypto";
8957
9139
 
8958
9140
  // ../lib/admins-write/src/index.ts
8959
- import { existsSync as existsSync11, readFileSync as readFileSync16, writeFileSync as writeFileSync7, renameSync as renameSync3, mkdirSync as mkdirSync2, readdirSync as readdirSync9, statSync as statSync5 } from "fs";
8960
- import { dirname as dirname3, join as join15 } from "path";
9141
+ import { existsSync as existsSync11, readFileSync as readFileSync16, writeFileSync as writeFileSync7, renameSync as renameSync3, mkdirSync as mkdirSync2, readdirSync as readdirSync9, statSync as statSync6 } from "fs";
9142
+ import { dirname as dirname4, join as join16 } from "path";
8961
9143
  function logLine(input, result) {
8962
9144
  const userIdShort = input.userId.slice(0, 8);
8963
9145
  console.error(
@@ -8965,7 +9147,7 @@ function logLine(input, result) {
8965
9147
  );
8966
9148
  }
8967
9149
  function writeFileAtomic(filePath, contents, mode) {
8968
- mkdirSync2(dirname3(filePath), { recursive: true });
9150
+ mkdirSync2(dirname4(filePath), { recursive: true });
8969
9151
  const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
8970
9152
  writeFileSync7(tempPath, contents, mode !== void 0 ? { mode } : void 0);
8971
9153
  renameSync3(tempPath, filePath);
@@ -8999,7 +9181,7 @@ function writeAdminEntry(input) {
8999
9181
  return result;
9000
9182
  }
9001
9183
  try {
9002
- const accountJsonPath = join15(input.accountDir, "account.json");
9184
+ const accountJsonPath = join16(input.accountDir, "account.json");
9003
9185
  if (!existsSync11(accountJsonPath)) {
9004
9186
  throw new Error(`account.json not found at ${accountJsonPath}`);
9005
9187
  }
@@ -9054,13 +9236,13 @@ function checkAdminAuthInvariant(input) {
9054
9236
  }
9055
9237
  for (const entry of entries) {
9056
9238
  if (entry.startsWith(".")) continue;
9057
- const accountDir = join15(input.accountsDir, entry);
9239
+ const accountDir = join16(input.accountsDir, entry);
9058
9240
  try {
9059
- if (!statSync5(accountDir).isDirectory()) continue;
9241
+ if (!statSync6(accountDir).isDirectory()) continue;
9060
9242
  } catch {
9061
9243
  continue;
9062
9244
  }
9063
- const accountJsonPath = join15(accountDir, "account.json");
9245
+ const accountJsonPath = join16(accountDir, "account.json");
9064
9246
  if (!existsSync11(accountJsonPath)) continue;
9065
9247
  let admins = [];
9066
9248
  try {
@@ -9135,11 +9317,11 @@ async function waitForAuthPage(timeoutMs = 2e4) {
9135
9317
  }
9136
9318
  return false;
9137
9319
  }
9138
- var app7 = new Hono();
9139
- app7.get("/claude-auth", async (c) => {
9320
+ var app8 = new Hono();
9321
+ app8.get("/claude-auth", async (c) => {
9140
9322
  return c.json({ authenticated: await checkAuthStatus() });
9141
9323
  });
9142
- app7.post("/claude-auth", async (c) => {
9324
+ app8.post("/claude-auth", async (c) => {
9143
9325
  let body = {};
9144
9326
  try {
9145
9327
  body = await c.req.json();
@@ -9177,7 +9359,7 @@ app7.post("/claude-auth", async (c) => {
9177
9359
  }
9178
9360
  ensureLogDir();
9179
9361
  writeFileSync8(logPath("claude-auth"), "");
9180
- const claudeAuthLogFd = openSync2(logPath("claude-auth"), "a");
9362
+ const claudeAuthLogFd = openSync3(logPath("claude-auth"), "a");
9181
9363
  const onClaudeOutput = (chunk) => writeSync(claudeAuthLogFd, chunk);
9182
9364
  if (process.platform === "darwin") {
9183
9365
  vncLog("claude-auth", { action: "start", transport: "native", platform: "darwin" });
@@ -9187,7 +9369,7 @@ app7.post("/claude-auth", async (c) => {
9187
9369
  claudeProc2.unref();
9188
9370
  claudeProc2.stdout?.on("data", onClaudeOutput);
9189
9371
  claudeProc2.stderr?.on("data", onClaudeOutput);
9190
- claudeProc2.once("close", () => closeSync2(claudeAuthLogFd));
9372
+ claudeProc2.once("close", () => closeSync3(claudeAuthLogFd));
9191
9373
  return c.json({ started: true, transport: "native" });
9192
9374
  }
9193
9375
  if (transport === "vnc") {
@@ -9205,11 +9387,11 @@ app7.post("/claude-auth", async (c) => {
9205
9387
  claudeProc.unref();
9206
9388
  claudeProc.stdout?.on("data", onClaudeOutput);
9207
9389
  claudeProc.stderr?.on("data", onClaudeOutput);
9208
- claudeProc.once("close", () => closeSync2(claudeAuthLogFd));
9390
+ claudeProc.once("close", () => closeSync3(claudeAuthLogFd));
9209
9391
  await waitForAuthPage(2e4);
9210
9392
  return c.json({ started: true, transport });
9211
9393
  });
9212
- app7.post("/set-pin", async (c) => {
9394
+ app8.post("/set-pin", async (c) => {
9213
9395
  let existingUsers = null;
9214
9396
  try {
9215
9397
  existingUsers = readUsersFile2();
@@ -9311,7 +9493,7 @@ ${body.pin}
9311
9493
  }
9312
9494
  return c.json({ ok: true });
9313
9495
  });
9314
- app7.delete("/set-pin", async (c) => {
9496
+ app8.delete("/set-pin", async (c) => {
9315
9497
  let users = null;
9316
9498
  try {
9317
9499
  users = readUsersFile2();
@@ -9345,12 +9527,12 @@ app7.delete("/set-pin", async (c) => {
9345
9527
  }
9346
9528
  return c.json({ ok: true });
9347
9529
  });
9348
- var onboarding_default = app7;
9530
+ var onboarding_default = app8;
9349
9531
 
9350
9532
  // server/routes/client-error.ts
9351
- import { appendFileSync, existsSync as existsSync13, renameSync as renameSync4, statSync as statSync6 } from "fs";
9352
- import { join as join16 } from "path";
9353
- var CLIENT_ERRORS_LOG = join16(LOG_DIR, "client-errors.log");
9533
+ import { appendFileSync, existsSync as existsSync13, renameSync as renameSync4, statSync as statSync7 } from "fs";
9534
+ import { join as join17 } from "path";
9535
+ var CLIENT_ERRORS_LOG = join17(LOG_DIR, "client-errors.log");
9354
9536
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
9355
9537
  var MAX_BODY_SIZE = 8 * 1024;
9356
9538
  var MAX_STACK_LEN = 2e3;
@@ -9394,15 +9576,15 @@ function stackHead(stack) {
9394
9576
  function rotateIfNeeded() {
9395
9577
  try {
9396
9578
  if (!existsSync13(CLIENT_ERRORS_LOG)) return;
9397
- const stats = statSync6(CLIENT_ERRORS_LOG);
9579
+ const stats = statSync7(CLIENT_ERRORS_LOG);
9398
9580
  if (stats.size < MAX_LOG_SIZE) return;
9399
9581
  renameSync4(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
9400
9582
  } catch (err) {
9401
9583
  console.error(`[client-error] log rotation failed: ${err instanceof Error ? err.message : String(err)}`);
9402
9584
  }
9403
9585
  }
9404
- var app8 = new Hono();
9405
- app8.post("/", async (c) => {
9586
+ var app9 = new Hono();
9587
+ app9.post("/", async (c) => {
9406
9588
  const client = resolveClientIp(
9407
9589
  c.env?.incoming?.socket?.remoteAddress,
9408
9590
  c.req.header("x-forwarded-for")
@@ -9504,7 +9686,7 @@ app8.post("/", async (c) => {
9504
9686
  }
9505
9687
  return c.json({ ok: true });
9506
9688
  });
9507
- var client_error_default = app8;
9689
+ var client_error_default = app9;
9508
9690
 
9509
9691
  // server/routes/admin/session.ts
9510
9692
  import { randomUUID as randomUUID9 } from "crypto";
@@ -9562,8 +9744,8 @@ async function createAdminSession(accountId, thinkingView, userId, userName, rol
9562
9744
  sessionId: initialSessionId
9563
9745
  };
9564
9746
  }
9565
- var app9 = new Hono();
9566
- app9.get("/", async (c) => {
9747
+ var app10 = new Hono();
9748
+ app10.get("/", async (c) => {
9567
9749
  const signedSessionToken = c.req.query("session_key");
9568
9750
  if (!signedSessionToken) {
9569
9751
  return c.json({ error: "Invalid or expired admin session" }, 401);
@@ -9609,7 +9791,7 @@ app9.get("/", async (c) => {
9609
9791
  sessionId: getSessionIdForSession(cacheKey) ?? null
9610
9792
  });
9611
9793
  });
9612
- app9.post("/", async (c) => {
9794
+ app10.post("/", async (c) => {
9613
9795
  let body;
9614
9796
  try {
9615
9797
  body = await c.req.json();
@@ -9672,20 +9854,20 @@ app9.post("/", async (c) => {
9672
9854
  const payload = await createAdminSession(selected.accountId, selected.config.thinkingView, userId, userName, selected.role, avatar);
9673
9855
  return c.json(payload);
9674
9856
  });
9675
- var session_default = app9;
9857
+ var session_default = app10;
9676
9858
 
9677
9859
  // server/routes/admin/logs.ts
9678
- import { existsSync as existsSync15, readdirSync as readdirSync10, readFileSync as readFileSync18, statSync as statSync7 } from "fs";
9679
- import { resolve as resolve15, basename as basename4 } from "path";
9860
+ import { existsSync as existsSync15, readdirSync as readdirSync10, readFileSync as readFileSync18, statSync as statSync8 } from "fs";
9861
+ import { resolve as resolve16, basename as basename5 } from "path";
9680
9862
 
9681
9863
  // app/lib/logs-read-resolve.ts
9682
9864
  import { existsSync as existsSync14 } from "fs";
9683
- import { join as join17 } from "path";
9865
+ import { join as join18 } from "path";
9684
9866
  function resolveSessionLogPaths(filename, logDirs) {
9685
9867
  const tried = [filename];
9686
9868
  const hits = [];
9687
9869
  for (const dir of logDirs) {
9688
- const fullPath = join17(dir, filename);
9870
+ const fullPath = join18(dir, filename);
9689
9871
  if (existsSync14(fullPath)) {
9690
9872
  hits.push({ path: fullPath, dir });
9691
9873
  }
@@ -9695,27 +9877,27 @@ function resolveSessionLogPaths(filename, logDirs) {
9695
9877
 
9696
9878
  // server/routes/admin/logs.ts
9697
9879
  var TAIL_BYTES = 8192;
9698
- var app10 = new Hono();
9699
- app10.get("/", async (c) => {
9880
+ var app11 = new Hono();
9881
+ app11.get("/", async (c) => {
9700
9882
  const fileParam = c.req.query("file");
9701
9883
  const typeParam = c.req.query("type");
9702
9884
  const sessionIdParam = c.req.query("sessionId");
9703
9885
  const cacheKeyParam = c.req.query("cacheKey");
9704
9886
  const download = c.req.query("download") === "1";
9705
9887
  const account = resolveAccount();
9706
- const accountLogDir = account ? resolve15(account.accountDir, "logs") : null;
9888
+ const accountLogDir = account ? resolve16(account.accountDir, "logs") : null;
9707
9889
  const logDirs = [];
9708
9890
  if (accountLogDir) logDirs.push(accountLogDir);
9709
9891
  logDirs.push(LOG_DIR);
9710
9892
  if (fileParam) {
9711
- const safe = basename4(fileParam);
9893
+ const safe = basename5(fileParam);
9712
9894
  const searched = [];
9713
9895
  for (const dir of logDirs) {
9714
- const filePath = resolve15(dir, safe);
9896
+ const filePath = resolve16(dir, safe);
9715
9897
  searched.push(filePath);
9716
9898
  try {
9717
9899
  const buffer = readFileSync18(filePath);
9718
- const onDiskBytes = statSync7(filePath).size;
9900
+ const onDiskBytes = statSync8(filePath).size;
9719
9901
  const headers = {
9720
9902
  "Content-Type": "text/plain; charset=utf-8",
9721
9903
  "Content-Length": String(buffer.byteLength)
@@ -9778,9 +9960,9 @@ app10.get("/", async (c) => {
9778
9960
  if (hit) {
9779
9961
  console.info(`[admin/logs] resolved cacheKey=${cacheKeySlice} sessionId=${sessionIdSlice} via=${primaryId === cacheKey ? "cacheKey" : primaryId === sessionKeyFromConv ? "reverse-lookup" : "sessionId-fallback"}`);
9780
9962
  try {
9781
- const filename = basename4(hit.path);
9963
+ const filename = basename5(hit.path);
9782
9964
  const buffer = readFileSync18(hit.path);
9783
- const onDiskBytes = statSync7(hit.path).size;
9965
+ const onDiskBytes = statSync8(hit.path).size;
9784
9966
  const headers = {
9785
9967
  "Content-Type": "text/plain; charset=utf-8",
9786
9968
  "Content-Length": String(buffer.byteLength)
@@ -9823,10 +10005,10 @@ app10.get("/", async (c) => {
9823
10005
  console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
9824
10006
  continue;
9825
10007
  }
9826
- files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync7(resolve15(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
10008
+ files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync8(resolve16(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
9827
10009
  seen.add(name);
9828
10010
  try {
9829
- const content = readFileSync18(resolve15(dir, name));
10011
+ const content = readFileSync18(resolve16(dir, name));
9830
10012
  const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
9831
10013
  logs[name] = tail.trim() || "(empty)";
9832
10014
  } catch (err) {
@@ -9838,12 +10020,12 @@ app10.get("/", async (c) => {
9838
10020
  }
9839
10021
  return c.json({ logs });
9840
10022
  });
9841
- var logs_default = app10;
10023
+ var logs_default = app11;
9842
10024
 
9843
10025
  // server/routes/admin/claude-info.ts
9844
10026
  import { execFileSync as execFileSync3 } from "child_process";
9845
- var app11 = new Hono();
9846
- app11.get("/", (c) => {
10027
+ var app12 = new Hono();
10028
+ app12.get("/", (c) => {
9847
10029
  let version = "unknown";
9848
10030
  try {
9849
10031
  const raw = execFileSync3("claude", ["--version"], { encoding: "utf-8", timeout: 5e3 });
@@ -9861,14 +10043,14 @@ app11.get("/", (c) => {
9861
10043
  const thinkingView = resolvedAccount?.config.thinkingView ?? "default";
9862
10044
  return c.json({ version, account, model, thinkingView });
9863
10045
  });
9864
- var claude_info_default = app11;
10046
+ var claude_info_default = app12;
9865
10047
 
9866
10048
  // server/routes/admin/attachment.ts
9867
10049
  import { readFile as readFile2, readdir } from "fs/promises";
9868
10050
  import { existsSync as existsSync16 } from "fs";
9869
- import { resolve as resolve16 } from "path";
9870
- var app12 = new Hono();
9871
- app12.get("/:attachmentId", requireAdminSession, async (c) => {
10051
+ import { resolve as resolve17 } from "path";
10052
+ var app13 = new Hono();
10053
+ app13.get("/:attachmentId", requireAdminSession, async (c) => {
9872
10054
  const attachmentId = c.req.param("attachmentId");
9873
10055
  const cacheKey = c.var.cacheKey;
9874
10056
  const accountId = getAccountIdForSession(cacheKey);
@@ -9878,11 +10060,11 @@ app12.get("/:attachmentId", requireAdminSession, async (c) => {
9878
10060
  if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(attachmentId)) {
9879
10061
  return new Response("Not found", { status: 404 });
9880
10062
  }
9881
- const dir = resolve16(DATA_ROOT, "accounts", accountId, "uploads", attachmentId);
10063
+ const dir = resolve17(DATA_ROOT, "accounts", accountId, "uploads", attachmentId);
9882
10064
  if (!existsSync16(dir)) {
9883
10065
  return new Response("Not found", { status: 404 });
9884
10066
  }
9885
- const metaPath = resolve16(dir, `${attachmentId}.meta.json`);
10067
+ const metaPath = resolve17(dir, `${attachmentId}.meta.json`);
9886
10068
  if (!existsSync16(metaPath)) {
9887
10069
  return new Response("Not found", { status: 404 });
9888
10070
  }
@@ -9897,7 +10079,7 @@ app12.get("/:attachmentId", requireAdminSession, async (c) => {
9897
10079
  if (!dataFile) {
9898
10080
  return new Response("Not found", { status: 404 });
9899
10081
  }
9900
- const filePath = resolve16(dir, dataFile);
10082
+ const filePath = resolve17(dir, dataFile);
9901
10083
  const buffer = await readFile2(filePath);
9902
10084
  return new Response(new Uint8Array(buffer), {
9903
10085
  headers: {
@@ -9907,16 +10089,16 @@ app12.get("/:attachmentId", requireAdminSession, async (c) => {
9907
10089
  }
9908
10090
  });
9909
10091
  });
9910
- var attachment_default = app12;
10092
+ var attachment_default = app13;
9911
10093
 
9912
10094
  // server/routes/admin/agents.ts
9913
- import { resolve as resolve17 } from "path";
10095
+ import { resolve as resolve18 } from "path";
9914
10096
  import { readdirSync as readdirSync11, readFileSync as readFileSync19, existsSync as existsSync17, rmSync } from "fs";
9915
- var app13 = new Hono();
9916
- app13.get("/", (c) => {
10097
+ var app14 = new Hono();
10098
+ app14.get("/", (c) => {
9917
10099
  const account = resolveAccount();
9918
10100
  if (!account) return c.json({ agents: [] });
9919
- const agentsDir = resolve17(account.accountDir, "agents");
10101
+ const agentsDir = resolve18(account.accountDir, "agents");
9920
10102
  if (!existsSync17(agentsDir)) return c.json({ agents: [] });
9921
10103
  const agents = [];
9922
10104
  try {
@@ -9924,7 +10106,7 @@ app13.get("/", (c) => {
9924
10106
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
9925
10107
  if (!entry.isDirectory()) continue;
9926
10108
  if (entry.name === "admin") continue;
9927
- const configPath2 = resolve17(agentsDir, entry.name, "config.json");
10109
+ const configPath2 = resolve18(agentsDir, entry.name, "config.json");
9928
10110
  if (!existsSync17(configPath2)) continue;
9929
10111
  try {
9930
10112
  const config = JSON.parse(readFileSync19(configPath2, "utf-8"));
@@ -9943,7 +10125,7 @@ app13.get("/", (c) => {
9943
10125
  }
9944
10126
  return c.json({ agents });
9945
10127
  });
9946
- app13.delete("/:slug", async (c) => {
10128
+ app14.delete("/:slug", async (c) => {
9947
10129
  const slug = c.req.param("slug");
9948
10130
  const account = resolveAccount();
9949
10131
  if (!account) return c.json({ error: "No account resolved" }, 400);
@@ -9953,7 +10135,7 @@ app13.delete("/:slug", async (c) => {
9953
10135
  if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
9954
10136
  return c.json({ error: "Invalid agent slug" }, 400);
9955
10137
  }
9956
- const agentDir = resolve17(account.accountDir, "agents", slug);
10138
+ const agentDir = resolve18(account.accountDir, "agents", slug);
9957
10139
  if (!existsSync17(agentDir)) {
9958
10140
  return c.json({ error: "Agent not found" }, 404);
9959
10141
  }
@@ -9973,7 +10155,7 @@ app13.delete("/:slug", async (c) => {
9973
10155
  return c.json({ error: "Failed to delete agent" }, 500);
9974
10156
  }
9975
10157
  });
9976
- app13.post("/:slug/project", async (c) => {
10158
+ app14.post("/:slug/project", async (c) => {
9977
10159
  const slug = c.req.param("slug");
9978
10160
  const account = resolveAccount();
9979
10161
  if (!account) return c.json({ error: "No account resolved" }, 400);
@@ -9983,7 +10165,7 @@ app13.post("/:slug/project", async (c) => {
9983
10165
  if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
9984
10166
  return c.json({ error: "Invalid agent slug" }, 400);
9985
10167
  }
9986
- const agentDir = resolve17(account.accountDir, "agents", slug);
10168
+ const agentDir = resolve18(account.accountDir, "agents", slug);
9987
10169
  if (!existsSync17(agentDir)) {
9988
10170
  return c.json({ error: "Agent not found on disk" }, 404);
9989
10171
  }
@@ -9995,7 +10177,7 @@ app13.post("/:slug/project", async (c) => {
9995
10177
  return c.json({ error: `Projection failed: ${msg}` }, 500);
9996
10178
  }
9997
10179
  });
9998
- var agents_default = app13;
10180
+ var agents_default = app14;
9999
10181
 
10000
10182
  // server/routes/admin/sessions.ts
10001
10183
  import crypto2 from "crypto";
@@ -10267,8 +10449,8 @@ function formatAge(updatedAtStr) {
10267
10449
  return "unknown";
10268
10450
  }
10269
10451
  }
10270
- var app14 = new Hono();
10271
- app14.get("/", requireAdminSession, async (c) => {
10452
+ var app15 = new Hono();
10453
+ app15.get("/", requireAdminSession, async (c) => {
10272
10454
  const cacheKey = c.var.cacheKey;
10273
10455
  const accountId = getAccountIdForSession(cacheKey);
10274
10456
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -10298,7 +10480,7 @@ app14.get("/", requireAdminSession, async (c) => {
10298
10480
  return c.json({ error: "Failed to fetch sessions" }, 500);
10299
10481
  }
10300
10482
  });
10301
- app14.post("/new", requireAdminSession, async (c) => {
10483
+ app15.post("/new", requireAdminSession, async (c) => {
10302
10484
  const oldCacheKey = c.var.cacheKey;
10303
10485
  console.log(`[admin-chat] new-conversation outcome=ingress cacheKey=${oldCacheKey.slice(0, 8)}`);
10304
10486
  const accountId = getAccountIdForSession(oldCacheKey);
@@ -10315,7 +10497,7 @@ app14.post("/new", requireAdminSession, async (c) => {
10315
10497
  console.log(`[admin-chat] new-conversation outcome=ok oldKey=${oldCacheKey.slice(0, 8)} newKey=${newCacheKey.slice(0, 8)}`);
10316
10498
  return c.json({ session_key: newSignedSessionToken, sessionId: null });
10317
10499
  });
10318
- app14.post("/switch", requireAdminSession, async (c) => {
10500
+ app15.post("/switch", requireAdminSession, async (c) => {
10319
10501
  const cacheKey = c.var.cacheKey;
10320
10502
  const accountId = getAccountIdForSession(cacheKey);
10321
10503
  const userId = getUserIdForSession(cacheKey);
@@ -10343,7 +10525,7 @@ app14.post("/switch", requireAdminSession, async (c) => {
10343
10525
  console.log(`[session-switch] from=${cacheKey.slice(0, 8)} to=${targetCacheKey.slice(0, 8)} targetConvId=${targetSessionId?.slice(0, 8) ?? "none"} accountId=${accountId.slice(0, 8)}`);
10344
10526
  return c.json({ session_key: targetSignedSessionToken, sessionId: targetSessionId });
10345
10527
  });
10346
- app14.delete("/:id", requireAdminSession, async (c) => {
10528
+ app15.delete("/:id", requireAdminSession, async (c) => {
10347
10529
  const sessionId = c.req.param("id");
10348
10530
  const cacheKey = c.var.cacheKey;
10349
10531
  const accountId = getAccountIdForSession(cacheKey);
@@ -10388,7 +10570,7 @@ app14.delete("/:id", requireAdminSession, async (c) => {
10388
10570
  500
10389
10571
  );
10390
10572
  });
10391
- app14.post("/:id/resume", async (c) => {
10573
+ app15.post("/:id/resume", async (c) => {
10392
10574
  const sessionId = c.req.param("id");
10393
10575
  const t0 = Date.now();
10394
10576
  const signedSessionToken = c.req.query("session_key") ?? "";
@@ -10657,7 +10839,7 @@ app14.post("/:id/resume", async (c) => {
10657
10839
  }
10658
10840
  });
10659
10841
  });
10660
- app14.put("/:id/label", requireAdminSession, async (c) => {
10842
+ app15.put("/:id/label", requireAdminSession, async (c) => {
10661
10843
  const sessionId = c.req.param("id");
10662
10844
  const cacheKey = c.var.cacheKey;
10663
10845
  let body;
@@ -10683,11 +10865,11 @@ app14.put("/:id/label", requireAdminSession, async (c) => {
10683
10865
  return c.json({ error: "Failed to rename session" }, 500);
10684
10866
  }
10685
10867
  });
10686
- var sessions_default = app14;
10868
+ var sessions_default = app15;
10687
10869
 
10688
10870
  // app/lib/claude-agent/spawn-context.ts
10689
- import { existsSync as existsSync19, readFileSync as readFileSync20, readdirSync as readdirSync12, statSync as statSync8 } from "fs";
10690
- import { dirname as dirname4, resolve as resolve18, join as join18 } from "path";
10871
+ import { existsSync as existsSync19, readFileSync as readFileSync20, readdirSync as readdirSync12, statSync as statSync9 } from "fs";
10872
+ import { dirname as dirname5, resolve as resolve19, join as join19 } from "path";
10691
10873
  async function resolveOwnerProfileBlock(accountId, userId) {
10692
10874
  if (!userId) return { ok: false, reason: "missing-user-id" };
10693
10875
  try {
@@ -10716,8 +10898,8 @@ function frontmatterField(manifest, field2) {
10716
10898
  function extractPluginToolDescriptions(pluginDir) {
10717
10899
  const out = /* @__PURE__ */ new Map();
10718
10900
  const candidates = [
10719
- join18(pluginDir, "mcp/dist/index.js"),
10720
- join18(pluginDir, "mcp/src/index.ts")
10901
+ join19(pluginDir, "mcp/dist/index.js"),
10902
+ join19(pluginDir, "mcp/src/index.ts")
10721
10903
  ];
10722
10904
  let raw = null;
10723
10905
  for (const path2 of candidates) {
@@ -10772,26 +10954,26 @@ function parseSkillPathsFromFrontmatter(fm) {
10772
10954
  }
10773
10955
  function listPluginDirs() {
10774
10956
  const out = /* @__PURE__ */ new Map();
10775
- const platformPlugins = resolve18(PLATFORM_ROOT, "plugins");
10957
+ const platformPlugins = resolve19(PLATFORM_ROOT, "plugins");
10776
10958
  if (existsSync19(platformPlugins)) {
10777
10959
  for (const name of readdirSync12(platformPlugins)) {
10778
- const dir = join18(platformPlugins, name);
10960
+ const dir = join19(platformPlugins, name);
10779
10961
  try {
10780
- if (statSync8(dir).isDirectory()) out.set(name, dir);
10962
+ if (statSync9(dir).isDirectory()) out.set(name, dir);
10781
10963
  } catch {
10782
10964
  }
10783
10965
  }
10784
10966
  }
10785
- const premiumRoot = resolve18(dirname4(PLATFORM_ROOT), "premium-plugins");
10967
+ const premiumRoot = resolve19(dirname5(PLATFORM_ROOT), "premium-plugins");
10786
10968
  if (existsSync19(premiumRoot)) {
10787
10969
  for (const bundle of readdirSync12(premiumRoot)) {
10788
- const bundlePlugins = join18(premiumRoot, bundle, "plugins");
10970
+ const bundlePlugins = join19(premiumRoot, bundle, "plugins");
10789
10971
  if (!existsSync19(bundlePlugins)) continue;
10790
10972
  try {
10791
10973
  for (const name of readdirSync12(bundlePlugins)) {
10792
- const dir = join18(bundlePlugins, name);
10974
+ const dir = join19(bundlePlugins, name);
10793
10975
  try {
10794
- if (statSync8(dir).isDirectory()) out.set(name, dir);
10976
+ if (statSync9(dir).isDirectory()) out.set(name, dir);
10795
10977
  } catch {
10796
10978
  }
10797
10979
  }
@@ -10802,7 +10984,7 @@ function listPluginDirs() {
10802
10984
  return out;
10803
10985
  }
10804
10986
  function readEnabledPlugins(accountId) {
10805
- const accountFile = resolve18(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
10987
+ const accountFile = resolve19(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
10806
10988
  if (!existsSync19(accountFile)) return /* @__PURE__ */ new Set();
10807
10989
  try {
10808
10990
  const parsed = JSON.parse(readFileSync20(accountFile, "utf-8"));
@@ -10832,7 +11014,7 @@ function computeActivePlugins(accountId) {
10832
11014
  for (const name of Array.from(enabled).sort()) {
10833
11015
  const dir = pluginDirs.get(name);
10834
11016
  if (!dir) continue;
10835
- const fm = readFrontmatter(join18(dir, "PLUGIN.md"));
11017
+ const fm = readFrontmatter(join19(dir, "PLUGIN.md"));
10836
11018
  if (!fm) continue;
10837
11019
  const description = frontmatterField(`---
10838
11020
  ${fm}
@@ -10849,7 +11031,7 @@ ${fm}
10849
11031
  `plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
10850
11032
  );
10851
11033
  if (toolNames.length > 0 && descMap.size === 0) {
10852
- const hasSource = existsSync19(join18(dir, "mcp/dist/index.js")) || existsSync19(join18(dir, "mcp/src/index.ts"));
11034
+ const hasSource = existsSync19(join19(dir, "mcp/dist/index.js")) || existsSync19(join19(dir, "mcp/src/index.ts"));
10853
11035
  if (hasSource) {
10854
11036
  console.warn(
10855
11037
  `[spawn-context] WARN plugin=${name} mcp source present but tool-description regex matched zero entries \u2014 SDK upgrade may have changed the registration shape`
@@ -10859,7 +11041,7 @@ ${fm}
10859
11041
  const skillPaths = parseSkillPathsFromFrontmatter(fm);
10860
11042
  const skills = [];
10861
11043
  for (const relPath of skillPaths) {
10862
- const skillPath = join18(dir, relPath);
11044
+ const skillPath = join19(dir, relPath);
10863
11045
  const skillFm = readFrontmatter(skillPath);
10864
11046
  if (!skillFm) continue;
10865
11047
  const skillName = frontmatterField(`---
@@ -10875,7 +11057,7 @@ ${skillFm}
10875
11057
  return out;
10876
11058
  }
10877
11059
  function computeSpecialistDomains(accountId) {
10878
- const specialistsDir = resolve18(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
11060
+ const specialistsDir = resolve19(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
10879
11061
  if (!existsSync19(specialistsDir)) return [];
10880
11062
  let entries;
10881
11063
  try {
@@ -10888,10 +11070,10 @@ function computeSpecialistDomains(accountId) {
10888
11070
  const resolveDesc = (qualified) => {
10889
11071
  if (!qualified.startsWith("mcp__")) return void 0;
10890
11072
  const rest = qualified.slice(5);
10891
- const sep8 = rest.indexOf("__");
10892
- if (sep8 < 0) return void 0;
10893
- const plugin = rest.slice(0, sep8);
10894
- const tool = rest.slice(sep8 + 2);
11073
+ const sep9 = rest.indexOf("__");
11074
+ if (sep9 < 0) return void 0;
11075
+ const plugin = rest.slice(0, sep9);
11076
+ const tool = rest.slice(sep9 + 2);
10895
11077
  let map = descByPlugin.get(plugin);
10896
11078
  if (!map) {
10897
11079
  const dir = pluginDirs.get(plugin);
@@ -10903,7 +11085,7 @@ function computeSpecialistDomains(accountId) {
10903
11085
  const out = [];
10904
11086
  for (const file of entries.sort()) {
10905
11087
  if (!file.endsWith(".md")) continue;
10906
- const fm = readFrontmatter(join18(specialistsDir, file));
11088
+ const fm = readFrontmatter(join19(specialistsDir, file));
10907
11089
  if (!fm) continue;
10908
11090
  const wrapped = `---
10909
11091
  ${fm}
@@ -10921,7 +11103,7 @@ ${fm}
10921
11103
  return out;
10922
11104
  }
10923
11105
  function computeDormantPlugins(accountId) {
10924
- const accountFile = resolve18(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
11106
+ const accountFile = resolve19(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
10925
11107
  if (!existsSync19(accountFile)) return [];
10926
11108
  let enabled;
10927
11109
  try {
@@ -10936,7 +11118,7 @@ function computeDormantPlugins(accountId) {
10936
11118
  );
10937
11119
  return [];
10938
11120
  }
10939
- const pluginsDir = resolve18(PLATFORM_ROOT, "plugins");
11121
+ const pluginsDir = resolve19(PLATFORM_ROOT, "plugins");
10940
11122
  if (!existsSync19(pluginsDir)) return [];
10941
11123
  let entries;
10942
11124
  try {
@@ -10947,7 +11129,7 @@ function computeDormantPlugins(accountId) {
10947
11129
  const out = [];
10948
11130
  for (const name of entries) {
10949
11131
  if (enabled.has(name)) continue;
10950
- const manifestPath = resolve18(pluginsDir, name, "PLUGIN.md");
11132
+ const manifestPath = resolve19(pluginsDir, name, "PLUGIN.md");
10951
11133
  if (!existsSync19(manifestPath)) continue;
10952
11134
  let manifest;
10953
11135
  try {
@@ -10966,7 +11148,7 @@ function computeDormantPlugins(accountId) {
10966
11148
 
10967
11149
  // server/routes/admin/claude-sessions.ts
10968
11150
  import { existsSync as existsSync20, readFileSync as readFileSync21 } from "fs";
10969
- import { resolve as resolve19 } from "path";
11151
+ import { resolve as resolve20 } from "path";
10970
11152
  function readTunnelState(brandConfigDir) {
10971
11153
  const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
10972
11154
  if (!existsSync20(statePath)) return null;
@@ -10982,10 +11164,10 @@ function readTunnelState(brandConfigDir) {
10982
11164
  }
10983
11165
  }
10984
11166
  function resolveTunnelUrl() {
10985
- const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve19(process.cwd(), "..");
11167
+ const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
10986
11168
  let brand;
10987
11169
  try {
10988
- brand = JSON.parse(readFileSync21(resolve19(platformRoot2, "config", "brand.json"), "utf-8"));
11170
+ brand = JSON.parse(readFileSync21(resolve20(platformRoot2, "config", "brand.json"), "utf-8"));
10989
11171
  } catch {
10990
11172
  return null;
10991
11173
  }
@@ -10996,7 +11178,7 @@ function resolveTunnelUrl() {
10996
11178
  if (!state) return null;
10997
11179
  return `https://${hostname2}.${state.domain}`;
10998
11180
  }
10999
- var TAG23 = "[claude-session-manager:wrapper]";
11181
+ var TAG24 = "[claude-session-manager:wrapper]";
11000
11182
  async function refuseIfClaudeAuthDead(c, route, sessionId) {
11001
11183
  const auth = await ensureAuth();
11002
11184
  if (auth.status !== "dead" && auth.status !== "missing") return null;
@@ -11008,18 +11190,18 @@ async function refuseIfClaudeAuthDead(c, route, sessionId) {
11008
11190
  503
11009
11191
  );
11010
11192
  }
11011
- var app15 = new Hono();
11193
+ var app16 = new Hono();
11012
11194
  async function performSpawnWithInitialMessage(args) {
11013
11195
  const ownerStart = Date.now();
11014
11196
  const aboutOwner = await resolveOwnerProfileBlock(args.senderId, args.userId);
11015
11197
  const ownerMs = Date.now() - ownerStart;
11016
11198
  const aboutOwnerStatus = aboutOwner == null ? "absent" : "ok" in aboutOwner && aboutOwner.ok === false ? `unresolved:${aboutOwner.reason}` : "ok";
11017
- console.log(`${TAG23} about-owner-resolved status=${aboutOwnerStatus} ms=${ownerMs}`);
11199
+ console.log(`${TAG24} about-owner-resolved status=${aboutOwnerStatus} ms=${ownerMs}`);
11018
11200
  const dormantPlugins = computeDormantPlugins(args.senderId);
11019
11201
  const activePlugins = computeActivePlugins(args.senderId);
11020
11202
  const specialistDomains = computeSpecialistDomains(args.senderId);
11021
11203
  const tunnelUrl = resolveTunnelUrl();
11022
- console.log(`${TAG23} tunnel-url-resolved value=${tunnelUrl ?? "null"}`);
11204
+ console.log(`${TAG24} tunnel-url-resolved value=${tunnelUrl ?? "null"}`);
11023
11205
  const upstreamPayload = JSON.stringify({
11024
11206
  senderId: args.senderId,
11025
11207
  // Task 205 — pass userId through to the manager so it lands as
@@ -11046,24 +11228,24 @@ async function performSpawnWithInitialMessage(args) {
11046
11228
  // unshapely values.
11047
11229
  conversationNodeId: args.conversationNodeId
11048
11230
  });
11049
- console.log(`${TAG23} forward-spawn-start managerBase=${managerBase("claude-session-manager:wrapper")} bytes=${upstreamPayload.length} hidden=${args.hidden} specialist=${args.specialist ?? "none"}`);
11231
+ console.log(`${TAG24} forward-spawn-start managerBase=${managerBase("claude-session-manager:wrapper")} bytes=${upstreamPayload.length} hidden=${args.hidden} specialist=${args.specialist ?? "none"}`);
11050
11232
  const forwardStart = Date.now();
11051
11233
  const upstream = await fetch(`${managerBase("claude-session-manager:wrapper")}/public-spawn`, {
11052
11234
  method: "POST",
11053
11235
  headers: { "content-type": "application/json" },
11054
11236
  body: upstreamPayload
11055
11237
  }).catch((err) => {
11056
- console.error(`${TAG23} fetch-failed op=spawn message=${err instanceof Error ? err.message : String(err)} ms=${Date.now() - forwardStart}`);
11238
+ console.error(`${TAG24} fetch-failed op=spawn message=${err instanceof Error ? err.message : String(err)} ms=${Date.now() - forwardStart}`);
11057
11239
  return null;
11058
11240
  });
11059
11241
  if (!upstream) return {
11060
11242
  response: new Response(JSON.stringify({ error: "manager-unreachable" }), { status: 503, headers: { "content-type": "application/json" } }),
11061
11243
  claudeSessionId: null
11062
11244
  };
11063
- console.log(`${TAG23} forward-spawn-done status=${upstream.status} ms=${Date.now() - forwardStart}`);
11245
+ console.log(`${TAG24} forward-spawn-done status=${upstream.status} ms=${Date.now() - forwardStart}`);
11064
11246
  if (args.initialMessage) {
11065
11247
  const inputBytes = Buffer.byteLength(args.initialMessage, "utf8");
11066
- console.log(`${TAG23} initial-message-inlined bytes=${inputBytes}`);
11248
+ console.log(`${TAG24} initial-message-inlined bytes=${inputBytes}`);
11067
11249
  }
11068
11250
  const bodyText = await upstream.text().catch(() => "");
11069
11251
  let claudeSessionId = null;
@@ -11085,8 +11267,8 @@ function mintTranscriptEdge(sessionId, claudeSessionId, accountId) {
11085
11267
  if (!sessionId || !claudeSessionId) return;
11086
11268
  void linkConversationTranscript(sessionId, claudeSessionId, accountId);
11087
11269
  }
11088
- app15.use("*", requireAdminSession);
11089
- app15.post("/", async (c) => {
11270
+ app16.use("*", requireAdminSession);
11271
+ app16.post("/", async (c) => {
11090
11272
  const routeStart = Date.now();
11091
11273
  const cacheKey = c.get("cacheKey") ?? "";
11092
11274
  let body = {};
@@ -11098,7 +11280,7 @@ app15.post("/", async (c) => {
11098
11280
  if (refusal) return refusal;
11099
11281
  const senderId = getAccountIdForSession(cacheKey) ?? "";
11100
11282
  if (!senderId) {
11101
- console.error(`${TAG23} reject reason=no-account-id cacheKey-prefix=${cacheKey.slice(0, 8)}`);
11283
+ console.error(`${TAG24} reject reason=no-account-id cacheKey-prefix=${cacheKey.slice(0, 8)}`);
11102
11284
  return c.json({ error: "admin-account-not-resolved" }, 500);
11103
11285
  }
11104
11286
  const userId = getUserIdForSession(cacheKey) ?? void 0;
@@ -11107,7 +11289,7 @@ app15.post("/", async (c) => {
11107
11289
  const permissionMode = typeof body.permissionMode === "string" ? body.permissionMode : void 0;
11108
11290
  const specialist = typeof body.specialist === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(body.specialist) ? body.specialist : void 0;
11109
11291
  const model = typeof body.model === "string" && /^[A-Za-z0-9._-]{1,64}$/.test(body.model) ? body.model : void 0;
11110
- console.log(`${TAG23} spawn-request-in surface=cookie accountId=${senderId.slice(0, 8)} userId=${userId ? userId.slice(0, 8) : "absent"} channel=${channel} permissionMode=${permissionMode ?? "default"} specialist=${specialist ?? "none"} model=${model ?? "default"} initialMessage=${initialMessage ? "yes" : "no"}`);
11292
+ console.log(`${TAG24} spawn-request-in surface=cookie accountId=${senderId.slice(0, 8)} userId=${userId ? userId.slice(0, 8) : "absent"} channel=${channel} permissionMode=${permissionMode ?? "default"} specialist=${specialist ?? "none"} model=${model ?? "default"} initialMessage=${initialMessage ? "yes" : "no"}`);
11111
11293
  const conversationNodeId = cacheKey ? getSessionIdForSession(cacheKey) : void 0;
11112
11294
  const { response, claudeSessionId } = await performSpawnWithInitialMessage({
11113
11295
  senderId,
@@ -11126,24 +11308,24 @@ app15.post("/", async (c) => {
11126
11308
  claudeSessionId,
11127
11309
  senderId
11128
11310
  );
11129
- console.log(`${TAG23} route-done surface=cookie status=${response.status} route-ms=${Date.now() - routeStart}`);
11311
+ console.log(`${TAG24} route-done surface=cookie status=${response.status} route-ms=${Date.now() - routeStart}`);
11130
11312
  return response;
11131
11313
  });
11132
- var claude_sessions_default = app15;
11314
+ var claude_sessions_default = app16;
11133
11315
 
11134
11316
  // server/routes/admin/log-ingest.ts
11135
- var TAG24 = "[log-ingest]";
11317
+ var TAG25 = "[log-ingest]";
11136
11318
  var TAG_PATTERN = /^[A-Za-z0-9_:-]{1,32}$/;
11137
11319
  var LEVELS = /* @__PURE__ */ new Set(["debug", "info", "warn", "error"]);
11138
11320
  var MAX_LINE_BYTES = 4096;
11139
- var app16 = new Hono();
11321
+ var app17 = new Hono();
11140
11322
  function isLoopbackAddr(addr) {
11141
11323
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
11142
11324
  }
11143
- app16.post("/", async (c) => {
11325
+ app17.post("/", async (c) => {
11144
11326
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
11145
11327
  if (!isLoopbackAddr(remoteAddr)) {
11146
- console.error(`${TAG24} reject reason=non-loopback remoteAddr=${remoteAddr}`);
11328
+ console.error(`${TAG25} reject reason=non-loopback remoteAddr=${remoteAddr}`);
11147
11329
  return c.json({ error: "log-ingest-loopback-only" }, 403);
11148
11330
  }
11149
11331
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -11152,7 +11334,7 @@ app16.post("/", async (c) => {
11152
11334
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
11153
11335
  const offender = tokens.find((t) => !isLoopbackAddr(t));
11154
11336
  if (offender !== void 0) {
11155
- console.error(`${TAG24} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
11337
+ console.error(`${TAG25} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
11156
11338
  return c.json({ error: "log-ingest-loopback-only" }, 403);
11157
11339
  }
11158
11340
  }
@@ -11183,7 +11365,7 @@ app16.post("/", async (c) => {
11183
11365
  else console.log(formatted);
11184
11366
  return c.json({ ok: true }, 200);
11185
11367
  });
11186
- var log_ingest_default = app16;
11368
+ var log_ingest_default = app17;
11187
11369
 
11188
11370
  // server/routes/admin/events.ts
11189
11371
  var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
@@ -11192,20 +11374,20 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
11192
11374
  "device-url:vnc-surface-shown",
11193
11375
  "device-url:malformed"
11194
11376
  ]);
11195
- var app17 = new Hono();
11196
- app17.post("/", async (c) => {
11197
- const TAG33 = "[admin:events]";
11377
+ var app18 = new Hono();
11378
+ app18.post("/", async (c) => {
11379
+ const TAG34 = "[admin:events]";
11198
11380
  let body;
11199
11381
  try {
11200
11382
  body = await c.req.json();
11201
11383
  } catch (err) {
11202
11384
  const detail = err instanceof Error ? err.message : String(err);
11203
- console.error(`${TAG33} reject reason=body-not-json detail=${detail}`);
11385
+ console.error(`${TAG34} reject reason=body-not-json detail=${detail}`);
11204
11386
  return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
11205
11387
  }
11206
11388
  const event = typeof body.event === "string" ? body.event : "";
11207
11389
  if (!ALLOWED_EVENTS.has(event)) {
11208
- console.error(`${TAG33} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
11390
+ console.error(`${TAG34} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
11209
11391
  return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
11210
11392
  }
11211
11393
  const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
@@ -11224,13 +11406,13 @@ app17.post("/", async (c) => {
11224
11406
  console.error(`[${event}] ${formatted}`);
11225
11407
  return c.json({ ok: true });
11226
11408
  });
11227
- var events_default = app17;
11409
+ var events_default = app18;
11228
11410
 
11229
11411
  // server/routes/admin/files.ts
11230
11412
  import { createReadStream as createReadStream2 } from "fs";
11231
11413
  import { readdir as readdir3, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
11232
11414
  import { realpathSync as realpathSync4 } from "fs";
11233
- import { basename as basename6, dirname as dirname5, join as join20, resolve as resolve21, sep as sep5 } from "path";
11415
+ import { basename as basename7, dirname as dirname6, join as join21, resolve as resolve22, sep as sep6 } from "path";
11234
11416
  import { Readable as Readable2 } from "stream";
11235
11417
 
11236
11418
  // ../lib/graph-trash/src/index.ts
@@ -11548,7 +11730,7 @@ async function cascadeDeleteDocument(params) {
11548
11730
 
11549
11731
  // app/lib/file-index.ts
11550
11732
  import * as fsp from "fs/promises";
11551
- import { resolve as resolve20, relative as relative2, join as join19, basename as basename5, extname as extname2, sep as sep4 } from "path";
11733
+ import { resolve as resolve21, relative as relative2, join as join20, basename as basename6, extname as extname2, sep as sep5 } from "path";
11552
11734
  import { tmpdir as tmpdir2 } from "os";
11553
11735
  import { execFile as execFile2 } from "child_process";
11554
11736
  import { promisify as promisify2 } from "util";
@@ -11630,7 +11812,7 @@ async function extractPdf(absolute) {
11630
11812
  return stdout.trim();
11631
11813
  }
11632
11814
  async function ocrPdf(absolute) {
11633
- const outPdf = join19(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
11815
+ const outPdf = join20(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
11634
11816
  try {
11635
11817
  await execFileAsync2(
11636
11818
  "ocrmypdf",
@@ -11686,13 +11868,13 @@ async function extractFileContent(absolute) {
11686
11868
  }
11687
11869
  }
11688
11870
  async function readDisplayName(absolute) {
11689
- const dir = absolute.slice(0, absolute.length - basename5(absolute).length);
11690
- const base = basename5(absolute);
11871
+ const dir = absolute.slice(0, absolute.length - basename6(absolute).length);
11872
+ const base = basename6(absolute);
11691
11873
  const dot = base.lastIndexOf(".");
11692
11874
  const stem = dot === -1 ? base : base.slice(0, dot);
11693
11875
  if (base === `${stem}.meta.json`) return null;
11694
11876
  try {
11695
- const raw = await fsp.readFile(join19(dir, `${stem}.meta.json`), "utf-8");
11877
+ const raw = await fsp.readFile(join20(dir, `${stem}.meta.json`), "utf-8");
11696
11878
  const meta = JSON.parse(raw);
11697
11879
  const dn = meta.displayName ?? meta.filename;
11698
11880
  return typeof dn === "string" && dn.length > 0 ? dn : null;
@@ -11712,7 +11894,7 @@ async function walkSubtree(root, dataRoot, out) {
11712
11894
  let clean = true;
11713
11895
  for (const entry of entries) {
11714
11896
  if (entry.isSymbolicLink()) continue;
11715
- const abs = join19(root, entry.name);
11897
+ const abs = join20(root, entry.name);
11716
11898
  if (entry.isDirectory()) {
11717
11899
  const sub = await walkSubtree(abs, dataRoot, out);
11718
11900
  if (!sub.clean) clean = false;
@@ -11721,7 +11903,7 @@ async function walkSubtree(root, dataRoot, out) {
11721
11903
  const st = await fsp.stat(abs);
11722
11904
  out.push({
11723
11905
  absolute: abs,
11724
- relativePath: relative2(dataRoot, abs).split(sep4).join("/"),
11906
+ relativePath: relative2(dataRoot, abs).split(sep5).join("/"),
11725
11907
  sizeBytes: st.size,
11726
11908
  modifiedAt: st.mtime.toISOString()
11727
11909
  });
@@ -11824,7 +12006,7 @@ async function cascadeTrashLinkedKnowledgeDocs(session, accountId, relativePaths
11824
12006
  return { kds, sections, chunks };
11825
12007
  }
11826
12008
  async function buildArtifact(accountId, wf, embed2) {
11827
- const name = basename5(wf.absolute);
12009
+ const name = basename6(wf.absolute);
11828
12010
  const { content, route } = await extractFileContent(wf.absolute);
11829
12011
  const displayName = await readDisplayName(wf.absolute);
11830
12012
  const embedInput = `${name}
@@ -11867,7 +12049,7 @@ async function reconcileFileIndex(accountId, opts) {
11867
12049
  return withSession(opts, async (session) => {
11868
12050
  const walked = [];
11869
12051
  const subtreeRoots = [
11870
- resolve20(dataRoot, "accounts", accountId)
12052
+ resolve21(dataRoot, "accounts", accountId)
11871
12053
  ];
11872
12054
  let clean = true;
11873
12055
  for (const root of subtreeRoots) {
@@ -11950,7 +12132,7 @@ async function reconcileFileIndexDebounced(accountId, opts) {
11950
12132
  async function indexFile(accountId, relativePath, opts) {
11951
12133
  const dataRoot = opts?.dataRoot ?? DATA_ROOT;
11952
12134
  const embed2 = opts?.embed ?? embed;
11953
- const absolute = resolve20(dataRoot, relativePath);
12135
+ const absolute = resolve21(dataRoot, relativePath);
11954
12136
  await withSession(opts, async (session) => {
11955
12137
  const st = await fsp.stat(absolute);
11956
12138
  const wf = {
@@ -11984,7 +12166,7 @@ async function dropFileIndex(accountId, relativePath, opts) {
11984
12166
  var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
11985
12167
  async function readMeta(absDir, baseName) {
11986
12168
  try {
11987
- const raw = await readFile4(join20(absDir, `${baseName}.meta.json`), "utf8");
12169
+ const raw = await readFile4(join21(absDir, `${baseName}.meta.json`), "utf8");
11988
12170
  const parsed = JSON.parse(raw);
11989
12171
  if (typeof parsed?.filename === "string") {
11990
12172
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -11995,7 +12177,7 @@ async function readMeta(absDir, baseName) {
11995
12177
  }
11996
12178
  async function readAccountNames() {
11997
12179
  const map = /* @__PURE__ */ new Map();
11998
- const accountsDir = resolve21(DATA_ROOT, "accounts");
12180
+ const accountsDir = resolve22(DATA_ROOT, "accounts");
11999
12181
  let names;
12000
12182
  try {
12001
12183
  names = await readdir3(accountsDir);
@@ -12004,7 +12186,7 @@ async function readAccountNames() {
12004
12186
  }
12005
12187
  for (const name of names) {
12006
12188
  if (!UUID_RE3.test(name)) continue;
12007
- const configPath2 = resolve21(accountsDir, name, "account.json");
12189
+ const configPath2 = resolve22(accountsDir, name, "account.json");
12008
12190
  try {
12009
12191
  const raw = await readFile4(configPath2, "utf8");
12010
12192
  const parsed = JSON.parse(raw);
@@ -12022,7 +12204,7 @@ async function readAccountNames() {
12022
12204
  }
12023
12205
  async function enrich(absolute, entry, accountNames) {
12024
12206
  if (entry.kind === "directory" && UUID_RE3.test(entry.name)) {
12025
- const meta = await readMeta(join20(absolute, entry.name), entry.name);
12207
+ const meta = await readMeta(join21(absolute, entry.name), entry.name);
12026
12208
  if (meta?.filename) {
12027
12209
  entry.displayName = meta.filename;
12028
12210
  entry.mimeType = meta.mimeType;
@@ -12108,8 +12290,8 @@ async function knowledgeDocOwnedByAccount(accountId, attachmentId) {
12108
12290
  await session.close();
12109
12291
  }
12110
12292
  }
12111
- var app18 = new Hono();
12112
- app18.get("/", requireAdminSession, async (c) => {
12293
+ var app19 = new Hono();
12294
+ app19.get("/", requireAdminSession, async (c) => {
12113
12295
  const cacheKey = c.var.cacheKey;
12114
12296
  const accountId = getAccountIdForSession(cacheKey);
12115
12297
  if (!accountId) {
@@ -12148,7 +12330,7 @@ app18.get("/", requireAdminSession, async (c) => {
12148
12330
  const childRel = relPath === "" || relPath === "." ? name : `${relPath}/${name}`;
12149
12331
  const protectedEntry = isProtectedFromDeletion(childRel).protected;
12150
12332
  try {
12151
- const entryPath = join20(absolute, name);
12333
+ const entryPath = join21(absolute, name);
12152
12334
  const s = await stat4(entryPath);
12153
12335
  entries.push({
12154
12336
  name,
@@ -12178,7 +12360,7 @@ app18.get("/", requireAdminSession, async (c) => {
12178
12360
  return c.json({ error: message }, 500);
12179
12361
  }
12180
12362
  });
12181
- app18.get("/download", requireAdminSession, async (c) => {
12363
+ app19.get("/download", requireAdminSession, async (c) => {
12182
12364
  const cacheKey = c.var.cacheKey;
12183
12365
  const accountId = getAccountIdForSession(cacheKey);
12184
12366
  if (!accountId) {
@@ -12215,7 +12397,7 @@ app18.get("/download", requireAdminSession, async (c) => {
12215
12397
  if (!info.isFile()) {
12216
12398
  return c.json({ error: "Path is not a file" }, 400);
12217
12399
  }
12218
- const filename = basename6(absolute);
12400
+ const filename = basename7(absolute);
12219
12401
  const mimeType = detectMimeType(absolute);
12220
12402
  const nodeStream = createReadStream2(absolute);
12221
12403
  const webStream = Readable2.toWeb(nodeStream);
@@ -12242,7 +12424,7 @@ app18.get("/download", requireAdminSession, async (c) => {
12242
12424
  return c.json({ error: message }, 500);
12243
12425
  }
12244
12426
  });
12245
- app18.post("/upload", requireAdminSession, async (c) => {
12427
+ app19.post("/upload", requireAdminSession, async (c) => {
12246
12428
  const cacheKey = c.var.cacheKey;
12247
12429
  const accountId = getAccountIdForSession(cacheKey);
12248
12430
  if (!accountId) {
@@ -12272,15 +12454,15 @@ app18.post("/upload", requireAdminSession, async (c) => {
12272
12454
  error: `Unsupported file type: "${file.type}". Supported: ${[...SUPPORTED_MIME_TYPES].join(", ")}.`
12273
12455
  }, 422);
12274
12456
  }
12275
- const safeName = basename6(file.name).replace(/[\0/\\]/g, "_");
12457
+ const safeName = basename7(file.name).replace(/[\0/\\]/g, "_");
12276
12458
  const finalName = `${Date.now()}-${safeName}`;
12277
- const destDir = resolve21(DATA_ROOT, "accounts", accountId, "uploads");
12278
- const destPath = resolve21(destDir, finalName);
12459
+ const destDir = resolve22(DATA_ROOT, "accounts", accountId, "uploads");
12460
+ const destPath = resolve22(destDir, finalName);
12279
12461
  try {
12280
12462
  await mkdir3(destDir, { recursive: true });
12281
12463
  const dataRootReal = realpathSync4(DATA_ROOT);
12282
12464
  const destDirReal = realpathSync4(destDir);
12283
- if (destDirReal !== dataRootReal && !destDirReal.startsWith(dataRootReal + sep5)) {
12465
+ if (destDirReal !== dataRootReal && !destDirReal.startsWith(dataRootReal + sep6)) {
12284
12466
  console.error(`[data] path-traversal-blocked requested="accounts/${accountId}/uploads" resolved="${destDirReal}"`);
12285
12467
  return c.json({ error: "Upload destination escapes DATA_ROOT" }, 403);
12286
12468
  }
@@ -12303,7 +12485,7 @@ app18.post("/upload", requireAdminSession, async (c) => {
12303
12485
  mimeType: file.type
12304
12486
  });
12305
12487
  });
12306
- app18.delete("/", requireAdminSession, async (c) => {
12488
+ app19.delete("/", requireAdminSession, async (c) => {
12307
12489
  const cacheKey = c.var.cacheKey;
12308
12490
  const accountId = getAccountIdForSession(cacheKey);
12309
12491
  if (!accountId) {
@@ -12324,7 +12506,7 @@ app18.delete("/", requireAdminSession, async (c) => {
12324
12506
  console.error(`[data] account-scope-blocked endpoint="DELETE /api/admin/files" path="${relPath}" account=${accountId.slice(0, 8)}\u2026`);
12325
12507
  return c.json({ error: "Not found" }, 404);
12326
12508
  }
12327
- const base = basename6(absolute);
12509
+ const base = basename7(absolute);
12328
12510
  const protection = isProtectedFromDeletion(relPath);
12329
12511
  if (protection.protected) {
12330
12512
  console.error(`[data] file-delete blocked path="${relPath}" reason="protected" rule="${protection.rule}"`);
@@ -12340,7 +12522,7 @@ app18.delete("/", requireAdminSession, async (c) => {
12340
12522
  }
12341
12523
  const dot = base.lastIndexOf(".");
12342
12524
  const stem = dot === -1 ? base : base.slice(0, dot);
12343
- const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join20(dirname5(absolute), `${stem}.meta.json`) : null;
12525
+ const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join21(dirname6(absolute), `${stem}.meta.json`) : null;
12344
12526
  await unlink2(absolute);
12345
12527
  if (sidecarPath) {
12346
12528
  try {
@@ -12379,7 +12561,7 @@ app18.delete("/", requireAdminSession, async (c) => {
12379
12561
  return c.json({ error: message }, 500);
12380
12562
  }
12381
12563
  });
12382
- var files_default = app18;
12564
+ var files_default = app19;
12383
12565
 
12384
12566
  // ../lib/graph-search/src/index.ts
12385
12567
  var import_dist = __toESM(require_dist());
@@ -13144,8 +13326,8 @@ var DEFAULT_LIMIT = 20;
13144
13326
  var MAX_LIMIT = 2e3;
13145
13327
  var MESSAGE_FAMILY_LABELS = ["Message", "UserMessage", "AssistantMessage", "WhatsAppMessage"];
13146
13328
  var CONVERSATION_PARENT_LABELS = /* @__PURE__ */ new Set(["AdminConversation", "PublicConversation"]);
13147
- var app19 = new Hono();
13148
- app19.get("/", requireAdminSession, async (c) => {
13329
+ var app20 = new Hono();
13330
+ app20.get("/", requireAdminSession, async (c) => {
13149
13331
  const cacheKey = c.var.cacheKey;
13150
13332
  const q = (c.req.query("q") ?? "").trim();
13151
13333
  const rawLimit = c.req.query("limit");
@@ -13281,7 +13463,7 @@ app19.get("/", requireAdminSession, async (c) => {
13281
13463
  await session.close();
13282
13464
  }
13283
13465
  });
13284
- var graph_search_default = app19;
13466
+ var graph_search_default = app20;
13285
13467
 
13286
13468
  // server/routes/admin/graph-subgraph.ts
13287
13469
  import neo4j2 from "neo4j-driver";
@@ -13365,8 +13547,8 @@ var STRIPPED_PROPERTIES = /* @__PURE__ */ new Set([
13365
13547
  "otpCode",
13366
13548
  "cacheKey"
13367
13549
  ]);
13368
- var app20 = new Hono();
13369
- app20.get("/", requireAdminSession, async (c) => {
13550
+ var app21 = new Hono();
13551
+ app21.get("/", requireAdminSession, async (c) => {
13370
13552
  const cacheKey = c.var.cacheKey;
13371
13553
  const accountId = getAccountIdForSession(cacheKey);
13372
13554
  if (!accountId) {
@@ -13949,12 +14131,12 @@ function pruneNode(node, warnedClasses, conversationWarnings) {
13949
14131
  }
13950
14132
  return trashed ? { id: node.id, labels, properties, trashed: true } : { id: node.id, labels, properties };
13951
14133
  }
13952
- var graph_subgraph_default = app20;
14134
+ var graph_subgraph_default = app21;
13953
14135
 
13954
14136
  // server/routes/admin/graph-delete.ts
13955
14137
  var ALLOWED_BY = ["graph-page", "graph-drag-trash", "graph-side-panel-trash"];
13956
- var app21 = new Hono();
13957
- app21.post("/", requireAdminSession, async (c) => {
14138
+ var app22 = new Hono();
14139
+ app22.post("/", requireAdminSession, async (c) => {
13958
14140
  const cacheKey = c.var.cacheKey;
13959
14141
  const accountId = getAccountIdForSession(cacheKey);
13960
14142
  if (!accountId) {
@@ -14116,11 +14298,11 @@ app21.post("/", requireAdminSession, async (c) => {
14116
14298
  }
14117
14299
  }
14118
14300
  });
14119
- var graph_delete_default = app21;
14301
+ var graph_delete_default = app22;
14120
14302
 
14121
14303
  // server/routes/admin/graph-restore.ts
14122
- var app22 = new Hono();
14123
- app22.post("/", requireAdminSession, async (c) => {
14304
+ var app23 = new Hono();
14305
+ app23.post("/", requireAdminSession, async (c) => {
14124
14306
  const cacheKey = c.var.cacheKey;
14125
14307
  const accountId = getAccountIdForSession(cacheKey);
14126
14308
  if (!accountId) {
@@ -14184,11 +14366,11 @@ app22.post("/", requireAdminSession, async (c) => {
14184
14366
  }
14185
14367
  }
14186
14368
  });
14187
- var graph_restore_default = app22;
14369
+ var graph_restore_default = app23;
14188
14370
 
14189
14371
  // server/routes/admin/graph-labels-in-graph.ts
14190
- var app23 = new Hono();
14191
- app23.get("/", requireAdminSession, async (c) => {
14372
+ var app24 = new Hono();
14373
+ app24.get("/", requireAdminSession, async (c) => {
14192
14374
  const cacheKey = c.var.cacheKey;
14193
14375
  const accountId = getAccountIdForSession(cacheKey);
14194
14376
  if (!accountId) {
@@ -14254,11 +14436,11 @@ var LABELS_IN_GRAPH_CYPHER = `
14254
14436
  sum(halfEdges) AS relDegree
14255
14437
  RETURN label, nodeCount, relDegree
14256
14438
  `;
14257
- var graph_labels_in_graph_default = app23;
14439
+ var graph_labels_in_graph_default = app24;
14258
14440
 
14259
14441
  // server/routes/admin/graph-default-view.ts
14260
- var app24 = new Hono();
14261
- app24.get("/", requireAdminSession, async (c) => {
14442
+ var app25 = new Hono();
14443
+ app25.get("/", requireAdminSession, async (c) => {
14262
14444
  const cacheKey = c.var.cacheKey;
14263
14445
  const accountId = getAccountIdForSession(cacheKey);
14264
14446
  const userId = getUserIdForSession(cacheKey);
@@ -14296,7 +14478,7 @@ app24.get("/", requireAdminSession, async (c) => {
14296
14478
  }
14297
14479
  }
14298
14480
  });
14299
- app24.put("/", requireAdminSession, async (c) => {
14481
+ app25.put("/", requireAdminSession, async (c) => {
14300
14482
  const cacheKey = c.var.cacheKey;
14301
14483
  const accountId = getAccountIdForSession(cacheKey);
14302
14484
  const userId = getUserIdForSession(cacheKey);
@@ -14385,20 +14567,20 @@ var WRITE_CYPHER = `
14385
14567
  p.updatedAt = $updatedAt
14386
14568
  RETURN p.labels AS labels
14387
14569
  `;
14388
- var graph_default_view_default = app24;
14570
+ var graph_default_view_default = app25;
14389
14571
 
14390
14572
  // server/routes/admin/sidebar-artefacts.ts
14391
14573
  import { readdir as readdir4, stat as stat5 } from "fs/promises";
14392
- import { resolve as resolve22, relative as relative3, isAbsolute, sep as sep6, basename as basename7 } from "path";
14574
+ import { resolve as resolve23, relative as relative3, isAbsolute, sep as sep7, basename as basename8 } from "path";
14393
14575
  import { existsSync as existsSync21 } from "fs";
14394
14576
  var LIMIT = 50;
14395
14577
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
14396
14578
  function toDataRootRelPath(absPath) {
14397
- if (absPath !== DATA_ROOT && !absPath.startsWith(DATA_ROOT + sep6)) return null;
14579
+ if (absPath !== DATA_ROOT && !absPath.startsWith(DATA_ROOT + sep7)) return null;
14398
14580
  return relative3(DATA_ROOT, absPath);
14399
14581
  }
14400
- var app25 = new Hono();
14401
- app25.get("/", requireAdminSession, async (c) => {
14582
+ var app26 = new Hono();
14583
+ app26.get("/", requireAdminSession, async (c) => {
14402
14584
  const cacheKey = c.var.cacheKey;
14403
14585
  const accountId = getAccountIdForSession(cacheKey);
14404
14586
  if (!accountId) {
@@ -14409,7 +14591,7 @@ app25.get("/", requireAdminSession, async (c) => {
14409
14591
  if (accountFiles === null) {
14410
14592
  return c.json({ error: "Failed to load artefacts" }, 500);
14411
14593
  }
14412
- const accountDir = resolve22(ACCOUNTS_DIR, accountId);
14594
+ const accountDir = resolve23(ACCOUNTS_DIR, accountId);
14413
14595
  const agents = await fetchAgentTemplateRows(accountDir);
14414
14596
  const artefacts = [...accountFiles, ...agents].sort(
14415
14597
  (a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "")
@@ -14442,7 +14624,7 @@ async function fetchAccountFileArtefacts(accountId) {
14442
14624
  const modifiedAt = r.get("modifiedAt") ?? "";
14443
14625
  return {
14444
14626
  id: `account-file:${relativePath}`,
14445
- name: displayName ?? basename7(relativePath),
14627
+ name: displayName ?? basename8(relativePath),
14446
14628
  kind: "account-file",
14447
14629
  updatedAt: modifiedAt,
14448
14630
  mimeType,
@@ -14461,8 +14643,8 @@ async function fetchAccountFileArtefacts(accountId) {
14461
14643
  async function fetchAgentTemplateRows(accountDir) {
14462
14644
  const rows = [];
14463
14645
  for (const filename of ADMIN_AGENT_FILES) {
14464
- const overridePath = resolve22(accountDir, "agents", "admin", filename);
14465
- const bundledPath = resolve22(PLATFORM_ROOT, "templates", "agents", "admin", filename);
14646
+ const overridePath = resolve23(accountDir, "agents", "admin", filename);
14647
+ const bundledPath = resolve23(PLATFORM_ROOT, "templates", "agents", "admin", filename);
14466
14648
  const labelStem = filename.replace(/\.md$/, "");
14467
14649
  const row = await readAgentTemplateRow({
14468
14650
  id: `agent-template:admin:${filename}`,
@@ -14475,12 +14657,12 @@ async function fetchAgentTemplateRows(accountDir) {
14475
14657
  });
14476
14658
  if (row) rows.push(row);
14477
14659
  }
14478
- const overrideDir = resolve22(accountDir, "specialists", "agents");
14479
- const bundledDir = resolve22(PLATFORM_ROOT, "templates", "specialists", "agents");
14660
+ const overrideDir = resolve23(accountDir, "specialists", "agents");
14661
+ const bundledDir = resolve23(PLATFORM_ROOT, "templates", "specialists", "agents");
14480
14662
  const specialistNames = await unionSpecialistFilenames(overrideDir, bundledDir);
14481
14663
  for (const filename of specialistNames) {
14482
- const overridePath = resolve22(overrideDir, filename);
14483
- const bundledPath = resolve22(bundledDir, filename);
14664
+ const overridePath = resolve23(overrideDir, filename);
14665
+ const bundledPath = resolve23(bundledDir, filename);
14484
14666
  const row = await readAgentTemplateRow({
14485
14667
  id: `agent-template:specialist:${filename}`,
14486
14668
  displayName: filename.replace(/\.md$/, ""),
@@ -14562,11 +14744,11 @@ function isWithin(target, root) {
14562
14744
  const rel = relative3(root, target);
14563
14745
  return !rel.startsWith("..") && !isAbsolute(rel);
14564
14746
  }
14565
- var sidebar_artefacts_default = app25;
14747
+ var sidebar_artefacts_default = app26;
14566
14748
 
14567
14749
  // server/routes/admin/session-delete.ts
14568
- var app26 = new Hono();
14569
- app26.post("/", requireAdminSession, async (c) => {
14750
+ var app27 = new Hono();
14751
+ app27.post("/", requireAdminSession, async (c) => {
14570
14752
  let body;
14571
14753
  try {
14572
14754
  body = await c.req.json();
@@ -14604,11 +14786,11 @@ app26.post("/", requireAdminSession, async (c) => {
14604
14786
  console.error(`[session-delete] sessionId=${sessionId} delete-status=${del.status}`);
14605
14787
  return c.json({ error: `manager-status-${del.status}` }, 502);
14606
14788
  });
14607
- var session_delete_default = app26;
14789
+ var session_delete_default = app27;
14608
14790
 
14609
14791
  // server/routes/admin/session-stop.ts
14610
- var app27 = new Hono();
14611
- app27.post("/", requireAdminSession, async (c) => {
14792
+ var app28 = new Hono();
14793
+ app28.post("/", requireAdminSession, async (c) => {
14612
14794
  let body;
14613
14795
  try {
14614
14796
  body = await c.req.json();
@@ -14633,11 +14815,11 @@ app27.post("/", requireAdminSession, async (c) => {
14633
14815
  console.error(`[session-stop] sessionId=${sessionId} manager-status=${res.status}`);
14634
14816
  return c.json({ error: `manager-status-${res.status}` }, 502);
14635
14817
  });
14636
- var session_stop_default = app27;
14818
+ var session_stop_default = app28;
14637
14819
 
14638
14820
  // server/routes/admin/session-archive.ts
14639
- var app28 = new Hono();
14640
- app28.post("/", requireAdminSession, async (c) => {
14821
+ var app29 = new Hono();
14822
+ app29.post("/", requireAdminSession, async (c) => {
14641
14823
  let body;
14642
14824
  try {
14643
14825
  body = await c.req.json();
@@ -14685,7 +14867,7 @@ app28.post("/", requireAdminSession, async (c) => {
14685
14867
  console.error(`[session-archive] sessionId=${sessionId.slice(0, 8)} manager-status=${res.status}`);
14686
14868
  return c.json({ error: `manager-status-${res.status}` }, 502);
14687
14869
  });
14688
- var session_archive_default = app28;
14870
+ var session_archive_default = app29;
14689
14871
 
14690
14872
  // server/routes/admin/session-rc-spawn.ts
14691
14873
  import { randomUUID as randomUUID10 } from "crypto";
@@ -14719,8 +14901,8 @@ function shapeWebchatResponse(sessionId, manager) {
14719
14901
  const outcome = typeof manager?.outcome === "string" ? manager.outcome : "bound";
14720
14902
  return { sessionId, outcome, target: `/chat?session=${sessionId}` };
14721
14903
  }
14722
- var app29 = new Hono();
14723
- app29.post("/", requireAdminSession, async (c) => {
14904
+ var app30 = new Hono();
14905
+ app30.post("/", requireAdminSession, async (c) => {
14724
14906
  let body;
14725
14907
  try {
14726
14908
  body = await c.req.json();
@@ -14773,7 +14955,7 @@ app29.post("/", requireAdminSession, async (c) => {
14773
14955
  }
14774
14956
  return c.json(parsed ?? {});
14775
14957
  });
14776
- var session_rc_spawn_default = app29;
14958
+ var session_rc_spawn_default = app30;
14777
14959
 
14778
14960
  // server/routes/admin/session-reseat.ts
14779
14961
  import { randomUUID as randomUUID11 } from "crypto";
@@ -14814,8 +14996,9 @@ function resolveReseatPlan(body, mintId = randomUUID11, adminUserId) {
14814
14996
  if (adminUserId) payload.adminUserId = adminUserId;
14815
14997
  return { sessionId, payload };
14816
14998
  }
14817
- var app30 = new Hono();
14818
- app30.post("/", requireAdminSession, async (c) => {
14999
+ var app31 = new Hono();
15000
+ var reseatsInFlight = /* @__PURE__ */ new Set();
15001
+ app31.post("/", requireAdminSession, async (c) => {
14819
15002
  let body;
14820
15003
  try {
14821
15004
  body = await c.req.json();
@@ -14826,57 +15009,65 @@ app30.post("/", requireAdminSession, async (c) => {
14826
15009
  const model = typeof body.model === "string" && isSelectableModel(body.model) ? body.model : null;
14827
15010
  if (fromSessionId === null) return c.json({ error: "fromSessionId must be a valid session id" }, 400);
14828
15011
  if (model === null) return c.json({ error: "model must be a selectable model" }, 400);
14829
- const cacheKey = c.get("cacheKey");
14830
- const adminUserId = cacheKey ? getUserIdForSession(cacheKey) : void 0;
14831
- const plan = resolveReseatPlan({ fromSessionId, model }, randomUUID11, adminUserId);
14832
- const reseatReqId = randomUUID11();
14833
- console.log(`[chat-reseat] op=request reseatReqId=${reseatReqId} from=${fromSessionId} to-model=${model} new=${plan.sessionId}`);
14834
- let res;
14835
- try {
14836
- res = await fetch(`${managerBase("session-reseat:wrapper")}/rc-spawn`, {
14837
- method: "POST",
14838
- headers: { "content-type": "application/json" },
14839
- body: JSON.stringify(plan.payload)
14840
- });
14841
- } catch (err) {
14842
- const msg = err instanceof Error ? err.message : String(err);
14843
- console.error(`[session-reseat] manager-unreachable err=${msg}`);
14844
- console.log(`[chat-reseat] op=exit reseatReqId=${reseatReqId} outcome=reseat-failed`);
14845
- return c.json({ error: `session manager unreachable: ${msg}` }, 502);
14846
- }
14847
- const text = await res.text();
14848
- let parsed = null;
14849
- try {
14850
- parsed = JSON.parse(text);
14851
- } catch {
14852
- }
14853
- if (!res.ok) {
14854
- console.error(`[session-reseat] manager-error status=${res.status} body=${text.slice(0, 200)}`);
14855
- console.log(`[chat-reseat] op=exit reseatReqId=${reseatReqId} outcome=reseat-failed`);
14856
- return c.json(parsed ?? { error: text }, res.status);
15012
+ if (reseatsInFlight.has(fromSessionId)) {
15013
+ return c.json({ error: "re-seat already in progress for this session" }, 409);
14857
15014
  }
15015
+ reseatsInFlight.add(fromSessionId);
14858
15016
  try {
14859
- const account = resolveAccount();
14860
- if (account) {
14861
- const accountId = resolvePlatformAccountId();
14862
- const canonicalId = adminSessionIdFor(accountId, WEBCHAT_ADMIN_KEY);
14863
- const currentOverride = readCanonicalOverrideId(account.accountDir);
14864
- if (fromSessionId === canonicalId || fromSessionId === currentOverride) {
14865
- writeCanonicalOverrideId(account.accountDir, plan.sessionId);
14866
- console.log(`[chat-reseat] op=canonical-forward reseatReqId=${reseatReqId} from=${fromSessionId} to=${plan.sessionId}`);
15017
+ const cacheKey = c.get("cacheKey");
15018
+ const adminUserId = cacheKey ? getUserIdForSession(cacheKey) : void 0;
15019
+ const plan = resolveReseatPlan({ fromSessionId, model }, randomUUID11, adminUserId);
15020
+ const reseatReqId = randomUUID11();
15021
+ console.log(`[chat-reseat] op=request reseatReqId=${reseatReqId} from=${fromSessionId} to-model=${model} new=${plan.sessionId}`);
15022
+ let res;
15023
+ try {
15024
+ res = await fetch(`${managerBase("session-reseat:wrapper")}/rc-spawn`, {
15025
+ method: "POST",
15026
+ headers: { "content-type": "application/json" },
15027
+ body: JSON.stringify(plan.payload)
15028
+ });
15029
+ } catch (err) {
15030
+ const msg = err instanceof Error ? err.message : String(err);
15031
+ console.error(`[session-reseat] manager-unreachable err=${msg}`);
15032
+ console.log(`[chat-reseat] op=exit reseatReqId=${reseatReqId} outcome=reseat-failed`);
15033
+ return c.json({ error: `session manager unreachable: ${msg}` }, 502);
15034
+ }
15035
+ const text = await res.text();
15036
+ let parsed = null;
15037
+ try {
15038
+ parsed = JSON.parse(text);
15039
+ } catch {
15040
+ }
15041
+ if (!res.ok) {
15042
+ console.error(`[session-reseat] manager-error status=${res.status} body=${text.slice(0, 200)}`);
15043
+ console.log(`[chat-reseat] op=exit reseatReqId=${reseatReqId} outcome=reseat-failed`);
15044
+ return c.json(parsed ?? { error: text }, res.status);
15045
+ }
15046
+ try {
15047
+ const account = resolveAccount();
15048
+ if (account) {
15049
+ const accountId = resolvePlatformAccountId();
15050
+ const canonicalId = adminSessionIdFor(accountId, WEBCHAT_ADMIN_KEY);
15051
+ const currentOverride = readCanonicalOverrideId(account.accountDir);
15052
+ if (fromSessionId === canonicalId || fromSessionId === currentOverride) {
15053
+ writeCanonicalOverrideId(account.accountDir, plan.sessionId);
15054
+ console.log(`[chat-reseat] op=canonical-forward reseatReqId=${reseatReqId} from=${fromSessionId} to=${plan.sessionId}`);
15055
+ }
14867
15056
  }
15057
+ } catch (err) {
15058
+ console.error(`[session-reseat] canonical-forward-failed err=${err instanceof Error ? err.message : String(err)}`);
14868
15059
  }
14869
- } catch (err) {
14870
- console.error(`[session-reseat] canonical-forward-failed err=${err instanceof Error ? err.message : String(err)}`);
14871
- }
14872
- const target = `/chat?session=${plan.sessionId}`;
14873
- console.log(`[chat-reseat] op=acquired reseatReqId=${reseatReqId} pid=${parsed?.spawnedPid ?? "none"} new=${plan.sessionId}`);
14874
- console.log(`[chat-reseat] op=navigate reseatReqId=${reseatReqId} target=${target}`);
14875
- console.log(`[chat-reseat] op=exit reseatReqId=${reseatReqId} outcome=bound`);
14876
- const outcome = typeof parsed?.outcome === "string" ? parsed.outcome : "bound";
14877
- return c.json({ sessionId: plan.sessionId, outcome, target });
15060
+ const target = `/chat?session=${plan.sessionId}`;
15061
+ console.log(`[chat-reseat] op=acquired reseatReqId=${reseatReqId} pid=${parsed?.spawnedPid ?? "none"} new=${plan.sessionId}`);
15062
+ console.log(`[chat-reseat] op=navigate reseatReqId=${reseatReqId} target=${target}`);
15063
+ console.log(`[chat-reseat] op=exit reseatReqId=${reseatReqId} outcome=bound`);
15064
+ const outcome = typeof parsed?.outcome === "string" ? parsed.outcome : "bound";
15065
+ return c.json({ sessionId: plan.sessionId, outcome, target });
15066
+ } finally {
15067
+ reseatsInFlight.delete(fromSessionId);
15068
+ }
14878
15069
  });
14879
- var session_reseat_default = app30;
15070
+ var session_reseat_default = app31;
14880
15071
 
14881
15072
  // server/routes/admin/system-stats.ts
14882
15073
  import { readFile as readFile5 } from "fs/promises";
@@ -14973,8 +15164,8 @@ async function sample() {
14973
15164
  if (process.platform === "linux") return sampleLinux();
14974
15165
  return sampleOsFallback();
14975
15166
  }
14976
- var app31 = new Hono();
14977
- app31.get("/", async (c) => {
15167
+ var app32 = new Hono();
15168
+ app32.get("/", async (c) => {
14978
15169
  const started = Date.now();
14979
15170
  if (!inflight) {
14980
15171
  inflight = sample().finally(() => {
@@ -14997,14 +15188,14 @@ app31.get("/", async (c) => {
14997
15188
  return c.json({ degraded: true, reason, sampledAtMs: Date.now() });
14998
15189
  }
14999
15190
  });
15000
- var system_stats_default = app31;
15191
+ var system_stats_default = app32;
15001
15192
 
15002
15193
  // server/routes/admin/health.ts
15003
15194
  import { existsSync as existsSync22, readFileSync as readFileSync22 } from "fs";
15004
- import { resolve as resolve23, join as join21 } from "path";
15005
- var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve23(process.cwd(), "..");
15195
+ import { resolve as resolve24, join as join22 } from "path";
15196
+ var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve24(process.cwd(), "..");
15006
15197
  var brandHostname = "maxy";
15007
- var brandJsonPath = join21(PLATFORM_ROOT6, "config", "brand.json");
15198
+ var brandJsonPath = join22(PLATFORM_ROOT6, "config", "brand.json");
15008
15199
  if (existsSync22(brandJsonPath)) {
15009
15200
  try {
15010
15201
  const brand = JSON.parse(readFileSync22(brandJsonPath, "utf-8"));
@@ -15012,7 +15203,7 @@ if (existsSync22(brandJsonPath)) {
15012
15203
  } catch {
15013
15204
  }
15014
15205
  }
15015
- var VERSION_FILE = resolve23(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
15206
+ var VERSION_FILE = resolve24(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
15016
15207
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
15017
15208
  var PROBE_TIMEOUT_MS = 1e3;
15018
15209
  function readVersion() {
@@ -15042,8 +15233,8 @@ async function probeConversationDb() {
15042
15233
  });
15043
15234
  }
15044
15235
  }
15045
- var app32 = new Hono();
15046
- app32.get("/", async (c) => {
15236
+ var app33 = new Hono();
15237
+ app33.get("/", async (c) => {
15047
15238
  const version = readVersion();
15048
15239
  const probe = await probeConversationDb();
15049
15240
  const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
@@ -15065,11 +15256,11 @@ app32.get("/", async (c) => {
15065
15256
  uptimeMs
15066
15257
  });
15067
15258
  });
15068
- var health_default2 = app32;
15259
+ var health_default2 = app33;
15069
15260
 
15070
15261
  // server/routes/admin/linkedin-ingest.ts
15071
15262
  import { randomUUID as randomUUID12 } from "crypto";
15072
- var TAG25 = "[linkedin-ingest-route]";
15263
+ var TAG26 = "[linkedin-ingest-route]";
15073
15264
  var UUID2 = /^[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}$/;
15074
15265
  var ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
15075
15266
  var LINKEDIN_URL = /^https:\/\/www\.linkedin\.com\//;
@@ -15167,35 +15358,35 @@ function buildInitialMessage(env) {
15167
15358
  }
15168
15359
  return header;
15169
15360
  }
15170
- var app33 = new Hono();
15171
- app33.post("/", requireAdminSession, async (c) => {
15361
+ var app34 = new Hono();
15362
+ app34.post("/", requireAdminSession, async (c) => {
15172
15363
  let body;
15173
15364
  try {
15174
15365
  body = await c.req.json();
15175
15366
  } catch {
15176
- console.error(TAG25 + " rejected status=400 reason=schema:body-not-json");
15367
+ console.error(TAG26 + " rejected status=400 reason=schema:body-not-json");
15177
15368
  return c.json({ ok: false, error: "schema", reason: "body-not-json" }, 400);
15178
15369
  }
15179
15370
  const v = validate(body);
15180
15371
  if (!v.ok) {
15181
- console.error(TAG25 + " rejected status=" + v.status + " reason=" + v.reason + " missing=" + v.missing.join(","));
15372
+ console.error(TAG26 + " rejected status=" + v.status + " reason=" + v.reason + " missing=" + v.missing.join(","));
15182
15373
  return c.json({ ok: false, error: v.error, reason: v.reason, missing: v.missing }, v.status);
15183
15374
  }
15184
15375
  const envelope = v.envelope;
15185
15376
  const cacheKey = c.var.cacheKey ?? "";
15186
15377
  const senderId = getAccountIdForSession(cacheKey) ?? "";
15187
15378
  if (!senderId) {
15188
- console.error(TAG25 + " rejected status=500 reason=admin-account-not-resolved");
15379
+ console.error(TAG26 + " rejected status=500 reason=admin-account-not-resolved");
15189
15380
  return c.json({ ok: false, error: "admin-account-not-resolved" }, 500);
15190
15381
  }
15191
15382
  const payloadBytes = JSON.stringify(envelope).length;
15192
15383
  console.log(
15193
- TAG25 + " received kind=" + envelope.kind + " account=" + senderId.slice(0, 8) + " pageUrl=" + envelope.pageUrl + " dispatchId=" + envelope.dispatchId + " payloadBytes=" + payloadBytes
15384
+ TAG26 + " received kind=" + envelope.kind + " account=" + senderId.slice(0, 8) + " pageUrl=" + envelope.pageUrl + " dispatchId=" + envelope.dispatchId + " payloadBytes=" + payloadBytes
15194
15385
  );
15195
15386
  const initialMessage = buildInitialMessage(envelope);
15196
15387
  const spawnStart = Date.now();
15197
15388
  const sessionId = randomUUID12();
15198
- console.log(TAG25 + " route target=rc-spawn dispatchId=" + envelope.dispatchId + " sessionId=" + sessionId.slice(0, 8));
15389
+ console.log(TAG26 + " route target=rc-spawn dispatchId=" + envelope.dispatchId + " sessionId=" + sessionId.slice(0, 8));
15199
15390
  const spawned = await managerRcSpawn({
15200
15391
  sessionId,
15201
15392
  initialMessage,
@@ -15204,20 +15395,20 @@ app33.post("/", requireAdminSession, async (c) => {
15204
15395
  });
15205
15396
  if ("error" in spawned) {
15206
15397
  console.error(
15207
- TAG25 + " dispatch-failed dispatchId=" + envelope.dispatchId + " status=" + spawned.status + " ms=" + (Date.now() - spawnStart) + " message=" + spawned.error
15398
+ TAG26 + " dispatch-failed dispatchId=" + envelope.dispatchId + " status=" + spawned.status + " ms=" + (Date.now() - spawnStart) + " message=" + spawned.error
15208
15399
  );
15209
15400
  return c.json({ ok: false, error: "dispatch-failed", upstreamStatus: spawned.status, detail: spawned.error }, 502);
15210
15401
  }
15211
15402
  console.log(
15212
- TAG25 + " dispatched dispatchId=" + envelope.dispatchId + " taskId=" + spawned.sessionId + " ms=" + (Date.now() - spawnStart)
15403
+ TAG26 + " dispatched dispatchId=" + envelope.dispatchId + " taskId=" + spawned.sessionId + " ms=" + (Date.now() - spawnStart)
15213
15404
  );
15214
15405
  return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: spawned.sessionId }, 202);
15215
15406
  });
15216
- var linkedin_ingest_default = app33;
15407
+ var linkedin_ingest_default = app34;
15217
15408
 
15218
15409
  // server/routes/admin/post-turn-context.ts
15219
15410
  import neo4j3 from "neo4j-driver";
15220
- var TAG26 = "[post-turn-context]";
15411
+ var TAG27 = "[post-turn-context]";
15221
15412
  var STRIPPED_PROPERTIES2 = /* @__PURE__ */ new Set([
15222
15413
  "embedding",
15223
15414
  "passwordHash",
@@ -15255,11 +15446,11 @@ function pruneProperties(raw) {
15255
15446
  }
15256
15447
  return out;
15257
15448
  }
15258
- var app34 = new Hono();
15259
- app34.get("/", async (c) => {
15449
+ var app35 = new Hono();
15450
+ app35.get("/", async (c) => {
15260
15451
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
15261
15452
  if (!isLoopbackAddr2(remoteAddr)) {
15262
- console.error(`${TAG26} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15453
+ console.error(`${TAG27} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15263
15454
  return c.json({ error: "post-turn-context-loopback-only" }, 403);
15264
15455
  }
15265
15456
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -15268,7 +15459,7 @@ app34.get("/", async (c) => {
15268
15459
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
15269
15460
  const offender = tokens.find((t) => !isLoopbackAddr2(t));
15270
15461
  if (offender !== void 0) {
15271
- console.error(`${TAG26} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15462
+ console.error(`${TAG27} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15272
15463
  return c.json({ error: "post-turn-context-loopback-only" }, 403);
15273
15464
  }
15274
15465
  }
@@ -15300,7 +15491,7 @@ app34.get("/", async (c) => {
15300
15491
  writes.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
15301
15492
  const total = Date.now() - started;
15302
15493
  console.log(
15303
- `${TAG26} sessionId=${sessionId} accountId=${accountId} writes=${writes.length} ms=${total}`
15494
+ `${TAG27} sessionId=${sessionId} accountId=${accountId} writes=${writes.length} ms=${total}`
15304
15495
  );
15305
15496
  return c.json({
15306
15497
  writes: writes.map(({ elementId, labels, properties }) => ({ elementId, labels, properties }))
@@ -15309,18 +15500,18 @@ app34.get("/", async (c) => {
15309
15500
  const elapsed = Date.now() - started;
15310
15501
  const message = err instanceof Error ? err.message : String(err);
15311
15502
  console.error(
15312
- `${TAG26} neo4j-unreachable sessionId=${sessionId} ms=${elapsed} err="${message}"`
15503
+ `${TAG27} neo4j-unreachable sessionId=${sessionId} ms=${elapsed} err="${message}"`
15313
15504
  );
15314
15505
  return c.json({ error: `post-turn-context unavailable: ${message}` }, 503);
15315
15506
  } finally {
15316
15507
  await session.close();
15317
15508
  }
15318
15509
  });
15319
- var post_turn_context_default = app34;
15510
+ var post_turn_context_default = app35;
15320
15511
 
15321
15512
  // server/routes/admin/public-session-context.ts
15322
15513
  import neo4j4 from "neo4j-driver";
15323
- var TAG27 = "[public-session-context]";
15514
+ var TAG28 = "[public-session-context]";
15324
15515
  var STRIPPED_PROPERTIES3 = /* @__PURE__ */ new Set([
15325
15516
  "embedding",
15326
15517
  "passwordHash",
@@ -15358,11 +15549,11 @@ function pruneProperties2(raw) {
15358
15549
  }
15359
15550
  return out;
15360
15551
  }
15361
- var app35 = new Hono();
15362
- app35.get("/", async (c) => {
15552
+ var app36 = new Hono();
15553
+ app36.get("/", async (c) => {
15363
15554
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
15364
15555
  if (!isLoopbackAddr3(remoteAddr)) {
15365
- console.error(`${TAG27} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15556
+ console.error(`${TAG28} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15366
15557
  return c.json({ error: "public-session-context-loopback-only" }, 403);
15367
15558
  }
15368
15559
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -15371,7 +15562,7 @@ app35.get("/", async (c) => {
15371
15562
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
15372
15563
  const offender = tokens.find((t) => !isLoopbackAddr3(t));
15373
15564
  if (offender !== void 0) {
15374
- console.error(`${TAG27} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15565
+ console.error(`${TAG28} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15375
15566
  return c.json({ error: "public-session-context-loopback-only" }, 403);
15376
15567
  }
15377
15568
  }
@@ -15402,7 +15593,7 @@ app35.get("/", async (c) => {
15402
15593
  writes.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
15403
15594
  const total = Date.now() - started;
15404
15595
  console.log(
15405
- `${TAG27} sliceToken=${sliceToken.slice(0, 8)} writes=${writes.length} ms=${total}`
15596
+ `${TAG28} sliceToken=${sliceToken.slice(0, 8)} writes=${writes.length} ms=${total}`
15406
15597
  );
15407
15598
  return c.json({
15408
15599
  writes: writes.map(({ elementId, labels, properties }) => ({ elementId, labels, properties }))
@@ -15411,25 +15602,25 @@ app35.get("/", async (c) => {
15411
15602
  const elapsed = Date.now() - started;
15412
15603
  const message = err instanceof Error ? err.message : String(err);
15413
15604
  console.error(
15414
- `${TAG27} neo4j-unreachable sliceToken=${sliceToken.slice(0, 8)} ms=${elapsed} err="${message}"`
15605
+ `${TAG28} neo4j-unreachable sliceToken=${sliceToken.slice(0, 8)} ms=${elapsed} err="${message}"`
15415
15606
  );
15416
15607
  return c.json({ error: `public-session-context unavailable: ${message}` }, 503);
15417
15608
  } finally {
15418
15609
  await session.close();
15419
15610
  }
15420
15611
  });
15421
- var public_session_context_default = app35;
15612
+ var public_session_context_default = app36;
15422
15613
 
15423
15614
  // server/routes/admin/public-session-exit.ts
15424
- var TAG28 = "[public-session-exit-route]";
15615
+ var TAG29 = "[public-session-exit-route]";
15425
15616
  function isLoopbackAddr4(addr) {
15426
15617
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
15427
15618
  }
15428
- var app36 = new Hono();
15429
- app36.post("/", async (c) => {
15619
+ var app37 = new Hono();
15620
+ app37.post("/", async (c) => {
15430
15621
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
15431
15622
  if (!isLoopbackAddr4(remoteAddr)) {
15432
- console.error(`${TAG28} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15623
+ console.error(`${TAG29} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15433
15624
  return c.json({ error: "public-session-exit-loopback-only" }, 403);
15434
15625
  }
15435
15626
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -15438,7 +15629,7 @@ app36.post("/", async (c) => {
15438
15629
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
15439
15630
  const offender = tokens.find((t) => !isLoopbackAddr4(t));
15440
15631
  if (offender !== void 0) {
15441
- console.error(`${TAG28} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15632
+ console.error(`${TAG29} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15442
15633
  return c.json({ error: "public-session-exit-loopback-only" }, 403);
15443
15634
  }
15444
15635
  }
@@ -15453,18 +15644,18 @@ app36.post("/", async (c) => {
15453
15644
  handlePublicSessionExit(sessionId);
15454
15645
  return c.json({ ok: true });
15455
15646
  });
15456
- var public_session_exit_default = app36;
15647
+ var public_session_exit_default = app37;
15457
15648
 
15458
15649
  // server/routes/admin/access-session-evict.ts
15459
- var TAG29 = "[access-session-evict]";
15650
+ var TAG30 = "[access-session-evict]";
15460
15651
  function isLoopbackAddr5(addr) {
15461
15652
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
15462
15653
  }
15463
- var app37 = new Hono();
15464
- app37.post("/", async (c) => {
15654
+ var app38 = new Hono();
15655
+ app38.post("/", async (c) => {
15465
15656
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
15466
15657
  if (!isLoopbackAddr5(remoteAddr)) {
15467
- console.error(`${TAG29} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15658
+ console.error(`${TAG30} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15468
15659
  return c.json({ error: "access-session-evict-loopback-only" }, 403);
15469
15660
  }
15470
15661
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -15473,7 +15664,7 @@ app37.post("/", async (c) => {
15473
15664
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
15474
15665
  const offender = tokens.find((t) => !isLoopbackAddr5(t));
15475
15666
  if (offender !== void 0) {
15476
- console.error(`${TAG29} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15667
+ console.error(`${TAG30} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15477
15668
  return c.json({ error: "access-session-evict-loopback-only" }, 403);
15478
15669
  }
15479
15670
  }
@@ -15486,22 +15677,22 @@ app37.post("/", async (c) => {
15486
15677
  const grantId = typeof body.grantId === "string" ? body.grantId.trim() : "";
15487
15678
  if (!grantId) return c.json({ error: "grantId required" }, 400);
15488
15679
  const dropped = evictAccessSessionsByGrant(grantId);
15489
- console.log(`${TAG29} grantId=${grantId} dropped=${dropped}`);
15680
+ console.log(`${TAG30} grantId=${grantId} dropped=${dropped}`);
15490
15681
  return c.json({ ok: true, dropped });
15491
15682
  });
15492
- var access_session_evict_default = app37;
15683
+ var access_session_evict_default = app38;
15493
15684
 
15494
15685
  // server/routes/admin/enrol-person.ts
15495
- var TAG30 = "[enrol]";
15686
+ var TAG31 = "[enrol]";
15496
15687
  function isLoopbackAddr6(addr) {
15497
15688
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
15498
15689
  }
15499
15690
  var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
15500
- var app38 = new Hono();
15501
- app38.post("/", async (c) => {
15691
+ var app39 = new Hono();
15692
+ app39.post("/", async (c) => {
15502
15693
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
15503
15694
  if (!isLoopbackAddr6(remoteAddr)) {
15504
- console.error(`${TAG30} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15695
+ console.error(`${TAG31} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15505
15696
  return c.json({ error: "enrol-person-loopback-only" }, 403);
15506
15697
  }
15507
15698
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -15510,7 +15701,7 @@ app38.post("/", async (c) => {
15510
15701
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
15511
15702
  const offender = tokens.find((t) => !isLoopbackAddr6(t));
15512
15703
  if (offender !== void 0) {
15513
- console.error(`${TAG30} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15704
+ console.error(`${TAG31} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15514
15705
  return c.json({ error: "enrol-person-loopback-only" }, 403);
15515
15706
  }
15516
15707
  }
@@ -15535,7 +15726,7 @@ app38.post("/", async (c) => {
15535
15726
  }
15536
15727
  const accountId = process.env.ACCOUNT_ID ?? "";
15537
15728
  if (!accountId) {
15538
- console.error(`${TAG30} op=person result=no-account-id`);
15729
+ console.error(`${TAG31} op=person result=no-account-id`);
15539
15730
  return c.json({ error: "no-account-id" }, 500);
15540
15731
  }
15541
15732
  let personId;
@@ -15543,7 +15734,7 @@ app38.post("/", async (c) => {
15543
15734
  personId = await enrolPerson({ accountId, phone, email, agentSlug });
15544
15735
  } catch (err) {
15545
15736
  console.error(
15546
- `${TAG30} op=person result=write-failed agentSlug=${agentSlug} contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
15737
+ `${TAG31} op=person result=write-failed agentSlug=${agentSlug} contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
15547
15738
  );
15548
15739
  return c.json({ error: "enrol-failed" }, 500);
15549
15740
  }
@@ -15553,19 +15744,19 @@ app38.post("/", async (c) => {
15553
15744
  if (g) grant = { grantId: g.grantId, status: g.status, contactValue: g.contactValue };
15554
15745
  } catch (err) {
15555
15746
  console.error(
15556
- `${TAG30} op=person result=grant-lookup-failed contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
15747
+ `${TAG31} op=person result=grant-lookup-failed contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
15557
15748
  );
15558
15749
  }
15559
15750
  console.log(
15560
- `${TAG30} op=person personId=${personId} account=${accountId} agentSlug=${agentSlug} contact=${maskContact(email)}`
15751
+ `${TAG31} op=person personId=${personId} account=${accountId} agentSlug=${agentSlug} contact=${maskContact(email)}`
15561
15752
  );
15562
15753
  return c.json({ personId, grant }, 200);
15563
15754
  });
15564
- var enrol_person_default = app38;
15755
+ var enrol_person_default = app39;
15565
15756
 
15566
15757
  // server/routes/admin/browser.ts
15567
- var app39 = new Hono();
15568
- app39.post("/launch", requireAdminSession, async (c) => {
15758
+ var app40 = new Hono();
15759
+ app40.post("/launch", requireAdminSession, async (c) => {
15569
15760
  try {
15570
15761
  const transport = resolveBrowserTransport(c.req.raw, c.env?.incoming?.socket?.remoteAddress);
15571
15762
  console.error(`[admin/browser/launch] op=request transport=${transport}`);
@@ -15593,50 +15784,50 @@ app39.post("/launch", requireAdminSession, async (c) => {
15593
15784
  );
15594
15785
  }
15595
15786
  });
15596
- var browser_default = app39;
15787
+ var browser_default = app40;
15597
15788
 
15598
15789
  // server/routes/admin/index.ts
15599
- var app40 = new Hono();
15600
- app40.route("/session", session_default);
15601
- app40.route("/logs", logs_default);
15602
- app40.route("/claude-info", claude_info_default);
15603
- app40.route("/attachment", attachment_default);
15604
- app40.route("/agents", agents_default);
15605
- app40.route("/sessions", sessions_default);
15606
- app40.route("/claude-sessions", claude_sessions_default);
15607
- app40.route("/log-ingest", log_ingest_default);
15608
- app40.route("/events", events_default);
15609
- app40.route("/files", files_default);
15610
- app40.route("/graph-search", graph_search_default);
15611
- app40.route("/graph-subgraph", graph_subgraph_default);
15612
- app40.route("/graph-delete", graph_delete_default);
15613
- app40.route("/graph-restore", graph_restore_default);
15614
- app40.route("/graph-labels-in-graph", graph_labels_in_graph_default);
15615
- app40.route("/graph-default-view", graph_default_view_default);
15616
- app40.route("/sidebar-artefacts", sidebar_artefacts_default);
15617
- app40.route("/sidebar-sessions", sidebar_sessions_default);
15618
- app40.route("/session-delete", session_delete_default);
15619
- app40.route("/session-stop", session_stop_default);
15620
- app40.route("/session-archive", session_archive_default);
15621
- app40.route("/browser", browser_default);
15622
- app40.route("/session-rc-spawn", session_rc_spawn_default);
15623
- app40.route("/session-reseat", session_reseat_default);
15624
- app40.route("/system-stats", system_stats_default);
15625
- app40.route("/health-brand", health_default2);
15626
- app40.route("/linkedin-ingest", linkedin_ingest_default);
15627
- app40.route("/post-turn-context", post_turn_context_default);
15628
- app40.route("/public-session-context", public_session_context_default);
15629
- app40.route("/public-session-exit", public_session_exit_default);
15630
- app40.route("/access-session-evict", access_session_evict_default);
15631
- app40.route("/enrol-person", enrol_person_default);
15632
- var admin_default = app40;
15790
+ var app41 = new Hono();
15791
+ app41.route("/session", session_default);
15792
+ app41.route("/logs", logs_default);
15793
+ app41.route("/claude-info", claude_info_default);
15794
+ app41.route("/attachment", attachment_default);
15795
+ app41.route("/agents", agents_default);
15796
+ app41.route("/sessions", sessions_default);
15797
+ app41.route("/claude-sessions", claude_sessions_default);
15798
+ app41.route("/log-ingest", log_ingest_default);
15799
+ app41.route("/events", events_default);
15800
+ app41.route("/files", files_default);
15801
+ app41.route("/graph-search", graph_search_default);
15802
+ app41.route("/graph-subgraph", graph_subgraph_default);
15803
+ app41.route("/graph-delete", graph_delete_default);
15804
+ app41.route("/graph-restore", graph_restore_default);
15805
+ app41.route("/graph-labels-in-graph", graph_labels_in_graph_default);
15806
+ app41.route("/graph-default-view", graph_default_view_default);
15807
+ app41.route("/sidebar-artefacts", sidebar_artefacts_default);
15808
+ app41.route("/sidebar-sessions", sidebar_sessions_default);
15809
+ app41.route("/session-delete", session_delete_default);
15810
+ app41.route("/session-stop", session_stop_default);
15811
+ app41.route("/session-archive", session_archive_default);
15812
+ app41.route("/browser", browser_default);
15813
+ app41.route("/session-rc-spawn", session_rc_spawn_default);
15814
+ app41.route("/session-reseat", session_reseat_default);
15815
+ app41.route("/system-stats", system_stats_default);
15816
+ app41.route("/health-brand", health_default2);
15817
+ app41.route("/linkedin-ingest", linkedin_ingest_default);
15818
+ app41.route("/post-turn-context", post_turn_context_default);
15819
+ app41.route("/public-session-context", public_session_context_default);
15820
+ app41.route("/public-session-exit", public_session_exit_default);
15821
+ app41.route("/access-session-evict", access_session_evict_default);
15822
+ app41.route("/enrol-person", enrol_person_default);
15823
+ var admin_default = app41;
15633
15824
 
15634
15825
  // server/routes/access/verify-token.ts
15635
- var TAG31 = "[access-verify]";
15826
+ var TAG32 = "[access-verify]";
15636
15827
  var MINT_TAG = "[access-session-mint]";
15637
15828
  var COOKIE_NAME = "__access_session";
15638
- var app41 = new Hono();
15639
- app41.post("/", async (c) => {
15829
+ var app42 = new Hono();
15830
+ app42.post("/", async (c) => {
15640
15831
  const ip = c.var.clientIp || "unknown";
15641
15832
  let body;
15642
15833
  try {
@@ -15651,39 +15842,39 @@ app41.post("/", async (c) => {
15651
15842
  }
15652
15843
  const rateMsg = checkAccessRateLimit(ip, agentSlug);
15653
15844
  if (rateMsg) {
15654
- console.error(`${TAG31} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
15845
+ console.error(`${TAG32} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
15655
15846
  return c.json({ error: rateMsg }, 429);
15656
15847
  }
15657
15848
  const grant = await findGrantByMagicToken(token);
15658
15849
  if (!grant) {
15659
15850
  recordAccessFailedAttempt(ip, agentSlug);
15660
- console.error(`${TAG31} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
15851
+ console.error(`${TAG32} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
15661
15852
  return c.json({ error: "invalid-or-expired-link" }, 401);
15662
15853
  }
15663
15854
  if (grant.agentSlug !== agentSlug) {
15664
15855
  recordAccessFailedAttempt(ip, agentSlug);
15665
15856
  console.error(
15666
- `${TAG31} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
15857
+ `${TAG32} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
15667
15858
  );
15668
15859
  return c.json({ error: "invalid-or-expired-link" }, 401);
15669
15860
  }
15670
15861
  if (grant.status === "expired" || grant.status === "revoked") {
15671
15862
  recordAccessFailedAttempt(ip, agentSlug);
15672
15863
  console.error(
15673
- `${TAG31} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
15864
+ `${TAG32} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
15674
15865
  );
15675
15866
  return c.json({ error: "access-no-longer-valid" }, 401);
15676
15867
  }
15677
15868
  if (grant.expiresAt !== null && grant.expiresAt < Date.now()) {
15678
15869
  recordAccessFailedAttempt(ip, agentSlug);
15679
15870
  console.error(
15680
- `${TAG31} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
15871
+ `${TAG32} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
15681
15872
  );
15682
15873
  return c.json({ error: "access-no-longer-valid" }, 401);
15683
15874
  }
15684
15875
  if (!grant.sliceToken) {
15685
15876
  console.error(
15686
- `${TAG31} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
15877
+ `${TAG32} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
15687
15878
  );
15688
15879
  return c.json({ error: "grant-misconfigured" }, 500);
15689
15880
  }
@@ -15699,12 +15890,12 @@ app41.post("/", async (c) => {
15699
15890
  await consumeMagicTokenAndActivate(grant.grantId);
15700
15891
  } catch (err) {
15701
15892
  console.error(
15702
- `${TAG31} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
15893
+ `${TAG32} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
15703
15894
  );
15704
15895
  return c.json({ error: "verification-failed" }, 500);
15705
15896
  }
15706
15897
  clearAccessRateLimit(ip, agentSlug);
15707
- console.log(`${TAG31} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
15898
+ console.log(`${TAG32} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
15708
15899
  console.log(
15709
15900
  `${MINT_TAG} grantId=${grant.grantId} sliceToken=${grant.sliceToken.slice(0, 8)} agentSlug=${agentSlug} personId=${grant.personId ?? "none"}`
15710
15901
  );
@@ -15718,13 +15909,13 @@ app41.post("/", async (c) => {
15718
15909
  displayName: grant.displayName
15719
15910
  });
15720
15911
  });
15721
- var verify_token_default = app41;
15912
+ var verify_token_default = app42;
15722
15913
 
15723
15914
  // app/lib/access-email.ts
15724
15915
  import { spawn as spawn2 } from "child_process";
15725
- import { resolve as resolve24 } from "path";
15726
- var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve24(process.cwd(), "..");
15727
- var SEND_SCRIPT = resolve24(
15916
+ import { resolve as resolve25 } from "path";
15917
+ var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve25(process.cwd(), "..");
15918
+ var SEND_SCRIPT = resolve25(
15728
15919
  PLATFORM_ROOT7,
15729
15920
  "plugins",
15730
15921
  "email",
@@ -15780,10 +15971,10 @@ async function sendMagicLinkEmail(payload) {
15780
15971
  }
15781
15972
 
15782
15973
  // server/routes/access/request-magic-link.ts
15783
- var TAG32 = "[access-request-link]";
15784
- var app42 = new Hono();
15974
+ var TAG33 = "[access-request-link]";
15975
+ var app43 = new Hono();
15785
15976
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
15786
- app42.post("/", async (c) => {
15977
+ app43.post("/", async (c) => {
15787
15978
  let body;
15788
15979
  try {
15789
15980
  body = await c.req.json();
@@ -15797,18 +15988,18 @@ app42.post("/", async (c) => {
15797
15988
  }
15798
15989
  const rateMsg = checkRequestLinkRateLimit(contactValue);
15799
15990
  if (rateMsg) {
15800
- console.error(`${TAG32} contactValue=${maskContact(contactValue)} result=rate-limited`);
15991
+ console.error(`${TAG33} contactValue=${maskContact(contactValue)} result=rate-limited`);
15801
15992
  return c.json({ error: rateMsg }, 429);
15802
15993
  }
15803
15994
  recordRequestLinkAttempt(contactValue);
15804
15995
  const accountId = process.env.ACCOUNT_ID ?? "";
15805
15996
  if (!accountId) {
15806
- console.error(`${TAG32} contactValue=${maskContact(contactValue)} result=no-account-id`);
15997
+ console.error(`${TAG33} contactValue=${maskContact(contactValue)} result=no-account-id`);
15807
15998
  return c.json({ message: VISITOR_MESSAGE }, 200);
15808
15999
  }
15809
16000
  const grant = await findActiveGrantByContact(contactValue, agentSlug, accountId);
15810
16001
  if (!grant) {
15811
- console.log(`${TAG32} contactValue=${maskContact(contactValue)} result=notfound`);
16002
+ console.log(`${TAG33} contactValue=${maskContact(contactValue)} result=notfound`);
15812
16003
  return c.json({ message: VISITOR_MESSAGE }, 200);
15813
16004
  }
15814
16005
  let token;
@@ -15816,7 +16007,7 @@ app42.post("/", async (c) => {
15816
16007
  token = await generateNewMagicToken(grant.grantId);
15817
16008
  } catch (err) {
15818
16009
  console.error(
15819
- `${TAG32} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
16010
+ `${TAG33} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
15820
16011
  );
15821
16012
  return c.json({ message: VISITOR_MESSAGE }, 200);
15822
16013
  }
@@ -15848,26 +16039,26 @@ app42.post("/", async (c) => {
15848
16039
  });
15849
16040
  if (!sendResult.ok) {
15850
16041
  console.error(
15851
- `${TAG32} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
16042
+ `${TAG33} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
15852
16043
  );
15853
16044
  return c.json({ message: VISITOR_MESSAGE }, 200);
15854
16045
  }
15855
16046
  console.log(
15856
- `${TAG32} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
16047
+ `${TAG33} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
15857
16048
  );
15858
16049
  return c.json({ message: VISITOR_MESSAGE }, 200);
15859
16050
  });
15860
- var request_magic_link_default = app42;
16051
+ var request_magic_link_default = app43;
15861
16052
 
15862
16053
  // server/routes/access/index.ts
15863
- var app43 = new Hono();
15864
- app43.route("/verify-token", verify_token_default);
15865
- app43.route("/request-magic-link", request_magic_link_default);
15866
- var access_default = app43;
16054
+ var app44 = new Hono();
16055
+ app44.route("/verify-token", verify_token_default);
16056
+ app44.route("/request-magic-link", request_magic_link_default);
16057
+ var access_default = app44;
15867
16058
 
15868
16059
  // server/routes/sites.ts
15869
- import { existsSync as existsSync23, readFileSync as readFileSync23, realpathSync as realpathSync5, statSync as statSync9 } from "fs";
15870
- import { resolve as resolve25 } from "path";
16060
+ import { existsSync as existsSync23, readFileSync as readFileSync23, realpathSync as realpathSync5, statSync as statSync10 } from "fs";
16061
+ import { resolve as resolve26 } from "path";
15871
16062
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
15872
16063
  var MIME = {
15873
16064
  ".html": "text/html; charset=utf-8",
@@ -15898,8 +16089,8 @@ function getExt(p) {
15898
16089
  if (idx < p.lastIndexOf("/")) return "";
15899
16090
  return p.slice(idx).toLowerCase();
15900
16091
  }
15901
- var app44 = new Hono();
15902
- app44.get("/:rel{.*}", (c) => {
16092
+ var app45 = new Hono();
16093
+ app45.get("/:rel{.*}", (c) => {
15903
16094
  const reqPath = c.req.path;
15904
16095
  const rawRel = c.req.param("rel") ?? "";
15905
16096
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -15924,15 +16115,15 @@ app44.get("/:rel{.*}", (c) => {
15924
16115
  }
15925
16116
  segments.push(seg);
15926
16117
  }
15927
- const rootDir = resolve25(account.accountDir, "sites");
15928
- let filePath = segments.length === 0 ? rootDir : resolve25(rootDir, ...segments);
16118
+ const rootDir = resolve26(account.accountDir, "sites");
16119
+ let filePath = segments.length === 0 ? rootDir : resolve26(rootDir, ...segments);
15929
16120
  if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
15930
16121
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
15931
16122
  return c.text("Forbidden", 403);
15932
16123
  }
15933
16124
  let stat7;
15934
16125
  try {
15935
- stat7 = existsSync23(filePath) ? statSync9(filePath) : null;
16126
+ stat7 = existsSync23(filePath) ? statSync10(filePath) : null;
15936
16127
  } catch {
15937
16128
  stat7 = null;
15938
16129
  }
@@ -15945,7 +16136,7 @@ app44.get("/:rel{.*}", (c) => {
15945
16136
  return c.redirect(target, 301);
15946
16137
  }
15947
16138
  if (stat7?.isDirectory()) {
15948
- filePath = resolve25(filePath, "index.html");
16139
+ filePath = resolve26(filePath, "index.html");
15949
16140
  }
15950
16141
  if (!filePath.startsWith(rootDir + "/")) {
15951
16142
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
@@ -16002,12 +16193,12 @@ app44.get("/:rel{.*}", (c) => {
16002
16193
  "X-Content-Type-Options": "nosniff"
16003
16194
  });
16004
16195
  });
16005
- var sites_default = app44;
16196
+ var sites_default = app45;
16006
16197
 
16007
16198
  // app/lib/visitor-token.ts
16008
16199
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
16009
16200
  import { mkdirSync as mkdirSync4, readFileSync as readFileSync24, writeFileSync as writeFileSync9 } from "fs";
16010
- import { dirname as dirname6 } from "path";
16201
+ import { dirname as dirname7 } from "path";
16011
16202
  var TOKEN_PREFIX = "v1.";
16012
16203
  var SECRET_BYTES = 32;
16013
16204
  var DEFAULT_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
@@ -16024,7 +16215,7 @@ function getSecret() {
16024
16215
  }
16025
16216
  const fresh = randomBytes(SECRET_BYTES).toString("hex");
16026
16217
  try {
16027
- mkdirSync4(dirname6(VISITOR_TOKEN_SECRET_FILE), { recursive: true, mode: 448 });
16218
+ mkdirSync4(dirname7(VISITOR_TOKEN_SECRET_FILE), { recursive: true, mode: 448 });
16028
16219
  writeFileSync9(VISITOR_TOKEN_SECRET_FILE, fresh, { mode: 384, flag: "wx" });
16029
16220
  console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
16030
16221
  } catch {
@@ -16083,7 +16274,7 @@ var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
16083
16274
 
16084
16275
  // app/lib/brand-config.ts
16085
16276
  import { existsSync as existsSync24, readFileSync as readFileSync25 } from "fs";
16086
- import { join as join22 } from "path";
16277
+ import { join as join23 } from "path";
16087
16278
  var cached2 = null;
16088
16279
  var cachedAttempted = false;
16089
16280
  function readBrandConfig() {
@@ -16091,7 +16282,7 @@ function readBrandConfig() {
16091
16282
  cachedAttempted = true;
16092
16283
  const platformRoot2 = process.env.MAXY_PLATFORM_ROOT;
16093
16284
  if (!platformRoot2) return null;
16094
- const brandPath = join22(platformRoot2, "config", "brand.json");
16285
+ const brandPath = join23(platformRoot2, "config", "brand.json");
16095
16286
  if (!existsSync24(brandPath)) return null;
16096
16287
  try {
16097
16288
  cached2 = JSON.parse(readFileSync25(brandPath, "utf-8"));
@@ -16102,7 +16293,7 @@ function readBrandConfig() {
16102
16293
  }
16103
16294
 
16104
16295
  // server/routes/visitor-consent.ts
16105
- var app45 = new Hono();
16296
+ var app46 = new Hono();
16106
16297
  var CONSENT_COOKIE_NAME = "mxy_consent";
16107
16298
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
16108
16299
  var DEFAULT_CONSENT_COPY = {
@@ -16147,17 +16338,17 @@ function siteSlugFromReferer(referer) {
16147
16338
  return "";
16148
16339
  }
16149
16340
  }
16150
- app45.options("/consent", (c) => {
16341
+ app46.options("/consent", (c) => {
16151
16342
  const origin = getOrigin(c);
16152
16343
  setCorsHeaders(c, origin);
16153
16344
  return c.body(null, 204);
16154
16345
  });
16155
- app45.options("/brand-config", (c) => {
16346
+ app46.options("/brand-config", (c) => {
16156
16347
  const origin = getOrigin(c);
16157
16348
  setCorsHeaders(c, origin);
16158
16349
  return c.body(null, 204);
16159
16350
  });
16160
- app45.post("/consent", async (c) => {
16351
+ app46.post("/consent", async (c) => {
16161
16352
  const origin = getOrigin(c);
16162
16353
  setCorsHeaders(c, origin);
16163
16354
  let raw;
@@ -16197,7 +16388,7 @@ app45.post("/consent", async (c) => {
16197
16388
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
16198
16389
  return c.body(null, 204);
16199
16390
  });
16200
- app45.get("/brand-config", (c) => {
16391
+ app46.get("/brand-config", (c) => {
16201
16392
  const origin = getOrigin(c);
16202
16393
  setCorsHeaders(c, origin);
16203
16394
  const brand = readBrandConfig();
@@ -16207,7 +16398,7 @@ app45.get("/brand-config", (c) => {
16207
16398
  c.header("Cache-Control", "public, max-age=300");
16208
16399
  return c.json({ consent: { copy, palette } });
16209
16400
  });
16210
- var visitor_consent_default = app45;
16401
+ var visitor_consent_default = app46;
16211
16402
 
16212
16403
  // server/routes/listings.ts
16213
16404
  function getCookie(headerValue, name) {
@@ -16228,14 +16419,14 @@ function appendConsentParams(pageUrl, token) {
16228
16419
  const hashIdx = pageUrl.indexOf("#");
16229
16420
  const hash = hashIdx >= 0 ? pageUrl.slice(hashIdx) : "";
16230
16421
  const base = hashIdx >= 0 ? pageUrl.slice(0, hashIdx) : pageUrl;
16231
- const sep8 = base.indexOf("?") >= 0 ? "&" : "?";
16232
- return base + sep8 + `consent=needed&v=${encodeURIComponent(token)}` + hash;
16422
+ const sep9 = base.indexOf("?") >= 0 ? "&" : "?";
16423
+ return base + sep9 + `consent=needed&v=${encodeURIComponent(token)}` + hash;
16233
16424
  }
16234
16425
  }
16235
16426
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
16236
16427
  var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
16237
- var app46 = new Hono();
16238
- app46.get("/:slug/click", async (c) => {
16428
+ var app47 = new Hono();
16429
+ app47.get("/:slug/click", async (c) => {
16239
16430
  const slug = c.req.param("slug") ?? "";
16240
16431
  const rawSession = c.req.query("session") ?? "";
16241
16432
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -16299,10 +16490,10 @@ app46.get("/:slug/click", async (c) => {
16299
16490
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
16300
16491
  return c.redirect(redirectUrl, 302);
16301
16492
  });
16302
- var listings_default = app46;
16493
+ var listings_default = app47;
16303
16494
 
16304
16495
  // server/routes/visitor-event.ts
16305
- var app47 = new Hono();
16496
+ var app48 = new Hono();
16306
16497
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
16307
16498
  var buckets = /* @__PURE__ */ new Map();
16308
16499
  var RATE_LIMIT = 60;
@@ -16369,12 +16560,12 @@ function originAllowed(origin, allowlist) {
16369
16560
  return false;
16370
16561
  }
16371
16562
  }
16372
- app47.options("/event", (c) => {
16563
+ app48.options("/event", (c) => {
16373
16564
  const origin = getOrigin2(c);
16374
16565
  setCorsHeaders2(c, origin);
16375
16566
  return c.body(null, 204);
16376
16567
  });
16377
- app47.post("/event", async (c) => {
16568
+ app48.post("/event", async (c) => {
16378
16569
  const origin = getOrigin2(c);
16379
16570
  setCorsHeaders2(c, origin);
16380
16571
  const ua = c.req.header("user-agent") ?? "";
@@ -16579,17 +16770,17 @@ async function writeEvent(opts) {
16579
16770
  );
16580
16771
  }
16581
16772
  }
16582
- var visitor_event_default = app47;
16773
+ var visitor_event_default = app48;
16583
16774
 
16584
16775
  // server/routes/session.ts
16585
- import { resolve as resolve26 } from "path";
16776
+ import { resolve as resolve27 } from "path";
16586
16777
  import { existsSync as existsSync25, writeFileSync as writeFileSync10, mkdirSync as mkdirSync5 } from "fs";
16587
16778
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16588
16779
  function writeBrandingCache(accountId, agentSlug, branding) {
16589
16780
  try {
16590
- const cacheDir = resolve26(MAXY_DIR, "branding-cache", accountId);
16781
+ const cacheDir = resolve27(MAXY_DIR, "branding-cache", accountId);
16591
16782
  mkdirSync5(cacheDir, { recursive: true });
16592
- writeFileSync10(resolve26(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
16783
+ writeFileSync10(resolve27(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
16593
16784
  } catch (err) {
16594
16785
  console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
16595
16786
  }
@@ -16601,7 +16792,7 @@ function parseVisitorCookie(cookieHeader) {
16601
16792
  const value = decodeURIComponent(match[1]).trim();
16602
16793
  return UUID_RE4.test(value) ? value : null;
16603
16794
  }
16604
- function parseAccessSessionId(cookieHeader) {
16795
+ function parseAccessSessionId2(cookieHeader) {
16605
16796
  if (!cookieHeader) return null;
16606
16797
  const part = cookieHeader.split(";").map((p) => p.trim()).find((p) => p.startsWith("__access_session="));
16607
16798
  return part ? part.slice("__access_session=".length) : null;
@@ -16625,8 +16816,8 @@ function withVisitorCookie(response, visitorId) {
16625
16816
  headers
16626
16817
  });
16627
16818
  }
16628
- var app48 = new Hono();
16629
- app48.post("/", async (c) => {
16819
+ var app49 = new Hono();
16820
+ app49.post("/", async (c) => {
16630
16821
  let body;
16631
16822
  try {
16632
16823
  body = await c.req.json();
@@ -16677,8 +16868,8 @@ app48.post("/", async (c) => {
16677
16868
  }
16678
16869
  let agentConfig = null;
16679
16870
  if (account) {
16680
- const agentDir = resolve26(account.accountDir, "agents", agentSlug);
16681
- if (!existsSync25(agentDir) || !existsSync25(resolve26(agentDir, "config.json"))) {
16871
+ const agentDir = resolve27(account.accountDir, "agents", agentSlug);
16872
+ if (!existsSync25(agentDir) || !existsSync25(resolve27(agentDir, "config.json"))) {
16682
16873
  return c.json({ error: "Agent not found" }, 404);
16683
16874
  }
16684
16875
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -16698,7 +16889,7 @@ app48.post("/", async (c) => {
16698
16889
  if (branding) writeBrandingCache(accountId, agentSlug, branding);
16699
16890
  let accessSession = null;
16700
16891
  if (agentConfig && agentConfig.accessMode !== "open") {
16701
- const accessSessionId = parseAccessSessionId(cookieHeader);
16892
+ const accessSessionId = parseAccessSessionId2(cookieHeader);
16702
16893
  accessSession = accessSessionId ? getAccessSession(accessSessionId) : null;
16703
16894
  if (!accessSession || accessSession.agentSlug !== agentSlug) {
16704
16895
  console.log(`[session] agent=${agentSlug} accessMode=${agentConfig.accessMode} \u2014 auth required`);
@@ -16837,7 +17028,7 @@ app48.post("/", async (c) => {
16837
17028
  newVisitorId
16838
17029
  );
16839
17030
  });
16840
- var session_default2 = app48;
17031
+ var session_default2 = app49;
16841
17032
 
16842
17033
  // app/lib/graph-health.ts
16843
17034
  var import_dist4 = __toESM(require_dist3(), 1);
@@ -16958,13 +17149,13 @@ function startGraphHealthTimer() {
16958
17149
 
16959
17150
  // app/lib/file-watcher.ts
16960
17151
  import * as fsp2 from "fs/promises";
16961
- import { resolve as resolve27, sep as sep7 } from "path";
17152
+ import { resolve as resolve28, sep as sep8 } from "path";
16962
17153
  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;
16963
17154
  var DEFAULT_COALESCE_MS = 500;
16964
17155
  var ROOTS = ["accounts"];
16965
17156
  function _routeEvent(rootName, filename) {
16966
17157
  if (!filename) return null;
16967
- const segs = filename.split(sep7).filter(Boolean);
17158
+ const segs = filename.split(sep8).filter(Boolean);
16968
17159
  if (segs.length < 2) return null;
16969
17160
  const accountId = segs[0];
16970
17161
  if (!ACCOUNT_UUID_RE2.test(accountId)) return null;
@@ -16977,7 +17168,7 @@ async function startFileWatcher(opts = {}) {
16977
17168
  const dropFn = opts.drop ?? dropFileIndex;
16978
17169
  for (const r of ROOTS) {
16979
17170
  try {
16980
- await fsp2.mkdir(resolve27(dataRoot, r), { recursive: true });
17171
+ await fsp2.mkdir(resolve28(dataRoot, r), { recursive: true });
16981
17172
  } catch (err) {
16982
17173
  console.error(
16983
17174
  `[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
@@ -16998,7 +17189,7 @@ async function startFileWatcher(opts = {}) {
16998
17189
  timers.set(relativePath, t);
16999
17190
  }
17000
17191
  async function runHook(relativePath, accountId) {
17001
- const absolute = resolve27(dataRoot, relativePath);
17192
+ const absolute = resolve28(dataRoot, relativePath);
17002
17193
  let exists = false;
17003
17194
  try {
17004
17195
  const st = await fsp2.stat(absolute);
@@ -17022,7 +17213,7 @@ async function startFileWatcher(opts = {}) {
17022
17213
  }
17023
17214
  }
17024
17215
  async function watchRoot(rootName) {
17025
- const absRoot = resolve27(dataRoot, rootName);
17216
+ const absRoot = resolve28(dataRoot, rootName);
17026
17217
  try {
17027
17218
  const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
17028
17219
  for await (const event of iter) {
@@ -17061,7 +17252,7 @@ async function startFileWatcher(opts = {}) {
17061
17252
 
17062
17253
  // app/lib/migrate-uploads.ts
17063
17254
  import { mkdir as mkdir5, readdir as readdir5, rename, rm as rm3 } from "fs/promises";
17064
- import { dirname as dirname7, relative as relative4, resolve as resolve28 } from "path";
17255
+ import { dirname as dirname8, relative as relative4, resolve as resolve29 } from "path";
17065
17256
  var ACCOUNT_UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
17066
17257
  async function walkFiles(dir) {
17067
17258
  const out = [];
@@ -17072,7 +17263,7 @@ async function walkFiles(dir) {
17072
17263
  return out;
17073
17264
  }
17074
17265
  for (const e of entries) {
17075
- const abs = resolve28(dir, e.name);
17266
+ const abs = resolve29(dir, e.name);
17076
17267
  if (e.isDirectory()) {
17077
17268
  out.push(...await walkFiles(abs));
17078
17269
  } else if (e.isFile()) {
@@ -17092,8 +17283,8 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
17092
17283
  let moved = 0;
17093
17284
  for (const oldAbs of files) {
17094
17285
  const suffix = relative4(srcDir, oldAbs);
17095
- const newAbs = resolve28(destDir, suffix);
17096
- await mkdir5(dirname7(newAbs), { recursive: true });
17286
+ const newAbs = resolve29(destDir, suffix);
17287
+ await mkdir5(dirname8(newAbs), { recursive: true });
17097
17288
  await rename(oldAbs, newAbs);
17098
17289
  moved++;
17099
17290
  const oldRel = relative4(dataRoot, oldAbs);
@@ -17119,7 +17310,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
17119
17310
  }
17120
17311
  async function migrateUploads(opts = {}) {
17121
17312
  const dataRoot = opts.dataRoot ?? DATA_ROOT;
17122
- const oldRoot = resolve28(dataRoot, "uploads");
17313
+ const oldRoot = resolve29(dataRoot, "uploads");
17123
17314
  let topEntries;
17124
17315
  try {
17125
17316
  topEntries = await readdir5(oldRoot, { withFileTypes: true });
@@ -17140,8 +17331,8 @@ async function migrateUploads(opts = {}) {
17140
17331
  const name = entry.name;
17141
17332
  if (ACCOUNT_UUID_RE3.test(name)) {
17142
17333
  moved += await relocateTree(
17143
- resolve28(oldRoot, name),
17144
- resolve28(dataRoot, "accounts", name, "uploads"),
17334
+ resolve29(oldRoot, name),
17335
+ resolve29(dataRoot, "accounts", name, "uploads"),
17145
17336
  dataRoot,
17146
17337
  name,
17147
17338
  session
@@ -17153,8 +17344,8 @@ async function migrateUploads(opts = {}) {
17153
17344
  continue;
17154
17345
  }
17155
17346
  moved += await relocateTree(
17156
- resolve28(oldRoot, "public"),
17157
- resolve28(dataRoot, "accounts", installAccountId, "uploads", "public"),
17347
+ resolve29(oldRoot, "public"),
17348
+ resolve29(dataRoot, "accounts", installAccountId, "uploads", "public"),
17158
17349
  dataRoot,
17159
17350
  null,
17160
17351
  // public uploads carry no graph nodes
@@ -17185,7 +17376,7 @@ async function migrateUploads(opts = {}) {
17185
17376
  // app/lib/migrate-admin-webchat-sidecars.ts
17186
17377
  import { readdir as readdir6, readFile as readFile6, rename as rename2, writeFile as writeFile5, unlink as unlink3 } from "fs/promises";
17187
17378
  import { existsSync as existsSync26 } from "fs";
17188
- import { join as join23 } from "path";
17379
+ import { join as join24 } from "path";
17189
17380
  var ADMIN_ROLE2 = "admin";
17190
17381
  var WEBCHAT_CHANNEL2 = "webchat";
17191
17382
  var SESSION_META_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.meta\.json$/i;
@@ -17230,7 +17421,7 @@ async function collectLiveSidecars(projectsRoot) {
17230
17421
  }
17231
17422
  for (const slug of slugs) {
17232
17423
  if (!slug.isDirectory()) continue;
17233
- const slugDir = join23(projectsRoot, slug.name);
17424
+ const slugDir = join24(projectsRoot, slug.name);
17234
17425
  let entries;
17235
17426
  try {
17236
17427
  entries = await readdir6(slugDir, { withFileTypes: true });
@@ -17239,9 +17430,9 @@ async function collectLiveSidecars(projectsRoot) {
17239
17430
  }
17240
17431
  for (const entry of entries) {
17241
17432
  if (entry.isFile() && SESSION_META_RE.test(entry.name)) {
17242
- out.push(join23(slugDir, entry.name));
17433
+ out.push(join24(slugDir, entry.name));
17243
17434
  } else if (entry.isDirectory() && entry.name === "subagents") {
17244
- const subDir = join23(slugDir, entry.name);
17435
+ const subDir = join24(slugDir, entry.name);
17245
17436
  let subs;
17246
17437
  try {
17247
17438
  subs = await readdir6(subDir, { withFileTypes: true });
@@ -17249,7 +17440,7 @@ async function collectLiveSidecars(projectsRoot) {
17249
17440
  continue;
17250
17441
  }
17251
17442
  for (const s of subs) {
17252
- if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join23(subDir, s.name));
17443
+ if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join24(subDir, s.name));
17253
17444
  }
17254
17445
  }
17255
17446
  }
@@ -17261,7 +17452,7 @@ function shortId(path2) {
17261
17452
  return base.slice(0, 8);
17262
17453
  }
17263
17454
  async function migrateAdminWebchatSidecars(opts = {}) {
17264
- const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join23(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
17455
+ const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join24(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
17265
17456
  const usersFile = opts.usersFile ?? USERS_FILE;
17266
17457
  const accountId = opts.accountId ?? resolveAccount()?.accountId ?? null;
17267
17458
  const resolveName = opts.resolveName ?? defaultResolveName;
@@ -17603,8 +17794,8 @@ var streamSSE = (c, cb, onError) => {
17603
17794
 
17604
17795
  // app/lib/whatsapp/gateway/routes.ts
17605
17796
  function createWaChannelRoutes(deps) {
17606
- const app50 = new Hono();
17607
- app50.get("/wa-channel/inbound", (c) => {
17797
+ const app51 = new Hono();
17798
+ app51.get("/wa-channel/inbound", (c) => {
17608
17799
  const senderId = c.req.query("senderId");
17609
17800
  if (!senderId) return c.json({ error: "senderId required" }, 400);
17610
17801
  return streamSSE(c, async (stream2) => {
@@ -17622,7 +17813,7 @@ function createWaChannelRoutes(deps) {
17622
17813
  }
17623
17814
  });
17624
17815
  });
17625
- app50.post("/wa-channel/reply", async (c) => {
17816
+ app51.post("/wa-channel/reply", async (c) => {
17626
17817
  const body = await c.req.json().catch(() => null);
17627
17818
  const senderId = body?.senderId;
17628
17819
  const text = body?.text;
@@ -17643,7 +17834,7 @@ function createWaChannelRoutes(deps) {
17643
17834
  console.error(`[whatsapp-native] op=reply-dispatch senderId=${senderId} bytes=${bytes}`);
17644
17835
  return c.json({ ok: true });
17645
17836
  });
17646
- app50.post("/wa-channel/reply-document", async (c) => {
17837
+ app51.post("/wa-channel/reply-document", async (c) => {
17647
17838
  const body = await c.req.json().catch(() => null);
17648
17839
  const senderId = body?.senderId;
17649
17840
  const files = body?.files;
@@ -17682,7 +17873,7 @@ function createWaChannelRoutes(deps) {
17682
17873
  }
17683
17874
  return c.json({ ok: true, results });
17684
17875
  });
17685
- app50.post("/wa-channel/ready", async (c) => {
17876
+ app51.post("/wa-channel/ready", async (c) => {
17686
17877
  const body = await c.req.json().catch(() => null);
17687
17878
  const senderId = body?.senderId;
17688
17879
  if (typeof senderId !== "string") {
@@ -17691,7 +17882,7 @@ function createWaChannelRoutes(deps) {
17691
17882
  deps.onReady?.(senderId);
17692
17883
  return c.json({ ok: true });
17693
17884
  });
17694
- app50.post("/wa-channel/received", async (c) => {
17885
+ app51.post("/wa-channel/received", async (c) => {
17695
17886
  const body = await c.req.json().catch(() => null);
17696
17887
  const senderId = body?.senderId;
17697
17888
  const waMessageId = body?.waMessageId;
@@ -17701,7 +17892,7 @@ function createWaChannelRoutes(deps) {
17701
17892
  deps.onReceived?.(senderId, waMessageId);
17702
17893
  return c.json({ ok: true });
17703
17894
  });
17704
- app50.post("/wa-channel/turn-end", async (c) => {
17895
+ app51.post("/wa-channel/turn-end", async (c) => {
17705
17896
  const body = await c.req.json().catch(() => null);
17706
17897
  const senderId = body?.senderId;
17707
17898
  const sessionId = body?.sessionId;
@@ -17732,7 +17923,7 @@ function createWaChannelRoutes(deps) {
17732
17923
  console.error(`[whatsapp-native] op=turn-end sessionId=${sid} replied=no delivered=fallback bytes=${bytes}`);
17733
17924
  return c.json({ ok: true, delivered: "fallback" });
17734
17925
  });
17735
- return app50;
17926
+ return app51;
17736
17927
  }
17737
17928
 
17738
17929
  // app/lib/whatsapp/gateway/wa-gateway.ts
@@ -17985,8 +18176,8 @@ var InboundHub2 = class {
17985
18176
 
17986
18177
  // app/lib/webchat/gateway/routes.ts
17987
18178
  function createWebchatChannelRoutes(deps) {
17988
- const app50 = new Hono();
17989
- app50.get("/webchat-channel/inbound", (c) => {
18179
+ const app51 = new Hono();
18180
+ app51.get("/webchat-channel/inbound", (c) => {
17990
18181
  const key = c.req.query("key");
17991
18182
  if (!key) return c.json({ error: "key required" }, 400);
17992
18183
  return streamSSE(c, async (stream2) => {
@@ -18004,7 +18195,7 @@ function createWebchatChannelRoutes(deps) {
18004
18195
  }
18005
18196
  });
18006
18197
  });
18007
- app50.post("/webchat-channel/reply", async (c) => {
18198
+ app51.post("/webchat-channel/reply", async (c) => {
18008
18199
  const body = await c.req.json().catch(() => null);
18009
18200
  const key = body?.key;
18010
18201
  const text = body?.text;
@@ -18014,7 +18205,7 @@ function createWebchatChannelRoutes(deps) {
18014
18205
  deps.onReply?.(key, text);
18015
18206
  return c.json({ ok: true });
18016
18207
  });
18017
- app50.post("/webchat-channel/ready", async (c) => {
18208
+ app51.post("/webchat-channel/ready", async (c) => {
18018
18209
  const body = await c.req.json().catch(() => null);
18019
18210
  const key = body?.key;
18020
18211
  if (typeof key !== "string") {
@@ -18023,7 +18214,7 @@ function createWebchatChannelRoutes(deps) {
18023
18214
  deps.onReady?.(key);
18024
18215
  return c.json({ ok: true });
18025
18216
  });
18026
- app50.post("/webchat-channel/received", async (c) => {
18217
+ app51.post("/webchat-channel/received", async (c) => {
18027
18218
  const body = await c.req.json().catch(() => null);
18028
18219
  const key = body?.key;
18029
18220
  const messageId = body?.messageId;
@@ -18033,7 +18224,7 @@ function createWebchatChannelRoutes(deps) {
18033
18224
  deps.onReceived?.(key, messageId);
18034
18225
  return c.json({ ok: true });
18035
18226
  });
18036
- return app50;
18227
+ return app51;
18037
18228
  }
18038
18229
 
18039
18230
  // app/lib/webchat/gateway/webchat-gateway.ts
@@ -18068,16 +18259,16 @@ var WebchatGateway = class {
18068
18259
  * The public /api/chat route awaits this to return the reply on the same SSE
18069
18260
  * response, preserving the pre-756 POST→single-blob browser contract. */
18070
18261
  awaitReply(key, timeoutMs) {
18071
- return new Promise((resolve31) => {
18262
+ return new Promise((resolve32) => {
18072
18263
  const timer2 = setTimeout(() => {
18073
18264
  this.replyAwaiters.delete(key);
18074
- resolve31({ timeout: true });
18265
+ resolve32({ timeout: true });
18075
18266
  }, timeoutMs);
18076
18267
  if (timer2.unref) timer2.unref();
18077
18268
  this.replyAwaiters.set(key, (r) => {
18078
18269
  clearTimeout(timer2);
18079
18270
  this.replyAwaiters.delete(key);
18080
- resolve31(r);
18271
+ resolve32(r);
18081
18272
  });
18082
18273
  });
18083
18274
  }
@@ -18346,8 +18537,8 @@ function broadcastAdminShutdown(reason) {
18346
18537
 
18347
18538
  // ../lib/entitlement/src/index.ts
18348
18539
  import { createPublicKey, createHash as createHash5, verify as cryptoVerify } from "crypto";
18349
- import { existsSync as existsSync27, readFileSync as readFileSync26, statSync as statSync10 } from "fs";
18350
- import { resolve as resolve29 } from "path";
18540
+ import { existsSync as existsSync27, readFileSync as readFileSync26, statSync as statSync11 } from "fs";
18541
+ import { resolve as resolve30 } from "path";
18351
18542
 
18352
18543
  // ../lib/entitlement/src/canonicalize.ts
18353
18544
  function canonicalize(value) {
@@ -18382,7 +18573,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
18382
18573
  var GRACE_DAYS = 7;
18383
18574
  var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
18384
18575
  function pubkeyPath(brand) {
18385
- return resolve29(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
18576
+ return resolve30(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
18386
18577
  }
18387
18578
  var memo = null;
18388
18579
  function memoKey(mtimeMs, account) {
@@ -18394,11 +18585,11 @@ function resolveEntitlement(brand, account) {
18394
18585
  if (brand.commercialMode !== true) {
18395
18586
  return logResolved(implicitTrust(account), null);
18396
18587
  }
18397
- const entitlementPath = resolve29(brand.configDir, "entitlement.json");
18588
+ const entitlementPath = resolve30(brand.configDir, "entitlement.json");
18398
18589
  if (!existsSync27(entitlementPath)) {
18399
18590
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
18400
18591
  }
18401
- const stat7 = statSync10(entitlementPath);
18592
+ const stat7 = statSync11(entitlementPath);
18402
18593
  const key = memoKey(stat7.mtimeMs, account);
18403
18594
  if (memo && memo.key === key) {
18404
18595
  return memo.result;
@@ -18585,7 +18776,7 @@ function clientFrom(c) {
18585
18776
  );
18586
18777
  }
18587
18778
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
18588
- var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join24(PLATFORM_ROOT8, "config", "brand.json") : "";
18779
+ var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join25(PLATFORM_ROOT8, "config", "brand.json") : "";
18589
18780
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
18590
18781
  if (BRAND_JSON_PATH && !existsSync28(BRAND_JSON_PATH)) {
18591
18782
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
@@ -18611,7 +18802,7 @@ var brandLoginOpts = {
18611
18802
  bodyFont: BRAND.defaultFonts?.body,
18612
18803
  logoContainsName: !!BRAND.logoContainsName
18613
18804
  };
18614
- var ALIAS_DOMAINS_PATH = join24(homedir3(), BRAND.configDir, "alias-domains.json");
18805
+ var ALIAS_DOMAINS_PATH = join25(homedir3(), BRAND.configDir, "alias-domains.json");
18615
18806
  function loadAliasDomains() {
18616
18807
  try {
18617
18808
  if (!existsSync28(ALIAS_DOMAINS_PATH)) return null;
@@ -18639,11 +18830,11 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
18639
18830
  function isPublicHost(host) {
18640
18831
  return host.startsWith("public.") || aliasDomains.has(host);
18641
18832
  }
18642
- var app49 = new Hono();
18833
+ var app50 = new Hono();
18643
18834
  var nativeFileFollowers = /* @__PURE__ */ new Map();
18644
18835
  var waGateway = new WaGateway({
18645
18836
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
18646
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve30(process.env.MAXY_PLATFORM_ROOT ?? join24(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
18837
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve31(process.env.MAXY_PLATFORM_ROOT ?? join25(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
18647
18838
  // Task 751 — file delivery on the native channel: resolve the platform
18648
18839
  // account + path validation here and funnel through the shared send core.
18649
18840
  sendDocument: async ({ senderId, accountId, filePath, caption }) => {
@@ -18659,7 +18850,7 @@ var waGateway = new WaGateway({
18659
18850
  caption,
18660
18851
  accountId,
18661
18852
  maxyAccountId,
18662
- platformRoot: resolve30(process.env.MAXY_PLATFORM_ROOT ?? join24(__dirname, ".."))
18853
+ platformRoot: resolve31(process.env.MAXY_PLATFORM_ROOT ?? join25(__dirname, ".."))
18663
18854
  });
18664
18855
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
18665
18856
  },
@@ -18689,7 +18880,7 @@ var waGateway = new WaGateway({
18689
18880
  nativeFileFollowers.set(senderId, ac);
18690
18881
  }
18691
18882
  });
18692
- app49.route("/", waGateway.routes());
18883
+ app50.route("/", waGateway.routes());
18693
18884
  waGateway.startSweeper();
18694
18885
  var webchatGateway = new WebchatGateway({
18695
18886
  gatewayUrl: webchatGatewayUrl(),
@@ -18729,15 +18920,15 @@ var webchatGateway = new WebchatGateway({
18729
18920
  deleteSession: (sessionId) => managerDelete(sessionId),
18730
18921
  firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
18731
18922
  });
18732
- app49.route("/", webchatGateway.routes());
18923
+ app50.route("/", webchatGateway.routes());
18733
18924
  webchatGateway.startSweeper();
18734
18925
  webchatGateway.startPublicReaper();
18735
18926
  var chatRoutes = createChatRoutes({
18736
18927
  handleInbound: (input) => webchatGateway.handleInbound(input),
18737
18928
  awaitReply: (key, timeoutMs) => webchatGateway.awaitReply(key, timeoutMs)
18738
18929
  });
18739
- app49.use("*", clientIpMiddleware);
18740
- app49.use("*", async (c, next) => {
18930
+ app50.use("*", clientIpMiddleware);
18931
+ app50.use("*", async (c, next) => {
18741
18932
  await next();
18742
18933
  c.header("X-Content-Type-Options", "nosniff");
18743
18934
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
@@ -18747,7 +18938,7 @@ app49.use("*", async (c, next) => {
18747
18938
  );
18748
18939
  });
18749
18940
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
18750
- app49.use("*", async (c, next) => {
18941
+ app50.use("*", async (c, next) => {
18751
18942
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
18752
18943
  await next();
18753
18944
  return;
@@ -18765,7 +18956,7 @@ app49.use("*", async (c, next) => {
18765
18956
  });
18766
18957
  }
18767
18958
  });
18768
- app49.use("*", async (c, next) => {
18959
+ app50.use("*", async (c, next) => {
18769
18960
  const host = (c.req.header("host") ?? "").split(":")[0];
18770
18961
  if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
18771
18962
  await next();
@@ -18796,7 +18987,7 @@ function resolveRemoteAuthOpts() {
18796
18987
  return brandLoginOpts;
18797
18988
  }
18798
18989
  var MAX_LOGIN_BODY = 8 * 1024;
18799
- app49.post("/__remote-auth/login", async (c) => {
18990
+ app50.post("/__remote-auth/login", async (c) => {
18800
18991
  const client = clientFrom(c);
18801
18992
  const clientIp = client.ip || "unknown";
18802
18993
  if (!requestIsTlsTerminated(c)) {
@@ -18841,7 +19032,7 @@ app49.post("/__remote-auth/login", async (c) => {
18841
19032
  }
18842
19033
  });
18843
19034
  });
18844
- app49.get("/__remote-auth/logout", (c) => {
19035
+ app50.get("/__remote-auth/logout", (c) => {
18845
19036
  const client = clientFrom(c);
18846
19037
  const clientIp = client.ip || "unknown";
18847
19038
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -18854,7 +19045,7 @@ app49.get("/__remote-auth/logout", (c) => {
18854
19045
  }
18855
19046
  });
18856
19047
  });
18857
- app49.post("/__remote-auth/change-password", async (c) => {
19048
+ app50.post("/__remote-auth/change-password", async (c) => {
18858
19049
  const client = clientFrom(c);
18859
19050
  const clientIp = client.ip || "unknown";
18860
19051
  const rateLimited = checkRateLimit(client);
@@ -18896,6 +19087,9 @@ app49.post("/__remote-auth/change-password", async (c) => {
18896
19087
  redirect
18897
19088
  }), 200);
18898
19089
  }
19090
+ if (targetUserId && await accessPasswordCollides(newPassword, USERS_FILE, targetUserId)) {
19091
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "That password is already in use by another admin. Choose a different one.", redirect }), 200);
19092
+ }
18899
19093
  try {
18900
19094
  if (targetUserId) {
18901
19095
  await setAccessPassword(targetUserId, newPassword, USERS_FILE);
@@ -18910,13 +19104,13 @@ app49.post("/__remote-auth/change-password", async (c) => {
18910
19104
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
18911
19105
  }
18912
19106
  });
18913
- app49.get("/__remote-auth/setup", (c) => {
19107
+ app50.get("/__remote-auth/setup", (c) => {
18914
19108
  if (isRemoteAuthConfigured()) {
18915
19109
  return c.redirect("/");
18916
19110
  }
18917
19111
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
18918
19112
  });
18919
- app49.post("/__remote-auth/set-initial-password", async (c) => {
19113
+ app50.post("/__remote-auth/set-initial-password", async (c) => {
18920
19114
  if (isRemoteAuthConfigured()) {
18921
19115
  return c.redirect("/");
18922
19116
  }
@@ -18954,10 +19148,10 @@ app49.post("/__remote-auth/set-initial-password", async (c) => {
18954
19148
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
18955
19149
  }
18956
19150
  });
18957
- app49.get("/api/remote-auth/status", (c) => {
19151
+ app50.get("/api/remote-auth/status", (c) => {
18958
19152
  return c.json({ configured: isRemoteAuthConfigured() });
18959
19153
  });
18960
- app49.post("/api/remote-auth/set-password", async (c) => {
19154
+ app50.post("/api/remote-auth/set-password", async (c) => {
18961
19155
  let body;
18962
19156
  try {
18963
19157
  body = await c.req.json();
@@ -18980,6 +19174,9 @@ app49.post("/api/remote-auth/set-password", async (c) => {
18980
19174
  requirements
18981
19175
  }, 400);
18982
19176
  }
19177
+ if (sessionUserId && await accessPasswordCollides(body.password, USERS_FILE, sessionUserId)) {
19178
+ return c.json({ error: "That password is already in use by another admin. Choose a different one." }, 400);
19179
+ }
18983
19180
  try {
18984
19181
  if (sessionUserId) {
18985
19182
  await setAccessPassword(sessionUserId, body.password, USERS_FILE);
@@ -18993,10 +19190,10 @@ app49.post("/api/remote-auth/set-password", async (c) => {
18993
19190
  return c.json({ error: "Failed to save password" }, 500);
18994
19191
  }
18995
19192
  });
18996
- app49.route("/api/_client-error", client_error_default);
19193
+ app50.route("/api/_client-error", client_error_default);
18997
19194
  console.log("[client-error-route] mounted");
18998
19195
  var PWA_PUBLIC_PATHS = /* @__PURE__ */ new Set(["/sw.js", ...PWA_SURFACES.map((s) => s.manifestPath)]);
18999
- app49.use("*", async (c, next) => {
19196
+ app50.use("*", async (c, next) => {
19000
19197
  const host = (c.req.header("host") ?? "").split(":")[0];
19001
19198
  const path2 = c.req.path;
19002
19199
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/") || PWA_PUBLIC_PATHS.has(path2)) {
@@ -19036,17 +19233,18 @@ app49.use("*", async (c, next) => {
19036
19233
  }
19037
19234
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
19038
19235
  });
19039
- app49.route("/api/health", health_default);
19040
- app49.route("/api/chat", chatRoutes);
19041
- app49.route("/api/whatsapp", whatsapp_default);
19042
- app49.route("/api/whatsapp-reader", whatsapp_reader_default);
19043
- app49.route("/api/webchat", createWebchatRoutes({ handleInbound: (input) => webchatGateway.handleInbound(input) }));
19044
- app49.route("/api/webchat/greeting", webchat_greeting_default);
19045
- app49.route("/api/telegram", telegram_default);
19046
- app49.route("/api/onboarding", onboarding_default);
19047
- app49.route("/api/admin", admin_default);
19048
- app49.route("/api/access", access_default);
19049
- app49.route("/api/session", session_default2);
19236
+ app50.route("/api/health", health_default);
19237
+ app50.route("/api/chat", chatRoutes);
19238
+ app50.route("/api/whatsapp", whatsapp_default);
19239
+ app50.route("/api/whatsapp-reader", whatsapp_reader_default);
19240
+ app50.route("/api/public-reader", public_reader_default);
19241
+ app50.route("/api/webchat", createWebchatRoutes({ handleInbound: (input) => webchatGateway.handleInbound(input) }));
19242
+ app50.route("/api/webchat/greeting", webchat_greeting_default);
19243
+ app50.route("/api/telegram", telegram_default);
19244
+ app50.route("/api/onboarding", onboarding_default);
19245
+ app50.route("/api/admin", admin_default);
19246
+ app50.route("/api/access", access_default);
19247
+ app50.route("/api/session", session_default2);
19050
19248
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
19051
19249
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
19052
19250
  var IMAGE_MIME = {
@@ -19058,7 +19256,7 @@ var IMAGE_MIME = {
19058
19256
  ".svg": "image/svg+xml",
19059
19257
  ".ico": "image/x-icon"
19060
19258
  };
19061
- app49.get("/agent-assets/:slug/:filename", (c) => {
19259
+ app50.get("/agent-assets/:slug/:filename", (c) => {
19062
19260
  const slug = c.req.param("slug");
19063
19261
  const filename = c.req.param("filename");
19064
19262
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -19074,8 +19272,8 @@ app49.get("/agent-assets/:slug/:filename", (c) => {
19074
19272
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
19075
19273
  return c.text("Not found", 404);
19076
19274
  }
19077
- const filePath = resolve30(account.accountDir, "agents", slug, "assets", filename);
19078
- const expectedDir = resolve30(account.accountDir, "agents", slug, "assets");
19275
+ const filePath = resolve31(account.accountDir, "agents", slug, "assets", filename);
19276
+ const expectedDir = resolve31(account.accountDir, "agents", slug, "assets");
19079
19277
  if (!filePath.startsWith(expectedDir + "/")) {
19080
19278
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
19081
19279
  return c.text("Forbidden", 403);
@@ -19093,7 +19291,7 @@ app49.get("/agent-assets/:slug/:filename", (c) => {
19093
19291
  "Cache-Control": "public, max-age=3600"
19094
19292
  });
19095
19293
  });
19096
- app49.get("/generated/:filename", (c) => {
19294
+ app50.get("/generated/:filename", (c) => {
19097
19295
  const filename = c.req.param("filename");
19098
19296
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
19099
19297
  console.error(`[generated] serve file=${filename} status=403`);
@@ -19104,8 +19302,8 @@ app49.get("/generated/:filename", (c) => {
19104
19302
  console.error(`[generated] serve file=${filename} status=404`);
19105
19303
  return c.text("Not found", 404);
19106
19304
  }
19107
- const filePath = resolve30(account.accountDir, "generated", filename);
19108
- const expectedDir = resolve30(account.accountDir, "generated");
19305
+ const filePath = resolve31(account.accountDir, "generated", filename);
19306
+ const expectedDir = resolve31(account.accountDir, "generated");
19109
19307
  if (!filePath.startsWith(expectedDir + "/")) {
19110
19308
  console.error(`[generated] serve file=${filename} status=403`);
19111
19309
  return c.text("Forbidden", 403);
@@ -19123,10 +19321,10 @@ app49.get("/generated/:filename", (c) => {
19123
19321
  "Cache-Control": "public, max-age=86400"
19124
19322
  });
19125
19323
  });
19126
- app49.route("/sites", sites_default);
19127
- app49.route("/listings", listings_default);
19128
- app49.route("/v", visitor_event_default);
19129
- app49.route("/v", visitor_consent_default);
19324
+ app50.route("/sites", sites_default);
19325
+ app50.route("/listings", listings_default);
19326
+ app50.route("/v", visitor_event_default);
19327
+ app50.route("/v", visitor_consent_default);
19130
19328
  var htmlCache = /* @__PURE__ */ new Map();
19131
19329
  var brandLogoPath = "/brand/maxy-monochrome.png";
19132
19330
  var brandIconPath = "/brand/maxy-monochrome.png";
@@ -19148,11 +19346,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
19148
19346
  })}</script>`;
19149
19347
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
19150
19348
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
19151
- var brandIconFsPath = resolve30(process.cwd(), "public", brandIconPath.replace(/^\//, ""));
19349
+ var brandIconFsPath = resolve31(process.cwd(), "public", brandIconPath.replace(/^\//, ""));
19152
19350
  var brandIconExists = existsSync28(brandIconFsPath);
19153
19351
  var SW_SOURCE = (() => {
19154
19352
  try {
19155
- return readFileSync27(resolve30(process.cwd(), "public", "sw.js"), "utf-8");
19353
+ return readFileSync27(resolve31(process.cwd(), "public", "sw.js"), "utf-8");
19156
19354
  } catch {
19157
19355
  return null;
19158
19356
  }
@@ -19160,7 +19358,7 @@ var SW_SOURCE = (() => {
19160
19358
  function readInstalledVersion() {
19161
19359
  try {
19162
19360
  if (!PLATFORM_ROOT8) return "unknown";
19163
- const versionFile = join24(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
19361
+ const versionFile = join25(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
19164
19362
  if (!existsSync28(versionFile)) return "unknown";
19165
19363
  const content = readFileSync27(versionFile, "utf-8").trim();
19166
19364
  return content || "unknown";
@@ -19203,7 +19401,7 @@ var clientErrorReporterScript = `<script>
19203
19401
  function cachedHtml(file) {
19204
19402
  let html = htmlCache.get(file);
19205
19403
  if (!html) {
19206
- html = readFileSync27(resolve30(process.cwd(), "public", file), "utf-8");
19404
+ html = readFileSync27(resolve31(process.cwd(), "public", file), "utf-8");
19207
19405
  const productNameEsc = escapeHtml(BRAND.productName);
19208
19406
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
19209
19407
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -19221,11 +19419,11 @@ ${clientErrorReporterScript}
19221
19419
  }
19222
19420
  var brandedHtmlCache = /* @__PURE__ */ new Map();
19223
19421
  function loadBrandingCache(agentSlug) {
19224
- const configDir2 = join24(homedir3(), BRAND.configDir);
19422
+ const configDir2 = join25(homedir3(), BRAND.configDir);
19225
19423
  try {
19226
19424
  const accountId = getDefaultAccountId();
19227
19425
  if (!accountId) return null;
19228
- const cachePath = join24(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
19426
+ const cachePath = join25(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
19229
19427
  if (!existsSync28(cachePath)) return null;
19230
19428
  return JSON.parse(readFileSync27(cachePath, "utf-8"));
19231
19429
  } catch {
@@ -19237,6 +19435,9 @@ function resolveDefaultSlug() {
19237
19435
  if (!account) return null;
19238
19436
  return resolveDefaultAgentSlug(account.accountDir);
19239
19437
  }
19438
+ function wantsNextSurface(c) {
19439
+ return c.req.query("surface") === "next";
19440
+ }
19240
19441
  function brandedPublicHtml(agentSlug) {
19241
19442
  const baseHtml = cachedHtml("public.html");
19242
19443
  if (!agentSlug) return baseHtml;
@@ -19270,7 +19471,7 @@ function escapeHtml(s) {
19270
19471
  function agentUnavailableHtml() {
19271
19472
  return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${escapeHtml(BRAND.productName)}</title></head><body style="font-family:system-ui,sans-serif;max-width:32rem;margin:4rem auto;padding:0 1.5rem;color:#222"><h1 style="font-size:1.25rem">Agent unavailable</h1><p>This agent isn't available right now. If you reached this page from a saved link, the agent may have been turned off.</p></body></html>`;
19272
19473
  }
19273
- app49.get("/", (c) => {
19474
+ app50.get("/", (c) => {
19274
19475
  const host = (c.req.header("host") ?? "").split(":")[0];
19275
19476
  const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
19276
19477
  if (klass === "operator") {
@@ -19287,19 +19488,22 @@ app49.get("/", (c) => {
19287
19488
  );
19288
19489
  }
19289
19490
  console.error(`[public-root] op=serve-default slug=${defaultSlug}`);
19491
+ if (wantsNextSurface(c)) return c.html(cachedHtml("public-next.html"));
19290
19492
  return c.html(brandedPublicHtml(defaultSlug));
19291
19493
  }
19292
19494
  console.log(`[host-class] host=${host} class=admin served=index.html`);
19293
19495
  return c.html(cachedHtml("index.html"));
19294
19496
  });
19295
- app49.get("/public", (c) => {
19497
+ app50.get("/public", (c) => {
19296
19498
  const host = (c.req.header("host") ?? "").split(":")[0];
19297
19499
  if (isPublicHost(host)) return c.text("Not found", 404);
19500
+ if (wantsNextSurface(c)) return c.html(cachedHtml("public-next.html"));
19298
19501
  return c.html(cachedHtml("public.html"));
19299
19502
  });
19300
- app49.get("/public-chat", (c) => {
19503
+ app50.get("/public-chat", (c) => {
19301
19504
  const host = (c.req.header("host") ?? "").split(":")[0];
19302
19505
  if (isPublicHost(host)) return c.text("Not found", 404);
19506
+ if (wantsNextSurface(c)) return c.html(cachedHtml("public-next.html"));
19303
19507
  return c.html(cachedHtml("public.html"));
19304
19508
  });
19305
19509
  async function logViewerFetch(c, next) {
@@ -19316,12 +19520,12 @@ async function logViewerFetch(c, next) {
19316
19520
  duration_ms: Date.now() - start
19317
19521
  });
19318
19522
  }
19319
- app49.use("/vnc-viewer.html", logViewerFetch);
19320
- app49.use("/vnc-popout.html", logViewerFetch);
19321
- app49.get("/vnc-popout.html", (c) => {
19523
+ app50.use("/vnc-viewer.html", logViewerFetch);
19524
+ app50.use("/vnc-popout.html", logViewerFetch);
19525
+ app50.get("/vnc-popout.html", (c) => {
19322
19526
  let html = htmlCache.get("vnc-popout.html");
19323
19527
  if (!html) {
19324
- html = readFileSync27(resolve30(process.cwd(), "public", "vnc-popout.html"), "utf-8");
19528
+ html = readFileSync27(resolve31(process.cwd(), "public", "vnc-popout.html"), "utf-8");
19325
19529
  const name = escapeHtml(BRAND.productName);
19326
19530
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
19327
19531
  html = html.replace("</head>", ` ${brandScript}
@@ -19331,7 +19535,7 @@ app49.get("/vnc-popout.html", (c) => {
19331
19535
  }
19332
19536
  return c.html(html);
19333
19537
  });
19334
- app49.post("/api/vnc/client-event", async (c) => {
19538
+ app50.post("/api/vnc/client-event", async (c) => {
19335
19539
  let body;
19336
19540
  try {
19337
19541
  body = await c.req.json();
@@ -19352,11 +19556,11 @@ app49.post("/api/vnc/client-event", async (c) => {
19352
19556
  });
19353
19557
  return c.json({ ok: true });
19354
19558
  });
19355
- app49.get("/g/:slug", (c) => {
19559
+ app50.get("/g/:slug", (c) => {
19356
19560
  return c.html(brandedPublicHtml());
19357
19561
  });
19358
19562
  for (const pwa of PWA_SURFACES) {
19359
- app49.get(pwa.manifestPath, (c) => {
19563
+ app50.get(pwa.manifestPath, (c) => {
19360
19564
  const manifest = buildManifest(pwa, {
19361
19565
  productName: BRAND.productName,
19362
19566
  iconPath: brandIconPath,
@@ -19370,7 +19574,7 @@ for (const pwa of PWA_SURFACES) {
19370
19574
  return c.body(JSON.stringify(manifest));
19371
19575
  });
19372
19576
  }
19373
- app49.get("/sw.js", (c) => {
19577
+ app50.get("/sw.js", (c) => {
19374
19578
  if (SW_SOURCE == null) {
19375
19579
  console.error("[pwa] op=sw status=500 reason=sw-source-missing");
19376
19580
  return c.text("Service worker unavailable", 500);
@@ -19379,27 +19583,27 @@ app49.get("/sw.js", (c) => {
19379
19583
  console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
19380
19584
  return c.body(SW_SOURCE);
19381
19585
  });
19382
- app49.get("/graph", (c) => {
19586
+ app50.get("/graph", (c) => {
19383
19587
  const host = (c.req.header("host") ?? "").split(":")[0];
19384
19588
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
19385
19589
  return c.html(cachedHtml("graph.html"));
19386
19590
  });
19387
- app49.get("/chat", (c) => {
19591
+ app50.get("/chat", (c) => {
19388
19592
  const host = (c.req.header("host") ?? "").split(":")[0];
19389
19593
  if (isPublicHost(host)) return c.text("Not found", 404);
19390
19594
  return c.html(cachedHtml("chat.html"));
19391
19595
  });
19392
- app49.get("/data", (c) => {
19596
+ app50.get("/data", (c) => {
19393
19597
  const host = (c.req.header("host") ?? "").split(":")[0];
19394
19598
  if (isPublicHost(host)) return c.text("Not found", 404);
19395
19599
  return c.html(cachedHtml("data.html"));
19396
19600
  });
19397
- app49.get("/browser", (c) => {
19601
+ app50.get("/browser", (c) => {
19398
19602
  const host = (c.req.header("host") ?? "").split(":")[0];
19399
19603
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
19400
19604
  return c.html(cachedHtml("browser.html"));
19401
19605
  });
19402
- app49.get("/:slug", async (c, next) => {
19606
+ app50.get("/:slug", async (c, next) => {
19403
19607
  const slug = c.req.param("slug");
19404
19608
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
19405
19609
  const account = resolveAccount();
@@ -19409,18 +19613,19 @@ app49.get("/:slug", async (c, next) => {
19409
19613
  }
19410
19614
  const branding = loadBrandingCache(slug);
19411
19615
  console.error(`[public-catchall] served path=/${slug} slug=${slug} branding=${branding ? "hit" : "miss"}`);
19616
+ if (wantsNextSurface(c)) return c.html(cachedHtml("public-next.html"));
19412
19617
  return c.html(brandedPublicHtml(slug));
19413
19618
  }
19414
19619
  await next();
19415
19620
  });
19416
19621
  if (brandFaviconPath !== "/favicon.ico") {
19417
- app49.get("/favicon.ico", (c) => {
19622
+ app50.get("/favicon.ico", (c) => {
19418
19623
  c.header("Cache-Control", "public, max-age=300");
19419
19624
  return c.redirect(brandFaviconPath, 302);
19420
19625
  });
19421
19626
  }
19422
- app49.use("/*", serveStatic({ root: "./public" }));
19423
- app49.all("*", (c) => {
19627
+ app50.use("/*", serveStatic({ root: "./public" }));
19628
+ app50.all("*", (c) => {
19424
19629
  const host = (c.req.header("host") ?? "").split(":")[0];
19425
19630
  const path2 = c.req.path;
19426
19631
  if (isPublicHost(host)) {
@@ -19434,7 +19639,7 @@ app49.all("*", (c) => {
19434
19639
  });
19435
19640
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
19436
19641
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
19437
- var httpServer = serve({ fetch: app49.fetch, port, hostname });
19642
+ var httpServer = serve({ fetch: app50.fetch, port, hostname });
19438
19643
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
19439
19644
  {
19440
19645
  const census = pwaCensus({
@@ -19488,7 +19693,7 @@ for (const m of SUBAPP_MANIFEST) {
19488
19693
  }
19489
19694
  try {
19490
19695
  const registered = [];
19491
- for (const r of app49.routes ?? []) {
19696
+ for (const r of app50.routes ?? []) {
19492
19697
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
19493
19698
  if (AGENT_SLUG_PATTERN.test(r.path)) {
19494
19699
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -19583,7 +19788,7 @@ try {
19583
19788
  } catch (err) {
19584
19789
  console.error(`[graph-health] account-enumeration unavailable reason=${err instanceof Error ? err.message : String(err)}`);
19585
19790
  }
19586
- var configDirForWhatsApp = basename8(MAXY_DIR) || ".maxy";
19791
+ var configDirForWhatsApp = basename9(MAXY_DIR) || ".maxy";
19587
19792
  var bootAccount = resolveAccount();
19588
19793
  if (bootAccount) {
19589
19794
  migrateRemovedConfigKeys(bootAccount.accountDir);
@@ -19645,7 +19850,7 @@ if (bootAccountConfig?.whatsapp) {
19645
19850
  }
19646
19851
  init({
19647
19852
  configDir: configDirForWhatsApp,
19648
- platformRoot: resolve30(process.env.MAXY_PLATFORM_ROOT ?? join24(__dirname, "..")),
19853
+ platformRoot: resolve31(process.env.MAXY_PLATFORM_ROOT ?? join25(__dirname, "..")),
19649
19854
  accountConfig: bootAccountConfig,
19650
19855
  onMessage: async (msg) => {
19651
19856
  if (msg.isOwnerMirror) {