@rubytech/create-maxy-code 0.1.297 → 0.1.299

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