@rubytech/create-maxy-code 0.1.500 → 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 (184) 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 +1 -0
  11. package/payload/platform/plugins/admin/skills/agent-builder/SKILL.md +15 -0
  12. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +51 -1
  13. package/payload/platform/plugins/admin/skills/summarise/SKILL.md +37 -0
  14. package/payload/platform/plugins/docs/references/admin-ui.md +50 -0
  15. package/payload/platform/plugins/docs/references/summarise-skill.md +7 -0
  16. package/payload/server/public/activity.html +6 -6
  17. package/payload/server/public/assets/{AdminLoginScreens-CKg_Dlpv.js → AdminLoginScreens-C3LZOPIY.js} +1 -1
  18. package/payload/server/public/assets/AdminShell-BlbUNAPc.js +2 -0
  19. package/payload/server/public/assets/{activity-CKUYOLd2.js → activity-CVdVSw5V.js} +1 -1
  20. package/payload/server/public/assets/admin-If1QLlS3.js +1 -0
  21. package/payload/server/public/assets/{arc-CpWWSum8.js → arc-CvlzUHOf.js} +1 -1
  22. package/payload/server/public/assets/architecture-YZFGNWBL-BQc779DH.js +1 -0
  23. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-D2EzaII0.js → architectureDiagram-Q4EWVU46-I1Hs0RJA.js} +1 -1
  24. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-8kDpaNSZ.js → blockDiagram-DXYQGD6D-Df5jTGtl.js} +1 -1
  25. package/payload/server/public/assets/{bot-DESMpxSQ.js → bot-8b26IlQY.js} +1 -1
  26. package/payload/server/public/assets/{browser-CpLq_DIo.js → browser-F40DXfKA.js} +1 -1
  27. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CbwmZpK3.js → c4Diagram-AHTNJAMY-B6WY5IDv.js} +1 -1
  28. package/payload/server/public/assets/{calendar-ClOwyuz-.js → calendar-DZiHiBwV.js} +1 -1
  29. package/payload/server/public/assets/channel-AqnC3SHu.js +1 -0
  30. package/payload/server/public/assets/chat-uD28FVCS.js +1 -0
  31. package/payload/server/public/assets/chevron-left-lBxD57tD.js +1 -0
  32. package/payload/server/public/assets/chevron-right-C-lDig9Y.js +1 -0
  33. package/payload/server/public/assets/{chunk-2KRD3SAO-PFheZ9mw.js → chunk-2KRD3SAO-BsIIFDkc.js} +1 -1
  34. package/payload/server/public/assets/{chunk-336JU56O-CCFOp5VK.js → chunk-336JU56O-j9z1VtyC.js} +2 -2
  35. package/payload/server/public/assets/chunk-426QAEUC-CO02gU5d.js +1 -0
  36. package/payload/server/public/assets/{chunk-4BX2VUAB-Hz4JWOf2.js → chunk-4BX2VUAB-C9i7prxq.js} +1 -1
  37. package/payload/server/public/assets/{chunk-4TB4RGXK-4xeV0s85.js → chunk-4TB4RGXK-DH0QVGcv.js} +1 -1
  38. package/payload/server/public/assets/{chunk-55IACEB6-4QKgBpoh.js → chunk-55IACEB6-Dnd_YCPA.js} +1 -1
  39. package/payload/server/public/assets/{chunk-5FUZZQ4R-ms3K6Z5z.js → chunk-5FUZZQ4R-D5sSz3yN.js} +1 -1
  40. package/payload/server/public/assets/{chunk-5PVQY5BW-CIC4GIGi.js → chunk-5PVQY5BW-CJrwWjAT.js} +1 -1
  41. package/payload/server/public/assets/{chunk-67CJDMHE-B-XrWVmV.js → chunk-67CJDMHE-SjP6_hUw.js} +1 -1
  42. package/payload/server/public/assets/{chunk-7N4EOEYR-C7ECOUYQ.js → chunk-7N4EOEYR-fAuhVJD0.js} +1 -1
  43. package/payload/server/public/assets/{chunk-AA7GKIK3-DOZ6Fxwk.js → chunk-AA7GKIK3-DZxa7KVg.js} +1 -1
  44. package/payload/server/public/assets/{chunk-BSJP7CBP-4cJ_b0c6.js → chunk-BSJP7CBP-DjeG3eQ-.js} +1 -1
  45. package/payload/server/public/assets/{chunk-CIAEETIT--mhZipWM.js → chunk-CIAEETIT-RYQULNJm.js} +1 -1
  46. package/payload/server/public/assets/{chunk-EDXVE4YY-jZpVwob_.js → chunk-EDXVE4YY-Cahapnon.js} +1 -1
  47. package/payload/server/public/assets/{chunk-ENJZ2VHE-Nn-p-xIA.js → chunk-ENJZ2VHE-1146X1L4.js} +1 -1
  48. package/payload/server/public/assets/{chunk-FMBD7UC4-DyNpcKOS.js → chunk-FMBD7UC4-BCFumtcP.js} +1 -1
  49. package/payload/server/public/assets/{chunk-FOC6F5B3-C0P8q1uz.js → chunk-FOC6F5B3-CkrtX8Zt.js} +1 -1
  50. package/payload/server/public/assets/{chunk-ICPOFSXX-CdXQ5SfI.js → chunk-ICPOFSXX-Ba1y3DaW.js} +2 -2
  51. package/payload/server/public/assets/{chunk-K5T4RW27-BVZJKKsT.js → chunk-K5T4RW27-CF-PI3uQ.js} +1 -1
  52. package/payload/server/public/assets/{chunk-KGLVRYIC-QlVWTe0V.js → chunk-KGLVRYIC-SFFC6ZC-.js} +1 -1
  53. package/payload/server/public/assets/{chunk-LIHQZDEY-CpGVZutP.js → chunk-LIHQZDEY-DbOLEP4R.js} +1 -1
  54. package/payload/server/public/assets/{chunk-ORNJ4GCN-WVcS6fUC.js → chunk-ORNJ4GCN-VB963bkN.js} +1 -1
  55. package/payload/server/public/assets/{chunk-OYMX7WX6-B7hiSTed.js → chunk-OYMX7WX6-DWYY1pQa.js} +1 -1
  56. package/payload/server/public/assets/chunk-QZHKN3VN-BiFMbK8t.js +1 -0
  57. package/payload/server/public/assets/{chunk-U2HBQHQK-DJPnZxGy.js → chunk-U2HBQHQK-DAH1diYP.js} +1 -1
  58. package/payload/server/public/assets/{chunk-X2U36JSP-DilBs1Yc.js → chunk-X2U36JSP-Dmw9coXz.js} +1 -1
  59. package/payload/server/public/assets/{chunk-XPW4576I-B5-uyrJ0.js → chunk-XPW4576I-DaAUON1-.js} +1 -1
  60. package/payload/server/public/assets/{chunk-YZCP3GAM-BNO4z0Mv.js → chunk-YZCP3GAM-BUcfkEef.js} +1 -1
  61. package/payload/server/public/assets/{chunk-ZZ45TVLE-BzHMQpip.js → chunk-ZZ45TVLE-BLD-vFRO.js} +1 -1
  62. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BdRqzScB.js +1 -0
  63. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-ChPLgHbS.js +1 -0
  64. package/payload/server/public/assets/clock-DqRNsY40.js +1 -0
  65. package/payload/server/public/assets/clone-TKtrjWBC.js +1 -0
  66. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-3DWYmn1o.js → cose-bilkent-S5V4N54A-CoZX0uki.js} +1 -1
  67. package/payload/server/public/assets/{dagre-Cpy31xJW.js → dagre-Bmjs8zJA.js} +1 -1
  68. package/payload/server/public/assets/{dagre-KV5264BT-C8fyxHFd.js → dagre-KV5264BT-BZCP2wnq.js} +1 -1
  69. package/payload/server/public/assets/data-BsFyBN85.js +1 -0
  70. package/payload/server/public/assets/{diagram-5BDNPKRD-ycyhnLvr.js → diagram-5BDNPKRD-8Nt9a4xX.js} +1 -1
  71. package/payload/server/public/assets/{diagram-G4DWMVQ6-BkeYicIt.js → diagram-G4DWMVQ6-vh5tcYqJ.js} +1 -1
  72. package/payload/server/public/assets/{diagram-MMDJMWI5-BcGZU-Q3.js → diagram-MMDJMWI5-DGf--jc8.js} +1 -1
  73. package/payload/server/public/assets/{diagram-TYMM5635-DuBDCFb_.js → diagram-TYMM5635-CsO7TIdw.js} +1 -1
  74. package/payload/server/public/assets/{dist-BYc_arNy.js → dist-cdnE4DqK.js} +1 -1
  75. package/payload/server/public/assets/{erDiagram-SMLLAGMA-DmkeOzvp.js → erDiagram-SMLLAGMA-4a78yV8_.js} +1 -1
  76. package/payload/server/public/assets/file-text-B1HjPFbM.js +1 -0
  77. package/payload/server/public/assets/{flatten-QjnJ1Gcl.js → flatten-BtIc9jX7.js} +1 -1
  78. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CkE-pjuB.js → flowDiagram-DWJPFMVM-BoQBXs6t.js} +1 -1
  79. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-Cjiy3kvE.js → ganttDiagram-T4ZO3ILL-CvzqwCC8.js} +1 -1
  80. package/payload/server/public/assets/gitGraph-7Q5UKJZL-DfcaTE9L.js +1 -0
  81. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CsI4lKZm.js → gitGraphDiagram-UUTBAWPF-D_nBxay_.js} +1 -1
  82. package/payload/server/public/assets/graph-CIC-mgKR.js +51 -0
  83. package/payload/server/public/assets/graph-labels-BnpHCHaQ.js +1 -0
  84. package/payload/server/public/assets/{graphlib-BkXxC6D5.js → graphlib-D0NdsKJI.js} +1 -1
  85. package/payload/server/public/assets/info-OMHHGYJF-CD-u6gw9.js +1 -0
  86. package/payload/server/public/assets/infoDiagram-42DDH7IO-C6gPQCvO.js +2 -0
  87. package/payload/server/public/assets/{isEmpty-BavJI9Cn.js → isEmpty-Bu4fZ8Kf.js} +1 -1
  88. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-D8lZtjRc.js → ishikawaDiagram-UXIWVN3A-auW-s0i0.js} +1 -1
  89. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-kLE7SiR_.js → journeyDiagram-VCZTEJTY-3Q6AWK4A.js} +1 -1
  90. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-ove6JuD3.js → kanban-definition-6JOO6SKY-B4MPFp98.js} +1 -1
  91. package/payload/server/public/assets/{line-CZMSoxM6.js → line-26MdeG5Z.js} +1 -1
  92. package/payload/server/public/assets/{linear-Be8IK9hK.js → linear-Dq9s_bDO.js} +1 -1
  93. package/payload/server/public/assets/{maximize-2-BbzPm7o8.js → maximize-2-BL7QVTcQ.js} +1 -1
  94. package/payload/server/public/assets/{mermaid-parser.core-BBADqbnp.js → mermaid-parser.core-vLEpOXgf.js} +2 -2
  95. package/payload/server/public/assets/{mermaid.core-mH3N7K0I.js → mermaid.core-Durk4m6D.js} +3 -3
  96. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-BjwwwWil.js → mindmap-definition-QFDTVHPH-DOIg-TyG.js} +1 -1
  97. package/payload/server/public/assets/{operator-DglDYmdV.js → operator-B62h_TaC.js} +1 -1
  98. package/payload/server/public/assets/{ordinal-BHeIKG-K.js → ordinal-C2TEWKNu.js} +1 -1
  99. package/payload/server/public/assets/packet-4T2RLAQJ-BaLYeIrU.js +1 -0
  100. package/payload/server/public/assets/page-BUUBseJZ.js +32 -0
  101. package/payload/server/public/assets/page-Bw-tYjw7.js +1 -0
  102. package/payload/server/public/assets/{pdf-render-fJz4vym9.js → pdf-render-C257cidb.js} +1 -1
  103. package/payload/server/public/assets/pie-ZZUOXDRM-CL-XJtk-.js +1 -0
  104. package/payload/server/public/assets/{pieDiagram-DEJITSTG-D-lXWWta.js → pieDiagram-DEJITSTG-DtgBHZfi.js} +1 -1
  105. package/payload/server/public/assets/{public-DqJjXR4p.js → public-BI21tOkm.js} +1 -1
  106. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-13QyG_AO.js → quadrantDiagram-34T5L4WZ-BTc5Qn2y.js} +1 -1
  107. package/payload/server/public/assets/radar-PYXPWWZC-Cn-g6F_h.js +1 -0
  108. package/payload/server/public/assets/{reduce-Fm685to3.js → reduce-BGpN5lgn.js} +1 -1
  109. package/payload/server/public/assets/{requirementDiagram-MS252O5E-Bx45Bgn4.js → requirementDiagram-MS252O5E-BNgOO5YW.js} +1 -1
  110. package/payload/server/public/assets/{rotate-ccw-L42fL8ey.js → rotate-ccw-C_20Bc3E.js} +1 -1
  111. package/payload/server/public/assets/routines-Ci3N8wqV.js +1 -0
  112. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-Cj-Gq25v.js → sankeyDiagram-XADWPNL6-MyUATmVt.js} +1 -1
  113. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-B8RDRq93.js → sequenceDiagram-FGHM5R23-CBJrF5Vi.js} +1 -1
  114. package/payload/server/public/assets/skills-CiflzOko.js +1 -0
  115. package/payload/server/public/assets/{src-D3VYuW_Z.js → src-DekKlUCp.js} +1 -1
  116. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DoyFF1Kl.js → stateDiagram-FHFEXIEX-6wbUjn1Q.js} +1 -1
  117. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BdMdfBeC.js +1 -0
  118. package/payload/server/public/assets/{tasks-GNtvZL8F.js → tasks-DC2Yf2Ev.js} +1 -1
  119. package/payload/server/public/assets/{time-entry-format-BreNpFLJ.js → time-entry-format-CNcjs2HV.js} +1 -1
  120. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Df4RQXm6.js → timeline-definition-GMOUNBTQ-BHjTMCGY.js} +1 -1
  121. package/payload/server/public/assets/treeView-SZITEDCU-CmZoOGlC.js +1 -0
  122. package/payload/server/public/assets/treemap-W4RFUUIX-H27WFS-y.js +1 -0
  123. package/payload/server/public/assets/{triangle-alert-DumCWC08.js → triangle-alert-CngnWtjD.js} +1 -1
  124. package/payload/server/public/assets/{useCopyFeedback-DHCtz8qX.js → useCopyFeedback-DZ9Bw5CI.js} +1 -1
  125. package/payload/server/public/assets/{useSubAccountSwitcher-Bc7XHr0L.js → useSubAccountSwitcher-CHwQhkaI.js} +1 -1
  126. package/payload/server/public/assets/{useSubAccountSwitcher-DPHQJO7E.css → useSubAccountSwitcher-yFQqnpQ8.css} +1 -1
  127. package/payload/server/public/assets/useVoiceRecorder-C3G6aqZr.js +2 -0
  128. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-D2o5og9l.js → vennDiagram-DHZGUBPP-yo3-cf0U.js} +1 -1
  129. package/payload/server/public/assets/wardley-RL74JXVD-DNpWIvU4.js +1 -0
  130. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-BDueObbS.js → wardleyDiagram-NUSXRM2D-DZlyFzrg.js} +1 -1
  131. package/payload/server/public/assets/{wrench-iWkROE1V.js → wrench-dky2-13x.js} +1 -1
  132. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BTYs4Fgh.js → xychartDiagram-5P7HB3ND-B5HV5h80.js} +1 -1
  133. package/payload/server/public/browser.html +5 -5
  134. package/payload/server/public/calendar.html +8 -8
  135. package/payload/server/public/chat.html +16 -15
  136. package/payload/server/public/data.html +13 -12
  137. package/payload/server/public/graph.html +10 -10
  138. package/payload/server/public/index.html +17 -16
  139. package/payload/server/public/operator.html +17 -16
  140. package/payload/server/public/public.html +16 -15
  141. package/payload/server/public/routines.html +7 -7
  142. package/payload/server/public/skills.html +19 -0
  143. package/payload/server/public/tasks.html +7 -7
  144. package/payload/server/server.js +672 -396
  145. package/payload/server/public/assets/AdminShell-BFVVkWFC.js +0 -2
  146. package/payload/server/public/assets/admin-wtSUU5N0.js +0 -1
  147. package/payload/server/public/assets/architecture-YZFGNWBL-D-AX2VuA.js +0 -1
  148. package/payload/server/public/assets/channel-DZ5sh6YQ.js +0 -1
  149. package/payload/server/public/assets/chat-DRuIxGtE.js +0 -1
  150. package/payload/server/public/assets/chevron-left-BzIg4in6.js +0 -1
  151. package/payload/server/public/assets/chevron-right-BcFSa9C3.js +0 -1
  152. package/payload/server/public/assets/chunk-426QAEUC-CcjBLp4a.js +0 -1
  153. package/payload/server/public/assets/chunk-QZHKN3VN-B2WjDYBE.js +0 -1
  154. package/payload/server/public/assets/classDiagram-6PBFFD2Q-CT3jNrze.js +0 -1
  155. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DJRsjAkC.js +0 -1
  156. package/payload/server/public/assets/clock-Dr3NGtjR.js +0 -1
  157. package/payload/server/public/assets/clone-FcEDnoMT.js +0 -1
  158. package/payload/server/public/assets/data-BdZCvyvN.js +0 -1
  159. package/payload/server/public/assets/gitGraph-7Q5UKJZL-D1uhnP9U.js +0 -1
  160. package/payload/server/public/assets/graph-B7niLM97.js +0 -51
  161. package/payload/server/public/assets/graph-labels-DykmXYHA.js +0 -1
  162. package/payload/server/public/assets/info-OMHHGYJF-oNm27GAV.js +0 -1
  163. package/payload/server/public/assets/infoDiagram-42DDH7IO-LxTftqyS.js +0 -2
  164. package/payload/server/public/assets/packet-4T2RLAQJ-eQNVGiK3.js +0 -1
  165. package/payload/server/public/assets/page-C-5sTAE-.js +0 -32
  166. package/payload/server/public/assets/page-C8G5p4jr.js +0 -1
  167. package/payload/server/public/assets/pie-ZZUOXDRM-E1u-48rt.js +0 -1
  168. package/payload/server/public/assets/radar-PYXPWWZC-Cn2cGN90.js +0 -1
  169. package/payload/server/public/assets/routines-JOV6xdYh.js +0 -1
  170. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Bml-X4-H.js +0 -1
  171. package/payload/server/public/assets/treeView-SZITEDCU-CimabhXy.js +0 -1
  172. package/payload/server/public/assets/treemap-W4RFUUIX-Cg264rpM.js +0 -1
  173. package/payload/server/public/assets/useVoiceRecorder-Cj-VZDKO.js +0 -2
  174. package/payload/server/public/assets/wardley-RL74JXVD-tbgfCg0E.js +0 -1
  175. /package/payload/server/public/assets/{_baseFor-Bvwvhrz4.js → _baseFor-Be3EKK3K.js} +0 -0
  176. /package/payload/server/public/assets/{array-D3d-WgFW.js → array-X0JlPOfd.js} +0 -0
  177. /package/payload/server/public/assets/{chunk-fQC6bEKA.js → chunk-CCr-iYLO.js} +0 -0
  178. /package/payload/server/public/assets/{cytoscape.esm-Cun-OM6a.js → cytoscape.esm-CI2IWMLB.js} +0 -0
  179. /package/payload/server/public/assets/{defaultLocale-CisKV5Ew.js → defaultLocale-B6RGN4id.js} +0 -0
  180. /package/payload/server/public/assets/{init-D9ZOVaZ3.js → init-BmUWJJHz.js} +0 -0
  181. /package/payload/server/public/assets/{katex-C-3ZDK8o.js → katex-BjZuzSQn.js} +0 -0
  182. /package/payload/server/public/assets/{path-BMOgQSLM.js → path-CoPyR7c2.js} +0 -0
  183. /package/payload/server/public/assets/{preload-helper-DL2DwvxV.js → preload-helper-BQrMkyGX.js} +0 -0
  184. /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);
@@ -11657,16 +11795,6 @@ function asString(content) {
11657
11795
  function tsOf(row) {
11658
11796
  return typeof row.timestamp === "string" ? row.timestamp : null;
11659
11797
  }
11660
- function hasWebchatReply(content) {
11661
- if (!Array.isArray(content)) return false;
11662
- for (const block of content) {
11663
- if (block && typeof block === "object") {
11664
- const b = block;
11665
- if (b.type === "tool_use" && b.name === WEBCHAT_REPLY_TOOL) return true;
11666
- }
11667
- }
11668
- return false;
11669
- }
11670
11798
  function joinTextBlocks(content) {
11671
11799
  if (!Array.isArray(content)) return "";
11672
11800
  const parts = [];
@@ -11789,9 +11917,8 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
11789
11917
  out.push({ kind: "agent-error", code, raw, ts });
11790
11918
  continue;
11791
11919
  }
11792
- if (hasWebchatReply(msg?.content)) turnCtx.repliedThisTurn = true;
11793
11920
  const isEnd = msg?.stop_reason === "end_turn";
11794
- const promoteFinal = isEnd && turnCtx.lastChannelSource === "webchat" && !turnCtx.repliedThisTurn;
11921
+ const promoteFinal = isEnd && turnCtx.lastChannelSource === "webchat";
11795
11922
  out.push(...assistantTurns(msg?.content, ts, promoteFinal, erroredIds));
11796
11923
  continue;
11797
11924
  }
@@ -11800,7 +11927,6 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
11800
11927
  if (content !== null && CHANNEL_WRAPPER2.test(content)) {
11801
11928
  const u = unwrapChannel(content);
11802
11929
  turnCtx.lastChannelSource = u.source;
11803
- turnCtx.repliedThisTurn = false;
11804
11930
  if (!isScheduleSource(content)) {
11805
11931
  out.push(operatorInboundTurn(u, ts));
11806
11932
  queuedPendingSuppress.set(u.text, (queuedPendingSuppress.get(u.text) ?? 0) + 1);
@@ -11814,7 +11940,6 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
11814
11940
  if (isChannelQueued) {
11815
11941
  const u = unwrapChannel(att.prompt);
11816
11942
  turnCtx.lastChannelSource = u.source;
11817
- turnCtx.repliedThisTurn = false;
11818
11943
  if (!isScheduleSource(att.prompt)) {
11819
11944
  renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress);
11820
11945
  }
@@ -11844,7 +11969,6 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
11844
11969
  if (isChannel) {
11845
11970
  const u = unwrapChannel(text);
11846
11971
  turnCtx.lastChannelSource = u.source;
11847
- turnCtx.repliedThisTurn = false;
11848
11972
  if (!isScheduleSource(text)) {
11849
11973
  renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress);
11850
11974
  }
@@ -13821,8 +13945,8 @@ async function reapplyLeversViaManager() {
13821
13945
  var WEBCHAT_SEND_TURN_WINDOW_MS = Number(process.env.WEBCHAT_SEND_TURN_WINDOW_MS ?? String(15e3));
13822
13946
  var sendSeq = 0;
13823
13947
  function createWebchatRoutes(deps) {
13824
- const app66 = new Hono();
13825
- app66.post("/send", requireAdminSession, async (c) => {
13948
+ const app67 = new Hono();
13949
+ app67.post("/send", requireAdminSession, async (c) => {
13826
13950
  let accountId;
13827
13951
  try {
13828
13952
  accountId = resolvePlatformAccountId();
@@ -14025,7 +14149,7 @@ ${note}` : note;
14025
14149
  if (turnTimer.unref) turnTimer.unref();
14026
14150
  return c.json({ ok: true });
14027
14151
  });
14028
- app66.post("/interrupt", requireAdminSession, async (c) => {
14152
+ app67.post("/interrupt", requireAdminSession, async (c) => {
14029
14153
  const cacheKey = c.get("cacheKey");
14030
14154
  const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
14031
14155
  const primaryUserId = resolvePrimaryAdminUserId();
@@ -14053,7 +14177,7 @@ ${note}` : note;
14053
14177
  }
14054
14178
  return c.json({ ok: true, stopped: outcome.stopped, intId: outcome.intId, deadChild: outcome.deadChild }, 200);
14055
14179
  });
14056
- app66.post("/settings", requireAdminSession, async (c) => {
14180
+ app67.post("/settings", requireAdminSession, async (c) => {
14057
14181
  const body = await c.req.json().catch(() => null);
14058
14182
  const op = body?.op;
14059
14183
  const value = body?.value;
@@ -14093,7 +14217,7 @@ ${note}` : note;
14093
14217
  console.log(`[webchat:settings] op=${op} outcome=accepted value=${value} settingsApplied=${settingsApplied}`);
14094
14218
  return c.json({ ok: true, settingsApplied });
14095
14219
  });
14096
- app66.get("/session", requireAdminSession, async (c) => {
14220
+ app67.get("/session", requireAdminSession, async (c) => {
14097
14221
  let accountId;
14098
14222
  try {
14099
14223
  accountId = resolvePlatformAccountId();
@@ -14171,7 +14295,7 @@ ${note}` : note;
14171
14295
  const indicators = await fetchComposerIndicators(sessionId);
14172
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) });
14173
14297
  });
14174
- app66.post("/permission-verdict", requireAdminSession, async (c) => {
14298
+ app67.post("/permission-verdict", requireAdminSession, async (c) => {
14175
14299
  const body = await c.req.json().catch(() => null);
14176
14300
  const sessionId = body?.sessionId;
14177
14301
  const requestId = body?.request_id;
@@ -14188,7 +14312,7 @@ ${note}` : note;
14188
14312
  const ok = deps.resolvePermissionVerdict?.(`session:${sessionId}`, requestId, behavior) ?? false;
14189
14313
  return c.json({ ok });
14190
14314
  });
14191
- return app66;
14315
+ return app67;
14192
14316
  }
14193
14317
 
14194
14318
  // server/routes/webchat-greeting.ts
@@ -15544,15 +15668,15 @@ function operatorRoleFor(config, userId) {
15544
15668
  async function buildAccountOptionList(accounts, userId) {
15545
15669
  const houseAccount = accounts.find((a) => a.config.role === "house");
15546
15670
  console.log(`[admin-accounts] op=list count=${accounts.length} house=${houseAccount?.accountId ?? "none"}`);
15547
- const resolve42 = async (a) => {
15671
+ const resolve43 = async (a) => {
15548
15672
  const businessName = await fetchAccountName(a.accountId) || void 0;
15549
15673
  return { accountId: a.accountId, businessName, role: operatorRoleFor(a.config, userId), isHouse: a.config.role === "house" };
15550
15674
  };
15551
15675
  const houseOptions = await Promise.all(
15552
- accounts.filter((a) => a.config.role === "house").map(resolve42)
15676
+ accounts.filter((a) => a.config.role === "house").map(resolve43)
15553
15677
  );
15554
15678
  const nonHouseOptions = await Promise.all(
15555
- accounts.filter((a) => a.config.role !== "house").map(resolve42)
15679
+ accounts.filter((a) => a.config.role !== "house").map(resolve43)
15556
15680
  );
15557
15681
  const sortKey = (o) => (o.businessName || o.accountId).toLowerCase();
15558
15682
  nonHouseOptions.sort((x, y) => {
@@ -23746,8 +23870,163 @@ app47.patch("/:eventId", requireAdminSession, async (c) => {
23746
23870
  await session.close();
23747
23871
  }
23748
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
+ });
23749
23901
  var routines_default = app47;
23750
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
+
23751
24030
  // app/lib/time-entry-format.ts
23752
24031
  function secondsBetween(startIso, endIso) {
23753
24032
  const s = Date.parse(startIso);
@@ -23769,8 +24048,8 @@ function toNum(v) {
23769
24048
  var TAG39 = "[task-timer]";
23770
24049
  var COMPLETED = /* @__PURE__ */ new Set(["completed"]);
23771
24050
  var HIDDEN_FROM_OPEN = /* @__PURE__ */ new Set(["completed", "cancelled"]);
23772
- var app48 = new Hono();
23773
- app48.get("/", requireAdminSession, async (c) => {
24051
+ var app49 = new Hono();
24052
+ app49.get("/", requireAdminSession, async (c) => {
23774
24053
  const cacheKey = c.var.cacheKey;
23775
24054
  const accountId = getAccountIdForSession(cacheKey);
23776
24055
  if (!accountId) {
@@ -23857,13 +24136,13 @@ app48.get("/", requireAdminSession, async (c) => {
23857
24136
  await session.close();
23858
24137
  }
23859
24138
  });
23860
- var tasks_list_default = app48;
24139
+ var tasks_list_default = app49;
23861
24140
 
23862
24141
  // server/routes/admin/task-timer-start.ts
23863
24142
  import { randomUUID as randomUUID14 } from "crypto";
23864
24143
  var TAG40 = "[task-timer]";
23865
- var app49 = new Hono();
23866
- app49.post("/", requireAdminSession, async (c) => {
24144
+ var app50 = new Hono();
24145
+ app50.post("/", requireAdminSession, async (c) => {
23867
24146
  const cacheKey = c.var.cacheKey;
23868
24147
  const accountId = getAccountIdForSession(cacheKey);
23869
24148
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -23918,13 +24197,13 @@ app49.post("/", requireAdminSession, async (c) => {
23918
24197
  await session.close();
23919
24198
  }
23920
24199
  });
23921
- var task_timer_start_default = app49;
24200
+ var task_timer_start_default = app50;
23922
24201
 
23923
24202
  // server/routes/admin/task-timer-stop.ts
23924
24203
  import neo4j5 from "neo4j-driver";
23925
24204
  var TAG41 = "[task-timer]";
23926
- var app50 = new Hono();
23927
- app50.post("/", requireAdminSession, async (c) => {
24205
+ var app51 = new Hono();
24206
+ app51.post("/", requireAdminSession, async (c) => {
23928
24207
  const cacheKey = c.var.cacheKey;
23929
24208
  const accountId = getAccountIdForSession(cacheKey);
23930
24209
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -23991,12 +24270,12 @@ app50.post("/", requireAdminSession, async (c) => {
23991
24270
  await session.close();
23992
24271
  }
23993
24272
  });
23994
- var task_timer_stop_default = app50;
24273
+ var task_timer_stop_default = app51;
23995
24274
 
23996
24275
  // server/routes/admin/task-complete.ts
23997
24276
  var TAG42 = "[task-timer]";
23998
- var app51 = new Hono();
23999
- app51.post("/", requireAdminSession, async (c) => {
24277
+ var app52 = new Hono();
24278
+ app52.post("/", requireAdminSession, async (c) => {
24000
24279
  const cacheKey = c.var.cacheKey;
24001
24280
  const accountId = getAccountIdForSession(cacheKey);
24002
24281
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -24034,14 +24313,14 @@ app51.post("/", requireAdminSession, async (c) => {
24034
24313
  await session.close();
24035
24314
  }
24036
24315
  });
24037
- var task_complete_default = app51;
24316
+ var task_complete_default = app52;
24038
24317
 
24039
24318
  // server/routes/admin/task-time-adjust.ts
24040
24319
  import { randomUUID as randomUUID15 } from "crypto";
24041
24320
  import neo4j6 from "neo4j-driver";
24042
24321
  var TAG43 = "[task-time-adjust]";
24043
- var app52 = new Hono();
24044
- app52.post("/", requireAdminSession, async (c) => {
24322
+ var app53 = new Hono();
24323
+ app53.post("/", requireAdminSession, async (c) => {
24045
24324
  const cacheKey = c.var.cacheKey;
24046
24325
  const accountId = getAccountIdForSession(cacheKey);
24047
24326
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -24115,11 +24394,11 @@ app52.post("/", requireAdminSession, async (c) => {
24115
24394
  await session.close();
24116
24395
  }
24117
24396
  });
24118
- var task_time_adjust_default = app52;
24397
+ var task_time_adjust_default = app53;
24119
24398
 
24120
24399
  // server/routes/admin/activity.ts
24121
- import { readdirSync as readdirSync24 } from "fs";
24122
- var app53 = new Hono();
24400
+ import { readdirSync as readdirSync25 } from "fs";
24401
+ var app54 = new Hono();
24123
24402
  var TAG44 = "[activity]";
24124
24403
  function resolveHouseAccountId(accounts) {
24125
24404
  const houses = accounts.filter((a) => a.config.role === "house");
@@ -24134,14 +24413,14 @@ function requestToken() {
24134
24413
  var short = (id) => id ? id.slice(0, 8) : "unset";
24135
24414
  function countAccountDirsOnDisk() {
24136
24415
  try {
24137
- return readdirSync24(ACCOUNTS_DIR, { withFileTypes: true }).filter(
24416
+ return readdirSync25(ACCOUNTS_DIR, { withFileTypes: true }).filter(
24138
24417
  (e) => e.isDirectory() && !e.name.startsWith(".")
24139
24418
  ).length;
24140
24419
  } catch {
24141
24420
  return null;
24142
24421
  }
24143
24422
  }
24144
- app53.get("/", requireAdminSession, async (c) => {
24423
+ app54.get("/", requireAdminSession, async (c) => {
24145
24424
  const req = requestToken();
24146
24425
  const cacheKey = c.var.cacheKey;
24147
24426
  const caller2 = getAccountIdForSession(cacheKey) ?? null;
@@ -24250,61 +24529,62 @@ app53.get("/", requireAdminSession, async (c) => {
24250
24529
  }
24251
24530
  });
24252
24531
  });
24253
- var activity_default = app53;
24532
+ var activity_default = app54;
24254
24533
 
24255
24534
  // server/routes/admin/index.ts
24256
- var app54 = new Hono();
24257
- app54.route("/session", session_default);
24258
- app54.route("/accounts", accounts_default);
24259
- app54.route("/logs", logs_default);
24260
- app54.route("/claude-info", claude_info_default);
24261
- app54.route("/attachment", attachment_default);
24262
- app54.route("/agents", agents_default);
24263
- app54.route("/sessions", sessions_default);
24264
- app54.route("/claude-sessions", claude_sessions_default);
24265
- app54.route("/log-ingest", log_ingest_default);
24266
- app54.route("/events", events_default);
24267
- app54.route("/files", files_default);
24268
- app54.route("/graph-search", graph_search_default);
24269
- app54.route("/graph-subgraph", graph_subgraph_default);
24270
- app54.route("/graph-delete", graph_delete_default);
24271
- app54.route("/graph-restore", graph_restore_default);
24272
- app54.route("/graph-labels-in-graph", graph_labels_in_graph_default);
24273
- app54.route("/graph-default-view", graph_default_view_default);
24274
- app54.route("/sidebar-artefacts", sidebar_artefacts_default);
24275
- app54.route("/sidebar-sessions", sidebar_sessions_default);
24276
- app54.route("/session-delete", session_delete_default);
24277
- app54.route("/session-stop", session_stop_default);
24278
- app54.route("/session-archive", session_archive_default);
24279
- app54.route("/session-rename", session_rename_default);
24280
- app54.route("/session-usage", session_usage_default);
24281
- app54.route("/browser", browser_default);
24282
- app54.route("/session-rc-spawn", session_rc_spawn_default);
24283
- app54.route("/session-reseat", session_reseat_default);
24284
- app54.route("/system-stats", system_stats_default);
24285
- app54.route("/health-brand", health_default2);
24286
- app54.route("/linkedin-ingest", linkedin_ingest_default);
24287
- app54.route("/post-turn-context", post_turn_context_default);
24288
- app54.route("/public-session-context", public_session_context_default);
24289
- app54.route("/public-session-exit", public_session_exit_default);
24290
- app54.route("/access-session-evict", access_session_evict_default);
24291
- app54.route("/enrol-person", enrol_person_default);
24292
- app54.route("/calendar", calendar_default);
24293
- app54.route("/routines", routines_default);
24294
- app54.route("/tasks-list", tasks_list_default);
24295
- app54.route("/task-timer-start", task_timer_start_default);
24296
- app54.route("/task-timer-stop", task_timer_stop_default);
24297
- app54.route("/task-complete", task_complete_default);
24298
- app54.route("/task-time-adjust", task_time_adjust_default);
24299
- app54.route("/activity", activity_default);
24300
- 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;
24301
24581
 
24302
24582
  // server/routes/access/verify-token.ts
24303
24583
  var TAG45 = "[access-verify]";
24304
24584
  var MINT_TAG = "[access-session-mint]";
24305
24585
  var COOKIE_NAME = "__access_session";
24306
- var app55 = new Hono();
24307
- app55.post("/", async (c) => {
24586
+ var app56 = new Hono();
24587
+ app56.post("/", async (c) => {
24308
24588
  const ip = c.var.clientIp || "unknown";
24309
24589
  let body;
24310
24590
  try {
@@ -24386,13 +24666,13 @@ app55.post("/", async (c) => {
24386
24666
  displayName: grant.displayName
24387
24667
  });
24388
24668
  });
24389
- var verify_token_default = app55;
24669
+ var verify_token_default = app56;
24390
24670
 
24391
24671
  // app/lib/access-email.ts
24392
24672
  import { spawn as spawn2 } from "child_process";
24393
- import { resolve as resolve31 } from "path";
24394
- var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve31(process.cwd(), "..");
24395
- 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(
24396
24676
  PLATFORM_ROOT7,
24397
24677
  "plugins",
24398
24678
  "email",
@@ -24449,9 +24729,9 @@ async function sendMagicLinkEmail(payload) {
24449
24729
 
24450
24730
  // server/routes/access/request-magic-link.ts
24451
24731
  var TAG46 = "[access-request-link]";
24452
- var app56 = new Hono();
24732
+ var app57 = new Hono();
24453
24733
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
24454
- app56.post("/", async (c) => {
24734
+ app57.post("/", async (c) => {
24455
24735
  let body;
24456
24736
  try {
24457
24737
  body = await c.req.json();
@@ -24525,17 +24805,17 @@ app56.post("/", async (c) => {
24525
24805
  );
24526
24806
  return c.json({ message: VISITOR_MESSAGE }, 200);
24527
24807
  });
24528
- var request_magic_link_default = app56;
24808
+ var request_magic_link_default = app57;
24529
24809
 
24530
24810
  // server/routes/access/index.ts
24531
- var app57 = new Hono();
24532
- app57.route("/verify-token", verify_token_default);
24533
- app57.route("/request-magic-link", request_magic_link_default);
24534
- 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;
24535
24815
 
24536
24816
  // server/routes/sites.ts
24537
- import { existsSync as existsSync36, readFileSync as readFileSync39, realpathSync as realpathSync7, statSync as statSync14 } from "fs";
24538
- 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";
24539
24819
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
24540
24820
  var MIME = {
24541
24821
  ".html": "text/html; charset=utf-8",
@@ -24566,8 +24846,8 @@ function getExt(p) {
24566
24846
  if (idx < p.lastIndexOf("/")) return "";
24567
24847
  return p.slice(idx).toLowerCase();
24568
24848
  }
24569
- var app58 = new Hono();
24570
- app58.get("/:rel{.*}", (c) => {
24849
+ var app59 = new Hono();
24850
+ app59.get("/:rel{.*}", (c) => {
24571
24851
  const reqPath = c.req.path;
24572
24852
  const rawRel = c.req.param("rel") ?? "";
24573
24853
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -24592,15 +24872,15 @@ app58.get("/:rel{.*}", (c) => {
24592
24872
  }
24593
24873
  segments.push(seg);
24594
24874
  }
24595
- const rootDir = resolve32(account.accountDir, "sites");
24596
- 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);
24597
24877
  if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
24598
24878
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
24599
24879
  return c.text("Forbidden", 403);
24600
24880
  }
24601
24881
  let stat11;
24602
24882
  try {
24603
- stat11 = existsSync36(filePath) ? statSync14(filePath) : null;
24883
+ stat11 = existsSync37(filePath) ? statSync15(filePath) : null;
24604
24884
  } catch {
24605
24885
  stat11 = null;
24606
24886
  }
@@ -24613,13 +24893,13 @@ app58.get("/:rel{.*}", (c) => {
24613
24893
  return c.redirect(target, 301);
24614
24894
  }
24615
24895
  if (stat11?.isDirectory()) {
24616
- filePath = resolve32(filePath, "index.html");
24896
+ filePath = resolve33(filePath, "index.html");
24617
24897
  }
24618
24898
  if (!filePath.startsWith(rootDir + "/")) {
24619
24899
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
24620
24900
  return c.text("Forbidden", 403);
24621
24901
  }
24622
- if (!existsSync36(filePath)) {
24902
+ if (!existsSync37(filePath)) {
24623
24903
  console.error(`[sites] not-found path=${reqPath} status=404`);
24624
24904
  return c.text("Not found", 404);
24625
24905
  }
@@ -24638,7 +24918,7 @@ app58.get("/:rel{.*}", (c) => {
24638
24918
  }
24639
24919
  let body;
24640
24920
  try {
24641
- body = readFileSync39(realPath);
24921
+ body = readFileSync40(realPath);
24642
24922
  } catch (err) {
24643
24923
  const code = err?.code;
24644
24924
  if (code === "EISDIR") {
@@ -24670,11 +24950,11 @@ app58.get("/:rel{.*}", (c) => {
24670
24950
  "X-Content-Type-Options": "nosniff"
24671
24951
  });
24672
24952
  });
24673
- var sites_default = app58;
24953
+ var sites_default = app59;
24674
24954
 
24675
24955
  // app/lib/visitor-token.ts
24676
24956
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
24677
- 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";
24678
24958
  import { dirname as dirname13 } from "path";
24679
24959
  var TOKEN_PREFIX = "v1.";
24680
24960
  var SECRET_BYTES = 32;
@@ -24683,7 +24963,7 @@ var cachedSecret = null;
24683
24963
  function getSecret() {
24684
24964
  if (cachedSecret) return cachedSecret;
24685
24965
  try {
24686
- const hex2 = readFileSync40(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
24966
+ const hex2 = readFileSync41(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
24687
24967
  if (hex2.length === SECRET_BYTES * 2) {
24688
24968
  cachedSecret = Buffer.from(hex2, "hex");
24689
24969
  return cachedSecret;
@@ -24697,7 +24977,7 @@ function getSecret() {
24697
24977
  console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
24698
24978
  } catch {
24699
24979
  }
24700
- const hex = readFileSync40(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
24980
+ const hex = readFileSync41(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
24701
24981
  cachedSecret = Buffer.from(hex, "hex");
24702
24982
  return cachedSecret;
24703
24983
  }
@@ -24750,7 +25030,7 @@ var VISITOR_COOKIE_NAME = "mxy_v";
24750
25030
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
24751
25031
 
24752
25032
  // app/lib/brand-config.ts
24753
- import { existsSync as existsSync37, readFileSync as readFileSync41 } from "fs";
25033
+ import { existsSync as existsSync38, readFileSync as readFileSync42 } from "fs";
24754
25034
  import { join as join43 } from "path";
24755
25035
  var cached2 = null;
24756
25036
  var cachedAttempted = false;
@@ -24760,9 +25040,9 @@ function readBrandConfig() {
24760
25040
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
24761
25041
  if (!platformRoot5) return null;
24762
25042
  const brandPath = join43(platformRoot5, "config", "brand.json");
24763
- if (!existsSync37(brandPath)) return null;
25043
+ if (!existsSync38(brandPath)) return null;
24764
25044
  try {
24765
- cached2 = JSON.parse(readFileSync41(brandPath, "utf-8"));
25045
+ cached2 = JSON.parse(readFileSync42(brandPath, "utf-8"));
24766
25046
  return cached2;
24767
25047
  } catch {
24768
25048
  return null;
@@ -24770,7 +25050,7 @@ function readBrandConfig() {
24770
25050
  }
24771
25051
 
24772
25052
  // server/routes/visitor-consent.ts
24773
- var app59 = new Hono();
25053
+ var app60 = new Hono();
24774
25054
  var CONSENT_COOKIE_NAME = "mxy_consent";
24775
25055
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
24776
25056
  var DEFAULT_CONSENT_COPY = {
@@ -24815,17 +25095,17 @@ function siteSlugFromReferer(referer) {
24815
25095
  return "";
24816
25096
  }
24817
25097
  }
24818
- app59.options("/consent", (c) => {
25098
+ app60.options("/consent", (c) => {
24819
25099
  const origin = getOrigin(c);
24820
25100
  setCorsHeaders(c, origin);
24821
25101
  return c.body(null, 204);
24822
25102
  });
24823
- app59.options("/brand-config", (c) => {
25103
+ app60.options("/brand-config", (c) => {
24824
25104
  const origin = getOrigin(c);
24825
25105
  setCorsHeaders(c, origin);
24826
25106
  return c.body(null, 204);
24827
25107
  });
24828
- app59.post("/consent", async (c) => {
25108
+ app60.post("/consent", async (c) => {
24829
25109
  const origin = getOrigin(c);
24830
25110
  setCorsHeaders(c, origin);
24831
25111
  let raw;
@@ -24865,7 +25145,7 @@ app59.post("/consent", async (c) => {
24865
25145
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
24866
25146
  return c.body(null, 204);
24867
25147
  });
24868
- app59.get("/brand-config", (c) => {
25148
+ app60.get("/brand-config", (c) => {
24869
25149
  const origin = getOrigin(c);
24870
25150
  setCorsHeaders(c, origin);
24871
25151
  const brand = readBrandConfig();
@@ -24875,7 +25155,7 @@ app59.get("/brand-config", (c) => {
24875
25155
  c.header("Cache-Control", "public, max-age=300");
24876
25156
  return c.json({ consent: { copy, palette } });
24877
25157
  });
24878
- var visitor_consent_default = app59;
25158
+ var visitor_consent_default = app60;
24879
25159
 
24880
25160
  // server/routes/listings.ts
24881
25161
  function getCookie(headerValue, name) {
@@ -24902,8 +25182,8 @@ function appendConsentParams(pageUrl, token) {
24902
25182
  }
24903
25183
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
24904
25184
  var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
24905
- var app60 = new Hono();
24906
- app60.get("/:slug/click", async (c) => {
25185
+ var app61 = new Hono();
25186
+ app61.get("/:slug/click", async (c) => {
24907
25187
  const slug = c.req.param("slug") ?? "";
24908
25188
  const rawSession = c.req.query("session") ?? "";
24909
25189
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -24967,10 +25247,10 @@ app60.get("/:slug/click", async (c) => {
24967
25247
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
24968
25248
  return c.redirect(redirectUrl, 302);
24969
25249
  });
24970
- var listings_default = app60;
25250
+ var listings_default = app61;
24971
25251
 
24972
25252
  // server/routes/visitor-event.ts
24973
- var app61 = new Hono();
25253
+ var app62 = new Hono();
24974
25254
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
24975
25255
  var buckets = /* @__PURE__ */ new Map();
24976
25256
  var RATE_LIMIT = 60;
@@ -25046,12 +25326,12 @@ function originAllowed(origin, allowlist) {
25046
25326
  return false;
25047
25327
  }
25048
25328
  }
25049
- app61.options("/event", (c) => {
25329
+ app62.options("/event", (c) => {
25050
25330
  const origin = getOrigin2(c);
25051
25331
  setCorsHeaders2(c, origin);
25052
25332
  return c.body(null, 204);
25053
25333
  });
25054
- app61.post("/event", async (c) => {
25334
+ app62.post("/event", async (c) => {
25055
25335
  const origin = getOrigin2(c);
25056
25336
  setCorsHeaders2(c, origin);
25057
25337
  const ua = c.req.header("user-agent") ?? "";
@@ -25256,17 +25536,17 @@ async function writeEvent(opts) {
25256
25536
  );
25257
25537
  }
25258
25538
  }
25259
- var visitor_event_default = app61;
25539
+ var visitor_event_default = app62;
25260
25540
 
25261
25541
  // server/routes/session.ts
25262
- import { resolve as resolve33 } from "path";
25263
- 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";
25264
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;
25265
25545
  function writeBrandingCache(accountId, agentSlug, branding) {
25266
25546
  try {
25267
- const cacheDir = resolve33(MAXY_DIR, "branding-cache", accountId);
25547
+ const cacheDir = resolve34(MAXY_DIR, "branding-cache", accountId);
25268
25548
  mkdirSync9(cacheDir, { recursive: true });
25269
- writeFileSync15(resolve33(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
25549
+ writeFileSync15(resolve34(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
25270
25550
  } catch (err) {
25271
25551
  console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
25272
25552
  }
@@ -25302,8 +25582,8 @@ function withVisitorCookie(response, visitorId) {
25302
25582
  headers
25303
25583
  });
25304
25584
  }
25305
- var app62 = new Hono();
25306
- app62.post("/", async (c) => {
25585
+ var app63 = new Hono();
25586
+ app63.post("/", async (c) => {
25307
25587
  let body;
25308
25588
  try {
25309
25589
  body = await c.req.json();
@@ -25343,8 +25623,8 @@ app62.post("/", async (c) => {
25343
25623
  }
25344
25624
  let agentConfig = null;
25345
25625
  if (account) {
25346
- const agentDir = resolve33(account.accountDir, "agents", agentSlug);
25347
- 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"))) {
25348
25628
  return c.json({ error: "Agent not found" }, 404);
25349
25629
  }
25350
25630
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -25450,7 +25730,7 @@ app62.post("/", async (c) => {
25450
25730
  newVisitorId
25451
25731
  );
25452
25732
  });
25453
- var session_default2 = app62;
25733
+ var session_default2 = app63;
25454
25734
 
25455
25735
  // server/lib/calendar-slots.ts
25456
25736
  var WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
@@ -25533,17 +25813,17 @@ function computeOpenSlots(config, busy, fromISO, toISO) {
25533
25813
  }
25534
25814
 
25535
25815
  // server/routes/calendar-public.ts
25536
- var app63 = new Hono();
25816
+ var app64 = new Hono();
25537
25817
  function setCors(c) {
25538
25818
  c.header("Access-Control-Allow-Origin", "*");
25539
25819
  c.header("Access-Control-Allow-Methods", "GET, OPTIONS");
25540
25820
  c.header("Access-Control-Allow-Headers", "content-type");
25541
25821
  }
25542
- app63.options("/free-busy", (c) => {
25822
+ app64.options("/free-busy", (c) => {
25543
25823
  setCors(c);
25544
25824
  return c.body(null, 204);
25545
25825
  });
25546
- app63.get("/free-busy", async (c) => {
25826
+ app64.get("/free-busy", async (c) => {
25547
25827
  setCors(c);
25548
25828
  const from = c.req.query("from");
25549
25829
  const to = c.req.query("to");
@@ -25599,14 +25879,14 @@ app63.get("/free-busy", async (c) => {
25599
25879
  await session.close();
25600
25880
  }
25601
25881
  });
25602
- var calendar_public_default = app63;
25882
+ var calendar_public_default = app64;
25603
25883
 
25604
25884
  // server/routes/portal-fetch.ts
25605
25885
  import { createReadStream as createReadStream3 } from "fs";
25606
25886
  import { stat as stat8, readFile as readFile8, realpath } from "fs/promises";
25607
- 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";
25608
25888
  import { Readable as Readable3 } from "stream";
25609
- var app64 = new Hono();
25889
+ var app65 = new Hono();
25610
25890
  var TAG47 = "[portal-fetch]";
25611
25891
  async function verifySignature(secret, accountId, relPath, expiresAtMs, signature, nowMs) {
25612
25892
  if (!secret || !signature) return false;
@@ -25657,7 +25937,7 @@ ${expiresAtMs}`)
25657
25937
  return diff === 0;
25658
25938
  }
25659
25939
  async function readAccountSecret(accountId) {
25660
- const path3 = resolve34(DATA_ROOT, "accounts", accountId, "secrets", "data-portal.env");
25940
+ const path3 = resolve35(DATA_ROOT, "accounts", accountId, "secrets", "data-portal.env");
25661
25941
  let text;
25662
25942
  try {
25663
25943
  text = await readFile8(path3, "utf8");
@@ -25693,7 +25973,7 @@ async function resolveFetchTarget(accountDir, relPath, ownerId) {
25693
25973
  const exposeFolders = await readExposeFolders2(accountDir);
25694
25974
  const { exposed } = resolveExposedDirs(schemaText, exposeFolders);
25695
25975
  if (exposed.length === 0 && !ownerId) return { ok: false, reason: "not-exposed" };
25696
- const lexical = resolve34(accountDir, relPath);
25976
+ const lexical = resolve35(accountDir, relPath);
25697
25977
  let root;
25698
25978
  let absolute;
25699
25979
  try {
@@ -25742,7 +26022,7 @@ async function handle(c, headOnly) {
25742
26022
  return c.json({ ok: false, error: "denied" }, 401);
25743
26023
  }
25744
26024
  const target = await resolveFetchTarget(
25745
- resolve34(DATA_ROOT, "accounts", accountId),
26025
+ resolve35(DATA_ROOT, "accounts", accountId),
25746
26026
  relPath,
25747
26027
  owner || void 0
25748
26028
  );
@@ -25769,9 +26049,9 @@ async function handle(c, headOnly) {
25769
26049
  }
25770
26050
  });
25771
26051
  }
25772
- app64.get("/fetch", (c) => handle(c, false));
25773
- app64.on("HEAD", "/fetch", (c) => handle(c, true));
25774
- 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;
25775
26055
 
25776
26056
  // app/lib/timeentry-census.ts
25777
26057
  var TAG48 = "[timeentry-census]";
@@ -25856,7 +26136,7 @@ function startTimeEntryCensus(openSession, opts = {}) {
25856
26136
  }
25857
26137
 
25858
26138
  // app/lib/ledger-census.ts
25859
- 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";
25860
26140
  import { join as join45 } from "path";
25861
26141
 
25862
26142
  // ../lib/ledger-core/dist/reconcile.js
@@ -25905,7 +26185,7 @@ var DAY_MS = 864e5;
25905
26185
  function countWriteRejects24h(logDir, now) {
25906
26186
  let entries;
25907
26187
  try {
25908
- 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"));
25909
26189
  } catch {
25910
26190
  return 0;
25911
26191
  }
@@ -25913,8 +26193,8 @@ function countWriteRejects24h(logDir, now) {
25913
26193
  for (const name of entries) {
25914
26194
  const path3 = join45(logDir, name);
25915
26195
  try {
25916
- if (now - statSync15(path3).mtimeMs > DAY_MS) continue;
25917
- 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")) {
25918
26198
  if (line.includes("[graph-write] reject")) total += 1;
25919
26199
  }
25920
26200
  } catch {
@@ -26183,7 +26463,7 @@ function startGraphHealthTimer() {
26183
26463
 
26184
26464
  // app/lib/file-watcher.ts
26185
26465
  import * as fsp2 from "fs/promises";
26186
- import { resolve as resolve35, sep as sep10 } from "path";
26466
+ import { resolve as resolve36, sep as sep10 } from "path";
26187
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;
26188
26468
  var DEFAULT_COALESCE_MS = 500;
26189
26469
  var ROOTS = ["accounts"];
@@ -26202,7 +26482,7 @@ async function startFileWatcher(opts = {}) {
26202
26482
  const dropFn = opts.drop ?? dropFileIndex;
26203
26483
  for (const r of ROOTS) {
26204
26484
  try {
26205
- await fsp2.mkdir(resolve35(dataRoot, r), { recursive: true });
26485
+ await fsp2.mkdir(resolve36(dataRoot, r), { recursive: true });
26206
26486
  } catch (err) {
26207
26487
  console.error(
26208
26488
  `[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
@@ -26223,7 +26503,7 @@ async function startFileWatcher(opts = {}) {
26223
26503
  timers.set(relativePath, t);
26224
26504
  }
26225
26505
  async function runHook(relativePath, accountId) {
26226
- const absolute = resolve35(dataRoot, relativePath);
26506
+ const absolute = resolve36(dataRoot, relativePath);
26227
26507
  let exists = false;
26228
26508
  try {
26229
26509
  const st = await fsp2.stat(absolute);
@@ -26247,7 +26527,7 @@ async function startFileWatcher(opts = {}) {
26247
26527
  }
26248
26528
  }
26249
26529
  async function watchRoot(rootName) {
26250
- const absRoot = resolve35(dataRoot, rootName);
26530
+ const absRoot = resolve36(dataRoot, rootName);
26251
26531
  try {
26252
26532
  const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
26253
26533
  for await (const event of iter) {
@@ -26286,7 +26566,7 @@ async function startFileWatcher(opts = {}) {
26286
26566
 
26287
26567
  // app/lib/migrate-uploads.ts
26288
26568
  import { mkdir as mkdir6, readdir as readdir6, rename as rename3, rm as rm3 } from "fs/promises";
26289
- 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";
26290
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;
26291
26571
  async function walkFiles(dir) {
26292
26572
  const out = [];
@@ -26297,7 +26577,7 @@ async function walkFiles(dir) {
26297
26577
  return out;
26298
26578
  }
26299
26579
  for (const e of entries) {
26300
- const abs = resolve36(dir, e.name);
26580
+ const abs = resolve37(dir, e.name);
26301
26581
  if (e.isDirectory()) {
26302
26582
  out.push(...await walkFiles(abs));
26303
26583
  } else if (e.isFile()) {
@@ -26317,7 +26597,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
26317
26597
  let moved = 0;
26318
26598
  for (const oldAbs of files) {
26319
26599
  const suffix = relative7(srcDir, oldAbs);
26320
- const newAbs = resolve36(destDir, suffix);
26600
+ const newAbs = resolve37(destDir, suffix);
26321
26601
  await mkdir6(dirname14(newAbs), { recursive: true });
26322
26602
  await rename3(oldAbs, newAbs);
26323
26603
  moved++;
@@ -26344,7 +26624,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
26344
26624
  }
26345
26625
  async function migrateUploads(opts = {}) {
26346
26626
  const dataRoot = opts.dataRoot ?? DATA_ROOT;
26347
- const oldRoot = resolve36(dataRoot, "uploads");
26627
+ const oldRoot = resolve37(dataRoot, "uploads");
26348
26628
  let topEntries;
26349
26629
  try {
26350
26630
  topEntries = await readdir6(oldRoot, { withFileTypes: true });
@@ -26365,8 +26645,8 @@ async function migrateUploads(opts = {}) {
26365
26645
  const name = entry.name;
26366
26646
  if (ACCOUNT_UUID_RE5.test(name)) {
26367
26647
  moved += await relocateTree(
26368
- resolve36(oldRoot, name),
26369
- resolve36(dataRoot, "accounts", name, "uploads"),
26648
+ resolve37(oldRoot, name),
26649
+ resolve37(dataRoot, "accounts", name, "uploads"),
26370
26650
  dataRoot,
26371
26651
  name,
26372
26652
  session
@@ -26378,8 +26658,8 @@ async function migrateUploads(opts = {}) {
26378
26658
  continue;
26379
26659
  }
26380
26660
  moved += await relocateTree(
26381
- resolve36(oldRoot, "public"),
26382
- resolve36(dataRoot, "accounts", installAccountId, "uploads", "public"),
26661
+ resolve37(oldRoot, "public"),
26662
+ resolve37(dataRoot, "accounts", installAccountId, "uploads", "public"),
26383
26663
  dataRoot,
26384
26664
  null,
26385
26665
  // public uploads carry no graph nodes
@@ -26409,7 +26689,7 @@ async function migrateUploads(opts = {}) {
26409
26689
 
26410
26690
  // app/lib/migrate-admin-webchat-sidecars.ts
26411
26691
  import { readdir as readdir7, readFile as readFile9, rename as rename4, writeFile as writeFile5, unlink as unlink4 } from "fs/promises";
26412
- import { existsSync as existsSync39 } from "fs";
26692
+ import { existsSync as existsSync40 } from "fs";
26413
26693
  import { join as join46 } from "path";
26414
26694
  var ADMIN_ROLE2 = "admin";
26415
26695
  var WEBCHAT_CHANNEL2 = "webchat";
@@ -26439,7 +26719,7 @@ async function writeRaw(path3, obj) {
26439
26719
  await rename4(tmp, path3);
26440
26720
  } catch (err) {
26441
26721
  try {
26442
- if (existsSync39(tmp)) await unlink4(tmp);
26722
+ if (existsSync40(tmp)) await unlink4(tmp);
26443
26723
  } catch {
26444
26724
  }
26445
26725
  throw err;
@@ -26828,8 +27108,8 @@ var streamSSE = (c, cb, onError) => {
26828
27108
 
26829
27109
  // app/lib/whatsapp/gateway/routes.ts
26830
27110
  function createWaChannelRoutes(deps) {
26831
- const app66 = new Hono();
26832
- app66.get("/wa-channel/inbound", (c) => {
27111
+ const app67 = new Hono();
27112
+ app67.get("/wa-channel/inbound", (c) => {
26833
27113
  const senderId = c.req.query("senderId");
26834
27114
  if (!senderId) return c.json({ error: "senderId required" }, 400);
26835
27115
  return streamSSE(c, async (stream2) => {
@@ -26847,7 +27127,7 @@ function createWaChannelRoutes(deps) {
26847
27127
  }
26848
27128
  });
26849
27129
  });
26850
- app66.post("/wa-channel/reply", async (c) => {
27130
+ app67.post("/wa-channel/reply", async (c) => {
26851
27131
  const body = await c.req.json().catch(() => null);
26852
27132
  const senderId = body?.senderId;
26853
27133
  const text = body?.text;
@@ -26868,7 +27148,7 @@ function createWaChannelRoutes(deps) {
26868
27148
  console.error(`[whatsapp-native] op=reply-dispatch senderId=${senderId} bytes=${bytes}`);
26869
27149
  return c.json({ ok: true });
26870
27150
  });
26871
- app66.post("/wa-channel/reply-document", async (c) => {
27151
+ app67.post("/wa-channel/reply-document", async (c) => {
26872
27152
  const body = await c.req.json().catch(() => null);
26873
27153
  const senderId = body?.senderId;
26874
27154
  const files = body?.files;
@@ -26907,7 +27187,7 @@ function createWaChannelRoutes(deps) {
26907
27187
  }
26908
27188
  return c.json({ ok: true, results });
26909
27189
  });
26910
- app66.post("/wa-channel/ready", async (c) => {
27190
+ app67.post("/wa-channel/ready", async (c) => {
26911
27191
  const body = await c.req.json().catch(() => null);
26912
27192
  const senderId = body?.senderId;
26913
27193
  if (typeof senderId !== "string") {
@@ -26916,7 +27196,7 @@ function createWaChannelRoutes(deps) {
26916
27196
  deps.onReady?.(senderId);
26917
27197
  return c.json({ ok: true });
26918
27198
  });
26919
- app66.post("/wa-channel/received", async (c) => {
27199
+ app67.post("/wa-channel/received", async (c) => {
26920
27200
  const body = await c.req.json().catch(() => null);
26921
27201
  const senderId = body?.senderId;
26922
27202
  const waMessageId = body?.waMessageId;
@@ -26926,7 +27206,7 @@ function createWaChannelRoutes(deps) {
26926
27206
  deps.onReceived?.(senderId, waMessageId);
26927
27207
  return c.json({ ok: true });
26928
27208
  });
26929
- app66.post("/wa-channel/turn-end", async (c) => {
27209
+ app67.post("/wa-channel/turn-end", async (c) => {
26930
27210
  const body = await c.req.json().catch(() => null);
26931
27211
  const senderId = body?.senderId;
26932
27212
  const sessionId = body?.sessionId;
@@ -26937,7 +27217,7 @@ function createWaChannelRoutes(deps) {
26937
27217
  const interactive = body?.interactive === true;
26938
27218
  const finalText = typeof body?.finalText === "string" ? body.finalText : "";
26939
27219
  const sid = sessionId.slice(0, 8);
26940
- const deliver = interactive && finalText.trim().length > 0;
27220
+ const deliver = interactive && !replied && finalText.trim().length > 0;
26941
27221
  if (deliver) {
26942
27222
  const bytes = Buffer.byteLength(finalText, "utf8");
26943
27223
  try {
@@ -26959,7 +27239,7 @@ function createWaChannelRoutes(deps) {
26959
27239
  console.error(`[whatsapp-native] op=turn-end sessionId=${sid} replied=no delivered=none`);
26960
27240
  return c.json({ ok: true, delivered: "none" });
26961
27241
  });
26962
- return app66;
27242
+ return app67;
26963
27243
  }
26964
27244
 
26965
27245
  // app/lib/whatsapp/gateway/wa-gateway.ts
@@ -27374,8 +27654,8 @@ var InboundHub2 = class {
27374
27654
 
27375
27655
  // app/lib/webchat/gateway/routes.ts
27376
27656
  function createWebchatChannelRoutes(deps) {
27377
- const app66 = new Hono();
27378
- app66.get("/webchat-channel/inbound", (c) => {
27657
+ const app67 = new Hono();
27658
+ app67.get("/webchat-channel/inbound", (c) => {
27379
27659
  const key = c.req.query("key");
27380
27660
  if (!key) return c.json({ error: "key required" }, 400);
27381
27661
  return streamSSE(c, async (stream2) => {
@@ -27393,7 +27673,7 @@ function createWebchatChannelRoutes(deps) {
27393
27673
  }
27394
27674
  });
27395
27675
  });
27396
- app66.post("/webchat-channel/reply", async (c) => {
27676
+ app67.post("/webchat-channel/reply", async (c) => {
27397
27677
  const body = await c.req.json().catch(() => null);
27398
27678
  const key = body?.key;
27399
27679
  const text = body?.text;
@@ -27403,7 +27683,7 @@ function createWebchatChannelRoutes(deps) {
27403
27683
  deps.onReply?.(key, text);
27404
27684
  return c.json({ ok: true });
27405
27685
  });
27406
- app66.post("/webchat-channel/connector-auth", async (c) => {
27686
+ app67.post("/webchat-channel/connector-auth", async (c) => {
27407
27687
  const body = await c.req.json().catch(() => null);
27408
27688
  const key = body?.key;
27409
27689
  const sessionId = body?.sessionId;
@@ -27416,7 +27696,7 @@ function createWebchatChannelRoutes(deps) {
27416
27696
  const result = await deps.onConnectorAuth({ key, sessionId, name, completed });
27417
27697
  return c.json(result);
27418
27698
  });
27419
- app66.post("/webchat-channel/ready", async (c) => {
27699
+ app67.post("/webchat-channel/ready", async (c) => {
27420
27700
  const body = await c.req.json().catch(() => null);
27421
27701
  const key = body?.key;
27422
27702
  if (typeof key !== "string") {
@@ -27425,7 +27705,7 @@ function createWebchatChannelRoutes(deps) {
27425
27705
  deps.onReady?.(key);
27426
27706
  return c.json({ ok: true });
27427
27707
  });
27428
- app66.post("/webchat-channel/permission-request", async (c) => {
27708
+ app67.post("/webchat-channel/permission-request", async (c) => {
27429
27709
  const body = await c.req.json().catch(() => null);
27430
27710
  const key = body?.key;
27431
27711
  const requestId = body?.request_id;
@@ -27439,7 +27719,7 @@ function createWebchatChannelRoutes(deps) {
27439
27719
  const verdict = await deps.awaitPermissionVerdict({ key, requestId, toolName, description, inputPreview });
27440
27720
  return c.json(verdict);
27441
27721
  });
27442
- app66.post("/webchat-channel/received", async (c) => {
27722
+ app67.post("/webchat-channel/received", async (c) => {
27443
27723
  const body = await c.req.json().catch(() => null);
27444
27724
  const key = body?.key;
27445
27725
  const messageId = body?.messageId;
@@ -27449,7 +27729,7 @@ function createWebchatChannelRoutes(deps) {
27449
27729
  deps.onReceived?.(key, messageId);
27450
27730
  return c.json({ ok: true });
27451
27731
  });
27452
- app66.post("/webchat-channel/turn-end", async (c) => {
27732
+ app67.post("/webchat-channel/turn-end", async (c) => {
27453
27733
  const body = await c.req.json().catch(() => null);
27454
27734
  const key = body?.key;
27455
27735
  const sessionId = body?.sessionId;
@@ -27457,22 +27737,13 @@ function createWebchatChannelRoutes(deps) {
27457
27737
  if (typeof key !== "string" || typeof sessionId !== "string" || typeof replied !== "boolean") {
27458
27738
  return c.json({ error: "key, sessionId and replied required" }, 400);
27459
27739
  }
27460
- const interactive = body?.interactive === true;
27461
27740
  const finalBytes = typeof body?.finalBytes === "number" && Number.isFinite(body.finalBytes) ? body.finalBytes : 0;
27462
27741
  const k = key.slice(0, 8);
27463
27742
  const sid = sessionId.slice(0, 8);
27464
- if (replied) {
27465
- console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=yes delivered=reply bytes=${finalBytes}`);
27466
- return c.json({ ok: true, delivered: "reply" });
27467
- }
27468
- if (interactive && finalBytes > 0) {
27469
- console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=no delivered=fallback bytes=${finalBytes}`);
27470
- return c.json({ ok: true, delivered: "fallback" });
27471
- }
27472
- console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=no delivered=none`);
27473
- 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 });
27474
27745
  });
27475
- return app66;
27746
+ return app67;
27476
27747
  }
27477
27748
 
27478
27749
  // app/lib/webchat/gateway/webchat-gateway.ts
@@ -27530,16 +27801,16 @@ var WebchatGateway = class _WebchatGateway {
27530
27801
  * The public /api/chat route awaits this to return the reply on the same SSE
27531
27802
  * response, preserving the pre-756 POST→single-blob browser contract. */
27532
27803
  awaitReply(key, timeoutMs) {
27533
- return new Promise((resolve42) => {
27804
+ return new Promise((resolve43) => {
27534
27805
  const timer = setTimeout(() => {
27535
27806
  this.replyAwaiters.delete(key);
27536
- resolve42({ timeout: true });
27807
+ resolve43({ timeout: true });
27537
27808
  }, timeoutMs);
27538
27809
  if (timer.unref) timer.unref();
27539
27810
  this.replyAwaiters.set(key, (r) => {
27540
27811
  clearTimeout(timer);
27541
27812
  this.replyAwaiters.delete(key);
27542
- resolve42(r);
27813
+ resolve43(r);
27543
27814
  });
27544
27815
  });
27545
27816
  }
@@ -27550,11 +27821,11 @@ var WebchatGateway = class _WebchatGateway {
27550
27821
  * terminal dialog stays answerable). */
27551
27822
  awaitPermissionVerdict(p, timeoutMs) {
27552
27823
  const k = _WebchatGateway.promptKey(p.key, p.requestId);
27553
- return new Promise((resolve42) => {
27824
+ return new Promise((resolve43) => {
27554
27825
  this.pendingPrompts.get(k)?.resolve({ timeout: true });
27555
27826
  const timer = setTimeout(() => {
27556
27827
  this.pendingPrompts.delete(k);
27557
- resolve42({ timeout: true });
27828
+ resolve43({ timeout: true });
27558
27829
  }, timeoutMs);
27559
27830
  if (timer.unref) timer.unref();
27560
27831
  this.pendingPrompts.set(k, {
@@ -27563,7 +27834,7 @@ var WebchatGateway = class _WebchatGateway {
27563
27834
  resolve: (r) => {
27564
27835
  clearTimeout(timer);
27565
27836
  this.pendingPrompts.delete(k);
27566
- resolve42(r);
27837
+ resolve43(r);
27567
27838
  }
27568
27839
  });
27569
27840
  console.error(`[webchat:perm] op=open key=${keyDisplay(p.key)} id=${p.requestId} tool=${p.toolName}`);
@@ -28128,7 +28399,7 @@ async function fanOut(subscribers, text, onError, tag) {
28128
28399
 
28129
28400
  // app/lib/webchat/file-delivery.ts
28130
28401
  import { realpathSync as realpathSync8 } from "fs";
28131
- import { resolve as resolve37 } from "path";
28402
+ import { resolve as resolve38 } from "path";
28132
28403
 
28133
28404
  // app/lib/channel-pty-bridge/file-delivery.ts
28134
28405
  var SEND_USER_FILE = "SendUserFile";
@@ -28229,7 +28500,7 @@ function makeWebchatSendFile(entry) {
28229
28500
  console.error(`${TAG51} file-delivery reject reason=no-account sender=${entry.senderId}`);
28230
28501
  return { ok: false, error: "no-account" };
28231
28502
  }
28232
- const accountDir = resolve37(platformRoot2(), "..", "data/accounts", entry.accountId);
28503
+ const accountDir = resolve38(platformRoot2(), "..", "data/accounts", entry.accountId);
28233
28504
  try {
28234
28505
  const resolved = realpathSync8(filePath);
28235
28506
  const accountResolved = realpathSync8(accountDir);
@@ -28556,8 +28827,8 @@ var InboundHub3 = class {
28556
28827
 
28557
28828
  // app/lib/telegram/gateway/routes.ts
28558
28829
  function createTelegramChannelRoutes(deps) {
28559
- const app66 = new Hono();
28560
- app66.get("/tg-channel/inbound", (c) => {
28830
+ const app67 = new Hono();
28831
+ app67.get("/tg-channel/inbound", (c) => {
28561
28832
  const key = c.req.query("key");
28562
28833
  if (!key) return c.json({ error: "key required" }, 400);
28563
28834
  return streamSSE(c, async (stream2) => {
@@ -28575,7 +28846,7 @@ function createTelegramChannelRoutes(deps) {
28575
28846
  }
28576
28847
  });
28577
28848
  });
28578
- app66.post("/tg-channel/reply", async (c) => {
28849
+ app67.post("/tg-channel/reply", async (c) => {
28579
28850
  const body = await c.req.json().catch(() => null);
28580
28851
  const key = body?.key;
28581
28852
  const text = body?.text;
@@ -28591,7 +28862,7 @@ function createTelegramChannelRoutes(deps) {
28591
28862
  console.error(`[telegram-native] op=reply key=${key} bytes=${Buffer.byteLength(text, "utf8")}`);
28592
28863
  return c.json({ ok: true });
28593
28864
  });
28594
- app66.post("/tg-channel/ready", async (c) => {
28865
+ app67.post("/tg-channel/ready", async (c) => {
28595
28866
  const body = await c.req.json().catch(() => null);
28596
28867
  const key = body?.key;
28597
28868
  if (typeof key !== "string") {
@@ -28600,7 +28871,7 @@ function createTelegramChannelRoutes(deps) {
28600
28871
  deps.onReady?.(key);
28601
28872
  return c.json({ ok: true });
28602
28873
  });
28603
- app66.post("/tg-channel/received", async (c) => {
28874
+ app67.post("/tg-channel/received", async (c) => {
28604
28875
  const body = await c.req.json().catch(() => null);
28605
28876
  const key = body?.key;
28606
28877
  const messageId = body?.messageId;
@@ -28610,7 +28881,7 @@ function createTelegramChannelRoutes(deps) {
28610
28881
  deps.onReceived?.(key, messageId);
28611
28882
  return c.json({ ok: true });
28612
28883
  });
28613
- app66.post("/tg-channel/turn-end", async (c) => {
28884
+ app67.post("/tg-channel/turn-end", async (c) => {
28614
28885
  const body = await c.req.json().catch(() => null);
28615
28886
  const key = body?.key;
28616
28887
  const sessionId = body?.sessionId;
@@ -28621,7 +28892,7 @@ function createTelegramChannelRoutes(deps) {
28621
28892
  const interactive = body?.interactive === true;
28622
28893
  const finalText = typeof body?.finalText === "string" ? body.finalText : "";
28623
28894
  const sid = sessionId.slice(0, 8);
28624
- const deliver = interactive && finalText.trim().length > 0;
28895
+ const deliver = interactive && !replied && finalText.trim().length > 0;
28625
28896
  if (deliver) {
28626
28897
  const bytes = Buffer.byteLength(finalText, "utf8");
28627
28898
  try {
@@ -28643,7 +28914,7 @@ function createTelegramChannelRoutes(deps) {
28643
28914
  console.error(`[telegram-native] op=turn-end key=${key} sessionId=${sid} replied=no delivered=none`);
28644
28915
  return c.json({ ok: true, delivered: "none" });
28645
28916
  });
28646
- return app66;
28917
+ return app67;
28647
28918
  }
28648
28919
 
28649
28920
  // app/lib/telegram/gateway/telegram-gateway.ts
@@ -28793,7 +29064,7 @@ function buildTelegramSpawnRequest(input) {
28793
29064
  // app/lib/telegram/outbound/send-document.ts
28794
29065
  import { realpathSync as realpathSync9 } from "fs";
28795
29066
  import { readFile as readFile10, stat as stat10 } from "fs/promises";
28796
- import { resolve as resolve38, basename as basename12 } from "path";
29067
+ import { resolve as resolve39, basename as basename12 } from "path";
28797
29068
  var TAG53 = "[telegram:outbound]";
28798
29069
  var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
28799
29070
  async function sendTelegramDocument(input) {
@@ -28804,7 +29075,7 @@ async function sendTelegramDocument(input) {
28804
29075
  if (!maxyAccountId || !platformRoot5) {
28805
29076
  return { ok: false, status: 400, error: "Cannot validate file path: missing account or platform context" };
28806
29077
  }
28807
- const accountDir = resolve38(platformRoot5, "..", "data/accounts", maxyAccountId);
29078
+ const accountDir = resolve39(platformRoot5, "..", "data/accounts", maxyAccountId);
28808
29079
  let accountResolved;
28809
29080
  try {
28810
29081
  accountResolved = realpathSync9(accountDir);
@@ -29196,14 +29467,14 @@ function warnOnChannelAdminBindingDrift() {
29196
29467
  }
29197
29468
 
29198
29469
  // server/lib/booking-site-accounts.ts
29199
- import { existsSync as existsSync40, readFileSync as readFileSync43 } from "fs";
29200
- import { resolve as resolve39 } from "path";
29470
+ import { existsSync as existsSync41, readFileSync as readFileSync44 } from "fs";
29471
+ import { resolve as resolve40 } from "path";
29201
29472
  function listBookingSiteAccounts(accounts) {
29202
29473
  return accounts.filter((a) => {
29203
- const availPath = resolve39(a.accountDir, "calendar-availability.json");
29204
- if (!existsSync40(availPath)) return false;
29474
+ const availPath = resolve40(a.accountDir, "calendar-availability.json");
29475
+ if (!existsSync41(availPath)) return false;
29205
29476
  try {
29206
- const cfg = JSON.parse(readFileSync43(availPath, "utf-8"));
29477
+ const cfg = JSON.parse(readFileSync44(availPath, "utf-8"));
29207
29478
  return typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
29208
29479
  } catch {
29209
29480
  return false;
@@ -29241,8 +29512,8 @@ function broadcastAdminShutdown(reason) {
29241
29512
 
29242
29513
  // ../lib/entitlement/src/index.ts
29243
29514
  import { createPublicKey, createHash as createHash6, verify as cryptoVerify } from "crypto";
29244
- import { existsSync as existsSync41, readFileSync as readFileSync44, statSync as statSync16 } from "fs";
29245
- 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";
29246
29517
 
29247
29518
  // ../lib/entitlement/src/canonicalize.ts
29248
29519
  function canonicalize(value) {
@@ -29277,7 +29548,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
29277
29548
  var GRACE_DAYS = 7;
29278
29549
  var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
29279
29550
  function pubkeyPath(brand) {
29280
- return resolve40(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
29551
+ return resolve41(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
29281
29552
  }
29282
29553
  var memo = null;
29283
29554
  function memoKey(mtimeMs, account) {
@@ -29289,11 +29560,11 @@ function resolveEntitlement(brand, account) {
29289
29560
  if (brand.commercialMode !== true) {
29290
29561
  return logResolved(implicitTrust(account), null);
29291
29562
  }
29292
- const entitlementPath = resolve40(brand.configDir, "entitlement.json");
29293
- if (!existsSync41(entitlementPath)) {
29563
+ const entitlementPath = resolve41(brand.configDir, "entitlement.json");
29564
+ if (!existsSync42(entitlementPath)) {
29294
29565
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
29295
29566
  }
29296
- const stat11 = statSync16(entitlementPath);
29567
+ const stat11 = statSync17(entitlementPath);
29297
29568
  const key = memoKey(stat11.mtimeMs, account);
29298
29569
  if (memo && memo.key === key) {
29299
29570
  return memo.result;
@@ -29305,7 +29576,7 @@ function resolveEntitlement(brand, account) {
29305
29576
  function verifyAndResolve(brand, entitlementPath, account) {
29306
29577
  let pubkeyPem;
29307
29578
  try {
29308
- pubkeyPem = readFileSync44(pubkeyPath(brand), "utf-8");
29579
+ pubkeyPem = readFileSync45(pubkeyPath(brand), "utf-8");
29309
29580
  } catch (err) {
29310
29581
  return logResolved(anonymousFallback("pubkey-missing"), {
29311
29582
  reason: "pubkey-missing"
@@ -29319,7 +29590,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
29319
29590
  }
29320
29591
  let envelope;
29321
29592
  try {
29322
- envelope = JSON.parse(readFileSync44(entitlementPath, "utf-8"));
29593
+ envelope = JSON.parse(readFileSync45(entitlementPath, "utf-8"));
29323
29594
  } catch {
29324
29595
  return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
29325
29596
  }
@@ -29483,12 +29754,12 @@ installMediaDownloadGuard();
29483
29754
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
29484
29755
  var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join47(PLATFORM_ROOT8, "config", "brand.json") : "";
29485
29756
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
29486
- if (BRAND_JSON_PATH && !existsSync42(BRAND_JSON_PATH)) {
29757
+ if (BRAND_JSON_PATH && !existsSync43(BRAND_JSON_PATH)) {
29487
29758
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
29488
29759
  }
29489
- if (BRAND_JSON_PATH && existsSync42(BRAND_JSON_PATH)) {
29760
+ if (BRAND_JSON_PATH && existsSync43(BRAND_JSON_PATH)) {
29490
29761
  try {
29491
- const parsed = JSON.parse(readFileSync45(BRAND_JSON_PATH, "utf-8"));
29762
+ const parsed = JSON.parse(readFileSync46(BRAND_JSON_PATH, "utf-8"));
29492
29763
  BRAND = { ...BRAND, ...parsed };
29493
29764
  } catch (err) {
29494
29765
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -29523,8 +29794,8 @@ var brandLoginOpts = {
29523
29794
  var ALIAS_DOMAINS_PATH = join47(homedir4(), BRAND.configDir, "alias-domains.json");
29524
29795
  function loadAliasDomains() {
29525
29796
  try {
29526
- if (!existsSync42(ALIAS_DOMAINS_PATH)) return null;
29527
- 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"));
29528
29799
  if (!Array.isArray(parsed)) {
29529
29800
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
29530
29801
  return null;
@@ -29548,7 +29819,7 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
29548
29819
  function isPublicHost(host) {
29549
29820
  return host.startsWith("public.") || aliasDomains.has(host);
29550
29821
  }
29551
- var app65 = new Hono();
29822
+ var app66 = new Hono();
29552
29823
  function resolveChannelOverride(accountId, channel, senderId) {
29553
29824
  try {
29554
29825
  const dir = listValidAccounts().find((a) => a.accountId === accountId)?.accountDir;
@@ -29597,7 +29868,7 @@ var waGateway = new WaGateway({
29597
29868
  fetchStandingRules: fetchAccountStandingRules,
29598
29869
  resolveSessionOverride: (accountId, senderId) => resolveChannelOverride(accountId, "whatsapp", senderId),
29599
29870
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
29600
- 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"),
29601
29872
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
29602
29873
  // path-validation scope) is the sender's effective SESSION account, resolved
29603
29874
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -29612,7 +29883,7 @@ var waGateway = new WaGateway({
29612
29883
  caption,
29613
29884
  accountId,
29614
29885
  maxyAccountId,
29615
- platformRoot: resolve41(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, ".."))
29886
+ platformRoot: resolve42(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, ".."))
29616
29887
  });
29617
29888
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
29618
29889
  },
@@ -29724,7 +29995,7 @@ var waGateway = new WaGateway({
29724
29995
  nativeFileFollowers.set(senderId, ac);
29725
29996
  }
29726
29997
  });
29727
- app65.route("/", waGateway.routes());
29998
+ app66.route("/", waGateway.routes());
29728
29999
  waGateway.startSweeper();
29729
30000
  function runDuplicateSenderAudit() {
29730
30001
  try {
@@ -29847,7 +30118,7 @@ var webchatGateway = new WebchatGateway({
29847
30118
  firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
29848
30119
  });
29849
30120
  setWebchatGateway(webchatGateway);
29850
- app65.route("/", webchatGateway.routes());
30121
+ app66.route("/", webchatGateway.routes());
29851
30122
  webchatGateway.startSweeper();
29852
30123
  webchatGateway.startPublicReaper();
29853
30124
  var telegramFileFollowers = /* @__PURE__ */ new Map();
@@ -29891,7 +30162,7 @@ var telegramGateway = new TelegramGateway({
29891
30162
  }
29892
30163
  });
29893
30164
  setTelegramGateway(telegramGateway);
29894
- app65.route("/", telegramGateway.routes());
30165
+ app66.route("/", telegramGateway.routes());
29895
30166
  telegramGateway.startSweeper();
29896
30167
  var chatRoutes = createChatRoutes({
29897
30168
  handleInbound: (input) => webchatGateway.handleInbound(input),
@@ -29925,19 +30196,19 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
29925
30196
  return managed.account;
29926
30197
  }
29927
30198
  });
29928
- app65.route("/api/channel/schedule-inject", scheduleInjectRoutes);
29929
- app65.use("*", clientIpMiddleware);
30199
+ app66.route("/api/channel/schedule-inject", scheduleInjectRoutes);
30200
+ app66.use("*", clientIpMiddleware);
29930
30201
  function allowsSameOriginFraming(path3) {
29931
30202
  return path3 === "/vnc-viewer.html" || path3.startsWith("/api/admin/attachment/") || path3.startsWith("/api/public-reader/attachment/") || path3 === "/api/admin/files/download";
29932
30203
  }
29933
- app65.use("*", async (c, next) => {
30204
+ app66.use("*", async (c, next) => {
29934
30205
  await next();
29935
30206
  c.header("X-Content-Type-Options", "nosniff");
29936
30207
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
29937
30208
  c.header("X-Frame-Options", allowsSameOriginFraming(c.req.path) ? "SAMEORIGIN" : "DENY");
29938
30209
  });
29939
30210
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
29940
- app65.use("*", async (c, next) => {
30211
+ app66.use("*", async (c, next) => {
29941
30212
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
29942
30213
  await next();
29943
30214
  return;
@@ -29955,7 +30226,7 @@ app65.use("*", async (c, next) => {
29955
30226
  });
29956
30227
  }
29957
30228
  });
29958
- app65.use("*", async (c, next) => {
30229
+ app66.use("*", async (c, next) => {
29959
30230
  const host = (c.req.header("host") ?? "").split(":")[0];
29960
30231
  if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
29961
30232
  await next();
@@ -29993,7 +30264,7 @@ function resolveRemoteAuthOpts(c) {
29993
30264
  return { ...brandLoginOpts, origin };
29994
30265
  }
29995
30266
  var MAX_LOGIN_BODY = 8 * 1024;
29996
- app65.post("/__remote-auth/login", async (c) => {
30267
+ app66.post("/__remote-auth/login", async (c) => {
29997
30268
  const client = clientFrom(c);
29998
30269
  const clientIp = client.ip || "unknown";
29999
30270
  if (!requestIsTlsTerminated(c)) {
@@ -30038,7 +30309,7 @@ app65.post("/__remote-auth/login", async (c) => {
30038
30309
  }
30039
30310
  });
30040
30311
  });
30041
- app65.get("/__remote-auth/logout", (c) => {
30312
+ app66.get("/__remote-auth/logout", (c) => {
30042
30313
  const client = clientFrom(c);
30043
30314
  const clientIp = client.ip || "unknown";
30044
30315
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -30051,7 +30322,7 @@ app65.get("/__remote-auth/logout", (c) => {
30051
30322
  }
30052
30323
  });
30053
30324
  });
30054
- app65.post("/__remote-auth/change-password", async (c) => {
30325
+ app66.post("/__remote-auth/change-password", async (c) => {
30055
30326
  const client = clientFrom(c);
30056
30327
  const clientIp = client.ip || "unknown";
30057
30328
  const rateLimited = checkRateLimit(client);
@@ -30110,13 +30381,13 @@ app65.post("/__remote-auth/change-password", async (c) => {
30110
30381
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Failed to save password", redirect }), 200);
30111
30382
  }
30112
30383
  });
30113
- app65.get("/__remote-auth/setup", (c) => {
30384
+ app66.get("/__remote-auth/setup", (c) => {
30114
30385
  if (isRemoteAuthConfigured()) {
30115
30386
  return c.redirect("/");
30116
30387
  }
30117
30388
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup" }), 200);
30118
30389
  });
30119
- app65.post("/__remote-auth/set-initial-password", async (c) => {
30390
+ app66.post("/__remote-auth/set-initial-password", async (c) => {
30120
30391
  if (isRemoteAuthConfigured()) {
30121
30392
  return c.redirect("/");
30122
30393
  }
@@ -30154,10 +30425,10 @@ app65.post("/__remote-auth/set-initial-password", async (c) => {
30154
30425
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
30155
30426
  }
30156
30427
  });
30157
- app65.get("/api/remote-auth/status", (c) => {
30428
+ app66.get("/api/remote-auth/status", (c) => {
30158
30429
  return c.json({ configured: isRemoteAuthConfigured() });
30159
30430
  });
30160
- app65.post("/api/remote-auth/set-password", async (c) => {
30431
+ app66.post("/api/remote-auth/set-password", async (c) => {
30161
30432
  let body;
30162
30433
  try {
30163
30434
  body = await c.req.json();
@@ -30196,10 +30467,10 @@ app65.post("/api/remote-auth/set-password", async (c) => {
30196
30467
  return c.json({ error: "Failed to save password" }, 500);
30197
30468
  }
30198
30469
  });
30199
- app65.route("/api/_client-error", client_error_default);
30470
+ app66.route("/api/_client-error", client_error_default);
30200
30471
  console.log("[client-error-route] mounted");
30201
30472
  var PWA_PUBLIC_PATHS = /* @__PURE__ */ new Set(["/sw.js", ...PWA_SURFACES.map((s) => s.manifestPath)]);
30202
- app65.use("*", async (c, next) => {
30473
+ app66.use("*", async (c, next) => {
30203
30474
  const host = (c.req.header("host") ?? "").split(":")[0];
30204
30475
  const path3 = c.req.path;
30205
30476
  if (path3 === "/favicon.ico" || path3.startsWith("/assets/") || path3.startsWith("/brand/") || // Public free/busy is read by the booking page (a separate Cloudflare Pages
@@ -30243,28 +30514,28 @@ app65.use("*", async (c, next) => {
30243
30514
  }
30244
30515
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), redirect: path3 }), 200);
30245
30516
  });
30246
- app65.route("/api/health", health_default);
30247
- app65.route("/api/chat", chatRoutes);
30248
- app65.route("/api/whatsapp", whatsapp_default);
30249
- app65.route("/api/storage", storage_broker_default);
30250
- app65.route("/api/whatsapp-reader", whatsapp_reader_default);
30251
- app65.route("/api/public-reader", public_reader_default);
30252
- 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({
30253
30524
  handleInbound: (input) => webchatGateway.handleInbound(input),
30254
30525
  // Task 940 — the permission relay's pointer read + verdict write.
30255
30526
  pendingPromptFor: (key) => webchatGateway.pendingPromptFor(key),
30256
30527
  deliveryFailureFor: (key) => webchatGateway.deliveryFailureFor(key),
30257
30528
  resolvePermissionVerdict: (key, requestId, behavior) => webchatGateway.resolvePermissionVerdict(key, requestId, behavior)
30258
30529
  }));
30259
- app65.route("/api/webchat/greeting", webchat_greeting_default);
30260
- app65.route("/api/telegram", telegram_default);
30261
- app65.route("/api/quickbooks", quickbooks_default);
30262
- app65.route("/api/onboarding", onboarding_default);
30263
- app65.route("/api/admin", admin_default);
30264
- app65.route("/api/access", access_default);
30265
- app65.route("/api/session", session_default2);
30266
- app65.route("/api/calendar", calendar_public_default);
30267
- 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);
30268
30539
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
30269
30540
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
30270
30541
  var IMAGE_MIME = {
@@ -30276,7 +30547,7 @@ var IMAGE_MIME = {
30276
30547
  ".svg": "image/svg+xml",
30277
30548
  ".ico": "image/x-icon"
30278
30549
  };
30279
- app65.get("/agent-assets/:slug/:filename", (c) => {
30550
+ app66.get("/agent-assets/:slug/:filename", (c) => {
30280
30551
  const slug = c.req.param("slug");
30281
30552
  const filename = c.req.param("filename");
30282
30553
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -30292,26 +30563,26 @@ app65.get("/agent-assets/:slug/:filename", (c) => {
30292
30563
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
30293
30564
  return c.text("Not found", 404);
30294
30565
  }
30295
- const filePath = resolve41(account.accountDir, "agents", slug, "assets", filename);
30296
- 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");
30297
30568
  if (!filePath.startsWith(expectedDir + "/")) {
30298
30569
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
30299
30570
  return c.text("Forbidden", 403);
30300
30571
  }
30301
- if (!existsSync42(filePath)) {
30572
+ if (!existsSync43(filePath)) {
30302
30573
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
30303
30574
  return c.text("Not found", 404);
30304
30575
  }
30305
30576
  const ext = "." + filename.split(".").pop()?.toLowerCase();
30306
30577
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
30307
30578
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
30308
- const body = readFileSync45(filePath);
30579
+ const body = readFileSync46(filePath);
30309
30580
  return c.body(body, 200, {
30310
30581
  "Content-Type": contentType,
30311
30582
  "Cache-Control": "public, max-age=3600"
30312
30583
  });
30313
30584
  });
30314
- app65.get("/generated/:filename", (c) => {
30585
+ app66.get("/generated/:filename", (c) => {
30315
30586
  const filename = c.req.param("filename");
30316
30587
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
30317
30588
  console.error(`[generated] serve file=${filename} status=403`);
@@ -30322,35 +30593,35 @@ app65.get("/generated/:filename", (c) => {
30322
30593
  console.error(`[generated] serve file=${filename} status=404`);
30323
30594
  return c.text("Not found", 404);
30324
30595
  }
30325
- const filePath = resolve41(account.accountDir, "generated", filename);
30326
- const expectedDir = resolve41(account.accountDir, "generated");
30596
+ const filePath = resolve42(account.accountDir, "generated", filename);
30597
+ const expectedDir = resolve42(account.accountDir, "generated");
30327
30598
  if (!filePath.startsWith(expectedDir + "/")) {
30328
30599
  console.error(`[generated] serve file=${filename} status=403`);
30329
30600
  return c.text("Forbidden", 403);
30330
30601
  }
30331
- if (!existsSync42(filePath)) {
30602
+ if (!existsSync43(filePath)) {
30332
30603
  console.error(`[generated] serve file=${filename} status=404`);
30333
30604
  return c.text("Not found", 404);
30334
30605
  }
30335
30606
  const ext = "." + filename.split(".").pop()?.toLowerCase();
30336
30607
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
30337
30608
  console.log(`[generated] serve file=${filename} status=200`);
30338
- const body = readFileSync45(filePath);
30609
+ const body = readFileSync46(filePath);
30339
30610
  return c.body(body, 200, {
30340
30611
  "Content-Type": contentType,
30341
30612
  "Cache-Control": "public, max-age=86400"
30342
30613
  });
30343
30614
  });
30344
- app65.route("/sites", sites_default);
30345
- app65.route("/listings", listings_default);
30346
- app65.route("/v", visitor_event_default);
30347
- 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);
30348
30619
  var htmlCache = /* @__PURE__ */ new Map();
30349
30620
  var brandLogoPath = "/brand/maxy-monochrome.png";
30350
30621
  var brandIconPath = "/brand/maxy-monochrome.png";
30351
- if (BRAND_JSON_PATH && existsSync42(BRAND_JSON_PATH)) {
30622
+ if (BRAND_JSON_PATH && existsSync43(BRAND_JSON_PATH)) {
30352
30623
  try {
30353
- const fullBrand = JSON.parse(readFileSync45(BRAND_JSON_PATH, "utf-8"));
30624
+ const fullBrand = JSON.parse(readFileSync46(BRAND_JSON_PATH, "utf-8"));
30354
30625
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
30355
30626
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
30356
30627
  } catch {
@@ -30377,11 +30648,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
30377
30648
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
30378
30649
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
30379
30650
  var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
30380
- (p) => existsSync42(resolve41(process.cwd(), "public", p.replace(/^\//, "")))
30651
+ (p) => existsSync43(resolve42(process.cwd(), "public", p.replace(/^\//, "")))
30381
30652
  );
30382
30653
  var SW_SOURCE = (() => {
30383
30654
  try {
30384
- return readFileSync45(resolve41(process.cwd(), "public", "sw.js"), "utf-8");
30655
+ return readFileSync46(resolve42(process.cwd(), "public", "sw.js"), "utf-8");
30385
30656
  } catch {
30386
30657
  return null;
30387
30658
  }
@@ -30390,8 +30661,8 @@ function readInstalledVersion() {
30390
30661
  try {
30391
30662
  if (!PLATFORM_ROOT8) return "unknown";
30392
30663
  const versionFile = join47(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
30393
- if (!existsSync42(versionFile)) return "unknown";
30394
- const content = readFileSync45(versionFile, "utf-8").trim();
30664
+ if (!existsSync43(versionFile)) return "unknown";
30665
+ const content = readFileSync46(versionFile, "utf-8").trim();
30395
30666
  return content || "unknown";
30396
30667
  } catch {
30397
30668
  return "unknown";
@@ -30432,7 +30703,7 @@ var clientErrorReporterScript = `<script>
30432
30703
  function cachedHtml(file) {
30433
30704
  let html = htmlCache.get(file);
30434
30705
  if (!html) {
30435
- html = readFileSync45(resolve41(process.cwd(), "public", file), "utf-8");
30706
+ html = readFileSync46(resolve42(process.cwd(), "public", file), "utf-8");
30436
30707
  const productNameEsc = escapeHtml(BRAND.productName);
30437
30708
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
30438
30709
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -30454,8 +30725,8 @@ function loadBrandingCache(agentSlug) {
30454
30725
  const accountId = getDefaultAccountId();
30455
30726
  if (!accountId) return null;
30456
30727
  const cachePath = join47(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
30457
- if (!existsSync42(cachePath)) return null;
30458
- return JSON.parse(readFileSync45(cachePath, "utf-8"));
30728
+ if (!existsSync43(cachePath)) return null;
30729
+ return JSON.parse(readFileSync46(cachePath, "utf-8"));
30459
30730
  } catch {
30460
30731
  return null;
30461
30732
  }
@@ -30499,7 +30770,7 @@ function brandedPublicHtml(agentSlug) {
30499
30770
  function agentUnavailableHtml() {
30500
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>`;
30501
30772
  }
30502
- app65.get("/", (c) => {
30773
+ app66.get("/", (c) => {
30503
30774
  const host = (c.req.header("host") ?? "").split(":")[0];
30504
30775
  const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
30505
30776
  if (klass === "operator") {
@@ -30521,12 +30792,12 @@ app65.get("/", (c) => {
30521
30792
  console.log(`[host-class] host=${host} class=admin served=index.html`);
30522
30793
  return c.html(cachedHtml("index.html"));
30523
30794
  });
30524
- app65.get("/public", (c) => {
30795
+ app66.get("/public", (c) => {
30525
30796
  const host = (c.req.header("host") ?? "").split(":")[0];
30526
30797
  if (isPublicHost(host)) return c.text("Not found", 404);
30527
30798
  return c.html(cachedHtml("public.html"));
30528
30799
  });
30529
- app65.get("/public-chat", (c) => {
30800
+ app66.get("/public-chat", (c) => {
30530
30801
  const host = (c.req.header("host") ?? "").split(":")[0];
30531
30802
  if (isPublicHost(host)) return c.text("Not found", 404);
30532
30803
  return c.html(cachedHtml("public.html"));
@@ -30545,12 +30816,12 @@ async function logViewerFetch(c, next) {
30545
30816
  duration_ms: Date.now() - start
30546
30817
  });
30547
30818
  }
30548
- app65.use("/vnc-viewer.html", logViewerFetch);
30549
- app65.use("/vnc-popout.html", logViewerFetch);
30550
- 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) => {
30551
30822
  let html = htmlCache.get("vnc-popout.html");
30552
30823
  if (!html) {
30553
- html = readFileSync45(resolve41(process.cwd(), "public", "vnc-popout.html"), "utf-8");
30824
+ html = readFileSync46(resolve42(process.cwd(), "public", "vnc-popout.html"), "utf-8");
30554
30825
  const name = escapeHtml(BRAND.productName);
30555
30826
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
30556
30827
  html = html.replace("</head>", ` ${brandScript}
@@ -30560,7 +30831,7 @@ app65.get("/vnc-popout.html", (c) => {
30560
30831
  }
30561
30832
  return c.html(html);
30562
30833
  });
30563
- app65.post("/api/vnc/client-event", async (c) => {
30834
+ app66.post("/api/vnc/client-event", async (c) => {
30564
30835
  let body;
30565
30836
  try {
30566
30837
  body = await c.req.json();
@@ -30581,11 +30852,11 @@ app65.post("/api/vnc/client-event", async (c) => {
30581
30852
  });
30582
30853
  return c.json({ ok: true });
30583
30854
  });
30584
- app65.get("/g/:slug", (c) => {
30855
+ app66.get("/g/:slug", (c) => {
30585
30856
  return c.html(brandedPublicHtml(resolveDefaultSlug() ?? void 0));
30586
30857
  });
30587
30858
  for (const pwa of PWA_SURFACES) {
30588
- app65.get(pwa.manifestPath, (c) => {
30859
+ app66.get(pwa.manifestPath, (c) => {
30589
30860
  const manifest = buildManifest(pwa, {
30590
30861
  productName: BRAND.productName,
30591
30862
  appIcon192: brandAppIcon192Path,
@@ -30601,7 +30872,7 @@ for (const pwa of PWA_SURFACES) {
30601
30872
  return c.body(JSON.stringify(manifest));
30602
30873
  });
30603
30874
  }
30604
- app65.get("/sw.js", (c) => {
30875
+ app66.get("/sw.js", (c) => {
30605
30876
  if (SW_SOURCE == null) {
30606
30877
  console.error("[pwa] op=sw status=500 reason=sw-source-missing");
30607
30878
  return c.text("Service worker unavailable", 500);
@@ -30610,12 +30881,12 @@ app65.get("/sw.js", (c) => {
30610
30881
  console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
30611
30882
  return c.body(SW_SOURCE);
30612
30883
  });
30613
- app65.get("/graph", (c) => {
30884
+ app66.get("/graph", (c) => {
30614
30885
  const host = (c.req.header("host") ?? "").split(":")[0];
30615
30886
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
30616
30887
  return c.html(cachedHtml("graph.html"));
30617
30888
  });
30618
- app65.get("/chat", (c) => {
30889
+ app66.get("/chat", (c) => {
30619
30890
  const host = (c.req.header("host") ?? "").split(":")[0];
30620
30891
  if (isOperatorHost(host, getOperatorDomains())) {
30621
30892
  console.log(`[host-class] host=${host} class=operator served=operator.html`);
@@ -30624,37 +30895,42 @@ app65.get("/chat", (c) => {
30624
30895
  if (isPublicHost(host)) return c.text("Not found", 404);
30625
30896
  return c.html(cachedHtml("chat.html"));
30626
30897
  });
30627
- app65.get("/data", (c) => {
30898
+ app66.get("/data", (c) => {
30628
30899
  const host = (c.req.header("host") ?? "").split(":")[0];
30629
30900
  if (isPublicHost(host)) return c.text("Not found", 404);
30630
30901
  return c.html(cachedHtml("data.html"));
30631
30902
  });
30632
- app65.get("/tasks", (c) => {
30903
+ app66.get("/tasks", (c) => {
30633
30904
  const host = (c.req.header("host") ?? "").split(":")[0];
30634
30905
  if (isPublicHost(host)) return c.text("Not found", 404);
30635
30906
  return c.html(cachedHtml("tasks.html"));
30636
30907
  });
30637
- app65.get("/activity", (c) => {
30908
+ app66.get("/activity", (c) => {
30638
30909
  const host = (c.req.header("host") ?? "").split(":")[0];
30639
30910
  if (isPublicHost(host)) return c.text("Not found", 404);
30640
30911
  return c.html(cachedHtml("activity.html"));
30641
30912
  });
30642
- app65.get("/calendar", (c) => {
30913
+ app66.get("/calendar", (c) => {
30643
30914
  const host = (c.req.header("host") ?? "").split(":")[0];
30644
30915
  if (isPublicHost(host)) return c.text("Not found", 404);
30645
30916
  return c.html(cachedHtml("calendar.html"));
30646
30917
  });
30647
- app65.get("/routines", (c) => {
30918
+ app66.get("/routines", (c) => {
30648
30919
  const host = (c.req.header("host") ?? "").split(":")[0];
30649
30920
  if (isPublicHost(host)) return c.text("Not found", 404);
30650
30921
  return c.html(cachedHtml("routines.html"));
30651
30922
  });
30652
- 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) => {
30653
30929
  const host = (c.req.header("host") ?? "").split(":")[0];
30654
30930
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
30655
30931
  return c.html(cachedHtml("browser.html"));
30656
30932
  });
30657
- app65.get("/:slug", async (c, next) => {
30933
+ app66.get("/:slug", async (c, next) => {
30658
30934
  const slug = c.req.param("slug");
30659
30935
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
30660
30936
  const account = resolveAccount();
@@ -30669,13 +30945,13 @@ app65.get("/:slug", async (c, next) => {
30669
30945
  await next();
30670
30946
  });
30671
30947
  if (brandFaviconPath !== "/favicon.ico") {
30672
- app65.get("/favicon.ico", (c) => {
30948
+ app66.get("/favicon.ico", (c) => {
30673
30949
  c.header("Cache-Control", "public, max-age=300");
30674
30950
  return c.redirect(brandFaviconPath, 302);
30675
30951
  });
30676
30952
  }
30677
- app65.use("/*", serveStatic({ root: "./public" }));
30678
- app65.all("*", (c) => {
30953
+ app66.use("/*", serveStatic({ root: "./public" }));
30954
+ app66.all("*", (c) => {
30679
30955
  const host = (c.req.header("host") ?? "").split(":")[0];
30680
30956
  const path3 = c.req.path;
30681
30957
  if (isPublicHost(host)) {
@@ -30689,13 +30965,13 @@ app65.all("*", (c) => {
30689
30965
  });
30690
30966
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
30691
30967
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
30692
- var httpServer = serve({ fetch: app65.fetch, port, hostname });
30968
+ var httpServer = serve({ fetch: app66.fetch, port, hostname });
30693
30969
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30694
30970
  {
30695
30971
  const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30696
- 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");
30697
30973
  const runReconcile = (ctx) => {
30698
- if (!existsSync42(reconcileScript)) return;
30974
+ if (!existsSync43(reconcileScript)) return;
30699
30975
  try {
30700
30976
  const child = spawn3(process.execPath, [reconcileScript], {
30701
30977
  env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
@@ -30734,14 +31010,14 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30734
31010
  {
30735
31011
  const DREAM_CYCLE_SWEEP_INTERVAL_MS = 36e5;
30736
31012
  const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30737
- 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");
30738
31014
  registerLoop({
30739
31015
  name: "dream-cycle-sweep",
30740
31016
  intervalMs: DREAM_CYCLE_SWEEP_INTERVAL_MS,
30741
31017
  firstRunDelayMs: 3e4,
30742
31018
  detached: true,
30743
31019
  run: (ctx) => {
30744
- if (!existsSync42(dreamSweepScript)) return;
31020
+ if (!existsSync43(dreamSweepScript)) return;
30745
31021
  try {
30746
31022
  const child = spawn3(process.execPath, [dreamSweepScript], {
30747
31023
  env: { ...process.env, PLATFORM_ROOT: dreamPlatformRoot },
@@ -30758,10 +31034,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30758
31034
  }
30759
31035
  {
30760
31036
  const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30761
- 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");
30762
31038
  const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
30763
31039
  const runOutlookComplete = (ctx) => {
30764
- if (!existsSync42(outlookScript)) return;
31040
+ if (!existsSync43(outlookScript)) return;
30765
31041
  try {
30766
31042
  const child = spawn3(process.execPath, [outlookScript], {
30767
31043
  env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
@@ -30784,19 +31060,19 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30784
31060
  }
30785
31061
  {
30786
31062
  const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30787
- const strandedAccountsDir = resolve41(auditRoot, "..", "data/accounts");
31063
+ const strandedAccountsDir = resolve42(auditRoot, "..", "data/accounts");
30788
31064
  const STRANDED_AUDIT_INTERVAL_MS = 3e5;
30789
31065
  const STRANDED_AGE_MS = 16 * 6e4;
30790
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;
30791
31067
  const runStrandedAudit = () => {
30792
31068
  try {
30793
- if (!existsSync42(strandedAccountsDir)) return;
31069
+ if (!existsSync43(strandedAccountsDir)) return;
30794
31070
  const now = Date.now();
30795
- for (const name of readdirSync26(strandedAccountsDir)) {
31071
+ for (const name of readdirSync27(strandedAccountsDir)) {
30796
31072
  if (!STRANDED_UUID_RE.test(name)) continue;
30797
- const pendingPath2 = resolve41(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
30798
- if (!existsSync42(pendingPath2)) continue;
30799
- 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;
30800
31076
  if (ageMs2 > STRANDED_AGE_MS) {
30801
31077
  console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs2 / 1e3)}`);
30802
31078
  }
@@ -30814,7 +31090,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30814
31090
  }
30815
31091
  {
30816
31092
  const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30817
- const googleAccountsDir = resolve41(googleRoot, "..", "data/accounts");
31093
+ const googleAccountsDir = resolve42(googleRoot, "..", "data/accounts");
30818
31094
  const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
30819
31095
  const runGooglePendingAuditSafe = () => {
30820
31096
  try {
@@ -30829,10 +31105,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30829
31105
  firstRunDelayMs: 27e3,
30830
31106
  run: runGooglePendingAuditSafe
30831
31107
  });
30832
- 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");
30833
31109
  const GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS = 36e5;
30834
31110
  const runGoogleAccountAudit = (ctx) => {
30835
- if (!existsSync42(googleAuditScript)) return;
31111
+ if (!existsSync43(googleAuditScript)) return;
30836
31112
  try {
30837
31113
  const child = spawn3(process.execPath, [googleAuditScript], {
30838
31114
  env: { ...process.env, PLATFORM_ROOT: googleRoot },
@@ -30904,7 +31180,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30904
31180
  }
30905
31181
  {
30906
31182
  const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30907
- 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");
30908
31184
  const PUBLISH_INTERVAL_MS = 3e5;
30909
31185
  const bookingAccounts = () => {
30910
31186
  try {
@@ -30915,7 +31191,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30915
31191
  }
30916
31192
  };
30917
31193
  const spawnPublish = (account, ctx) => {
30918
- if (!existsSync42(publishScript)) return;
31194
+ if (!existsSync43(publishScript)) return;
30919
31195
  try {
30920
31196
  const child = spawn3(process.execPath, [publishScript], {
30921
31197
  env: {
@@ -30934,21 +31210,21 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
30934
31210
  }
30935
31211
  };
30936
31212
  const auditSnapshotAge = (account) => {
30937
- const availPath = resolve41(account.accountDir, "calendar-availability.json");
31213
+ const availPath = resolve42(account.accountDir, "calendar-availability.json");
30938
31214
  let hasBookingSite = false;
30939
31215
  try {
30940
- if (existsSync42(availPath)) {
30941
- const cfg = JSON.parse(readFileSync45(availPath, "utf-8"));
31216
+ if (existsSync43(availPath)) {
31217
+ const cfg = JSON.parse(readFileSync46(availPath, "utf-8"));
30942
31218
  hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
30943
31219
  }
30944
31220
  } catch {
30945
31221
  }
30946
31222
  if (!hasBookingSite) return;
30947
- const statePath = resolve41(account.accountDir, "state", "booking-availability", "last-publish.json");
31223
+ const statePath = resolve42(account.accountDir, "state", "booking-availability", "last-publish.json");
30948
31224
  let lastSuccessAt = null;
30949
- if (existsSync42(statePath)) {
31225
+ if (existsSync43(statePath)) {
30950
31226
  try {
30951
- const rec = JSON.parse(readFileSync45(statePath, "utf-8"));
31227
+ const rec = JSON.parse(readFileSync46(statePath, "utf-8"));
30952
31228
  lastSuccessAt = rec.lastSuccessAt ?? null;
30953
31229
  } catch {
30954
31230
  console.error(`[calendar-availability] op=audit accountId=${account.accountId} snapshotAgeMs=na reason=bad-state-file`);
@@ -30981,11 +31257,11 @@ startTimeEntryCensus(() => getSession());
30981
31257
  startLedgerCensus(() => getSession());
30982
31258
  {
30983
31259
  const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
30984
- 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");
30985
31261
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
30986
31262
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
30987
31263
  const runConnectorAudit = (ctx) => {
30988
- if (!existsSync42(auditScript)) return;
31264
+ if (!existsSync43(auditScript)) return;
30989
31265
  try {
30990
31266
  const child = spawn3(process.execPath, [auditScript], {
30991
31267
  env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
@@ -31065,7 +31341,7 @@ for (const m of SUBAPP_MANIFEST) {
31065
31341
  }
31066
31342
  try {
31067
31343
  const registered = [];
31068
- for (const r of app65.routes ?? []) {
31344
+ for (const r of app66.routes ?? []) {
31069
31345
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
31070
31346
  if (AGENT_SLUG_PATTERN.test(r.path)) {
31071
31347
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -31105,11 +31381,11 @@ try {
31105
31381
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
31106
31382
  async function runAdminUserReconcileTick() {
31107
31383
  try {
31108
- if (!existsSync42(USERS_FILE)) {
31384
+ if (!existsSync43(USERS_FILE)) {
31109
31385
  console.error("[adminuser-self-heal] skip reason=no-users-file");
31110
31386
  return;
31111
31387
  }
31112
- const usersRaw = readFileSync45(USERS_FILE, "utf-8").trim();
31388
+ const usersRaw = readFileSync46(USERS_FILE, "utf-8").trim();
31113
31389
  if (!usersRaw) {
31114
31390
  console.error("[adminuser-self-heal] skip reason=empty-users-file");
31115
31391
  return;
@@ -31156,8 +31432,8 @@ registerLoop({
31156
31432
  });
31157
31433
  var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
31158
31434
  function countUsersRows() {
31159
- if (!existsSync42(USERS_FILE)) return 0;
31160
- const raw = readFileSync45(USERS_FILE, "utf-8").trim();
31435
+ if (!existsSync43(USERS_FILE)) return 0;
31436
+ const raw = readFileSync46(USERS_FILE, "utf-8").trim();
31161
31437
  if (!raw) return 0;
31162
31438
  const users = JSON.parse(raw);
31163
31439
  return users.filter((u) => typeof u.userId === "string").length;
@@ -31290,7 +31566,7 @@ if (bootAccountConfig?.whatsapp) {
31290
31566
  }
31291
31567
  init({
31292
31568
  configDir: configDirForWhatsApp,
31293
- platformRoot: resolve41(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..")),
31569
+ platformRoot: resolve42(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..")),
31294
31570
  accountConfig: bootAccountConfig,
31295
31571
  onMessage: async (msg) => {
31296
31572
  if (isObserveAccount(msg.accountId)) {