@rubytech/create-maxy-code 0.1.308 → 0.1.310

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 (199) 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/admin/skills/plugin-management/SKILL.md +1 -1
  20. package/payload/platform/plugins/admin/skills/specialist-management/SKILL.md +1 -1
  21. package/payload/platform/plugins/cloudflare/skills/cloudflare/SKILL.md +1 -1
  22. package/payload/platform/plugins/docs/references/admin-ui.md +20 -0
  23. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +2 -0
  24. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  25. package/payload/platform/services/claude-session-manager/dist/http-server.js +50 -0
  26. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  27. package/payload/platform/services/webchat-channel/dist/instructions.d.ts +1 -0
  28. package/payload/platform/services/webchat-channel/dist/instructions.d.ts.map +1 -1
  29. package/payload/platform/services/webchat-channel/dist/instructions.js +31 -0
  30. package/payload/platform/services/webchat-channel/dist/instructions.js.map +1 -1
  31. package/payload/platform/services/webchat-channel/dist/notification.d.ts +8 -3
  32. package/payload/platform/services/webchat-channel/dist/notification.d.ts.map +1 -1
  33. package/payload/platform/services/webchat-channel/dist/notification.js +25 -9
  34. package/payload/platform/services/webchat-channel/dist/notification.js.map +1 -1
  35. package/payload/platform/services/webchat-channel/dist/server.d.ts.map +1 -1
  36. package/payload/platform/services/webchat-channel/dist/server.js +5 -3
  37. package/payload/platform/services/webchat-channel/dist/server.js.map +1 -1
  38. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +8 -0
  39. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
  40. package/payload/platform/services/whatsapp-channel/dist/notification.js +10 -0
  41. package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
  42. package/payload/server/{chunk-FBGIHWWM.js → chunk-J6WDAWFJ.js} +20 -0
  43. package/payload/server/maxy-edge.js +1 -1
  44. package/payload/server/public/assets/AccessGate-BOqUU-za.js +1 -0
  45. package/payload/server/public/assets/AdminLoginScreens-WvRuaNIg.js +1 -0
  46. package/payload/server/public/assets/AdminShell-DHv6_SZ4.js +1 -0
  47. package/payload/server/public/assets/{Checkbox-8elc7oXU.js → Checkbox-DjM6aYP_.js} +1 -1
  48. package/payload/server/public/assets/OperatorConversations-CDY0jUMb.js +1 -0
  49. package/payload/server/public/assets/admin-XbVTsU2q.js +1 -0
  50. package/payload/server/public/assets/admin-types-D2qTXuCg.js +1 -0
  51. package/payload/server/public/assets/{arc-DxSm8tli.js → arc-J2g2u5Xv.js} +1 -1
  52. package/payload/server/public/assets/architecture-YZFGNWBL-C6nkAxzW.js +1 -0
  53. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-7JSAh0vL.js → architectureDiagram-Q4EWVU46-CN0BXxpE.js} +1 -1
  54. package/payload/server/public/assets/audio-attachment-mime-CVxjPN8V.js +30 -0
  55. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DLoVmHKD.js → blockDiagram-DXYQGD6D-HX-8wF2p.js} +1 -1
  56. package/payload/server/public/assets/brand-N-Hi3IPA.css +1 -0
  57. package/payload/server/public/assets/{brand-Dh5UlVO2.js → brand-zL3tAdql.js} +1 -1
  58. package/payload/server/public/assets/browser-Ct5Kwlmk.js +1 -0
  59. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-Nv1G0o9P.js → c4Diagram-AHTNJAMY-wIuarKF5.js} +1 -1
  60. package/payload/server/public/assets/channel-Q39xIXyT.js +1 -0
  61. package/payload/server/public/assets/chat-CEde1CLX.js +1 -0
  62. package/payload/server/public/assets/{chunk-2KRD3SAO-BpqPMhoA.js → chunk-2KRD3SAO-Buz7egJZ.js} +1 -1
  63. package/payload/server/public/assets/{chunk-336JU56O-DgXHlVU_.js → chunk-336JU56O-_JcFXJqc.js} +2 -2
  64. package/payload/server/public/assets/chunk-426QAEUC-CCYjp9C2.js +1 -0
  65. package/payload/server/public/assets/{chunk-4BX2VUAB-nwyZSZH8.js → chunk-4BX2VUAB-DUR5Dg3M.js} +1 -1
  66. package/payload/server/public/assets/{chunk-4TB4RGXK-Tfxz9LHX.js → chunk-4TB4RGXK-BRIqQ9st.js} +1 -1
  67. package/payload/server/public/assets/{chunk-55IACEB6-6FMJQGXG.js → chunk-55IACEB6-CezTHWXL.js} +1 -1
  68. package/payload/server/public/assets/{chunk-5FUZZQ4R-g2FgZF3D.js → chunk-5FUZZQ4R-DHYUPzF1.js} +1 -1
  69. package/payload/server/public/assets/{chunk-5PVQY5BW-DtLwXsPH.js → chunk-5PVQY5BW-BVn4_fI5.js} +1 -1
  70. package/payload/server/public/assets/{chunk-67CJDMHE-K91CP5ZU.js → chunk-67CJDMHE-BBLA8Mbi.js} +1 -1
  71. package/payload/server/public/assets/{chunk-7N4EOEYR-BGpCQhqK.js → chunk-7N4EOEYR-CdWfEI5c.js} +1 -1
  72. package/payload/server/public/assets/{chunk-AA7GKIK3-jkDbInck.js → chunk-AA7GKIK3-tS11knCR.js} +1 -1
  73. package/payload/server/public/assets/{chunk-BSJP7CBP-mDosdzGs.js → chunk-BSJP7CBP-GEu1OOZ6.js} +1 -1
  74. package/payload/server/public/assets/{chunk-CIAEETIT-DhBxewpQ.js → chunk-CIAEETIT-DKrNbbp_.js} +1 -1
  75. package/payload/server/public/assets/{chunk-EDXVE4YY-B7c-9Emg.js → chunk-EDXVE4YY-B0InXNyr.js} +1 -1
  76. package/payload/server/public/assets/{chunk-ENJZ2VHE-Cqhhncox.js → chunk-ENJZ2VHE-CO7lkHdm.js} +1 -1
  77. package/payload/server/public/assets/{chunk-FMBD7UC4-BpDq6wj1.js → chunk-FMBD7UC4-CMj74lWo.js} +1 -1
  78. package/payload/server/public/assets/{chunk-FOC6F5B3-Ds02-ktu.js → chunk-FOC6F5B3-CLnKQoXw.js} +1 -1
  79. package/payload/server/public/assets/{chunk-ICPOFSXX-BTX5POFr.js → chunk-ICPOFSXX-CdiEKIaz.js} +2 -2
  80. package/payload/server/public/assets/{chunk-K5T4RW27-Du1PXXBU.js → chunk-K5T4RW27-B6LA3fiv.js} +1 -1
  81. package/payload/server/public/assets/{chunk-KGLVRYIC-siasOAf8.js → chunk-KGLVRYIC-DrhRrb8Q.js} +1 -1
  82. package/payload/server/public/assets/{chunk-LIHQZDEY-xf1rbZtf.js → chunk-LIHQZDEY-DVQukevB.js} +1 -1
  83. package/payload/server/public/assets/{chunk-ORNJ4GCN-DeTLQ_LD.js → chunk-ORNJ4GCN-ZMLkoDhP.js} +1 -1
  84. package/payload/server/public/assets/{chunk-OYMX7WX6-DQ7_oVJn.js → chunk-OYMX7WX6-C0dJkynG.js} +1 -1
  85. package/payload/server/public/assets/chunk-QZHKN3VN-BNBxnHZh.js +1 -0
  86. package/payload/server/public/assets/{chunk-U2HBQHQK-CXmFUKgn.js → chunk-U2HBQHQK-BQ9BPIFZ.js} +1 -1
  87. package/payload/server/public/assets/{chunk-X2U36JSP-Bj8-8Wkz.js → chunk-X2U36JSP-CAonGMOd.js} +1 -1
  88. package/payload/server/public/assets/{chunk-XPW4576I-Con3TXqt.js → chunk-XPW4576I-D5C_WNlk.js} +1 -1
  89. package/payload/server/public/assets/{chunk-YZCP3GAM-Dx8BHGWf.js → chunk-YZCP3GAM-Ecdvzekb.js} +1 -1
  90. package/payload/server/public/assets/{chunk-ZZ45TVLE-Dp4Q5Y-f.js → chunk-ZZ45TVLE-BsFZd1cN.js} +1 -1
  91. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BShusfby.js +1 -0
  92. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-D4ivPLFF.js +1 -0
  93. package/payload/server/public/assets/clone-CjEM8LwB.js +1 -0
  94. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-pZiCv69E.js → cose-bilkent-S5V4N54A-DBWHaIwm.js} +1 -1
  95. package/payload/server/public/assets/{dagre-CLqhEgbL.js → dagre-Dr7ZJYeS.js} +1 -1
  96. package/payload/server/public/assets/{dagre-KV5264BT-BCxE8iyk.js → dagre-KV5264BT-oIJddk7m.js} +1 -1
  97. package/payload/server/public/assets/data-TZOmA1Qg.js +1 -0
  98. package/payload/server/public/assets/{diagram-5BDNPKRD-slUEdZzz.js → diagram-5BDNPKRD-CEVxqOZ4.js} +1 -1
  99. package/payload/server/public/assets/{diagram-G4DWMVQ6-DPcraMfu.js → diagram-G4DWMVQ6-BovF7Rjx.js} +1 -1
  100. package/payload/server/public/assets/{diagram-MMDJMWI5-DR6luhGK.js → diagram-MMDJMWI5-BhrF8zoF.js} +1 -1
  101. package/payload/server/public/assets/{diagram-TYMM5635-Jap1B4wA.js → diagram-TYMM5635-DCUYwxtR.js} +1 -1
  102. package/payload/server/public/assets/{dist-Dbh7HrZX.js → dist-DSsFp0Qd.js} +1 -1
  103. package/payload/server/public/assets/{erDiagram-SMLLAGMA-DJKUs2hO.js → erDiagram-SMLLAGMA-BS2-HdCg.js} +1 -1
  104. package/payload/server/public/assets/{flatten-Cl1Bc3dR.js → flatten-BZMXCpLh.js} +1 -1
  105. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-C8W-ZZ9W.js → flowDiagram-DWJPFMVM-BzSFLoea.js} +1 -1
  106. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-DYCX4Xu2.js → ganttDiagram-T4ZO3ILL-1-3QU7mT.js} +1 -1
  107. package/payload/server/public/assets/gitGraph-7Q5UKJZL-Btp3PwZh.js +1 -0
  108. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CZu_fpgS.js → gitGraphDiagram-UUTBAWPF-fTrJ35Wk.js} +1 -1
  109. package/payload/server/public/assets/{graph-DKSjcpmR.js → graph-DWT1rhy9.js} +2 -2
  110. package/payload/server/public/assets/{graph-labels-CVWPQgBV.js → graph-labels-OBadNo54.js} +1 -1
  111. package/payload/server/public/assets/{graphlib-Bdp7TA4y.js → graphlib-rlEzI2qD.js} +1 -1
  112. package/payload/server/public/assets/info-OMHHGYJF-CPt2y6_L.js +1 -0
  113. package/payload/server/public/assets/infoDiagram-42DDH7IO-CpXNTMgd.js +2 -0
  114. package/payload/server/public/assets/{isEmpty-D1pGOD1J.js → isEmpty-DaYIrHay.js} +1 -1
  115. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-B7KfIX6z.js → ishikawaDiagram-UXIWVN3A-0eU_UtlT.js} +1 -1
  116. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CSDwBfhF.js → journeyDiagram-VCZTEJTY-BKLeZohp.js} +1 -1
  117. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-CWzcEKTr.js → kanban-definition-6JOO6SKY-Dq72xyaN.js} +1 -1
  118. package/payload/server/public/assets/{line-BNQSlbYn.js → line-LQhmDT8k.js} +1 -1
  119. package/payload/server/public/assets/{linear-BN6kGN93.js → linear-BGotDbGs.js} +1 -1
  120. package/payload/server/public/assets/{mermaid-parser.core-CcFhkElq.js → mermaid-parser.core-DoLdho1V.js} +2 -2
  121. package/payload/server/public/assets/{mermaid.core-BsIeJ7Cc.js → mermaid.core-C1RRyHGm.js} +3 -3
  122. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CQVzj6D_.js → mindmap-definition-QFDTVHPH-vUVVVyV1.js} +1 -1
  123. package/payload/server/public/assets/operator-BpzQ9Ezb.js +1 -0
  124. package/payload/server/public/assets/{ordinal-CBZeH4Yp.js → ordinal-BqEhkPyh.js} +1 -1
  125. package/payload/server/public/assets/packet-4T2RLAQJ-Cwc-j_AI.js +1 -0
  126. package/payload/server/public/assets/page-Dts8u8MD.js +1 -0
  127. package/payload/server/public/assets/pie-ZZUOXDRM-BZ9fjD1_.js +1 -0
  128. package/payload/server/public/assets/{pieDiagram-DEJITSTG-DnrQ9fyn.js → pieDiagram-DEJITSTG-B9Pl6Qhc.js} +1 -1
  129. package/payload/server/public/assets/public-next-ClQwtyeC.js +1 -0
  130. package/payload/server/public/assets/public-owWW-MIA.js +6 -0
  131. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-BQWlCyWi.js → quadrantDiagram-34T5L4WZ-Drn9T81A.js} +1 -1
  132. package/payload/server/public/assets/radar-PYXPWWZC-BNz5Rt9V.js +1 -0
  133. package/payload/server/public/assets/{reduce-PuPlFPRX.js → reduce-T2IuntYP.js} +1 -1
  134. package/payload/server/public/assets/{requirementDiagram-MS252O5E-Du_vZhU1.js → requirementDiagram-MS252O5E-C0PAItJm.js} +1 -1
  135. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-Cf6Z8GPQ.js → sankeyDiagram-XADWPNL6-BR42Mtwd.js} +1 -1
  136. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-CS8GVol8.js → sequenceDiagram-FGHM5R23-c2lR9UOS.js} +1 -1
  137. package/payload/server/public/assets/{src-BoaldmnP.js → src-DXUM2BJo.js} +1 -1
  138. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-Bv1NW2F1.js → stateDiagram-FHFEXIEX-BcHhtqsZ.js} +1 -1
  139. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BUQ_F4eP.js +1 -0
  140. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-ClGYAsr0.js → timeline-definition-GMOUNBTQ-Ax32c10H.js} +1 -1
  141. package/payload/server/public/assets/treeView-SZITEDCU-DcVCQgp1.js +1 -0
  142. package/payload/server/public/assets/treemap-W4RFUUIX-Bm12mwGd.js +1 -0
  143. package/payload/server/public/assets/{useSelectionMode-FIodJKzS.js → useSelectionMode-BZsJuUm-.js} +1 -1
  144. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-C2wTcxQT.js → vennDiagram-DHZGUBPP-BxePewPq.js} +1 -1
  145. package/payload/server/public/assets/wardley-RL74JXVD-47Z3ymtK.js +1 -0
  146. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-D86-ivEx.js → wardleyDiagram-NUSXRM2D-DmJwZ2f5.js} +1 -1
  147. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-Ba5WAN8P.js → xychartDiagram-5P7HB3ND-YjHomudv.js} +1 -1
  148. package/payload/server/public/browser.html +8 -8
  149. package/payload/server/public/chat.html +12 -11
  150. package/payload/server/public/data.html +7 -7
  151. package/payload/server/public/graph.html +10 -10
  152. package/payload/server/public/index.html +11 -10
  153. package/payload/server/public/operator.html +14 -13
  154. package/payload/server/public/public-next.html +25 -0
  155. package/payload/server/public/public.html +9 -8
  156. package/payload/server/server.js +890 -641
  157. package/dist/__tests__/onboarding-state-readback.test.js +0 -61
  158. package/dist/__tests__/rss-sampler-installer.test.js +0 -27
  159. package/dist/onboarding-readback.js +0 -27
  160. package/payload/server/public/assets/AdminLoginScreens-BZIA9Z6o.js +0 -1
  161. package/payload/server/public/assets/AdminShell-iazLHsk7.js +0 -1
  162. package/payload/server/public/assets/admin-BEx6o3fa.js +0 -1
  163. package/payload/server/public/assets/architecture-YZFGNWBL-6g9jRVgc.js +0 -1
  164. package/payload/server/public/assets/audio-attachment-mime-DzbKNqbH.js +0 -30
  165. package/payload/server/public/assets/brand-CmMZe4RK.css +0 -1
  166. package/payload/server/public/assets/browser-D16sPVkI.js +0 -1
  167. package/payload/server/public/assets/channel-BgQLJanG.js +0 -1
  168. package/payload/server/public/assets/chat-x4PnXhkd.js +0 -1
  169. package/payload/server/public/assets/chunk-426QAEUC-Dr_XVuUq.js +0 -1
  170. package/payload/server/public/assets/chunk-QZHKN3VN-DF4o9HRJ.js +0 -1
  171. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DAbPKU6u.js +0 -1
  172. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BKuFQLcv.js +0 -1
  173. package/payload/server/public/assets/clone-DnNHGhNe.js +0 -1
  174. package/payload/server/public/assets/data-DqG45sq0.js +0 -1
  175. package/payload/server/public/assets/file-download-BvGS7Qmi.js +0 -1
  176. package/payload/server/public/assets/gitGraph-7Q5UKJZL-g7mvu6IY.js +0 -1
  177. package/payload/server/public/assets/info-OMHHGYJF-DZqJuIkB.js +0 -1
  178. package/payload/server/public/assets/infoDiagram-42DDH7IO-cGfGccHz.js +0 -2
  179. package/payload/server/public/assets/operator-Cnzbhdh2.js +0 -1
  180. package/payload/server/public/assets/packet-4T2RLAQJ-Hn8rlHpy.js +0 -1
  181. package/payload/server/public/assets/page-CH8JQkQN.js +0 -1
  182. package/payload/server/public/assets/pie-ZZUOXDRM-BPGWVqBm.js +0 -1
  183. package/payload/server/public/assets/public-CA90VhI9.js +0 -6
  184. package/payload/server/public/assets/radar-PYXPWWZC-DMdLrj3E.js +0 -1
  185. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BGUCxPmp.js +0 -1
  186. package/payload/server/public/assets/treeView-SZITEDCU-CWxofUbI.js +0 -1
  187. package/payload/server/public/assets/treemap-W4RFUUIX-Cfgb_ZG0.js +0 -1
  188. package/payload/server/public/assets/wardley-RL74JXVD-B45olYjj.js +0 -1
  189. /package/payload/server/public/assets/{file-download-qc_xy7Az.css → OperatorConversations-qc_xy7Az.css} +0 -0
  190. /package/payload/server/public/assets/{_baseFor-brRjpUOX.js → _baseFor-Y5mTRiRv.js} +0 -0
  191. /package/payload/server/public/assets/{array-BGFCBI0e.js → array-BwJyW1Dp.js} +0 -0
  192. /package/payload/server/public/assets/{chunk-Pqm5yXtL.js → chunk-CAM3fms7.js} +0 -0
  193. /package/payload/server/public/assets/{cytoscape.esm-TvRJ2tGX.js → cytoscape.esm-D95TtHqz.js} +0 -0
  194. /package/payload/server/public/assets/{defaultLocale-CRZydyG6.js → defaultLocale-kiwRz9Au.js} +0 -0
  195. /package/payload/server/public/assets/{init-B8gtcn7T.js → init-CKZirZ49.js} +0 -0
  196. /package/payload/server/public/assets/{katex-RxgSu_dy.js → katex-8mXVa4k3.js} +0 -0
  197. /package/payload/server/public/assets/{path-DZF-JdEe.js → path-B0d9ncVi.js} +0 -0
  198. /package/payload/server/public/assets/{preload-helper-CQ36nxok.js → preload-helper-C5gCWwwF.js} +0 -0
  199. /package/payload/server/public/assets/{rough.esm-6CnTHTkH.js → rough.esm-BWqoIFNR.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(
@@ -6590,6 +6591,28 @@ import { basename as basename2, dirname, join as join10, resolve as resolve11, s
6590
6591
  // server/routes/admin/sidebar-sessions.ts
6591
6592
  import { readdirSync as readdirSync4, readFileSync as readFileSync9, statSync as statSync2 } from "fs";
6592
6593
  import { join as join8, resolve as resolve10 } from "path";
6594
+
6595
+ // app/lib/whatsapp-reader/select-sessions.ts
6596
+ function isReaderChannelSession(role, channel) {
6597
+ return role === "admin" && (channel === "whatsapp" || channel === "telegram") || role === "public" && (channel === "whatsapp" || channel === "webchat");
6598
+ }
6599
+ function selectReaderChannelSessions(rows) {
6600
+ return rows.filter((r) => isReaderChannelSession(r.role, r.channel)).sort((a, b) => b.startedAt.localeCompare(a.startedAt)).map((r) => ({
6601
+ sessionId: r.sessionId,
6602
+ projectDir: r.projectDir,
6603
+ title: r.title,
6604
+ senderId: r.senderId,
6605
+ startedAt: r.startedAt,
6606
+ channel: r.channel,
6607
+ role: r.role,
6608
+ operatorName: null,
6609
+ whatsappName: null,
6610
+ lastMessageAt: r.lastMessageAt,
6611
+ modelGated: r.modelGated
6612
+ }));
6613
+ }
6614
+
6615
+ // server/routes/admin/sidebar-sessions.ts
6593
6616
  var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.jsonl$/i;
6594
6617
  var CLI_MARKER_PREFIXES = ["<local-command-", "<command-name>", "<command-message>"];
6595
6618
  var PUBLIC_ROLE = "public";
@@ -6815,6 +6838,7 @@ app3.get("/", requireAdminSession, async (c) => {
6815
6838
  let subagentCount = 0;
6816
6839
  let nonResumableCount = 0;
6817
6840
  let archivedCount = 0;
6841
+ let excludedChannelCount = 0;
6818
6842
  const titleSourceCounts = { user: 0, ai: 0, "first-message": 0, prefix: 0 };
6819
6843
  const personIdBySession = /* @__PURE__ */ new Map();
6820
6844
  const adminUserIdBySession = /* @__PURE__ */ new Map();
@@ -6842,6 +6866,10 @@ app3.get("/", requireAdminSession, async (c) => {
6842
6866
  titleSourceCounts[resolved.source] += 1;
6843
6867
  const metaPath = join8(projectDir, `${sessionId}.meta.json`);
6844
6868
  const { bridgeIds, role, channel: sidecarChannel, personId, adminUserId } = readSidecarMeta(metaPath);
6869
+ if (isReaderChannelSession(role, sidecarChannel)) {
6870
+ excludedChannelCount += 1;
6871
+ continue;
6872
+ }
6845
6873
  const resumable = !(role === PUBLIC_ROLE && (sidecarChannel === WEBCHAT_CHANNEL || sidecarChannel === WHATSAPP_CHANNEL));
6846
6874
  if (personId) personIdBySession.set(sessionId, personId);
6847
6875
  if (adminUserId && role === ADMIN_ROLE && sidecarChannel === WEBCHAT_CHANNEL) {
@@ -6895,29 +6923,12 @@ app3.get("/", requireAdminSession, async (c) => {
6895
6923
  }
6896
6924
  rows.sort((a, b) => a.startedAt < b.startedAt ? 1 : -1);
6897
6925
  console.log(
6898
- `[admin-sessions-list] rows=${rows.length} live=${liveCount} subagents=${subagentCount} archived=${archivedCount} nonResumable=${nonResumableCount} titles user=${titleSourceCounts.user} ai=${titleSourceCounts.ai} first=${titleSourceCounts["first-message"]} prefix=${titleSourceCounts.prefix} personNames=${personNameCount} adminNames=${adminNameCount} accountId=${accountId ? accountId.slice(0, 8) : "unset"}`
6926
+ `[admin-sessions-list] rows=${rows.length} live=${liveCount} subagents=${subagentCount} archived=${archivedCount} nonResumable=${nonResumableCount} excludedChannel=${excludedChannelCount} titles user=${titleSourceCounts.user} ai=${titleSourceCounts.ai} first=${titleSourceCounts["first-message"]} prefix=${titleSourceCounts.prefix} personNames=${personNameCount} adminNames=${adminNameCount} accountId=${accountId ? accountId.slice(0, 8) : "unset"}`
6899
6927
  );
6900
6928
  return c.json({ sessions: rows, accountId });
6901
6929
  });
6902
6930
  var sidebar_sessions_default = app3;
6903
6931
 
6904
- // app/lib/whatsapp-reader/select-sessions.ts
6905
- function selectReaderChannelSessions(rows) {
6906
- return rows.filter((r) => r.role === "admin" && (r.channel === "whatsapp" || r.channel === "telegram") || r.role === "public" && (r.channel === "whatsapp" || r.channel === "webchat")).sort((a, b) => b.startedAt.localeCompare(a.startedAt)).map((r) => ({
6907
- sessionId: r.sessionId,
6908
- projectDir: r.projectDir,
6909
- title: r.title,
6910
- senderId: r.senderId,
6911
- startedAt: r.startedAt,
6912
- channel: r.channel,
6913
- role: r.role,
6914
- operatorName: null,
6915
- whatsappName: null,
6916
- lastMessageAt: r.lastMessageAt,
6917
- modelGated: r.modelGated
6918
- }));
6919
- }
6920
-
6921
6932
  // app/lib/admin-identity/pin-validator.ts
6922
6933
  import { createHash } from "crypto";
6923
6934
  import { existsSync as existsSync6, readFileSync as readFileSync10, readdirSync as readdirSync5, statSync as statSync3 } from "fs";
@@ -7120,6 +7131,7 @@ function isModelGated(turns) {
7120
7131
  }
7121
7132
  function parseTranscript(lines) {
7122
7133
  const out = [];
7134
+ const queuedPendingSuppress = /* @__PURE__ */ new Map();
7123
7135
  for (const line of lines) {
7124
7136
  if (!line || line[0] !== "{") continue;
7125
7137
  let row;
@@ -7144,12 +7156,26 @@ function parseTranscript(lines) {
7144
7156
  out.push(...assistantTurns(msg?.content, ts));
7145
7157
  continue;
7146
7158
  }
7159
+ if (row.type === "queue-operation" && row.operation === "enqueue") {
7160
+ const content = asString(row.content);
7161
+ if (content !== null && CHANNEL_WRAPPER2.test(content)) {
7162
+ const u = unwrapChannel(content);
7163
+ out.push({ kind: "operator-inbound", text: u.text, ts, ...u.source ? { source: u.source } : {} });
7164
+ queuedPendingSuppress.set(u.text, (queuedPendingSuppress.get(u.text) ?? 0) + 1);
7165
+ }
7166
+ continue;
7167
+ }
7147
7168
  if (row.type === "attachment") {
7148
7169
  const att = row.attachment;
7149
7170
  const isChannelQueued = att?.type === "queued_command" && att.isMeta === true && typeof att.origin === "object" && att.origin !== null && att.origin.kind === "channel" && typeof att.prompt === "string";
7150
7171
  if (isChannelQueued) {
7151
7172
  const u = unwrapChannel(att.prompt);
7152
- out.push({ kind: "operator-inbound", text: u.text, ts, ...u.source ? { source: u.source } : {} });
7173
+ const armed = queuedPendingSuppress.get(u.text) ?? 0;
7174
+ if (armed > 0) {
7175
+ queuedPendingSuppress.set(u.text, armed - 1);
7176
+ } else {
7177
+ out.push({ kind: "operator-inbound", text: u.text, ts, ...u.source ? { source: u.source } : {} });
7178
+ }
7153
7179
  }
7154
7180
  continue;
7155
7181
  }
@@ -7207,9 +7233,7 @@ app4.get("/conversations", requireAdminSession, async (c) => {
7207
7233
  const sessionId = basename2(path2).replace(/\.jsonl$/, "");
7208
7234
  const projectDir = dirname(path2);
7209
7235
  const meta = readSidecarMeta(join10(projectDir, `${sessionId}.meta.json`));
7210
- const isAdminChannel = meta.role === "admin" && (meta.channel === "whatsapp" || meta.channel === "telegram");
7211
- const isPublicChannel = meta.role === "public" && (meta.channel === "whatsapp" || meta.channel === "webchat");
7212
- if (!isAdminChannel && !isPublicChannel) continue;
7236
+ if (!isReaderChannelSession(meta.role, meta.channel)) continue;
7213
7237
  let body = "";
7214
7238
  try {
7215
7239
  body = readFileSync11(path2, "utf8");
@@ -7442,18 +7466,202 @@ app4.get("/directive", requireAdminSession, (c) => {
7442
7466
  });
7443
7467
  var whatsapp_reader_default = app4;
7444
7468
 
7469
+ // server/routes/public-reader.ts
7470
+ import { statSync as statSync5, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, watch as watch2 } from "fs";
7471
+ import { basename as basename3, dirname as dirname2, join as join11, resolve as resolve12, sep as sep4 } from "path";
7472
+
7473
+ // app/lib/whatsapp-reader/delivered-kinds.ts
7474
+ var PUBLIC_DELIVERED_KINDS = /* @__PURE__ */ new Set([
7475
+ "operator-inbound",
7476
+ "agent-reply",
7477
+ "agent-reply-document",
7478
+ "agent-error"
7479
+ ]);
7480
+ function isDeliveredKind(kind, set) {
7481
+ return set.has(kind);
7482
+ }
7483
+
7484
+ // app/lib/public-reader/filter-delivered.ts
7485
+ function filterDeliveredFrames(lines) {
7486
+ const turns = [];
7487
+ let dropped = 0;
7488
+ for (const turn of parseTranscript(lines)) {
7489
+ if (!isDeliveredKind(turn.kind, PUBLIC_DELIVERED_KINDS)) {
7490
+ dropped++;
7491
+ continue;
7492
+ }
7493
+ turns.push(turn.kind === "agent-error" ? { ...turn, raw: "" } : turn);
7494
+ }
7495
+ return { turns, dropped };
7496
+ }
7497
+
7498
+ // app/lib/public-reader/resolve-visitor-session.ts
7499
+ function resolveVisitorSession(rows, visitorPersonId) {
7500
+ const matches = rows.filter(
7501
+ (r) => r.role === "public" && r.channel === "webchat" && r.personId === visitorPersonId
7502
+ );
7503
+ if (matches.length === 0) return null;
7504
+ return matches.reduce(
7505
+ (best, r) => (r.startedAt ?? "") > (best.startedAt ?? "") ? r : best
7506
+ );
7507
+ }
7508
+
7509
+ // server/routes/public-reader.ts
7510
+ var app5 = new Hono();
7511
+ var TAG20 = "[public-webchat]";
7512
+ function parseAccessSessionId(cookieHeader) {
7513
+ if (!cookieHeader) return null;
7514
+ const part = cookieHeader.split(";").map((p) => p.trim()).find((p) => p.startsWith("__access_session="));
7515
+ return part ? part.slice("__access_session=".length) : null;
7516
+ }
7517
+ function resolveVisitor(c) {
7518
+ const id = parseAccessSessionId(c.req.header("cookie"));
7519
+ const session = id ? getAccessSession(id) : null;
7520
+ return session && session.personId ? { personId: session.personId } : null;
7521
+ }
7522
+ function enumeratePublicRows() {
7523
+ const cfg = claudeConfigDir();
7524
+ if (!cfg) return [];
7525
+ const rows = [];
7526
+ for (const { path: path2 } of enumerateJsonls(join11(cfg, "projects"))) {
7527
+ const sessionId = basename3(path2).replace(/\.jsonl$/, "");
7528
+ const projectDir = dirname2(path2);
7529
+ const meta = readSidecarMeta(join11(projectDir, `${sessionId}.meta.json`));
7530
+ rows.push({
7531
+ sessionId,
7532
+ projectDir,
7533
+ role: meta.role,
7534
+ channel: meta.channel,
7535
+ personId: meta.personId,
7536
+ senderId: meta.senderId,
7537
+ startedAt: meta.startedAt
7538
+ });
7539
+ }
7540
+ return rows;
7541
+ }
7542
+ app5.get("/session", (c) => {
7543
+ const visitor = resolveVisitor(c);
7544
+ if (!visitor) {
7545
+ console.error(`${TAG20} op=reader-refused reason=no-grant path=/session`);
7546
+ return c.json({ error: "gate-required" }, 401);
7547
+ }
7548
+ const found = resolveVisitorSession(enumeratePublicRows(), visitor.personId);
7549
+ if (found) {
7550
+ console.log(`${TAG20} op=session-resume key=${(found.senderId ?? "").slice(0, 8)} sessionId=${found.sessionId.slice(0, 8)}`);
7551
+ return c.json({ sessionId: found.sessionId, projectDir: found.projectDir, sessionKey: found.senderId });
7552
+ }
7553
+ const sessionKey = crypto.randomUUID();
7554
+ console.log(`${TAG20} op=session-new key=${sessionKey.slice(0, 8)}`);
7555
+ return c.json({ sessionId: null, projectDir: null, sessionKey });
7556
+ });
7557
+ function readFrom2(path2, from) {
7558
+ const end = statSync5(path2).size;
7559
+ if (end <= from) return { buf: Buffer.alloc(0), end: from };
7560
+ const fd = openSync2(path2, "r");
7561
+ try {
7562
+ const buf = Buffer.alloc(end - from);
7563
+ readSync2(fd, buf, 0, buf.length, from);
7564
+ return { buf, end };
7565
+ } finally {
7566
+ closeSync2(fd);
7567
+ }
7568
+ }
7569
+ app5.get("/stream", (c) => {
7570
+ const visitor = resolveVisitor(c);
7571
+ if (!visitor) {
7572
+ console.error(`${TAG20} op=reader-refused reason=no-grant path=/stream`);
7573
+ return c.json({ error: "gate-required" }, 401);
7574
+ }
7575
+ const sessionId = c.req.query("sessionId") ?? "";
7576
+ const projectDir = c.req.query("projectDir") ?? "";
7577
+ const cfg = claudeConfigDir();
7578
+ const projectsRoot = cfg ? resolve12(join11(cfg, "projects")) : null;
7579
+ if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
7580
+ return c.json({ error: "bad session reference" }, 400);
7581
+ }
7582
+ const jsonlPath = resolve12(join11(projectDir, `${sessionId}.jsonl`));
7583
+ if (!jsonlPath.startsWith(projectsRoot + sep4)) {
7584
+ return c.json({ error: "bad session reference" }, 400);
7585
+ }
7586
+ const meta = readSidecarMeta(join11(projectDir, `${sessionId}.meta.json`));
7587
+ if (!(meta.role === "public" && meta.channel === "webchat" && meta.personId === visitor.personId)) {
7588
+ console.error(`${TAG20} op=reader-refused reason=not-owner sessionId=${sessionId.slice(0, 8)}`);
7589
+ return c.json({ error: "forbidden" }, 403);
7590
+ }
7591
+ const senderShort = (meta.senderId ?? "").slice(0, 8);
7592
+ const encoder = new TextEncoder();
7593
+ console.log(`${TAG20} op=reader-open key=${senderShort} mode=delivered-only sessionId=${sessionId.slice(0, 8)}`);
7594
+ const send = (controller, turn, id) => controller.enqueue(encoder.encode(`id: ${id}
7595
+ data: ${JSON.stringify(turn)}
7596
+
7597
+ `));
7598
+ const readable = new ReadableStream({
7599
+ start(controller) {
7600
+ let offset = 0;
7601
+ const emit = (lines) => {
7602
+ const { turns, dropped } = filterDeliveredFrames(lines);
7603
+ for (const turn of turns) send(controller, turn, offset);
7604
+ if (dropped > 0) console.log(`${TAG20} op=reader-filtered key=${senderShort} dropped=${dropped}`);
7605
+ };
7606
+ try {
7607
+ const { buf, end } = readFrom2(jsonlPath, 0);
7608
+ offset = end;
7609
+ emit(buf.toString("utf8").split("\n"));
7610
+ } catch {
7611
+ controller.enqueue(encoder.encode('event: error\ndata: "read-failed"\n\n'));
7612
+ }
7613
+ const drain = () => {
7614
+ try {
7615
+ const { buf, end } = readFrom2(jsonlPath, offset);
7616
+ if (end <= offset) return;
7617
+ const { lines, nextOffset } = splitNewLines(buf, offset);
7618
+ offset = nextOffset;
7619
+ emit(lines);
7620
+ } catch {
7621
+ }
7622
+ };
7623
+ let watcher = null;
7624
+ try {
7625
+ watcher = watch2(jsonlPath, drain);
7626
+ } catch {
7627
+ }
7628
+ const poll = setInterval(drain, 1e3);
7629
+ const heartbeat = setInterval(() => {
7630
+ try {
7631
+ controller.enqueue(encoder.encode(": ping\n\n"));
7632
+ } catch {
7633
+ }
7634
+ }, 2e4);
7635
+ c.req.raw.signal.addEventListener("abort", () => {
7636
+ watcher?.close();
7637
+ clearInterval(poll);
7638
+ clearInterval(heartbeat);
7639
+ console.log(`${TAG20} op=reader-close key=${senderShort}`);
7640
+ try {
7641
+ controller.close();
7642
+ } catch {
7643
+ }
7644
+ });
7645
+ }
7646
+ });
7647
+ return new Response(readable, {
7648
+ headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive" }
7649
+ });
7650
+ });
7651
+ var public_reader_default = app5;
7652
+
7445
7653
  // server/routes/webchat.ts
7446
- import { basename as basename3, dirname as dirname2 } from "path";
7447
- import { join as join12 } from "path";
7654
+ import { basename as basename4, dirname as dirname3 } from "path";
7655
+ import { join as join13 } from "path";
7448
7656
  import { existsSync as existsSync8, readdirSync as readdirSync7, readFileSync as readFileSync13, renameSync as renameSync2, writeFileSync as writeFileSync6 } from "fs";
7449
7657
 
7450
7658
  // server/canonical-webchat-override.ts
7451
7659
  import { readFileSync as readFileSync12, writeFileSync as writeFileSync5, renameSync } from "fs";
7452
- import { join as join11 } from "path";
7660
+ import { join as join12 } from "path";
7453
7661
  var FILE = "canonical-webchat-session.json";
7454
7662
  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
7663
  function canonicalOverridePath(accountDir) {
7456
- return join11(accountDir, FILE);
7664
+ return join12(accountDir, FILE);
7457
7665
  }
7458
7666
  function readCanonicalOverrideId(accountDir) {
7459
7667
  try {
@@ -7488,10 +7696,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
7696
  function locateSession(sessionId) {
7489
7697
  const cfg = claudeConfigDir();
7490
7698
  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`));
7699
+ for (const { path: path2 } of enumerateJsonls(join13(cfg, "projects"))) {
7700
+ if (basename4(path2) === `${sessionId}.jsonl`) {
7701
+ const dir = dirname3(path2);
7702
+ const meta = readSidecarMeta(join13(dir, `${sessionId}.meta.json`));
7495
7703
  return { projectDir: dir, channel: meta.channel };
7496
7704
  }
7497
7705
  }
@@ -7500,7 +7708,7 @@ function locateSession(sessionId) {
7500
7708
  function locateSidecar(sessionId) {
7501
7709
  const cfg = claudeConfigDir();
7502
7710
  if (!cfg) return null;
7503
- const projectsRoot = join12(cfg, "projects");
7711
+ const projectsRoot = join13(cfg, "projects");
7504
7712
  let slugs;
7505
7713
  try {
7506
7714
  slugs = readdirSync7(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
@@ -7508,7 +7716,7 @@ function locateSidecar(sessionId) {
7508
7716
  return null;
7509
7717
  }
7510
7718
  for (const slug of slugs) {
7511
- const metaPath = join12(projectsRoot, slug, `${sessionId}.meta.json`);
7719
+ const metaPath = join13(projectsRoot, slug, `${sessionId}.meta.json`);
7512
7720
  if (existsSync8(metaPath)) {
7513
7721
  return { channel: readSidecarMeta(metaPath).channel };
7514
7722
  }
@@ -7606,8 +7814,8 @@ async function reapplyLeversViaManager() {
7606
7814
  }
7607
7815
  }
7608
7816
  function createWebchatRoutes(deps) {
7609
- const app50 = new Hono();
7610
- app50.post("/send", requireAdminSession, async (c) => {
7817
+ const app51 = new Hono();
7818
+ app51.post("/send", requireAdminSession, async (c) => {
7611
7819
  let accountId;
7612
7820
  try {
7613
7821
  accountId = resolvePlatformAccountId();
@@ -7738,7 +7946,7 @@ ${note}` : note;
7738
7946
  }
7739
7947
  return c.json({ ok: true });
7740
7948
  });
7741
- app50.post("/settings", requireAdminSession, async (c) => {
7949
+ app51.post("/settings", requireAdminSession, async (c) => {
7742
7950
  const body = await c.req.json().catch(() => null);
7743
7951
  const op = body?.op;
7744
7952
  const value = body?.value;
@@ -7760,7 +7968,7 @@ ${note}` : note;
7760
7968
  console.error(`[webchat:settings] op=${op} outcome=refused value=${value} reason=account-unresolved`);
7761
7969
  return c.json({ error: "account unresolved" }, 503);
7762
7970
  }
7763
- const accountJsonPath = join12(account.accountDir, "account.json");
7971
+ const accountJsonPath = join13(account.accountDir, "account.json");
7764
7972
  try {
7765
7973
  const parsed = JSON.parse(readFileSync13(accountJsonPath, "utf8"));
7766
7974
  if (op === "model") parsed.adminModel = value;
@@ -7778,7 +7986,7 @@ ${note}` : note;
7778
7986
  console.log(`[webchat:settings] op=${op} outcome=accepted value=${value} settingsApplied=${settingsApplied}`);
7779
7987
  return c.json({ ok: true, settingsApplied });
7780
7988
  });
7781
- app50.get("/session", requireAdminSession, async (c) => {
7989
+ app51.get("/session", requireAdminSession, async (c) => {
7782
7990
  let accountId;
7783
7991
  try {
7784
7992
  accountId = resolvePlatformAccountId();
@@ -7807,9 +8015,9 @@ ${note}` : note;
7807
8015
  const cfg = claudeConfigDir();
7808
8016
  let projectDir = null;
7809
8017
  if (cfg) {
7810
- for (const { path: path2 } of enumerateJsonls(join12(cfg, "projects"))) {
7811
- if (basename3(path2) === `${sessionId}.jsonl`) {
7812
- projectDir = dirname2(path2);
8018
+ for (const { path: path2 } of enumerateJsonls(join13(cfg, "projects"))) {
8019
+ if (basename4(path2) === `${sessionId}.jsonl`) {
8020
+ projectDir = dirname3(path2);
7813
8021
  break;
7814
8022
  }
7815
8023
  }
@@ -7817,15 +8025,15 @@ ${note}` : note;
7817
8025
  const indicators = await fetchComposerIndicators(sessionId);
7818
8026
  return c.json({ sessionId, projectDir, ...indicators, ...readLevers(account) });
7819
8027
  });
7820
- return app50;
8028
+ return app51;
7821
8029
  }
7822
8030
 
7823
8031
  // server/routes/webchat-greeting.ts
7824
- import { resolve as resolve12 } from "path";
8032
+ import { resolve as resolve13 } from "path";
7825
8033
 
7826
8034
  // app/lib/claude-agent/specialist-roster.ts
7827
8035
  import { existsSync as existsSync9, readFileSync as readFileSync14, readdirSync as readdirSync8 } from "fs";
7828
- import { join as join13 } from "path";
8036
+ import { join as join14 } from "path";
7829
8037
  function field(fm, name) {
7830
8038
  const m = fm.match(new RegExp(`^${name}:\\s*(.*?)\\r?$`, "m"));
7831
8039
  if (!m) return null;
@@ -7844,7 +8052,7 @@ function readSpecialistRoster(specialistsDir) {
7844
8052
  if (!file.endsWith(".md")) continue;
7845
8053
  let raw;
7846
8054
  try {
7847
- raw = readFileSync14(join13(specialistsDir, file), "utf-8");
8055
+ raw = readFileSync14(join14(specialistsDir, file), "utf-8");
7848
8056
  } catch (err) {
7849
8057
  skipped.push({ file, reason: err instanceof Error ? err.message : String(err) });
7850
8058
  continue;
@@ -7885,8 +8093,8 @@ var TASKS_CYPHER = `
7885
8093
  WITH t ORDER BY coalesce(t.createdAt, '') ASC
7886
8094
  WITH collect({ taskId: t.taskId, name: t.name, status: t.status }) AS all
7887
8095
  RETURN all[0..${TASK_ITEMS_CAP}] AS items, size(all) AS total`;
7888
- var app5 = new Hono();
7889
- app5.get("/", requireAdminSession, async (c) => {
8096
+ var app6 = new Hono();
8097
+ app6.get("/", requireAdminSession, async (c) => {
7890
8098
  const cacheKey = c.var.cacheKey;
7891
8099
  const accountId = getAccountIdForSession(cacheKey);
7892
8100
  if (!accountId) {
@@ -7926,7 +8134,7 @@ app5.get("/", requireAdminSession, async (c) => {
7926
8134
  let specialists = [];
7927
8135
  try {
7928
8136
  const roster = readSpecialistRoster(
7929
- resolve12(ACCOUNTS_DIR, accountId, "specialists", "agents")
8137
+ resolve13(ACCOUNTS_DIR, accountId, "specialists", "agents")
7930
8138
  );
7931
8139
  specialists = roster.specialists;
7932
8140
  for (const s of roster.skipped) {
@@ -7957,15 +8165,15 @@ function r2n(value) {
7957
8165
  }
7958
8166
  return Number(value ?? 0);
7959
8167
  }
7960
- var webchat_greeting_default = app5;
8168
+ var webchat_greeting_default = app6;
7961
8169
 
7962
8170
  // server/routes/telegram.ts
7963
8171
  import { homedir } from "os";
7964
- import { resolve as resolve14, join as join14 } from "path";
8172
+ import { resolve as resolve15, join as join15 } from "path";
7965
8173
  import { existsSync as existsSync10, readFileSync as readFileSync15 } from "fs";
7966
8174
 
7967
8175
  // app/lib/channel-pty-bridge/bridge.ts
7968
- import { resolve as resolve13 } from "path";
8176
+ import { resolve as resolve14 } from "path";
7969
8177
 
7970
8178
  // app/lib/channel-pty-bridge/manager-client.ts
7971
8179
  function managerBase2() {
@@ -8086,7 +8294,7 @@ function classifyTimeout(ndjson, writeAtMs) {
8086
8294
 
8087
8295
  // app/lib/channel-pty-bridge/public-session-end-review.ts
8088
8296
  import { randomUUID as randomUUID7 } from "crypto";
8089
- var TAG20 = "[public-session-review]";
8297
+ var TAG21 = "[public-session-review]";
8090
8298
  var CONSUMED_CAP = 500;
8091
8299
  var consumed = /* @__PURE__ */ new Set();
8092
8300
  function consumeOnce(sessionId) {
@@ -8113,7 +8321,7 @@ async function fetchJsonl(sessionId) {
8113
8321
  return await res.text();
8114
8322
  } catch (err) {
8115
8323
  console.error(
8116
- `${TAG20} jsonl-fetch-failed sessionId=${sessionId} err="${err instanceof Error ? err.message : String(err)}"`
8324
+ `${TAG21} jsonl-fetch-failed sessionId=${sessionId} err="${err instanceof Error ? err.message : String(err)}"`
8117
8325
  );
8118
8326
  return null;
8119
8327
  }
@@ -8137,7 +8345,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
8137
8345
  const res = await fetch(url);
8138
8346
  if (!res.ok) {
8139
8347
  console.error(
8140
- `${TAG20} prior-writes-fetch-failed sliceToken=${sliceToken.slice(0, 8)} status=${res.status}`
8348
+ `${TAG21} prior-writes-fetch-failed sliceToken=${sliceToken.slice(0, 8)} status=${res.status}`
8141
8349
  );
8142
8350
  return [];
8143
8351
  }
@@ -8145,7 +8353,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
8145
8353
  return Array.isArray(body.writes) ? body.writes : [];
8146
8354
  } catch (err) {
8147
8355
  console.error(
8148
- `${TAG20} prior-writes-fetch-threw sliceToken=${sliceToken.slice(0, 8)} err="${err instanceof Error ? err.message : String(err)}"`
8356
+ `${TAG21} prior-writes-fetch-threw sliceToken=${sliceToken.slice(0, 8)} err="${err instanceof Error ? err.message : String(err)}"`
8149
8357
  );
8150
8358
  return [];
8151
8359
  }
@@ -8174,7 +8382,7 @@ function composeInitialMessage(input) {
8174
8382
  }
8175
8383
  async function dispatchReviewer(input, initialMessage) {
8176
8384
  const sessionId = randomUUID7();
8177
- console.log(`${TAG20} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
8385
+ console.log(`${TAG21} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
8178
8386
  const spawned = await managerRcSpawn({
8179
8387
  sessionId,
8180
8388
  initialMessage,
@@ -8194,21 +8402,21 @@ async function firePublicSessionEndReview(input) {
8194
8402
  const dispatchedAt = Date.now();
8195
8403
  if (consumed.has(input.sessionId)) {
8196
8404
  console.log(
8197
- `${TAG20} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
8405
+ `${TAG21} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
8198
8406
  );
8199
8407
  return;
8200
8408
  }
8201
8409
  const jsonl = await fetchJsonl(input.sessionId);
8202
8410
  if (!jsonl) {
8203
8411
  console.log(
8204
- `${TAG20} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-jsonl-missing`
8412
+ `${TAG21} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-jsonl-missing`
8205
8413
  );
8206
8414
  return;
8207
8415
  }
8208
8416
  const operatorTurns = countOperatorTurns(jsonl);
8209
8417
  if (operatorTurns === 0) {
8210
8418
  console.log(
8211
- `${TAG20} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-no-turns`
8419
+ `${TAG21} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-no-turns`
8212
8420
  );
8213
8421
  return;
8214
8422
  }
@@ -8222,19 +8430,19 @@ async function firePublicSessionEndReview(input) {
8222
8430
  });
8223
8431
  if (!consumeOnce(input.sessionId)) {
8224
8432
  console.log(
8225
- `${TAG20} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
8433
+ `${TAG21} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
8226
8434
  );
8227
8435
  return;
8228
8436
  }
8229
8437
  const dispatched = await dispatchReviewer(input, initialMessage);
8230
8438
  if (!dispatched.ok) {
8231
8439
  console.error(
8232
- `${TAG20} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-spawn-failed reason=${dispatched.reason}`
8440
+ `${TAG21} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-spawn-failed reason=${dispatched.reason}`
8233
8441
  );
8234
8442
  return;
8235
8443
  }
8236
8444
  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}`
8445
+ `${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
8446
  );
8239
8447
  }
8240
8448
 
@@ -8405,7 +8613,7 @@ async function fanOut(subscribers, text, onError, tag) {
8405
8613
  }
8406
8614
 
8407
8615
  // app/lib/whatsapp/inbound/file-delivery-bridge.ts
8408
- var TAG21 = "[whatsapp-adaptor]";
8616
+ var TAG22 = "[whatsapp-adaptor]";
8409
8617
  var SEND_USER_FILE = "SendUserFile";
8410
8618
  var WHATSAPP_SEND_DOCUMENT = "whatsapp-send-document";
8411
8619
  function platformRoot() {
@@ -8440,7 +8648,7 @@ function makeWhatsAppFileDelivery(entry) {
8440
8648
  maxyAccountId = resolvePlatformAccountId();
8441
8649
  } catch (err) {
8442
8650
  console.error(
8443
- `${TAG21} file-delivery reject reason=account-unresolved sender=${entry.senderId} message=${err instanceof Error ? err.message : String(err)}`
8651
+ `${TAG22} file-delivery reject reason=account-unresolved sender=${entry.senderId} message=${err instanceof Error ? err.message : String(err)}`
8444
8652
  );
8445
8653
  return;
8446
8654
  }
@@ -8457,7 +8665,7 @@ function makeWhatsAppFileDelivery(entry) {
8457
8665
  if (!result.ok) {
8458
8666
  failedFiles.push(files[i]);
8459
8667
  console.error(
8460
- `${TAG21} file-delivery reject reason=send-failed sender=${entry.senderId} status=${result.status} message=${result.error}`
8668
+ `${TAG22} file-delivery reject reason=send-failed sender=${entry.senderId} status=${result.status} message=${result.error}`
8461
8669
  );
8462
8670
  }
8463
8671
  }
@@ -8474,7 +8682,7 @@ function makeWhatsAppFileDelivery(entry) {
8474
8682
  const sid = entry.sessionId.slice(0, 8);
8475
8683
  for (const file of failed) {
8476
8684
  console.error(
8477
- `${TAG21} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${SEND_USER_FILE} file=${file}`
8685
+ `${TAG22} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${SEND_USER_FILE} file=${file}`
8478
8686
  );
8479
8687
  }
8480
8688
  const okAt = documentOutboundAt(entry.senderId);
@@ -8485,13 +8693,13 @@ function makeWhatsAppFileDelivery(entry) {
8485
8693
  if (!delivered) {
8486
8694
  const fileField = call.filePath !== void 0 ? ` file=${call.filePath}` : "";
8487
8695
  console.error(
8488
- `${TAG21} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
8696
+ `${TAG22} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
8489
8697
  );
8490
8698
  }
8491
8699
  }
8492
8700
  if (firedTools.includes(SEND_USER_FILE) && attempts === 0 && !documentWentOut) {
8493
8701
  console.error(
8494
- `${TAG21} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${SEND_USER_FILE}`
8702
+ `${TAG22} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${SEND_USER_FILE}`
8495
8703
  );
8496
8704
  }
8497
8705
  }
@@ -8562,7 +8770,7 @@ async function ensureEntry(input) {
8562
8770
  });
8563
8771
  } else {
8564
8772
  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);
8773
+ const attachmentDir = resolve14(DATA_ROOT, "accounts", input.accountId, "uploads", "public", input.senderId);
8566
8774
  spawned = await managerSpawn({
8567
8775
  senderId: input.senderId,
8568
8776
  role: input.role,
@@ -8694,12 +8902,12 @@ async function dispatchOnce(input) {
8694
8902
  });
8695
8903
  if (!entry) return { error: "spawn-failed" };
8696
8904
  entry.lastInboundAt = Date.now();
8697
- let resolve31;
8905
+ let resolve32;
8698
8906
  const turnPromise = new Promise((r) => {
8699
- resolve31 = r;
8907
+ resolve32 = r;
8700
8908
  });
8701
8909
  const listener = (text) => {
8702
- resolve31(text);
8910
+ resolve32(text);
8703
8911
  };
8704
8912
  entry.subscribers.add(listener);
8705
8913
  const writeAtMs = Date.now();
@@ -8846,11 +9054,11 @@ function routeTelegramUpdate(input) {
8846
9054
  }
8847
9055
 
8848
9056
  // server/routes/telegram.ts
8849
- var TAG22 = "[telegram-inbound]";
9057
+ var TAG23 = "[telegram-inbound]";
8850
9058
  var DISPATCH_TIMEOUT_MS = 12e4;
8851
9059
  function configDirName() {
8852
- const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve14(process.cwd(), "..");
8853
- const brandPath = join14(platformRoot2, "config", "brand.json");
9060
+ const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve15(process.cwd(), "..");
9061
+ const brandPath = join15(platformRoot2, "config", "brand.json");
8854
9062
  if (existsSync10(brandPath)) {
8855
9063
  try {
8856
9064
  return JSON.parse(readFileSync15(brandPath, "utf-8")).configDir ?? ".maxy";
@@ -8861,7 +9069,7 @@ function configDirName() {
8861
9069
  }
8862
9070
  function secretPath(botType) {
8863
9071
  const filename = botType === "admin" ? ".telegram-admin-webhook-secret" : ".telegram-webhook-secret";
8864
- return resolve14(homedir(), configDirName(), filename);
9072
+ return resolve15(homedir(), configDirName(), filename);
8865
9073
  }
8866
9074
  async function sendTelegram(botToken, chatId, text) {
8867
9075
  try {
@@ -8876,23 +9084,23 @@ async function sendTelegram(botToken, chatId, text) {
8876
9084
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
8877
9085
  }
8878
9086
  }
8879
- var app6 = new Hono();
8880
- app6.post("/", async (c) => {
9087
+ var app7 = new Hono();
9088
+ app7.post("/", async (c) => {
8881
9089
  const botParam = c.req.query("bot");
8882
9090
  const botType = botParam === "admin" ? "admin" : botParam === "public" ? "public" : null;
8883
9091
  if (!botType) {
8884
- console.error(`${TAG22} op=reject reason=missing-bot-param`);
9092
+ console.error(`${TAG23} op=reject reason=missing-bot-param`);
8885
9093
  return c.json({ ok: false }, 400);
8886
9094
  }
8887
9095
  const sp = secretPath(botType);
8888
9096
  if (!existsSync10(sp)) {
8889
- console.error(`${TAG22} op=reject reason=no-secret-file botType=${botType}`);
9097
+ console.error(`${TAG23} op=reject reason=no-secret-file botType=${botType}`);
8890
9098
  return c.json({ ok: false }, 401);
8891
9099
  }
8892
9100
  const expected = readFileSync15(sp, "utf-8").trim();
8893
9101
  const got = c.req.header("x-telegram-bot-api-secret-token") ?? "";
8894
9102
  if (got !== expected) {
8895
- console.error(`${TAG22} op=reject reason=bad-secret botType=${botType}`);
9103
+ console.error(`${TAG23} op=reject reason=bad-secret botType=${botType}`);
8896
9104
  return c.json({ ok: false }, 401);
8897
9105
  }
8898
9106
  let update;
@@ -8903,25 +9111,25 @@ app6.post("/", async (c) => {
8903
9111
  }
8904
9112
  const account = resolveAccount();
8905
9113
  if (!account) {
8906
- console.error(`${TAG22} op=reject reason=no-account`);
9114
+ console.error(`${TAG23} op=reject reason=no-account`);
8907
9115
  return c.json({ ok: true }, 200);
8908
9116
  }
8909
9117
  const decision = routeTelegramUpdate({ update, botType, config: account.config.telegram ?? {} });
8910
9118
  if (decision.kind === "ignore") {
8911
- console.error(`${TAG22} op=ignore reason=${decision.reason}`);
9119
+ console.error(`${TAG23} op=ignore reason=${decision.reason}`);
8912
9120
  return c.json({ ok: true }, 200);
8913
9121
  }
8914
9122
  if (decision.kind === "denied") {
8915
- console.error(`${TAG22} op=denied reason=${decision.reason} agentType=${decision.agentType}`);
9123
+ console.error(`${TAG23} op=denied reason=${decision.reason} agentType=${decision.agentType}`);
8916
9124
  return c.json({ ok: true }, 200);
8917
9125
  }
8918
9126
  const role = decision.agentType === "admin" ? "admin" : "public";
8919
9127
  const agentSlug = role === "admin" ? "admin" : resolveDefaultAgentSlug(account.accountDir);
8920
9128
  if (!agentSlug) {
8921
- console.error(`${TAG22} op=reject reason=no-default-agent`);
9129
+ console.error(`${TAG23} op=reject reason=no-default-agent`);
8922
9130
  return c.json({ ok: true }, 200);
8923
9131
  }
8924
- console.error(`${TAG22} op=update accountId=${account.accountId} from=${decision.senderId}`);
9132
+ console.error(`${TAG23} op=update accountId=${account.accountId} from=${decision.senderId}`);
8925
9133
  const botToken = botType === "admin" ? account.config.telegram?.adminBotToken : account.config.telegram?.publicBotToken;
8926
9134
  const { senderId, chatId, text } = decision;
8927
9135
  void (async () => {
@@ -8935,29 +9143,29 @@ app6.post("/", async (c) => {
8935
9143
  timeoutMs: DISPATCH_TIMEOUT_MS
8936
9144
  });
8937
9145
  if ("error" in result) {
8938
- console.error(`${TAG22} op=dispatch-failed from=${senderId} error=${result.error}`);
9146
+ console.error(`${TAG23} op=dispatch-failed from=${senderId} error=${result.error}`);
8939
9147
  return;
8940
9148
  }
8941
9149
  if (!botToken) {
8942
9150
  const reason = account.config.telegram ? "no-bot-token" : "no-telegram-config";
8943
- console.error(`${TAG22} op=reply-dropped reason=${reason} botType=${botType}`);
9151
+ console.error(`${TAG23} op=reply-dropped reason=${reason} botType=${botType}`);
8944
9152
  return;
8945
9153
  }
8946
9154
  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}`}`);
9155
+ console.error(`${TAG23} op=reply-sent from=${senderId} ok=${sent.ok}${sent.ok ? "" : ` error=${sent.error}`}`);
8948
9156
  })();
8949
9157
  return c.json({ ok: true }, 200);
8950
9158
  });
8951
- var telegram_default = app6;
9159
+ var telegram_default = app7;
8952
9160
 
8953
9161
  // server/routes/onboarding.ts
8954
9162
  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";
9163
+ import { openSync as openSync3, closeSync as closeSync3, writeFileSync as writeFileSync8, writeSync, existsSync as existsSync12, readFileSync as readFileSync17, unlinkSync } from "fs";
8956
9164
  import { createHash as createHash3, randomUUID as randomUUID8 } from "crypto";
8957
9165
 
8958
9166
  // ../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";
9167
+ import { existsSync as existsSync11, readFileSync as readFileSync16, writeFileSync as writeFileSync7, renameSync as renameSync3, mkdirSync as mkdirSync2, readdirSync as readdirSync9, statSync as statSync6 } from "fs";
9168
+ import { dirname as dirname4, join as join16 } from "path";
8961
9169
  function logLine(input, result) {
8962
9170
  const userIdShort = input.userId.slice(0, 8);
8963
9171
  console.error(
@@ -8965,7 +9173,7 @@ function logLine(input, result) {
8965
9173
  );
8966
9174
  }
8967
9175
  function writeFileAtomic(filePath, contents, mode) {
8968
- mkdirSync2(dirname3(filePath), { recursive: true });
9176
+ mkdirSync2(dirname4(filePath), { recursive: true });
8969
9177
  const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
8970
9178
  writeFileSync7(tempPath, contents, mode !== void 0 ? { mode } : void 0);
8971
9179
  renameSync3(tempPath, filePath);
@@ -8999,7 +9207,7 @@ function writeAdminEntry(input) {
8999
9207
  return result;
9000
9208
  }
9001
9209
  try {
9002
- const accountJsonPath = join15(input.accountDir, "account.json");
9210
+ const accountJsonPath = join16(input.accountDir, "account.json");
9003
9211
  if (!existsSync11(accountJsonPath)) {
9004
9212
  throw new Error(`account.json not found at ${accountJsonPath}`);
9005
9213
  }
@@ -9054,13 +9262,13 @@ function checkAdminAuthInvariant(input) {
9054
9262
  }
9055
9263
  for (const entry of entries) {
9056
9264
  if (entry.startsWith(".")) continue;
9057
- const accountDir = join15(input.accountsDir, entry);
9265
+ const accountDir = join16(input.accountsDir, entry);
9058
9266
  try {
9059
- if (!statSync5(accountDir).isDirectory()) continue;
9267
+ if (!statSync6(accountDir).isDirectory()) continue;
9060
9268
  } catch {
9061
9269
  continue;
9062
9270
  }
9063
- const accountJsonPath = join15(accountDir, "account.json");
9271
+ const accountJsonPath = join16(accountDir, "account.json");
9064
9272
  if (!existsSync11(accountJsonPath)) continue;
9065
9273
  let admins = [];
9066
9274
  try {
@@ -9135,11 +9343,11 @@ async function waitForAuthPage(timeoutMs = 2e4) {
9135
9343
  }
9136
9344
  return false;
9137
9345
  }
9138
- var app7 = new Hono();
9139
- app7.get("/claude-auth", async (c) => {
9346
+ var app8 = new Hono();
9347
+ app8.get("/claude-auth", async (c) => {
9140
9348
  return c.json({ authenticated: await checkAuthStatus() });
9141
9349
  });
9142
- app7.post("/claude-auth", async (c) => {
9350
+ app8.post("/claude-auth", async (c) => {
9143
9351
  let body = {};
9144
9352
  try {
9145
9353
  body = await c.req.json();
@@ -9177,7 +9385,7 @@ app7.post("/claude-auth", async (c) => {
9177
9385
  }
9178
9386
  ensureLogDir();
9179
9387
  writeFileSync8(logPath("claude-auth"), "");
9180
- const claudeAuthLogFd = openSync2(logPath("claude-auth"), "a");
9388
+ const claudeAuthLogFd = openSync3(logPath("claude-auth"), "a");
9181
9389
  const onClaudeOutput = (chunk) => writeSync(claudeAuthLogFd, chunk);
9182
9390
  if (process.platform === "darwin") {
9183
9391
  vncLog("claude-auth", { action: "start", transport: "native", platform: "darwin" });
@@ -9187,7 +9395,7 @@ app7.post("/claude-auth", async (c) => {
9187
9395
  claudeProc2.unref();
9188
9396
  claudeProc2.stdout?.on("data", onClaudeOutput);
9189
9397
  claudeProc2.stderr?.on("data", onClaudeOutput);
9190
- claudeProc2.once("close", () => closeSync2(claudeAuthLogFd));
9398
+ claudeProc2.once("close", () => closeSync3(claudeAuthLogFd));
9191
9399
  return c.json({ started: true, transport: "native" });
9192
9400
  }
9193
9401
  if (transport === "vnc") {
@@ -9205,11 +9413,11 @@ app7.post("/claude-auth", async (c) => {
9205
9413
  claudeProc.unref();
9206
9414
  claudeProc.stdout?.on("data", onClaudeOutput);
9207
9415
  claudeProc.stderr?.on("data", onClaudeOutput);
9208
- claudeProc.once("close", () => closeSync2(claudeAuthLogFd));
9416
+ claudeProc.once("close", () => closeSync3(claudeAuthLogFd));
9209
9417
  await waitForAuthPage(2e4);
9210
9418
  return c.json({ started: true, transport });
9211
9419
  });
9212
- app7.post("/set-pin", async (c) => {
9420
+ app8.post("/set-pin", async (c) => {
9213
9421
  let existingUsers = null;
9214
9422
  try {
9215
9423
  existingUsers = readUsersFile2();
@@ -9311,7 +9519,7 @@ ${body.pin}
9311
9519
  }
9312
9520
  return c.json({ ok: true });
9313
9521
  });
9314
- app7.delete("/set-pin", async (c) => {
9522
+ app8.delete("/set-pin", async (c) => {
9315
9523
  let users = null;
9316
9524
  try {
9317
9525
  users = readUsersFile2();
@@ -9345,12 +9553,12 @@ app7.delete("/set-pin", async (c) => {
9345
9553
  }
9346
9554
  return c.json({ ok: true });
9347
9555
  });
9348
- var onboarding_default = app7;
9556
+ var onboarding_default = app8;
9349
9557
 
9350
9558
  // 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");
9559
+ import { appendFileSync, existsSync as existsSync13, renameSync as renameSync4, statSync as statSync7 } from "fs";
9560
+ import { join as join17 } from "path";
9561
+ var CLIENT_ERRORS_LOG = join17(LOG_DIR, "client-errors.log");
9354
9562
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
9355
9563
  var MAX_BODY_SIZE = 8 * 1024;
9356
9564
  var MAX_STACK_LEN = 2e3;
@@ -9394,15 +9602,15 @@ function stackHead(stack) {
9394
9602
  function rotateIfNeeded() {
9395
9603
  try {
9396
9604
  if (!existsSync13(CLIENT_ERRORS_LOG)) return;
9397
- const stats = statSync6(CLIENT_ERRORS_LOG);
9605
+ const stats = statSync7(CLIENT_ERRORS_LOG);
9398
9606
  if (stats.size < MAX_LOG_SIZE) return;
9399
9607
  renameSync4(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
9400
9608
  } catch (err) {
9401
9609
  console.error(`[client-error] log rotation failed: ${err instanceof Error ? err.message : String(err)}`);
9402
9610
  }
9403
9611
  }
9404
- var app8 = new Hono();
9405
- app8.post("/", async (c) => {
9612
+ var app9 = new Hono();
9613
+ app9.post("/", async (c) => {
9406
9614
  const client = resolveClientIp(
9407
9615
  c.env?.incoming?.socket?.remoteAddress,
9408
9616
  c.req.header("x-forwarded-for")
@@ -9504,7 +9712,7 @@ app8.post("/", async (c) => {
9504
9712
  }
9505
9713
  return c.json({ ok: true });
9506
9714
  });
9507
- var client_error_default = app8;
9715
+ var client_error_default = app9;
9508
9716
 
9509
9717
  // server/routes/admin/session.ts
9510
9718
  import { randomUUID as randomUUID9 } from "crypto";
@@ -9562,8 +9770,8 @@ async function createAdminSession(accountId, thinkingView, userId, userName, rol
9562
9770
  sessionId: initialSessionId
9563
9771
  };
9564
9772
  }
9565
- var app9 = new Hono();
9566
- app9.get("/", async (c) => {
9773
+ var app10 = new Hono();
9774
+ app10.get("/", async (c) => {
9567
9775
  const signedSessionToken = c.req.query("session_key");
9568
9776
  if (!signedSessionToken) {
9569
9777
  return c.json({ error: "Invalid or expired admin session" }, 401);
@@ -9609,7 +9817,7 @@ app9.get("/", async (c) => {
9609
9817
  sessionId: getSessionIdForSession(cacheKey) ?? null
9610
9818
  });
9611
9819
  });
9612
- app9.post("/", async (c) => {
9820
+ app10.post("/", async (c) => {
9613
9821
  let body;
9614
9822
  try {
9615
9823
  body = await c.req.json();
@@ -9672,20 +9880,20 @@ app9.post("/", async (c) => {
9672
9880
  const payload = await createAdminSession(selected.accountId, selected.config.thinkingView, userId, userName, selected.role, avatar);
9673
9881
  return c.json(payload);
9674
9882
  });
9675
- var session_default = app9;
9883
+ var session_default = app10;
9676
9884
 
9677
9885
  // 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";
9886
+ import { existsSync as existsSync15, readdirSync as readdirSync10, readFileSync as readFileSync18, statSync as statSync8 } from "fs";
9887
+ import { resolve as resolve16, basename as basename5 } from "path";
9680
9888
 
9681
9889
  // app/lib/logs-read-resolve.ts
9682
9890
  import { existsSync as existsSync14 } from "fs";
9683
- import { join as join17 } from "path";
9891
+ import { join as join18 } from "path";
9684
9892
  function resolveSessionLogPaths(filename, logDirs) {
9685
9893
  const tried = [filename];
9686
9894
  const hits = [];
9687
9895
  for (const dir of logDirs) {
9688
- const fullPath = join17(dir, filename);
9896
+ const fullPath = join18(dir, filename);
9689
9897
  if (existsSync14(fullPath)) {
9690
9898
  hits.push({ path: fullPath, dir });
9691
9899
  }
@@ -9695,27 +9903,27 @@ function resolveSessionLogPaths(filename, logDirs) {
9695
9903
 
9696
9904
  // server/routes/admin/logs.ts
9697
9905
  var TAIL_BYTES = 8192;
9698
- var app10 = new Hono();
9699
- app10.get("/", async (c) => {
9906
+ var app11 = new Hono();
9907
+ app11.get("/", async (c) => {
9700
9908
  const fileParam = c.req.query("file");
9701
9909
  const typeParam = c.req.query("type");
9702
9910
  const sessionIdParam = c.req.query("sessionId");
9703
9911
  const cacheKeyParam = c.req.query("cacheKey");
9704
9912
  const download = c.req.query("download") === "1";
9705
9913
  const account = resolveAccount();
9706
- const accountLogDir = account ? resolve15(account.accountDir, "logs") : null;
9914
+ const accountLogDir = account ? resolve16(account.accountDir, "logs") : null;
9707
9915
  const logDirs = [];
9708
9916
  if (accountLogDir) logDirs.push(accountLogDir);
9709
9917
  logDirs.push(LOG_DIR);
9710
9918
  if (fileParam) {
9711
- const safe = basename4(fileParam);
9919
+ const safe = basename5(fileParam);
9712
9920
  const searched = [];
9713
9921
  for (const dir of logDirs) {
9714
- const filePath = resolve15(dir, safe);
9922
+ const filePath = resolve16(dir, safe);
9715
9923
  searched.push(filePath);
9716
9924
  try {
9717
9925
  const buffer = readFileSync18(filePath);
9718
- const onDiskBytes = statSync7(filePath).size;
9926
+ const onDiskBytes = statSync8(filePath).size;
9719
9927
  const headers = {
9720
9928
  "Content-Type": "text/plain; charset=utf-8",
9721
9929
  "Content-Length": String(buffer.byteLength)
@@ -9778,9 +9986,9 @@ app10.get("/", async (c) => {
9778
9986
  if (hit) {
9779
9987
  console.info(`[admin/logs] resolved cacheKey=${cacheKeySlice} sessionId=${sessionIdSlice} via=${primaryId === cacheKey ? "cacheKey" : primaryId === sessionKeyFromConv ? "reverse-lookup" : "sessionId-fallback"}`);
9780
9988
  try {
9781
- const filename = basename4(hit.path);
9989
+ const filename = basename5(hit.path);
9782
9990
  const buffer = readFileSync18(hit.path);
9783
- const onDiskBytes = statSync7(hit.path).size;
9991
+ const onDiskBytes = statSync8(hit.path).size;
9784
9992
  const headers = {
9785
9993
  "Content-Type": "text/plain; charset=utf-8",
9786
9994
  "Content-Length": String(buffer.byteLength)
@@ -9823,10 +10031,10 @@ app10.get("/", async (c) => {
9823
10031
  console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
9824
10032
  continue;
9825
10033
  }
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 }) => {
10034
+ 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
10035
  seen.add(name);
9828
10036
  try {
9829
- const content = readFileSync18(resolve15(dir, name));
10037
+ const content = readFileSync18(resolve16(dir, name));
9830
10038
  const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
9831
10039
  logs[name] = tail.trim() || "(empty)";
9832
10040
  } catch (err) {
@@ -9838,12 +10046,12 @@ app10.get("/", async (c) => {
9838
10046
  }
9839
10047
  return c.json({ logs });
9840
10048
  });
9841
- var logs_default = app10;
10049
+ var logs_default = app11;
9842
10050
 
9843
10051
  // server/routes/admin/claude-info.ts
9844
10052
  import { execFileSync as execFileSync3 } from "child_process";
9845
- var app11 = new Hono();
9846
- app11.get("/", (c) => {
10053
+ var app12 = new Hono();
10054
+ app12.get("/", (c) => {
9847
10055
  let version = "unknown";
9848
10056
  try {
9849
10057
  const raw = execFileSync3("claude", ["--version"], { encoding: "utf-8", timeout: 5e3 });
@@ -9861,14 +10069,14 @@ app11.get("/", (c) => {
9861
10069
  const thinkingView = resolvedAccount?.config.thinkingView ?? "default";
9862
10070
  return c.json({ version, account, model, thinkingView });
9863
10071
  });
9864
- var claude_info_default = app11;
10072
+ var claude_info_default = app12;
9865
10073
 
9866
10074
  // server/routes/admin/attachment.ts
9867
10075
  import { readFile as readFile2, readdir } from "fs/promises";
9868
10076
  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) => {
10077
+ import { resolve as resolve17 } from "path";
10078
+ var app13 = new Hono();
10079
+ app13.get("/:attachmentId", requireAdminSession, async (c) => {
9872
10080
  const attachmentId = c.req.param("attachmentId");
9873
10081
  const cacheKey = c.var.cacheKey;
9874
10082
  const accountId = getAccountIdForSession(cacheKey);
@@ -9878,11 +10086,11 @@ app12.get("/:attachmentId", requireAdminSession, async (c) => {
9878
10086
  if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(attachmentId)) {
9879
10087
  return new Response("Not found", { status: 404 });
9880
10088
  }
9881
- const dir = resolve16(DATA_ROOT, "accounts", accountId, "uploads", attachmentId);
10089
+ const dir = resolve17(DATA_ROOT, "accounts", accountId, "uploads", attachmentId);
9882
10090
  if (!existsSync16(dir)) {
9883
10091
  return new Response("Not found", { status: 404 });
9884
10092
  }
9885
- const metaPath = resolve16(dir, `${attachmentId}.meta.json`);
10093
+ const metaPath = resolve17(dir, `${attachmentId}.meta.json`);
9886
10094
  if (!existsSync16(metaPath)) {
9887
10095
  return new Response("Not found", { status: 404 });
9888
10096
  }
@@ -9897,7 +10105,7 @@ app12.get("/:attachmentId", requireAdminSession, async (c) => {
9897
10105
  if (!dataFile) {
9898
10106
  return new Response("Not found", { status: 404 });
9899
10107
  }
9900
- const filePath = resolve16(dir, dataFile);
10108
+ const filePath = resolve17(dir, dataFile);
9901
10109
  const buffer = await readFile2(filePath);
9902
10110
  return new Response(new Uint8Array(buffer), {
9903
10111
  headers: {
@@ -9907,16 +10115,16 @@ app12.get("/:attachmentId", requireAdminSession, async (c) => {
9907
10115
  }
9908
10116
  });
9909
10117
  });
9910
- var attachment_default = app12;
10118
+ var attachment_default = app13;
9911
10119
 
9912
10120
  // server/routes/admin/agents.ts
9913
- import { resolve as resolve17 } from "path";
10121
+ import { resolve as resolve18 } from "path";
9914
10122
  import { readdirSync as readdirSync11, readFileSync as readFileSync19, existsSync as existsSync17, rmSync } from "fs";
9915
- var app13 = new Hono();
9916
- app13.get("/", (c) => {
10123
+ var app14 = new Hono();
10124
+ app14.get("/", (c) => {
9917
10125
  const account = resolveAccount();
9918
10126
  if (!account) return c.json({ agents: [] });
9919
- const agentsDir = resolve17(account.accountDir, "agents");
10127
+ const agentsDir = resolve18(account.accountDir, "agents");
9920
10128
  if (!existsSync17(agentsDir)) return c.json({ agents: [] });
9921
10129
  const agents = [];
9922
10130
  try {
@@ -9924,7 +10132,7 @@ app13.get("/", (c) => {
9924
10132
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
9925
10133
  if (!entry.isDirectory()) continue;
9926
10134
  if (entry.name === "admin") continue;
9927
- const configPath2 = resolve17(agentsDir, entry.name, "config.json");
10135
+ const configPath2 = resolve18(agentsDir, entry.name, "config.json");
9928
10136
  if (!existsSync17(configPath2)) continue;
9929
10137
  try {
9930
10138
  const config = JSON.parse(readFileSync19(configPath2, "utf-8"));
@@ -9943,7 +10151,7 @@ app13.get("/", (c) => {
9943
10151
  }
9944
10152
  return c.json({ agents });
9945
10153
  });
9946
- app13.delete("/:slug", async (c) => {
10154
+ app14.delete("/:slug", async (c) => {
9947
10155
  const slug = c.req.param("slug");
9948
10156
  const account = resolveAccount();
9949
10157
  if (!account) return c.json({ error: "No account resolved" }, 400);
@@ -9953,7 +10161,7 @@ app13.delete("/:slug", async (c) => {
9953
10161
  if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
9954
10162
  return c.json({ error: "Invalid agent slug" }, 400);
9955
10163
  }
9956
- const agentDir = resolve17(account.accountDir, "agents", slug);
10164
+ const agentDir = resolve18(account.accountDir, "agents", slug);
9957
10165
  if (!existsSync17(agentDir)) {
9958
10166
  return c.json({ error: "Agent not found" }, 404);
9959
10167
  }
@@ -9973,7 +10181,7 @@ app13.delete("/:slug", async (c) => {
9973
10181
  return c.json({ error: "Failed to delete agent" }, 500);
9974
10182
  }
9975
10183
  });
9976
- app13.post("/:slug/project", async (c) => {
10184
+ app14.post("/:slug/project", async (c) => {
9977
10185
  const slug = c.req.param("slug");
9978
10186
  const account = resolveAccount();
9979
10187
  if (!account) return c.json({ error: "No account resolved" }, 400);
@@ -9983,7 +10191,7 @@ app13.post("/:slug/project", async (c) => {
9983
10191
  if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
9984
10192
  return c.json({ error: "Invalid agent slug" }, 400);
9985
10193
  }
9986
- const agentDir = resolve17(account.accountDir, "agents", slug);
10194
+ const agentDir = resolve18(account.accountDir, "agents", slug);
9987
10195
  if (!existsSync17(agentDir)) {
9988
10196
  return c.json({ error: "Agent not found on disk" }, 404);
9989
10197
  }
@@ -9995,7 +10203,7 @@ app13.post("/:slug/project", async (c) => {
9995
10203
  return c.json({ error: `Projection failed: ${msg}` }, 500);
9996
10204
  }
9997
10205
  });
9998
- var agents_default = app13;
10206
+ var agents_default = app14;
9999
10207
 
10000
10208
  // server/routes/admin/sessions.ts
10001
10209
  import crypto2 from "crypto";
@@ -10267,8 +10475,8 @@ function formatAge(updatedAtStr) {
10267
10475
  return "unknown";
10268
10476
  }
10269
10477
  }
10270
- var app14 = new Hono();
10271
- app14.get("/", requireAdminSession, async (c) => {
10478
+ var app15 = new Hono();
10479
+ app15.get("/", requireAdminSession, async (c) => {
10272
10480
  const cacheKey = c.var.cacheKey;
10273
10481
  const accountId = getAccountIdForSession(cacheKey);
10274
10482
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -10298,7 +10506,7 @@ app14.get("/", requireAdminSession, async (c) => {
10298
10506
  return c.json({ error: "Failed to fetch sessions" }, 500);
10299
10507
  }
10300
10508
  });
10301
- app14.post("/new", requireAdminSession, async (c) => {
10509
+ app15.post("/new", requireAdminSession, async (c) => {
10302
10510
  const oldCacheKey = c.var.cacheKey;
10303
10511
  console.log(`[admin-chat] new-conversation outcome=ingress cacheKey=${oldCacheKey.slice(0, 8)}`);
10304
10512
  const accountId = getAccountIdForSession(oldCacheKey);
@@ -10315,7 +10523,7 @@ app14.post("/new", requireAdminSession, async (c) => {
10315
10523
  console.log(`[admin-chat] new-conversation outcome=ok oldKey=${oldCacheKey.slice(0, 8)} newKey=${newCacheKey.slice(0, 8)}`);
10316
10524
  return c.json({ session_key: newSignedSessionToken, sessionId: null });
10317
10525
  });
10318
- app14.post("/switch", requireAdminSession, async (c) => {
10526
+ app15.post("/switch", requireAdminSession, async (c) => {
10319
10527
  const cacheKey = c.var.cacheKey;
10320
10528
  const accountId = getAccountIdForSession(cacheKey);
10321
10529
  const userId = getUserIdForSession(cacheKey);
@@ -10343,7 +10551,7 @@ app14.post("/switch", requireAdminSession, async (c) => {
10343
10551
  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
10552
  return c.json({ session_key: targetSignedSessionToken, sessionId: targetSessionId });
10345
10553
  });
10346
- app14.delete("/:id", requireAdminSession, async (c) => {
10554
+ app15.delete("/:id", requireAdminSession, async (c) => {
10347
10555
  const sessionId = c.req.param("id");
10348
10556
  const cacheKey = c.var.cacheKey;
10349
10557
  const accountId = getAccountIdForSession(cacheKey);
@@ -10388,7 +10596,7 @@ app14.delete("/:id", requireAdminSession, async (c) => {
10388
10596
  500
10389
10597
  );
10390
10598
  });
10391
- app14.post("/:id/resume", async (c) => {
10599
+ app15.post("/:id/resume", async (c) => {
10392
10600
  const sessionId = c.req.param("id");
10393
10601
  const t0 = Date.now();
10394
10602
  const signedSessionToken = c.req.query("session_key") ?? "";
@@ -10657,7 +10865,7 @@ app14.post("/:id/resume", async (c) => {
10657
10865
  }
10658
10866
  });
10659
10867
  });
10660
- app14.put("/:id/label", requireAdminSession, async (c) => {
10868
+ app15.put("/:id/label", requireAdminSession, async (c) => {
10661
10869
  const sessionId = c.req.param("id");
10662
10870
  const cacheKey = c.var.cacheKey;
10663
10871
  let body;
@@ -10683,11 +10891,11 @@ app14.put("/:id/label", requireAdminSession, async (c) => {
10683
10891
  return c.json({ error: "Failed to rename session" }, 500);
10684
10892
  }
10685
10893
  });
10686
- var sessions_default = app14;
10894
+ var sessions_default = app15;
10687
10895
 
10688
10896
  // 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";
10897
+ import { existsSync as existsSync19, readFileSync as readFileSync20, readdirSync as readdirSync12, statSync as statSync9 } from "fs";
10898
+ import { dirname as dirname5, resolve as resolve19, join as join19 } from "path";
10691
10899
  async function resolveOwnerProfileBlock(accountId, userId) {
10692
10900
  if (!userId) return { ok: false, reason: "missing-user-id" };
10693
10901
  try {
@@ -10701,6 +10909,18 @@ async function resolveOwnerProfileBlock(accountId, userId) {
10701
10909
  return { ok: false, reason: "neo4j-unreachable" };
10702
10910
  }
10703
10911
  }
10912
+ async function resolveAuthenticatedName(accountId, userId) {
10913
+ if (!userId) return void 0;
10914
+ try {
10915
+ const res = await loadAdminUserName(accountId, userId);
10916
+ return res.source === "neo4j" ? res.joined : void 0;
10917
+ } catch (err) {
10918
+ console.error(
10919
+ `[spawn-context] resolveAuthenticatedName failed: ${err instanceof Error ? err.message : String(err)}`
10920
+ );
10921
+ return void 0;
10922
+ }
10923
+ }
10704
10924
  function frontmatterField(manifest, field2) {
10705
10925
  const fm = manifest.match(/^---\r?\n([\s\S]*?)\r?\n---/);
10706
10926
  if (!fm) return null;
@@ -10716,8 +10936,8 @@ function frontmatterField(manifest, field2) {
10716
10936
  function extractPluginToolDescriptions(pluginDir) {
10717
10937
  const out = /* @__PURE__ */ new Map();
10718
10938
  const candidates = [
10719
- join18(pluginDir, "mcp/dist/index.js"),
10720
- join18(pluginDir, "mcp/src/index.ts")
10939
+ join19(pluginDir, "mcp/dist/index.js"),
10940
+ join19(pluginDir, "mcp/src/index.ts")
10721
10941
  ];
10722
10942
  let raw = null;
10723
10943
  for (const path2 of candidates) {
@@ -10772,26 +10992,26 @@ function parseSkillPathsFromFrontmatter(fm) {
10772
10992
  }
10773
10993
  function listPluginDirs() {
10774
10994
  const out = /* @__PURE__ */ new Map();
10775
- const platformPlugins = resolve18(PLATFORM_ROOT, "plugins");
10995
+ const platformPlugins = resolve19(PLATFORM_ROOT, "plugins");
10776
10996
  if (existsSync19(platformPlugins)) {
10777
10997
  for (const name of readdirSync12(platformPlugins)) {
10778
- const dir = join18(platformPlugins, name);
10998
+ const dir = join19(platformPlugins, name);
10779
10999
  try {
10780
- if (statSync8(dir).isDirectory()) out.set(name, dir);
11000
+ if (statSync9(dir).isDirectory()) out.set(name, dir);
10781
11001
  } catch {
10782
11002
  }
10783
11003
  }
10784
11004
  }
10785
- const premiumRoot = resolve18(dirname4(PLATFORM_ROOT), "premium-plugins");
11005
+ const premiumRoot = resolve19(dirname5(PLATFORM_ROOT), "premium-plugins");
10786
11006
  if (existsSync19(premiumRoot)) {
10787
11007
  for (const bundle of readdirSync12(premiumRoot)) {
10788
- const bundlePlugins = join18(premiumRoot, bundle, "plugins");
11008
+ const bundlePlugins = join19(premiumRoot, bundle, "plugins");
10789
11009
  if (!existsSync19(bundlePlugins)) continue;
10790
11010
  try {
10791
11011
  for (const name of readdirSync12(bundlePlugins)) {
10792
- const dir = join18(bundlePlugins, name);
11012
+ const dir = join19(bundlePlugins, name);
10793
11013
  try {
10794
- if (statSync8(dir).isDirectory()) out.set(name, dir);
11014
+ if (statSync9(dir).isDirectory()) out.set(name, dir);
10795
11015
  } catch {
10796
11016
  }
10797
11017
  }
@@ -10802,7 +11022,7 @@ function listPluginDirs() {
10802
11022
  return out;
10803
11023
  }
10804
11024
  function readEnabledPlugins(accountId) {
10805
- const accountFile = resolve18(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
11025
+ const accountFile = resolve19(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
10806
11026
  if (!existsSync19(accountFile)) return /* @__PURE__ */ new Set();
10807
11027
  try {
10808
11028
  const parsed = JSON.parse(readFileSync20(accountFile, "utf-8"));
@@ -10832,7 +11052,7 @@ function computeActivePlugins(accountId) {
10832
11052
  for (const name of Array.from(enabled).sort()) {
10833
11053
  const dir = pluginDirs.get(name);
10834
11054
  if (!dir) continue;
10835
- const fm = readFrontmatter(join18(dir, "PLUGIN.md"));
11055
+ const fm = readFrontmatter(join19(dir, "PLUGIN.md"));
10836
11056
  if (!fm) continue;
10837
11057
  const description = frontmatterField(`---
10838
11058
  ${fm}
@@ -10849,7 +11069,7 @@ ${fm}
10849
11069
  `plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
10850
11070
  );
10851
11071
  if (toolNames.length > 0 && descMap.size === 0) {
10852
- const hasSource = existsSync19(join18(dir, "mcp/dist/index.js")) || existsSync19(join18(dir, "mcp/src/index.ts"));
11072
+ const hasSource = existsSync19(join19(dir, "mcp/dist/index.js")) || existsSync19(join19(dir, "mcp/src/index.ts"));
10853
11073
  if (hasSource) {
10854
11074
  console.warn(
10855
11075
  `[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 +11079,7 @@ ${fm}
10859
11079
  const skillPaths = parseSkillPathsFromFrontmatter(fm);
10860
11080
  const skills = [];
10861
11081
  for (const relPath of skillPaths) {
10862
- const skillPath = join18(dir, relPath);
11082
+ const skillPath = join19(dir, relPath);
10863
11083
  const skillFm = readFrontmatter(skillPath);
10864
11084
  if (!skillFm) continue;
10865
11085
  const skillName = frontmatterField(`---
@@ -10875,7 +11095,7 @@ ${skillFm}
10875
11095
  return out;
10876
11096
  }
10877
11097
  function computeSpecialistDomains(accountId) {
10878
- const specialistsDir = resolve18(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
11098
+ const specialistsDir = resolve19(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
10879
11099
  if (!existsSync19(specialistsDir)) return [];
10880
11100
  let entries;
10881
11101
  try {
@@ -10888,10 +11108,10 @@ function computeSpecialistDomains(accountId) {
10888
11108
  const resolveDesc = (qualified) => {
10889
11109
  if (!qualified.startsWith("mcp__")) return void 0;
10890
11110
  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);
11111
+ const sep9 = rest.indexOf("__");
11112
+ if (sep9 < 0) return void 0;
11113
+ const plugin = rest.slice(0, sep9);
11114
+ const tool = rest.slice(sep9 + 2);
10895
11115
  let map = descByPlugin.get(plugin);
10896
11116
  if (!map) {
10897
11117
  const dir = pluginDirs.get(plugin);
@@ -10903,7 +11123,7 @@ function computeSpecialistDomains(accountId) {
10903
11123
  const out = [];
10904
11124
  for (const file of entries.sort()) {
10905
11125
  if (!file.endsWith(".md")) continue;
10906
- const fm = readFrontmatter(join18(specialistsDir, file));
11126
+ const fm = readFrontmatter(join19(specialistsDir, file));
10907
11127
  if (!fm) continue;
10908
11128
  const wrapped = `---
10909
11129
  ${fm}
@@ -10921,7 +11141,7 @@ ${fm}
10921
11141
  return out;
10922
11142
  }
10923
11143
  function computeDormantPlugins(accountId) {
10924
- const accountFile = resolve18(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
11144
+ const accountFile = resolve19(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
10925
11145
  if (!existsSync19(accountFile)) return [];
10926
11146
  let enabled;
10927
11147
  try {
@@ -10936,7 +11156,7 @@ function computeDormantPlugins(accountId) {
10936
11156
  );
10937
11157
  return [];
10938
11158
  }
10939
- const pluginsDir = resolve18(PLATFORM_ROOT, "plugins");
11159
+ const pluginsDir = resolve19(PLATFORM_ROOT, "plugins");
10940
11160
  if (!existsSync19(pluginsDir)) return [];
10941
11161
  let entries;
10942
11162
  try {
@@ -10947,7 +11167,7 @@ function computeDormantPlugins(accountId) {
10947
11167
  const out = [];
10948
11168
  for (const name of entries) {
10949
11169
  if (enabled.has(name)) continue;
10950
- const manifestPath = resolve18(pluginsDir, name, "PLUGIN.md");
11170
+ const manifestPath = resolve19(pluginsDir, name, "PLUGIN.md");
10951
11171
  if (!existsSync19(manifestPath)) continue;
10952
11172
  let manifest;
10953
11173
  try {
@@ -10966,7 +11186,7 @@ function computeDormantPlugins(accountId) {
10966
11186
 
10967
11187
  // server/routes/admin/claude-sessions.ts
10968
11188
  import { existsSync as existsSync20, readFileSync as readFileSync21 } from "fs";
10969
- import { resolve as resolve19 } from "path";
11189
+ import { resolve as resolve20 } from "path";
10970
11190
  function readTunnelState(brandConfigDir) {
10971
11191
  const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
10972
11192
  if (!existsSync20(statePath)) return null;
@@ -10982,10 +11202,10 @@ function readTunnelState(brandConfigDir) {
10982
11202
  }
10983
11203
  }
10984
11204
  function resolveTunnelUrl() {
10985
- const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve19(process.cwd(), "..");
11205
+ const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
10986
11206
  let brand;
10987
11207
  try {
10988
- brand = JSON.parse(readFileSync21(resolve19(platformRoot2, "config", "brand.json"), "utf-8"));
11208
+ brand = JSON.parse(readFileSync21(resolve20(platformRoot2, "config", "brand.json"), "utf-8"));
10989
11209
  } catch {
10990
11210
  return null;
10991
11211
  }
@@ -10996,7 +11216,7 @@ function resolveTunnelUrl() {
10996
11216
  if (!state) return null;
10997
11217
  return `https://${hostname2}.${state.domain}`;
10998
11218
  }
10999
- var TAG23 = "[claude-session-manager:wrapper]";
11219
+ var TAG24 = "[claude-session-manager:wrapper]";
11000
11220
  async function refuseIfClaudeAuthDead(c, route, sessionId) {
11001
11221
  const auth = await ensureAuth();
11002
11222
  if (auth.status !== "dead" && auth.status !== "missing") return null;
@@ -11008,18 +11228,18 @@ async function refuseIfClaudeAuthDead(c, route, sessionId) {
11008
11228
  503
11009
11229
  );
11010
11230
  }
11011
- var app15 = new Hono();
11231
+ var app16 = new Hono();
11012
11232
  async function performSpawnWithInitialMessage(args) {
11013
11233
  const ownerStart = Date.now();
11014
11234
  const aboutOwner = await resolveOwnerProfileBlock(args.senderId, args.userId);
11015
11235
  const ownerMs = Date.now() - ownerStart;
11016
11236
  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}`);
11237
+ console.log(`${TAG24} about-owner-resolved status=${aboutOwnerStatus} ms=${ownerMs}`);
11018
11238
  const dormantPlugins = computeDormantPlugins(args.senderId);
11019
11239
  const activePlugins = computeActivePlugins(args.senderId);
11020
11240
  const specialistDomains = computeSpecialistDomains(args.senderId);
11021
11241
  const tunnelUrl = resolveTunnelUrl();
11022
- console.log(`${TAG23} tunnel-url-resolved value=${tunnelUrl ?? "null"}`);
11242
+ console.log(`${TAG24} tunnel-url-resolved value=${tunnelUrl ?? "null"}`);
11023
11243
  const upstreamPayload = JSON.stringify({
11024
11244
  senderId: args.senderId,
11025
11245
  // Task 205 — pass userId through to the manager so it lands as
@@ -11046,24 +11266,24 @@ async function performSpawnWithInitialMessage(args) {
11046
11266
  // unshapely values.
11047
11267
  conversationNodeId: args.conversationNodeId
11048
11268
  });
11049
- console.log(`${TAG23} forward-spawn-start managerBase=${managerBase("claude-session-manager:wrapper")} bytes=${upstreamPayload.length} hidden=${args.hidden} specialist=${args.specialist ?? "none"}`);
11269
+ console.log(`${TAG24} forward-spawn-start managerBase=${managerBase("claude-session-manager:wrapper")} bytes=${upstreamPayload.length} hidden=${args.hidden} specialist=${args.specialist ?? "none"}`);
11050
11270
  const forwardStart = Date.now();
11051
11271
  const upstream = await fetch(`${managerBase("claude-session-manager:wrapper")}/public-spawn`, {
11052
11272
  method: "POST",
11053
11273
  headers: { "content-type": "application/json" },
11054
11274
  body: upstreamPayload
11055
11275
  }).catch((err) => {
11056
- console.error(`${TAG23} fetch-failed op=spawn message=${err instanceof Error ? err.message : String(err)} ms=${Date.now() - forwardStart}`);
11276
+ console.error(`${TAG24} fetch-failed op=spawn message=${err instanceof Error ? err.message : String(err)} ms=${Date.now() - forwardStart}`);
11057
11277
  return null;
11058
11278
  });
11059
11279
  if (!upstream) return {
11060
11280
  response: new Response(JSON.stringify({ error: "manager-unreachable" }), { status: 503, headers: { "content-type": "application/json" } }),
11061
11281
  claudeSessionId: null
11062
11282
  };
11063
- console.log(`${TAG23} forward-spawn-done status=${upstream.status} ms=${Date.now() - forwardStart}`);
11283
+ console.log(`${TAG24} forward-spawn-done status=${upstream.status} ms=${Date.now() - forwardStart}`);
11064
11284
  if (args.initialMessage) {
11065
11285
  const inputBytes = Buffer.byteLength(args.initialMessage, "utf8");
11066
- console.log(`${TAG23} initial-message-inlined bytes=${inputBytes}`);
11286
+ console.log(`${TAG24} initial-message-inlined bytes=${inputBytes}`);
11067
11287
  }
11068
11288
  const bodyText = await upstream.text().catch(() => "");
11069
11289
  let claudeSessionId = null;
@@ -11085,8 +11305,8 @@ function mintTranscriptEdge(sessionId, claudeSessionId, accountId) {
11085
11305
  if (!sessionId || !claudeSessionId) return;
11086
11306
  void linkConversationTranscript(sessionId, claudeSessionId, accountId);
11087
11307
  }
11088
- app15.use("*", requireAdminSession);
11089
- app15.post("/", async (c) => {
11308
+ app16.use("*", requireAdminSession);
11309
+ app16.post("/", async (c) => {
11090
11310
  const routeStart = Date.now();
11091
11311
  const cacheKey = c.get("cacheKey") ?? "";
11092
11312
  let body = {};
@@ -11098,7 +11318,7 @@ app15.post("/", async (c) => {
11098
11318
  if (refusal) return refusal;
11099
11319
  const senderId = getAccountIdForSession(cacheKey) ?? "";
11100
11320
  if (!senderId) {
11101
- console.error(`${TAG23} reject reason=no-account-id cacheKey-prefix=${cacheKey.slice(0, 8)}`);
11321
+ console.error(`${TAG24} reject reason=no-account-id cacheKey-prefix=${cacheKey.slice(0, 8)}`);
11102
11322
  return c.json({ error: "admin-account-not-resolved" }, 500);
11103
11323
  }
11104
11324
  const userId = getUserIdForSession(cacheKey) ?? void 0;
@@ -11107,7 +11327,7 @@ app15.post("/", async (c) => {
11107
11327
  const permissionMode = typeof body.permissionMode === "string" ? body.permissionMode : void 0;
11108
11328
  const specialist = typeof body.specialist === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(body.specialist) ? body.specialist : void 0;
11109
11329
  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"}`);
11330
+ 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
11331
  const conversationNodeId = cacheKey ? getSessionIdForSession(cacheKey) : void 0;
11112
11332
  const { response, claudeSessionId } = await performSpawnWithInitialMessage({
11113
11333
  senderId,
@@ -11126,24 +11346,24 @@ app15.post("/", async (c) => {
11126
11346
  claudeSessionId,
11127
11347
  senderId
11128
11348
  );
11129
- console.log(`${TAG23} route-done surface=cookie status=${response.status} route-ms=${Date.now() - routeStart}`);
11349
+ console.log(`${TAG24} route-done surface=cookie status=${response.status} route-ms=${Date.now() - routeStart}`);
11130
11350
  return response;
11131
11351
  });
11132
- var claude_sessions_default = app15;
11352
+ var claude_sessions_default = app16;
11133
11353
 
11134
11354
  // server/routes/admin/log-ingest.ts
11135
- var TAG24 = "[log-ingest]";
11355
+ var TAG25 = "[log-ingest]";
11136
11356
  var TAG_PATTERN = /^[A-Za-z0-9_:-]{1,32}$/;
11137
11357
  var LEVELS = /* @__PURE__ */ new Set(["debug", "info", "warn", "error"]);
11138
11358
  var MAX_LINE_BYTES = 4096;
11139
- var app16 = new Hono();
11359
+ var app17 = new Hono();
11140
11360
  function isLoopbackAddr(addr) {
11141
11361
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
11142
11362
  }
11143
- app16.post("/", async (c) => {
11363
+ app17.post("/", async (c) => {
11144
11364
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
11145
11365
  if (!isLoopbackAddr(remoteAddr)) {
11146
- console.error(`${TAG24} reject reason=non-loopback remoteAddr=${remoteAddr}`);
11366
+ console.error(`${TAG25} reject reason=non-loopback remoteAddr=${remoteAddr}`);
11147
11367
  return c.json({ error: "log-ingest-loopback-only" }, 403);
11148
11368
  }
11149
11369
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -11152,7 +11372,7 @@ app16.post("/", async (c) => {
11152
11372
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
11153
11373
  const offender = tokens.find((t) => !isLoopbackAddr(t));
11154
11374
  if (offender !== void 0) {
11155
- console.error(`${TAG24} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
11375
+ console.error(`${TAG25} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
11156
11376
  return c.json({ error: "log-ingest-loopback-only" }, 403);
11157
11377
  }
11158
11378
  }
@@ -11183,7 +11403,7 @@ app16.post("/", async (c) => {
11183
11403
  else console.log(formatted);
11184
11404
  return c.json({ ok: true }, 200);
11185
11405
  });
11186
- var log_ingest_default = app16;
11406
+ var log_ingest_default = app17;
11187
11407
 
11188
11408
  // server/routes/admin/events.ts
11189
11409
  var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
@@ -11192,20 +11412,20 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
11192
11412
  "device-url:vnc-surface-shown",
11193
11413
  "device-url:malformed"
11194
11414
  ]);
11195
- var app17 = new Hono();
11196
- app17.post("/", async (c) => {
11197
- const TAG33 = "[admin:events]";
11415
+ var app18 = new Hono();
11416
+ app18.post("/", async (c) => {
11417
+ const TAG34 = "[admin:events]";
11198
11418
  let body;
11199
11419
  try {
11200
11420
  body = await c.req.json();
11201
11421
  } catch (err) {
11202
11422
  const detail = err instanceof Error ? err.message : String(err);
11203
- console.error(`${TAG33} reject reason=body-not-json detail=${detail}`);
11423
+ console.error(`${TAG34} reject reason=body-not-json detail=${detail}`);
11204
11424
  return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
11205
11425
  }
11206
11426
  const event = typeof body.event === "string" ? body.event : "";
11207
11427
  if (!ALLOWED_EVENTS.has(event)) {
11208
- console.error(`${TAG33} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
11428
+ console.error(`${TAG34} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
11209
11429
  return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
11210
11430
  }
11211
11431
  const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
@@ -11224,13 +11444,13 @@ app17.post("/", async (c) => {
11224
11444
  console.error(`[${event}] ${formatted}`);
11225
11445
  return c.json({ ok: true });
11226
11446
  });
11227
- var events_default = app17;
11447
+ var events_default = app18;
11228
11448
 
11229
11449
  // server/routes/admin/files.ts
11230
11450
  import { createReadStream as createReadStream2 } from "fs";
11231
11451
  import { readdir as readdir3, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
11232
11452
  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";
11453
+ import { basename as basename7, dirname as dirname6, join as join21, resolve as resolve22, sep as sep6 } from "path";
11234
11454
  import { Readable as Readable2 } from "stream";
11235
11455
 
11236
11456
  // ../lib/graph-trash/src/index.ts
@@ -11548,7 +11768,7 @@ async function cascadeDeleteDocument(params) {
11548
11768
 
11549
11769
  // app/lib/file-index.ts
11550
11770
  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";
11771
+ import { resolve as resolve21, relative as relative2, join as join20, basename as basename6, extname as extname2, sep as sep5 } from "path";
11552
11772
  import { tmpdir as tmpdir2 } from "os";
11553
11773
  import { execFile as execFile2 } from "child_process";
11554
11774
  import { promisify as promisify2 } from "util";
@@ -11630,7 +11850,7 @@ async function extractPdf(absolute) {
11630
11850
  return stdout.trim();
11631
11851
  }
11632
11852
  async function ocrPdf(absolute) {
11633
- const outPdf = join19(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
11853
+ const outPdf = join20(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
11634
11854
  try {
11635
11855
  await execFileAsync2(
11636
11856
  "ocrmypdf",
@@ -11686,13 +11906,13 @@ async function extractFileContent(absolute) {
11686
11906
  }
11687
11907
  }
11688
11908
  async function readDisplayName(absolute) {
11689
- const dir = absolute.slice(0, absolute.length - basename5(absolute).length);
11690
- const base = basename5(absolute);
11909
+ const dir = absolute.slice(0, absolute.length - basename6(absolute).length);
11910
+ const base = basename6(absolute);
11691
11911
  const dot = base.lastIndexOf(".");
11692
11912
  const stem = dot === -1 ? base : base.slice(0, dot);
11693
11913
  if (base === `${stem}.meta.json`) return null;
11694
11914
  try {
11695
- const raw = await fsp.readFile(join19(dir, `${stem}.meta.json`), "utf-8");
11915
+ const raw = await fsp.readFile(join20(dir, `${stem}.meta.json`), "utf-8");
11696
11916
  const meta = JSON.parse(raw);
11697
11917
  const dn = meta.displayName ?? meta.filename;
11698
11918
  return typeof dn === "string" && dn.length > 0 ? dn : null;
@@ -11712,7 +11932,7 @@ async function walkSubtree(root, dataRoot, out) {
11712
11932
  let clean = true;
11713
11933
  for (const entry of entries) {
11714
11934
  if (entry.isSymbolicLink()) continue;
11715
- const abs = join19(root, entry.name);
11935
+ const abs = join20(root, entry.name);
11716
11936
  if (entry.isDirectory()) {
11717
11937
  const sub = await walkSubtree(abs, dataRoot, out);
11718
11938
  if (!sub.clean) clean = false;
@@ -11721,7 +11941,7 @@ async function walkSubtree(root, dataRoot, out) {
11721
11941
  const st = await fsp.stat(abs);
11722
11942
  out.push({
11723
11943
  absolute: abs,
11724
- relativePath: relative2(dataRoot, abs).split(sep4).join("/"),
11944
+ relativePath: relative2(dataRoot, abs).split(sep5).join("/"),
11725
11945
  sizeBytes: st.size,
11726
11946
  modifiedAt: st.mtime.toISOString()
11727
11947
  });
@@ -11824,7 +12044,7 @@ async function cascadeTrashLinkedKnowledgeDocs(session, accountId, relativePaths
11824
12044
  return { kds, sections, chunks };
11825
12045
  }
11826
12046
  async function buildArtifact(accountId, wf, embed2) {
11827
- const name = basename5(wf.absolute);
12047
+ const name = basename6(wf.absolute);
11828
12048
  const { content, route } = await extractFileContent(wf.absolute);
11829
12049
  const displayName = await readDisplayName(wf.absolute);
11830
12050
  const embedInput = `${name}
@@ -11867,7 +12087,7 @@ async function reconcileFileIndex(accountId, opts) {
11867
12087
  return withSession(opts, async (session) => {
11868
12088
  const walked = [];
11869
12089
  const subtreeRoots = [
11870
- resolve20(dataRoot, "accounts", accountId)
12090
+ resolve21(dataRoot, "accounts", accountId)
11871
12091
  ];
11872
12092
  let clean = true;
11873
12093
  for (const root of subtreeRoots) {
@@ -11950,7 +12170,7 @@ async function reconcileFileIndexDebounced(accountId, opts) {
11950
12170
  async function indexFile(accountId, relativePath, opts) {
11951
12171
  const dataRoot = opts?.dataRoot ?? DATA_ROOT;
11952
12172
  const embed2 = opts?.embed ?? embed;
11953
- const absolute = resolve20(dataRoot, relativePath);
12173
+ const absolute = resolve21(dataRoot, relativePath);
11954
12174
  await withSession(opts, async (session) => {
11955
12175
  const st = await fsp.stat(absolute);
11956
12176
  const wf = {
@@ -11984,7 +12204,7 @@ async function dropFileIndex(accountId, relativePath, opts) {
11984
12204
  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
12205
  async function readMeta(absDir, baseName) {
11986
12206
  try {
11987
- const raw = await readFile4(join20(absDir, `${baseName}.meta.json`), "utf8");
12207
+ const raw = await readFile4(join21(absDir, `${baseName}.meta.json`), "utf8");
11988
12208
  const parsed = JSON.parse(raw);
11989
12209
  if (typeof parsed?.filename === "string") {
11990
12210
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -11995,7 +12215,7 @@ async function readMeta(absDir, baseName) {
11995
12215
  }
11996
12216
  async function readAccountNames() {
11997
12217
  const map = /* @__PURE__ */ new Map();
11998
- const accountsDir = resolve21(DATA_ROOT, "accounts");
12218
+ const accountsDir = resolve22(DATA_ROOT, "accounts");
11999
12219
  let names;
12000
12220
  try {
12001
12221
  names = await readdir3(accountsDir);
@@ -12004,7 +12224,7 @@ async function readAccountNames() {
12004
12224
  }
12005
12225
  for (const name of names) {
12006
12226
  if (!UUID_RE3.test(name)) continue;
12007
- const configPath2 = resolve21(accountsDir, name, "account.json");
12227
+ const configPath2 = resolve22(accountsDir, name, "account.json");
12008
12228
  try {
12009
12229
  const raw = await readFile4(configPath2, "utf8");
12010
12230
  const parsed = JSON.parse(raw);
@@ -12022,7 +12242,7 @@ async function readAccountNames() {
12022
12242
  }
12023
12243
  async function enrich(absolute, entry, accountNames) {
12024
12244
  if (entry.kind === "directory" && UUID_RE3.test(entry.name)) {
12025
- const meta = await readMeta(join20(absolute, entry.name), entry.name);
12245
+ const meta = await readMeta(join21(absolute, entry.name), entry.name);
12026
12246
  if (meta?.filename) {
12027
12247
  entry.displayName = meta.filename;
12028
12248
  entry.mimeType = meta.mimeType;
@@ -12108,8 +12328,8 @@ async function knowledgeDocOwnedByAccount(accountId, attachmentId) {
12108
12328
  await session.close();
12109
12329
  }
12110
12330
  }
12111
- var app18 = new Hono();
12112
- app18.get("/", requireAdminSession, async (c) => {
12331
+ var app19 = new Hono();
12332
+ app19.get("/", requireAdminSession, async (c) => {
12113
12333
  const cacheKey = c.var.cacheKey;
12114
12334
  const accountId = getAccountIdForSession(cacheKey);
12115
12335
  if (!accountId) {
@@ -12148,7 +12368,7 @@ app18.get("/", requireAdminSession, async (c) => {
12148
12368
  const childRel = relPath === "" || relPath === "." ? name : `${relPath}/${name}`;
12149
12369
  const protectedEntry = isProtectedFromDeletion(childRel).protected;
12150
12370
  try {
12151
- const entryPath = join20(absolute, name);
12371
+ const entryPath = join21(absolute, name);
12152
12372
  const s = await stat4(entryPath);
12153
12373
  entries.push({
12154
12374
  name,
@@ -12178,7 +12398,7 @@ app18.get("/", requireAdminSession, async (c) => {
12178
12398
  return c.json({ error: message }, 500);
12179
12399
  }
12180
12400
  });
12181
- app18.get("/download", requireAdminSession, async (c) => {
12401
+ app19.get("/download", requireAdminSession, async (c) => {
12182
12402
  const cacheKey = c.var.cacheKey;
12183
12403
  const accountId = getAccountIdForSession(cacheKey);
12184
12404
  if (!accountId) {
@@ -12215,7 +12435,7 @@ app18.get("/download", requireAdminSession, async (c) => {
12215
12435
  if (!info.isFile()) {
12216
12436
  return c.json({ error: "Path is not a file" }, 400);
12217
12437
  }
12218
- const filename = basename6(absolute);
12438
+ const filename = basename7(absolute);
12219
12439
  const mimeType = detectMimeType(absolute);
12220
12440
  const nodeStream = createReadStream2(absolute);
12221
12441
  const webStream = Readable2.toWeb(nodeStream);
@@ -12242,7 +12462,7 @@ app18.get("/download", requireAdminSession, async (c) => {
12242
12462
  return c.json({ error: message }, 500);
12243
12463
  }
12244
12464
  });
12245
- app18.post("/upload", requireAdminSession, async (c) => {
12465
+ app19.post("/upload", requireAdminSession, async (c) => {
12246
12466
  const cacheKey = c.var.cacheKey;
12247
12467
  const accountId = getAccountIdForSession(cacheKey);
12248
12468
  if (!accountId) {
@@ -12272,15 +12492,15 @@ app18.post("/upload", requireAdminSession, async (c) => {
12272
12492
  error: `Unsupported file type: "${file.type}". Supported: ${[...SUPPORTED_MIME_TYPES].join(", ")}.`
12273
12493
  }, 422);
12274
12494
  }
12275
- const safeName = basename6(file.name).replace(/[\0/\\]/g, "_");
12495
+ const safeName = basename7(file.name).replace(/[\0/\\]/g, "_");
12276
12496
  const finalName = `${Date.now()}-${safeName}`;
12277
- const destDir = resolve21(DATA_ROOT, "accounts", accountId, "uploads");
12278
- const destPath = resolve21(destDir, finalName);
12497
+ const destDir = resolve22(DATA_ROOT, "accounts", accountId, "uploads");
12498
+ const destPath = resolve22(destDir, finalName);
12279
12499
  try {
12280
12500
  await mkdir3(destDir, { recursive: true });
12281
12501
  const dataRootReal = realpathSync4(DATA_ROOT);
12282
12502
  const destDirReal = realpathSync4(destDir);
12283
- if (destDirReal !== dataRootReal && !destDirReal.startsWith(dataRootReal + sep5)) {
12503
+ if (destDirReal !== dataRootReal && !destDirReal.startsWith(dataRootReal + sep6)) {
12284
12504
  console.error(`[data] path-traversal-blocked requested="accounts/${accountId}/uploads" resolved="${destDirReal}"`);
12285
12505
  return c.json({ error: "Upload destination escapes DATA_ROOT" }, 403);
12286
12506
  }
@@ -12303,7 +12523,7 @@ app18.post("/upload", requireAdminSession, async (c) => {
12303
12523
  mimeType: file.type
12304
12524
  });
12305
12525
  });
12306
- app18.delete("/", requireAdminSession, async (c) => {
12526
+ app19.delete("/", requireAdminSession, async (c) => {
12307
12527
  const cacheKey = c.var.cacheKey;
12308
12528
  const accountId = getAccountIdForSession(cacheKey);
12309
12529
  if (!accountId) {
@@ -12324,7 +12544,7 @@ app18.delete("/", requireAdminSession, async (c) => {
12324
12544
  console.error(`[data] account-scope-blocked endpoint="DELETE /api/admin/files" path="${relPath}" account=${accountId.slice(0, 8)}\u2026`);
12325
12545
  return c.json({ error: "Not found" }, 404);
12326
12546
  }
12327
- const base = basename6(absolute);
12547
+ const base = basename7(absolute);
12328
12548
  const protection = isProtectedFromDeletion(relPath);
12329
12549
  if (protection.protected) {
12330
12550
  console.error(`[data] file-delete blocked path="${relPath}" reason="protected" rule="${protection.rule}"`);
@@ -12340,7 +12560,7 @@ app18.delete("/", requireAdminSession, async (c) => {
12340
12560
  }
12341
12561
  const dot = base.lastIndexOf(".");
12342
12562
  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;
12563
+ const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join21(dirname6(absolute), `${stem}.meta.json`) : null;
12344
12564
  await unlink2(absolute);
12345
12565
  if (sidecarPath) {
12346
12566
  try {
@@ -12379,7 +12599,7 @@ app18.delete("/", requireAdminSession, async (c) => {
12379
12599
  return c.json({ error: message }, 500);
12380
12600
  }
12381
12601
  });
12382
- var files_default = app18;
12602
+ var files_default = app19;
12383
12603
 
12384
12604
  // ../lib/graph-search/src/index.ts
12385
12605
  var import_dist = __toESM(require_dist());
@@ -13144,8 +13364,8 @@ var DEFAULT_LIMIT = 20;
13144
13364
  var MAX_LIMIT = 2e3;
13145
13365
  var MESSAGE_FAMILY_LABELS = ["Message", "UserMessage", "AssistantMessage", "WhatsAppMessage"];
13146
13366
  var CONVERSATION_PARENT_LABELS = /* @__PURE__ */ new Set(["AdminConversation", "PublicConversation"]);
13147
- var app19 = new Hono();
13148
- app19.get("/", requireAdminSession, async (c) => {
13367
+ var app20 = new Hono();
13368
+ app20.get("/", requireAdminSession, async (c) => {
13149
13369
  const cacheKey = c.var.cacheKey;
13150
13370
  const q = (c.req.query("q") ?? "").trim();
13151
13371
  const rawLimit = c.req.query("limit");
@@ -13281,7 +13501,7 @@ app19.get("/", requireAdminSession, async (c) => {
13281
13501
  await session.close();
13282
13502
  }
13283
13503
  });
13284
- var graph_search_default = app19;
13504
+ var graph_search_default = app20;
13285
13505
 
13286
13506
  // server/routes/admin/graph-subgraph.ts
13287
13507
  import neo4j2 from "neo4j-driver";
@@ -13365,8 +13585,8 @@ var STRIPPED_PROPERTIES = /* @__PURE__ */ new Set([
13365
13585
  "otpCode",
13366
13586
  "cacheKey"
13367
13587
  ]);
13368
- var app20 = new Hono();
13369
- app20.get("/", requireAdminSession, async (c) => {
13588
+ var app21 = new Hono();
13589
+ app21.get("/", requireAdminSession, async (c) => {
13370
13590
  const cacheKey = c.var.cacheKey;
13371
13591
  const accountId = getAccountIdForSession(cacheKey);
13372
13592
  if (!accountId) {
@@ -13949,12 +14169,12 @@ function pruneNode(node, warnedClasses, conversationWarnings) {
13949
14169
  }
13950
14170
  return trashed ? { id: node.id, labels, properties, trashed: true } : { id: node.id, labels, properties };
13951
14171
  }
13952
- var graph_subgraph_default = app20;
14172
+ var graph_subgraph_default = app21;
13953
14173
 
13954
14174
  // server/routes/admin/graph-delete.ts
13955
14175
  var ALLOWED_BY = ["graph-page", "graph-drag-trash", "graph-side-panel-trash"];
13956
- var app21 = new Hono();
13957
- app21.post("/", requireAdminSession, async (c) => {
14176
+ var app22 = new Hono();
14177
+ app22.post("/", requireAdminSession, async (c) => {
13958
14178
  const cacheKey = c.var.cacheKey;
13959
14179
  const accountId = getAccountIdForSession(cacheKey);
13960
14180
  if (!accountId) {
@@ -14116,11 +14336,11 @@ app21.post("/", requireAdminSession, async (c) => {
14116
14336
  }
14117
14337
  }
14118
14338
  });
14119
- var graph_delete_default = app21;
14339
+ var graph_delete_default = app22;
14120
14340
 
14121
14341
  // server/routes/admin/graph-restore.ts
14122
- var app22 = new Hono();
14123
- app22.post("/", requireAdminSession, async (c) => {
14342
+ var app23 = new Hono();
14343
+ app23.post("/", requireAdminSession, async (c) => {
14124
14344
  const cacheKey = c.var.cacheKey;
14125
14345
  const accountId = getAccountIdForSession(cacheKey);
14126
14346
  if (!accountId) {
@@ -14184,11 +14404,11 @@ app22.post("/", requireAdminSession, async (c) => {
14184
14404
  }
14185
14405
  }
14186
14406
  });
14187
- var graph_restore_default = app22;
14407
+ var graph_restore_default = app23;
14188
14408
 
14189
14409
  // server/routes/admin/graph-labels-in-graph.ts
14190
- var app23 = new Hono();
14191
- app23.get("/", requireAdminSession, async (c) => {
14410
+ var app24 = new Hono();
14411
+ app24.get("/", requireAdminSession, async (c) => {
14192
14412
  const cacheKey = c.var.cacheKey;
14193
14413
  const accountId = getAccountIdForSession(cacheKey);
14194
14414
  if (!accountId) {
@@ -14254,11 +14474,11 @@ var LABELS_IN_GRAPH_CYPHER = `
14254
14474
  sum(halfEdges) AS relDegree
14255
14475
  RETURN label, nodeCount, relDegree
14256
14476
  `;
14257
- var graph_labels_in_graph_default = app23;
14477
+ var graph_labels_in_graph_default = app24;
14258
14478
 
14259
14479
  // server/routes/admin/graph-default-view.ts
14260
- var app24 = new Hono();
14261
- app24.get("/", requireAdminSession, async (c) => {
14480
+ var app25 = new Hono();
14481
+ app25.get("/", requireAdminSession, async (c) => {
14262
14482
  const cacheKey = c.var.cacheKey;
14263
14483
  const accountId = getAccountIdForSession(cacheKey);
14264
14484
  const userId = getUserIdForSession(cacheKey);
@@ -14296,7 +14516,7 @@ app24.get("/", requireAdminSession, async (c) => {
14296
14516
  }
14297
14517
  }
14298
14518
  });
14299
- app24.put("/", requireAdminSession, async (c) => {
14519
+ app25.put("/", requireAdminSession, async (c) => {
14300
14520
  const cacheKey = c.var.cacheKey;
14301
14521
  const accountId = getAccountIdForSession(cacheKey);
14302
14522
  const userId = getUserIdForSession(cacheKey);
@@ -14385,20 +14605,20 @@ var WRITE_CYPHER = `
14385
14605
  p.updatedAt = $updatedAt
14386
14606
  RETURN p.labels AS labels
14387
14607
  `;
14388
- var graph_default_view_default = app24;
14608
+ var graph_default_view_default = app25;
14389
14609
 
14390
14610
  // server/routes/admin/sidebar-artefacts.ts
14391
14611
  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";
14612
+ import { resolve as resolve23, relative as relative3, isAbsolute, sep as sep7, basename as basename8 } from "path";
14393
14613
  import { existsSync as existsSync21 } from "fs";
14394
14614
  var LIMIT = 50;
14395
14615
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
14396
14616
  function toDataRootRelPath(absPath) {
14397
- if (absPath !== DATA_ROOT && !absPath.startsWith(DATA_ROOT + sep6)) return null;
14617
+ if (absPath !== DATA_ROOT && !absPath.startsWith(DATA_ROOT + sep7)) return null;
14398
14618
  return relative3(DATA_ROOT, absPath);
14399
14619
  }
14400
- var app25 = new Hono();
14401
- app25.get("/", requireAdminSession, async (c) => {
14620
+ var app26 = new Hono();
14621
+ app26.get("/", requireAdminSession, async (c) => {
14402
14622
  const cacheKey = c.var.cacheKey;
14403
14623
  const accountId = getAccountIdForSession(cacheKey);
14404
14624
  if (!accountId) {
@@ -14409,7 +14629,7 @@ app25.get("/", requireAdminSession, async (c) => {
14409
14629
  if (accountFiles === null) {
14410
14630
  return c.json({ error: "Failed to load artefacts" }, 500);
14411
14631
  }
14412
- const accountDir = resolve22(ACCOUNTS_DIR, accountId);
14632
+ const accountDir = resolve23(ACCOUNTS_DIR, accountId);
14413
14633
  const agents = await fetchAgentTemplateRows(accountDir);
14414
14634
  const artefacts = [...accountFiles, ...agents].sort(
14415
14635
  (a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "")
@@ -14442,7 +14662,7 @@ async function fetchAccountFileArtefacts(accountId) {
14442
14662
  const modifiedAt = r.get("modifiedAt") ?? "";
14443
14663
  return {
14444
14664
  id: `account-file:${relativePath}`,
14445
- name: displayName ?? basename7(relativePath),
14665
+ name: displayName ?? basename8(relativePath),
14446
14666
  kind: "account-file",
14447
14667
  updatedAt: modifiedAt,
14448
14668
  mimeType,
@@ -14461,8 +14681,8 @@ async function fetchAccountFileArtefacts(accountId) {
14461
14681
  async function fetchAgentTemplateRows(accountDir) {
14462
14682
  const rows = [];
14463
14683
  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);
14684
+ const overridePath = resolve23(accountDir, "agents", "admin", filename);
14685
+ const bundledPath = resolve23(PLATFORM_ROOT, "templates", "agents", "admin", filename);
14466
14686
  const labelStem = filename.replace(/\.md$/, "");
14467
14687
  const row = await readAgentTemplateRow({
14468
14688
  id: `agent-template:admin:${filename}`,
@@ -14475,12 +14695,12 @@ async function fetchAgentTemplateRows(accountDir) {
14475
14695
  });
14476
14696
  if (row) rows.push(row);
14477
14697
  }
14478
- const overrideDir = resolve22(accountDir, "specialists", "agents");
14479
- const bundledDir = resolve22(PLATFORM_ROOT, "templates", "specialists", "agents");
14698
+ const overrideDir = resolve23(accountDir, "specialists", "agents");
14699
+ const bundledDir = resolve23(PLATFORM_ROOT, "templates", "specialists", "agents");
14480
14700
  const specialistNames = await unionSpecialistFilenames(overrideDir, bundledDir);
14481
14701
  for (const filename of specialistNames) {
14482
- const overridePath = resolve22(overrideDir, filename);
14483
- const bundledPath = resolve22(bundledDir, filename);
14702
+ const overridePath = resolve23(overrideDir, filename);
14703
+ const bundledPath = resolve23(bundledDir, filename);
14484
14704
  const row = await readAgentTemplateRow({
14485
14705
  id: `agent-template:specialist:${filename}`,
14486
14706
  displayName: filename.replace(/\.md$/, ""),
@@ -14562,11 +14782,11 @@ function isWithin(target, root) {
14562
14782
  const rel = relative3(root, target);
14563
14783
  return !rel.startsWith("..") && !isAbsolute(rel);
14564
14784
  }
14565
- var sidebar_artefacts_default = app25;
14785
+ var sidebar_artefacts_default = app26;
14566
14786
 
14567
14787
  // server/routes/admin/session-delete.ts
14568
- var app26 = new Hono();
14569
- app26.post("/", requireAdminSession, async (c) => {
14788
+ var app27 = new Hono();
14789
+ app27.post("/", requireAdminSession, async (c) => {
14570
14790
  let body;
14571
14791
  try {
14572
14792
  body = await c.req.json();
@@ -14604,11 +14824,11 @@ app26.post("/", requireAdminSession, async (c) => {
14604
14824
  console.error(`[session-delete] sessionId=${sessionId} delete-status=${del.status}`);
14605
14825
  return c.json({ error: `manager-status-${del.status}` }, 502);
14606
14826
  });
14607
- var session_delete_default = app26;
14827
+ var session_delete_default = app27;
14608
14828
 
14609
14829
  // server/routes/admin/session-stop.ts
14610
- var app27 = new Hono();
14611
- app27.post("/", requireAdminSession, async (c) => {
14830
+ var app28 = new Hono();
14831
+ app28.post("/", requireAdminSession, async (c) => {
14612
14832
  let body;
14613
14833
  try {
14614
14834
  body = await c.req.json();
@@ -14633,11 +14853,11 @@ app27.post("/", requireAdminSession, async (c) => {
14633
14853
  console.error(`[session-stop] sessionId=${sessionId} manager-status=${res.status}`);
14634
14854
  return c.json({ error: `manager-status-${res.status}` }, 502);
14635
14855
  });
14636
- var session_stop_default = app27;
14856
+ var session_stop_default = app28;
14637
14857
 
14638
14858
  // server/routes/admin/session-archive.ts
14639
- var app28 = new Hono();
14640
- app28.post("/", requireAdminSession, async (c) => {
14859
+ var app29 = new Hono();
14860
+ app29.post("/", requireAdminSession, async (c) => {
14641
14861
  let body;
14642
14862
  try {
14643
14863
  body = await c.req.json();
@@ -14685,11 +14905,11 @@ app28.post("/", requireAdminSession, async (c) => {
14685
14905
  console.error(`[session-archive] sessionId=${sessionId.slice(0, 8)} manager-status=${res.status}`);
14686
14906
  return c.json({ error: `manager-status-${res.status}` }, 502);
14687
14907
  });
14688
- var session_archive_default = app28;
14908
+ var session_archive_default = app29;
14689
14909
 
14690
14910
  // server/routes/admin/session-rc-spawn.ts
14691
14911
  import { randomUUID as randomUUID10 } from "crypto";
14692
- function resolveSpawnPlan(host, operatorDomains, body, mintId = randomUUID10, adminUserId) {
14912
+ function resolveSpawnPlan(host, operatorDomains, body, mintId = randomUUID10, adminUserId, authenticatedName) {
14693
14913
  const operator = isOperatorHost(host, operatorDomains);
14694
14914
  const resumeId = typeof body.sessionId === "string" && body.sessionId.length > 0 ? body.sessionId : void 0;
14695
14915
  const name = typeof body.name === "string" && body.name.length > 0 ? body.name : void 0;
@@ -14708,6 +14928,7 @@ function resolveSpawnPlan(host, operatorDomains, body, mintId = randomUUID10, ad
14708
14928
  payload.webchatChannel = webchatChannelDescriptor(key);
14709
14929
  if (name) payload.name = name;
14710
14930
  if (adminUserId) payload.adminUserId = adminUserId;
14931
+ if (authenticatedName) payload.authenticatedName = authenticatedName;
14711
14932
  } else {
14712
14933
  sessionId = resumeId;
14713
14934
  payload.sessionId = resumeId;
@@ -14719,8 +14940,8 @@ function shapeWebchatResponse(sessionId, manager) {
14719
14940
  const outcome = typeof manager?.outcome === "string" ? manager.outcome : "bound";
14720
14941
  return { sessionId, outcome, target: `/chat?session=${sessionId}` };
14721
14942
  }
14722
- var app29 = new Hono();
14723
- app29.post("/", requireAdminSession, async (c) => {
14943
+ var app30 = new Hono();
14944
+ app30.post("/", requireAdminSession, async (c) => {
14724
14945
  let body;
14725
14946
  try {
14726
14947
  body = await c.req.json();
@@ -14730,7 +14951,9 @@ app29.post("/", requireAdminSession, async (c) => {
14730
14951
  const host = (c.req.header("host") ?? "").split(":")[0];
14731
14952
  const cacheKey = c.get("cacheKey");
14732
14953
  const adminUserId = cacheKey ? getUserIdForSession(cacheKey) : void 0;
14733
- const plan = resolveSpawnPlan(host, getOperatorDomains(), body, randomUUID10, adminUserId);
14954
+ const accountId = cacheKey ? getAccountIdForSession(cacheKey) : void 0;
14955
+ const authenticatedName = accountId ? await resolveAuthenticatedName(accountId, adminUserId) : void 0;
14956
+ const plan = resolveSpawnPlan(host, getOperatorDomains(), body, randomUUID10, adminUserId, authenticatedName);
14734
14957
  const spawnReqId = randomUUID10();
14735
14958
  console.log(
14736
14959
  `[chat-spawn] op=request spawnReqId=${spawnReqId} origin=${plan.origin} kind=${plan.kind} sessionId=${plan.kind === "new" ? "new" : plan.sessionId}`
@@ -14773,7 +14996,7 @@ app29.post("/", requireAdminSession, async (c) => {
14773
14996
  }
14774
14997
  return c.json(parsed ?? {});
14775
14998
  });
14776
- var session_rc_spawn_default = app29;
14999
+ var session_rc_spawn_default = app30;
14777
15000
 
14778
15001
  // server/routes/admin/session-reseat.ts
14779
15002
  import { randomUUID as randomUUID11 } from "crypto";
@@ -14798,7 +15021,7 @@ function isSelectableModel(id) {
14798
15021
  }
14799
15022
 
14800
15023
  // server/routes/admin/session-reseat.ts
14801
- function resolveReseatPlan(body, mintId = randomUUID11, adminUserId) {
15024
+ function resolveReseatPlan(body, mintId = randomUUID11, adminUserId, authenticatedName) {
14802
15025
  const sessionId = mintId();
14803
15026
  const key = `session:${sessionId}`;
14804
15027
  const payload = {
@@ -14812,10 +15035,12 @@ function resolveReseatPlan(body, mintId = randomUUID11, adminUserId) {
14812
15035
  };
14813
15036
  if (body.name) payload.name = body.name;
14814
15037
  if (adminUserId) payload.adminUserId = adminUserId;
15038
+ if (authenticatedName) payload.authenticatedName = authenticatedName;
14815
15039
  return { sessionId, payload };
14816
15040
  }
14817
- var app30 = new Hono();
14818
- app30.post("/", requireAdminSession, async (c) => {
15041
+ var app31 = new Hono();
15042
+ var reseatsInFlight = /* @__PURE__ */ new Set();
15043
+ app31.post("/", requireAdminSession, async (c) => {
14819
15044
  let body;
14820
15045
  try {
14821
15046
  body = await c.req.json();
@@ -14826,57 +15051,67 @@ app30.post("/", requireAdminSession, async (c) => {
14826
15051
  const model = typeof body.model === "string" && isSelectableModel(body.model) ? body.model : null;
14827
15052
  if (fromSessionId === null) return c.json({ error: "fromSessionId must be a valid session id" }, 400);
14828
15053
  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);
14857
- }
14858
- 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}`);
15054
+ if (reseatsInFlight.has(fromSessionId)) {
15055
+ return c.json({ error: "re-seat already in progress for this session" }, 409);
15056
+ }
15057
+ reseatsInFlight.add(fromSessionId);
15058
+ try {
15059
+ const cacheKey = c.get("cacheKey");
15060
+ const adminUserId = cacheKey ? getUserIdForSession(cacheKey) : void 0;
15061
+ const accountId = cacheKey ? getAccountIdForSession(cacheKey) : void 0;
15062
+ const authenticatedName = accountId ? await resolveAuthenticatedName(accountId, adminUserId) : void 0;
15063
+ const plan = resolveReseatPlan({ fromSessionId, model }, randomUUID11, adminUserId, authenticatedName);
15064
+ const reseatReqId = randomUUID11();
15065
+ console.log(`[chat-reseat] op=request reseatReqId=${reseatReqId} from=${fromSessionId} to-model=${model} new=${plan.sessionId}`);
15066
+ let res;
15067
+ try {
15068
+ res = await fetch(`${managerBase("session-reseat:wrapper")}/rc-spawn`, {
15069
+ method: "POST",
15070
+ headers: { "content-type": "application/json" },
15071
+ body: JSON.stringify(plan.payload)
15072
+ });
15073
+ } catch (err) {
15074
+ const msg = err instanceof Error ? err.message : String(err);
15075
+ console.error(`[session-reseat] manager-unreachable err=${msg}`);
15076
+ console.log(`[chat-reseat] op=exit reseatReqId=${reseatReqId} outcome=reseat-failed`);
15077
+ return c.json({ error: `session manager unreachable: ${msg}` }, 502);
15078
+ }
15079
+ const text = await res.text();
15080
+ let parsed = null;
15081
+ try {
15082
+ parsed = JSON.parse(text);
15083
+ } catch {
15084
+ }
15085
+ if (!res.ok) {
15086
+ console.error(`[session-reseat] manager-error status=${res.status} body=${text.slice(0, 200)}`);
15087
+ console.log(`[chat-reseat] op=exit reseatReqId=${reseatReqId} outcome=reseat-failed`);
15088
+ return c.json(parsed ?? { error: text }, res.status);
15089
+ }
15090
+ try {
15091
+ const account = resolveAccount();
15092
+ if (account) {
15093
+ const accountId2 = resolvePlatformAccountId();
15094
+ const canonicalId = adminSessionIdFor(accountId2, WEBCHAT_ADMIN_KEY);
15095
+ const currentOverride = readCanonicalOverrideId(account.accountDir);
15096
+ if (fromSessionId === canonicalId || fromSessionId === currentOverride) {
15097
+ writeCanonicalOverrideId(account.accountDir, plan.sessionId);
15098
+ console.log(`[chat-reseat] op=canonical-forward reseatReqId=${reseatReqId} from=${fromSessionId} to=${plan.sessionId}`);
15099
+ }
14867
15100
  }
15101
+ } catch (err) {
15102
+ console.error(`[session-reseat] canonical-forward-failed err=${err instanceof Error ? err.message : String(err)}`);
14868
15103
  }
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 });
15104
+ const target = `/chat?session=${plan.sessionId}`;
15105
+ console.log(`[chat-reseat] op=acquired reseatReqId=${reseatReqId} pid=${parsed?.spawnedPid ?? "none"} new=${plan.sessionId}`);
15106
+ console.log(`[chat-reseat] op=navigate reseatReqId=${reseatReqId} target=${target}`);
15107
+ console.log(`[chat-reseat] op=exit reseatReqId=${reseatReqId} outcome=bound`);
15108
+ const outcome = typeof parsed?.outcome === "string" ? parsed.outcome : "bound";
15109
+ return c.json({ sessionId: plan.sessionId, outcome, target });
15110
+ } finally {
15111
+ reseatsInFlight.delete(fromSessionId);
15112
+ }
14878
15113
  });
14879
- var session_reseat_default = app30;
15114
+ var session_reseat_default = app31;
14880
15115
 
14881
15116
  // server/routes/admin/system-stats.ts
14882
15117
  import { readFile as readFile5 } from "fs/promises";
@@ -14973,8 +15208,8 @@ async function sample() {
14973
15208
  if (process.platform === "linux") return sampleLinux();
14974
15209
  return sampleOsFallback();
14975
15210
  }
14976
- var app31 = new Hono();
14977
- app31.get("/", async (c) => {
15211
+ var app32 = new Hono();
15212
+ app32.get("/", async (c) => {
14978
15213
  const started = Date.now();
14979
15214
  if (!inflight) {
14980
15215
  inflight = sample().finally(() => {
@@ -14997,14 +15232,14 @@ app31.get("/", async (c) => {
14997
15232
  return c.json({ degraded: true, reason, sampledAtMs: Date.now() });
14998
15233
  }
14999
15234
  });
15000
- var system_stats_default = app31;
15235
+ var system_stats_default = app32;
15001
15236
 
15002
15237
  // server/routes/admin/health.ts
15003
15238
  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(), "..");
15239
+ import { resolve as resolve24, join as join22 } from "path";
15240
+ var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve24(process.cwd(), "..");
15006
15241
  var brandHostname = "maxy";
15007
- var brandJsonPath = join21(PLATFORM_ROOT6, "config", "brand.json");
15242
+ var brandJsonPath = join22(PLATFORM_ROOT6, "config", "brand.json");
15008
15243
  if (existsSync22(brandJsonPath)) {
15009
15244
  try {
15010
15245
  const brand = JSON.parse(readFileSync22(brandJsonPath, "utf-8"));
@@ -15012,7 +15247,7 @@ if (existsSync22(brandJsonPath)) {
15012
15247
  } catch {
15013
15248
  }
15014
15249
  }
15015
- var VERSION_FILE = resolve23(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
15250
+ var VERSION_FILE = resolve24(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
15016
15251
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
15017
15252
  var PROBE_TIMEOUT_MS = 1e3;
15018
15253
  function readVersion() {
@@ -15042,8 +15277,8 @@ async function probeConversationDb() {
15042
15277
  });
15043
15278
  }
15044
15279
  }
15045
- var app32 = new Hono();
15046
- app32.get("/", async (c) => {
15280
+ var app33 = new Hono();
15281
+ app33.get("/", async (c) => {
15047
15282
  const version = readVersion();
15048
15283
  const probe = await probeConversationDb();
15049
15284
  const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
@@ -15065,11 +15300,11 @@ app32.get("/", async (c) => {
15065
15300
  uptimeMs
15066
15301
  });
15067
15302
  });
15068
- var health_default2 = app32;
15303
+ var health_default2 = app33;
15069
15304
 
15070
15305
  // server/routes/admin/linkedin-ingest.ts
15071
15306
  import { randomUUID as randomUUID12 } from "crypto";
15072
- var TAG25 = "[linkedin-ingest-route]";
15307
+ var TAG26 = "[linkedin-ingest-route]";
15073
15308
  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
15309
  var ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
15075
15310
  var LINKEDIN_URL = /^https:\/\/www\.linkedin\.com\//;
@@ -15167,35 +15402,35 @@ function buildInitialMessage(env) {
15167
15402
  }
15168
15403
  return header;
15169
15404
  }
15170
- var app33 = new Hono();
15171
- app33.post("/", requireAdminSession, async (c) => {
15405
+ var app34 = new Hono();
15406
+ app34.post("/", requireAdminSession, async (c) => {
15172
15407
  let body;
15173
15408
  try {
15174
15409
  body = await c.req.json();
15175
15410
  } catch {
15176
- console.error(TAG25 + " rejected status=400 reason=schema:body-not-json");
15411
+ console.error(TAG26 + " rejected status=400 reason=schema:body-not-json");
15177
15412
  return c.json({ ok: false, error: "schema", reason: "body-not-json" }, 400);
15178
15413
  }
15179
15414
  const v = validate(body);
15180
15415
  if (!v.ok) {
15181
- console.error(TAG25 + " rejected status=" + v.status + " reason=" + v.reason + " missing=" + v.missing.join(","));
15416
+ console.error(TAG26 + " rejected status=" + v.status + " reason=" + v.reason + " missing=" + v.missing.join(","));
15182
15417
  return c.json({ ok: false, error: v.error, reason: v.reason, missing: v.missing }, v.status);
15183
15418
  }
15184
15419
  const envelope = v.envelope;
15185
15420
  const cacheKey = c.var.cacheKey ?? "";
15186
15421
  const senderId = getAccountIdForSession(cacheKey) ?? "";
15187
15422
  if (!senderId) {
15188
- console.error(TAG25 + " rejected status=500 reason=admin-account-not-resolved");
15423
+ console.error(TAG26 + " rejected status=500 reason=admin-account-not-resolved");
15189
15424
  return c.json({ ok: false, error: "admin-account-not-resolved" }, 500);
15190
15425
  }
15191
15426
  const payloadBytes = JSON.stringify(envelope).length;
15192
15427
  console.log(
15193
- TAG25 + " received kind=" + envelope.kind + " account=" + senderId.slice(0, 8) + " pageUrl=" + envelope.pageUrl + " dispatchId=" + envelope.dispatchId + " payloadBytes=" + payloadBytes
15428
+ TAG26 + " received kind=" + envelope.kind + " account=" + senderId.slice(0, 8) + " pageUrl=" + envelope.pageUrl + " dispatchId=" + envelope.dispatchId + " payloadBytes=" + payloadBytes
15194
15429
  );
15195
15430
  const initialMessage = buildInitialMessage(envelope);
15196
15431
  const spawnStart = Date.now();
15197
15432
  const sessionId = randomUUID12();
15198
- console.log(TAG25 + " route target=rc-spawn dispatchId=" + envelope.dispatchId + " sessionId=" + sessionId.slice(0, 8));
15433
+ console.log(TAG26 + " route target=rc-spawn dispatchId=" + envelope.dispatchId + " sessionId=" + sessionId.slice(0, 8));
15199
15434
  const spawned = await managerRcSpawn({
15200
15435
  sessionId,
15201
15436
  initialMessage,
@@ -15204,20 +15439,20 @@ app33.post("/", requireAdminSession, async (c) => {
15204
15439
  });
15205
15440
  if ("error" in spawned) {
15206
15441
  console.error(
15207
- TAG25 + " dispatch-failed dispatchId=" + envelope.dispatchId + " status=" + spawned.status + " ms=" + (Date.now() - spawnStart) + " message=" + spawned.error
15442
+ TAG26 + " dispatch-failed dispatchId=" + envelope.dispatchId + " status=" + spawned.status + " ms=" + (Date.now() - spawnStart) + " message=" + spawned.error
15208
15443
  );
15209
15444
  return c.json({ ok: false, error: "dispatch-failed", upstreamStatus: spawned.status, detail: spawned.error }, 502);
15210
15445
  }
15211
15446
  console.log(
15212
- TAG25 + " dispatched dispatchId=" + envelope.dispatchId + " taskId=" + spawned.sessionId + " ms=" + (Date.now() - spawnStart)
15447
+ TAG26 + " dispatched dispatchId=" + envelope.dispatchId + " taskId=" + spawned.sessionId + " ms=" + (Date.now() - spawnStart)
15213
15448
  );
15214
15449
  return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: spawned.sessionId }, 202);
15215
15450
  });
15216
- var linkedin_ingest_default = app33;
15451
+ var linkedin_ingest_default = app34;
15217
15452
 
15218
15453
  // server/routes/admin/post-turn-context.ts
15219
15454
  import neo4j3 from "neo4j-driver";
15220
- var TAG26 = "[post-turn-context]";
15455
+ var TAG27 = "[post-turn-context]";
15221
15456
  var STRIPPED_PROPERTIES2 = /* @__PURE__ */ new Set([
15222
15457
  "embedding",
15223
15458
  "passwordHash",
@@ -15255,11 +15490,11 @@ function pruneProperties(raw) {
15255
15490
  }
15256
15491
  return out;
15257
15492
  }
15258
- var app34 = new Hono();
15259
- app34.get("/", async (c) => {
15493
+ var app35 = new Hono();
15494
+ app35.get("/", async (c) => {
15260
15495
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
15261
15496
  if (!isLoopbackAddr2(remoteAddr)) {
15262
- console.error(`${TAG26} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15497
+ console.error(`${TAG27} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15263
15498
  return c.json({ error: "post-turn-context-loopback-only" }, 403);
15264
15499
  }
15265
15500
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -15268,7 +15503,7 @@ app34.get("/", async (c) => {
15268
15503
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
15269
15504
  const offender = tokens.find((t) => !isLoopbackAddr2(t));
15270
15505
  if (offender !== void 0) {
15271
- console.error(`${TAG26} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15506
+ console.error(`${TAG27} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15272
15507
  return c.json({ error: "post-turn-context-loopback-only" }, 403);
15273
15508
  }
15274
15509
  }
@@ -15300,7 +15535,7 @@ app34.get("/", async (c) => {
15300
15535
  writes.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
15301
15536
  const total = Date.now() - started;
15302
15537
  console.log(
15303
- `${TAG26} sessionId=${sessionId} accountId=${accountId} writes=${writes.length} ms=${total}`
15538
+ `${TAG27} sessionId=${sessionId} accountId=${accountId} writes=${writes.length} ms=${total}`
15304
15539
  );
15305
15540
  return c.json({
15306
15541
  writes: writes.map(({ elementId, labels, properties }) => ({ elementId, labels, properties }))
@@ -15309,18 +15544,18 @@ app34.get("/", async (c) => {
15309
15544
  const elapsed = Date.now() - started;
15310
15545
  const message = err instanceof Error ? err.message : String(err);
15311
15546
  console.error(
15312
- `${TAG26} neo4j-unreachable sessionId=${sessionId} ms=${elapsed} err="${message}"`
15547
+ `${TAG27} neo4j-unreachable sessionId=${sessionId} ms=${elapsed} err="${message}"`
15313
15548
  );
15314
15549
  return c.json({ error: `post-turn-context unavailable: ${message}` }, 503);
15315
15550
  } finally {
15316
15551
  await session.close();
15317
15552
  }
15318
15553
  });
15319
- var post_turn_context_default = app34;
15554
+ var post_turn_context_default = app35;
15320
15555
 
15321
15556
  // server/routes/admin/public-session-context.ts
15322
15557
  import neo4j4 from "neo4j-driver";
15323
- var TAG27 = "[public-session-context]";
15558
+ var TAG28 = "[public-session-context]";
15324
15559
  var STRIPPED_PROPERTIES3 = /* @__PURE__ */ new Set([
15325
15560
  "embedding",
15326
15561
  "passwordHash",
@@ -15358,11 +15593,11 @@ function pruneProperties2(raw) {
15358
15593
  }
15359
15594
  return out;
15360
15595
  }
15361
- var app35 = new Hono();
15362
- app35.get("/", async (c) => {
15596
+ var app36 = new Hono();
15597
+ app36.get("/", async (c) => {
15363
15598
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
15364
15599
  if (!isLoopbackAddr3(remoteAddr)) {
15365
- console.error(`${TAG27} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15600
+ console.error(`${TAG28} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15366
15601
  return c.json({ error: "public-session-context-loopback-only" }, 403);
15367
15602
  }
15368
15603
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -15371,7 +15606,7 @@ app35.get("/", async (c) => {
15371
15606
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
15372
15607
  const offender = tokens.find((t) => !isLoopbackAddr3(t));
15373
15608
  if (offender !== void 0) {
15374
- console.error(`${TAG27} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15609
+ console.error(`${TAG28} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15375
15610
  return c.json({ error: "public-session-context-loopback-only" }, 403);
15376
15611
  }
15377
15612
  }
@@ -15402,7 +15637,7 @@ app35.get("/", async (c) => {
15402
15637
  writes.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
15403
15638
  const total = Date.now() - started;
15404
15639
  console.log(
15405
- `${TAG27} sliceToken=${sliceToken.slice(0, 8)} writes=${writes.length} ms=${total}`
15640
+ `${TAG28} sliceToken=${sliceToken.slice(0, 8)} writes=${writes.length} ms=${total}`
15406
15641
  );
15407
15642
  return c.json({
15408
15643
  writes: writes.map(({ elementId, labels, properties }) => ({ elementId, labels, properties }))
@@ -15411,25 +15646,25 @@ app35.get("/", async (c) => {
15411
15646
  const elapsed = Date.now() - started;
15412
15647
  const message = err instanceof Error ? err.message : String(err);
15413
15648
  console.error(
15414
- `${TAG27} neo4j-unreachable sliceToken=${sliceToken.slice(0, 8)} ms=${elapsed} err="${message}"`
15649
+ `${TAG28} neo4j-unreachable sliceToken=${sliceToken.slice(0, 8)} ms=${elapsed} err="${message}"`
15415
15650
  );
15416
15651
  return c.json({ error: `public-session-context unavailable: ${message}` }, 503);
15417
15652
  } finally {
15418
15653
  await session.close();
15419
15654
  }
15420
15655
  });
15421
- var public_session_context_default = app35;
15656
+ var public_session_context_default = app36;
15422
15657
 
15423
15658
  // server/routes/admin/public-session-exit.ts
15424
- var TAG28 = "[public-session-exit-route]";
15659
+ var TAG29 = "[public-session-exit-route]";
15425
15660
  function isLoopbackAddr4(addr) {
15426
15661
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
15427
15662
  }
15428
- var app36 = new Hono();
15429
- app36.post("/", async (c) => {
15663
+ var app37 = new Hono();
15664
+ app37.post("/", async (c) => {
15430
15665
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
15431
15666
  if (!isLoopbackAddr4(remoteAddr)) {
15432
- console.error(`${TAG28} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15667
+ console.error(`${TAG29} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15433
15668
  return c.json({ error: "public-session-exit-loopback-only" }, 403);
15434
15669
  }
15435
15670
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -15438,7 +15673,7 @@ app36.post("/", async (c) => {
15438
15673
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
15439
15674
  const offender = tokens.find((t) => !isLoopbackAddr4(t));
15440
15675
  if (offender !== void 0) {
15441
- console.error(`${TAG28} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15676
+ console.error(`${TAG29} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15442
15677
  return c.json({ error: "public-session-exit-loopback-only" }, 403);
15443
15678
  }
15444
15679
  }
@@ -15453,18 +15688,18 @@ app36.post("/", async (c) => {
15453
15688
  handlePublicSessionExit(sessionId);
15454
15689
  return c.json({ ok: true });
15455
15690
  });
15456
- var public_session_exit_default = app36;
15691
+ var public_session_exit_default = app37;
15457
15692
 
15458
15693
  // server/routes/admin/access-session-evict.ts
15459
- var TAG29 = "[access-session-evict]";
15694
+ var TAG30 = "[access-session-evict]";
15460
15695
  function isLoopbackAddr5(addr) {
15461
15696
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
15462
15697
  }
15463
- var app37 = new Hono();
15464
- app37.post("/", async (c) => {
15698
+ var app38 = new Hono();
15699
+ app38.post("/", async (c) => {
15465
15700
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
15466
15701
  if (!isLoopbackAddr5(remoteAddr)) {
15467
- console.error(`${TAG29} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15702
+ console.error(`${TAG30} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15468
15703
  return c.json({ error: "access-session-evict-loopback-only" }, 403);
15469
15704
  }
15470
15705
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -15473,7 +15708,7 @@ app37.post("/", async (c) => {
15473
15708
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
15474
15709
  const offender = tokens.find((t) => !isLoopbackAddr5(t));
15475
15710
  if (offender !== void 0) {
15476
- console.error(`${TAG29} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15711
+ console.error(`${TAG30} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15477
15712
  return c.json({ error: "access-session-evict-loopback-only" }, 403);
15478
15713
  }
15479
15714
  }
@@ -15486,22 +15721,22 @@ app37.post("/", async (c) => {
15486
15721
  const grantId = typeof body.grantId === "string" ? body.grantId.trim() : "";
15487
15722
  if (!grantId) return c.json({ error: "grantId required" }, 400);
15488
15723
  const dropped = evictAccessSessionsByGrant(grantId);
15489
- console.log(`${TAG29} grantId=${grantId} dropped=${dropped}`);
15724
+ console.log(`${TAG30} grantId=${grantId} dropped=${dropped}`);
15490
15725
  return c.json({ ok: true, dropped });
15491
15726
  });
15492
- var access_session_evict_default = app37;
15727
+ var access_session_evict_default = app38;
15493
15728
 
15494
15729
  // server/routes/admin/enrol-person.ts
15495
- var TAG30 = "[enrol]";
15730
+ var TAG31 = "[enrol]";
15496
15731
  function isLoopbackAddr6(addr) {
15497
15732
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
15498
15733
  }
15499
15734
  var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
15500
- var app38 = new Hono();
15501
- app38.post("/", async (c) => {
15735
+ var app39 = new Hono();
15736
+ app39.post("/", async (c) => {
15502
15737
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
15503
15738
  if (!isLoopbackAddr6(remoteAddr)) {
15504
- console.error(`${TAG30} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15739
+ console.error(`${TAG31} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15505
15740
  return c.json({ error: "enrol-person-loopback-only" }, 403);
15506
15741
  }
15507
15742
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -15510,7 +15745,7 @@ app38.post("/", async (c) => {
15510
15745
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
15511
15746
  const offender = tokens.find((t) => !isLoopbackAddr6(t));
15512
15747
  if (offender !== void 0) {
15513
- console.error(`${TAG30} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15748
+ console.error(`${TAG31} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15514
15749
  return c.json({ error: "enrol-person-loopback-only" }, 403);
15515
15750
  }
15516
15751
  }
@@ -15535,7 +15770,7 @@ app38.post("/", async (c) => {
15535
15770
  }
15536
15771
  const accountId = process.env.ACCOUNT_ID ?? "";
15537
15772
  if (!accountId) {
15538
- console.error(`${TAG30} op=person result=no-account-id`);
15773
+ console.error(`${TAG31} op=person result=no-account-id`);
15539
15774
  return c.json({ error: "no-account-id" }, 500);
15540
15775
  }
15541
15776
  let personId;
@@ -15543,7 +15778,7 @@ app38.post("/", async (c) => {
15543
15778
  personId = await enrolPerson({ accountId, phone, email, agentSlug });
15544
15779
  } catch (err) {
15545
15780
  console.error(
15546
- `${TAG30} op=person result=write-failed agentSlug=${agentSlug} contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
15781
+ `${TAG31} op=person result=write-failed agentSlug=${agentSlug} contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
15547
15782
  );
15548
15783
  return c.json({ error: "enrol-failed" }, 500);
15549
15784
  }
@@ -15553,19 +15788,19 @@ app38.post("/", async (c) => {
15553
15788
  if (g) grant = { grantId: g.grantId, status: g.status, contactValue: g.contactValue };
15554
15789
  } catch (err) {
15555
15790
  console.error(
15556
- `${TAG30} op=person result=grant-lookup-failed contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
15791
+ `${TAG31} op=person result=grant-lookup-failed contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
15557
15792
  );
15558
15793
  }
15559
15794
  console.log(
15560
- `${TAG30} op=person personId=${personId} account=${accountId} agentSlug=${agentSlug} contact=${maskContact(email)}`
15795
+ `${TAG31} op=person personId=${personId} account=${accountId} agentSlug=${agentSlug} contact=${maskContact(email)}`
15561
15796
  );
15562
15797
  return c.json({ personId, grant }, 200);
15563
15798
  });
15564
- var enrol_person_default = app38;
15799
+ var enrol_person_default = app39;
15565
15800
 
15566
15801
  // server/routes/admin/browser.ts
15567
- var app39 = new Hono();
15568
- app39.post("/launch", requireAdminSession, async (c) => {
15802
+ var app40 = new Hono();
15803
+ app40.post("/launch", requireAdminSession, async (c) => {
15569
15804
  try {
15570
15805
  const transport = resolveBrowserTransport(c.req.raw, c.env?.incoming?.socket?.remoteAddress);
15571
15806
  console.error(`[admin/browser/launch] op=request transport=${transport}`);
@@ -15593,50 +15828,50 @@ app39.post("/launch", requireAdminSession, async (c) => {
15593
15828
  );
15594
15829
  }
15595
15830
  });
15596
- var browser_default = app39;
15831
+ var browser_default = app40;
15597
15832
 
15598
15833
  // 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;
15834
+ var app41 = new Hono();
15835
+ app41.route("/session", session_default);
15836
+ app41.route("/logs", logs_default);
15837
+ app41.route("/claude-info", claude_info_default);
15838
+ app41.route("/attachment", attachment_default);
15839
+ app41.route("/agents", agents_default);
15840
+ app41.route("/sessions", sessions_default);
15841
+ app41.route("/claude-sessions", claude_sessions_default);
15842
+ app41.route("/log-ingest", log_ingest_default);
15843
+ app41.route("/events", events_default);
15844
+ app41.route("/files", files_default);
15845
+ app41.route("/graph-search", graph_search_default);
15846
+ app41.route("/graph-subgraph", graph_subgraph_default);
15847
+ app41.route("/graph-delete", graph_delete_default);
15848
+ app41.route("/graph-restore", graph_restore_default);
15849
+ app41.route("/graph-labels-in-graph", graph_labels_in_graph_default);
15850
+ app41.route("/graph-default-view", graph_default_view_default);
15851
+ app41.route("/sidebar-artefacts", sidebar_artefacts_default);
15852
+ app41.route("/sidebar-sessions", sidebar_sessions_default);
15853
+ app41.route("/session-delete", session_delete_default);
15854
+ app41.route("/session-stop", session_stop_default);
15855
+ app41.route("/session-archive", session_archive_default);
15856
+ app41.route("/browser", browser_default);
15857
+ app41.route("/session-rc-spawn", session_rc_spawn_default);
15858
+ app41.route("/session-reseat", session_reseat_default);
15859
+ app41.route("/system-stats", system_stats_default);
15860
+ app41.route("/health-brand", health_default2);
15861
+ app41.route("/linkedin-ingest", linkedin_ingest_default);
15862
+ app41.route("/post-turn-context", post_turn_context_default);
15863
+ app41.route("/public-session-context", public_session_context_default);
15864
+ app41.route("/public-session-exit", public_session_exit_default);
15865
+ app41.route("/access-session-evict", access_session_evict_default);
15866
+ app41.route("/enrol-person", enrol_person_default);
15867
+ var admin_default = app41;
15633
15868
 
15634
15869
  // server/routes/access/verify-token.ts
15635
- var TAG31 = "[access-verify]";
15870
+ var TAG32 = "[access-verify]";
15636
15871
  var MINT_TAG = "[access-session-mint]";
15637
15872
  var COOKIE_NAME = "__access_session";
15638
- var app41 = new Hono();
15639
- app41.post("/", async (c) => {
15873
+ var app42 = new Hono();
15874
+ app42.post("/", async (c) => {
15640
15875
  const ip = c.var.clientIp || "unknown";
15641
15876
  let body;
15642
15877
  try {
@@ -15651,39 +15886,39 @@ app41.post("/", async (c) => {
15651
15886
  }
15652
15887
  const rateMsg = checkAccessRateLimit(ip, agentSlug);
15653
15888
  if (rateMsg) {
15654
- console.error(`${TAG31} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
15889
+ console.error(`${TAG32} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
15655
15890
  return c.json({ error: rateMsg }, 429);
15656
15891
  }
15657
15892
  const grant = await findGrantByMagicToken(token);
15658
15893
  if (!grant) {
15659
15894
  recordAccessFailedAttempt(ip, agentSlug);
15660
- console.error(`${TAG31} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
15895
+ console.error(`${TAG32} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
15661
15896
  return c.json({ error: "invalid-or-expired-link" }, 401);
15662
15897
  }
15663
15898
  if (grant.agentSlug !== agentSlug) {
15664
15899
  recordAccessFailedAttempt(ip, agentSlug);
15665
15900
  console.error(
15666
- `${TAG31} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
15901
+ `${TAG32} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
15667
15902
  );
15668
15903
  return c.json({ error: "invalid-or-expired-link" }, 401);
15669
15904
  }
15670
15905
  if (grant.status === "expired" || grant.status === "revoked") {
15671
15906
  recordAccessFailedAttempt(ip, agentSlug);
15672
15907
  console.error(
15673
- `${TAG31} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
15908
+ `${TAG32} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
15674
15909
  );
15675
15910
  return c.json({ error: "access-no-longer-valid" }, 401);
15676
15911
  }
15677
15912
  if (grant.expiresAt !== null && grant.expiresAt < Date.now()) {
15678
15913
  recordAccessFailedAttempt(ip, agentSlug);
15679
15914
  console.error(
15680
- `${TAG31} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
15915
+ `${TAG32} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
15681
15916
  );
15682
15917
  return c.json({ error: "access-no-longer-valid" }, 401);
15683
15918
  }
15684
15919
  if (!grant.sliceToken) {
15685
15920
  console.error(
15686
- `${TAG31} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
15921
+ `${TAG32} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
15687
15922
  );
15688
15923
  return c.json({ error: "grant-misconfigured" }, 500);
15689
15924
  }
@@ -15699,12 +15934,12 @@ app41.post("/", async (c) => {
15699
15934
  await consumeMagicTokenAndActivate(grant.grantId);
15700
15935
  } catch (err) {
15701
15936
  console.error(
15702
- `${TAG31} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
15937
+ `${TAG32} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
15703
15938
  );
15704
15939
  return c.json({ error: "verification-failed" }, 500);
15705
15940
  }
15706
15941
  clearAccessRateLimit(ip, agentSlug);
15707
- console.log(`${TAG31} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
15942
+ console.log(`${TAG32} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
15708
15943
  console.log(
15709
15944
  `${MINT_TAG} grantId=${grant.grantId} sliceToken=${grant.sliceToken.slice(0, 8)} agentSlug=${agentSlug} personId=${grant.personId ?? "none"}`
15710
15945
  );
@@ -15718,13 +15953,13 @@ app41.post("/", async (c) => {
15718
15953
  displayName: grant.displayName
15719
15954
  });
15720
15955
  });
15721
- var verify_token_default = app41;
15956
+ var verify_token_default = app42;
15722
15957
 
15723
15958
  // app/lib/access-email.ts
15724
15959
  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(
15960
+ import { resolve as resolve25 } from "path";
15961
+ var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve25(process.cwd(), "..");
15962
+ var SEND_SCRIPT = resolve25(
15728
15963
  PLATFORM_ROOT7,
15729
15964
  "plugins",
15730
15965
  "email",
@@ -15780,10 +16015,10 @@ async function sendMagicLinkEmail(payload) {
15780
16015
  }
15781
16016
 
15782
16017
  // server/routes/access/request-magic-link.ts
15783
- var TAG32 = "[access-request-link]";
15784
- var app42 = new Hono();
16018
+ var TAG33 = "[access-request-link]";
16019
+ var app43 = new Hono();
15785
16020
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
15786
- app42.post("/", async (c) => {
16021
+ app43.post("/", async (c) => {
15787
16022
  let body;
15788
16023
  try {
15789
16024
  body = await c.req.json();
@@ -15797,18 +16032,18 @@ app42.post("/", async (c) => {
15797
16032
  }
15798
16033
  const rateMsg = checkRequestLinkRateLimit(contactValue);
15799
16034
  if (rateMsg) {
15800
- console.error(`${TAG32} contactValue=${maskContact(contactValue)} result=rate-limited`);
16035
+ console.error(`${TAG33} contactValue=${maskContact(contactValue)} result=rate-limited`);
15801
16036
  return c.json({ error: rateMsg }, 429);
15802
16037
  }
15803
16038
  recordRequestLinkAttempt(contactValue);
15804
16039
  const accountId = process.env.ACCOUNT_ID ?? "";
15805
16040
  if (!accountId) {
15806
- console.error(`${TAG32} contactValue=${maskContact(contactValue)} result=no-account-id`);
16041
+ console.error(`${TAG33} contactValue=${maskContact(contactValue)} result=no-account-id`);
15807
16042
  return c.json({ message: VISITOR_MESSAGE }, 200);
15808
16043
  }
15809
16044
  const grant = await findActiveGrantByContact(contactValue, agentSlug, accountId);
15810
16045
  if (!grant) {
15811
- console.log(`${TAG32} contactValue=${maskContact(contactValue)} result=notfound`);
16046
+ console.log(`${TAG33} contactValue=${maskContact(contactValue)} result=notfound`);
15812
16047
  return c.json({ message: VISITOR_MESSAGE }, 200);
15813
16048
  }
15814
16049
  let token;
@@ -15816,7 +16051,7 @@ app42.post("/", async (c) => {
15816
16051
  token = await generateNewMagicToken(grant.grantId);
15817
16052
  } catch (err) {
15818
16053
  console.error(
15819
- `${TAG32} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
16054
+ `${TAG33} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
15820
16055
  );
15821
16056
  return c.json({ message: VISITOR_MESSAGE }, 200);
15822
16057
  }
@@ -15848,26 +16083,26 @@ app42.post("/", async (c) => {
15848
16083
  });
15849
16084
  if (!sendResult.ok) {
15850
16085
  console.error(
15851
- `${TAG32} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
16086
+ `${TAG33} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
15852
16087
  );
15853
16088
  return c.json({ message: VISITOR_MESSAGE }, 200);
15854
16089
  }
15855
16090
  console.log(
15856
- `${TAG32} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
16091
+ `${TAG33} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
15857
16092
  );
15858
16093
  return c.json({ message: VISITOR_MESSAGE }, 200);
15859
16094
  });
15860
- var request_magic_link_default = app42;
16095
+ var request_magic_link_default = app43;
15861
16096
 
15862
16097
  // 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;
16098
+ var app44 = new Hono();
16099
+ app44.route("/verify-token", verify_token_default);
16100
+ app44.route("/request-magic-link", request_magic_link_default);
16101
+ var access_default = app44;
15867
16102
 
15868
16103
  // 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";
16104
+ import { existsSync as existsSync23, readFileSync as readFileSync23, realpathSync as realpathSync5, statSync as statSync10 } from "fs";
16105
+ import { resolve as resolve26 } from "path";
15871
16106
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
15872
16107
  var MIME = {
15873
16108
  ".html": "text/html; charset=utf-8",
@@ -15898,8 +16133,8 @@ function getExt(p) {
15898
16133
  if (idx < p.lastIndexOf("/")) return "";
15899
16134
  return p.slice(idx).toLowerCase();
15900
16135
  }
15901
- var app44 = new Hono();
15902
- app44.get("/:rel{.*}", (c) => {
16136
+ var app45 = new Hono();
16137
+ app45.get("/:rel{.*}", (c) => {
15903
16138
  const reqPath = c.req.path;
15904
16139
  const rawRel = c.req.param("rel") ?? "";
15905
16140
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -15924,15 +16159,15 @@ app44.get("/:rel{.*}", (c) => {
15924
16159
  }
15925
16160
  segments.push(seg);
15926
16161
  }
15927
- const rootDir = resolve25(account.accountDir, "sites");
15928
- let filePath = segments.length === 0 ? rootDir : resolve25(rootDir, ...segments);
16162
+ const rootDir = resolve26(account.accountDir, "sites");
16163
+ let filePath = segments.length === 0 ? rootDir : resolve26(rootDir, ...segments);
15929
16164
  if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
15930
16165
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
15931
16166
  return c.text("Forbidden", 403);
15932
16167
  }
15933
16168
  let stat7;
15934
16169
  try {
15935
- stat7 = existsSync23(filePath) ? statSync9(filePath) : null;
16170
+ stat7 = existsSync23(filePath) ? statSync10(filePath) : null;
15936
16171
  } catch {
15937
16172
  stat7 = null;
15938
16173
  }
@@ -15945,7 +16180,7 @@ app44.get("/:rel{.*}", (c) => {
15945
16180
  return c.redirect(target, 301);
15946
16181
  }
15947
16182
  if (stat7?.isDirectory()) {
15948
- filePath = resolve25(filePath, "index.html");
16183
+ filePath = resolve26(filePath, "index.html");
15949
16184
  }
15950
16185
  if (!filePath.startsWith(rootDir + "/")) {
15951
16186
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
@@ -16002,12 +16237,12 @@ app44.get("/:rel{.*}", (c) => {
16002
16237
  "X-Content-Type-Options": "nosniff"
16003
16238
  });
16004
16239
  });
16005
- var sites_default = app44;
16240
+ var sites_default = app45;
16006
16241
 
16007
16242
  // app/lib/visitor-token.ts
16008
16243
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
16009
16244
  import { mkdirSync as mkdirSync4, readFileSync as readFileSync24, writeFileSync as writeFileSync9 } from "fs";
16010
- import { dirname as dirname6 } from "path";
16245
+ import { dirname as dirname7 } from "path";
16011
16246
  var TOKEN_PREFIX = "v1.";
16012
16247
  var SECRET_BYTES = 32;
16013
16248
  var DEFAULT_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
@@ -16024,7 +16259,7 @@ function getSecret() {
16024
16259
  }
16025
16260
  const fresh = randomBytes(SECRET_BYTES).toString("hex");
16026
16261
  try {
16027
- mkdirSync4(dirname6(VISITOR_TOKEN_SECRET_FILE), { recursive: true, mode: 448 });
16262
+ mkdirSync4(dirname7(VISITOR_TOKEN_SECRET_FILE), { recursive: true, mode: 448 });
16028
16263
  writeFileSync9(VISITOR_TOKEN_SECRET_FILE, fresh, { mode: 384, flag: "wx" });
16029
16264
  console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
16030
16265
  } catch {
@@ -16083,7 +16318,7 @@ var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
16083
16318
 
16084
16319
  // app/lib/brand-config.ts
16085
16320
  import { existsSync as existsSync24, readFileSync as readFileSync25 } from "fs";
16086
- import { join as join22 } from "path";
16321
+ import { join as join23 } from "path";
16087
16322
  var cached2 = null;
16088
16323
  var cachedAttempted = false;
16089
16324
  function readBrandConfig() {
@@ -16091,7 +16326,7 @@ function readBrandConfig() {
16091
16326
  cachedAttempted = true;
16092
16327
  const platformRoot2 = process.env.MAXY_PLATFORM_ROOT;
16093
16328
  if (!platformRoot2) return null;
16094
- const brandPath = join22(platformRoot2, "config", "brand.json");
16329
+ const brandPath = join23(platformRoot2, "config", "brand.json");
16095
16330
  if (!existsSync24(brandPath)) return null;
16096
16331
  try {
16097
16332
  cached2 = JSON.parse(readFileSync25(brandPath, "utf-8"));
@@ -16102,7 +16337,7 @@ function readBrandConfig() {
16102
16337
  }
16103
16338
 
16104
16339
  // server/routes/visitor-consent.ts
16105
- var app45 = new Hono();
16340
+ var app46 = new Hono();
16106
16341
  var CONSENT_COOKIE_NAME = "mxy_consent";
16107
16342
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
16108
16343
  var DEFAULT_CONSENT_COPY = {
@@ -16147,17 +16382,17 @@ function siteSlugFromReferer(referer) {
16147
16382
  return "";
16148
16383
  }
16149
16384
  }
16150
- app45.options("/consent", (c) => {
16385
+ app46.options("/consent", (c) => {
16151
16386
  const origin = getOrigin(c);
16152
16387
  setCorsHeaders(c, origin);
16153
16388
  return c.body(null, 204);
16154
16389
  });
16155
- app45.options("/brand-config", (c) => {
16390
+ app46.options("/brand-config", (c) => {
16156
16391
  const origin = getOrigin(c);
16157
16392
  setCorsHeaders(c, origin);
16158
16393
  return c.body(null, 204);
16159
16394
  });
16160
- app45.post("/consent", async (c) => {
16395
+ app46.post("/consent", async (c) => {
16161
16396
  const origin = getOrigin(c);
16162
16397
  setCorsHeaders(c, origin);
16163
16398
  let raw;
@@ -16197,7 +16432,7 @@ app45.post("/consent", async (c) => {
16197
16432
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
16198
16433
  return c.body(null, 204);
16199
16434
  });
16200
- app45.get("/brand-config", (c) => {
16435
+ app46.get("/brand-config", (c) => {
16201
16436
  const origin = getOrigin(c);
16202
16437
  setCorsHeaders(c, origin);
16203
16438
  const brand = readBrandConfig();
@@ -16207,7 +16442,7 @@ app45.get("/brand-config", (c) => {
16207
16442
  c.header("Cache-Control", "public, max-age=300");
16208
16443
  return c.json({ consent: { copy, palette } });
16209
16444
  });
16210
- var visitor_consent_default = app45;
16445
+ var visitor_consent_default = app46;
16211
16446
 
16212
16447
  // server/routes/listings.ts
16213
16448
  function getCookie(headerValue, name) {
@@ -16228,14 +16463,14 @@ function appendConsentParams(pageUrl, token) {
16228
16463
  const hashIdx = pageUrl.indexOf("#");
16229
16464
  const hash = hashIdx >= 0 ? pageUrl.slice(hashIdx) : "";
16230
16465
  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;
16466
+ const sep9 = base.indexOf("?") >= 0 ? "&" : "?";
16467
+ return base + sep9 + `consent=needed&v=${encodeURIComponent(token)}` + hash;
16233
16468
  }
16234
16469
  }
16235
16470
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
16236
16471
  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) => {
16472
+ var app47 = new Hono();
16473
+ app47.get("/:slug/click", async (c) => {
16239
16474
  const slug = c.req.param("slug") ?? "";
16240
16475
  const rawSession = c.req.query("session") ?? "";
16241
16476
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -16299,10 +16534,10 @@ app46.get("/:slug/click", async (c) => {
16299
16534
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
16300
16535
  return c.redirect(redirectUrl, 302);
16301
16536
  });
16302
- var listings_default = app46;
16537
+ var listings_default = app47;
16303
16538
 
16304
16539
  // server/routes/visitor-event.ts
16305
- var app47 = new Hono();
16540
+ var app48 = new Hono();
16306
16541
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
16307
16542
  var buckets = /* @__PURE__ */ new Map();
16308
16543
  var RATE_LIMIT = 60;
@@ -16369,12 +16604,12 @@ function originAllowed(origin, allowlist) {
16369
16604
  return false;
16370
16605
  }
16371
16606
  }
16372
- app47.options("/event", (c) => {
16607
+ app48.options("/event", (c) => {
16373
16608
  const origin = getOrigin2(c);
16374
16609
  setCorsHeaders2(c, origin);
16375
16610
  return c.body(null, 204);
16376
16611
  });
16377
- app47.post("/event", async (c) => {
16612
+ app48.post("/event", async (c) => {
16378
16613
  const origin = getOrigin2(c);
16379
16614
  setCorsHeaders2(c, origin);
16380
16615
  const ua = c.req.header("user-agent") ?? "";
@@ -16579,17 +16814,17 @@ async function writeEvent(opts) {
16579
16814
  );
16580
16815
  }
16581
16816
  }
16582
- var visitor_event_default = app47;
16817
+ var visitor_event_default = app48;
16583
16818
 
16584
16819
  // server/routes/session.ts
16585
- import { resolve as resolve26 } from "path";
16820
+ import { resolve as resolve27 } from "path";
16586
16821
  import { existsSync as existsSync25, writeFileSync as writeFileSync10, mkdirSync as mkdirSync5 } from "fs";
16587
16822
  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
16823
  function writeBrandingCache(accountId, agentSlug, branding) {
16589
16824
  try {
16590
- const cacheDir = resolve26(MAXY_DIR, "branding-cache", accountId);
16825
+ const cacheDir = resolve27(MAXY_DIR, "branding-cache", accountId);
16591
16826
  mkdirSync5(cacheDir, { recursive: true });
16592
- writeFileSync10(resolve26(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
16827
+ writeFileSync10(resolve27(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
16593
16828
  } catch (err) {
16594
16829
  console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
16595
16830
  }
@@ -16601,7 +16836,7 @@ function parseVisitorCookie(cookieHeader) {
16601
16836
  const value = decodeURIComponent(match[1]).trim();
16602
16837
  return UUID_RE4.test(value) ? value : null;
16603
16838
  }
16604
- function parseAccessSessionId(cookieHeader) {
16839
+ function parseAccessSessionId2(cookieHeader) {
16605
16840
  if (!cookieHeader) return null;
16606
16841
  const part = cookieHeader.split(";").map((p) => p.trim()).find((p) => p.startsWith("__access_session="));
16607
16842
  return part ? part.slice("__access_session=".length) : null;
@@ -16625,8 +16860,8 @@ function withVisitorCookie(response, visitorId) {
16625
16860
  headers
16626
16861
  });
16627
16862
  }
16628
- var app48 = new Hono();
16629
- app48.post("/", async (c) => {
16863
+ var app49 = new Hono();
16864
+ app49.post("/", async (c) => {
16630
16865
  let body;
16631
16866
  try {
16632
16867
  body = await c.req.json();
@@ -16677,8 +16912,8 @@ app48.post("/", async (c) => {
16677
16912
  }
16678
16913
  let agentConfig = null;
16679
16914
  if (account) {
16680
- const agentDir = resolve26(account.accountDir, "agents", agentSlug);
16681
- if (!existsSync25(agentDir) || !existsSync25(resolve26(agentDir, "config.json"))) {
16915
+ const agentDir = resolve27(account.accountDir, "agents", agentSlug);
16916
+ if (!existsSync25(agentDir) || !existsSync25(resolve27(agentDir, "config.json"))) {
16682
16917
  return c.json({ error: "Agent not found" }, 404);
16683
16918
  }
16684
16919
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -16698,7 +16933,7 @@ app48.post("/", async (c) => {
16698
16933
  if (branding) writeBrandingCache(accountId, agentSlug, branding);
16699
16934
  let accessSession = null;
16700
16935
  if (agentConfig && agentConfig.accessMode !== "open") {
16701
- const accessSessionId = parseAccessSessionId(cookieHeader);
16936
+ const accessSessionId = parseAccessSessionId2(cookieHeader);
16702
16937
  accessSession = accessSessionId ? getAccessSession(accessSessionId) : null;
16703
16938
  if (!accessSession || accessSession.agentSlug !== agentSlug) {
16704
16939
  console.log(`[session] agent=${agentSlug} accessMode=${agentConfig.accessMode} \u2014 auth required`);
@@ -16837,7 +17072,7 @@ app48.post("/", async (c) => {
16837
17072
  newVisitorId
16838
17073
  );
16839
17074
  });
16840
- var session_default2 = app48;
17075
+ var session_default2 = app49;
16841
17076
 
16842
17077
  // app/lib/graph-health.ts
16843
17078
  var import_dist4 = __toESM(require_dist3(), 1);
@@ -16958,13 +17193,13 @@ function startGraphHealthTimer() {
16958
17193
 
16959
17194
  // app/lib/file-watcher.ts
16960
17195
  import * as fsp2 from "fs/promises";
16961
- import { resolve as resolve27, sep as sep7 } from "path";
17196
+ import { resolve as resolve28, sep as sep8 } from "path";
16962
17197
  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
17198
  var DEFAULT_COALESCE_MS = 500;
16964
17199
  var ROOTS = ["accounts"];
16965
17200
  function _routeEvent(rootName, filename) {
16966
17201
  if (!filename) return null;
16967
- const segs = filename.split(sep7).filter(Boolean);
17202
+ const segs = filename.split(sep8).filter(Boolean);
16968
17203
  if (segs.length < 2) return null;
16969
17204
  const accountId = segs[0];
16970
17205
  if (!ACCOUNT_UUID_RE2.test(accountId)) return null;
@@ -16977,7 +17212,7 @@ async function startFileWatcher(opts = {}) {
16977
17212
  const dropFn = opts.drop ?? dropFileIndex;
16978
17213
  for (const r of ROOTS) {
16979
17214
  try {
16980
- await fsp2.mkdir(resolve27(dataRoot, r), { recursive: true });
17215
+ await fsp2.mkdir(resolve28(dataRoot, r), { recursive: true });
16981
17216
  } catch (err) {
16982
17217
  console.error(
16983
17218
  `[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
@@ -16998,7 +17233,7 @@ async function startFileWatcher(opts = {}) {
16998
17233
  timers.set(relativePath, t);
16999
17234
  }
17000
17235
  async function runHook(relativePath, accountId) {
17001
- const absolute = resolve27(dataRoot, relativePath);
17236
+ const absolute = resolve28(dataRoot, relativePath);
17002
17237
  let exists = false;
17003
17238
  try {
17004
17239
  const st = await fsp2.stat(absolute);
@@ -17022,7 +17257,7 @@ async function startFileWatcher(opts = {}) {
17022
17257
  }
17023
17258
  }
17024
17259
  async function watchRoot(rootName) {
17025
- const absRoot = resolve27(dataRoot, rootName);
17260
+ const absRoot = resolve28(dataRoot, rootName);
17026
17261
  try {
17027
17262
  const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
17028
17263
  for await (const event of iter) {
@@ -17061,7 +17296,7 @@ async function startFileWatcher(opts = {}) {
17061
17296
 
17062
17297
  // app/lib/migrate-uploads.ts
17063
17298
  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";
17299
+ import { dirname as dirname8, relative as relative4, resolve as resolve29 } from "path";
17065
17300
  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
17301
  async function walkFiles(dir) {
17067
17302
  const out = [];
@@ -17072,7 +17307,7 @@ async function walkFiles(dir) {
17072
17307
  return out;
17073
17308
  }
17074
17309
  for (const e of entries) {
17075
- const abs = resolve28(dir, e.name);
17310
+ const abs = resolve29(dir, e.name);
17076
17311
  if (e.isDirectory()) {
17077
17312
  out.push(...await walkFiles(abs));
17078
17313
  } else if (e.isFile()) {
@@ -17092,8 +17327,8 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
17092
17327
  let moved = 0;
17093
17328
  for (const oldAbs of files) {
17094
17329
  const suffix = relative4(srcDir, oldAbs);
17095
- const newAbs = resolve28(destDir, suffix);
17096
- await mkdir5(dirname7(newAbs), { recursive: true });
17330
+ const newAbs = resolve29(destDir, suffix);
17331
+ await mkdir5(dirname8(newAbs), { recursive: true });
17097
17332
  await rename(oldAbs, newAbs);
17098
17333
  moved++;
17099
17334
  const oldRel = relative4(dataRoot, oldAbs);
@@ -17119,7 +17354,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
17119
17354
  }
17120
17355
  async function migrateUploads(opts = {}) {
17121
17356
  const dataRoot = opts.dataRoot ?? DATA_ROOT;
17122
- const oldRoot = resolve28(dataRoot, "uploads");
17357
+ const oldRoot = resolve29(dataRoot, "uploads");
17123
17358
  let topEntries;
17124
17359
  try {
17125
17360
  topEntries = await readdir5(oldRoot, { withFileTypes: true });
@@ -17140,8 +17375,8 @@ async function migrateUploads(opts = {}) {
17140
17375
  const name = entry.name;
17141
17376
  if (ACCOUNT_UUID_RE3.test(name)) {
17142
17377
  moved += await relocateTree(
17143
- resolve28(oldRoot, name),
17144
- resolve28(dataRoot, "accounts", name, "uploads"),
17378
+ resolve29(oldRoot, name),
17379
+ resolve29(dataRoot, "accounts", name, "uploads"),
17145
17380
  dataRoot,
17146
17381
  name,
17147
17382
  session
@@ -17153,8 +17388,8 @@ async function migrateUploads(opts = {}) {
17153
17388
  continue;
17154
17389
  }
17155
17390
  moved += await relocateTree(
17156
- resolve28(oldRoot, "public"),
17157
- resolve28(dataRoot, "accounts", installAccountId, "uploads", "public"),
17391
+ resolve29(oldRoot, "public"),
17392
+ resolve29(dataRoot, "accounts", installAccountId, "uploads", "public"),
17158
17393
  dataRoot,
17159
17394
  null,
17160
17395
  // public uploads carry no graph nodes
@@ -17185,7 +17420,7 @@ async function migrateUploads(opts = {}) {
17185
17420
  // app/lib/migrate-admin-webchat-sidecars.ts
17186
17421
  import { readdir as readdir6, readFile as readFile6, rename as rename2, writeFile as writeFile5, unlink as unlink3 } from "fs/promises";
17187
17422
  import { existsSync as existsSync26 } from "fs";
17188
- import { join as join23 } from "path";
17423
+ import { join as join24 } from "path";
17189
17424
  var ADMIN_ROLE2 = "admin";
17190
17425
  var WEBCHAT_CHANNEL2 = "webchat";
17191
17426
  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 +17465,7 @@ async function collectLiveSidecars(projectsRoot) {
17230
17465
  }
17231
17466
  for (const slug of slugs) {
17232
17467
  if (!slug.isDirectory()) continue;
17233
- const slugDir = join23(projectsRoot, slug.name);
17468
+ const slugDir = join24(projectsRoot, slug.name);
17234
17469
  let entries;
17235
17470
  try {
17236
17471
  entries = await readdir6(slugDir, { withFileTypes: true });
@@ -17239,9 +17474,9 @@ async function collectLiveSidecars(projectsRoot) {
17239
17474
  }
17240
17475
  for (const entry of entries) {
17241
17476
  if (entry.isFile() && SESSION_META_RE.test(entry.name)) {
17242
- out.push(join23(slugDir, entry.name));
17477
+ out.push(join24(slugDir, entry.name));
17243
17478
  } else if (entry.isDirectory() && entry.name === "subagents") {
17244
- const subDir = join23(slugDir, entry.name);
17479
+ const subDir = join24(slugDir, entry.name);
17245
17480
  let subs;
17246
17481
  try {
17247
17482
  subs = await readdir6(subDir, { withFileTypes: true });
@@ -17249,7 +17484,7 @@ async function collectLiveSidecars(projectsRoot) {
17249
17484
  continue;
17250
17485
  }
17251
17486
  for (const s of subs) {
17252
- if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join23(subDir, s.name));
17487
+ if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join24(subDir, s.name));
17253
17488
  }
17254
17489
  }
17255
17490
  }
@@ -17261,7 +17496,7 @@ function shortId(path2) {
17261
17496
  return base.slice(0, 8);
17262
17497
  }
17263
17498
  async function migrateAdminWebchatSidecars(opts = {}) {
17264
- const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join23(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
17499
+ const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join24(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
17265
17500
  const usersFile = opts.usersFile ?? USERS_FILE;
17266
17501
  const accountId = opts.accountId ?? resolveAccount()?.accountId ?? null;
17267
17502
  const resolveName = opts.resolveName ?? defaultResolveName;
@@ -17603,8 +17838,8 @@ var streamSSE = (c, cb, onError) => {
17603
17838
 
17604
17839
  // app/lib/whatsapp/gateway/routes.ts
17605
17840
  function createWaChannelRoutes(deps) {
17606
- const app50 = new Hono();
17607
- app50.get("/wa-channel/inbound", (c) => {
17841
+ const app51 = new Hono();
17842
+ app51.get("/wa-channel/inbound", (c) => {
17608
17843
  const senderId = c.req.query("senderId");
17609
17844
  if (!senderId) return c.json({ error: "senderId required" }, 400);
17610
17845
  return streamSSE(c, async (stream2) => {
@@ -17622,7 +17857,7 @@ function createWaChannelRoutes(deps) {
17622
17857
  }
17623
17858
  });
17624
17859
  });
17625
- app50.post("/wa-channel/reply", async (c) => {
17860
+ app51.post("/wa-channel/reply", async (c) => {
17626
17861
  const body = await c.req.json().catch(() => null);
17627
17862
  const senderId = body?.senderId;
17628
17863
  const text = body?.text;
@@ -17643,7 +17878,7 @@ function createWaChannelRoutes(deps) {
17643
17878
  console.error(`[whatsapp-native] op=reply-dispatch senderId=${senderId} bytes=${bytes}`);
17644
17879
  return c.json({ ok: true });
17645
17880
  });
17646
- app50.post("/wa-channel/reply-document", async (c) => {
17881
+ app51.post("/wa-channel/reply-document", async (c) => {
17647
17882
  const body = await c.req.json().catch(() => null);
17648
17883
  const senderId = body?.senderId;
17649
17884
  const files = body?.files;
@@ -17682,7 +17917,7 @@ function createWaChannelRoutes(deps) {
17682
17917
  }
17683
17918
  return c.json({ ok: true, results });
17684
17919
  });
17685
- app50.post("/wa-channel/ready", async (c) => {
17920
+ app51.post("/wa-channel/ready", async (c) => {
17686
17921
  const body = await c.req.json().catch(() => null);
17687
17922
  const senderId = body?.senderId;
17688
17923
  if (typeof senderId !== "string") {
@@ -17691,7 +17926,7 @@ function createWaChannelRoutes(deps) {
17691
17926
  deps.onReady?.(senderId);
17692
17927
  return c.json({ ok: true });
17693
17928
  });
17694
- app50.post("/wa-channel/received", async (c) => {
17929
+ app51.post("/wa-channel/received", async (c) => {
17695
17930
  const body = await c.req.json().catch(() => null);
17696
17931
  const senderId = body?.senderId;
17697
17932
  const waMessageId = body?.waMessageId;
@@ -17701,7 +17936,7 @@ function createWaChannelRoutes(deps) {
17701
17936
  deps.onReceived?.(senderId, waMessageId);
17702
17937
  return c.json({ ok: true });
17703
17938
  });
17704
- app50.post("/wa-channel/turn-end", async (c) => {
17939
+ app51.post("/wa-channel/turn-end", async (c) => {
17705
17940
  const body = await c.req.json().catch(() => null);
17706
17941
  const senderId = body?.senderId;
17707
17942
  const sessionId = body?.sessionId;
@@ -17732,7 +17967,7 @@ function createWaChannelRoutes(deps) {
17732
17967
  console.error(`[whatsapp-native] op=turn-end sessionId=${sid} replied=no delivered=fallback bytes=${bytes}`);
17733
17968
  return c.json({ ok: true, delivered: "fallback" });
17734
17969
  });
17735
- return app50;
17970
+ return app51;
17736
17971
  }
17737
17972
 
17738
17973
  // app/lib/whatsapp/gateway/wa-gateway.ts
@@ -17985,8 +18220,8 @@ var InboundHub2 = class {
17985
18220
 
17986
18221
  // app/lib/webchat/gateway/routes.ts
17987
18222
  function createWebchatChannelRoutes(deps) {
17988
- const app50 = new Hono();
17989
- app50.get("/webchat-channel/inbound", (c) => {
18223
+ const app51 = new Hono();
18224
+ app51.get("/webchat-channel/inbound", (c) => {
17990
18225
  const key = c.req.query("key");
17991
18226
  if (!key) return c.json({ error: "key required" }, 400);
17992
18227
  return streamSSE(c, async (stream2) => {
@@ -18004,7 +18239,7 @@ function createWebchatChannelRoutes(deps) {
18004
18239
  }
18005
18240
  });
18006
18241
  });
18007
- app50.post("/webchat-channel/reply", async (c) => {
18242
+ app51.post("/webchat-channel/reply", async (c) => {
18008
18243
  const body = await c.req.json().catch(() => null);
18009
18244
  const key = body?.key;
18010
18245
  const text = body?.text;
@@ -18014,7 +18249,7 @@ function createWebchatChannelRoutes(deps) {
18014
18249
  deps.onReply?.(key, text);
18015
18250
  return c.json({ ok: true });
18016
18251
  });
18017
- app50.post("/webchat-channel/ready", async (c) => {
18252
+ app51.post("/webchat-channel/ready", async (c) => {
18018
18253
  const body = await c.req.json().catch(() => null);
18019
18254
  const key = body?.key;
18020
18255
  if (typeof key !== "string") {
@@ -18023,7 +18258,7 @@ function createWebchatChannelRoutes(deps) {
18023
18258
  deps.onReady?.(key);
18024
18259
  return c.json({ ok: true });
18025
18260
  });
18026
- app50.post("/webchat-channel/received", async (c) => {
18261
+ app51.post("/webchat-channel/received", async (c) => {
18027
18262
  const body = await c.req.json().catch(() => null);
18028
18263
  const key = body?.key;
18029
18264
  const messageId = body?.messageId;
@@ -18033,7 +18268,7 @@ function createWebchatChannelRoutes(deps) {
18033
18268
  deps.onReceived?.(key, messageId);
18034
18269
  return c.json({ ok: true });
18035
18270
  });
18036
- return app50;
18271
+ return app51;
18037
18272
  }
18038
18273
 
18039
18274
  // app/lib/webchat/gateway/webchat-gateway.ts
@@ -18068,16 +18303,16 @@ var WebchatGateway = class {
18068
18303
  * The public /api/chat route awaits this to return the reply on the same SSE
18069
18304
  * response, preserving the pre-756 POST→single-blob browser contract. */
18070
18305
  awaitReply(key, timeoutMs) {
18071
- return new Promise((resolve31) => {
18306
+ return new Promise((resolve32) => {
18072
18307
  const timer2 = setTimeout(() => {
18073
18308
  this.replyAwaiters.delete(key);
18074
- resolve31({ timeout: true });
18309
+ resolve32({ timeout: true });
18075
18310
  }, timeoutMs);
18076
18311
  if (timer2.unref) timer2.unref();
18077
18312
  this.replyAwaiters.set(key, (r) => {
18078
18313
  clearTimeout(timer2);
18079
18314
  this.replyAwaiters.delete(key);
18080
- resolve31(r);
18315
+ resolve32(r);
18081
18316
  });
18082
18317
  });
18083
18318
  }
@@ -18346,8 +18581,8 @@ function broadcastAdminShutdown(reason) {
18346
18581
 
18347
18582
  // ../lib/entitlement/src/index.ts
18348
18583
  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";
18584
+ import { existsSync as existsSync27, readFileSync as readFileSync26, statSync as statSync11 } from "fs";
18585
+ import { resolve as resolve30 } from "path";
18351
18586
 
18352
18587
  // ../lib/entitlement/src/canonicalize.ts
18353
18588
  function canonicalize(value) {
@@ -18382,7 +18617,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
18382
18617
  var GRACE_DAYS = 7;
18383
18618
  var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
18384
18619
  function pubkeyPath(brand) {
18385
- return resolve29(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
18620
+ return resolve30(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
18386
18621
  }
18387
18622
  var memo = null;
18388
18623
  function memoKey(mtimeMs, account) {
@@ -18394,11 +18629,11 @@ function resolveEntitlement(brand, account) {
18394
18629
  if (brand.commercialMode !== true) {
18395
18630
  return logResolved(implicitTrust(account), null);
18396
18631
  }
18397
- const entitlementPath = resolve29(brand.configDir, "entitlement.json");
18632
+ const entitlementPath = resolve30(brand.configDir, "entitlement.json");
18398
18633
  if (!existsSync27(entitlementPath)) {
18399
18634
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
18400
18635
  }
18401
- const stat7 = statSync10(entitlementPath);
18636
+ const stat7 = statSync11(entitlementPath);
18402
18637
  const key = memoKey(stat7.mtimeMs, account);
18403
18638
  if (memo && memo.key === key) {
18404
18639
  return memo.result;
@@ -18585,7 +18820,7 @@ function clientFrom(c) {
18585
18820
  );
18586
18821
  }
18587
18822
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
18588
- var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join24(PLATFORM_ROOT8, "config", "brand.json") : "";
18823
+ var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join25(PLATFORM_ROOT8, "config", "brand.json") : "";
18589
18824
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
18590
18825
  if (BRAND_JSON_PATH && !existsSync28(BRAND_JSON_PATH)) {
18591
18826
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
@@ -18611,7 +18846,7 @@ var brandLoginOpts = {
18611
18846
  bodyFont: BRAND.defaultFonts?.body,
18612
18847
  logoContainsName: !!BRAND.logoContainsName
18613
18848
  };
18614
- var ALIAS_DOMAINS_PATH = join24(homedir3(), BRAND.configDir, "alias-domains.json");
18849
+ var ALIAS_DOMAINS_PATH = join25(homedir3(), BRAND.configDir, "alias-domains.json");
18615
18850
  function loadAliasDomains() {
18616
18851
  try {
18617
18852
  if (!existsSync28(ALIAS_DOMAINS_PATH)) return null;
@@ -18639,11 +18874,11 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
18639
18874
  function isPublicHost(host) {
18640
18875
  return host.startsWith("public.") || aliasDomains.has(host);
18641
18876
  }
18642
- var app49 = new Hono();
18877
+ var app50 = new Hono();
18643
18878
  var nativeFileFollowers = /* @__PURE__ */ new Map();
18644
18879
  var waGateway = new WaGateway({
18645
18880
  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"),
18881
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve31(process.env.MAXY_PLATFORM_ROOT ?? join25(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
18647
18882
  // Task 751 — file delivery on the native channel: resolve the platform
18648
18883
  // account + path validation here and funnel through the shared send core.
18649
18884
  sendDocument: async ({ senderId, accountId, filePath, caption }) => {
@@ -18659,7 +18894,7 @@ var waGateway = new WaGateway({
18659
18894
  caption,
18660
18895
  accountId,
18661
18896
  maxyAccountId,
18662
- platformRoot: resolve30(process.env.MAXY_PLATFORM_ROOT ?? join24(__dirname, ".."))
18897
+ platformRoot: resolve31(process.env.MAXY_PLATFORM_ROOT ?? join25(__dirname, ".."))
18663
18898
  });
18664
18899
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
18665
18900
  },
@@ -18689,7 +18924,7 @@ var waGateway = new WaGateway({
18689
18924
  nativeFileFollowers.set(senderId, ac);
18690
18925
  }
18691
18926
  });
18692
- app49.route("/", waGateway.routes());
18927
+ app50.route("/", waGateway.routes());
18693
18928
  waGateway.startSweeper();
18694
18929
  var webchatGateway = new WebchatGateway({
18695
18930
  gatewayUrl: webchatGatewayUrl(),
@@ -18729,15 +18964,15 @@ var webchatGateway = new WebchatGateway({
18729
18964
  deleteSession: (sessionId) => managerDelete(sessionId),
18730
18965
  firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
18731
18966
  });
18732
- app49.route("/", webchatGateway.routes());
18967
+ app50.route("/", webchatGateway.routes());
18733
18968
  webchatGateway.startSweeper();
18734
18969
  webchatGateway.startPublicReaper();
18735
18970
  var chatRoutes = createChatRoutes({
18736
18971
  handleInbound: (input) => webchatGateway.handleInbound(input),
18737
18972
  awaitReply: (key, timeoutMs) => webchatGateway.awaitReply(key, timeoutMs)
18738
18973
  });
18739
- app49.use("*", clientIpMiddleware);
18740
- app49.use("*", async (c, next) => {
18974
+ app50.use("*", clientIpMiddleware);
18975
+ app50.use("*", async (c, next) => {
18741
18976
  await next();
18742
18977
  c.header("X-Content-Type-Options", "nosniff");
18743
18978
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
@@ -18747,7 +18982,7 @@ app49.use("*", async (c, next) => {
18747
18982
  );
18748
18983
  });
18749
18984
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
18750
- app49.use("*", async (c, next) => {
18985
+ app50.use("*", async (c, next) => {
18751
18986
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
18752
18987
  await next();
18753
18988
  return;
@@ -18765,7 +19000,7 @@ app49.use("*", async (c, next) => {
18765
19000
  });
18766
19001
  }
18767
19002
  });
18768
- app49.use("*", async (c, next) => {
19003
+ app50.use("*", async (c, next) => {
18769
19004
  const host = (c.req.header("host") ?? "").split(":")[0];
18770
19005
  if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
18771
19006
  await next();
@@ -18796,7 +19031,7 @@ function resolveRemoteAuthOpts() {
18796
19031
  return brandLoginOpts;
18797
19032
  }
18798
19033
  var MAX_LOGIN_BODY = 8 * 1024;
18799
- app49.post("/__remote-auth/login", async (c) => {
19034
+ app50.post("/__remote-auth/login", async (c) => {
18800
19035
  const client = clientFrom(c);
18801
19036
  const clientIp = client.ip || "unknown";
18802
19037
  if (!requestIsTlsTerminated(c)) {
@@ -18841,7 +19076,7 @@ app49.post("/__remote-auth/login", async (c) => {
18841
19076
  }
18842
19077
  });
18843
19078
  });
18844
- app49.get("/__remote-auth/logout", (c) => {
19079
+ app50.get("/__remote-auth/logout", (c) => {
18845
19080
  const client = clientFrom(c);
18846
19081
  const clientIp = client.ip || "unknown";
18847
19082
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -18854,7 +19089,7 @@ app49.get("/__remote-auth/logout", (c) => {
18854
19089
  }
18855
19090
  });
18856
19091
  });
18857
- app49.post("/__remote-auth/change-password", async (c) => {
19092
+ app50.post("/__remote-auth/change-password", async (c) => {
18858
19093
  const client = clientFrom(c);
18859
19094
  const clientIp = client.ip || "unknown";
18860
19095
  const rateLimited = checkRateLimit(client);
@@ -18896,6 +19131,9 @@ app49.post("/__remote-auth/change-password", async (c) => {
18896
19131
  redirect
18897
19132
  }), 200);
18898
19133
  }
19134
+ if (targetUserId && await accessPasswordCollides(newPassword, USERS_FILE, targetUserId)) {
19135
+ return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "That password is already in use by another admin. Choose a different one.", redirect }), 200);
19136
+ }
18899
19137
  try {
18900
19138
  if (targetUserId) {
18901
19139
  await setAccessPassword(targetUserId, newPassword, USERS_FILE);
@@ -18910,13 +19148,13 @@ app49.post("/__remote-auth/change-password", async (c) => {
18910
19148
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
18911
19149
  }
18912
19150
  });
18913
- app49.get("/__remote-auth/setup", (c) => {
19151
+ app50.get("/__remote-auth/setup", (c) => {
18914
19152
  if (isRemoteAuthConfigured()) {
18915
19153
  return c.redirect("/");
18916
19154
  }
18917
19155
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
18918
19156
  });
18919
- app49.post("/__remote-auth/set-initial-password", async (c) => {
19157
+ app50.post("/__remote-auth/set-initial-password", async (c) => {
18920
19158
  if (isRemoteAuthConfigured()) {
18921
19159
  return c.redirect("/");
18922
19160
  }
@@ -18954,10 +19192,10 @@ app49.post("/__remote-auth/set-initial-password", async (c) => {
18954
19192
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
18955
19193
  }
18956
19194
  });
18957
- app49.get("/api/remote-auth/status", (c) => {
19195
+ app50.get("/api/remote-auth/status", (c) => {
18958
19196
  return c.json({ configured: isRemoteAuthConfigured() });
18959
19197
  });
18960
- app49.post("/api/remote-auth/set-password", async (c) => {
19198
+ app50.post("/api/remote-auth/set-password", async (c) => {
18961
19199
  let body;
18962
19200
  try {
18963
19201
  body = await c.req.json();
@@ -18980,6 +19218,9 @@ app49.post("/api/remote-auth/set-password", async (c) => {
18980
19218
  requirements
18981
19219
  }, 400);
18982
19220
  }
19221
+ if (sessionUserId && await accessPasswordCollides(body.password, USERS_FILE, sessionUserId)) {
19222
+ return c.json({ error: "That password is already in use by another admin. Choose a different one." }, 400);
19223
+ }
18983
19224
  try {
18984
19225
  if (sessionUserId) {
18985
19226
  await setAccessPassword(sessionUserId, body.password, USERS_FILE);
@@ -18993,10 +19234,10 @@ app49.post("/api/remote-auth/set-password", async (c) => {
18993
19234
  return c.json({ error: "Failed to save password" }, 500);
18994
19235
  }
18995
19236
  });
18996
- app49.route("/api/_client-error", client_error_default);
19237
+ app50.route("/api/_client-error", client_error_default);
18997
19238
  console.log("[client-error-route] mounted");
18998
19239
  var PWA_PUBLIC_PATHS = /* @__PURE__ */ new Set(["/sw.js", ...PWA_SURFACES.map((s) => s.manifestPath)]);
18999
- app49.use("*", async (c, next) => {
19240
+ app50.use("*", async (c, next) => {
19000
19241
  const host = (c.req.header("host") ?? "").split(":")[0];
19001
19242
  const path2 = c.req.path;
19002
19243
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/") || PWA_PUBLIC_PATHS.has(path2)) {
@@ -19036,17 +19277,18 @@ app49.use("*", async (c, next) => {
19036
19277
  }
19037
19278
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
19038
19279
  });
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);
19280
+ app50.route("/api/health", health_default);
19281
+ app50.route("/api/chat", chatRoutes);
19282
+ app50.route("/api/whatsapp", whatsapp_default);
19283
+ app50.route("/api/whatsapp-reader", whatsapp_reader_default);
19284
+ app50.route("/api/public-reader", public_reader_default);
19285
+ app50.route("/api/webchat", createWebchatRoutes({ handleInbound: (input) => webchatGateway.handleInbound(input) }));
19286
+ app50.route("/api/webchat/greeting", webchat_greeting_default);
19287
+ app50.route("/api/telegram", telegram_default);
19288
+ app50.route("/api/onboarding", onboarding_default);
19289
+ app50.route("/api/admin", admin_default);
19290
+ app50.route("/api/access", access_default);
19291
+ app50.route("/api/session", session_default2);
19050
19292
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
19051
19293
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
19052
19294
  var IMAGE_MIME = {
@@ -19058,7 +19300,7 @@ var IMAGE_MIME = {
19058
19300
  ".svg": "image/svg+xml",
19059
19301
  ".ico": "image/x-icon"
19060
19302
  };
19061
- app49.get("/agent-assets/:slug/:filename", (c) => {
19303
+ app50.get("/agent-assets/:slug/:filename", (c) => {
19062
19304
  const slug = c.req.param("slug");
19063
19305
  const filename = c.req.param("filename");
19064
19306
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -19074,8 +19316,8 @@ app49.get("/agent-assets/:slug/:filename", (c) => {
19074
19316
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
19075
19317
  return c.text("Not found", 404);
19076
19318
  }
19077
- const filePath = resolve30(account.accountDir, "agents", slug, "assets", filename);
19078
- const expectedDir = resolve30(account.accountDir, "agents", slug, "assets");
19319
+ const filePath = resolve31(account.accountDir, "agents", slug, "assets", filename);
19320
+ const expectedDir = resolve31(account.accountDir, "agents", slug, "assets");
19079
19321
  if (!filePath.startsWith(expectedDir + "/")) {
19080
19322
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
19081
19323
  return c.text("Forbidden", 403);
@@ -19093,7 +19335,7 @@ app49.get("/agent-assets/:slug/:filename", (c) => {
19093
19335
  "Cache-Control": "public, max-age=3600"
19094
19336
  });
19095
19337
  });
19096
- app49.get("/generated/:filename", (c) => {
19338
+ app50.get("/generated/:filename", (c) => {
19097
19339
  const filename = c.req.param("filename");
19098
19340
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
19099
19341
  console.error(`[generated] serve file=${filename} status=403`);
@@ -19104,8 +19346,8 @@ app49.get("/generated/:filename", (c) => {
19104
19346
  console.error(`[generated] serve file=${filename} status=404`);
19105
19347
  return c.text("Not found", 404);
19106
19348
  }
19107
- const filePath = resolve30(account.accountDir, "generated", filename);
19108
- const expectedDir = resolve30(account.accountDir, "generated");
19349
+ const filePath = resolve31(account.accountDir, "generated", filename);
19350
+ const expectedDir = resolve31(account.accountDir, "generated");
19109
19351
  if (!filePath.startsWith(expectedDir + "/")) {
19110
19352
  console.error(`[generated] serve file=${filename} status=403`);
19111
19353
  return c.text("Forbidden", 403);
@@ -19123,10 +19365,10 @@ app49.get("/generated/:filename", (c) => {
19123
19365
  "Cache-Control": "public, max-age=86400"
19124
19366
  });
19125
19367
  });
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);
19368
+ app50.route("/sites", sites_default);
19369
+ app50.route("/listings", listings_default);
19370
+ app50.route("/v", visitor_event_default);
19371
+ app50.route("/v", visitor_consent_default);
19130
19372
  var htmlCache = /* @__PURE__ */ new Map();
19131
19373
  var brandLogoPath = "/brand/maxy-monochrome.png";
19132
19374
  var brandIconPath = "/brand/maxy-monochrome.png";
@@ -19148,11 +19390,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
19148
19390
  })}</script>`;
19149
19391
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
19150
19392
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
19151
- var brandIconFsPath = resolve30(process.cwd(), "public", brandIconPath.replace(/^\//, ""));
19393
+ var brandIconFsPath = resolve31(process.cwd(), "public", brandIconPath.replace(/^\//, ""));
19152
19394
  var brandIconExists = existsSync28(brandIconFsPath);
19153
19395
  var SW_SOURCE = (() => {
19154
19396
  try {
19155
- return readFileSync27(resolve30(process.cwd(), "public", "sw.js"), "utf-8");
19397
+ return readFileSync27(resolve31(process.cwd(), "public", "sw.js"), "utf-8");
19156
19398
  } catch {
19157
19399
  return null;
19158
19400
  }
@@ -19160,7 +19402,7 @@ var SW_SOURCE = (() => {
19160
19402
  function readInstalledVersion() {
19161
19403
  try {
19162
19404
  if (!PLATFORM_ROOT8) return "unknown";
19163
- const versionFile = join24(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
19405
+ const versionFile = join25(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
19164
19406
  if (!existsSync28(versionFile)) return "unknown";
19165
19407
  const content = readFileSync27(versionFile, "utf-8").trim();
19166
19408
  return content || "unknown";
@@ -19203,7 +19445,7 @@ var clientErrorReporterScript = `<script>
19203
19445
  function cachedHtml(file) {
19204
19446
  let html = htmlCache.get(file);
19205
19447
  if (!html) {
19206
- html = readFileSync27(resolve30(process.cwd(), "public", file), "utf-8");
19448
+ html = readFileSync27(resolve31(process.cwd(), "public", file), "utf-8");
19207
19449
  const productNameEsc = escapeHtml(BRAND.productName);
19208
19450
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
19209
19451
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -19221,11 +19463,11 @@ ${clientErrorReporterScript}
19221
19463
  }
19222
19464
  var brandedHtmlCache = /* @__PURE__ */ new Map();
19223
19465
  function loadBrandingCache(agentSlug) {
19224
- const configDir2 = join24(homedir3(), BRAND.configDir);
19466
+ const configDir2 = join25(homedir3(), BRAND.configDir);
19225
19467
  try {
19226
19468
  const accountId = getDefaultAccountId();
19227
19469
  if (!accountId) return null;
19228
- const cachePath = join24(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
19470
+ const cachePath = join25(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
19229
19471
  if (!existsSync28(cachePath)) return null;
19230
19472
  return JSON.parse(readFileSync27(cachePath, "utf-8"));
19231
19473
  } catch {
@@ -19237,6 +19479,9 @@ function resolveDefaultSlug() {
19237
19479
  if (!account) return null;
19238
19480
  return resolveDefaultAgentSlug(account.accountDir);
19239
19481
  }
19482
+ function wantsNextSurface(c) {
19483
+ return c.req.query("surface") === "next";
19484
+ }
19240
19485
  function brandedPublicHtml(agentSlug) {
19241
19486
  const baseHtml = cachedHtml("public.html");
19242
19487
  if (!agentSlug) return baseHtml;
@@ -19270,7 +19515,7 @@ function escapeHtml(s) {
19270
19515
  function agentUnavailableHtml() {
19271
19516
  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
19517
  }
19273
- app49.get("/", (c) => {
19518
+ app50.get("/", (c) => {
19274
19519
  const host = (c.req.header("host") ?? "").split(":")[0];
19275
19520
  const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
19276
19521
  if (klass === "operator") {
@@ -19287,19 +19532,22 @@ app49.get("/", (c) => {
19287
19532
  );
19288
19533
  }
19289
19534
  console.error(`[public-root] op=serve-default slug=${defaultSlug}`);
19535
+ if (wantsNextSurface(c)) return c.html(cachedHtml("public-next.html"));
19290
19536
  return c.html(brandedPublicHtml(defaultSlug));
19291
19537
  }
19292
19538
  console.log(`[host-class] host=${host} class=admin served=index.html`);
19293
19539
  return c.html(cachedHtml("index.html"));
19294
19540
  });
19295
- app49.get("/public", (c) => {
19541
+ app50.get("/public", (c) => {
19296
19542
  const host = (c.req.header("host") ?? "").split(":")[0];
19297
19543
  if (isPublicHost(host)) return c.text("Not found", 404);
19544
+ if (wantsNextSurface(c)) return c.html(cachedHtml("public-next.html"));
19298
19545
  return c.html(cachedHtml("public.html"));
19299
19546
  });
19300
- app49.get("/public-chat", (c) => {
19547
+ app50.get("/public-chat", (c) => {
19301
19548
  const host = (c.req.header("host") ?? "").split(":")[0];
19302
19549
  if (isPublicHost(host)) return c.text("Not found", 404);
19550
+ if (wantsNextSurface(c)) return c.html(cachedHtml("public-next.html"));
19303
19551
  return c.html(cachedHtml("public.html"));
19304
19552
  });
19305
19553
  async function logViewerFetch(c, next) {
@@ -19316,12 +19564,12 @@ async function logViewerFetch(c, next) {
19316
19564
  duration_ms: Date.now() - start
19317
19565
  });
19318
19566
  }
19319
- app49.use("/vnc-viewer.html", logViewerFetch);
19320
- app49.use("/vnc-popout.html", logViewerFetch);
19321
- app49.get("/vnc-popout.html", (c) => {
19567
+ app50.use("/vnc-viewer.html", logViewerFetch);
19568
+ app50.use("/vnc-popout.html", logViewerFetch);
19569
+ app50.get("/vnc-popout.html", (c) => {
19322
19570
  let html = htmlCache.get("vnc-popout.html");
19323
19571
  if (!html) {
19324
- html = readFileSync27(resolve30(process.cwd(), "public", "vnc-popout.html"), "utf-8");
19572
+ html = readFileSync27(resolve31(process.cwd(), "public", "vnc-popout.html"), "utf-8");
19325
19573
  const name = escapeHtml(BRAND.productName);
19326
19574
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
19327
19575
  html = html.replace("</head>", ` ${brandScript}
@@ -19331,7 +19579,7 @@ app49.get("/vnc-popout.html", (c) => {
19331
19579
  }
19332
19580
  return c.html(html);
19333
19581
  });
19334
- app49.post("/api/vnc/client-event", async (c) => {
19582
+ app50.post("/api/vnc/client-event", async (c) => {
19335
19583
  let body;
19336
19584
  try {
19337
19585
  body = await c.req.json();
@@ -19352,11 +19600,11 @@ app49.post("/api/vnc/client-event", async (c) => {
19352
19600
  });
19353
19601
  return c.json({ ok: true });
19354
19602
  });
19355
- app49.get("/g/:slug", (c) => {
19603
+ app50.get("/g/:slug", (c) => {
19356
19604
  return c.html(brandedPublicHtml());
19357
19605
  });
19358
19606
  for (const pwa of PWA_SURFACES) {
19359
- app49.get(pwa.manifestPath, (c) => {
19607
+ app50.get(pwa.manifestPath, (c) => {
19360
19608
  const manifest = buildManifest(pwa, {
19361
19609
  productName: BRAND.productName,
19362
19610
  iconPath: brandIconPath,
@@ -19370,7 +19618,7 @@ for (const pwa of PWA_SURFACES) {
19370
19618
  return c.body(JSON.stringify(manifest));
19371
19619
  });
19372
19620
  }
19373
- app49.get("/sw.js", (c) => {
19621
+ app50.get("/sw.js", (c) => {
19374
19622
  if (SW_SOURCE == null) {
19375
19623
  console.error("[pwa] op=sw status=500 reason=sw-source-missing");
19376
19624
  return c.text("Service worker unavailable", 500);
@@ -19379,27 +19627,27 @@ app49.get("/sw.js", (c) => {
19379
19627
  console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
19380
19628
  return c.body(SW_SOURCE);
19381
19629
  });
19382
- app49.get("/graph", (c) => {
19630
+ app50.get("/graph", (c) => {
19383
19631
  const host = (c.req.header("host") ?? "").split(":")[0];
19384
19632
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
19385
19633
  return c.html(cachedHtml("graph.html"));
19386
19634
  });
19387
- app49.get("/chat", (c) => {
19635
+ app50.get("/chat", (c) => {
19388
19636
  const host = (c.req.header("host") ?? "").split(":")[0];
19389
19637
  if (isPublicHost(host)) return c.text("Not found", 404);
19390
19638
  return c.html(cachedHtml("chat.html"));
19391
19639
  });
19392
- app49.get("/data", (c) => {
19640
+ app50.get("/data", (c) => {
19393
19641
  const host = (c.req.header("host") ?? "").split(":")[0];
19394
19642
  if (isPublicHost(host)) return c.text("Not found", 404);
19395
19643
  return c.html(cachedHtml("data.html"));
19396
19644
  });
19397
- app49.get("/browser", (c) => {
19645
+ app50.get("/browser", (c) => {
19398
19646
  const host = (c.req.header("host") ?? "").split(":")[0];
19399
19647
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
19400
19648
  return c.html(cachedHtml("browser.html"));
19401
19649
  });
19402
- app49.get("/:slug", async (c, next) => {
19650
+ app50.get("/:slug", async (c, next) => {
19403
19651
  const slug = c.req.param("slug");
19404
19652
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
19405
19653
  const account = resolveAccount();
@@ -19409,18 +19657,19 @@ app49.get("/:slug", async (c, next) => {
19409
19657
  }
19410
19658
  const branding = loadBrandingCache(slug);
19411
19659
  console.error(`[public-catchall] served path=/${slug} slug=${slug} branding=${branding ? "hit" : "miss"}`);
19660
+ if (wantsNextSurface(c)) return c.html(cachedHtml("public-next.html"));
19412
19661
  return c.html(brandedPublicHtml(slug));
19413
19662
  }
19414
19663
  await next();
19415
19664
  });
19416
19665
  if (brandFaviconPath !== "/favicon.ico") {
19417
- app49.get("/favicon.ico", (c) => {
19666
+ app50.get("/favicon.ico", (c) => {
19418
19667
  c.header("Cache-Control", "public, max-age=300");
19419
19668
  return c.redirect(brandFaviconPath, 302);
19420
19669
  });
19421
19670
  }
19422
- app49.use("/*", serveStatic({ root: "./public" }));
19423
- app49.all("*", (c) => {
19671
+ app50.use("/*", serveStatic({ root: "./public" }));
19672
+ app50.all("*", (c) => {
19424
19673
  const host = (c.req.header("host") ?? "").split(":")[0];
19425
19674
  const path2 = c.req.path;
19426
19675
  if (isPublicHost(host)) {
@@ -19434,7 +19683,7 @@ app49.all("*", (c) => {
19434
19683
  });
19435
19684
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
19436
19685
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
19437
- var httpServer = serve({ fetch: app49.fetch, port, hostname });
19686
+ var httpServer = serve({ fetch: app50.fetch, port, hostname });
19438
19687
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
19439
19688
  {
19440
19689
  const census = pwaCensus({
@@ -19488,7 +19737,7 @@ for (const m of SUBAPP_MANIFEST) {
19488
19737
  }
19489
19738
  try {
19490
19739
  const registered = [];
19491
- for (const r of app49.routes ?? []) {
19740
+ for (const r of app50.routes ?? []) {
19492
19741
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
19493
19742
  if (AGENT_SLUG_PATTERN.test(r.path)) {
19494
19743
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -19583,7 +19832,7 @@ try {
19583
19832
  } catch (err) {
19584
19833
  console.error(`[graph-health] account-enumeration unavailable reason=${err instanceof Error ? err.message : String(err)}`);
19585
19834
  }
19586
- var configDirForWhatsApp = basename8(MAXY_DIR) || ".maxy";
19835
+ var configDirForWhatsApp = basename9(MAXY_DIR) || ".maxy";
19587
19836
  var bootAccount = resolveAccount();
19588
19837
  if (bootAccount) {
19589
19838
  migrateRemovedConfigKeys(bootAccount.accountDir);
@@ -19645,7 +19894,7 @@ if (bootAccountConfig?.whatsapp) {
19645
19894
  }
19646
19895
  init({
19647
19896
  configDir: configDirForWhatsApp,
19648
- platformRoot: resolve30(process.env.MAXY_PLATFORM_ROOT ?? join24(__dirname, "..")),
19897
+ platformRoot: resolve31(process.env.MAXY_PLATFORM_ROOT ?? join25(__dirname, "..")),
19649
19898
  accountConfig: bootAccountConfig,
19650
19899
  onMessage: async (msg) => {
19651
19900
  if (msg.isOwnerMirror) {