@rubytech/create-maxy-code 0.1.499 → 0.1.501

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 (221) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/graph-style/dist/index.d.ts +9 -0
  3. package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/graph-style/dist/index.js +152 -6
  5. package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
  6. package/payload/platform/lib/graph-style/src/__tests__/caption-coverage.test.ts +69 -0
  7. package/payload/platform/lib/graph-style/src/__tests__/coverage-source.ts +73 -0
  8. package/payload/platform/lib/graph-style/src/__tests__/icons.test.ts +20 -3
  9. package/payload/platform/lib/graph-style/src/index.ts +166 -5
  10. package/payload/platform/plugins/admin/PLUGIN.md +2 -1
  11. package/payload/platform/plugins/admin/hooks/__tests__/admin-authoring-observer.test.sh +135 -0
  12. package/payload/platform/plugins/admin/hooks/__tests__/prompt-optimiser-directive.test.sh +11 -2
  13. package/payload/platform/plugins/admin/hooks/prompt-optimiser-directive.sh +6 -3
  14. package/payload/platform/plugins/admin/mcp/dist/index.js +52 -107
  15. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  16. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.d.ts +8 -4
  17. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.d.ts.map +1 -1
  18. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js +67 -50
  19. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js.map +1 -1
  20. package/payload/platform/plugins/admin/mcp/dist/store-skill-core.d.ts +33 -0
  21. package/payload/platform/plugins/admin/mcp/dist/store-skill-core.d.ts.map +1 -0
  22. package/payload/platform/plugins/admin/mcp/dist/store-skill-core.js +122 -0
  23. package/payload/platform/plugins/admin/mcp/dist/store-skill-core.js.map +1 -0
  24. package/payload/platform/plugins/admin/skills/agent-builder/SKILL.md +15 -0
  25. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +59 -3
  26. package/payload/platform/plugins/admin/skills/summarise/SKILL.md +37 -0
  27. package/payload/platform/plugins/contacts/.claude-plugin/plugin.json +1 -1
  28. package/payload/platform/plugins/contacts/PLUGIN.md +1 -1
  29. package/payload/platform/plugins/contacts/mcp/dist/index.js +3 -12
  30. package/payload/platform/plugins/contacts/mcp/dist/index.js.map +1 -1
  31. package/payload/platform/plugins/contacts/mcp/dist/tools/__tests__/contact-lookup.test.js +105 -2
  32. package/payload/platform/plugins/contacts/mcp/dist/tools/__tests__/contact-lookup.test.js.map +1 -1
  33. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.d.ts +11 -1
  34. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.d.ts.map +1 -1
  35. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.js +56 -4
  36. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.js.map +1 -1
  37. package/payload/platform/plugins/docs/references/admin-ui.md +50 -0
  38. package/payload/platform/plugins/docs/references/contacts-guide.md +2 -0
  39. package/payload/platform/plugins/docs/references/outlook-guide.md +4 -0
  40. package/payload/platform/plugins/docs/references/plugins-guide.md +2 -2
  41. package/payload/platform/plugins/docs/references/summarise-skill.md +7 -0
  42. package/payload/platform/plugins/email/skills/email-composition/SKILL.md +9 -1
  43. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +6 -0
  44. package/payload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/SKILL.md +1 -1
  45. package/payload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/__tests__/restatement-ladder.test.sh +2 -1
  46. package/payload/platform/services/claude-session-manager/dist/index.js +26 -1
  47. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  48. package/payload/platform/services/claude-session-manager/dist/skill-registration-drift.d.ts +15 -0
  49. package/payload/platform/services/claude-session-manager/dist/skill-registration-drift.d.ts.map +1 -1
  50. package/payload/platform/services/claude-session-manager/dist/skill-registration-drift.js +61 -0
  51. package/payload/platform/services/claude-session-manager/dist/skill-registration-drift.js.map +1 -1
  52. package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
  53. package/payload/server/public/activity.html +6 -6
  54. package/payload/server/public/assets/{AdminLoginScreens-Ce5aBBWF.js → AdminLoginScreens-C3LZOPIY.js} +1 -1
  55. package/payload/server/public/assets/AdminShell-BlbUNAPc.js +2 -0
  56. package/payload/server/public/assets/{activity-CKUYOLd2.js → activity-CVdVSw5V.js} +1 -1
  57. package/payload/server/public/assets/admin-If1QLlS3.js +1 -0
  58. package/payload/server/public/assets/{arc-CpWWSum8.js → arc-CvlzUHOf.js} +1 -1
  59. package/payload/server/public/assets/architecture-YZFGNWBL-BQc779DH.js +1 -0
  60. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-D2EzaII0.js → architectureDiagram-Q4EWVU46-I1Hs0RJA.js} +1 -1
  61. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-8kDpaNSZ.js → blockDiagram-DXYQGD6D-Df5jTGtl.js} +1 -1
  62. package/payload/server/public/assets/{bot-DESMpxSQ.js → bot-8b26IlQY.js} +1 -1
  63. package/payload/server/public/assets/{browser-CpLq_DIo.js → browser-F40DXfKA.js} +1 -1
  64. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CbwmZpK3.js → c4Diagram-AHTNJAMY-B6WY5IDv.js} +1 -1
  65. package/payload/server/public/assets/{calendar-ClOwyuz-.js → calendar-DZiHiBwV.js} +1 -1
  66. package/payload/server/public/assets/channel-AqnC3SHu.js +1 -0
  67. package/payload/server/public/assets/chat-uD28FVCS.js +1 -0
  68. package/payload/server/public/assets/chevron-left-lBxD57tD.js +1 -0
  69. package/payload/server/public/assets/chevron-right-C-lDig9Y.js +1 -0
  70. package/payload/server/public/assets/{chunk-2KRD3SAO-PFheZ9mw.js → chunk-2KRD3SAO-BsIIFDkc.js} +1 -1
  71. package/payload/server/public/assets/{chunk-336JU56O-CCFOp5VK.js → chunk-336JU56O-j9z1VtyC.js} +2 -2
  72. package/payload/server/public/assets/chunk-426QAEUC-CO02gU5d.js +1 -0
  73. package/payload/server/public/assets/{chunk-4BX2VUAB-Hz4JWOf2.js → chunk-4BX2VUAB-C9i7prxq.js} +1 -1
  74. package/payload/server/public/assets/{chunk-4TB4RGXK-4xeV0s85.js → chunk-4TB4RGXK-DH0QVGcv.js} +1 -1
  75. package/payload/server/public/assets/{chunk-55IACEB6-4QKgBpoh.js → chunk-55IACEB6-Dnd_YCPA.js} +1 -1
  76. package/payload/server/public/assets/{chunk-5FUZZQ4R-ms3K6Z5z.js → chunk-5FUZZQ4R-D5sSz3yN.js} +1 -1
  77. package/payload/server/public/assets/{chunk-5PVQY5BW-CIC4GIGi.js → chunk-5PVQY5BW-CJrwWjAT.js} +1 -1
  78. package/payload/server/public/assets/{chunk-67CJDMHE-B-XrWVmV.js → chunk-67CJDMHE-SjP6_hUw.js} +1 -1
  79. package/payload/server/public/assets/{chunk-7N4EOEYR-C7ECOUYQ.js → chunk-7N4EOEYR-fAuhVJD0.js} +1 -1
  80. package/payload/server/public/assets/{chunk-AA7GKIK3-DOZ6Fxwk.js → chunk-AA7GKIK3-DZxa7KVg.js} +1 -1
  81. package/payload/server/public/assets/{chunk-BSJP7CBP-4cJ_b0c6.js → chunk-BSJP7CBP-DjeG3eQ-.js} +1 -1
  82. package/payload/server/public/assets/{chunk-CIAEETIT--mhZipWM.js → chunk-CIAEETIT-RYQULNJm.js} +1 -1
  83. package/payload/server/public/assets/{chunk-EDXVE4YY-jZpVwob_.js → chunk-EDXVE4YY-Cahapnon.js} +1 -1
  84. package/payload/server/public/assets/{chunk-ENJZ2VHE-Nn-p-xIA.js → chunk-ENJZ2VHE-1146X1L4.js} +1 -1
  85. package/payload/server/public/assets/{chunk-FMBD7UC4-DyNpcKOS.js → chunk-FMBD7UC4-BCFumtcP.js} +1 -1
  86. package/payload/server/public/assets/{chunk-FOC6F5B3-C0P8q1uz.js → chunk-FOC6F5B3-CkrtX8Zt.js} +1 -1
  87. package/payload/server/public/assets/{chunk-ICPOFSXX-CdXQ5SfI.js → chunk-ICPOFSXX-Ba1y3DaW.js} +2 -2
  88. package/payload/server/public/assets/{chunk-K5T4RW27-BVZJKKsT.js → chunk-K5T4RW27-CF-PI3uQ.js} +1 -1
  89. package/payload/server/public/assets/{chunk-KGLVRYIC-QlVWTe0V.js → chunk-KGLVRYIC-SFFC6ZC-.js} +1 -1
  90. package/payload/server/public/assets/{chunk-LIHQZDEY-CpGVZutP.js → chunk-LIHQZDEY-DbOLEP4R.js} +1 -1
  91. package/payload/server/public/assets/{chunk-ORNJ4GCN-WVcS6fUC.js → chunk-ORNJ4GCN-VB963bkN.js} +1 -1
  92. package/payload/server/public/assets/{chunk-OYMX7WX6-B7hiSTed.js → chunk-OYMX7WX6-DWYY1pQa.js} +1 -1
  93. package/payload/server/public/assets/chunk-QZHKN3VN-BiFMbK8t.js +1 -0
  94. package/payload/server/public/assets/{chunk-U2HBQHQK-DJPnZxGy.js → chunk-U2HBQHQK-DAH1diYP.js} +1 -1
  95. package/payload/server/public/assets/{chunk-X2U36JSP-DilBs1Yc.js → chunk-X2U36JSP-Dmw9coXz.js} +1 -1
  96. package/payload/server/public/assets/{chunk-XPW4576I-B5-uyrJ0.js → chunk-XPW4576I-DaAUON1-.js} +1 -1
  97. package/payload/server/public/assets/{chunk-YZCP3GAM-BNO4z0Mv.js → chunk-YZCP3GAM-BUcfkEef.js} +1 -1
  98. package/payload/server/public/assets/{chunk-ZZ45TVLE-BzHMQpip.js → chunk-ZZ45TVLE-BLD-vFRO.js} +1 -1
  99. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BdRqzScB.js +1 -0
  100. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-ChPLgHbS.js +1 -0
  101. package/payload/server/public/assets/clock-DqRNsY40.js +1 -0
  102. package/payload/server/public/assets/clone-TKtrjWBC.js +1 -0
  103. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-3DWYmn1o.js → cose-bilkent-S5V4N54A-CoZX0uki.js} +1 -1
  104. package/payload/server/public/assets/{dagre-Cpy31xJW.js → dagre-Bmjs8zJA.js} +1 -1
  105. package/payload/server/public/assets/{dagre-KV5264BT-C8fyxHFd.js → dagre-KV5264BT-BZCP2wnq.js} +1 -1
  106. package/payload/server/public/assets/data-BsFyBN85.js +1 -0
  107. package/payload/server/public/assets/{diagram-5BDNPKRD-ycyhnLvr.js → diagram-5BDNPKRD-8Nt9a4xX.js} +1 -1
  108. package/payload/server/public/assets/{diagram-G4DWMVQ6-BkeYicIt.js → diagram-G4DWMVQ6-vh5tcYqJ.js} +1 -1
  109. package/payload/server/public/assets/{diagram-MMDJMWI5-BcGZU-Q3.js → diagram-MMDJMWI5-DGf--jc8.js} +1 -1
  110. package/payload/server/public/assets/{diagram-TYMM5635-DuBDCFb_.js → diagram-TYMM5635-CsO7TIdw.js} +1 -1
  111. package/payload/server/public/assets/{dist-BYc_arNy.js → dist-cdnE4DqK.js} +1 -1
  112. package/payload/server/public/assets/{erDiagram-SMLLAGMA-DmkeOzvp.js → erDiagram-SMLLAGMA-4a78yV8_.js} +1 -1
  113. package/payload/server/public/assets/file-text-B1HjPFbM.js +1 -0
  114. package/payload/server/public/assets/{flatten-QjnJ1Gcl.js → flatten-BtIc9jX7.js} +1 -1
  115. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CkE-pjuB.js → flowDiagram-DWJPFMVM-BoQBXs6t.js} +1 -1
  116. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-Cjiy3kvE.js → ganttDiagram-T4ZO3ILL-CvzqwCC8.js} +1 -1
  117. package/payload/server/public/assets/gitGraph-7Q5UKJZL-DfcaTE9L.js +1 -0
  118. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CsI4lKZm.js → gitGraphDiagram-UUTBAWPF-D_nBxay_.js} +1 -1
  119. package/payload/server/public/assets/graph-CIC-mgKR.js +51 -0
  120. package/payload/server/public/assets/graph-labels-BnpHCHaQ.js +1 -0
  121. package/payload/server/public/assets/{graphlib-BkXxC6D5.js → graphlib-D0NdsKJI.js} +1 -1
  122. package/payload/server/public/assets/info-OMHHGYJF-CD-u6gw9.js +1 -0
  123. package/payload/server/public/assets/infoDiagram-42DDH7IO-C6gPQCvO.js +2 -0
  124. package/payload/server/public/assets/{isEmpty-BavJI9Cn.js → isEmpty-Bu4fZ8Kf.js} +1 -1
  125. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-D8lZtjRc.js → ishikawaDiagram-UXIWVN3A-auW-s0i0.js} +1 -1
  126. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-kLE7SiR_.js → journeyDiagram-VCZTEJTY-3Q6AWK4A.js} +1 -1
  127. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-ove6JuD3.js → kanban-definition-6JOO6SKY-B4MPFp98.js} +1 -1
  128. package/payload/server/public/assets/{line-CZMSoxM6.js → line-26MdeG5Z.js} +1 -1
  129. package/payload/server/public/assets/{linear-Be8IK9hK.js → linear-Dq9s_bDO.js} +1 -1
  130. package/payload/server/public/assets/{maximize-2-BbzPm7o8.js → maximize-2-BL7QVTcQ.js} +1 -1
  131. package/payload/server/public/assets/{mermaid-parser.core-BBADqbnp.js → mermaid-parser.core-vLEpOXgf.js} +2 -2
  132. package/payload/server/public/assets/{mermaid.core-mH3N7K0I.js → mermaid.core-Durk4m6D.js} +3 -3
  133. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-BjwwwWil.js → mindmap-definition-QFDTVHPH-DOIg-TyG.js} +1 -1
  134. package/payload/server/public/assets/{operator-DCNWUKP_.js → operator-B62h_TaC.js} +1 -1
  135. package/payload/server/public/assets/{ordinal-BHeIKG-K.js → ordinal-C2TEWKNu.js} +1 -1
  136. package/payload/server/public/assets/packet-4T2RLAQJ-BaLYeIrU.js +1 -0
  137. package/payload/server/public/assets/page-BUUBseJZ.js +32 -0
  138. package/payload/server/public/assets/page-Bw-tYjw7.js +1 -0
  139. package/payload/server/public/assets/{pdf-render-fJz4vym9.js → pdf-render-C257cidb.js} +1 -1
  140. package/payload/server/public/assets/pie-ZZUOXDRM-CL-XJtk-.js +1 -0
  141. package/payload/server/public/assets/{pieDiagram-DEJITSTG-D-lXWWta.js → pieDiagram-DEJITSTG-DtgBHZfi.js} +1 -1
  142. package/payload/server/public/assets/{public-DXJXQPwe.js → public-BI21tOkm.js} +1 -1
  143. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-13QyG_AO.js → quadrantDiagram-34T5L4WZ-BTc5Qn2y.js} +1 -1
  144. package/payload/server/public/assets/radar-PYXPWWZC-Cn-g6F_h.js +1 -0
  145. package/payload/server/public/assets/{reduce-Fm685to3.js → reduce-BGpN5lgn.js} +1 -1
  146. package/payload/server/public/assets/{requirementDiagram-MS252O5E-Bx45Bgn4.js → requirementDiagram-MS252O5E-BNgOO5YW.js} +1 -1
  147. package/payload/server/public/assets/{rotate-ccw-L42fL8ey.js → rotate-ccw-C_20Bc3E.js} +1 -1
  148. package/payload/server/public/assets/routines-Ci3N8wqV.js +1 -0
  149. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-Cj-Gq25v.js → sankeyDiagram-XADWPNL6-MyUATmVt.js} +1 -1
  150. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-B8RDRq93.js → sequenceDiagram-FGHM5R23-CBJrF5Vi.js} +1 -1
  151. package/payload/server/public/assets/skills-CiflzOko.js +1 -0
  152. package/payload/server/public/assets/{src-D3VYuW_Z.js → src-DekKlUCp.js} +1 -1
  153. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DoyFF1Kl.js → stateDiagram-FHFEXIEX-6wbUjn1Q.js} +1 -1
  154. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BdMdfBeC.js +1 -0
  155. package/payload/server/public/assets/{tasks-GNtvZL8F.js → tasks-DC2Yf2Ev.js} +1 -1
  156. package/payload/server/public/assets/{time-entry-format-BreNpFLJ.js → time-entry-format-CNcjs2HV.js} +1 -1
  157. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Df4RQXm6.js → timeline-definition-GMOUNBTQ-BHjTMCGY.js} +1 -1
  158. package/payload/server/public/assets/treeView-SZITEDCU-CmZoOGlC.js +1 -0
  159. package/payload/server/public/assets/treemap-W4RFUUIX-H27WFS-y.js +1 -0
  160. package/payload/server/public/assets/{triangle-alert-DumCWC08.js → triangle-alert-CngnWtjD.js} +1 -1
  161. package/payload/server/public/assets/{useCopyFeedback-DHCtz8qX.js → useCopyFeedback-DZ9Bw5CI.js} +1 -1
  162. package/payload/server/public/assets/{useSubAccountSwitcher-Bc7XHr0L.js → useSubAccountSwitcher-CHwQhkaI.js} +1 -1
  163. package/payload/server/public/assets/{useSubAccountSwitcher-DPHQJO7E.css → useSubAccountSwitcher-yFQqnpQ8.css} +1 -1
  164. package/payload/server/public/assets/useVoiceRecorder-C3G6aqZr.js +2 -0
  165. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-D2o5og9l.js → vennDiagram-DHZGUBPP-yo3-cf0U.js} +1 -1
  166. package/payload/server/public/assets/wardley-RL74JXVD-DNpWIvU4.js +1 -0
  167. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-BDueObbS.js → wardleyDiagram-NUSXRM2D-DZlyFzrg.js} +1 -1
  168. package/payload/server/public/assets/{wrench-iWkROE1V.js → wrench-dky2-13x.js} +1 -1
  169. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BTYs4Fgh.js → xychartDiagram-5P7HB3ND-B5HV5h80.js} +1 -1
  170. package/payload/server/public/browser.html +5 -5
  171. package/payload/server/public/calendar.html +8 -8
  172. package/payload/server/public/chat.html +16 -15
  173. package/payload/server/public/data.html +13 -12
  174. package/payload/server/public/graph.html +10 -10
  175. package/payload/server/public/index.html +17 -16
  176. package/payload/server/public/operator.html +17 -16
  177. package/payload/server/public/public.html +16 -15
  178. package/payload/server/public/routines.html +7 -7
  179. package/payload/server/public/skills.html +19 -0
  180. package/payload/server/public/tasks.html +7 -7
  181. package/payload/server/server.js +714 -402
  182. package/payload/server/public/assets/AdminShell-BFVVkWFC.js +0 -2
  183. package/payload/server/public/assets/admin-BWb8me-E.js +0 -1
  184. package/payload/server/public/assets/architecture-YZFGNWBL-D-AX2VuA.js +0 -1
  185. package/payload/server/public/assets/channel-DZ5sh6YQ.js +0 -1
  186. package/payload/server/public/assets/chat-MvnxPJZ5.js +0 -1
  187. package/payload/server/public/assets/chevron-left-BzIg4in6.js +0 -1
  188. package/payload/server/public/assets/chevron-right-BcFSa9C3.js +0 -1
  189. package/payload/server/public/assets/chunk-426QAEUC-CcjBLp4a.js +0 -1
  190. package/payload/server/public/assets/chunk-QZHKN3VN-B2WjDYBE.js +0 -1
  191. package/payload/server/public/assets/classDiagram-6PBFFD2Q-CT3jNrze.js +0 -1
  192. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DJRsjAkC.js +0 -1
  193. package/payload/server/public/assets/clock-Dr3NGtjR.js +0 -1
  194. package/payload/server/public/assets/clone-FcEDnoMT.js +0 -1
  195. package/payload/server/public/assets/data-BjqC4hyM.js +0 -1
  196. package/payload/server/public/assets/gitGraph-7Q5UKJZL-D1uhnP9U.js +0 -1
  197. package/payload/server/public/assets/graph-B7niLM97.js +0 -51
  198. package/payload/server/public/assets/graph-labels-DykmXYHA.js +0 -1
  199. package/payload/server/public/assets/info-OMHHGYJF-oNm27GAV.js +0 -1
  200. package/payload/server/public/assets/infoDiagram-42DDH7IO-LxTftqyS.js +0 -2
  201. package/payload/server/public/assets/packet-4T2RLAQJ-eQNVGiK3.js +0 -1
  202. package/payload/server/public/assets/page-C4TrTU6r.js +0 -32
  203. package/payload/server/public/assets/page-DUgrGrJp.js +0 -1
  204. package/payload/server/public/assets/pie-ZZUOXDRM-E1u-48rt.js +0 -1
  205. package/payload/server/public/assets/radar-PYXPWWZC-Cn2cGN90.js +0 -1
  206. package/payload/server/public/assets/routines-JOV6xdYh.js +0 -1
  207. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Bml-X4-H.js +0 -1
  208. package/payload/server/public/assets/treeView-SZITEDCU-CimabhXy.js +0 -1
  209. package/payload/server/public/assets/treemap-W4RFUUIX-Cg264rpM.js +0 -1
  210. package/payload/server/public/assets/useVoiceRecorder-Cu6zvuFx.js +0 -2
  211. package/payload/server/public/assets/wardley-RL74JXVD-tbgfCg0E.js +0 -1
  212. /package/payload/server/public/assets/{_baseFor-Bvwvhrz4.js → _baseFor-Be3EKK3K.js} +0 -0
  213. /package/payload/server/public/assets/{array-D3d-WgFW.js → array-X0JlPOfd.js} +0 -0
  214. /package/payload/server/public/assets/{chunk-fQC6bEKA.js → chunk-CCr-iYLO.js} +0 -0
  215. /package/payload/server/public/assets/{cytoscape.esm-Cun-OM6a.js → cytoscape.esm-CI2IWMLB.js} +0 -0
  216. /package/payload/server/public/assets/{defaultLocale-CisKV5Ew.js → defaultLocale-B6RGN4id.js} +0 -0
  217. /package/payload/server/public/assets/{init-D9ZOVaZ3.js → init-BmUWJJHz.js} +0 -0
  218. /package/payload/server/public/assets/{katex-C-3ZDK8o.js → katex-BjZuzSQn.js} +0 -0
  219. /package/payload/server/public/assets/{path-BMOgQSLM.js → path-CoPyR7c2.js} +0 -0
  220. /package/payload/server/public/assets/{preload-helper-DL2DwvxV.js → preload-helper-BQrMkyGX.js} +0 -0
  221. /package/payload/server/public/assets/{rough.esm-BrTFrov0.js → rough.esm-jSt7UMyi.js} +0 -0
@@ -503,7 +503,7 @@ var require_dist3 = __commonJS({
503
503
  "../lib/graph-style/dist/index.js"(exports) {
504
504
  "use strict";
505
505
  Object.defineProperty(exports, "__esModule", { value: true });
506
- exports.FALLBACK_LABEL_SHAPE = exports.EXTERNAL_LABEL_SHAPES = exports.ALL_GRAPH_LABELS = exports.ADDITIONAL_BASE_LABELS = exports.FALLBACK_LABEL_COLOUR = exports.GRAPH_LABEL_COLOURS = void 0;
506
+ exports.CODE_EMITTED_NODE_LABELS = exports.FALLBACK_LABEL_SHAPE = exports.EXTERNAL_LABEL_SHAPES = exports.ALL_GRAPH_LABELS = exports.ADDITIONAL_BASE_LABELS = exports.FALLBACK_LABEL_COLOUR = exports.GRAPH_LABEL_COLOURS = void 0;
507
507
  exports.pickDisplayLabel = pickDisplayLabel2;
508
508
  exports.colourForLabel = colourForLabel2;
509
509
  exports.shapeForLabel = shapeForLabel2;
@@ -531,11 +531,12 @@ var require_dist3 = __commonJS({
531
531
  // JobLogic service-delivery ontology (Task 1084; supersedes the Task 650/773
532
532
  // homegrown set). Muted brick-red / earthy family — the service register sits
533
533
  // apart from people-terracotta, viewing-amber, and task-rose bands so
534
- // sitedesk legends read as their own group. Top-level (operator-entry)
535
- // labels only; child labels (QuoteLine, Milestone, Valuation, VariationNote,
536
- // JobCost, Contact, PurchaseOrderLine, InvoiceLine, InvoicePayment, Credit)
537
- // intentionally stay fallback-grey. :Engineer is an additional label on
538
- // Person and takes the Person colour; :Supplier is an additional label on
534
+ // sitedesk legends read as their own group. These are the top-level
535
+ // (operator-entry) labels; the child labels (QuoteLine, Milestone, Valuation,
536
+ // VariationNote, JobCost, Contact, PurchaseOrderLine, InvoiceLine,
537
+ // InvoicePayment, Credit) are coloured in the Task 1965 block appended at the
538
+ // end of this object, not here. :Engineer is an additional label on Person
539
+ // and takes the Person colour; :Supplier is an additional label on
539
540
  // Organization and takes the tobacco Organization colour. All hexes here are
540
541
  // pairwise-unique across the registry.
541
542
  Job: "#8C3B2E",
@@ -633,7 +634,82 @@ var require_dist3 = __commonJS({
633
634
  // SHAPE_BY_LABEL assigns shapes by index position in ALL_GRAPH_LABELS
634
635
  // (this object's key order), so a mid-table insert would silently change
635
636
  // the rendered shape of every label after it.
636
- CashEntry: "#7D5A2B"
637
+ CashEntry: "#7D5A2B",
638
+ // --- Task 1965: colour every node type that can appear in the graph ---
639
+ // Appended at the END so SHAPE_BY_LABEL indices for the labels above are
640
+ // unchanged. Grouped by family band; each hex is pairwise-unique across the
641
+ // whole registry (except the pre-existing UserMessage/Preference twin).
642
+ // Ledger / money children (brown-gold, beside Invoice and CashEntry).
643
+ InvoiceLine: "#7A5326",
644
+ InvoicePayment: "#8A6230",
645
+ QuoteLine: "#9A7038",
646
+ PurchaseOrderLine: "#A67E42",
647
+ JobCost: "#6A4A22",
648
+ Credit: "#B48A48",
649
+ Retainer: "#C29A55",
650
+ Sale: "#8E5E2A",
651
+ Valuation: "#A06A34",
652
+ Order: "#B87C3E",
653
+ DiningOrder: "#C9954E",
654
+ // Documents / content (steel-blue, hue-adjacent to the business slates).
655
+ Content: "#58708C",
656
+ Report: "#6D8299",
657
+ Page: "#849AAF",
658
+ Post: "#93A7BA",
659
+ VariationNote: "#47617B",
660
+ FileArtifact: "#A9BBCC",
661
+ // Marketing (bright teal-green, apart from workflow and research teals).
662
+ SocialPost: "#2FA69A",
663
+ Campaign: "#3FB8A0",
664
+ BrandDeal: "#57C2AE",
665
+ Recommendation: "#74CDBB",
666
+ // CRM people (terracotta, beside Person and Customer).
667
+ Contact: "#C97E52",
668
+ Lead: "#A85E38",
669
+ Position: "#96522E",
670
+ Audience: "#E0B088",
671
+ // Places / transport / retail (forest-emerald, apart from knowledge moss).
672
+ PostalAddress: "#2E8B57",
673
+ Room: "#3A9B63",
674
+ StoreLocation: "#46A96F",
675
+ Vehicle: "#54B77B",
676
+ Route: "#62C187",
677
+ Stop: "#2A7A4C",
678
+ Shipment: "#6FCB93",
679
+ Reservation: "#7ED4A0",
680
+ TableReservation: "#8CDBAC",
681
+ Menu: "#1F6B41",
682
+ MenuItem: "#98E0B6",
683
+ Product: "#34925E",
684
+ StockMovement: "#4CA574",
685
+ // Work / delivery (indigo, apart from the strategy indigo band).
686
+ Milestone: "#4A5FA8",
687
+ Deliverable: "#6274C0",
688
+ TimeEntry: "#8189CE",
689
+ Engagement: "#9AA0DA",
690
+ Case: "#3B4E92",
691
+ Meeting: "#5566B4",
692
+ // Idea (amber).
693
+ Idea: "#E0A82E",
694
+ // Web analytics (sky-cyan, apart from the research teal).
695
+ Session: "#2AA7C4",
696
+ PageView: "#3DB4CE",
697
+ Click: "#55C0D6",
698
+ ScrollMilestone: "#70CCDE",
699
+ TimelineEvent: "#1E93B0",
700
+ AnonVisitor: "#88D6E6",
701
+ AEOAudit: "#46B0CB",
702
+ // WhatsApp transport (brand green).
703
+ WhatsAppConversation: "#128C7E",
704
+ WhatsAppMessage: "#1FA894",
705
+ // Cloudflare / chain infra (grey-blue).
706
+ CloudflareHostname: "#5B6E82",
707
+ CloudflareTunnel: "#6E8296",
708
+ Chain: "#47586A",
709
+ ChainLink: "#8496AA",
710
+ // Voice (violet).
711
+ VoiceProfile: "#9B59B6",
712
+ VoiceEdit: "#B07CC9"
637
713
  };
638
714
  exports.FALLBACK_LABEL_COLOUR = "#94A3B8";
639
715
  exports.ADDITIONAL_BASE_LABELS = Object.freeze(/* @__PURE__ */ new Set(["Applicant", "Engineer", "GuestProfile", "Supplier"]));
@@ -669,6 +745,7 @@ var require_dist3 = __commonJS({
669
745
  function shapeForLabel2(label) {
670
746
  return SHAPE_BY_LABEL[label] ?? exports.FALLBACK_LABEL_SHAPE;
671
747
  }
748
+ exports.CODE_EMITTED_NODE_LABELS = Object.freeze(/* @__PURE__ */ new Set(["FileArtifact"]));
672
749
  var LABEL_ICONS = {
673
750
  LocalBusiness: '<path d="M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5"></path><path d="M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244"></path><path d="M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05"></path>',
674
751
  Service: '<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"></path>',
@@ -732,7 +809,68 @@ var require_dist3 = __commonJS({
732
809
  Source: '<path d="M12 7v14"></path><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"></path>',
733
810
  Finding: '<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"></path><path d="M9 18h6"></path><path d="M10 22h4"></path>',
734
811
  Hypothesis: '<path d="M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2"></path><path d="M6.453 15h11.094"></path><path d="M8.5 2h7"></path>',
735
- CashEntry: '<rect width="20" height="12" x="2" y="6" rx="2"></rect><circle cx="12" cy="12" r="2"></circle><path d="M6 12h.01"></path><path d="M18 12h.01"></path>'
812
+ CashEntry: '<rect width="20" height="12" x="2" y="6" rx="2"></rect><circle cx="12" cy="12" r="2"></circle><path d="M6 12h.01"></path><path d="M18 12h.01"></path>',
813
+ // --- Task 1965: glyphs for the 60 previously-uncovered node labels ---
814
+ InvoiceLine: '<path d="M13 16H8" /><path d="M14 8H8" /><path d="M16 12H8" /><path d="M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z" />',
815
+ InvoicePayment: '<path d="M11 15h2a2 2 0 1 0 0-4h-3c-.6 0-1.1.2-1.4.6L3 17" /><path d="m7 21 1.6-1.4c.3-.4.8-.6 1.4-.6h4c1.1 0 2.1-.4 2.8-1.2l4.6-4.4a2 2 0 0 0-2.75-2.91l-4.2 3.9" /><path d="m2 16 6 6" /><circle cx="16" cy="9" r="2.9" /><circle cx="6" cy="5" r="3" />',
816
+ QuoteLine: '<path d="M3 5h.01" /><path d="M3 12h.01" /><path d="M3 19h.01" /><path d="M8 5h13" /><path d="M8 12h13" /><path d="M8 19h13" />',
817
+ PurchaseOrderLine: '<path d="M11 5h10" /><path d="M11 12h10" /><path d="M11 19h10" /><path d="M4 4h1v5" /><path d="M4 9h2" /><path d="M6.5 20H3.4c0-1 2.6-1.925 2.6-3.5a1.5 1.5 0 0 0-2.6-1.02" />',
818
+ JobCost: '<rect width="20" height="12" x="2" y="6" rx="2" /><circle cx="12" cy="12" r="2" /><path d="M6 12h.01M18 12h.01" />',
819
+ Credit: '<path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z" /><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8" /><path d="M12 18V6" />',
820
+ Retainer: '<path d="M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1" /><path d="M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4" />',
821
+ Sale: '<path d="M12 17V7" /><path d="M16 8h-6a2 2 0 0 0 0 4h4a2 2 0 0 1 0 4H8" /><path d="M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z" />',
822
+ Valuation: '<path d="M12 3v18" /><path d="m19 8 3 8a5 5 0 0 1-6 0zV7" /><path d="M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1" /><path d="m5 8 3 8a5 5 0 0 1-6 0zV7" /><path d="M7 21h10" />',
823
+ Order: '<path d="M16 10a4 4 0 0 1-8 0" /><path d="M3.103 6.034h17.794" /><path d="M3.4 5.467a2 2 0 0 0-.4 1.2V20a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.667a2 2 0 0 0-.4-1.2l-2-2.667A2 2 0 0 0 17 2H7a2 2 0 0 0-1.6.8z" />',
824
+ DiningOrder: '<path d="M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2" /><path d="M7 2v20" /><path d="M21 15V2a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7" />',
825
+ Content: '<path d="M15 18h-5" /><path d="M18 14h-8" /><path d="M4 22h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-4 0v-9a2 2 0 0 1 2-2h2" /><rect width="8" height="4" x="10" y="6" rx="1" />',
826
+ Report: '<rect width="8" height="4" x="8" y="2" rx="1" ry="1" /><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" /><path d="M12 11h4" /><path d="M12 16h4" /><path d="M8 11h.01" /><path d="M8 16h.01" />',
827
+ Page: '<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" /><path d="M14 2v5a1 1 0 0 0 1 1h5" />',
828
+ Post: '<path d="M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" /><path d="M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z" />',
829
+ SocialPost: '<path d="M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z" /><path d="M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14" /><path d="M8 6v8" />',
830
+ VariationNote: '<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" /><path d="M9 10h6" /><path d="M12 13V7" /><path d="M9 17h6" />',
831
+ Contact: '<path d="M16 2v2" /><path d="M17.915 22a6 6 0 0 0-12 0" /><path d="M8 2v2" /><circle cx="12" cy="12" r="4" /><rect x="3" y="4" width="18" height="18" rx="2" />',
832
+ Lead: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><circle cx="9" cy="7" r="4" /><line x1="19" x2="19" y1="8" y2="14" /><line x1="22" x2="16" y1="11" y2="11" />',
833
+ Position: '<path d="M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16" /><rect width="20" height="14" x="2" y="6" rx="2" />',
834
+ Audience: '<path d="M18 21a8 8 0 0 0-16 0" /><circle cx="10" cy="8" r="5" /><path d="M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3" />',
835
+ PostalAddress: '<path d="M18 8c0 3.613-3.869 7.429-5.393 8.795a1 1 0 0 1-1.214 0C9.87 15.429 6 11.613 6 8a6 6 0 0 1 12 0" /><circle cx="12" cy="8" r="2" /><path d="M8.714 14h-3.71a1 1 0 0 0-.948.683l-2.004 6A1 1 0 0 0 3 22h18a1 1 0 0 0 .948-1.316l-2-6a1 1 0 0 0-.949-.684h-3.712" />',
836
+ Room: '<path d="M11 20H2" /><path d="M11 4.562v16.157a1 1 0 0 0 1.242.97L19 20V5.562a2 2 0 0 0-1.515-1.94l-4-1A2 2 0 0 0 11 4.561z" /><path d="M11 4H8a2 2 0 0 0-2 2v14" /><path d="M14 12h.01" /><path d="M22 20h-3" />',
837
+ StoreLocation: '<path d="M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5" /><path d="M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244" /><path d="M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05" />',
838
+ Vehicle: '<path d="M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2" /><circle cx="7" cy="17" r="2" /><path d="M9 17h6" /><circle cx="17" cy="17" r="2" />',
839
+ Route: '<circle cx="6" cy="19" r="3" /><path d="M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15" /><circle cx="18" cy="5" r="3" />',
840
+ Stop: '<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0" /><circle cx="12" cy="10" r="3" />',
841
+ Shipment: '<path d="M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z" /><path d="M12 22V12" /><polyline points="3.29 7 12 12 20.71 7" /><path d="m7.5 4.27 9 5.15" />',
842
+ Reservation: '<path d="M8 2v4" /><path d="M16 2v4" /><rect width="18" height="18" x="3" y="4" rx="2" /><path d="M3 10h18" /><path d="m9 16 2 2 4-4" />',
843
+ TableReservation: '<path d="m16 2-2.3 2.3a3 3 0 0 0 0 4.2l1.8 1.8a3 3 0 0 0 4.2 0L22 8" /><path d="M15 15 3.3 3.3a4.2 4.2 0 0 0 0 6l7.3 7.3c.7.7 2 .7 2.8 0L15 15Zm0 0 7 7" /><path d="m2.1 21.8 6.4-6.3" /><path d="m19 5-7 7" />',
844
+ Menu: '<path d="M12 5v16" /><path d="M20.001 19A2 2 0 0022 17V5a2 2 0 00-1.999-2L16 3.002A5 5 0 0012 5a5 5 0 00-4-2H4a2 2 0 00-2 2v12a2 2 0 001.999 2H8a5 5 0 014 2 5 5 0 014-2z" />',
845
+ MenuItem: '<path d="M7 21h10" /><path d="M12 21a9 9 0 0 0 9-9H3a9 9 0 0 0 9 9Z" /><path d="M11.38 12a2.4 2.4 0 0 1-.4-4.77 2.4 2.4 0 0 1 3.2-2.77 2.4 2.4 0 0 1 3.47-.63 2.4 2.4 0 0 1 3.37 3.37 2.4 2.4 0 0 1-1.1 3.7 2.51 2.51 0 0 1 .03 1.1" /><path d="m13 12 4-4" /><path d="M10.9 7.25A3.99 3.99 0 0 0 4 10c0 .73.2 1.41.54 2" />',
846
+ Product: '<path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z" /><path d="m3.3 7 8.7 5 8.7-5" /><path d="M12 22V12" />',
847
+ StockMovement: '<path d="m16 3 4 4-4 4" /><path d="M20 7H4" /><path d="m8 21-4-4 4-4" /><path d="M4 17h16" />',
848
+ Milestone: '<path d="M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528" />',
849
+ Deliverable: '<path d="M12 22V12" /><path d="m16 17 2 2 4-4" /><path d="M21 11.127V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.729l7 4a2 2 0 0 0 2 .001l1.32-.753" /><path d="M3.29 7 12 12l8.71-5" /><path d="m7.5 4.27 8.997 5.148" />',
850
+ TimeEntry: '<line x1="10" x2="14" y1="2" y2="2" /><line x1="12" x2="15" y1="14" y2="11" /><circle cx="12" cy="14" r="8" />',
851
+ Engagement: '<path d="m11 17 2 2a1 1 0 1 0 3-3" /><path d="m14 14 2.5 2.5a1 1 0 1 0 3-3l-3.88-3.88a3 3 0 0 0-4.24 0l-.88.88a1 1 0 1 1-3-3l2.81-2.81a5.79 5.79 0 0 1 7.06-.87l.47.28a2 2 0 0 0 1.42.25L21 4" /><path d="m21 3 1 11h-2" /><path d="M3 3 2 14l6.5 6.5a1 1 0 1 0 3-3" /><path d="M3 4h8" />',
852
+ Case: '<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" />',
853
+ Meeting: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><path d="M16 3.128a4 4 0 0 1 0 7.744" /><path d="M22 21v-2a4 4 0 0 0-3-3.87" /><circle cx="9" cy="7" r="4" />',
854
+ Idea: '<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5" /><path d="M9 18h6" /><path d="M10 22h4" />',
855
+ Campaign: '<path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5" /><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09" /><path d="M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z" /><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05" />',
856
+ BrandDeal: '<path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z" /><path d="m9 12 2 2 4-4" />',
857
+ Recommendation: '<path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z" /><path d="M7 10v12" />',
858
+ Session: '<rect width="20" height="14" x="2" y="3" rx="2" /><line x1="8" x2="16" y1="21" y2="21" /><line x1="12" x2="12" y1="17" y2="21" />',
859
+ PageView: '<path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" /><circle cx="12" cy="12" r="3" />',
860
+ Click: '<path d="M14 4.1 12 6" /><path d="m5.1 8-2.9-.8" /><path d="m6 12-1.9 2" /><path d="M7.2 2.2 8 5.1" /><path d="M9.037 9.69a.498.498 0 0 1 .653-.653l11 4.5a.5.5 0 0 1-.074.949l-4.349 1.041a1 1 0 0 0-.74.739l-1.04 4.35a.5.5 0 0 1-.95.074z" />',
861
+ ScrollMilestone: '<path d="m7 6 5 5 5-5" /><path d="m7 13 5 5 5-5" />',
862
+ TimelineEvent: '<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" /><path d="M3 3v5h5" /><path d="M12 7v5l4 2" />',
863
+ AnonVisitor: '<path d="M9 10h.01" /><path d="M15 10h.01" /><path d="M12 2a8 8 0 0 0-8 8v12l3-3 2.5 2.5L12 19l2.5 2.5L17 19l3 3V10a8 8 0 0 0-8-8z" />',
864
+ AEOAudit: '<path d="m8 11 2 2 4-4" /><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" />',
865
+ WhatsAppConversation: '<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719" />',
866
+ WhatsAppMessage: '<path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z" /><path d="M7 11h10" /><path d="M7 15h6" /><path d="M7 7h8" />',
867
+ CloudflareHostname: '<circle cx="12" cy="12" r="10" /><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" /><path d="M2 12h20" />',
868
+ CloudflareTunnel: '<rect x="16" y="16" width="6" height="6" rx="1" /><rect x="2" y="16" width="6" height="6" rx="1" /><rect x="9" y="2" width="6" height="6" rx="1" /><path d="M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3" /><path d="M12 12V8" />',
869
+ Chain: '<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />',
870
+ ChainLink: '<path d="M9 17H7A5 5 0 0 1 7 7h2" /><path d="M15 7h2a5 5 0 1 1 0 10h-2" /><line x1="8" x2="16" y1="12" y2="12" />',
871
+ FileArtifact: '<path d="M13.659 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v11.5" /><path d="M14 2v5a1 1 0 0 0 1 1h5" /><path d="M8 12v-1" /><path d="M8 18v-2" /><path d="M8 7V6" /><circle cx="8" cy="20" r="2" />',
872
+ VoiceProfile: '<path d="M12 19v3" /><path d="M19 10v2a7 7 0 0 1-14 0v-2" /><rect x="9" y="2" width="6" height="13" rx="3" />',
873
+ VoiceEdit: '<path d="M2 10v3" /><path d="M6 6v11" /><path d="M10 3v18" /><path d="M14 8v7" /><path d="M18 5v13" /><path d="M22 10v3" />'
736
874
  };
737
875
  function iconForLabel2(label) {
738
876
  return Object.prototype.hasOwnProperty.call(LABEL_ICONS, label) ? LABEL_ICONS[label] : null;
@@ -1615,10 +1753,10 @@ var serveStatic = (options = { root: "" }) => {
1615
1753
  };
1616
1754
 
1617
1755
  // server/index.ts
1618
- import { readFileSync as readFileSync45, existsSync as existsSync42, watchFile, readdirSync as readdirSync26, statSync as statSync17 } from "fs";
1756
+ import { readFileSync as readFileSync46, existsSync as existsSync43, watchFile, readdirSync as readdirSync27, statSync as statSync18 } from "fs";
1619
1757
  import { spawn as spawn3 } from "child_process";
1620
1758
  import { createHash as createHash7 } from "crypto";
1621
- import { resolve as resolve41, join as join47, basename as basename13 } from "path";
1759
+ import { resolve as resolve42, join as join47, basename as basename13 } from "path";
1622
1760
  import { homedir as homedir4 } from "os";
1623
1761
  import { monitorEventLoopDelay } from "perf_hooks";
1624
1762
 
@@ -2892,7 +3030,7 @@ var credsSaveQueue = Promise.resolve();
2892
3030
  async function drainCredsSaveQueue(timeoutMs = 5e3) {
2893
3031
  console.error(`${TAG6} draining credential save queue\u2026`);
2894
3032
  const timer = new Promise(
2895
- (resolve42) => setTimeout(() => resolve42("timeout"), timeoutMs)
3033
+ (resolve43) => setTimeout(() => resolve43("timeout"), timeoutMs)
2896
3034
  );
2897
3035
  const result = await Promise.race([
2898
3036
  credsSaveQueue.then(() => "drained"),
@@ -3069,11 +3207,11 @@ async function createWaSocket(opts) {
3069
3207
  return sock;
3070
3208
  }
3071
3209
  async function waitForConnection(sock) {
3072
- return new Promise((resolve42, reject) => {
3210
+ return new Promise((resolve43, reject) => {
3073
3211
  const handler = (update) => {
3074
3212
  if (update.connection === "open") {
3075
3213
  sock.ev.off("connection.update", handler);
3076
- resolve42();
3214
+ resolve43();
3077
3215
  }
3078
3216
  if (update.connection === "close") {
3079
3217
  sock.ev.off("connection.update", handler);
@@ -3181,7 +3319,7 @@ function isTimeoutError(err) {
3181
3319
  return Boolean(err?.__maxyTimeout);
3182
3320
  }
3183
3321
  function withTimeout(label, promise, timeoutMs) {
3184
- return new Promise((resolve42, reject) => {
3322
+ return new Promise((resolve43, reject) => {
3185
3323
  const timer = setTimeout(() => {
3186
3324
  const err = new Error(`${label} timed out after ${timeoutMs}ms`);
3187
3325
  err.__maxyTimeout = true;
@@ -3191,7 +3329,7 @@ function withTimeout(label, promise, timeoutMs) {
3191
3329
  promise.then(
3192
3330
  (value) => {
3193
3331
  clearTimeout(timer);
3194
- resolve42(value);
3332
+ resolve43(value);
3195
3333
  },
3196
3334
  (err) => {
3197
3335
  clearTimeout(timer);
@@ -4256,8 +4394,8 @@ async function persistWhatsAppMessage(input) {
4256
4394
  const { givenName, familyName } = splitName(input.pushName);
4257
4395
  const prev = sessionWriteLocks.get(input.cacheKey);
4258
4396
  let release;
4259
- const mine = new Promise((resolve42) => {
4260
- release = resolve42;
4397
+ const mine = new Promise((resolve43) => {
4398
+ release = resolve43;
4261
4399
  });
4262
4400
  const chained = (prev ?? Promise.resolve()).then(() => mine);
4263
4401
  sessionWriteLocks.set(input.cacheKey, chained);
@@ -5994,11 +6132,11 @@ async function connectWithReconnect(conn) {
5994
6132
  console.error(
5995
6133
  `${TAG17} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
5996
6134
  );
5997
- await new Promise((resolve42) => {
5998
- const timer = setTimeout(resolve42, delay);
6135
+ await new Promise((resolve43) => {
6136
+ const timer = setTimeout(resolve43, delay);
5999
6137
  conn.abortController.signal.addEventListener("abort", () => {
6000
6138
  clearTimeout(timer);
6001
- resolve42();
6139
+ resolve43();
6002
6140
  }, { once: true });
6003
6141
  });
6004
6142
  }
@@ -6006,16 +6144,16 @@ async function connectWithReconnect(conn) {
6006
6144
  }
6007
6145
  }
6008
6146
  function waitForDisconnectEvent(conn) {
6009
- return new Promise((resolve42) => {
6147
+ return new Promise((resolve43) => {
6010
6148
  if (!conn.sock) {
6011
- resolve42();
6149
+ resolve43();
6012
6150
  return;
6013
6151
  }
6014
6152
  const sock = conn.sock;
6015
6153
  const handler = (update) => {
6016
6154
  if (update.connection === "close") {
6017
6155
  sock.ev.off("connection.update", handler);
6018
- resolve42();
6156
+ resolve43();
6019
6157
  }
6020
6158
  };
6021
6159
  sock.ev.on("connection.update", handler);
@@ -6125,7 +6263,7 @@ function monitorInbound(conn) {
6125
6263
  }
6126
6264
  const entries = messageStore.get(storeKey);
6127
6265
  console.error(
6128
- `${TAG17} stored message ${msg.key.id ?? "?"} for ${remoteJid} (type: ${upsert.type}, store size: ${entries?.length ?? 0}/${MESSAGE_STORE_MAX}) account=${conn.platformAccountId}`
6266
+ `${TAG17} stored message ${msg.key.id ?? "?"} for ${remoteJid} (type: ${upsert.type}, store size: ${entries?.length ?? 0}/${MESSAGE_STORE_MAX}) storeAccount=${persistAccountId} socketOwner=${conn.platformAccountId}`
6129
6267
  );
6130
6268
  recordActivity({
6131
6269
  accountId: conn.accountId,
@@ -6489,8 +6627,8 @@ async function handleInboundMessage(conn, msg) {
6489
6627
  const conversationKey = isGroup ? remoteJid : senderPhone;
6490
6628
  const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
6491
6629
  let resolvePending;
6492
- const sttPending = new Promise((resolve42) => {
6493
- resolvePending = resolve42;
6630
+ const sttPending = new Promise((resolve43) => {
6631
+ resolvePending = resolve43;
6494
6632
  });
6495
6633
  if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
6496
6634
  try {
@@ -6879,20 +7017,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
6879
7017
 
6880
7018
  // server/routes/health.ts
6881
7019
  function checkPort(port2, timeoutMs = 500) {
6882
- return new Promise((resolve42) => {
7020
+ return new Promise((resolve43) => {
6883
7021
  const socket = createConnection2(port2, "127.0.0.1");
6884
7022
  socket.setTimeout(timeoutMs);
6885
7023
  socket.once("connect", () => {
6886
7024
  socket.destroy();
6887
- resolve42(true);
7025
+ resolve43(true);
6888
7026
  });
6889
7027
  socket.once("error", () => {
6890
7028
  socket.destroy();
6891
- resolve42(false);
7029
+ resolve43(false);
6892
7030
  });
6893
7031
  socket.once("timeout", () => {
6894
7032
  socket.destroy();
6895
- resolve42(false);
7033
+ resolve43(false);
6896
7034
  });
6897
7035
  });
6898
7036
  }
@@ -7147,8 +7285,8 @@ function webchatTurnTimeoutMs() {
7147
7285
  return Number(process.env.WEBCHAT_TURN_TIMEOUT_MS ?? String(2 * 6e4));
7148
7286
  }
7149
7287
  function createChatRoutes(deps) {
7150
- const app66 = new Hono();
7151
- app66.post("/", async (c) => {
7288
+ const app67 = new Hono();
7289
+ app67.post("/", async (c) => {
7152
7290
  console.log(`[chat-route] entered route=public method=POST`);
7153
7291
  const contentType = c.req.header("content-type") ?? "";
7154
7292
  const account = resolveAccount();
@@ -7412,7 +7550,7 @@ ${result.result.text}` : result.result.text;
7412
7550
  }
7413
7551
  });
7414
7552
  });
7415
- return app66;
7553
+ return app67;
7416
7554
  }
7417
7555
 
7418
7556
  // app/lib/channel-pty-bridge/admin-session-id.ts
@@ -7446,8 +7584,8 @@ function isLoopbackAddr(addr) {
7446
7584
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
7447
7585
  }
7448
7586
  function createScheduleInjectRoutes(deps) {
7449
- const app66 = new Hono();
7450
- app66.post("/", async (c) => {
7587
+ const app67 = new Hono();
7588
+ app67.post("/", async (c) => {
7451
7589
  const env = c.env;
7452
7590
  const remoteAddr = env?.incoming?.socket?.remoteAddress ?? "";
7453
7591
  if (!isLoopbackAddr(remoteAddr)) {
@@ -7548,7 +7686,7 @@ function createScheduleInjectRoutes(deps) {
7548
7686
  console.error(`${TAG20} op=inject-spawn eventId=${eventId} sessionId=${sessionId} result=ok status=-`);
7549
7687
  return c.json({ ok: true }, 200);
7550
7688
  });
7551
- return app66;
7689
+ return app67;
7552
7690
  }
7553
7691
 
7554
7692
  // server/index.ts
@@ -8231,8 +8369,8 @@ async function startLogin(opts) {
8231
8369
  await clearAuth(authDir);
8232
8370
  let resolveCode = null;
8233
8371
  let rejectCode = null;
8234
- const codePromise = new Promise((resolve42, reject) => {
8235
- resolveCode = resolve42;
8372
+ const codePromise = new Promise((resolve43, reject) => {
8373
+ resolveCode = resolve43;
8236
8374
  rejectCode = reject;
8237
8375
  });
8238
8376
  const codeTimer = setTimeout(
@@ -8814,9 +8952,9 @@ function evaluateCallerScope(c, requestedAccountId) {
8814
8952
  }
8815
8953
  function callerScopeDenial(c, requestedAccountId) {
8816
8954
  const { decision, callerAccountId, houseAdminScope } = evaluateCallerScope(c, requestedAccountId);
8817
- if (decision.authorized) return null;
8955
+ if (decision.authorized) return { denial: null, callerAccountId };
8818
8956
  console.error(`[whatsapp-read-tool] op=authz-deny requested=${requestedAccountId} caller=${callerAccountId ?? "none"} houseAdmin=${houseAdminScope ? "y" : "n"}`);
8819
- return c.json({ error: decision.reason }, 403);
8957
+ return { denial: c.json({ error: decision.reason }, 403), callerAccountId };
8820
8958
  }
8821
8959
  function houseSocketScopeDenial(c, op) {
8822
8960
  const houseAccountId = resolveAccount()?.accountId ?? "";
@@ -9244,7 +9382,7 @@ app2.get("/activity", (c) => {
9244
9382
  app2.get("/conversations", (c) => {
9245
9383
  try {
9246
9384
  const requestedAccountId = validateAccountId(c.req.query("accountId") ?? null);
9247
- const denial = callerScopeDenial(c, requestedAccountId);
9385
+ const { denial, callerAccountId } = callerScopeDenial(c, requestedAccountId);
9248
9386
  if (denial) return denial;
9249
9387
  const projection = projectionFor(requestedAccountId);
9250
9388
  const storeAccountId = resolveReadStoreKey(projection.storeAccountId);
@@ -9265,7 +9403,7 @@ app2.get("/conversations", (c) => {
9265
9403
  };
9266
9404
  });
9267
9405
  conversations.sort((a, b) => (b.lastMessageTimestamp ?? 0) - (a.lastMessageTimestamp ?? 0));
9268
- console.error(`${TAG25} conversations requested=${requestedAccountId} account=${storeAccountId} projected=${projecting} storeAccount=${projecting ? storeAccountId : "self"} managerPhonesBound=${managerPhonesBound} storeKeyFound=${allConversations.size > 0} count=${conversations.length}`);
9406
+ console.error(`${TAG25} conversations requested=${requestedAccountId} caller=${callerAccountId ?? "none"} account=${storeAccountId} projected=${projecting} storeAccount=${projecting ? storeAccountId : "self"} managerPhonesBound=${managerPhonesBound} storeKeyFound=${allConversations.size > 0} count=${conversations.length}`);
9269
9407
  return c.json({ conversations });
9270
9408
  } catch (err) {
9271
9409
  console.error(`${TAG25} conversations error: ${String(err)}`);
@@ -9275,7 +9413,7 @@ app2.get("/conversations", (c) => {
9275
9413
  app2.get("/messages", (c) => {
9276
9414
  try {
9277
9415
  const requestedAccountId = validateAccountId(c.req.query("accountId") ?? null);
9278
- const denial = callerScopeDenial(c, requestedAccountId);
9416
+ const { denial, callerAccountId } = callerScopeDenial(c, requestedAccountId);
9279
9417
  if (denial) return denial;
9280
9418
  const jid = c.req.query("jid");
9281
9419
  if (!jid) {
@@ -9321,7 +9459,7 @@ app2.get("/messages", (c) => {
9321
9459
  ...reactions && reactions.length > 0 ? { reactions } : {}
9322
9460
  };
9323
9461
  });
9324
- console.error(`${TAG25} messages requested=${requestedAccountId} account=${storeAccountId} jid=${jid} projected=${projecting} storeAccount=${projecting ? storeAccountId : "self"} managerPhonesBound=${managerPhonesBound} storeKeyFound=${storeMessages.length > 0} limit=${effectiveLimit ?? "all"} returned=${messages.length} withAttachments=${withAttachments}`);
9462
+ console.error(`${TAG25} messages requested=${requestedAccountId} caller=${callerAccountId ?? "none"} account=${storeAccountId} jid=${jid} projected=${projecting} storeAccount=${projecting ? storeAccountId : "self"} managerPhonesBound=${managerPhonesBound} storeKeyFound=${storeMessages.length > 0} limit=${effectiveLimit ?? "all"} returned=${messages.length} withAttachments=${withAttachments}`);
9325
9463
  return c.json({ messages });
9326
9464
  } catch (err) {
9327
9465
  console.error(`${TAG25} messages error: ${String(err)}`);
@@ -9334,7 +9472,7 @@ app2.get("/conversation-graph-state", async (c) => {
9334
9472
  const jid = c.req.query("jid");
9335
9473
  const accountIdQuery = c.req.query("accountId");
9336
9474
  const t0 = Date.now();
9337
- const denial = callerScopeDenial(c, validateAccountId(accountIdQuery ?? null));
9475
+ const { denial } = callerScopeDenial(c, validateAccountId(accountIdQuery ?? null));
9338
9476
  if (denial) return denial;
9339
9477
  if (!directCacheKey && !jid) {
9340
9478
  const requestedAccountId = validateAccountId(accountIdQuery ?? null);
@@ -11623,6 +11761,7 @@ function unwrapChannel(text) {
11623
11761
  return source ? { text: inner, source } : { text: inner };
11624
11762
  }
11625
11763
  var COMPOSED_ADMIN_FRAME = /^(?:## Scheduled automation \(platform-verified\)\n[\s\S]*?\n\n)?(?:## Standing rules\n[\s\S]*?\n\n)?## Context\n([\s\S]*)\n\n## Instruction\n[\s\S]*$/;
11764
+ var SCHEDULED_MARKER_PREFIX = "## Scheduled automation (platform-verified)\n";
11626
11765
  var UPLOAD_ANNOTATION = /(?:\n\n)?\[The operator uploaded \d+ file\(s\): [\s\S]*\]$/;
11627
11766
  function rawFromComposedAdminFrame(text) {
11628
11767
  const context = text.match(COMPOSED_ADMIN_FRAME)?.[1];
@@ -11638,6 +11777,7 @@ function uploadCountOf(text) {
11638
11777
  function operatorInboundTurn(u, ts) {
11639
11778
  const rawBody = rawFromComposedAdminFrame(u.text);
11640
11779
  const uploadCount = uploadCountOf(u.text);
11780
+ const scheduled = rawBody !== void 0 && u.text.startsWith(SCHEDULED_MARKER_PREFIX);
11641
11781
  const text = rawBody === void 0 ? u.text.replace(PUBLIC_UPLOAD_ANNOTATION, "") : u.text;
11642
11782
  return {
11643
11783
  kind: "operator-inbound",
@@ -11645,7 +11785,8 @@ function operatorInboundTurn(u, ts) {
11645
11785
  ts,
11646
11786
  ...u.source ? { source: u.source } : {},
11647
11787
  ...rawBody !== void 0 ? { rawBody } : {},
11648
- ...uploadCount !== void 0 ? { uploadCount } : {}
11788
+ ...uploadCount !== void 0 ? { uploadCount } : {},
11789
+ ...scheduled ? { scheduled: true } : {}
11649
11790
  };
11650
11791
  }
11651
11792
  function asString(content) {
@@ -11654,16 +11795,6 @@ function asString(content) {
11654
11795
  function tsOf(row) {
11655
11796
  return typeof row.timestamp === "string" ? row.timestamp : null;
11656
11797
  }
11657
- function hasWebchatReply(content) {
11658
- if (!Array.isArray(content)) return false;
11659
- for (const block of content) {
11660
- if (block && typeof block === "object") {
11661
- const b = block;
11662
- if (b.type === "tool_use" && b.name === WEBCHAT_REPLY_TOOL) return true;
11663
- }
11664
- }
11665
- return false;
11666
- }
11667
11798
  function joinTextBlocks(content) {
11668
11799
  if (!Array.isArray(content)) return "";
11669
11800
  const parts = [];
@@ -11786,9 +11917,8 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
11786
11917
  out.push({ kind: "agent-error", code, raw, ts });
11787
11918
  continue;
11788
11919
  }
11789
- if (hasWebchatReply(msg?.content)) turnCtx.repliedThisTurn = true;
11790
11920
  const isEnd = msg?.stop_reason === "end_turn";
11791
- const promoteFinal = isEnd && turnCtx.lastChannelSource === "webchat" && !turnCtx.repliedThisTurn;
11921
+ const promoteFinal = isEnd && turnCtx.lastChannelSource === "webchat";
11792
11922
  out.push(...assistantTurns(msg?.content, ts, promoteFinal, erroredIds));
11793
11923
  continue;
11794
11924
  }
@@ -11797,7 +11927,6 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
11797
11927
  if (content !== null && CHANNEL_WRAPPER2.test(content)) {
11798
11928
  const u = unwrapChannel(content);
11799
11929
  turnCtx.lastChannelSource = u.source;
11800
- turnCtx.repliedThisTurn = false;
11801
11930
  if (!isScheduleSource(content)) {
11802
11931
  out.push(operatorInboundTurn(u, ts));
11803
11932
  queuedPendingSuppress.set(u.text, (queuedPendingSuppress.get(u.text) ?? 0) + 1);
@@ -11811,7 +11940,6 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
11811
11940
  if (isChannelQueued) {
11812
11941
  const u = unwrapChannel(att.prompt);
11813
11942
  turnCtx.lastChannelSource = u.source;
11814
- turnCtx.repliedThisTurn = false;
11815
11943
  if (!isScheduleSource(att.prompt)) {
11816
11944
  renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress);
11817
11945
  }
@@ -11841,7 +11969,6 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
11841
11969
  if (isChannel) {
11842
11970
  const u = unwrapChannel(text);
11843
11971
  turnCtx.lastChannelSource = u.source;
11844
- turnCtx.repliedThisTurn = false;
11845
11972
  if (!isScheduleSource(text)) {
11846
11973
  renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress);
11847
11974
  }
@@ -13818,8 +13945,8 @@ async function reapplyLeversViaManager() {
13818
13945
  var WEBCHAT_SEND_TURN_WINDOW_MS = Number(process.env.WEBCHAT_SEND_TURN_WINDOW_MS ?? String(15e3));
13819
13946
  var sendSeq = 0;
13820
13947
  function createWebchatRoutes(deps) {
13821
- const app66 = new Hono();
13822
- app66.post("/send", requireAdminSession, async (c) => {
13948
+ const app67 = new Hono();
13949
+ app67.post("/send", requireAdminSession, async (c) => {
13823
13950
  let accountId;
13824
13951
  try {
13825
13952
  accountId = resolvePlatformAccountId();
@@ -14022,7 +14149,7 @@ ${note}` : note;
14022
14149
  if (turnTimer.unref) turnTimer.unref();
14023
14150
  return c.json({ ok: true });
14024
14151
  });
14025
- app66.post("/interrupt", requireAdminSession, async (c) => {
14152
+ app67.post("/interrupt", requireAdminSession, async (c) => {
14026
14153
  const cacheKey = c.get("cacheKey");
14027
14154
  const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
14028
14155
  const primaryUserId = resolvePrimaryAdminUserId();
@@ -14050,7 +14177,7 @@ ${note}` : note;
14050
14177
  }
14051
14178
  return c.json({ ok: true, stopped: outcome.stopped, intId: outcome.intId, deadChild: outcome.deadChild }, 200);
14052
14179
  });
14053
- app66.post("/settings", requireAdminSession, async (c) => {
14180
+ app67.post("/settings", requireAdminSession, async (c) => {
14054
14181
  const body = await c.req.json().catch(() => null);
14055
14182
  const op = body?.op;
14056
14183
  const value = body?.value;
@@ -14090,7 +14217,7 @@ ${note}` : note;
14090
14217
  console.log(`[webchat:settings] op=${op} outcome=accepted value=${value} settingsApplied=${settingsApplied}`);
14091
14218
  return c.json({ ok: true, settingsApplied });
14092
14219
  });
14093
- app66.get("/session", requireAdminSession, async (c) => {
14220
+ app67.get("/session", requireAdminSession, async (c) => {
14094
14221
  let accountId;
14095
14222
  try {
14096
14223
  accountId = resolvePlatformAccountId();
@@ -14168,7 +14295,7 @@ ${note}` : note;
14168
14295
  const indicators = await fetchComposerIndicators(sessionId);
14169
14296
  return c.json({ sessionId, projectDir, source, sizeBytes: jsonlSizeBytes(projectDir, sessionId), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${sessionId}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${sessionId}`) ?? null, ...indicators, ...readLevers(account) });
14170
14297
  });
14171
- app66.post("/permission-verdict", requireAdminSession, async (c) => {
14298
+ app67.post("/permission-verdict", requireAdminSession, async (c) => {
14172
14299
  const body = await c.req.json().catch(() => null);
14173
14300
  const sessionId = body?.sessionId;
14174
14301
  const requestId = body?.request_id;
@@ -14185,7 +14312,7 @@ ${note}` : note;
14185
14312
  const ok = deps.resolvePermissionVerdict?.(`session:${sessionId}`, requestId, behavior) ?? false;
14186
14313
  return c.json({ ok });
14187
14314
  });
14188
- return app66;
14315
+ return app67;
14189
14316
  }
14190
14317
 
14191
14318
  // server/routes/webchat-greeting.ts
@@ -15541,15 +15668,15 @@ function operatorRoleFor(config, userId) {
15541
15668
  async function buildAccountOptionList(accounts, userId) {
15542
15669
  const houseAccount = accounts.find((a) => a.config.role === "house");
15543
15670
  console.log(`[admin-accounts] op=list count=${accounts.length} house=${houseAccount?.accountId ?? "none"}`);
15544
- const resolve42 = async (a) => {
15671
+ const resolve43 = async (a) => {
15545
15672
  const businessName = await fetchAccountName(a.accountId) || void 0;
15546
15673
  return { accountId: a.accountId, businessName, role: operatorRoleFor(a.config, userId), isHouse: a.config.role === "house" };
15547
15674
  };
15548
15675
  const houseOptions = await Promise.all(
15549
- accounts.filter((a) => a.config.role === "house").map(resolve42)
15676
+ accounts.filter((a) => a.config.role === "house").map(resolve43)
15550
15677
  );
15551
15678
  const nonHouseOptions = await Promise.all(
15552
- accounts.filter((a) => a.config.role !== "house").map(resolve42)
15679
+ accounts.filter((a) => a.config.role !== "house").map(resolve43)
15553
15680
  );
15554
15681
  const sortKey = (o) => (o.businessName || o.accountId).toLowerCase();
15555
15682
  nonHouseOptions.sort((x, y) => {
@@ -16821,7 +16948,7 @@ function parseSkillPathsFromFrontmatter(fm) {
16821
16948
  }
16822
16949
  return out;
16823
16950
  }
16824
- function listPluginDirs() {
16951
+ function listPluginDirs(accountPluginsDir) {
16825
16952
  const out = /* @__PURE__ */ new Map();
16826
16953
  const platformPlugins = resolve22(PLATFORM_ROOT, "plugins");
16827
16954
  if (existsSync30(platformPlugins)) {
@@ -16850,8 +16977,38 @@ function listPluginDirs() {
16850
16977
  }
16851
16978
  }
16852
16979
  }
16980
+ if (accountPluginsDir && existsSync30(accountPluginsDir)) {
16981
+ try {
16982
+ for (const name of readdirSync22(accountPluginsDir)) {
16983
+ if (out.has(name)) continue;
16984
+ const dir = join33(accountPluginsDir, name);
16985
+ try {
16986
+ if (statSync13(dir).isDirectory()) out.set(name, dir);
16987
+ } catch {
16988
+ }
16989
+ }
16990
+ } catch {
16991
+ }
16992
+ }
16853
16993
  return out;
16854
16994
  }
16995
+ function accountPluginsDirFor(accountId) {
16996
+ return resolve22(PLATFORM_ROOT, "..", "data/accounts", accountId, "plugins");
16997
+ }
16998
+ function listAccountPluginNames(accountPluginsDir) {
16999
+ if (!existsSync30(accountPluginsDir)) return [];
17000
+ try {
17001
+ return readdirSync22(accountPluginsDir).filter((name) => {
17002
+ try {
17003
+ return statSync13(join33(accountPluginsDir, name)).isDirectory();
17004
+ } catch {
17005
+ return false;
17006
+ }
17007
+ });
17008
+ } catch {
17009
+ return [];
17010
+ }
17011
+ }
16855
17012
  function readEnabledPlugins(accountId) {
16856
17013
  const accountFile = resolve22(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
16857
17014
  if (!existsSync30(accountFile)) return /* @__PURE__ */ new Set();
@@ -16877,10 +17034,13 @@ function readFrontmatter(path3) {
16877
17034
  }
16878
17035
  function computeActivePlugins(accountId) {
16879
17036
  const enabled = readEnabledPlugins(accountId);
16880
- if (enabled.size === 0) return [];
16881
- const pluginDirs = listPluginDirs();
17037
+ const accountPluginsDir = accountPluginsDirFor(accountId);
17038
+ const accountPluginNames = listAccountPluginNames(accountPluginsDir);
17039
+ const emitNames = Array.from(/* @__PURE__ */ new Set([...enabled, ...accountPluginNames])).sort();
17040
+ if (emitNames.length === 0) return [];
17041
+ const pluginDirs = listPluginDirs(accountPluginsDir);
16882
17042
  const out = [];
16883
- for (const name of Array.from(enabled).sort()) {
17043
+ for (const name of emitNames) {
16884
17044
  const dir = pluginDirs.get(name);
16885
17045
  if (!dir) continue;
16886
17046
  const fm = readFrontmatter(join33(dir, "PLUGIN.md"));
@@ -16934,7 +17094,7 @@ function computeSpecialistDomains(accountId) {
16934
17094
  } catch {
16935
17095
  return [];
16936
17096
  }
16937
- const pluginDirs = listPluginDirs();
17097
+ const pluginDirs = listPluginDirs(accountPluginsDirFor(accountId));
16938
17098
  const descByPlugin = /* @__PURE__ */ new Map();
16939
17099
  const resolveDesc = (qualified) => {
16940
17100
  if (!qualified.startsWith("mcp__")) return void 0;
@@ -23710,8 +23870,163 @@ app47.patch("/:eventId", requireAdminSession, async (c) => {
23710
23870
  await session.close();
23711
23871
  }
23712
23872
  });
23873
+ app47.delete("/:eventId", requireAdminSession, async (c) => {
23874
+ const accountId = getAccountIdForSession(c.var.cacheKey);
23875
+ if (!accountId) {
23876
+ console.error('[admin:routines] op=delete auth-rejected reason="no account for session"');
23877
+ return c.json({ error: "Account not found for session" }, 401);
23878
+ }
23879
+ const eventId = c.req.param("eventId");
23880
+ const session = getSession();
23881
+ try {
23882
+ const res = await session.run(
23883
+ `MATCH (e:Event {eventId: $eventId, accountId: $accountId})
23884
+ WHERE ${AUTOMATION_WHERE}
23885
+ WITH e, e.name AS name
23886
+ DETACH DELETE e
23887
+ RETURN name`,
23888
+ { eventId, accountId }
23889
+ );
23890
+ const found = res.records.length > 0;
23891
+ console.log(`[admin:routines] op=delete id=${eventId.slice(0, 8)} found=${found ? 1 : 0}`);
23892
+ return c.json({ found });
23893
+ } catch (err) {
23894
+ const message = err instanceof Error ? err.message : String(err);
23895
+ console.error(`[admin:routines] op=delete-fail id=${eventId.slice(0, 8)} err="${message}"`);
23896
+ return c.json({ error: `Delete failed: ${message}` }, 503);
23897
+ } finally {
23898
+ await session.close();
23899
+ }
23900
+ });
23713
23901
  var routines_default = app47;
23714
23902
 
23903
+ // server/routes/admin/skills.ts
23904
+ import { existsSync as existsSync36, readdirSync as readdirSync24, readFileSync as readFileSync39, rmSync as rmSync3 } from "fs";
23905
+ import { resolve as resolve31 } from "path";
23906
+ var app48 = new Hono();
23907
+ var NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
23908
+ function splitSkillMd(text) {
23909
+ const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
23910
+ const fm = { name: "", description: "", publicEmbed: false };
23911
+ if (!m) return { frontmatter: fm, body: text };
23912
+ for (const line of m[1].split(/\r?\n/)) {
23913
+ const kv = line.match(/^([A-Za-z][\w-]*):[ \t]*(.*)$/);
23914
+ if (!kv) continue;
23915
+ const [, key, rawVal] = kv;
23916
+ const val = stripQuotes(rawVal.trim());
23917
+ if (key === "name") fm.name = val;
23918
+ else if (key === "description") fm.description = val;
23919
+ else if (key === "publicEmbed") fm.publicEmbed = val === "true";
23920
+ }
23921
+ return { frontmatter: fm, body: text.slice(m[0].length) };
23922
+ }
23923
+ function stripQuotes(s) {
23924
+ if (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'")) return s.slice(1, -1);
23925
+ return s;
23926
+ }
23927
+ function accountDirForSession(cacheKey) {
23928
+ const accountId = getAccountIdForSession(cacheKey);
23929
+ if (!accountId) return null;
23930
+ const match = listValidAccounts().find((a) => a.accountId === accountId);
23931
+ return match ? { accountId, accountDir: match.accountDir } : null;
23932
+ }
23933
+ function subdirs(dir) {
23934
+ if (!existsSync36(dir)) return [];
23935
+ try {
23936
+ return readdirSync24(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
23937
+ } catch {
23938
+ return [];
23939
+ }
23940
+ }
23941
+ app48.get("/", requireAdminSession, async (c) => {
23942
+ const acct = accountDirForSession(c.var.cacheKey);
23943
+ if (!acct) {
23944
+ console.error('[admin:skills] op=list auth-rejected reason="no account for session"');
23945
+ return c.json({ error: "Account not found for session" }, 401);
23946
+ }
23947
+ const pluginsDir = resolve31(acct.accountDir, "plugins");
23948
+ const skills = [];
23949
+ let pluginCount = 0;
23950
+ for (const plugin of subdirs(pluginsDir)) {
23951
+ pluginCount++;
23952
+ const skillsDir = resolve31(pluginsDir, plugin, "skills");
23953
+ for (const skill of subdirs(skillsDir)) {
23954
+ const skillMd = resolve31(skillsDir, skill, "SKILL.md");
23955
+ if (!existsSync36(skillMd)) continue;
23956
+ try {
23957
+ const { frontmatter } = splitSkillMd(readFileSync39(skillMd, "utf-8"));
23958
+ const refsDir = resolve31(skillsDir, skill, "references");
23959
+ const refCount = existsSync36(refsDir) ? readdirSync24(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).length : 0;
23960
+ skills.push({ plugin, skill, description: frontmatter.description, refCount });
23961
+ } catch (err) {
23962
+ console.error(`[admin:skills] op=list-skip plugin=${plugin} skill=${skill} reason="${err instanceof Error ? err.message : String(err)}"`);
23963
+ }
23964
+ }
23965
+ }
23966
+ skills.sort((a, b) => a.plugin.localeCompare(b.plugin) || a.skill.localeCompare(b.skill));
23967
+ console.log(`[admin:skills] op=list accountId=${acct.accountId.slice(0, 8)} plugins=${pluginCount} skills=${skills.length}`);
23968
+ return c.json({ skills });
23969
+ });
23970
+ app48.get("/:plugin/:skill", requireAdminSession, async (c) => {
23971
+ const acct = accountDirForSession(c.var.cacheKey);
23972
+ if (!acct) return c.json({ error: "Account not found for session" }, 401);
23973
+ const plugin = c.req.param("plugin");
23974
+ const skill = c.req.param("skill");
23975
+ if (!NAME_RE.test(plugin) || !NAME_RE.test(skill)) {
23976
+ console.error(`[admin:skills] op=get outcome=rejected reason=invalid-name plugin="${plugin}" skill="${skill}"`);
23977
+ return c.json({ error: "Invalid plugin or skill name" }, 400);
23978
+ }
23979
+ const skillDir = resolve31(acct.accountDir, "plugins", plugin, "skills", skill);
23980
+ const skillMd = resolve31(skillDir, "SKILL.md");
23981
+ const found = existsSync36(skillMd);
23982
+ console.log(`[admin:skills] op=get plugin=${plugin} skill=${skill} found=${found}`);
23983
+ if (!found) return c.json({ error: "Skill not found" }, 404);
23984
+ try {
23985
+ const { frontmatter, body } = splitSkillMd(readFileSync39(skillMd, "utf-8"));
23986
+ const refsDir = resolve31(skillDir, "references");
23987
+ const references = existsSync36(refsDir) ? readdirSync24(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).map((e) => e.name).sort() : [];
23988
+ return c.json({ skill: { plugin, skill, frontmatter, body, references } });
23989
+ } catch (err) {
23990
+ const message = err instanceof Error ? err.message : String(err);
23991
+ console.error(`[admin:skills] op=get-fail plugin=${plugin} skill=${skill} err="${message}"`);
23992
+ return c.json({ error: `Skill unavailable: ${message}` }, 503);
23993
+ }
23994
+ });
23995
+ app48.delete("/:plugin/:skill", requireAdminSession, async (c) => {
23996
+ const acct = accountDirForSession(c.var.cacheKey);
23997
+ if (!acct) return c.json({ error: "Account not found for session" }, 401);
23998
+ const plugin = c.req.param("plugin");
23999
+ const skill = c.req.param("skill");
24000
+ if (!NAME_RE.test(plugin) || !NAME_RE.test(skill)) {
24001
+ console.error(`[admin:skills] op=delete outcome=rejected reason=invalid-name plugin="${plugin}" skill="${skill}"`);
24002
+ return c.json({ error: "Invalid plugin or skill name" }, 400);
24003
+ }
24004
+ const pluginDir = resolve31(acct.accountDir, "plugins", plugin);
24005
+ const skillsDir = resolve31(pluginDir, "skills");
24006
+ const skillDir = resolve31(skillsDir, skill);
24007
+ if (!existsSync36(resolve31(skillDir, "SKILL.md"))) {
24008
+ console.error(`[admin:skills] op=delete outcome=rejected reason=not-found plugin=${plugin} skill=${skill}`);
24009
+ return c.json({ error: "Skill not found" }, 404);
24010
+ }
24011
+ try {
24012
+ rmSync3(skillDir, { recursive: true, force: true });
24013
+ const pluginDirRemoved = subdirs(skillsDir).length === 0;
24014
+ if (pluginDirRemoved) rmSync3(pluginDir, { recursive: true, force: true });
24015
+ const skillDirGone = !existsSync36(skillDir);
24016
+ if (!skillDirGone) {
24017
+ console.error(`[admin:skills] op=delete plugin=${plugin} skill=${skill} outcome=rejected reason=rm-incomplete skillDirGone=false`);
24018
+ return c.json({ error: "Delete did not remove the skill directory" }, 503);
24019
+ }
24020
+ console.log(`[admin:skills] op=delete plugin=${plugin} skill=${skill} outcome=ok skillDirGone=${skillDirGone} pluginDirRemoved=${pluginDirRemoved}`);
24021
+ return c.json({ ok: true, skillDirGone, pluginDirRemoved });
24022
+ } catch (err) {
24023
+ const message = err instanceof Error ? err.message : String(err);
24024
+ console.error(`[admin:skills] op=delete plugin=${plugin} skill=${skill} outcome=rejected reason=rm-error err="${message}"`);
24025
+ return c.json({ error: `Delete failed: ${message}` }, 503);
24026
+ }
24027
+ });
24028
+ var skills_default = app48;
24029
+
23715
24030
  // app/lib/time-entry-format.ts
23716
24031
  function secondsBetween(startIso, endIso) {
23717
24032
  const s = Date.parse(startIso);
@@ -23733,8 +24048,8 @@ function toNum(v) {
23733
24048
  var TAG39 = "[task-timer]";
23734
24049
  var COMPLETED = /* @__PURE__ */ new Set(["completed"]);
23735
24050
  var HIDDEN_FROM_OPEN = /* @__PURE__ */ new Set(["completed", "cancelled"]);
23736
- var app48 = new Hono();
23737
- app48.get("/", requireAdminSession, async (c) => {
24051
+ var app49 = new Hono();
24052
+ app49.get("/", requireAdminSession, async (c) => {
23738
24053
  const cacheKey = c.var.cacheKey;
23739
24054
  const accountId = getAccountIdForSession(cacheKey);
23740
24055
  if (!accountId) {
@@ -23821,13 +24136,13 @@ app48.get("/", requireAdminSession, async (c) => {
23821
24136
  await session.close();
23822
24137
  }
23823
24138
  });
23824
- var tasks_list_default = app48;
24139
+ var tasks_list_default = app49;
23825
24140
 
23826
24141
  // server/routes/admin/task-timer-start.ts
23827
24142
  import { randomUUID as randomUUID14 } from "crypto";
23828
24143
  var TAG40 = "[task-timer]";
23829
- var app49 = new Hono();
23830
- app49.post("/", requireAdminSession, async (c) => {
24144
+ var app50 = new Hono();
24145
+ app50.post("/", requireAdminSession, async (c) => {
23831
24146
  const cacheKey = c.var.cacheKey;
23832
24147
  const accountId = getAccountIdForSession(cacheKey);
23833
24148
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -23882,13 +24197,13 @@ app49.post("/", requireAdminSession, async (c) => {
23882
24197
  await session.close();
23883
24198
  }
23884
24199
  });
23885
- var task_timer_start_default = app49;
24200
+ var task_timer_start_default = app50;
23886
24201
 
23887
24202
  // server/routes/admin/task-timer-stop.ts
23888
24203
  import neo4j5 from "neo4j-driver";
23889
24204
  var TAG41 = "[task-timer]";
23890
- var app50 = new Hono();
23891
- app50.post("/", requireAdminSession, async (c) => {
24205
+ var app51 = new Hono();
24206
+ app51.post("/", requireAdminSession, async (c) => {
23892
24207
  const cacheKey = c.var.cacheKey;
23893
24208
  const accountId = getAccountIdForSession(cacheKey);
23894
24209
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -23955,12 +24270,12 @@ app50.post("/", requireAdminSession, async (c) => {
23955
24270
  await session.close();
23956
24271
  }
23957
24272
  });
23958
- var task_timer_stop_default = app50;
24273
+ var task_timer_stop_default = app51;
23959
24274
 
23960
24275
  // server/routes/admin/task-complete.ts
23961
24276
  var TAG42 = "[task-timer]";
23962
- var app51 = new Hono();
23963
- app51.post("/", requireAdminSession, async (c) => {
24277
+ var app52 = new Hono();
24278
+ app52.post("/", requireAdminSession, async (c) => {
23964
24279
  const cacheKey = c.var.cacheKey;
23965
24280
  const accountId = getAccountIdForSession(cacheKey);
23966
24281
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -23998,14 +24313,14 @@ app51.post("/", requireAdminSession, async (c) => {
23998
24313
  await session.close();
23999
24314
  }
24000
24315
  });
24001
- var task_complete_default = app51;
24316
+ var task_complete_default = app52;
24002
24317
 
24003
24318
  // server/routes/admin/task-time-adjust.ts
24004
24319
  import { randomUUID as randomUUID15 } from "crypto";
24005
24320
  import neo4j6 from "neo4j-driver";
24006
24321
  var TAG43 = "[task-time-adjust]";
24007
- var app52 = new Hono();
24008
- app52.post("/", requireAdminSession, async (c) => {
24322
+ var app53 = new Hono();
24323
+ app53.post("/", requireAdminSession, async (c) => {
24009
24324
  const cacheKey = c.var.cacheKey;
24010
24325
  const accountId = getAccountIdForSession(cacheKey);
24011
24326
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -24079,11 +24394,11 @@ app52.post("/", requireAdminSession, async (c) => {
24079
24394
  await session.close();
24080
24395
  }
24081
24396
  });
24082
- var task_time_adjust_default = app52;
24397
+ var task_time_adjust_default = app53;
24083
24398
 
24084
24399
  // server/routes/admin/activity.ts
24085
- import { readdirSync as readdirSync24 } from "fs";
24086
- var app53 = new Hono();
24400
+ import { readdirSync as readdirSync25 } from "fs";
24401
+ var app54 = new Hono();
24087
24402
  var TAG44 = "[activity]";
24088
24403
  function resolveHouseAccountId(accounts) {
24089
24404
  const houses = accounts.filter((a) => a.config.role === "house");
@@ -24098,14 +24413,14 @@ function requestToken() {
24098
24413
  var short = (id) => id ? id.slice(0, 8) : "unset";
24099
24414
  function countAccountDirsOnDisk() {
24100
24415
  try {
24101
- return readdirSync24(ACCOUNTS_DIR, { withFileTypes: true }).filter(
24416
+ return readdirSync25(ACCOUNTS_DIR, { withFileTypes: true }).filter(
24102
24417
  (e) => e.isDirectory() && !e.name.startsWith(".")
24103
24418
  ).length;
24104
24419
  } catch {
24105
24420
  return null;
24106
24421
  }
24107
24422
  }
24108
- app53.get("/", requireAdminSession, async (c) => {
24423
+ app54.get("/", requireAdminSession, async (c) => {
24109
24424
  const req = requestToken();
24110
24425
  const cacheKey = c.var.cacheKey;
24111
24426
  const caller2 = getAccountIdForSession(cacheKey) ?? null;
@@ -24214,61 +24529,62 @@ app53.get("/", requireAdminSession, async (c) => {
24214
24529
  }
24215
24530
  });
24216
24531
  });
24217
- var activity_default = app53;
24532
+ var activity_default = app54;
24218
24533
 
24219
24534
  // server/routes/admin/index.ts
24220
- var app54 = new Hono();
24221
- app54.route("/session", session_default);
24222
- app54.route("/accounts", accounts_default);
24223
- app54.route("/logs", logs_default);
24224
- app54.route("/claude-info", claude_info_default);
24225
- app54.route("/attachment", attachment_default);
24226
- app54.route("/agents", agents_default);
24227
- app54.route("/sessions", sessions_default);
24228
- app54.route("/claude-sessions", claude_sessions_default);
24229
- app54.route("/log-ingest", log_ingest_default);
24230
- app54.route("/events", events_default);
24231
- app54.route("/files", files_default);
24232
- app54.route("/graph-search", graph_search_default);
24233
- app54.route("/graph-subgraph", graph_subgraph_default);
24234
- app54.route("/graph-delete", graph_delete_default);
24235
- app54.route("/graph-restore", graph_restore_default);
24236
- app54.route("/graph-labels-in-graph", graph_labels_in_graph_default);
24237
- app54.route("/graph-default-view", graph_default_view_default);
24238
- app54.route("/sidebar-artefacts", sidebar_artefacts_default);
24239
- app54.route("/sidebar-sessions", sidebar_sessions_default);
24240
- app54.route("/session-delete", session_delete_default);
24241
- app54.route("/session-stop", session_stop_default);
24242
- app54.route("/session-archive", session_archive_default);
24243
- app54.route("/session-rename", session_rename_default);
24244
- app54.route("/session-usage", session_usage_default);
24245
- app54.route("/browser", browser_default);
24246
- app54.route("/session-rc-spawn", session_rc_spawn_default);
24247
- app54.route("/session-reseat", session_reseat_default);
24248
- app54.route("/system-stats", system_stats_default);
24249
- app54.route("/health-brand", health_default2);
24250
- app54.route("/linkedin-ingest", linkedin_ingest_default);
24251
- app54.route("/post-turn-context", post_turn_context_default);
24252
- app54.route("/public-session-context", public_session_context_default);
24253
- app54.route("/public-session-exit", public_session_exit_default);
24254
- app54.route("/access-session-evict", access_session_evict_default);
24255
- app54.route("/enrol-person", enrol_person_default);
24256
- app54.route("/calendar", calendar_default);
24257
- app54.route("/routines", routines_default);
24258
- app54.route("/tasks-list", tasks_list_default);
24259
- app54.route("/task-timer-start", task_timer_start_default);
24260
- app54.route("/task-timer-stop", task_timer_stop_default);
24261
- app54.route("/task-complete", task_complete_default);
24262
- app54.route("/task-time-adjust", task_time_adjust_default);
24263
- app54.route("/activity", activity_default);
24264
- var admin_default = app54;
24535
+ var app55 = new Hono();
24536
+ app55.route("/session", session_default);
24537
+ app55.route("/accounts", accounts_default);
24538
+ app55.route("/logs", logs_default);
24539
+ app55.route("/claude-info", claude_info_default);
24540
+ app55.route("/attachment", attachment_default);
24541
+ app55.route("/agents", agents_default);
24542
+ app55.route("/sessions", sessions_default);
24543
+ app55.route("/claude-sessions", claude_sessions_default);
24544
+ app55.route("/log-ingest", log_ingest_default);
24545
+ app55.route("/events", events_default);
24546
+ app55.route("/files", files_default);
24547
+ app55.route("/graph-search", graph_search_default);
24548
+ app55.route("/graph-subgraph", graph_subgraph_default);
24549
+ app55.route("/graph-delete", graph_delete_default);
24550
+ app55.route("/graph-restore", graph_restore_default);
24551
+ app55.route("/graph-labels-in-graph", graph_labels_in_graph_default);
24552
+ app55.route("/graph-default-view", graph_default_view_default);
24553
+ app55.route("/sidebar-artefacts", sidebar_artefacts_default);
24554
+ app55.route("/sidebar-sessions", sidebar_sessions_default);
24555
+ app55.route("/session-delete", session_delete_default);
24556
+ app55.route("/session-stop", session_stop_default);
24557
+ app55.route("/session-archive", session_archive_default);
24558
+ app55.route("/session-rename", session_rename_default);
24559
+ app55.route("/session-usage", session_usage_default);
24560
+ app55.route("/browser", browser_default);
24561
+ app55.route("/session-rc-spawn", session_rc_spawn_default);
24562
+ app55.route("/session-reseat", session_reseat_default);
24563
+ app55.route("/system-stats", system_stats_default);
24564
+ app55.route("/health-brand", health_default2);
24565
+ app55.route("/linkedin-ingest", linkedin_ingest_default);
24566
+ app55.route("/post-turn-context", post_turn_context_default);
24567
+ app55.route("/public-session-context", public_session_context_default);
24568
+ app55.route("/public-session-exit", public_session_exit_default);
24569
+ app55.route("/access-session-evict", access_session_evict_default);
24570
+ app55.route("/enrol-person", enrol_person_default);
24571
+ app55.route("/calendar", calendar_default);
24572
+ app55.route("/routines", routines_default);
24573
+ app55.route("/skills", skills_default);
24574
+ app55.route("/tasks-list", tasks_list_default);
24575
+ app55.route("/task-timer-start", task_timer_start_default);
24576
+ app55.route("/task-timer-stop", task_timer_stop_default);
24577
+ app55.route("/task-complete", task_complete_default);
24578
+ app55.route("/task-time-adjust", task_time_adjust_default);
24579
+ app55.route("/activity", activity_default);
24580
+ var admin_default = app55;
24265
24581
 
24266
24582
  // server/routes/access/verify-token.ts
24267
24583
  var TAG45 = "[access-verify]";
24268
24584
  var MINT_TAG = "[access-session-mint]";
24269
24585
  var COOKIE_NAME = "__access_session";
24270
- var app55 = new Hono();
24271
- app55.post("/", async (c) => {
24586
+ var app56 = new Hono();
24587
+ app56.post("/", async (c) => {
24272
24588
  const ip = c.var.clientIp || "unknown";
24273
24589
  let body;
24274
24590
  try {
@@ -24350,13 +24666,13 @@ app55.post("/", async (c) => {
24350
24666
  displayName: grant.displayName
24351
24667
  });
24352
24668
  });
24353
- var verify_token_default = app55;
24669
+ var verify_token_default = app56;
24354
24670
 
24355
24671
  // app/lib/access-email.ts
24356
24672
  import { spawn as spawn2 } from "child_process";
24357
- import { resolve as resolve31 } from "path";
24358
- var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve31(process.cwd(), "..");
24359
- var SEND_SCRIPT = resolve31(
24673
+ import { resolve as resolve32 } from "path";
24674
+ var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve32(process.cwd(), "..");
24675
+ var SEND_SCRIPT = resolve32(
24360
24676
  PLATFORM_ROOT7,
24361
24677
  "plugins",
24362
24678
  "email",
@@ -24413,9 +24729,9 @@ async function sendMagicLinkEmail(payload) {
24413
24729
 
24414
24730
  // server/routes/access/request-magic-link.ts
24415
24731
  var TAG46 = "[access-request-link]";
24416
- var app56 = new Hono();
24732
+ var app57 = new Hono();
24417
24733
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
24418
- app56.post("/", async (c) => {
24734
+ app57.post("/", async (c) => {
24419
24735
  let body;
24420
24736
  try {
24421
24737
  body = await c.req.json();
@@ -24489,17 +24805,17 @@ app56.post("/", async (c) => {
24489
24805
  );
24490
24806
  return c.json({ message: VISITOR_MESSAGE }, 200);
24491
24807
  });
24492
- var request_magic_link_default = app56;
24808
+ var request_magic_link_default = app57;
24493
24809
 
24494
24810
  // server/routes/access/index.ts
24495
- var app57 = new Hono();
24496
- app57.route("/verify-token", verify_token_default);
24497
- app57.route("/request-magic-link", request_magic_link_default);
24498
- var access_default = app57;
24811
+ var app58 = new Hono();
24812
+ app58.route("/verify-token", verify_token_default);
24813
+ app58.route("/request-magic-link", request_magic_link_default);
24814
+ var access_default = app58;
24499
24815
 
24500
24816
  // server/routes/sites.ts
24501
- import { existsSync as existsSync36, readFileSync as readFileSync39, realpathSync as realpathSync7, statSync as statSync14 } from "fs";
24502
- import { resolve as resolve32 } from "path";
24817
+ import { existsSync as existsSync37, readFileSync as readFileSync40, realpathSync as realpathSync7, statSync as statSync15 } from "fs";
24818
+ import { resolve as resolve33 } from "path";
24503
24819
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
24504
24820
  var MIME = {
24505
24821
  ".html": "text/html; charset=utf-8",
@@ -24530,8 +24846,8 @@ function getExt(p) {
24530
24846
  if (idx < p.lastIndexOf("/")) return "";
24531
24847
  return p.slice(idx).toLowerCase();
24532
24848
  }
24533
- var app58 = new Hono();
24534
- app58.get("/:rel{.*}", (c) => {
24849
+ var app59 = new Hono();
24850
+ app59.get("/:rel{.*}", (c) => {
24535
24851
  const reqPath = c.req.path;
24536
24852
  const rawRel = c.req.param("rel") ?? "";
24537
24853
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -24556,15 +24872,15 @@ app58.get("/:rel{.*}", (c) => {
24556
24872
  }
24557
24873
  segments.push(seg);
24558
24874
  }
24559
- const rootDir = resolve32(account.accountDir, "sites");
24560
- let filePath = segments.length === 0 ? rootDir : resolve32(rootDir, ...segments);
24875
+ const rootDir = resolve33(account.accountDir, "sites");
24876
+ let filePath = segments.length === 0 ? rootDir : resolve33(rootDir, ...segments);
24561
24877
  if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
24562
24878
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
24563
24879
  return c.text("Forbidden", 403);
24564
24880
  }
24565
24881
  let stat11;
24566
24882
  try {
24567
- stat11 = existsSync36(filePath) ? statSync14(filePath) : null;
24883
+ stat11 = existsSync37(filePath) ? statSync15(filePath) : null;
24568
24884
  } catch {
24569
24885
  stat11 = null;
24570
24886
  }
@@ -24577,13 +24893,13 @@ app58.get("/:rel{.*}", (c) => {
24577
24893
  return c.redirect(target, 301);
24578
24894
  }
24579
24895
  if (stat11?.isDirectory()) {
24580
- filePath = resolve32(filePath, "index.html");
24896
+ filePath = resolve33(filePath, "index.html");
24581
24897
  }
24582
24898
  if (!filePath.startsWith(rootDir + "/")) {
24583
24899
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
24584
24900
  return c.text("Forbidden", 403);
24585
24901
  }
24586
- if (!existsSync36(filePath)) {
24902
+ if (!existsSync37(filePath)) {
24587
24903
  console.error(`[sites] not-found path=${reqPath} status=404`);
24588
24904
  return c.text("Not found", 404);
24589
24905
  }
@@ -24602,7 +24918,7 @@ app58.get("/:rel{.*}", (c) => {
24602
24918
  }
24603
24919
  let body;
24604
24920
  try {
24605
- body = readFileSync39(realPath);
24921
+ body = readFileSync40(realPath);
24606
24922
  } catch (err) {
24607
24923
  const code = err?.code;
24608
24924
  if (code === "EISDIR") {
@@ -24634,11 +24950,11 @@ app58.get("/:rel{.*}", (c) => {
24634
24950
  "X-Content-Type-Options": "nosniff"
24635
24951
  });
24636
24952
  });
24637
- var sites_default = app58;
24953
+ var sites_default = app59;
24638
24954
 
24639
24955
  // app/lib/visitor-token.ts
24640
24956
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
24641
- import { mkdirSync as mkdirSync8, readFileSync as readFileSync40, writeFileSync as writeFileSync14 } from "fs";
24957
+ import { mkdirSync as mkdirSync8, readFileSync as readFileSync41, writeFileSync as writeFileSync14 } from "fs";
24642
24958
  import { dirname as dirname13 } from "path";
24643
24959
  var TOKEN_PREFIX = "v1.";
24644
24960
  var SECRET_BYTES = 32;
@@ -24647,7 +24963,7 @@ var cachedSecret = null;
24647
24963
  function getSecret() {
24648
24964
  if (cachedSecret) return cachedSecret;
24649
24965
  try {
24650
- const hex2 = readFileSync40(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
24966
+ const hex2 = readFileSync41(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
24651
24967
  if (hex2.length === SECRET_BYTES * 2) {
24652
24968
  cachedSecret = Buffer.from(hex2, "hex");
24653
24969
  return cachedSecret;
@@ -24661,7 +24977,7 @@ function getSecret() {
24661
24977
  console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
24662
24978
  } catch {
24663
24979
  }
24664
- const hex = readFileSync40(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
24980
+ const hex = readFileSync41(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
24665
24981
  cachedSecret = Buffer.from(hex, "hex");
24666
24982
  return cachedSecret;
24667
24983
  }
@@ -24714,7 +25030,7 @@ var VISITOR_COOKIE_NAME = "mxy_v";
24714
25030
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
24715
25031
 
24716
25032
  // app/lib/brand-config.ts
24717
- import { existsSync as existsSync37, readFileSync as readFileSync41 } from "fs";
25033
+ import { existsSync as existsSync38, readFileSync as readFileSync42 } from "fs";
24718
25034
  import { join as join43 } from "path";
24719
25035
  var cached2 = null;
24720
25036
  var cachedAttempted = false;
@@ -24724,9 +25040,9 @@ function readBrandConfig() {
24724
25040
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
24725
25041
  if (!platformRoot5) return null;
24726
25042
  const brandPath = join43(platformRoot5, "config", "brand.json");
24727
- if (!existsSync37(brandPath)) return null;
25043
+ if (!existsSync38(brandPath)) return null;
24728
25044
  try {
24729
- cached2 = JSON.parse(readFileSync41(brandPath, "utf-8"));
25045
+ cached2 = JSON.parse(readFileSync42(brandPath, "utf-8"));
24730
25046
  return cached2;
24731
25047
  } catch {
24732
25048
  return null;
@@ -24734,7 +25050,7 @@ function readBrandConfig() {
24734
25050
  }
24735
25051
 
24736
25052
  // server/routes/visitor-consent.ts
24737
- var app59 = new Hono();
25053
+ var app60 = new Hono();
24738
25054
  var CONSENT_COOKIE_NAME = "mxy_consent";
24739
25055
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
24740
25056
  var DEFAULT_CONSENT_COPY = {
@@ -24779,17 +25095,17 @@ function siteSlugFromReferer(referer) {
24779
25095
  return "";
24780
25096
  }
24781
25097
  }
24782
- app59.options("/consent", (c) => {
25098
+ app60.options("/consent", (c) => {
24783
25099
  const origin = getOrigin(c);
24784
25100
  setCorsHeaders(c, origin);
24785
25101
  return c.body(null, 204);
24786
25102
  });
24787
- app59.options("/brand-config", (c) => {
25103
+ app60.options("/brand-config", (c) => {
24788
25104
  const origin = getOrigin(c);
24789
25105
  setCorsHeaders(c, origin);
24790
25106
  return c.body(null, 204);
24791
25107
  });
24792
- app59.post("/consent", async (c) => {
25108
+ app60.post("/consent", async (c) => {
24793
25109
  const origin = getOrigin(c);
24794
25110
  setCorsHeaders(c, origin);
24795
25111
  let raw;
@@ -24829,7 +25145,7 @@ app59.post("/consent", async (c) => {
24829
25145
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
24830
25146
  return c.body(null, 204);
24831
25147
  });
24832
- app59.get("/brand-config", (c) => {
25148
+ app60.get("/brand-config", (c) => {
24833
25149
  const origin = getOrigin(c);
24834
25150
  setCorsHeaders(c, origin);
24835
25151
  const brand = readBrandConfig();
@@ -24839,7 +25155,7 @@ app59.get("/brand-config", (c) => {
24839
25155
  c.header("Cache-Control", "public, max-age=300");
24840
25156
  return c.json({ consent: { copy, palette } });
24841
25157
  });
24842
- var visitor_consent_default = app59;
25158
+ var visitor_consent_default = app60;
24843
25159
 
24844
25160
  // server/routes/listings.ts
24845
25161
  function getCookie(headerValue, name) {
@@ -24866,8 +25182,8 @@ function appendConsentParams(pageUrl, token) {
24866
25182
  }
24867
25183
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
24868
25184
  var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
24869
- var app60 = new Hono();
24870
- app60.get("/:slug/click", async (c) => {
25185
+ var app61 = new Hono();
25186
+ app61.get("/:slug/click", async (c) => {
24871
25187
  const slug = c.req.param("slug") ?? "";
24872
25188
  const rawSession = c.req.query("session") ?? "";
24873
25189
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -24931,10 +25247,10 @@ app60.get("/:slug/click", async (c) => {
24931
25247
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
24932
25248
  return c.redirect(redirectUrl, 302);
24933
25249
  });
24934
- var listings_default = app60;
25250
+ var listings_default = app61;
24935
25251
 
24936
25252
  // server/routes/visitor-event.ts
24937
- var app61 = new Hono();
25253
+ var app62 = new Hono();
24938
25254
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
24939
25255
  var buckets = /* @__PURE__ */ new Map();
24940
25256
  var RATE_LIMIT = 60;
@@ -25010,12 +25326,12 @@ function originAllowed(origin, allowlist) {
25010
25326
  return false;
25011
25327
  }
25012
25328
  }
25013
- app61.options("/event", (c) => {
25329
+ app62.options("/event", (c) => {
25014
25330
  const origin = getOrigin2(c);
25015
25331
  setCorsHeaders2(c, origin);
25016
25332
  return c.body(null, 204);
25017
25333
  });
25018
- app61.post("/event", async (c) => {
25334
+ app62.post("/event", async (c) => {
25019
25335
  const origin = getOrigin2(c);
25020
25336
  setCorsHeaders2(c, origin);
25021
25337
  const ua = c.req.header("user-agent") ?? "";
@@ -25220,17 +25536,17 @@ async function writeEvent(opts) {
25220
25536
  );
25221
25537
  }
25222
25538
  }
25223
- var visitor_event_default = app61;
25539
+ var visitor_event_default = app62;
25224
25540
 
25225
25541
  // server/routes/session.ts
25226
- import { resolve as resolve33 } from "path";
25227
- import { existsSync as existsSync38, writeFileSync as writeFileSync15, mkdirSync as mkdirSync9 } from "fs";
25542
+ import { resolve as resolve34 } from "path";
25543
+ import { existsSync as existsSync39, writeFileSync as writeFileSync15, mkdirSync as mkdirSync9 } from "fs";
25228
25544
  var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
25229
25545
  function writeBrandingCache(accountId, agentSlug, branding) {
25230
25546
  try {
25231
- const cacheDir = resolve33(MAXY_DIR, "branding-cache", accountId);
25547
+ const cacheDir = resolve34(MAXY_DIR, "branding-cache", accountId);
25232
25548
  mkdirSync9(cacheDir, { recursive: true });
25233
- writeFileSync15(resolve33(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
25549
+ writeFileSync15(resolve34(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
25234
25550
  } catch (err) {
25235
25551
  console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
25236
25552
  }
@@ -25266,8 +25582,8 @@ function withVisitorCookie(response, visitorId) {
25266
25582
  headers
25267
25583
  });
25268
25584
  }
25269
- var app62 = new Hono();
25270
- app62.post("/", async (c) => {
25585
+ var app63 = new Hono();
25586
+ app63.post("/", async (c) => {
25271
25587
  let body;
25272
25588
  try {
25273
25589
  body = await c.req.json();
@@ -25307,8 +25623,8 @@ app62.post("/", async (c) => {
25307
25623
  }
25308
25624
  let agentConfig = null;
25309
25625
  if (account) {
25310
- const agentDir = resolve33(account.accountDir, "agents", agentSlug);
25311
- if (!existsSync38(agentDir) || !existsSync38(resolve33(agentDir, "config.json"))) {
25626
+ const agentDir = resolve34(account.accountDir, "agents", agentSlug);
25627
+ if (!existsSync39(agentDir) || !existsSync39(resolve34(agentDir, "config.json"))) {
25312
25628
  return c.json({ error: "Agent not found" }, 404);
25313
25629
  }
25314
25630
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -25414,7 +25730,7 @@ app62.post("/", async (c) => {
25414
25730
  newVisitorId
25415
25731
  );
25416
25732
  });
25417
- var session_default2 = app62;
25733
+ var session_default2 = app63;
25418
25734
 
25419
25735
  // server/lib/calendar-slots.ts
25420
25736
  var WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
@@ -25497,17 +25813,17 @@ function computeOpenSlots(config, busy, fromISO, toISO) {
25497
25813
  }
25498
25814
 
25499
25815
  // server/routes/calendar-public.ts
25500
- var app63 = new Hono();
25816
+ var app64 = new Hono();
25501
25817
  function setCors(c) {
25502
25818
  c.header("Access-Control-Allow-Origin", "*");
25503
25819
  c.header("Access-Control-Allow-Methods", "GET, OPTIONS");
25504
25820
  c.header("Access-Control-Allow-Headers", "content-type");
25505
25821
  }
25506
- app63.options("/free-busy", (c) => {
25822
+ app64.options("/free-busy", (c) => {
25507
25823
  setCors(c);
25508
25824
  return c.body(null, 204);
25509
25825
  });
25510
- app63.get("/free-busy", async (c) => {
25826
+ app64.get("/free-busy", async (c) => {
25511
25827
  setCors(c);
25512
25828
  const from = c.req.query("from");
25513
25829
  const to = c.req.query("to");
@@ -25563,14 +25879,14 @@ app63.get("/free-busy", async (c) => {
25563
25879
  await session.close();
25564
25880
  }
25565
25881
  });
25566
- var calendar_public_default = app63;
25882
+ var calendar_public_default = app64;
25567
25883
 
25568
25884
  // server/routes/portal-fetch.ts
25569
25885
  import { createReadStream as createReadStream3 } from "fs";
25570
25886
  import { stat as stat8, readFile as readFile8, realpath } from "fs/promises";
25571
- import { join as join44, resolve as resolve34, sep as sep9 } from "path";
25887
+ import { join as join44, resolve as resolve35, sep as sep9 } from "path";
25572
25888
  import { Readable as Readable3 } from "stream";
25573
- var app64 = new Hono();
25889
+ var app65 = new Hono();
25574
25890
  var TAG47 = "[portal-fetch]";
25575
25891
  async function verifySignature(secret, accountId, relPath, expiresAtMs, signature, nowMs) {
25576
25892
  if (!secret || !signature) return false;
@@ -25621,7 +25937,7 @@ ${expiresAtMs}`)
25621
25937
  return diff === 0;
25622
25938
  }
25623
25939
  async function readAccountSecret(accountId) {
25624
- const path3 = resolve34(DATA_ROOT, "accounts", accountId, "secrets", "data-portal.env");
25940
+ const path3 = resolve35(DATA_ROOT, "accounts", accountId, "secrets", "data-portal.env");
25625
25941
  let text;
25626
25942
  try {
25627
25943
  text = await readFile8(path3, "utf8");
@@ -25657,7 +25973,7 @@ async function resolveFetchTarget(accountDir, relPath, ownerId) {
25657
25973
  const exposeFolders = await readExposeFolders2(accountDir);
25658
25974
  const { exposed } = resolveExposedDirs(schemaText, exposeFolders);
25659
25975
  if (exposed.length === 0 && !ownerId) return { ok: false, reason: "not-exposed" };
25660
- const lexical = resolve34(accountDir, relPath);
25976
+ const lexical = resolve35(accountDir, relPath);
25661
25977
  let root;
25662
25978
  let absolute;
25663
25979
  try {
@@ -25706,7 +26022,7 @@ async function handle(c, headOnly) {
25706
26022
  return c.json({ ok: false, error: "denied" }, 401);
25707
26023
  }
25708
26024
  const target = await resolveFetchTarget(
25709
- resolve34(DATA_ROOT, "accounts", accountId),
26025
+ resolve35(DATA_ROOT, "accounts", accountId),
25710
26026
  relPath,
25711
26027
  owner || void 0
25712
26028
  );
@@ -25733,9 +26049,9 @@ async function handle(c, headOnly) {
25733
26049
  }
25734
26050
  });
25735
26051
  }
25736
- app64.get("/fetch", (c) => handle(c, false));
25737
- app64.on("HEAD", "/fetch", (c) => handle(c, true));
25738
- var portal_fetch_default = app64;
26052
+ app65.get("/fetch", (c) => handle(c, false));
26053
+ app65.on("HEAD", "/fetch", (c) => handle(c, true));
26054
+ var portal_fetch_default = app65;
25739
26055
 
25740
26056
  // app/lib/timeentry-census.ts
25741
26057
  var TAG48 = "[timeentry-census]";
@@ -25820,7 +26136,7 @@ function startTimeEntryCensus(openSession, opts = {}) {
25820
26136
  }
25821
26137
 
25822
26138
  // app/lib/ledger-census.ts
25823
- import { readdirSync as readdirSync25, readFileSync as readFileSync42, statSync as statSync15 } from "fs";
26139
+ import { readdirSync as readdirSync26, readFileSync as readFileSync43, statSync as statSync16 } from "fs";
25824
26140
  import { join as join45 } from "path";
25825
26141
 
25826
26142
  // ../lib/ledger-core/dist/reconcile.js
@@ -25869,7 +26185,7 @@ var DAY_MS = 864e5;
25869
26185
  function countWriteRejects24h(logDir, now) {
25870
26186
  let entries;
25871
26187
  try {
25872
- entries = readdirSync25(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
26188
+ entries = readdirSync26(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
25873
26189
  } catch {
25874
26190
  return 0;
25875
26191
  }
@@ -25877,8 +26193,8 @@ function countWriteRejects24h(logDir, now) {
25877
26193
  for (const name of entries) {
25878
26194
  const path3 = join45(logDir, name);
25879
26195
  try {
25880
- if (now - statSync15(path3).mtimeMs > DAY_MS) continue;
25881
- for (const line of readFileSync42(path3, "utf8").split("\n")) {
26196
+ if (now - statSync16(path3).mtimeMs > DAY_MS) continue;
26197
+ for (const line of readFileSync43(path3, "utf8").split("\n")) {
25882
26198
  if (line.includes("[graph-write] reject")) total += 1;
25883
26199
  }
25884
26200
  } catch {
@@ -26147,7 +26463,7 @@ function startGraphHealthTimer() {
26147
26463
 
26148
26464
  // app/lib/file-watcher.ts
26149
26465
  import * as fsp2 from "fs/promises";
26150
- import { resolve as resolve35, sep as sep10 } from "path";
26466
+ import { resolve as resolve36, sep as sep10 } from "path";
26151
26467
  var ACCOUNT_UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
26152
26468
  var DEFAULT_COALESCE_MS = 500;
26153
26469
  var ROOTS = ["accounts"];
@@ -26166,7 +26482,7 @@ async function startFileWatcher(opts = {}) {
26166
26482
  const dropFn = opts.drop ?? dropFileIndex;
26167
26483
  for (const r of ROOTS) {
26168
26484
  try {
26169
- await fsp2.mkdir(resolve35(dataRoot, r), { recursive: true });
26485
+ await fsp2.mkdir(resolve36(dataRoot, r), { recursive: true });
26170
26486
  } catch (err) {
26171
26487
  console.error(
26172
26488
  `[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
@@ -26187,7 +26503,7 @@ async function startFileWatcher(opts = {}) {
26187
26503
  timers.set(relativePath, t);
26188
26504
  }
26189
26505
  async function runHook(relativePath, accountId) {
26190
- const absolute = resolve35(dataRoot, relativePath);
26506
+ const absolute = resolve36(dataRoot, relativePath);
26191
26507
  let exists = false;
26192
26508
  try {
26193
26509
  const st = await fsp2.stat(absolute);
@@ -26211,7 +26527,7 @@ async function startFileWatcher(opts = {}) {
26211
26527
  }
26212
26528
  }
26213
26529
  async function watchRoot(rootName) {
26214
- const absRoot = resolve35(dataRoot, rootName);
26530
+ const absRoot = resolve36(dataRoot, rootName);
26215
26531
  try {
26216
26532
  const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
26217
26533
  for await (const event of iter) {
@@ -26250,7 +26566,7 @@ async function startFileWatcher(opts = {}) {
26250
26566
 
26251
26567
  // app/lib/migrate-uploads.ts
26252
26568
  import { mkdir as mkdir6, readdir as readdir6, rename as rename3, rm as rm3 } from "fs/promises";
26253
- import { dirname as dirname14, relative as relative7, resolve as resolve36 } from "path";
26569
+ import { dirname as dirname14, relative as relative7, resolve as resolve37 } from "path";
26254
26570
  var ACCOUNT_UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
26255
26571
  async function walkFiles(dir) {
26256
26572
  const out = [];
@@ -26261,7 +26577,7 @@ async function walkFiles(dir) {
26261
26577
  return out;
26262
26578
  }
26263
26579
  for (const e of entries) {
26264
- const abs = resolve36(dir, e.name);
26580
+ const abs = resolve37(dir, e.name);
26265
26581
  if (e.isDirectory()) {
26266
26582
  out.push(...await walkFiles(abs));
26267
26583
  } else if (e.isFile()) {
@@ -26281,7 +26597,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
26281
26597
  let moved = 0;
26282
26598
  for (const oldAbs of files) {
26283
26599
  const suffix = relative7(srcDir, oldAbs);
26284
- const newAbs = resolve36(destDir, suffix);
26600
+ const newAbs = resolve37(destDir, suffix);
26285
26601
  await mkdir6(dirname14(newAbs), { recursive: true });
26286
26602
  await rename3(oldAbs, newAbs);
26287
26603
  moved++;
@@ -26308,7 +26624,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
26308
26624
  }
26309
26625
  async function migrateUploads(opts = {}) {
26310
26626
  const dataRoot = opts.dataRoot ?? DATA_ROOT;
26311
- const oldRoot = resolve36(dataRoot, "uploads");
26627
+ const oldRoot = resolve37(dataRoot, "uploads");
26312
26628
  let topEntries;
26313
26629
  try {
26314
26630
  topEntries = await readdir6(oldRoot, { withFileTypes: true });
@@ -26329,8 +26645,8 @@ async function migrateUploads(opts = {}) {
26329
26645
  const name = entry.name;
26330
26646
  if (ACCOUNT_UUID_RE5.test(name)) {
26331
26647
  moved += await relocateTree(
26332
- resolve36(oldRoot, name),
26333
- resolve36(dataRoot, "accounts", name, "uploads"),
26648
+ resolve37(oldRoot, name),
26649
+ resolve37(dataRoot, "accounts", name, "uploads"),
26334
26650
  dataRoot,
26335
26651
  name,
26336
26652
  session
@@ -26342,8 +26658,8 @@ async function migrateUploads(opts = {}) {
26342
26658
  continue;
26343
26659
  }
26344
26660
  moved += await relocateTree(
26345
- resolve36(oldRoot, "public"),
26346
- resolve36(dataRoot, "accounts", installAccountId, "uploads", "public"),
26661
+ resolve37(oldRoot, "public"),
26662
+ resolve37(dataRoot, "accounts", installAccountId, "uploads", "public"),
26347
26663
  dataRoot,
26348
26664
  null,
26349
26665
  // public uploads carry no graph nodes
@@ -26373,7 +26689,7 @@ async function migrateUploads(opts = {}) {
26373
26689
 
26374
26690
  // app/lib/migrate-admin-webchat-sidecars.ts
26375
26691
  import { readdir as readdir7, readFile as readFile9, rename as rename4, writeFile as writeFile5, unlink as unlink4 } from "fs/promises";
26376
- import { existsSync as existsSync39 } from "fs";
26692
+ import { existsSync as existsSync40 } from "fs";
26377
26693
  import { join as join46 } from "path";
26378
26694
  var ADMIN_ROLE2 = "admin";
26379
26695
  var WEBCHAT_CHANNEL2 = "webchat";
@@ -26403,7 +26719,7 @@ async function writeRaw(path3, obj) {
26403
26719
  await rename4(tmp, path3);
26404
26720
  } catch (err) {
26405
26721
  try {
26406
- if (existsSync39(tmp)) await unlink4(tmp);
26722
+ if (existsSync40(tmp)) await unlink4(tmp);
26407
26723
  } catch {
26408
26724
  }
26409
26725
  throw err;
@@ -26792,8 +27108,8 @@ var streamSSE = (c, cb, onError) => {
26792
27108
 
26793
27109
  // app/lib/whatsapp/gateway/routes.ts
26794
27110
  function createWaChannelRoutes(deps) {
26795
- const app66 = new Hono();
26796
- app66.get("/wa-channel/inbound", (c) => {
27111
+ const app67 = new Hono();
27112
+ app67.get("/wa-channel/inbound", (c) => {
26797
27113
  const senderId = c.req.query("senderId");
26798
27114
  if (!senderId) return c.json({ error: "senderId required" }, 400);
26799
27115
  return streamSSE(c, async (stream2) => {
@@ -26811,7 +27127,7 @@ function createWaChannelRoutes(deps) {
26811
27127
  }
26812
27128
  });
26813
27129
  });
26814
- app66.post("/wa-channel/reply", async (c) => {
27130
+ app67.post("/wa-channel/reply", async (c) => {
26815
27131
  const body = await c.req.json().catch(() => null);
26816
27132
  const senderId = body?.senderId;
26817
27133
  const text = body?.text;
@@ -26832,7 +27148,7 @@ function createWaChannelRoutes(deps) {
26832
27148
  console.error(`[whatsapp-native] op=reply-dispatch senderId=${senderId} bytes=${bytes}`);
26833
27149
  return c.json({ ok: true });
26834
27150
  });
26835
- app66.post("/wa-channel/reply-document", async (c) => {
27151
+ app67.post("/wa-channel/reply-document", async (c) => {
26836
27152
  const body = await c.req.json().catch(() => null);
26837
27153
  const senderId = body?.senderId;
26838
27154
  const files = body?.files;
@@ -26871,7 +27187,7 @@ function createWaChannelRoutes(deps) {
26871
27187
  }
26872
27188
  return c.json({ ok: true, results });
26873
27189
  });
26874
- app66.post("/wa-channel/ready", async (c) => {
27190
+ app67.post("/wa-channel/ready", async (c) => {
26875
27191
  const body = await c.req.json().catch(() => null);
26876
27192
  const senderId = body?.senderId;
26877
27193
  if (typeof senderId !== "string") {
@@ -26880,7 +27196,7 @@ function createWaChannelRoutes(deps) {
26880
27196
  deps.onReady?.(senderId);
26881
27197
  return c.json({ ok: true });
26882
27198
  });
26883
- app66.post("/wa-channel/received", async (c) => {
27199
+ app67.post("/wa-channel/received", async (c) => {
26884
27200
  const body = await c.req.json().catch(() => null);
26885
27201
  const senderId = body?.senderId;
26886
27202
  const waMessageId = body?.waMessageId;
@@ -26890,7 +27206,7 @@ function createWaChannelRoutes(deps) {
26890
27206
  deps.onReceived?.(senderId, waMessageId);
26891
27207
  return c.json({ ok: true });
26892
27208
  });
26893
- app66.post("/wa-channel/turn-end", async (c) => {
27209
+ app67.post("/wa-channel/turn-end", async (c) => {
26894
27210
  const body = await c.req.json().catch(() => null);
26895
27211
  const senderId = body?.senderId;
26896
27212
  const sessionId = body?.sessionId;
@@ -26901,7 +27217,7 @@ function createWaChannelRoutes(deps) {
26901
27217
  const interactive = body?.interactive === true;
26902
27218
  const finalText = typeof body?.finalText === "string" ? body.finalText : "";
26903
27219
  const sid = sessionId.slice(0, 8);
26904
- const deliver = interactive && finalText.trim().length > 0;
27220
+ const deliver = interactive && !replied && finalText.trim().length > 0;
26905
27221
  if (deliver) {
26906
27222
  const bytes = Buffer.byteLength(finalText, "utf8");
26907
27223
  try {
@@ -26923,7 +27239,7 @@ function createWaChannelRoutes(deps) {
26923
27239
  console.error(`[whatsapp-native] op=turn-end sessionId=${sid} replied=no delivered=none`);
26924
27240
  return c.json({ ok: true, delivered: "none" });
26925
27241
  });
26926
- return app66;
27242
+ return app67;
26927
27243
  }
26928
27244
 
26929
27245
  // app/lib/whatsapp/gateway/wa-gateway.ts
@@ -27338,8 +27654,8 @@ var InboundHub2 = class {
27338
27654
 
27339
27655
  // app/lib/webchat/gateway/routes.ts
27340
27656
  function createWebchatChannelRoutes(deps) {
27341
- const app66 = new Hono();
27342
- app66.get("/webchat-channel/inbound", (c) => {
27657
+ const app67 = new Hono();
27658
+ app67.get("/webchat-channel/inbound", (c) => {
27343
27659
  const key = c.req.query("key");
27344
27660
  if (!key) return c.json({ error: "key required" }, 400);
27345
27661
  return streamSSE(c, async (stream2) => {
@@ -27357,7 +27673,7 @@ function createWebchatChannelRoutes(deps) {
27357
27673
  }
27358
27674
  });
27359
27675
  });
27360
- app66.post("/webchat-channel/reply", async (c) => {
27676
+ app67.post("/webchat-channel/reply", async (c) => {
27361
27677
  const body = await c.req.json().catch(() => null);
27362
27678
  const key = body?.key;
27363
27679
  const text = body?.text;
@@ -27367,7 +27683,7 @@ function createWebchatChannelRoutes(deps) {
27367
27683
  deps.onReply?.(key, text);
27368
27684
  return c.json({ ok: true });
27369
27685
  });
27370
- app66.post("/webchat-channel/connector-auth", async (c) => {
27686
+ app67.post("/webchat-channel/connector-auth", async (c) => {
27371
27687
  const body = await c.req.json().catch(() => null);
27372
27688
  const key = body?.key;
27373
27689
  const sessionId = body?.sessionId;
@@ -27380,7 +27696,7 @@ function createWebchatChannelRoutes(deps) {
27380
27696
  const result = await deps.onConnectorAuth({ key, sessionId, name, completed });
27381
27697
  return c.json(result);
27382
27698
  });
27383
- app66.post("/webchat-channel/ready", async (c) => {
27699
+ app67.post("/webchat-channel/ready", async (c) => {
27384
27700
  const body = await c.req.json().catch(() => null);
27385
27701
  const key = body?.key;
27386
27702
  if (typeof key !== "string") {
@@ -27389,7 +27705,7 @@ function createWebchatChannelRoutes(deps) {
27389
27705
  deps.onReady?.(key);
27390
27706
  return c.json({ ok: true });
27391
27707
  });
27392
- app66.post("/webchat-channel/permission-request", async (c) => {
27708
+ app67.post("/webchat-channel/permission-request", async (c) => {
27393
27709
  const body = await c.req.json().catch(() => null);
27394
27710
  const key = body?.key;
27395
27711
  const requestId = body?.request_id;
@@ -27403,7 +27719,7 @@ function createWebchatChannelRoutes(deps) {
27403
27719
  const verdict = await deps.awaitPermissionVerdict({ key, requestId, toolName, description, inputPreview });
27404
27720
  return c.json(verdict);
27405
27721
  });
27406
- app66.post("/webchat-channel/received", async (c) => {
27722
+ app67.post("/webchat-channel/received", async (c) => {
27407
27723
  const body = await c.req.json().catch(() => null);
27408
27724
  const key = body?.key;
27409
27725
  const messageId = body?.messageId;
@@ -27413,7 +27729,7 @@ function createWebchatChannelRoutes(deps) {
27413
27729
  deps.onReceived?.(key, messageId);
27414
27730
  return c.json({ ok: true });
27415
27731
  });
27416
- app66.post("/webchat-channel/turn-end", async (c) => {
27732
+ app67.post("/webchat-channel/turn-end", async (c) => {
27417
27733
  const body = await c.req.json().catch(() => null);
27418
27734
  const key = body?.key;
27419
27735
  const sessionId = body?.sessionId;
@@ -27421,22 +27737,13 @@ function createWebchatChannelRoutes(deps) {
27421
27737
  if (typeof key !== "string" || typeof sessionId !== "string" || typeof replied !== "boolean") {
27422
27738
  return c.json({ error: "key, sessionId and replied required" }, 400);
27423
27739
  }
27424
- const interactive = body?.interactive === true;
27425
27740
  const finalBytes = typeof body?.finalBytes === "number" && Number.isFinite(body.finalBytes) ? body.finalBytes : 0;
27426
27741
  const k = key.slice(0, 8);
27427
27742
  const sid = sessionId.slice(0, 8);
27428
- if (replied) {
27429
- console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=yes delivered=reply bytes=${finalBytes}`);
27430
- return c.json({ ok: true, delivered: "reply" });
27431
- }
27432
- if (interactive && finalBytes > 0) {
27433
- console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=no delivered=fallback bytes=${finalBytes}`);
27434
- return c.json({ ok: true, delivered: "fallback" });
27435
- }
27436
- console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=no delivered=none`);
27437
- return c.json({ ok: true, delivered: "none" });
27743
+ console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=${replied ? "yes" : "no"} trailing=${finalBytes}`);
27744
+ return c.json({ ok: true });
27438
27745
  });
27439
- return app66;
27746
+ return app67;
27440
27747
  }
27441
27748
 
27442
27749
  // app/lib/webchat/gateway/webchat-gateway.ts
@@ -27494,16 +27801,16 @@ var WebchatGateway = class _WebchatGateway {
27494
27801
  * The public /api/chat route awaits this to return the reply on the same SSE
27495
27802
  * response, preserving the pre-756 POST→single-blob browser contract. */
27496
27803
  awaitReply(key, timeoutMs) {
27497
- return new Promise((resolve42) => {
27804
+ return new Promise((resolve43) => {
27498
27805
  const timer = setTimeout(() => {
27499
27806
  this.replyAwaiters.delete(key);
27500
- resolve42({ timeout: true });
27807
+ resolve43({ timeout: true });
27501
27808
  }, timeoutMs);
27502
27809
  if (timer.unref) timer.unref();
27503
27810
  this.replyAwaiters.set(key, (r) => {
27504
27811
  clearTimeout(timer);
27505
27812
  this.replyAwaiters.delete(key);
27506
- resolve42(r);
27813
+ resolve43(r);
27507
27814
  });
27508
27815
  });
27509
27816
  }
@@ -27514,11 +27821,11 @@ var WebchatGateway = class _WebchatGateway {
27514
27821
  * terminal dialog stays answerable). */
27515
27822
  awaitPermissionVerdict(p, timeoutMs) {
27516
27823
  const k = _WebchatGateway.promptKey(p.key, p.requestId);
27517
- return new Promise((resolve42) => {
27824
+ return new Promise((resolve43) => {
27518
27825
  this.pendingPrompts.get(k)?.resolve({ timeout: true });
27519
27826
  const timer = setTimeout(() => {
27520
27827
  this.pendingPrompts.delete(k);
27521
- resolve42({ timeout: true });
27828
+ resolve43({ timeout: true });
27522
27829
  }, timeoutMs);
27523
27830
  if (timer.unref) timer.unref();
27524
27831
  this.pendingPrompts.set(k, {
@@ -27527,7 +27834,7 @@ var WebchatGateway = class _WebchatGateway {
27527
27834
  resolve: (r) => {
27528
27835
  clearTimeout(timer);
27529
27836
  this.pendingPrompts.delete(k);
27530
- resolve42(r);
27837
+ resolve43(r);
27531
27838
  }
27532
27839
  });
27533
27840
  console.error(`[webchat:perm] op=open key=${keyDisplay(p.key)} id=${p.requestId} tool=${p.toolName}`);
@@ -28092,7 +28399,7 @@ async function fanOut(subscribers, text, onError, tag) {
28092
28399
 
28093
28400
  // app/lib/webchat/file-delivery.ts
28094
28401
  import { realpathSync as realpathSync8 } from "fs";
28095
- import { resolve as resolve37 } from "path";
28402
+ import { resolve as resolve38 } from "path";
28096
28403
 
28097
28404
  // app/lib/channel-pty-bridge/file-delivery.ts
28098
28405
  var SEND_USER_FILE = "SendUserFile";
@@ -28193,7 +28500,7 @@ function makeWebchatSendFile(entry) {
28193
28500
  console.error(`${TAG51} file-delivery reject reason=no-account sender=${entry.senderId}`);
28194
28501
  return { ok: false, error: "no-account" };
28195
28502
  }
28196
- const accountDir = resolve37(platformRoot2(), "..", "data/accounts", entry.accountId);
28503
+ const accountDir = resolve38(platformRoot2(), "..", "data/accounts", entry.accountId);
28197
28504
  try {
28198
28505
  const resolved = realpathSync8(filePath);
28199
28506
  const accountResolved = realpathSync8(accountDir);
@@ -28520,8 +28827,8 @@ var InboundHub3 = class {
28520
28827
 
28521
28828
  // app/lib/telegram/gateway/routes.ts
28522
28829
  function createTelegramChannelRoutes(deps) {
28523
- const app66 = new Hono();
28524
- app66.get("/tg-channel/inbound", (c) => {
28830
+ const app67 = new Hono();
28831
+ app67.get("/tg-channel/inbound", (c) => {
28525
28832
  const key = c.req.query("key");
28526
28833
  if (!key) return c.json({ error: "key required" }, 400);
28527
28834
  return streamSSE(c, async (stream2) => {
@@ -28539,7 +28846,7 @@ function createTelegramChannelRoutes(deps) {
28539
28846
  }
28540
28847
  });
28541
28848
  });
28542
- app66.post("/tg-channel/reply", async (c) => {
28849
+ app67.post("/tg-channel/reply", async (c) => {
28543
28850
  const body = await c.req.json().catch(() => null);
28544
28851
  const key = body?.key;
28545
28852
  const text = body?.text;
@@ -28555,7 +28862,7 @@ function createTelegramChannelRoutes(deps) {
28555
28862
  console.error(`[telegram-native] op=reply key=${key} bytes=${Buffer.byteLength(text, "utf8")}`);
28556
28863
  return c.json({ ok: true });
28557
28864
  });
28558
- app66.post("/tg-channel/ready", async (c) => {
28865
+ app67.post("/tg-channel/ready", async (c) => {
28559
28866
  const body = await c.req.json().catch(() => null);
28560
28867
  const key = body?.key;
28561
28868
  if (typeof key !== "string") {
@@ -28564,7 +28871,7 @@ function createTelegramChannelRoutes(deps) {
28564
28871
  deps.onReady?.(key);
28565
28872
  return c.json({ ok: true });
28566
28873
  });
28567
- app66.post("/tg-channel/received", async (c) => {
28874
+ app67.post("/tg-channel/received", async (c) => {
28568
28875
  const body = await c.req.json().catch(() => null);
28569
28876
  const key = body?.key;
28570
28877
  const messageId = body?.messageId;
@@ -28574,7 +28881,7 @@ function createTelegramChannelRoutes(deps) {
28574
28881
  deps.onReceived?.(key, messageId);
28575
28882
  return c.json({ ok: true });
28576
28883
  });
28577
- app66.post("/tg-channel/turn-end", async (c) => {
28884
+ app67.post("/tg-channel/turn-end", async (c) => {
28578
28885
  const body = await c.req.json().catch(() => null);
28579
28886
  const key = body?.key;
28580
28887
  const sessionId = body?.sessionId;
@@ -28585,7 +28892,7 @@ function createTelegramChannelRoutes(deps) {
28585
28892
  const interactive = body?.interactive === true;
28586
28893
  const finalText = typeof body?.finalText === "string" ? body.finalText : "";
28587
28894
  const sid = sessionId.slice(0, 8);
28588
- const deliver = interactive && finalText.trim().length > 0;
28895
+ const deliver = interactive && !replied && finalText.trim().length > 0;
28589
28896
  if (deliver) {
28590
28897
  const bytes = Buffer.byteLength(finalText, "utf8");
28591
28898
  try {
@@ -28607,7 +28914,7 @@ function createTelegramChannelRoutes(deps) {
28607
28914
  console.error(`[telegram-native] op=turn-end key=${key} sessionId=${sid} replied=no delivered=none`);
28608
28915
  return c.json({ ok: true, delivered: "none" });
28609
28916
  });
28610
- return app66;
28917
+ return app67;
28611
28918
  }
28612
28919
 
28613
28920
  // app/lib/telegram/gateway/telegram-gateway.ts
@@ -28757,7 +29064,7 @@ function buildTelegramSpawnRequest(input) {
28757
29064
  // app/lib/telegram/outbound/send-document.ts
28758
29065
  import { realpathSync as realpathSync9 } from "fs";
28759
29066
  import { readFile as readFile10, stat as stat10 } from "fs/promises";
28760
- import { resolve as resolve38, basename as basename12 } from "path";
29067
+ import { resolve as resolve39, basename as basename12 } from "path";
28761
29068
  var TAG53 = "[telegram:outbound]";
28762
29069
  var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
28763
29070
  async function sendTelegramDocument(input) {
@@ -28768,7 +29075,7 @@ async function sendTelegramDocument(input) {
28768
29075
  if (!maxyAccountId || !platformRoot5) {
28769
29076
  return { ok: false, status: 400, error: "Cannot validate file path: missing account or platform context" };
28770
29077
  }
28771
- const accountDir = resolve38(platformRoot5, "..", "data/accounts", maxyAccountId);
29078
+ const accountDir = resolve39(platformRoot5, "..", "data/accounts", maxyAccountId);
28772
29079
  let accountResolved;
28773
29080
  try {
28774
29081
  accountResolved = realpathSync9(accountDir);
@@ -29160,14 +29467,14 @@ function warnOnChannelAdminBindingDrift() {
29160
29467
  }
29161
29468
 
29162
29469
  // server/lib/booking-site-accounts.ts
29163
- import { existsSync as existsSync40, readFileSync as readFileSync43 } from "fs";
29164
- import { resolve as resolve39 } from "path";
29470
+ import { existsSync as existsSync41, readFileSync as readFileSync44 } from "fs";
29471
+ import { resolve as resolve40 } from "path";
29165
29472
  function listBookingSiteAccounts(accounts) {
29166
29473
  return accounts.filter((a) => {
29167
- const availPath = resolve39(a.accountDir, "calendar-availability.json");
29168
- if (!existsSync40(availPath)) return false;
29474
+ const availPath = resolve40(a.accountDir, "calendar-availability.json");
29475
+ if (!existsSync41(availPath)) return false;
29169
29476
  try {
29170
- const cfg = JSON.parse(readFileSync43(availPath, "utf-8"));
29477
+ const cfg = JSON.parse(readFileSync44(availPath, "utf-8"));
29171
29478
  return typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
29172
29479
  } catch {
29173
29480
  return false;
@@ -29205,8 +29512,8 @@ function broadcastAdminShutdown(reason) {
29205
29512
 
29206
29513
  // ../lib/entitlement/src/index.ts
29207
29514
  import { createPublicKey, createHash as createHash6, verify as cryptoVerify } from "crypto";
29208
- import { existsSync as existsSync41, readFileSync as readFileSync44, statSync as statSync16 } from "fs";
29209
- import { resolve as resolve40 } from "path";
29515
+ import { existsSync as existsSync42, readFileSync as readFileSync45, statSync as statSync17 } from "fs";
29516
+ import { resolve as resolve41 } from "path";
29210
29517
 
29211
29518
  // ../lib/entitlement/src/canonicalize.ts
29212
29519
  function canonicalize(value) {
@@ -29241,7 +29548,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
29241
29548
  var GRACE_DAYS = 7;
29242
29549
  var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
29243
29550
  function pubkeyPath(brand) {
29244
- return resolve40(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
29551
+ return resolve41(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
29245
29552
  }
29246
29553
  var memo = null;
29247
29554
  function memoKey(mtimeMs, account) {
@@ -29253,11 +29560,11 @@ function resolveEntitlement(brand, account) {
29253
29560
  if (brand.commercialMode !== true) {
29254
29561
  return logResolved(implicitTrust(account), null);
29255
29562
  }
29256
- const entitlementPath = resolve40(brand.configDir, "entitlement.json");
29257
- if (!existsSync41(entitlementPath)) {
29563
+ const entitlementPath = resolve41(brand.configDir, "entitlement.json");
29564
+ if (!existsSync42(entitlementPath)) {
29258
29565
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
29259
29566
  }
29260
- const stat11 = statSync16(entitlementPath);
29567
+ const stat11 = statSync17(entitlementPath);
29261
29568
  const key = memoKey(stat11.mtimeMs, account);
29262
29569
  if (memo && memo.key === key) {
29263
29570
  return memo.result;
@@ -29269,7 +29576,7 @@ function resolveEntitlement(brand, account) {
29269
29576
  function verifyAndResolve(brand, entitlementPath, account) {
29270
29577
  let pubkeyPem;
29271
29578
  try {
29272
- pubkeyPem = readFileSync44(pubkeyPath(brand), "utf-8");
29579
+ pubkeyPem = readFileSync45(pubkeyPath(brand), "utf-8");
29273
29580
  } catch (err) {
29274
29581
  return logResolved(anonymousFallback("pubkey-missing"), {
29275
29582
  reason: "pubkey-missing"
@@ -29283,7 +29590,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
29283
29590
  }
29284
29591
  let envelope;
29285
29592
  try {
29286
- envelope = JSON.parse(readFileSync44(entitlementPath, "utf-8"));
29593
+ envelope = JSON.parse(readFileSync45(entitlementPath, "utf-8"));
29287
29594
  } catch {
29288
29595
  return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
29289
29596
  }
@@ -29447,12 +29754,12 @@ installMediaDownloadGuard();
29447
29754
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
29448
29755
  var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join47(PLATFORM_ROOT8, "config", "brand.json") : "";
29449
29756
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
29450
- if (BRAND_JSON_PATH && !existsSync42(BRAND_JSON_PATH)) {
29757
+ if (BRAND_JSON_PATH && !existsSync43(BRAND_JSON_PATH)) {
29451
29758
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
29452
29759
  }
29453
- if (BRAND_JSON_PATH && existsSync42(BRAND_JSON_PATH)) {
29760
+ if (BRAND_JSON_PATH && existsSync43(BRAND_JSON_PATH)) {
29454
29761
  try {
29455
- const parsed = JSON.parse(readFileSync45(BRAND_JSON_PATH, "utf-8"));
29762
+ const parsed = JSON.parse(readFileSync46(BRAND_JSON_PATH, "utf-8"));
29456
29763
  BRAND = { ...BRAND, ...parsed };
29457
29764
  } catch (err) {
29458
29765
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -29487,8 +29794,8 @@ var brandLoginOpts = {
29487
29794
  var ALIAS_DOMAINS_PATH = join47(homedir4(), BRAND.configDir, "alias-domains.json");
29488
29795
  function loadAliasDomains() {
29489
29796
  try {
29490
- if (!existsSync42(ALIAS_DOMAINS_PATH)) return null;
29491
- const parsed = JSON.parse(readFileSync45(ALIAS_DOMAINS_PATH, "utf-8"));
29797
+ if (!existsSync43(ALIAS_DOMAINS_PATH)) return null;
29798
+ const parsed = JSON.parse(readFileSync46(ALIAS_DOMAINS_PATH, "utf-8"));
29492
29799
  if (!Array.isArray(parsed)) {
29493
29800
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
29494
29801
  return null;
@@ -29512,7 +29819,7 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
29512
29819
  function isPublicHost(host) {
29513
29820
  return host.startsWith("public.") || aliasDomains.has(host);
29514
29821
  }
29515
- var app65 = new Hono();
29822
+ var app66 = new Hono();
29516
29823
  function resolveChannelOverride(accountId, channel, senderId) {
29517
29824
  try {
29518
29825
  const dir = listValidAccounts().find((a) => a.accountId === accountId)?.accountDir;
@@ -29561,7 +29868,7 @@ var waGateway = new WaGateway({
29561
29868
  fetchStandingRules: fetchAccountStandingRules,
29562
29869
  resolveSessionOverride: (accountId, senderId) => resolveChannelOverride(accountId, "whatsapp", senderId),
29563
29870
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
29564
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve41(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
29871
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve42(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
29565
29872
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
29566
29873
  // path-validation scope) is the sender's effective SESSION account, resolved
29567
29874
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -29576,7 +29883,7 @@ var waGateway = new WaGateway({
29576
29883
  caption,
29577
29884
  accountId,
29578
29885
  maxyAccountId,
29579
- platformRoot: resolve41(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, ".."))
29886
+ platformRoot: resolve42(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, ".."))
29580
29887
  });
29581
29888
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
29582
29889
  },
@@ -29688,7 +29995,7 @@ var waGateway = new WaGateway({
29688
29995
  nativeFileFollowers.set(senderId, ac);
29689
29996
  }
29690
29997
  });
29691
- app65.route("/", waGateway.routes());
29998
+ app66.route("/", waGateway.routes());
29692
29999
  waGateway.startSweeper();
29693
30000
  function runDuplicateSenderAudit() {
29694
30001
  try {
@@ -29811,7 +30118,7 @@ var webchatGateway = new WebchatGateway({
29811
30118
  firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
29812
30119
  });
29813
30120
  setWebchatGateway(webchatGateway);
29814
- app65.route("/", webchatGateway.routes());
30121
+ app66.route("/", webchatGateway.routes());
29815
30122
  webchatGateway.startSweeper();
29816
30123
  webchatGateway.startPublicReaper();
29817
30124
  var telegramFileFollowers = /* @__PURE__ */ new Map();
@@ -29855,7 +30162,7 @@ var telegramGateway = new TelegramGateway({
29855
30162
  }
29856
30163
  });
29857
30164
  setTelegramGateway(telegramGateway);
29858
- app65.route("/", telegramGateway.routes());
30165
+ app66.route("/", telegramGateway.routes());
29859
30166
  telegramGateway.startSweeper();
29860
30167
  var chatRoutes = createChatRoutes({
29861
30168
  handleInbound: (input) => webchatGateway.handleInbound(input),
@@ -29889,19 +30196,19 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
29889
30196
  return managed.account;
29890
30197
  }
29891
30198
  });
29892
- app65.route("/api/channel/schedule-inject", scheduleInjectRoutes);
29893
- app65.use("*", clientIpMiddleware);
30199
+ app66.route("/api/channel/schedule-inject", scheduleInjectRoutes);
30200
+ app66.use("*", clientIpMiddleware);
29894
30201
  function allowsSameOriginFraming(path3) {
29895
30202
  return path3 === "/vnc-viewer.html" || path3.startsWith("/api/admin/attachment/") || path3.startsWith("/api/public-reader/attachment/") || path3 === "/api/admin/files/download";
29896
30203
  }
29897
- app65.use("*", async (c, next) => {
30204
+ app66.use("*", async (c, next) => {
29898
30205
  await next();
29899
30206
  c.header("X-Content-Type-Options", "nosniff");
29900
30207
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
29901
30208
  c.header("X-Frame-Options", allowsSameOriginFraming(c.req.path) ? "SAMEORIGIN" : "DENY");
29902
30209
  });
29903
30210
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
29904
- app65.use("*", async (c, next) => {
30211
+ app66.use("*", async (c, next) => {
29905
30212
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
29906
30213
  await next();
29907
30214
  return;
@@ -29919,7 +30226,7 @@ app65.use("*", async (c, next) => {
29919
30226
  });
29920
30227
  }
29921
30228
  });
29922
- app65.use("*", async (c, next) => {
30229
+ app66.use("*", async (c, next) => {
29923
30230
  const host = (c.req.header("host") ?? "").split(":")[0];
29924
30231
  if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
29925
30232
  await next();
@@ -29957,7 +30264,7 @@ function resolveRemoteAuthOpts(c) {
29957
30264
  return { ...brandLoginOpts, origin };
29958
30265
  }
29959
30266
  var MAX_LOGIN_BODY = 8 * 1024;
29960
- app65.post("/__remote-auth/login", async (c) => {
30267
+ app66.post("/__remote-auth/login", async (c) => {
29961
30268
  const client = clientFrom(c);
29962
30269
  const clientIp = client.ip || "unknown";
29963
30270
  if (!requestIsTlsTerminated(c)) {
@@ -30002,7 +30309,7 @@ app65.post("/__remote-auth/login", async (c) => {
30002
30309
  }
30003
30310
  });
30004
30311
  });
30005
- app65.get("/__remote-auth/logout", (c) => {
30312
+ app66.get("/__remote-auth/logout", (c) => {
30006
30313
  const client = clientFrom(c);
30007
30314
  const clientIp = client.ip || "unknown";
30008
30315
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -30015,7 +30322,7 @@ app65.get("/__remote-auth/logout", (c) => {
30015
30322
  }
30016
30323
  });
30017
30324
  });
30018
- app65.post("/__remote-auth/change-password", async (c) => {
30325
+ app66.post("/__remote-auth/change-password", async (c) => {
30019
30326
  const client = clientFrom(c);
30020
30327
  const clientIp = client.ip || "unknown";
30021
30328
  const rateLimited = checkRateLimit(client);
@@ -30074,13 +30381,13 @@ app65.post("/__remote-auth/change-password", async (c) => {
30074
30381
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Failed to save password", redirect }), 200);
30075
30382
  }
30076
30383
  });
30077
- app65.get("/__remote-auth/setup", (c) => {
30384
+ app66.get("/__remote-auth/setup", (c) => {
30078
30385
  if (isRemoteAuthConfigured()) {
30079
30386
  return c.redirect("/");
30080
30387
  }
30081
30388
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup" }), 200);
30082
30389
  });
30083
- app65.post("/__remote-auth/set-initial-password", async (c) => {
30390
+ app66.post("/__remote-auth/set-initial-password", async (c) => {
30084
30391
  if (isRemoteAuthConfigured()) {
30085
30392
  return c.redirect("/");
30086
30393
  }
@@ -30118,10 +30425,10 @@ app65.post("/__remote-auth/set-initial-password", async (c) => {
30118
30425
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
30119
30426
  }
30120
30427
  });
30121
- app65.get("/api/remote-auth/status", (c) => {
30428
+ app66.get("/api/remote-auth/status", (c) => {
30122
30429
  return c.json({ configured: isRemoteAuthConfigured() });
30123
30430
  });
30124
- app65.post("/api/remote-auth/set-password", async (c) => {
30431
+ app66.post("/api/remote-auth/set-password", async (c) => {
30125
30432
  let body;
30126
30433
  try {
30127
30434
  body = await c.req.json();
@@ -30160,10 +30467,10 @@ app65.post("/api/remote-auth/set-password", async (c) => {
30160
30467
  return c.json({ error: "Failed to save password" }, 500);
30161
30468
  }
30162
30469
  });
30163
- app65.route("/api/_client-error", client_error_default);
30470
+ app66.route("/api/_client-error", client_error_default);
30164
30471
  console.log("[client-error-route] mounted");
30165
30472
  var PWA_PUBLIC_PATHS = /* @__PURE__ */ new Set(["/sw.js", ...PWA_SURFACES.map((s) => s.manifestPath)]);
30166
- app65.use("*", async (c, next) => {
30473
+ app66.use("*", async (c, next) => {
30167
30474
  const host = (c.req.header("host") ?? "").split(":")[0];
30168
30475
  const path3 = c.req.path;
30169
30476
  if (path3 === "/favicon.ico" || path3.startsWith("/assets/") || path3.startsWith("/brand/") || // Public free/busy is read by the booking page (a separate Cloudflare Pages
@@ -30207,28 +30514,28 @@ app65.use("*", async (c, next) => {
30207
30514
  }
30208
30515
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), redirect: path3 }), 200);
30209
30516
  });
30210
- app65.route("/api/health", health_default);
30211
- app65.route("/api/chat", chatRoutes);
30212
- app65.route("/api/whatsapp", whatsapp_default);
30213
- app65.route("/api/storage", storage_broker_default);
30214
- app65.route("/api/whatsapp-reader", whatsapp_reader_default);
30215
- app65.route("/api/public-reader", public_reader_default);
30216
- app65.route("/api/webchat", createWebchatRoutes({
30517
+ app66.route("/api/health", health_default);
30518
+ app66.route("/api/chat", chatRoutes);
30519
+ app66.route("/api/whatsapp", whatsapp_default);
30520
+ app66.route("/api/storage", storage_broker_default);
30521
+ app66.route("/api/whatsapp-reader", whatsapp_reader_default);
30522
+ app66.route("/api/public-reader", public_reader_default);
30523
+ app66.route("/api/webchat", createWebchatRoutes({
30217
30524
  handleInbound: (input) => webchatGateway.handleInbound(input),
30218
30525
  // Task 940 — the permission relay's pointer read + verdict write.
30219
30526
  pendingPromptFor: (key) => webchatGateway.pendingPromptFor(key),
30220
30527
  deliveryFailureFor: (key) => webchatGateway.deliveryFailureFor(key),
30221
30528
  resolvePermissionVerdict: (key, requestId, behavior) => webchatGateway.resolvePermissionVerdict(key, requestId, behavior)
30222
30529
  }));
30223
- app65.route("/api/webchat/greeting", webchat_greeting_default);
30224
- app65.route("/api/telegram", telegram_default);
30225
- app65.route("/api/quickbooks", quickbooks_default);
30226
- app65.route("/api/onboarding", onboarding_default);
30227
- app65.route("/api/admin", admin_default);
30228
- app65.route("/api/access", access_default);
30229
- app65.route("/api/session", session_default2);
30230
- app65.route("/api/calendar", calendar_public_default);
30231
- app65.route("/api/portal", portal_fetch_default);
30530
+ app66.route("/api/webchat/greeting", webchat_greeting_default);
30531
+ app66.route("/api/telegram", telegram_default);
30532
+ app66.route("/api/quickbooks", quickbooks_default);
30533
+ app66.route("/api/onboarding", onboarding_default);
30534
+ app66.route("/api/admin", admin_default);
30535
+ app66.route("/api/access", access_default);
30536
+ app66.route("/api/session", session_default2);
30537
+ app66.route("/api/calendar", calendar_public_default);
30538
+ app66.route("/api/portal", portal_fetch_default);
30232
30539
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
30233
30540
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
30234
30541
  var IMAGE_MIME = {
@@ -30240,7 +30547,7 @@ var IMAGE_MIME = {
30240
30547
  ".svg": "image/svg+xml",
30241
30548
  ".ico": "image/x-icon"
30242
30549
  };
30243
- app65.get("/agent-assets/:slug/:filename", (c) => {
30550
+ app66.get("/agent-assets/:slug/:filename", (c) => {
30244
30551
  const slug = c.req.param("slug");
30245
30552
  const filename = c.req.param("filename");
30246
30553
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -30256,26 +30563,26 @@ app65.get("/agent-assets/:slug/:filename", (c) => {
30256
30563
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
30257
30564
  return c.text("Not found", 404);
30258
30565
  }
30259
- const filePath = resolve41(account.accountDir, "agents", slug, "assets", filename);
30260
- const expectedDir = resolve41(account.accountDir, "agents", slug, "assets");
30566
+ const filePath = resolve42(account.accountDir, "agents", slug, "assets", filename);
30567
+ const expectedDir = resolve42(account.accountDir, "agents", slug, "assets");
30261
30568
  if (!filePath.startsWith(expectedDir + "/")) {
30262
30569
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
30263
30570
  return c.text("Forbidden", 403);
30264
30571
  }
30265
- if (!existsSync42(filePath)) {
30572
+ if (!existsSync43(filePath)) {
30266
30573
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
30267
30574
  return c.text("Not found", 404);
30268
30575
  }
30269
30576
  const ext = "." + filename.split(".").pop()?.toLowerCase();
30270
30577
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
30271
30578
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
30272
- const body = readFileSync45(filePath);
30579
+ const body = readFileSync46(filePath);
30273
30580
  return c.body(body, 200, {
30274
30581
  "Content-Type": contentType,
30275
30582
  "Cache-Control": "public, max-age=3600"
30276
30583
  });
30277
30584
  });
30278
- app65.get("/generated/:filename", (c) => {
30585
+ app66.get("/generated/:filename", (c) => {
30279
30586
  const filename = c.req.param("filename");
30280
30587
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
30281
30588
  console.error(`[generated] serve file=${filename} status=403`);
@@ -30286,35 +30593,35 @@ app65.get("/generated/:filename", (c) => {
30286
30593
  console.error(`[generated] serve file=${filename} status=404`);
30287
30594
  return c.text("Not found", 404);
30288
30595
  }
30289
- const filePath = resolve41(account.accountDir, "generated", filename);
30290
- const expectedDir = resolve41(account.accountDir, "generated");
30596
+ const filePath = resolve42(account.accountDir, "generated", filename);
30597
+ const expectedDir = resolve42(account.accountDir, "generated");
30291
30598
  if (!filePath.startsWith(expectedDir + "/")) {
30292
30599
  console.error(`[generated] serve file=${filename} status=403`);
30293
30600
  return c.text("Forbidden", 403);
30294
30601
  }
30295
- if (!existsSync42(filePath)) {
30602
+ if (!existsSync43(filePath)) {
30296
30603
  console.error(`[generated] serve file=${filename} status=404`);
30297
30604
  return c.text("Not found", 404);
30298
30605
  }
30299
30606
  const ext = "." + filename.split(".").pop()?.toLowerCase();
30300
30607
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
30301
30608
  console.log(`[generated] serve file=${filename} status=200`);
30302
- const body = readFileSync45(filePath);
30609
+ const body = readFileSync46(filePath);
30303
30610
  return c.body(body, 200, {
30304
30611
  "Content-Type": contentType,
30305
30612
  "Cache-Control": "public, max-age=86400"
30306
30613
  });
30307
30614
  });
30308
- app65.route("/sites", sites_default);
30309
- app65.route("/listings", listings_default);
30310
- app65.route("/v", visitor_event_default);
30311
- app65.route("/v", visitor_consent_default);
30615
+ app66.route("/sites", sites_default);
30616
+ app66.route("/listings", listings_default);
30617
+ app66.route("/v", visitor_event_default);
30618
+ app66.route("/v", visitor_consent_default);
30312
30619
  var htmlCache = /* @__PURE__ */ new Map();
30313
30620
  var brandLogoPath = "/brand/maxy-monochrome.png";
30314
30621
  var brandIconPath = "/brand/maxy-monochrome.png";
30315
- if (BRAND_JSON_PATH && existsSync42(BRAND_JSON_PATH)) {
30622
+ if (BRAND_JSON_PATH && existsSync43(BRAND_JSON_PATH)) {
30316
30623
  try {
30317
- const fullBrand = JSON.parse(readFileSync45(BRAND_JSON_PATH, "utf-8"));
30624
+ const fullBrand = JSON.parse(readFileSync46(BRAND_JSON_PATH, "utf-8"));
30318
30625
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
30319
30626
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
30320
30627
  } catch {
@@ -30341,11 +30648,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
30341
30648
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
30342
30649
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
30343
30650
  var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
30344
- (p) => existsSync42(resolve41(process.cwd(), "public", p.replace(/^\//, "")))
30651
+ (p) => existsSync43(resolve42(process.cwd(), "public", p.replace(/^\//, "")))
30345
30652
  );
30346
30653
  var SW_SOURCE = (() => {
30347
30654
  try {
30348
- return readFileSync45(resolve41(process.cwd(), "public", "sw.js"), "utf-8");
30655
+ return readFileSync46(resolve42(process.cwd(), "public", "sw.js"), "utf-8");
30349
30656
  } catch {
30350
30657
  return null;
30351
30658
  }
@@ -30354,8 +30661,8 @@ function readInstalledVersion() {
30354
30661
  try {
30355
30662
  if (!PLATFORM_ROOT8) return "unknown";
30356
30663
  const versionFile = join47(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
30357
- if (!existsSync42(versionFile)) return "unknown";
30358
- const content = readFileSync45(versionFile, "utf-8").trim();
30664
+ if (!existsSync43(versionFile)) return "unknown";
30665
+ const content = readFileSync46(versionFile, "utf-8").trim();
30359
30666
  return content || "unknown";
30360
30667
  } catch {
30361
30668
  return "unknown";
@@ -30396,7 +30703,7 @@ var clientErrorReporterScript = `<script>
30396
30703
  function cachedHtml(file) {
30397
30704
  let html = htmlCache.get(file);
30398
30705
  if (!html) {
30399
- html = readFileSync45(resolve41(process.cwd(), "public", file), "utf-8");
30706
+ html = readFileSync46(resolve42(process.cwd(), "public", file), "utf-8");
30400
30707
  const productNameEsc = escapeHtml(BRAND.productName);
30401
30708
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
30402
30709
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -30418,8 +30725,8 @@ function loadBrandingCache(agentSlug) {
30418
30725
  const accountId = getDefaultAccountId();
30419
30726
  if (!accountId) return null;
30420
30727
  const cachePath = join47(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
30421
- if (!existsSync42(cachePath)) return null;
30422
- return JSON.parse(readFileSync45(cachePath, "utf-8"));
30728
+ if (!existsSync43(cachePath)) return null;
30729
+ return JSON.parse(readFileSync46(cachePath, "utf-8"));
30423
30730
  } catch {
30424
30731
  return null;
30425
30732
  }
@@ -30463,7 +30770,7 @@ function brandedPublicHtml(agentSlug) {
30463
30770
  function agentUnavailableHtml() {
30464
30771
  return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${escapeHtml(BRAND.productName)}</title></head><body style="font-family:system-ui,sans-serif;max-width:32rem;margin:4rem auto;padding:0 1.5rem;color:#222"><h1 style="font-size:1.25rem">Agent unavailable</h1><p>This agent isn't available right now. If you reached this page from a saved link, the agent may have been turned off.</p></body></html>`;
30465
30772
  }
30466
- app65.get("/", (c) => {
30773
+ app66.get("/", (c) => {
30467
30774
  const host = (c.req.header("host") ?? "").split(":")[0];
30468
30775
  const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
30469
30776
  if (klass === "operator") {
@@ -30485,12 +30792,12 @@ app65.get("/", (c) => {
30485
30792
  console.log(`[host-class] host=${host} class=admin served=index.html`);
30486
30793
  return c.html(cachedHtml("index.html"));
30487
30794
  });
30488
- app65.get("/public", (c) => {
30795
+ app66.get("/public", (c) => {
30489
30796
  const host = (c.req.header("host") ?? "").split(":")[0];
30490
30797
  if (isPublicHost(host)) return c.text("Not found", 404);
30491
30798
  return c.html(cachedHtml("public.html"));
30492
30799
  });
30493
- app65.get("/public-chat", (c) => {
30800
+ app66.get("/public-chat", (c) => {
30494
30801
  const host = (c.req.header("host") ?? "").split(":")[0];
30495
30802
  if (isPublicHost(host)) return c.text("Not found", 404);
30496
30803
  return c.html(cachedHtml("public.html"));
@@ -30509,12 +30816,12 @@ async function logViewerFetch(c, next) {
30509
30816
  duration_ms: Date.now() - start
30510
30817
  });
30511
30818
  }
30512
- app65.use("/vnc-viewer.html", logViewerFetch);
30513
- app65.use("/vnc-popout.html", logViewerFetch);
30514
- app65.get("/vnc-popout.html", (c) => {
30819
+ app66.use("/vnc-viewer.html", logViewerFetch);
30820
+ app66.use("/vnc-popout.html", logViewerFetch);
30821
+ app66.get("/vnc-popout.html", (c) => {
30515
30822
  let html = htmlCache.get("vnc-popout.html");
30516
30823
  if (!html) {
30517
- html = readFileSync45(resolve41(process.cwd(), "public", "vnc-popout.html"), "utf-8");
30824
+ html = readFileSync46(resolve42(process.cwd(), "public", "vnc-popout.html"), "utf-8");
30518
30825
  const name = escapeHtml(BRAND.productName);
30519
30826
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
30520
30827
  html = html.replace("</head>", ` ${brandScript}
@@ -30524,7 +30831,7 @@ app65.get("/vnc-popout.html", (c) => {
30524
30831
  }
30525
30832
  return c.html(html);
30526
30833
  });
30527
- app65.post("/api/vnc/client-event", async (c) => {
30834
+ app66.post("/api/vnc/client-event", async (c) => {
30528
30835
  let body;
30529
30836
  try {
30530
30837
  body = await c.req.json();
@@ -30545,11 +30852,11 @@ app65.post("/api/vnc/client-event", async (c) => {
30545
30852
  });
30546
30853
  return c.json({ ok: true });
30547
30854
  });
30548
- app65.get("/g/:slug", (c) => {
30855
+ app66.get("/g/:slug", (c) => {
30549
30856
  return c.html(brandedPublicHtml(resolveDefaultSlug() ?? void 0));
30550
30857
  });
30551
30858
  for (const pwa of PWA_SURFACES) {
30552
- app65.get(pwa.manifestPath, (c) => {
30859
+ app66.get(pwa.manifestPath, (c) => {
30553
30860
  const manifest = buildManifest(pwa, {
30554
30861
  productName: BRAND.productName,
30555
30862
  appIcon192: brandAppIcon192Path,
@@ -30565,7 +30872,7 @@ for (const pwa of PWA_SURFACES) {
30565
30872
  return c.body(JSON.stringify(manifest));
30566
30873
  });
30567
30874
  }
30568
- app65.get("/sw.js", (c) => {
30875
+ app66.get("/sw.js", (c) => {
30569
30876
  if (SW_SOURCE == null) {
30570
30877
  console.error("[pwa] op=sw status=500 reason=sw-source-missing");
30571
30878
  return c.text("Service worker unavailable", 500);
@@ -30574,12 +30881,12 @@ app65.get("/sw.js", (c) => {
30574
30881
  console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
30575
30882
  return c.body(SW_SOURCE);
30576
30883
  });
30577
- app65.get("/graph", (c) => {
30884
+ app66.get("/graph", (c) => {
30578
30885
  const host = (c.req.header("host") ?? "").split(":")[0];
30579
30886
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
30580
30887
  return c.html(cachedHtml("graph.html"));
30581
30888
  });
30582
- app65.get("/chat", (c) => {
30889
+ app66.get("/chat", (c) => {
30583
30890
  const host = (c.req.header("host") ?? "").split(":")[0];
30584
30891
  if (isOperatorHost(host, getOperatorDomains())) {
30585
30892
  console.log(`[host-class] host=${host} class=operator served=operator.html`);
@@ -30588,37 +30895,42 @@ app65.get("/chat", (c) => {
30588
30895
  if (isPublicHost(host)) return c.text("Not found", 404);
30589
30896
  return c.html(cachedHtml("chat.html"));
30590
30897
  });
30591
- app65.get("/data", (c) => {
30898
+ app66.get("/data", (c) => {
30592
30899
  const host = (c.req.header("host") ?? "").split(":")[0];
30593
30900
  if (isPublicHost(host)) return c.text("Not found", 404);
30594
30901
  return c.html(cachedHtml("data.html"));
30595
30902
  });
30596
- app65.get("/tasks", (c) => {
30903
+ app66.get("/tasks", (c) => {
30597
30904
  const host = (c.req.header("host") ?? "").split(":")[0];
30598
30905
  if (isPublicHost(host)) return c.text("Not found", 404);
30599
30906
  return c.html(cachedHtml("tasks.html"));
30600
30907
  });
30601
- app65.get("/activity", (c) => {
30908
+ app66.get("/activity", (c) => {
30602
30909
  const host = (c.req.header("host") ?? "").split(":")[0];
30603
30910
  if (isPublicHost(host)) return c.text("Not found", 404);
30604
30911
  return c.html(cachedHtml("activity.html"));
30605
30912
  });
30606
- app65.get("/calendar", (c) => {
30913
+ app66.get("/calendar", (c) => {
30607
30914
  const host = (c.req.header("host") ?? "").split(":")[0];
30608
30915
  if (isPublicHost(host)) return c.text("Not found", 404);
30609
30916
  return c.html(cachedHtml("calendar.html"));
30610
30917
  });
30611
- app65.get("/routines", (c) => {
30918
+ app66.get("/routines", (c) => {
30612
30919
  const host = (c.req.header("host") ?? "").split(":")[0];
30613
30920
  if (isPublicHost(host)) return c.text("Not found", 404);
30614
30921
  return c.html(cachedHtml("routines.html"));
30615
30922
  });
30616
- app65.get("/browser", (c) => {
30923
+ app66.get("/skills", (c) => {
30924
+ const host = (c.req.header("host") ?? "").split(":")[0];
30925
+ if (isPublicHost(host)) return c.text("Not found", 404);
30926
+ return c.html(cachedHtml("skills.html"));
30927
+ });
30928
+ app66.get("/browser", (c) => {
30617
30929
  const host = (c.req.header("host") ?? "").split(":")[0];
30618
30930
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
30619
30931
  return c.html(cachedHtml("browser.html"));
30620
30932
  });
30621
- app65.get("/:slug", async (c, next) => {
30933
+ app66.get("/:slug", async (c, next) => {
30622
30934
  const slug = c.req.param("slug");
30623
30935
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
30624
30936
  const account = resolveAccount();
@@ -30633,13 +30945,13 @@ app65.get("/:slug", async (c, next) => {
30633
30945
  await next();
30634
30946
  });
30635
30947
  if (brandFaviconPath !== "/favicon.ico") {
30636
- app65.get("/favicon.ico", (c) => {
30948
+ app66.get("/favicon.ico", (c) => {
30637
30949
  c.header("Cache-Control", "public, max-age=300");
30638
30950
  return c.redirect(brandFaviconPath, 302);
30639
30951
  });
30640
30952
  }
30641
- app65.use("/*", serveStatic({ root: "./public" }));
30642
- app65.all("*", (c) => {
30953
+ app66.use("/*", serveStatic({ root: "./public" }));
30954
+ app66.all("*", (c) => {
30643
30955
  const host = (c.req.header("host") ?? "").split(":")[0];
30644
30956
  const path3 = c.req.path;
30645
30957
  if (isPublicHost(host)) {
@@ -30653,13 +30965,13 @@ app65.all("*", (c) => {
30653
30965
  });
30654
30966
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
30655
30967
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
30656
- var httpServer = serve({ fetch: app65.fetch, port, hostname });
30968
+ var httpServer = serve({ fetch: app66.fetch, port, hostname });
30657
30969
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30658
30970
  {
30659
30971
  const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30660
- const reconcileScript = resolve41(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
30972
+ const reconcileScript = resolve42(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
30661
30973
  const runReconcile = (ctx) => {
30662
- if (!existsSync42(reconcileScript)) return;
30974
+ if (!existsSync43(reconcileScript)) return;
30663
30975
  try {
30664
30976
  const child = spawn3(process.execPath, [reconcileScript], {
30665
30977
  env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
@@ -30698,14 +31010,14 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30698
31010
  {
30699
31011
  const DREAM_CYCLE_SWEEP_INTERVAL_MS = 36e5;
30700
31012
  const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30701
- const dreamSweepScript = resolve41(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
31013
+ const dreamSweepScript = resolve42(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
30702
31014
  registerLoop({
30703
31015
  name: "dream-cycle-sweep",
30704
31016
  intervalMs: DREAM_CYCLE_SWEEP_INTERVAL_MS,
30705
31017
  firstRunDelayMs: 3e4,
30706
31018
  detached: true,
30707
31019
  run: (ctx) => {
30708
- if (!existsSync42(dreamSweepScript)) return;
31020
+ if (!existsSync43(dreamSweepScript)) return;
30709
31021
  try {
30710
31022
  const child = spawn3(process.execPath, [dreamSweepScript], {
30711
31023
  env: { ...process.env, PLATFORM_ROOT: dreamPlatformRoot },
@@ -30722,10 +31034,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30722
31034
  }
30723
31035
  {
30724
31036
  const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30725
- const outlookScript = resolve41(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
31037
+ const outlookScript = resolve42(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
30726
31038
  const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
30727
31039
  const runOutlookComplete = (ctx) => {
30728
- if (!existsSync42(outlookScript)) return;
31040
+ if (!existsSync43(outlookScript)) return;
30729
31041
  try {
30730
31042
  const child = spawn3(process.execPath, [outlookScript], {
30731
31043
  env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
@@ -30748,19 +31060,19 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30748
31060
  }
30749
31061
  {
30750
31062
  const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30751
- const strandedAccountsDir = resolve41(auditRoot, "..", "data/accounts");
31063
+ const strandedAccountsDir = resolve42(auditRoot, "..", "data/accounts");
30752
31064
  const STRANDED_AUDIT_INTERVAL_MS = 3e5;
30753
31065
  const STRANDED_AGE_MS = 16 * 6e4;
30754
31066
  const STRANDED_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
30755
31067
  const runStrandedAudit = () => {
30756
31068
  try {
30757
- if (!existsSync42(strandedAccountsDir)) return;
31069
+ if (!existsSync43(strandedAccountsDir)) return;
30758
31070
  const now = Date.now();
30759
- for (const name of readdirSync26(strandedAccountsDir)) {
31071
+ for (const name of readdirSync27(strandedAccountsDir)) {
30760
31072
  if (!STRANDED_UUID_RE.test(name)) continue;
30761
- const pendingPath2 = resolve41(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
30762
- if (!existsSync42(pendingPath2)) continue;
30763
- const ageMs2 = now - statSync17(pendingPath2).mtimeMs;
31073
+ const pendingPath2 = resolve42(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
31074
+ if (!existsSync43(pendingPath2)) continue;
31075
+ const ageMs2 = now - statSync18(pendingPath2).mtimeMs;
30764
31076
  if (ageMs2 > STRANDED_AGE_MS) {
30765
31077
  console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs2 / 1e3)}`);
30766
31078
  }
@@ -30778,7 +31090,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30778
31090
  }
30779
31091
  {
30780
31092
  const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30781
- const googleAccountsDir = resolve41(googleRoot, "..", "data/accounts");
31093
+ const googleAccountsDir = resolve42(googleRoot, "..", "data/accounts");
30782
31094
  const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
30783
31095
  const runGooglePendingAuditSafe = () => {
30784
31096
  try {
@@ -30793,10 +31105,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30793
31105
  firstRunDelayMs: 27e3,
30794
31106
  run: runGooglePendingAuditSafe
30795
31107
  });
30796
- const googleAuditScript = resolve41(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
31108
+ const googleAuditScript = resolve42(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
30797
31109
  const GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS = 36e5;
30798
31110
  const runGoogleAccountAudit = (ctx) => {
30799
- if (!existsSync42(googleAuditScript)) return;
31111
+ if (!existsSync43(googleAuditScript)) return;
30800
31112
  try {
30801
31113
  const child = spawn3(process.execPath, [googleAuditScript], {
30802
31114
  env: { ...process.env, PLATFORM_ROOT: googleRoot },
@@ -30868,7 +31180,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30868
31180
  }
30869
31181
  {
30870
31182
  const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30871
- const publishScript = resolve41(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
31183
+ const publishScript = resolve42(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
30872
31184
  const PUBLISH_INTERVAL_MS = 3e5;
30873
31185
  const bookingAccounts = () => {
30874
31186
  try {
@@ -30879,7 +31191,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30879
31191
  }
30880
31192
  };
30881
31193
  const spawnPublish = (account, ctx) => {
30882
- if (!existsSync42(publishScript)) return;
31194
+ if (!existsSync43(publishScript)) return;
30883
31195
  try {
30884
31196
  const child = spawn3(process.execPath, [publishScript], {
30885
31197
  env: {
@@ -30898,21 +31210,21 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30898
31210
  }
30899
31211
  };
30900
31212
  const auditSnapshotAge = (account) => {
30901
- const availPath = resolve41(account.accountDir, "calendar-availability.json");
31213
+ const availPath = resolve42(account.accountDir, "calendar-availability.json");
30902
31214
  let hasBookingSite = false;
30903
31215
  try {
30904
- if (existsSync42(availPath)) {
30905
- const cfg = JSON.parse(readFileSync45(availPath, "utf-8"));
31216
+ if (existsSync43(availPath)) {
31217
+ const cfg = JSON.parse(readFileSync46(availPath, "utf-8"));
30906
31218
  hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
30907
31219
  }
30908
31220
  } catch {
30909
31221
  }
30910
31222
  if (!hasBookingSite) return;
30911
- const statePath = resolve41(account.accountDir, "state", "booking-availability", "last-publish.json");
31223
+ const statePath = resolve42(account.accountDir, "state", "booking-availability", "last-publish.json");
30912
31224
  let lastSuccessAt = null;
30913
- if (existsSync42(statePath)) {
31225
+ if (existsSync43(statePath)) {
30914
31226
  try {
30915
- const rec = JSON.parse(readFileSync45(statePath, "utf-8"));
31227
+ const rec = JSON.parse(readFileSync46(statePath, "utf-8"));
30916
31228
  lastSuccessAt = rec.lastSuccessAt ?? null;
30917
31229
  } catch {
30918
31230
  console.error(`[calendar-availability] op=audit accountId=${account.accountId} snapshotAgeMs=na reason=bad-state-file`);
@@ -30945,11 +31257,11 @@ startTimeEntryCensus(() => getSession());
30945
31257
  startLedgerCensus(() => getSession());
30946
31258
  {
30947
31259
  const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30948
- const auditScript = resolve41(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
31260
+ const auditScript = resolve42(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
30949
31261
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
30950
31262
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
30951
31263
  const runConnectorAudit = (ctx) => {
30952
- if (!existsSync42(auditScript)) return;
31264
+ if (!existsSync43(auditScript)) return;
30953
31265
  try {
30954
31266
  const child = spawn3(process.execPath, [auditScript], {
30955
31267
  env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
@@ -31029,7 +31341,7 @@ for (const m of SUBAPP_MANIFEST) {
31029
31341
  }
31030
31342
  try {
31031
31343
  const registered = [];
31032
- for (const r of app65.routes ?? []) {
31344
+ for (const r of app66.routes ?? []) {
31033
31345
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
31034
31346
  if (AGENT_SLUG_PATTERN.test(r.path)) {
31035
31347
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -31069,11 +31381,11 @@ try {
31069
31381
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
31070
31382
  async function runAdminUserReconcileTick() {
31071
31383
  try {
31072
- if (!existsSync42(USERS_FILE)) {
31384
+ if (!existsSync43(USERS_FILE)) {
31073
31385
  console.error("[adminuser-self-heal] skip reason=no-users-file");
31074
31386
  return;
31075
31387
  }
31076
- const usersRaw = readFileSync45(USERS_FILE, "utf-8").trim();
31388
+ const usersRaw = readFileSync46(USERS_FILE, "utf-8").trim();
31077
31389
  if (!usersRaw) {
31078
31390
  console.error("[adminuser-self-heal] skip reason=empty-users-file");
31079
31391
  return;
@@ -31120,8 +31432,8 @@ registerLoop({
31120
31432
  });
31121
31433
  var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
31122
31434
  function countUsersRows() {
31123
- if (!existsSync42(USERS_FILE)) return 0;
31124
- const raw = readFileSync45(USERS_FILE, "utf-8").trim();
31435
+ if (!existsSync43(USERS_FILE)) return 0;
31436
+ const raw = readFileSync46(USERS_FILE, "utf-8").trim();
31125
31437
  if (!raw) return 0;
31126
31438
  const users = JSON.parse(raw);
31127
31439
  return users.filter((u) => typeof u.userId === "string").length;
@@ -31254,7 +31566,7 @@ if (bootAccountConfig?.whatsapp) {
31254
31566
  }
31255
31567
  init({
31256
31568
  configDir: configDirForWhatsApp,
31257
- platformRoot: resolve41(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..")),
31569
+ platformRoot: resolve42(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..")),
31258
31570
  accountConfig: bootAccountConfig,
31259
31571
  onMessage: async (msg) => {
31260
31572
  if (isObserveAccount(msg.accountId)) {