@rubytech/create-maxy-code 0.1.435 → 0.1.437

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 (257) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/docs/superpowers/plans/2026-07-11-task-1557-operator-on-behalf-preference-attribution.md +542 -0
  3. package/payload/platform/docs/superpowers/specs/2026-07-11-task-1557-operator-on-behalf-preference-attribution-design.md +90 -0
  4. package/payload/platform/lib/active-rules/dist/index.d.ts +14 -0
  5. package/payload/platform/lib/active-rules/dist/index.d.ts.map +1 -1
  6. package/payload/platform/lib/active-rules/dist/index.js +56 -9
  7. package/payload/platform/lib/active-rules/dist/index.js.map +1 -1
  8. package/payload/platform/lib/active-rules/src/index.test.ts +106 -0
  9. package/payload/platform/lib/active-rules/src/index.ts +98 -9
  10. package/payload/platform/lib/embed-client/dist/index.d.ts +1 -1
  11. package/payload/platform/lib/embed-client/dist/index.d.ts.map +1 -1
  12. package/payload/platform/lib/embed-client/dist/index.js +42 -13
  13. package/payload/platform/lib/embed-client/dist/index.js.map +1 -1
  14. package/payload/platform/lib/embed-client/src/index.ts +44 -13
  15. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +7 -7
  16. package/payload/platform/plugins/docs/references/admin-session.md +2 -0
  17. package/payload/platform/plugins/docs/references/admin-ui.md +2 -2
  18. package/payload/platform/plugins/docs/references/internals.md +4 -4
  19. package/payload/platform/plugins/memory/PLUGIN.md +2 -0
  20. package/payload/platform/plugins/memory/mcp/dist/index.js +54 -25
  21. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  22. package/payload/platform/plugins/memory/mcp/dist/lib/embed-progress-reporter.d.ts +22 -0
  23. package/payload/platform/plugins/memory/mcp/dist/lib/embed-progress-reporter.d.ts.map +1 -0
  24. package/payload/platform/plugins/memory/mcp/dist/lib/embed-progress-reporter.js +43 -0
  25. package/payload/platform/plugins/memory/mcp/dist/lib/embed-progress-reporter.js.map +1 -0
  26. package/payload/platform/plugins/memory/mcp/dist/lib/profile-identity.d.ts +34 -0
  27. package/payload/platform/plugins/memory/mcp/dist/lib/profile-identity.d.ts.map +1 -0
  28. package/payload/platform/plugins/memory/mcp/dist/lib/profile-identity.js +22 -0
  29. package/payload/platform/plugins/memory/mcp/dist/lib/profile-identity.js.map +1 -0
  30. package/payload/platform/plugins/memory/mcp/dist/lib/resolve-admin-home-account.d.ts +13 -0
  31. package/payload/platform/plugins/memory/mcp/dist/lib/resolve-admin-home-account.d.ts.map +1 -0
  32. package/payload/platform/plugins/memory/mcp/dist/lib/resolve-admin-home-account.js +26 -0
  33. package/payload/platform/plugins/memory/mcp/dist/lib/resolve-admin-home-account.js.map +1 -0
  34. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-progress-reporter.test.d.ts +2 -0
  35. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-progress-reporter.test.d.ts.map +1 -0
  36. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-progress-reporter.test.js +52 -0
  37. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-progress-reporter.test.js.map +1 -0
  38. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-progress.test.d.ts +2 -0
  39. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-progress.test.d.ts.map +1 -0
  40. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-progress.test.js +56 -0
  41. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-progress.test.js.map +1 -0
  42. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.js +30 -5
  43. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.js.map +1 -1
  44. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.js +9 -7
  45. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.js.map +1 -1
  46. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write-progress.test.d.ts +2 -0
  47. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write-progress.test.d.ts.map +1 -0
  48. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write-progress.test.js +79 -0
  49. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write-progress.test.js.map +1 -0
  50. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-write-phase-progress.test.d.ts +2 -0
  51. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-write-phase-progress.test.d.ts.map +1 -0
  52. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-write-phase-progress.test.js +50 -0
  53. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-write-phase-progress.test.js.map +1 -0
  54. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex-progress.test.d.ts +2 -0
  55. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex-progress.test.d.ts.map +1 -0
  56. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex-progress.test.js +114 -0
  57. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex-progress.test.js.map +1 -0
  58. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-identity.test.d.ts +2 -0
  59. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-identity.test.d.ts.map +1 -0
  60. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-identity.test.js +72 -0
  61. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-identity.test.js.map +1 -0
  62. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-read-active-rules.test.js +5 -0
  63. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-read-active-rules.test.js.map +1 -1
  64. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-bootstrap.test.js +2 -2
  65. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-bootstrap.test.js.map +1 -1
  66. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/resolve-admin-home-account.test.d.ts +2 -0
  67. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/resolve-admin-home-account.test.d.ts.map +1 -0
  68. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/resolve-admin-home-account.test.js +38 -0
  69. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/resolve-admin-home-account.test.js.map +1 -0
  70. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts +15 -0
  71. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts.map +1 -1
  72. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js +17 -17
  73. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js.map +1 -1
  74. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts +9 -0
  75. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
  76. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +22 -2
  77. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
  78. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.d.ts +1 -1
  79. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.d.ts.map +1 -1
  80. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js +19 -4
  81. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js.map +1 -1
  82. package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.d.ts.map +1 -1
  83. package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js +4 -2
  84. package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js.map +1 -1
  85. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +5 -3
  86. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
  87. package/payload/platform/plugins/memory/skills/conversational-memory/SKILL.md +8 -0
  88. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  89. package/payload/platform/services/claude-session-manager/dist/http-server.js +16 -6
  90. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  91. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.d.ts +7 -0
  92. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.d.ts.map +1 -1
  93. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.js +9 -0
  94. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.js.map +1 -1
  95. package/payload/platform/services/claude-session-manager/dist/preference-reconciliation-audit.d.ts +4 -1
  96. package/payload/platform/services/claude-session-manager/dist/preference-reconciliation-audit.d.ts.map +1 -1
  97. package/payload/platform/services/claude-session-manager/dist/preference-reconciliation-audit.js.map +1 -1
  98. package/payload/server/{chunk-DAYMXQG2.js → chunk-LMLVOZ6G.js} +7 -2
  99. package/payload/server/maxy-edge.js +1 -1
  100. package/payload/server/public/assets/{AdminLoginScreens-CMh1pdOp.js → AdminLoginScreens-DeR71H29.js} +1 -1
  101. package/payload/server/public/assets/AdminShell-DlAVQUda.js +2 -0
  102. package/payload/server/public/assets/{Checkbox-OCfZCTCO.js → Checkbox-B629mOPp.js} +1 -1
  103. package/payload/server/public/assets/{admin-Bi2uYnAg.js → admin-C15h-NL0.js} +1 -1
  104. package/payload/server/public/assets/{arc-Bm9oSOth.js → arc-qKfXIt8v.js} +1 -1
  105. package/payload/server/public/assets/architecture-YZFGNWBL-FPHT7s-C.js +1 -0
  106. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-C2dK88g3.js → architectureDiagram-Q4EWVU46-DkVrGn7G.js} +1 -1
  107. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DfLSsjCJ.js → blockDiagram-DXYQGD6D-DqavswGH.js} +1 -1
  108. package/payload/server/public/assets/browser-B7xQLIRK.js +1 -0
  109. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-Bxkmp6OL.js → c4Diagram-AHTNJAMY-B7fyKiXe.js} +1 -1
  110. package/payload/server/public/assets/calendar-A-vGm6pL.js +1 -0
  111. package/payload/server/public/assets/channel-j70eMvcL.js +1 -0
  112. package/payload/server/public/assets/chat-DAae6Z51.js +1 -0
  113. package/payload/server/public/assets/chevron-left-u4tjq7fI.js +1 -0
  114. package/payload/server/public/assets/{chunk-2KRD3SAO-BVNDFwNH.js → chunk-2KRD3SAO-DsgMtGkv.js} +1 -1
  115. package/payload/server/public/assets/{chunk-336JU56O-Daz6nMta.js → chunk-336JU56O-CkdISfNt.js} +2 -2
  116. package/payload/server/public/assets/chunk-426QAEUC-D-NcAlTW.js +1 -0
  117. package/payload/server/public/assets/{chunk-4BX2VUAB-DTldfvwP.js → chunk-4BX2VUAB-CYpiF2bl.js} +1 -1
  118. package/payload/server/public/assets/{chunk-4TB4RGXK-DhM8pwRG.js → chunk-4TB4RGXK-CWyc_F7v.js} +1 -1
  119. package/payload/server/public/assets/{chunk-55IACEB6-CzTsbIHo.js → chunk-55IACEB6-BbzKMw2Z.js} +1 -1
  120. package/payload/server/public/assets/{chunk-5FUZZQ4R-BrcObZhe.js → chunk-5FUZZQ4R-u19Nai9e.js} +1 -1
  121. package/payload/server/public/assets/{chunk-5PVQY5BW-SFqTuS11.js → chunk-5PVQY5BW-Ba8by6Uy.js} +1 -1
  122. package/payload/server/public/assets/{chunk-67CJDMHE-EIbrSGOo.js → chunk-67CJDMHE-BwUuxtyb.js} +1 -1
  123. package/payload/server/public/assets/{chunk-7N4EOEYR-B1D4Jorr.js → chunk-7N4EOEYR-BRH9iM9L.js} +1 -1
  124. package/payload/server/public/assets/{chunk-AA7GKIK3-BKHiX4cC.js → chunk-AA7GKIK3-BGoztgLL.js} +1 -1
  125. package/payload/server/public/assets/{chunk-BSJP7CBP-xBzu29m7.js → chunk-BSJP7CBP-C5GDAZTl.js} +1 -1
  126. package/payload/server/public/assets/{chunk-CIAEETIT-x2x0gMpL.js → chunk-CIAEETIT-ChY32VPS.js} +1 -1
  127. package/payload/server/public/assets/{chunk-EDXVE4YY-D5UkD28M.js → chunk-EDXVE4YY-CPSD3p6p.js} +1 -1
  128. package/payload/server/public/assets/{chunk-ENJZ2VHE-Dbz67a7E.js → chunk-ENJZ2VHE-D1oL-iUr.js} +1 -1
  129. package/payload/server/public/assets/{chunk-FMBD7UC4-XfWvuu2F.js → chunk-FMBD7UC4-CPvYEr54.js} +1 -1
  130. package/payload/server/public/assets/{chunk-FOC6F5B3-DfOEDS4q.js → chunk-FOC6F5B3-9Yyj7Vbz.js} +1 -1
  131. package/payload/server/public/assets/{chunk-ICPOFSXX-D_WEZZvg.js → chunk-ICPOFSXX-BaYgh8FR.js} +2 -2
  132. package/payload/server/public/assets/{chunk-K5T4RW27-7O627Xi1.js → chunk-K5T4RW27-5ucpeRvm.js} +1 -1
  133. package/payload/server/public/assets/{chunk-KGLVRYIC-BXI3XDP9.js → chunk-KGLVRYIC-DW-FHk7T.js} +1 -1
  134. package/payload/server/public/assets/{chunk-LIHQZDEY-B9cFNN0l.js → chunk-LIHQZDEY-CGGVfAyG.js} +1 -1
  135. package/payload/server/public/assets/{chunk-ORNJ4GCN-BR3UNDTn.js → chunk-ORNJ4GCN-Bv8EUa5d.js} +1 -1
  136. package/payload/server/public/assets/{chunk-OYMX7WX6-2wKIEtFZ.js → chunk-OYMX7WX6-C1mXJnyw.js} +1 -1
  137. package/payload/server/public/assets/chunk-QZHKN3VN-CAwbQBtf.js +1 -0
  138. package/payload/server/public/assets/{chunk-U2HBQHQK-augM3AXB.js → chunk-U2HBQHQK-PwSQz6EP.js} +1 -1
  139. package/payload/server/public/assets/{chunk-X2U36JSP-BAM9q9ZQ.js → chunk-X2U36JSP--NPHTBlU.js} +1 -1
  140. package/payload/server/public/assets/{chunk-XPW4576I-DxPpji5P.js → chunk-XPW4576I-Bbc7Da32.js} +1 -1
  141. package/payload/server/public/assets/{chunk-YZCP3GAM-BD3ClFXP.js → chunk-YZCP3GAM-D-9v8e--.js} +1 -1
  142. package/payload/server/public/assets/{chunk-ZZ45TVLE-CqxhLPep.js → chunk-ZZ45TVLE-CMPg670Q.js} +1 -1
  143. package/payload/server/public/assets/classDiagram-6PBFFD2Q-Ct6Rn0vt.js +1 -0
  144. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-B_2XCIFv.js +1 -0
  145. package/payload/server/public/assets/clone-DjPWA_NH.js +1 -0
  146. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-xywWX-9i.js → cose-bilkent-S5V4N54A-NVSb1Bhy.js} +1 -1
  147. package/payload/server/public/assets/{dagre-KV5264BT-ChRpqqiH.js → dagre-KV5264BT-V2Ai1DFl.js} +1 -1
  148. package/payload/server/public/assets/{dagre-BaHjDQ-8.js → dagre-QfLcO-1j.js} +1 -1
  149. package/payload/server/public/assets/data-BNWpKx1d.js +1 -0
  150. package/payload/server/public/assets/{diagram-5BDNPKRD-KjwTpyBi.js → diagram-5BDNPKRD-Caw21693.js} +1 -1
  151. package/payload/server/public/assets/{diagram-G4DWMVQ6-DZO9njAF.js → diagram-G4DWMVQ6-CgwVkT2q.js} +1 -1
  152. package/payload/server/public/assets/{diagram-MMDJMWI5-Bus-U-TI.js → diagram-MMDJMWI5-DFUrLZhs.js} +1 -1
  153. package/payload/server/public/assets/{diagram-TYMM5635-CfJodFgq.js → diagram-TYMM5635-CEEiEuZJ.js} +1 -1
  154. package/payload/server/public/assets/{erDiagram-SMLLAGMA-Bt5zqWiW.js → erDiagram-SMLLAGMA-CG10NrT3.js} +1 -1
  155. package/payload/server/public/assets/file-download-4mKJxUi-.js +1 -0
  156. package/payload/server/public/assets/{flatten-Bpu1L63d.js → flatten-DAO0sfCM.js} +1 -1
  157. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-B64Q590S.js → flowDiagram-DWJPFMVM-BqkV9Okv.js} +1 -1
  158. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BWdgCEpH.js → ganttDiagram-T4ZO3ILL-DRiCDQF6.js} +1 -1
  159. package/payload/server/public/assets/gitGraph-7Q5UKJZL-B8Hx7f-D.js +1 -0
  160. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-Djq2B0WT.js → gitGraphDiagram-UUTBAWPF-BZV2voyy.js} +1 -1
  161. package/payload/server/public/assets/{graph-CrJ-itbq.js → graph-D0orIRAh.js} +3 -3
  162. package/payload/server/public/assets/{graph-labels-CmCWaKJT.js → graph-labels-B8YAdo3Z.js} +1 -1
  163. package/payload/server/public/assets/{graphlib-CNJh9_lx.js → graphlib-DGPThX8M.js} +1 -1
  164. package/payload/server/public/assets/info-OMHHGYJF-BicCJTqU.js +1 -0
  165. package/payload/server/public/assets/infoDiagram-42DDH7IO-tf-8rOez.js +2 -0
  166. package/payload/server/public/assets/{isEmpty-DkDEVnMZ.js → isEmpty-Cb_U81C6.js} +1 -1
  167. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-V3ACkWCW.js → ishikawaDiagram-UXIWVN3A-BKsAxSvp.js} +1 -1
  168. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-9T0qZeH3.js → journeyDiagram-VCZTEJTY-CmliuOd-.js} +1 -1
  169. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-CxZ0ukx3.js → kanban-definition-6JOO6SKY-DAlElMb-.js} +1 -1
  170. package/payload/server/public/assets/{line-DUHKCQZT.js → line-DKZqLKAC.js} +1 -1
  171. package/payload/server/public/assets/{linear-BgIBblun.js → linear-CbSGdh1x.js} +1 -1
  172. package/payload/server/public/assets/{maximize-2-_cJWIgx2.js → maximize-2-CxstTgoK.js} +1 -1
  173. package/payload/server/public/assets/{mermaid-parser.core-CyHygs0-.js → mermaid-parser.core-DFvbao9C.js} +2 -2
  174. package/payload/server/public/assets/{mermaid.core-L55fJBSx.js → mermaid.core-C0vEBxDm.js} +3 -3
  175. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-DczaUX_E.js → mindmap-definition-QFDTVHPH-CShASUKd.js} +1 -1
  176. package/payload/server/public/assets/operator-DZzuotDB.js +1 -0
  177. package/payload/server/public/assets/{ordinal-DK3QISRR.js → ordinal-H0tVmBDP.js} +1 -1
  178. package/payload/server/public/assets/packet-4T2RLAQJ-Ckn_5hq0.js +1 -0
  179. package/payload/server/public/assets/page-3g0A19Rv.js +32 -0
  180. package/payload/server/public/assets/page-Ck_pLhAk.js +1 -0
  181. package/payload/server/public/assets/{pdf-render-COLA4aPx.js → pdf-render-jAQU0nXt.js} +1 -1
  182. package/payload/server/public/assets/pie-ZZUOXDRM-DzlGQW3J.js +1 -0
  183. package/payload/server/public/assets/{pieDiagram-DEJITSTG-Da5TdnNt.js → pieDiagram-DEJITSTG-CBZHpDAJ.js} +1 -1
  184. package/payload/server/public/assets/{public-DmBKnBkr.js → public-WFUQw9AD.js} +1 -1
  185. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-DX7J81uh.js → quadrantDiagram-34T5L4WZ-n3bB3K91.js} +1 -1
  186. package/payload/server/public/assets/radar-PYXPWWZC-BHo2YD8b.js +1 -0
  187. package/payload/server/public/assets/{reduce-uzWdoyL7.js → reduce-DAvwat-a.js} +1 -1
  188. package/payload/server/public/assets/{requirementDiagram-MS252O5E-DJQGrZPG.js → requirementDiagram-MS252O5E-DiDvQK3c.js} +1 -1
  189. package/payload/server/public/assets/rotate-ccw-COGQTi7n.js +1 -0
  190. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-Ba8fGz96.js → sankeyDiagram-XADWPNL6-DWDQQZmd.js} +1 -1
  191. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-BmDPC7qx.js → sequenceDiagram-FGHM5R23-DmAqRlBT.js} +1 -1
  192. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-1VkptYFz.js → stateDiagram-FHFEXIEX-D4R-n6bZ.js} +1 -1
  193. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BcFRbGRu.js +1 -0
  194. package/payload/server/public/assets/tasks-B97VpwEJ.js +1 -0
  195. package/payload/server/public/assets/{time-entry-format-D477WAes.js → time-entry-format-C09rDHo9.js} +1 -1
  196. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-B92U3T_f.js → timeline-definition-GMOUNBTQ-CjiHGP4l.js} +1 -1
  197. package/payload/server/public/assets/treeView-SZITEDCU-BtRr5vXp.js +1 -0
  198. package/payload/server/public/assets/treemap-W4RFUUIX-D8p0sbyo.js +1 -0
  199. package/payload/server/public/assets/useCopyFeedback-CSk9KjhY.js +1 -0
  200. package/payload/server/public/assets/useSubAccountSwitcher-DLJFISqf.js +9 -0
  201. package/payload/server/public/assets/{useSubAccountSwitcher-BKCWKo97.css → useSubAccountSwitcher-Dzmd7Aip.css} +1 -1
  202. package/payload/server/public/assets/{useVoiceRecorder-CZPtVpM-.js → useVoiceRecorder-DCyJQkFK.js} +2 -2
  203. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-Y6Wkihrs.js → vennDiagram-DHZGUBPP-CBdDQ7c-.js} +1 -1
  204. package/payload/server/public/assets/wardley-RL74JXVD-DgMn-9ZJ.js +1 -0
  205. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-iJpfal2z.js → wardleyDiagram-NUSXRM2D-BlIQPKLb.js} +1 -1
  206. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-S0bv7oH0.js → xychartDiagram-5P7HB3ND-CslKgh9B.js} +1 -1
  207. package/payload/server/public/browser.html +5 -5
  208. package/payload/server/public/calendar.html +6 -6
  209. package/payload/server/public/chat.html +13 -12
  210. package/payload/server/public/data.html +11 -11
  211. package/payload/server/public/graph.html +11 -10
  212. package/payload/server/public/index.html +14 -14
  213. package/payload/server/public/operator.html +15 -14
  214. package/payload/server/public/public.html +13 -12
  215. package/payload/server/public/tasks.html +5 -4
  216. package/payload/server/server.js +691 -542
  217. package/payload/server/public/assets/AdminShell-X9Bg3AKc.js +0 -2
  218. package/payload/server/public/assets/architecture-YZFGNWBL-Bbnxm4F4.js +0 -1
  219. package/payload/server/public/assets/browser-B0ieZy-b.js +0 -1
  220. package/payload/server/public/assets/calendar-CRL2_9Fl.js +0 -1
  221. package/payload/server/public/assets/channel-CatPTq-5.js +0 -1
  222. package/payload/server/public/assets/chat-C56bmC6C.js +0 -1
  223. package/payload/server/public/assets/chevron-left-B2DKUxLk.js +0 -1
  224. package/payload/server/public/assets/chunk-426QAEUC-CqLMwOdA.js +0 -1
  225. package/payload/server/public/assets/chunk-QZHKN3VN-CjWy8NJ7.js +0 -1
  226. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DHhR5rdN.js +0 -1
  227. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DH4pAdfu.js +0 -1
  228. package/payload/server/public/assets/clone-DCKzwjWW.js +0 -1
  229. package/payload/server/public/assets/data-C1ftMulP.js +0 -1
  230. package/payload/server/public/assets/file-download-CHTyUQqS.js +0 -1
  231. package/payload/server/public/assets/gitGraph-7Q5UKJZL-Ps5HDzLh.js +0 -1
  232. package/payload/server/public/assets/info-OMHHGYJF-gtlpwIig.js +0 -1
  233. package/payload/server/public/assets/infoDiagram-42DDH7IO-CPrWlrsa.js +0 -2
  234. package/payload/server/public/assets/operator-B4wN2c53.js +0 -1
  235. package/payload/server/public/assets/packet-4T2RLAQJ-DrSn1e0n.js +0 -1
  236. package/payload/server/public/assets/page-BIfOKi9I.js +0 -32
  237. package/payload/server/public/assets/page-C1G57kPZ.js +0 -1
  238. package/payload/server/public/assets/pie-ZZUOXDRM-C09i6N-g.js +0 -1
  239. package/payload/server/public/assets/radar-PYXPWWZC-CMZN2KQH.js +0 -1
  240. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BdgkPHuh.js +0 -1
  241. package/payload/server/public/assets/tasks-0OcRiBdQ.js +0 -1
  242. package/payload/server/public/assets/treeView-SZITEDCU-CeuUM5oL.js +0 -1
  243. package/payload/server/public/assets/treemap-W4RFUUIX-C--fAaJv.js +0 -1
  244. package/payload/server/public/assets/useCopyFeedback-CpfVOO26.js +0 -1
  245. package/payload/server/public/assets/useSubAccountSwitcher-Bo7bnFtC.js +0 -9
  246. package/payload/server/public/assets/wardley-RL74JXVD-4WPJ2UA9.js +0 -1
  247. /package/payload/server/public/assets/{_baseFor-Q4DeIqQC.js → _baseFor-D3BqAOBr.js} +0 -0
  248. /package/payload/server/public/assets/{array-WaOTgZu7.js → array-iYP9fzJp.js} +0 -0
  249. /package/payload/server/public/assets/{cytoscape.esm-CMmjo4hO.js → cytoscape.esm-BQSBzPsB.js} +0 -0
  250. /package/payload/server/public/assets/{defaultLocale-BxqJVxq5.js → defaultLocale-BrdA1gDi.js} +0 -0
  251. /package/payload/server/public/assets/{dist-Dx-cpU53.js → dist-Cvgxm7qv.js} +0 -0
  252. /package/payload/server/public/assets/{init-DX7c5Edh.js → init-Bx0S6pkp.js} +0 -0
  253. /package/payload/server/public/assets/{katex-B2dtGfSp.js → katex-BsiH_a6d.js} +0 -0
  254. /package/payload/server/public/assets/{path-CnSyroar.js → path-BLSgTy3w.js} +0 -0
  255. /package/payload/server/public/assets/{preload-helper-DqboRNgS.js → preload-helper-ClBMtM1g.js} +0 -0
  256. /package/payload/server/public/assets/{rough.esm-eLccZ4OJ.js → rough.esm-BMOtDaaS.js} +0 -0
  257. /package/payload/server/public/assets/{src-Dqs1wlnb.js → src-DV4LKv2E.js} +0 -0
@@ -78,7 +78,7 @@ import {
78
78
  persistMessage,
79
79
  preloadEmbedModel,
80
80
  projectAgent,
81
- reconcileEnabledPlugins,
81
+ reconcileEnabledPluginsForAccounts,
82
82
  recordFailedAttempt,
83
83
  registerSession,
84
84
  renameConversation,
@@ -112,7 +112,7 @@ import {
112
112
  vncLog,
113
113
  walkPremiumBundles,
114
114
  writeAdminUserAndPerson
115
- } from "./chunk-DAYMXQG2.js";
115
+ } from "./chunk-LMLVOZ6G.js";
116
116
  import {
117
117
  __commonJS,
118
118
  __toESM
@@ -127,8 +127,10 @@ var require_dist = __commonJS({
127
127
  exports.cosine = cosine;
128
128
  exports.deconflictBySubject = deconflictBySubject;
129
129
  exports.formatStandingRulesBlock = formatStandingRulesBlock2;
130
+ exports.resolveOwnerUserId = resolveOwnerUserId;
130
131
  exports.queryActiveRuleCandidates = queryActiveRuleCandidates;
131
- exports.activeRuleSet = activeRuleSet2;
132
+ exports.resolveActiveRules = resolveActiveRules2;
133
+ exports.activeRuleSet = activeRuleSet;
132
134
  exports.SAME_SUBJECT_COSINE = 0.85;
133
135
  exports.INJECTION_RULE_CAP = 12;
134
136
  exports.ACTIVE_CANDIDATE_FLOOR = 0.4;
@@ -165,9 +167,20 @@ var require_dist = __commonJS({
165
167
  return `## Standing rules
166
168
  ${lines.join("\n")}`;
167
169
  }
168
- async function queryActiveRuleCandidates(session, accountId) {
170
+ async function resolveOwnerUserId(session, accountId) {
171
+ const res = await session.run(`
172
+ MATCH (au:AdminUser {accountId: $accountId, role: 'owner'})
173
+ RETURN au.userId AS userId
174
+ ORDER BY au.createdAt ASC
175
+ LIMIT 1
176
+ `, { accountId });
177
+ const rec = res.records[0];
178
+ const userId = rec ? rec.get("userId") : null;
179
+ return typeof userId === "string" && userId.length > 0 ? userId : null;
180
+ }
181
+ async function queryOwnerCandidates(session, accountId, ownerUserId) {
169
182
  const result = await session.run(`
170
- MATCH (pref:Preference {accountId: $accountId, scope: 'admin'})
183
+ MATCH (up:UserProfile {accountId: $accountId, userId: $ownerUserId})-[:HAS_PREFERENCE]->(pref:Preference {scope: 'admin'})
171
184
  WHERE NOT pref:Trashed AND pref.deletedAt IS NULL
172
185
  AND coalesce(pref.notApplicable, false) = false
173
186
  AND pref.confidence >= $floor
@@ -176,7 +189,7 @@ ${lines.join("\n")}`;
176
189
  pref.observedAt AS observedAt, pref.embedding AS embedding
177
190
  ORDER BY pref.confidence DESC, pref.observedAt DESC
178
191
  LIMIT ${exports.ACTIVE_CANDIDATE_LIMIT}
179
- `, { accountId, floor: exports.ACTIVE_CANDIDATE_FLOOR });
192
+ `, { accountId, ownerUserId, floor: exports.ACTIVE_CANDIDATE_FLOOR });
180
193
  return result.records.map((r) => ({
181
194
  preferenceId: r.get("preferenceId"),
182
195
  category: r.get("category"),
@@ -187,9 +200,27 @@ ${lines.join("\n")}`;
187
200
  embedding: r.get("embedding") ?? null
188
201
  }));
189
202
  }
190
- async function activeRuleSet2(session, accountId, cap = exports.INJECTION_RULE_CAP) {
191
- const candidates = await queryActiveRuleCandidates(session, accountId);
192
- return deconflictBySubject(candidates).slice(0, cap);
203
+ async function resolveCandidates(session, accountId) {
204
+ let ownerUserId;
205
+ try {
206
+ ownerUserId = await resolveOwnerUserId(session, accountId);
207
+ } catch {
208
+ return { candidates: [], ownerUserId: null, source: "owner-error" };
209
+ }
210
+ if (!ownerUserId)
211
+ return { candidates: [], ownerUserId: null, source: "no-owner" };
212
+ const candidates = await queryOwnerCandidates(session, accountId, ownerUserId);
213
+ return { candidates, ownerUserId, source: "owner" };
214
+ }
215
+ async function queryActiveRuleCandidates(session, accountId) {
216
+ return (await resolveCandidates(session, accountId)).candidates;
217
+ }
218
+ async function resolveActiveRules2(session, accountId, cap = exports.INJECTION_RULE_CAP) {
219
+ const { candidates, ownerUserId, source } = await resolveCandidates(session, accountId);
220
+ return { rules: deconflictBySubject(candidates).slice(0, cap), ownerUserId, source };
221
+ }
222
+ async function activeRuleSet(session, accountId, cap = exports.INJECTION_RULE_CAP) {
223
+ return (await resolveActiveRules2(session, accountId, cap)).rules;
193
224
  }
194
225
  }
195
226
  });
@@ -1384,11 +1415,11 @@ var serveStatic = (options = { root: "" }) => {
1384
1415
  };
1385
1416
 
1386
1417
  // server/index.ts
1387
- import { readFileSync as readFileSync35, existsSync as existsSync34, watchFile } from "fs";
1418
+ import { readFileSync as readFileSync35, existsSync as existsSync35, watchFile } from "fs";
1388
1419
  import { spawn as spawn3 } from "child_process";
1389
1420
  import { createHash as createHash7 } from "crypto";
1390
- import { resolve as resolve33, join as join35, basename as basename13 } from "path";
1391
- import { homedir as homedir3 } from "os";
1421
+ import { resolve as resolve33, join as join36, basename as basename12 } from "path";
1422
+ import { homedir as homedir4 } from "os";
1392
1423
  import { monitorEventLoopDelay } from "perf_hooks";
1393
1424
 
1394
1425
  // app/lib/pwa.ts
@@ -6137,8 +6168,8 @@ function webchatTurnTimeoutMs() {
6137
6168
  return Number(process.env.WEBCHAT_TURN_TIMEOUT_MS ?? String(2 * 6e4));
6138
6169
  }
6139
6170
  function createChatRoutes(deps) {
6140
- const app61 = new Hono();
6141
- app61.post("/", async (c) => {
6171
+ const app62 = new Hono();
6172
+ app62.post("/", async (c) => {
6142
6173
  console.log(`[chat-route] entered route=public method=POST`);
6143
6174
  const contentType = c.req.header("content-type") ?? "";
6144
6175
  const account = resolveAccount();
@@ -6401,7 +6432,7 @@ ${result.result.text}` : result.result.text;
6401
6432
  }
6402
6433
  });
6403
6434
  });
6404
- return app61;
6435
+ return app62;
6405
6436
  }
6406
6437
 
6407
6438
  // app/lib/channel-pty-bridge/admin-session-id.ts
@@ -6436,8 +6467,8 @@ function isLoopbackAddr(addr) {
6436
6467
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
6437
6468
  }
6438
6469
  function createScheduleInjectRoutes(deps) {
6439
- const app61 = new Hono();
6440
- app61.post("/", async (c) => {
6470
+ const app62 = new Hono();
6471
+ app62.post("/", async (c) => {
6441
6472
  const env = c.env;
6442
6473
  const remoteAddr = env?.incoming?.socket?.remoteAddress ?? "";
6443
6474
  if (!isLoopbackAddr(remoteAddr)) {
@@ -6541,7 +6572,7 @@ function createScheduleInjectRoutes(deps) {
6541
6572
  console.error(`${TAG16} op=inject-spawn eventId=${eventId} sessionId=${sessionId} result=ok status=-`);
6542
6573
  return c.json({ ok: true }, 200);
6543
6574
  });
6544
- return app61;
6575
+ return app62;
6545
6576
  }
6546
6577
 
6547
6578
  // server/index.ts
@@ -7562,6 +7593,9 @@ function reconcileCredsOnDisk(opts) {
7562
7593
  function isReaderChannelSession(role, channel) {
7563
7594
  return role === "admin" && (channel === "whatsapp" || channel === "telegram") || role === "public" && (channel === "whatsapp" || channel === "webchat");
7564
7595
  }
7596
+ function isSessionListExcluded(role, channel) {
7597
+ return role === "public" && channel === "webchat";
7598
+ }
7565
7599
  function selectReaderChannelSessions(rows) {
7566
7600
  return rows.filter((r) => isReaderChannelSession(r.role, r.channel)).sort((a, b) => b.startedAt.localeCompare(a.startedAt)).map((r) => ({
7567
7601
  sessionId: r.sessionId,
@@ -8162,12 +8196,37 @@ app2.get("/group-info", async (c) => {
8162
8196
  var whatsapp_default = app2;
8163
8197
 
8164
8198
  // server/routes/whatsapp-reader.ts
8165
- import { readFileSync as readFileSync15, watch, statSync as statSync5, openSync, readSync, closeSync, existsSync as existsSync9, readdirSync as readdirSync8, realpathSync as realpathSync4 } from "fs";
8166
- import { basename as basename5, dirname as dirname4, isAbsolute, join as join14, relative as relative2, resolve as resolve12, sep as sep3 } from "path";
8199
+ import { readFileSync as readFileSync15, watch, statSync as statSync5, openSync, readSync, closeSync, existsSync as existsSync10, readdirSync as readdirSync9, realpathSync as realpathSync4 } from "fs";
8200
+ import { basename as basename4, dirname as dirname4, isAbsolute, join as join15, relative as relative2, resolve as resolve12, sep as sep3 } from "path";
8201
+
8202
+ // server/routes/admin/sidebar-sessions.ts
8203
+ import { readdirSync as readdirSync6, readFileSync as readFileSync12, statSync as statSync3 } from "fs";
8204
+ import { dirname as dirname3, join as join12, resolve as resolve11 } from "path";
8205
+
8206
+ // ../services/claude-session-manager/src/jsonl-path.ts
8207
+ import { existsSync as existsSync8, readdirSync as readdirSync5 } from "fs";
8208
+ import { homedir } from "os";
8209
+ import { join as join11 } from "path";
8210
+ function findExistingJsonlForSessionId(claudeConfigDir2, sessionId) {
8211
+ const projectsRoot = join11(claudeConfigDir2, "projects");
8212
+ if (!existsSync8(projectsRoot)) return null;
8213
+ let slugs;
8214
+ try {
8215
+ slugs = readdirSync5(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
8216
+ } catch {
8217
+ return null;
8218
+ }
8219
+ const basename13 = `${sessionId}.jsonl`;
8220
+ for (const slug of slugs) {
8221
+ const live = join11(projectsRoot, slug, basename13);
8222
+ if (existsSync8(live)) return live;
8223
+ const archived = join11(projectsRoot, slug, "archive", basename13);
8224
+ if (existsSync8(archived)) return archived;
8225
+ }
8226
+ return null;
8227
+ }
8167
8228
 
8168
8229
  // server/routes/admin/sidebar-sessions.ts
8169
- import { readdirSync as readdirSync5, readFileSync as readFileSync12, statSync as statSync3 } from "fs";
8170
- import { basename as basename4, dirname as dirname3, join as join11, resolve as resolve11 } from "path";
8171
8230
  var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.jsonl$/i;
8172
8231
  function lastAssistantModel(body) {
8173
8232
  const lines = body.split("\n");
@@ -8196,25 +8255,23 @@ function claudeConfigDir() {
8196
8255
  function findSessionProjectDir(sessionId) {
8197
8256
  const cfg = claudeConfigDir();
8198
8257
  if (!cfg) return null;
8199
- for (const { path: path2 } of enumerateJsonls(join11(cfg, "projects"))) {
8200
- if (basename4(path2) === `${sessionId}.jsonl`) return dirname3(path2);
8201
- }
8202
- return null;
8258
+ const jsonlPath = findExistingJsonlForSessionId(cfg, sessionId);
8259
+ return jsonlPath ? dirname3(jsonlPath) : null;
8203
8260
  }
8204
8261
  function enumerateJsonls(projectsRoot) {
8205
8262
  const out = [];
8206
8263
  let slugs;
8207
8264
  try {
8208
- slugs = readdirSync5(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
8265
+ slugs = readdirSync6(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
8209
8266
  } catch (err) {
8210
8267
  if (err.code === "ENOENT") return out;
8211
8268
  throw err;
8212
8269
  }
8213
8270
  for (const slug of slugs) {
8214
- const slugDir = join11(projectsRoot, slug);
8271
+ const slugDir = join12(projectsRoot, slug);
8215
8272
  let entries;
8216
8273
  try {
8217
- entries = readdirSync5(slugDir, { withFileTypes: true });
8274
+ entries = readdirSync6(slugDir, { withFileTypes: true });
8218
8275
  } catch (err) {
8219
8276
  const code = err.code ?? "unknown";
8220
8277
  console.error(`[admin-sessions-list] slug-skipped slug=${slug} code=${code}`);
@@ -8222,12 +8279,12 @@ function enumerateJsonls(projectsRoot) {
8222
8279
  }
8223
8280
  for (const entry of entries) {
8224
8281
  if (entry.isFile() && SESSION_ID_RE.test(entry.name)) {
8225
- out.push({ path: join11(slugDir, entry.name), isSubagent: false, archived: false });
8282
+ out.push({ path: join12(slugDir, entry.name), isSubagent: false, archived: false });
8226
8283
  } else if (entry.isDirectory() && entry.name === "subagents") {
8227
- const subDir = join11(slugDir, entry.name);
8284
+ const subDir = join12(slugDir, entry.name);
8228
8285
  let subEntries;
8229
8286
  try {
8230
- subEntries = readdirSync5(subDir, { withFileTypes: true });
8287
+ subEntries = readdirSync6(subDir, { withFileTypes: true });
8231
8288
  } catch (err) {
8232
8289
  const code = err.code ?? "unknown";
8233
8290
  console.error(`[admin-sessions-list] subagents-skipped slug=${slug} code=${code}`);
@@ -8235,14 +8292,14 @@ function enumerateJsonls(projectsRoot) {
8235
8292
  }
8236
8293
  for (const sub of subEntries) {
8237
8294
  if (sub.isFile() && SESSION_ID_RE.test(sub.name)) {
8238
- out.push({ path: join11(subDir, sub.name), isSubagent: true, archived: false });
8295
+ out.push({ path: join12(subDir, sub.name), isSubagent: true, archived: false });
8239
8296
  }
8240
8297
  }
8241
8298
  } else if (entry.isDirectory() && entry.name === "archive") {
8242
- const archiveDir = join11(slugDir, entry.name);
8299
+ const archiveDir = join12(slugDir, entry.name);
8243
8300
  let archiveEntries;
8244
8301
  try {
8245
- archiveEntries = readdirSync5(archiveDir, { withFileTypes: true });
8302
+ archiveEntries = readdirSync6(archiveDir, { withFileTypes: true });
8246
8303
  } catch (err) {
8247
8304
  const code = err.code ?? "unknown";
8248
8305
  console.error(`[admin-sessions-list] archive-skipped slug=${slug} code=${code}`);
@@ -8250,7 +8307,7 @@ function enumerateJsonls(projectsRoot) {
8250
8307
  }
8251
8308
  for (const arc of archiveEntries) {
8252
8309
  if (arc.isFile() && SESSION_ID_RE.test(arc.name)) {
8253
- out.push({ path: join11(archiveDir, arc.name), isSubagent: false, archived: true });
8310
+ out.push({ path: join12(archiveDir, arc.name), isSubagent: false, archived: true });
8254
8311
  }
8255
8312
  }
8256
8313
  }
@@ -8283,7 +8340,7 @@ async function fetchLiveSessions() {
8283
8340
  function loadUserTitles(accountDir) {
8284
8341
  const out = /* @__PURE__ */ new Map();
8285
8342
  if (!accountDir) return out;
8286
- const path2 = join11(accountDir, "session-titles.json");
8343
+ const path2 = join12(accountDir, "session-titles.json");
8287
8344
  let raw;
8288
8345
  try {
8289
8346
  raw = readFileSync12(path2, "utf8");
@@ -8410,7 +8467,7 @@ app3.get("/", requireAdminSession, async (c) => {
8410
8467
  console.error("[admin-sessions-list] CLAUDE_CONFIG_DIR not set; returning empty list");
8411
8468
  return c.json({ sessions: [], accountId: scopeAccountId });
8412
8469
  }
8413
- const projectsRoot = join11(configDir2, "projects");
8470
+ const projectsRoot = join12(configDir2, "projects");
8414
8471
  const jsonls = enumerateJsonls(projectsRoot);
8415
8472
  const liveSessions = await fetchLiveSessions();
8416
8473
  const accountDir = scopeAccountId ? resolve11(ACCOUNTS_DIR, scopeAccountId) : null;
@@ -8420,7 +8477,10 @@ app3.get("/", requireAdminSession, async (c) => {
8420
8477
  let liveCount = 0;
8421
8478
  let subagentCount = 0;
8422
8479
  let archivedCount = 0;
8423
- let excludedChannelCount = 0;
8480
+ let excludedPublicWebchatCount = 0;
8481
+ const channelInList = { whatsapp: 0, telegram: 0, webchat: 0 };
8482
+ const KNOWN_CHANNELS = /* @__PURE__ */ new Set(["browser", "whatsapp", "telegram", "webchat", "email"]);
8483
+ let unknownChannelCount = 0;
8424
8484
  let untaggedCount = 0;
8425
8485
  const titleSourceCounts = { user: 0, ai: 0, "first-message": 0, prefix: 0 };
8426
8486
  const personIdBySession = /* @__PURE__ */ new Map();
@@ -8447,14 +8507,14 @@ app3.get("/", requireAdminSession, async (c) => {
8447
8507
  const pid = live ? liveSessions.get(sessionId) ?? null : null;
8448
8508
  const resolved = resolveTitle(body, sessionId, userTitles);
8449
8509
  titleSourceCounts[resolved.source] += 1;
8450
- const metaPath = join11(projectDir, `${sessionId}.meta.json`);
8510
+ const metaPath = join12(projectDir, `${sessionId}.meta.json`);
8451
8511
  const { bridgeIds, role, channel: sidecarChannel, personId, adminUserId, accountId: rowAccountId } = readSidecarMeta(metaPath);
8452
8512
  if (multiAccount) {
8453
8513
  if (rowAccountId === null) untaggedCount += 1;
8454
8514
  if (rowAccountId !== scopeAccountId) continue;
8455
8515
  }
8456
- if (isReaderChannelSession(role, sidecarChannel)) {
8457
- excludedChannelCount += 1;
8516
+ if (isSessionListExcluded(role, sidecarChannel)) {
8517
+ excludedPublicWebchatCount += 1;
8458
8518
  continue;
8459
8519
  }
8460
8520
  if (personId) personIdBySession.set(sessionId, personId);
@@ -8472,11 +8532,20 @@ app3.get("/", requireAdminSession, async (c) => {
8472
8532
  projectDir,
8473
8533
  bridgeIds,
8474
8534
  archived,
8475
- channel: resolved.channel,
8535
+ // Task 1566 — the row's channel is the authoritative `.meta.json` sidecar
8536
+ // value (whatsapp/telegram/webchat/browser/null), which drives the client
8537
+ // row colour and glyph. The JSONL-envelope channel (`resolved.channel`) is
8538
+ // no longer the row channel: it is null for browser/CLI rows and can
8539
+ // diverge from the sidecar (e.g. an ai-titled channel row).
8540
+ channel: sidecarChannel,
8476
8541
  personName: null,
8477
8542
  model: lastAssistantModel(body),
8478
8543
  accountId: rowAccountId
8479
8544
  });
8545
+ if (sidecarChannel === "whatsapp") channelInList.whatsapp += 1;
8546
+ else if (sidecarChannel === "telegram") channelInList.telegram += 1;
8547
+ else if (sidecarChannel === "webchat") channelInList.webchat += 1;
8548
+ if (sidecarChannel !== null && !KNOWN_CHANNELS.has(sidecarChannel)) unknownChannelCount += 1;
8480
8549
  if (live) liveCount += 1;
8481
8550
  if (isSubagent) subagentCount += 1;
8482
8551
  if (archived) archivedCount += 1;
@@ -8509,7 +8578,7 @@ app3.get("/", requireAdminSession, async (c) => {
8509
8578
  }
8510
8579
  rows.sort((a, b) => a.startedAt < b.startedAt ? 1 : -1);
8511
8580
  console.log(
8512
- `[admin-sessions-list] rows=${rows.length} live=${liveCount} subagents=${subagentCount} archived=${archivedCount} excludedChannel=${excludedChannelCount} titles user=${titleSourceCounts.user} ai=${titleSourceCounts.ai} first=${titleSourceCounts["first-message"]} prefix=${titleSourceCounts.prefix} personNames=${personNameCount} adminNames=${adminNameCount} accountId=${scopeAccountId ? scopeAccountId.slice(0, 8) : "unset"}`
8581
+ `[admin-sessions-list] rows=${rows.length} live=${liveCount} subagents=${subagentCount} archived=${archivedCount} channelInList=whatsapp:${channelInList.whatsapp},telegram:${channelInList.telegram},webchat:${channelInList.webchat} unknownChannel=${unknownChannelCount} excludedPublicWebchat=${excludedPublicWebchatCount} titles user=${titleSourceCounts.user} ai=${titleSourceCounts.ai} first=${titleSourceCounts["first-message"]} prefix=${titleSourceCounts.prefix} personNames=${personNameCount} adminNames=${adminNameCount} accountId=${scopeAccountId ? scopeAccountId.slice(0, 8) : "unset"}`
8513
8582
  );
8514
8583
  console.log(
8515
8584
  `[admin-sessions-list] accountId=${scopeAccountId ? scopeAccountId.slice(0, 8) : "unset"} scope=${multiAccount ? "scoped" : "all"} rows=${rows.length}`
@@ -8523,13 +8592,13 @@ var sidebar_sessions_default = app3;
8523
8592
 
8524
8593
  // app/lib/admin-identity/pin-validator.ts
8525
8594
  import { createHash as createHash3 } from "crypto";
8526
- import { existsSync as existsSync8, readFileSync as readFileSync13, readdirSync as readdirSync6, statSync as statSync4 } from "fs";
8527
- import { join as join12 } from "path";
8595
+ import { existsSync as existsSync9, readFileSync as readFileSync13, readdirSync as readdirSync7, statSync as statSync4 } from "fs";
8596
+ import { join as join13 } from "path";
8528
8597
  function hashPin(pin) {
8529
8598
  return createHash3("sha256").update(pin).digest("hex");
8530
8599
  }
8531
8600
  function readUsersFile(usersFilePath) {
8532
- if (!existsSync8(usersFilePath)) return null;
8601
+ if (!existsSync9(usersFilePath)) return null;
8533
8602
  const raw = readFileSync13(usersFilePath, "utf-8").trim();
8534
8603
  if (!raw) return [];
8535
8604
  return JSON.parse(raw);
@@ -8829,8 +8898,8 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
8829
8898
  }
8830
8899
 
8831
8900
  // app/lib/whatsapp-reader/enrich-attachments.ts
8832
- import { readFileSync as readFileSync14, readdirSync as readdirSync7 } from "fs";
8833
- import { join as join13 } from "path";
8901
+ import { readFileSync as readFileSync14, readdirSync as readdirSync8 } from "fs";
8902
+ import { join as join14 } from "path";
8834
8903
  var ADMIN_UPLOAD_PATH = /\/uploads\/(?!public\/)([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})\//gi;
8835
8904
  function adminAttachmentIds(text) {
8836
8905
  const ids = [];
@@ -8843,7 +8912,7 @@ function adminAttachmentIds(text) {
8843
8912
  function adminAttachmentsFromText(text, uploadsBase) {
8844
8913
  const out = [];
8845
8914
  for (const id of adminAttachmentIds(text)) {
8846
- const meta = readAttachmentMeta(join13(uploadsBase, id));
8915
+ const meta = readAttachmentMeta(join14(uploadsBase, id));
8847
8916
  if (meta) out.push(meta);
8848
8917
  }
8849
8918
  return out;
@@ -8851,7 +8920,7 @@ function adminAttachmentsFromText(text, uploadsBase) {
8851
8920
  function readSidecar(dir, attachmentId) {
8852
8921
  let parsed;
8853
8922
  try {
8854
- parsed = JSON.parse(readFileSync14(join13(dir, `${attachmentId}.meta.json`), "utf8"));
8923
+ parsed = JSON.parse(readFileSync14(join14(dir, `${attachmentId}.meta.json`), "utf8"));
8855
8924
  } catch {
8856
8925
  return null;
8857
8926
  }
@@ -8874,13 +8943,13 @@ function readAttachmentMeta(dir) {
8874
8943
  function listSessionAttachmentsInDir(dir) {
8875
8944
  let entries;
8876
8945
  try {
8877
- entries = readdirSync7(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
8946
+ entries = readdirSync8(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
8878
8947
  } catch {
8879
8948
  return [];
8880
8949
  }
8881
8950
  const sidecars = [];
8882
8951
  for (const name of entries) {
8883
- const sidecar = readSidecar(join13(dir, name), name);
8952
+ const sidecar = readSidecar(join14(dir, name), name);
8884
8953
  if (sidecar) sidecars.push(sidecar);
8885
8954
  }
8886
8955
  sidecars.sort((a, b) => a.storedAt.localeCompare(b.storedAt));
@@ -8945,14 +9014,14 @@ app4.get("/conversations", requireAdminSession, async (c) => {
8945
9014
  }
8946
9015
  const cfg = claudeConfigDir();
8947
9016
  if (!cfg) return c.json({ conversations: [] });
8948
- const projectsRoot = join14(cfg, "projects");
9017
+ const projectsRoot = join15(cfg, "projects");
8949
9018
  const userTitles = loadUserTitles(ACCOUNTS_DIR ?? null);
8950
9019
  const rows = [];
8951
9020
  let sessionRowsExcludedUntagged = 0;
8952
9021
  for (const { path: path2 } of enumerateJsonls(projectsRoot)) {
8953
- const sessionId = basename5(path2).replace(/\.jsonl$/, "");
9022
+ const sessionId = basename4(path2).replace(/\.jsonl$/, "");
8954
9023
  const projectDir = dirname4(path2);
8955
- const meta = readSidecarMeta(join14(projectDir, `${sessionId}.meta.json`));
9024
+ const meta = readSidecarMeta(join15(projectDir, `${sessionId}.meta.json`));
8956
9025
  if (!isReaderChannelSession(meta.role, meta.channel)) continue;
8957
9026
  if (multiAccount) {
8958
9027
  if (meta.accountId === null) sessionRowsExcludedUntagged += 1;
@@ -9132,7 +9201,7 @@ function openTaskKey(turns) {
9132
9201
  }
9133
9202
  function readSubagentMeta(dir, hex) {
9134
9203
  try {
9135
- const m = JSON.parse(readFileSync15(join14(dir, `agent-${hex}.meta.json`), "utf8"));
9204
+ const m = JSON.parse(readFileSync15(join15(dir, `agent-${hex}.meta.json`), "utf8"));
9136
9205
  if (typeof m.agentType === "string" && typeof m.description === "string" && typeof m.toolUseId === "string") {
9137
9206
  return { agentType: m.agentType, description: m.description, toolUseId: m.toolUseId };
9138
9207
  }
@@ -9155,7 +9224,7 @@ function runActivityTick(c) {
9155
9224
  c.parentGrewThisTick = false;
9156
9225
  let names = [];
9157
9226
  try {
9158
- names = readdirSync8(c.subagentsDir).filter((n) => AGENT_JSONL_RE.test(n));
9227
+ names = readdirSync9(c.subagentsDir).filter((n) => AGENT_JSONL_RE.test(n));
9159
9228
  } catch {
9160
9229
  }
9161
9230
  const entries = [];
@@ -9164,7 +9233,7 @@ function runActivityTick(c) {
9164
9233
  let size = 0;
9165
9234
  let mtimeMs = 0;
9166
9235
  try {
9167
- const st = statSync5(join14(c.subagentsDir, name));
9236
+ const st = statSync5(join15(c.subagentsDir, name));
9168
9237
  size = st.size;
9169
9238
  mtimeMs = st.mtimeMs;
9170
9239
  } catch {
@@ -9209,11 +9278,11 @@ app4.get("/stream", requireAdminSession, (c) => {
9209
9278
  const sessionId = c.req.query("sessionId") ?? "";
9210
9279
  const projectDir = c.req.query("projectDir") ?? "";
9211
9280
  const cfg = claudeConfigDir();
9212
- const projectsRoot = cfg ? resolve12(join14(cfg, "projects")) : null;
9281
+ const projectsRoot = cfg ? resolve12(join15(cfg, "projects")) : null;
9213
9282
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
9214
9283
  return c.json({ error: "bad session reference" }, 400);
9215
9284
  }
9216
- const jsonlPath = resolve12(join14(projectDir, `${sessionId}.jsonl`));
9285
+ const jsonlPath = resolve12(join15(projectDir, `${sessionId}.jsonl`));
9217
9286
  if (!jsonlPath.startsWith(projectsRoot + sep3)) {
9218
9287
  return c.json({ error: "bad session reference" }, 400);
9219
9288
  }
@@ -9238,9 +9307,9 @@ data: ${JSON.stringify(turn)}
9238
9307
  let offset = resumeOffset(lastEventId, fileEnd0);
9239
9308
  console.log(`[wa-stream] op=open conn=${connId} sessionId=${sessionId} channel=reader resume=${offset}`);
9240
9309
  const sessionKey = c.req.query("session_key") ?? "";
9241
- const subagentsDir = resolve12(join14(projectDir, sessionId, "subagents"));
9310
+ const subagentsDir = resolve12(join15(projectDir, sessionId, "subagents"));
9242
9311
  console.log(
9243
- `[webchat-activity] op=watch-subagents key=${sessionKey} dir=${subagentsDir} exists=${existsSync9(subagentsDir)}`
9312
+ `[webchat-activity] op=watch-subagents key=${sessionKey} dir=${subagentsDir} exists=${existsSync10(subagentsDir)}`
9244
9313
  );
9245
9314
  const actx = makeActivityCtx({
9246
9315
  subagentsDir,
@@ -9347,10 +9416,10 @@ app4.get("/directives", requireAdminSession, (c) => {
9347
9416
  const sessionId = c.req.query("sessionId") ?? "";
9348
9417
  if (!SESSION_ID_RE2.test(sessionId)) return c.json({ error: "bad session reference" }, 400);
9349
9418
  const dir = directiveStoreDir(sessionId);
9350
- if (!dir || !existsSync9(dir)) return c.json({ entries: [] });
9419
+ if (!dir || !existsSync10(dir)) return c.json({ entries: [] });
9351
9420
  let names;
9352
9421
  try {
9353
- names = readdirSync8(dir).filter((n) => DIRECTIVE_NAME_RE.test(n));
9422
+ names = readdirSync9(dir).filter((n) => DIRECTIVE_NAME_RE.test(n));
9354
9423
  } catch {
9355
9424
  return c.json({ entries: [] });
9356
9425
  }
@@ -9360,7 +9429,7 @@ app4.get("/directives", requireAdminSession, (c) => {
9360
9429
  const pid = Number(pidPart);
9361
9430
  let len = 0;
9362
9431
  try {
9363
- len = statSync5(join14(dir, name)).size;
9432
+ len = statSync5(join15(dir, name)).size;
9364
9433
  } catch {
9365
9434
  }
9366
9435
  return { name, secs, pid, ts: Number.isFinite(secs) ? new Date(secs * 1e3).toISOString() : null, len };
@@ -9375,7 +9444,7 @@ app4.get("/directive", requireAdminSession, (c) => {
9375
9444
  }
9376
9445
  const dir = directiveStoreDir(sessionId);
9377
9446
  if (!dir) return c.json({ error: "no account" }, 404);
9378
- const path2 = resolve12(join14(dir, name));
9447
+ const path2 = resolve12(join15(dir, name));
9379
9448
  if (!path2.startsWith(dir + sep3)) return c.json({ error: "bad reference" }, 400);
9380
9449
  let body;
9381
9450
  try {
@@ -9429,7 +9498,7 @@ app4.get("/store-stream", requireAdminSession, (c) => {
9429
9498
  console.log(`[wa-reader] op=store-quote msgId=${r.msgKeyId} quoted=${!!q}`);
9430
9499
  }
9431
9500
  if (r.attachmentId) {
9432
- const meta = readAttachmentMeta(join14(uploadsBase, r.attachmentId));
9501
+ const meta = readAttachmentMeta(join15(uploadsBase, r.attachmentId));
9433
9502
  if (meta) return { ...turn, attachments: [meta] };
9434
9503
  }
9435
9504
  return turn;
@@ -9644,7 +9713,7 @@ app4.post("/reply", requireAdminSession, async (c) => {
9644
9713
  }
9645
9714
  if (size > MAX_FILE_BYTES) {
9646
9715
  exit("rejected");
9647
- return c.json({ error: `"${basename5(absolute)}" exceeds the 50 MB limit` }, 400);
9716
+ return c.json({ error: `"${basename4(absolute)}" exceeds the 50 MB limit` }, 400);
9648
9717
  }
9649
9718
  const mime = detectMimeType(absolute);
9650
9719
  if (!isMimeAdmitted(mime, SUPPORTED_MIME_SET)) {
@@ -9736,7 +9805,7 @@ app4.post("/reply", requireAdminSession, async (c) => {
9736
9805
  }
9737
9806
  for (let i = 0; i < resolvedRefs.length; i++) {
9738
9807
  const { absolute, mime } = resolvedRefs[i];
9739
- const file = new File([readFileSync15(absolute)], basename5(absolute), { type: mime });
9808
+ const file = new File([readFileSync15(absolute)], basename4(absolute), { type: mime });
9740
9809
  const out = await sendStagedFile(file, `ref=${i}`);
9741
9810
  if (!out.ok) {
9742
9811
  exit("error");
@@ -9755,8 +9824,8 @@ app4.post("/reply", requireAdminSession, async (c) => {
9755
9824
  var whatsapp_reader_default = app4;
9756
9825
 
9757
9826
  // server/routes/public-reader.ts
9758
- import { statSync as statSync6, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, watch as watch2, readFileSync as readFileSync16, readdirSync as readdirSync9 } from "fs";
9759
- import { basename as basename6, dirname as dirname5, join as join15, resolve as resolve13, sep as sep4 } from "path";
9827
+ import { statSync as statSync6, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, watch as watch2, readFileSync as readFileSync16, readdirSync as readdirSync10 } from "fs";
9828
+ import { basename as basename5, dirname as dirname5, join as join16, resolve as resolve13, sep as sep4 } from "path";
9760
9829
 
9761
9830
  // app/lib/whatsapp-reader/delivered-kinds.ts
9762
9831
  var PUBLIC_DELIVERED_KINDS = /* @__PURE__ */ new Set([
@@ -9830,10 +9899,10 @@ function enumeratePublicRows() {
9830
9899
  const cfg = claudeConfigDir();
9831
9900
  if (!cfg) return [];
9832
9901
  const rows = [];
9833
- for (const { path: path2 } of enumerateJsonls(join15(cfg, "projects"))) {
9834
- const sessionId = basename6(path2).replace(/\.jsonl$/, "");
9902
+ for (const { path: path2 } of enumerateJsonls(join16(cfg, "projects"))) {
9903
+ const sessionId = basename5(path2).replace(/\.jsonl$/, "");
9835
9904
  const projectDir = dirname5(path2);
9836
- const meta = readSidecarMeta(join15(projectDir, `${sessionId}.meta.json`));
9905
+ const meta = readSidecarMeta(join16(projectDir, `${sessionId}.meta.json`));
9837
9906
  rows.push({
9838
9907
  sessionId,
9839
9908
  projectDir,
@@ -9909,15 +9978,15 @@ app5.get("/stream", (c) => {
9909
9978
  const sessionId = c.req.query("sessionId") ?? "";
9910
9979
  const projectDir = c.req.query("projectDir") ?? "";
9911
9980
  const cfg = claudeConfigDir();
9912
- const projectsRoot = cfg ? resolve13(join15(cfg, "projects")) : null;
9981
+ const projectsRoot = cfg ? resolve13(join16(cfg, "projects")) : null;
9913
9982
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
9914
9983
  return c.json({ error: "bad session reference" }, 400);
9915
9984
  }
9916
- const jsonlPath = resolve13(join15(projectDir, `${sessionId}.jsonl`));
9985
+ const jsonlPath = resolve13(join16(projectDir, `${sessionId}.jsonl`));
9917
9986
  if (!jsonlPath.startsWith(projectsRoot + sep4)) {
9918
9987
  return c.json({ error: "bad session reference" }, 400);
9919
9988
  }
9920
- const meta = readSidecarMeta(join15(projectDir, `${sessionId}.meta.json`));
9989
+ const meta = readSidecarMeta(join16(projectDir, `${sessionId}.meta.json`));
9921
9990
  const isPublicWebchat = meta.role === "public" && meta.channel === "webchat";
9922
9991
  const owns = visitor.kind === "person" ? meta.personId === visitor.personId : meta.personId === null && meta.visitorId === visitor.visitorId;
9923
9992
  if (!(isPublicWebchat && owns)) {
@@ -10030,7 +10099,7 @@ app5.get("/attachment/:attachmentId", (c) => {
10030
10099
  let dataFile;
10031
10100
  let buffer;
10032
10101
  try {
10033
- dataFile = readdirSync9(dir).find((f) => !f.endsWith(".meta.json") && !f.endsWith(EXTRACTED_TEXT_SUFFIX));
10102
+ dataFile = readdirSync10(dir).find((f) => !f.endsWith(".meta.json") && !f.endsWith(EXTRACTED_TEXT_SUFFIX));
10034
10103
  if (!dataFile) throw new Error("no data file");
10035
10104
  buffer = readFileSync16(resolve13(dir, dataFile));
10036
10105
  } catch {
@@ -10050,17 +10119,17 @@ app5.get("/attachment/:attachmentId", (c) => {
10050
10119
  var public_reader_default = app5;
10051
10120
 
10052
10121
  // server/routes/webchat.ts
10053
- import { basename as basename7, dirname as dirname6 } from "path";
10054
- import { join as join18 } from "path";
10055
- import { existsSync as existsSync11, readdirSync as readdirSync11, readFileSync as readFileSync19, renameSync as renameSync4, statSync as statSync7, writeFileSync as writeFileSync7 } from "fs";
10122
+ import { basename as basename6, dirname as dirname6 } from "path";
10123
+ import { join as join19 } from "path";
10124
+ import { existsSync as existsSync12, readdirSync as readdirSync12, readFileSync as readFileSync19, renameSync as renameSync4, statSync as statSync7, writeFileSync as writeFileSync7 } from "fs";
10056
10125
 
10057
10126
  // server/canonical-webchat-override.ts
10058
10127
  import { readFileSync as readFileSync17, writeFileSync as writeFileSync5, renameSync as renameSync2 } from "fs";
10059
- import { join as join16 } from "path";
10128
+ import { join as join17 } from "path";
10060
10129
  var FILE = "canonical-webchat-session.json";
10061
10130
  var UUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
10062
10131
  function canonicalOverridePath(accountDir) {
10063
- return join16(accountDir, FILE);
10132
+ return join17(accountDir, FILE);
10064
10133
  }
10065
10134
  function readRaw(accountDir) {
10066
10135
  try {
@@ -10139,8 +10208,8 @@ function isNewSessionEffortLevel(value) {
10139
10208
  }
10140
10209
 
10141
10210
  // ../services/claude-session-manager/src/sidecar-store.ts
10142
- import { existsSync as existsSync10, mkdirSync as mkdirSync3, readdirSync as readdirSync10, readFileSync as readFileSync18, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
10143
- import { join as join17 } from "path";
10211
+ import { existsSync as existsSync11, mkdirSync as mkdirSync3, readdirSync as readdirSync11, readFileSync as readFileSync18, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
10212
+ import { join as join18 } from "path";
10144
10213
  function escapeRegExp(s) {
10145
10214
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
10146
10215
  }
@@ -10148,7 +10217,7 @@ function createSidecarStore(config) {
10148
10217
  const { suffix, validate: validate2 } = config;
10149
10218
  const suffixRe = new RegExp(`${escapeRegExp(suffix)}$`);
10150
10219
  function pathFor(sessionsDir, id) {
10151
- return join17(sessionsDir, `${id}${suffix}`);
10220
+ return join18(sessionsDir, `${id}${suffix}`);
10152
10221
  }
10153
10222
  function write(sessionsDir, id, record) {
10154
10223
  mkdirSync3(sessionsDir, { recursive: true });
@@ -10160,7 +10229,7 @@ function createSidecarStore(config) {
10160
10229
  return { ok: true };
10161
10230
  } catch (error) {
10162
10231
  try {
10163
- if (existsSync10(tmp)) unlinkSync2(tmp);
10232
+ if (existsSync11(tmp)) unlinkSync2(tmp);
10164
10233
  } catch {
10165
10234
  }
10166
10235
  return { ok: false, error };
@@ -10185,14 +10254,14 @@ function createSidecarStore(config) {
10185
10254
  function readAll(sessionsDir, onSkip) {
10186
10255
  let names;
10187
10256
  try {
10188
- names = readdirSync10(sessionsDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name);
10257
+ names = readdirSync11(sessionsDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name);
10189
10258
  } catch {
10190
10259
  return [];
10191
10260
  }
10192
10261
  const out = [];
10193
10262
  for (const name of names) {
10194
10263
  if (!suffixRe.test(name)) continue;
10195
- const path2 = join17(sessionsDir, name);
10264
+ const path2 = join18(sessionsDir, name);
10196
10265
  let raw;
10197
10266
  try {
10198
10267
  raw = readFileSync18(path2, "utf8");
@@ -10216,7 +10285,7 @@ function createSidecarStore(config) {
10216
10285
  function clear(sessionsDir, id) {
10217
10286
  const path2 = pathFor(sessionsDir, id);
10218
10287
  try {
10219
- if (existsSync10(path2)) {
10288
+ if (existsSync11(path2)) {
10220
10289
  unlinkSync2(path2);
10221
10290
  return { ok: true, removed: true };
10222
10291
  }
@@ -10269,22 +10338,22 @@ var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9
10269
10338
  function locateSession(sessionId) {
10270
10339
  const dir = findSessionProjectDir(sessionId);
10271
10340
  if (!dir) return { projectDir: null, channel: null, accountId: null };
10272
- const meta = readSidecarMeta(join18(dir, `${sessionId}.meta.json`));
10341
+ const meta = readSidecarMeta(join19(dir, `${sessionId}.meta.json`));
10273
10342
  return { projectDir: dir, channel: meta.channel, accountId: meta.accountId };
10274
10343
  }
10275
10344
  function locateSidecar(sessionId) {
10276
10345
  const cfg = claudeConfigDir();
10277
10346
  if (!cfg) return null;
10278
- const projectsRoot = join18(cfg, "projects");
10347
+ const projectsRoot = join19(cfg, "projects");
10279
10348
  let slugs;
10280
10349
  try {
10281
- slugs = readdirSync11(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
10350
+ slugs = readdirSync12(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
10282
10351
  } catch {
10283
10352
  return null;
10284
10353
  }
10285
10354
  for (const slug of slugs) {
10286
- const metaPath = join18(projectsRoot, slug, `${sessionId}.meta.json`);
10287
- if (existsSync11(metaPath)) {
10355
+ const metaPath = join19(projectsRoot, slug, `${sessionId}.meta.json`);
10356
+ if (existsSync12(metaPath)) {
10288
10357
  const meta = readSidecarMeta(metaPath);
10289
10358
  return { channel: meta.channel, adminUserId: meta.adminUserId, accountId: meta.accountId };
10290
10359
  }
@@ -10296,7 +10365,7 @@ function readTargetOwner(sessionId) {
10296
10365
  if (sidecar !== null) return { found: true, owner: sidecar.adminUserId };
10297
10366
  const { projectDir } = locateSession(sessionId);
10298
10367
  if (projectDir !== null) {
10299
- return { found: true, owner: readSidecarMeta(join18(projectDir, `${sessionId}.meta.json`)).adminUserId };
10368
+ return { found: true, owner: readSidecarMeta(join19(projectDir, `${sessionId}.meta.json`)).adminUserId };
10300
10369
  }
10301
10370
  return { found: false, owner: null };
10302
10371
  }
@@ -10310,7 +10379,7 @@ function sessionSidecarExists(sessionId) {
10310
10379
  function jsonlSizeBytes(projectDir, sessionId) {
10311
10380
  if (projectDir === null) return null;
10312
10381
  try {
10313
- return statSync7(join18(projectDir, `${sessionId}.jsonl`)).size;
10382
+ return statSync7(join19(projectDir, `${sessionId}.jsonl`)).size;
10314
10383
  } catch {
10315
10384
  return null;
10316
10385
  }
@@ -10446,10 +10515,10 @@ function latestAdminWebchatSessionId(requesterUserId, primaryUserId, scopeAccoun
10446
10515
  const cfg = claudeConfigDir();
10447
10516
  if (!cfg) return null;
10448
10517
  let best = null;
10449
- for (const { path: path2, isSubagent, archived } of enumerateJsonls(join18(cfg, "projects"))) {
10518
+ for (const { path: path2, isSubagent, archived } of enumerateJsonls(join19(cfg, "projects"))) {
10450
10519
  if (isSubagent || archived) continue;
10451
- const id = basename7(path2).slice(0, -".jsonl".length);
10452
- const meta = readSidecarMeta(join18(dirname6(path2), `${id}.meta.json`));
10520
+ const id = basename6(path2).slice(0, -".jsonl".length);
10521
+ const meta = readSidecarMeta(join19(dirname6(path2), `${id}.meta.json`));
10453
10522
  if (meta.role !== "admin" || meta.channel !== "webchat") continue;
10454
10523
  if (multiAccount && meta.accountId !== scopeAccountId) continue;
10455
10524
  let mtimeMs;
@@ -10472,7 +10541,7 @@ function latestAdminWebchatSessionId(requesterUserId, primaryUserId, scopeAccoun
10472
10541
  function overrideKnownNonArchived(id) {
10473
10542
  const { projectDir } = locateSession(id);
10474
10543
  if (projectDir === null) return sessionSidecarExists(id);
10475
- return basename7(projectDir) !== "archive";
10544
+ return basename6(projectDir) !== "archive";
10476
10545
  }
10477
10546
  function resolveCanonical(accountId, accountDir, requesterUserId, primaryUserId, scopeAccountId, multiAccount) {
10478
10547
  const bootstrapAccountId = scopeAccountId ?? accountId;
@@ -10508,8 +10577,8 @@ async function reapplyLeversViaManager() {
10508
10577
  var WEBCHAT_SEND_TURN_WINDOW_MS = Number(process.env.WEBCHAT_SEND_TURN_WINDOW_MS ?? String(15e3));
10509
10578
  var sendSeq = 0;
10510
10579
  function createWebchatRoutes(deps) {
10511
- const app61 = new Hono();
10512
- app61.post("/send", requireAdminSession, async (c) => {
10580
+ const app62 = new Hono();
10581
+ app62.post("/send", requireAdminSession, async (c) => {
10513
10582
  let accountId;
10514
10583
  try {
10515
10584
  accountId = resolvePlatformAccountId();
@@ -10709,7 +10778,7 @@ ${note}` : note;
10709
10778
  if (turnTimer.unref) turnTimer.unref();
10710
10779
  return c.json({ ok: true });
10711
10780
  });
10712
- app61.post("/interrupt", requireAdminSession, async (c) => {
10781
+ app62.post("/interrupt", requireAdminSession, async (c) => {
10713
10782
  const cacheKey = c.get("cacheKey");
10714
10783
  const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
10715
10784
  const primaryUserId = resolvePrimaryAdminUserId();
@@ -10737,7 +10806,7 @@ ${note}` : note;
10737
10806
  }
10738
10807
  return c.json({ ok: true, stopped: outcome.stopped, intId: outcome.intId, deadChild: outcome.deadChild }, 200);
10739
10808
  });
10740
- app61.post("/settings", requireAdminSession, async (c) => {
10809
+ app62.post("/settings", requireAdminSession, async (c) => {
10741
10810
  const body = await c.req.json().catch(() => null);
10742
10811
  const op = body?.op;
10743
10812
  const value = body?.value;
@@ -10759,7 +10828,7 @@ ${note}` : note;
10759
10828
  console.error(`[webchat:settings] op=${op} outcome=refused value=${value} reason=account-unresolved`);
10760
10829
  return c.json({ error: "account unresolved" }, 503);
10761
10830
  }
10762
- const accountJsonPath = join18(account.accountDir, "account.json");
10831
+ const accountJsonPath = join19(account.accountDir, "account.json");
10763
10832
  try {
10764
10833
  const parsed = JSON.parse(readFileSync19(accountJsonPath, "utf8"));
10765
10834
  if (op === "model") parsed.adminModel = value;
@@ -10777,7 +10846,7 @@ ${note}` : note;
10777
10846
  console.log(`[webchat:settings] op=${op} outcome=accepted value=${value} settingsApplied=${settingsApplied}`);
10778
10847
  return c.json({ ok: true, settingsApplied });
10779
10848
  });
10780
- app61.get("/session", requireAdminSession, async (c) => {
10849
+ app62.get("/session", requireAdminSession, async (c) => {
10781
10850
  let accountId;
10782
10851
  try {
10783
10852
  accountId = resolvePlatformAccountId();
@@ -10807,7 +10876,7 @@ ${note}` : note;
10807
10876
  const cfg2 = claudeConfigDir();
10808
10877
  if (cfg2) {
10809
10878
  const source2 = resolveBridgeSource(
10810
- join18(cfg2, "sessions"),
10879
+ join19(cfg2, "sessions"),
10811
10880
  target,
10812
10881
  (id) => locateSession(id).projectDir !== null
10813
10882
  );
@@ -10839,15 +10908,15 @@ ${note}` : note;
10839
10908
  const cfg = claudeConfigDir();
10840
10909
  let projectDir = null;
10841
10910
  if (cfg) {
10842
- for (const { path: path2 } of enumerateJsonls(join18(cfg, "projects"))) {
10843
- if (basename7(path2) === `${sessionId}.jsonl`) {
10911
+ for (const { path: path2 } of enumerateJsonls(join19(cfg, "projects"))) {
10912
+ if (basename6(path2) === `${sessionId}.jsonl`) {
10844
10913
  projectDir = dirname6(path2);
10845
10914
  break;
10846
10915
  }
10847
10916
  }
10848
10917
  }
10849
10918
  if (source === "latest" && requesterUserId !== null) {
10850
- const owner = readSidecarMeta(join18(projectDir ?? "", `${sessionId}.meta.json`)).adminUserId;
10919
+ const owner = readSidecarMeta(join19(projectDir ?? "", `${sessionId}.meta.json`)).adminUserId;
10851
10920
  if (owner !== null && owner !== requesterUserId && requesterUserId !== primaryUserId) {
10852
10921
  console.error(`[webchat:inbound] op=session-resolve-foreign key=${sessionId.slice(0, 8)} owner=${owner.slice(0, 8)} requester=${requesterUserId.slice(0, 8)}`);
10853
10922
  }
@@ -10855,7 +10924,7 @@ ${note}` : note;
10855
10924
  const indicators = await fetchComposerIndicators(sessionId);
10856
10925
  return c.json({ sessionId, projectDir, sizeBytes: jsonlSizeBytes(projectDir, sessionId), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${sessionId}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${sessionId}`) ?? null, ...indicators, ...readLevers(account) });
10857
10926
  });
10858
- app61.post("/permission-verdict", requireAdminSession, async (c) => {
10927
+ app62.post("/permission-verdict", requireAdminSession, async (c) => {
10859
10928
  const body = await c.req.json().catch(() => null);
10860
10929
  const sessionId = body?.sessionId;
10861
10930
  const requestId = body?.request_id;
@@ -10872,15 +10941,15 @@ ${note}` : note;
10872
10941
  const ok = deps.resolvePermissionVerdict?.(`session:${sessionId}`, requestId, behavior) ?? false;
10873
10942
  return c.json({ ok });
10874
10943
  });
10875
- return app61;
10944
+ return app62;
10876
10945
  }
10877
10946
 
10878
10947
  // server/routes/webchat-greeting.ts
10879
10948
  import { resolve as resolve14 } from "path";
10880
10949
 
10881
10950
  // app/lib/claude-agent/specialist-roster.ts
10882
- import { existsSync as existsSync12, readFileSync as readFileSync20, readdirSync as readdirSync12 } from "fs";
10883
- import { join as join19 } from "path";
10951
+ import { existsSync as existsSync13, readFileSync as readFileSync20, readdirSync as readdirSync13 } from "fs";
10952
+ import { join as join20 } from "path";
10884
10953
  function field(fm, name) {
10885
10954
  const m = fm.match(new RegExp(`^${name}:\\s*(.*?)\\r?$`, "m"));
10886
10955
  if (!m) return null;
@@ -10891,15 +10960,15 @@ function field(fm, name) {
10891
10960
  return value || null;
10892
10961
  }
10893
10962
  function readSpecialistRoster(specialistsDir) {
10894
- if (!existsSync12(specialistsDir)) return { specialists: [], skipped: [] };
10895
- const entries = readdirSync12(specialistsDir);
10963
+ if (!existsSync13(specialistsDir)) return { specialists: [], skipped: [] };
10964
+ const entries = readdirSync13(specialistsDir);
10896
10965
  const specialists = [];
10897
10966
  const skipped = [];
10898
10967
  for (const file of entries.sort()) {
10899
10968
  if (!file.endsWith(".md")) continue;
10900
10969
  let raw;
10901
10970
  try {
10902
- raw = readFileSync20(join19(specialistsDir, file), "utf-8");
10971
+ raw = readFileSync20(join20(specialistsDir, file), "utf-8");
10903
10972
  } catch (err) {
10904
10973
  skipped.push({ file, reason: err instanceof Error ? err.message : String(err) });
10905
10974
  continue;
@@ -11015,9 +11084,9 @@ function r2n(value) {
11015
11084
  var webchat_greeting_default = app6;
11016
11085
 
11017
11086
  // server/routes/telegram.ts
11018
- import { homedir } from "os";
11019
- import { resolve as resolve15, join as join20 } from "path";
11020
- import { existsSync as existsSync13, readFileSync as readFileSync21 } from "fs";
11087
+ import { homedir as homedir2 } from "os";
11088
+ import { resolve as resolve15, join as join21 } from "path";
11089
+ import { existsSync as existsSync14, readFileSync as readFileSync21 } from "fs";
11021
11090
 
11022
11091
  // app/lib/telegram/gateway/instance.ts
11023
11092
  var instance = null;
@@ -11076,8 +11145,8 @@ function routeTelegramUpdate(input) {
11076
11145
  var TAG23 = "[telegram-inbound]";
11077
11146
  function configDirName() {
11078
11147
  const platformRoot3 = process.env.MAXY_PLATFORM_ROOT ?? resolve15(process.cwd(), "..");
11079
- const brandPath = join20(platformRoot3, "config", "brand.json");
11080
- if (existsSync13(brandPath)) {
11148
+ const brandPath = join21(platformRoot3, "config", "brand.json");
11149
+ if (existsSync14(brandPath)) {
11081
11150
  try {
11082
11151
  return JSON.parse(readFileSync21(brandPath, "utf-8")).configDir ?? ".maxy";
11083
11152
  } catch {
@@ -11087,7 +11156,7 @@ function configDirName() {
11087
11156
  }
11088
11157
  function secretPath(botType) {
11089
11158
  const filename = botType === "admin" ? ".telegram-admin-webhook-secret" : ".telegram-webhook-secret";
11090
- return resolve15(homedir(), configDirName(), filename);
11159
+ return resolve15(homedir2(), configDirName(), filename);
11091
11160
  }
11092
11161
  var app7 = new Hono();
11093
11162
  app7.post("/", async (c) => {
@@ -11098,7 +11167,7 @@ app7.post("/", async (c) => {
11098
11167
  return c.json({ ok: false }, 400);
11099
11168
  }
11100
11169
  const sp = secretPath(botType);
11101
- if (!existsSync13(sp)) {
11170
+ if (!existsSync14(sp)) {
11102
11171
  console.error(`${TAG23} op=reject reason=no-secret-file botType=${botType}`);
11103
11172
  return c.json({ ok: false }, 401);
11104
11173
  }
@@ -11165,21 +11234,21 @@ app7.post("/", async (c) => {
11165
11234
  var telegram_default = app7;
11166
11235
 
11167
11236
  // server/routes/quickbooks.ts
11168
- import { join as join21 } from "path";
11169
- import { existsSync as existsSync14, readFileSync as readFileSync22, writeFileSync as writeFileSync8, mkdirSync as mkdirSync4, rmSync, renameSync as renameSync5 } from "fs";
11237
+ import { join as join22 } from "path";
11238
+ import { existsSync as existsSync15, readFileSync as readFileSync22, writeFileSync as writeFileSync8, mkdirSync as mkdirSync4, rmSync, renameSync as renameSync5 } from "fs";
11170
11239
  var TAG24 = "[quickbooks]";
11171
11240
  var INTUIT_TOKEN_URL = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer";
11172
11241
  var STATE_RE = /^[A-Za-z0-9_-]+$/;
11173
11242
  function pendingPath(accountDir, state) {
11174
- return join21(accountDir, "secrets", "quickbooks-pending", `${state}.json`);
11243
+ return join22(accountDir, "secrets", "quickbooks-pending", `${state}.json`);
11175
11244
  }
11176
11245
  function storePath(accountDir) {
11177
- return join21(accountDir, "secrets", "quickbooks.json");
11246
+ return join22(accountDir, "secrets", "quickbooks.json");
11178
11247
  }
11179
11248
  async function completeConsent(args) {
11180
11249
  const { accountDir, code, realmId } = args;
11181
11250
  const state = args.state;
11182
- if (!state || !STATE_RE.test(state) || !existsSync14(pendingPath(accountDir, state))) {
11251
+ if (!state || !STATE_RE.test(state) || !existsSync15(pendingPath(accountDir, state))) {
11183
11252
  console.error(`${TAG24} op=callback state=${state ?? ""} stateValid=false realmId=${realmId ?? ""}`);
11184
11253
  return { ok: false, status: 400, message: "Invalid or unknown authorization state.", stateValid: false };
11185
11254
  }
@@ -11206,7 +11275,7 @@ async function completeConsent(args) {
11206
11275
  if (!code || !realmId) {
11207
11276
  return { ok: false, status: 400, message: "Missing code or realmId in the callback.", stateValid: true };
11208
11277
  }
11209
- if (!existsSync14(storePath(accountDir))) {
11278
+ if (!existsSync15(storePath(accountDir))) {
11210
11279
  return { ok: false, status: 500, message: "No QuickBooks credentials are stored for this account.", stateValid: true };
11211
11280
  }
11212
11281
  const store2 = JSON.parse(readFileSync22(storePath(accountDir), "utf-8"));
@@ -11241,7 +11310,7 @@ async function completeConsent(args) {
11241
11310
  refreshTokenExpiry: now + (body.x_refresh_token_expires_in ?? 864e4) * 1e3,
11242
11311
  lastRefresh: now
11243
11312
  };
11244
- mkdirSync4(join21(accountDir, "secrets"), { recursive: true });
11313
+ mkdirSync4(join22(accountDir, "secrets"), { recursive: true });
11245
11314
  writeFileSync8(storePath(accountDir), JSON.stringify(store2, null, 2), { mode: 384 });
11246
11315
  const persisted = JSON.parse(readFileSync22(storePath(accountDir), "utf-8")).connections?.[realmId]?.refreshToken === body.refresh_token;
11247
11316
  console.error(`${TAG24} op=token-exchange realmId=${realmId} persisted=${persisted}`);
@@ -11274,7 +11343,7 @@ var quickbooks_default = app8;
11274
11343
 
11275
11344
  // server/routes/onboarding.ts
11276
11345
  import { spawn, spawnSync as spawnSync2, execFileSync as execFileSync3 } from "child_process";
11277
- import { openSync as openSync3, closeSync as closeSync3, writeFileSync as writeFileSync10, writeSync, existsSync as existsSync16, readFileSync as readFileSync24, unlinkSync as unlinkSync3, renameSync as renameSync7 } from "fs";
11346
+ import { openSync as openSync3, closeSync as closeSync3, writeFileSync as writeFileSync10, writeSync, existsSync as existsSync17, readFileSync as readFileSync24, unlinkSync as unlinkSync3, renameSync as renameSync7 } from "fs";
11278
11347
  import { createHash as createHash4, randomUUID as randomUUID7 } from "crypto";
11279
11348
 
11280
11349
  // app/lib/claude-spawn-env.ts
@@ -11283,7 +11352,7 @@ function claudeBin() {
11283
11352
  }
11284
11353
 
11285
11354
  // server/routes/onboarding.ts
11286
- import { dirname as dirname8, join as join23 } from "path";
11355
+ import { dirname as dirname8, join as join24 } from "path";
11287
11356
 
11288
11357
  // app/lib/claude-keychain.ts
11289
11358
  import { execFileSync as execFileSync2 } from "child_process";
@@ -11412,8 +11481,8 @@ function readHostCredsBlob(service) {
11412
11481
  }
11413
11482
 
11414
11483
  // ../lib/admins-write/src/index.ts
11415
- import { existsSync as existsSync15, readFileSync as readFileSync23, writeFileSync as writeFileSync9, renameSync as renameSync6, mkdirSync as mkdirSync5, readdirSync as readdirSync13, statSync as statSync8, appendFileSync as appendFileSync2 } from "fs";
11416
- import { dirname as dirname7, join as join22 } from "path";
11484
+ import { existsSync as existsSync16, readFileSync as readFileSync23, writeFileSync as writeFileSync9, renameSync as renameSync6, mkdirSync as mkdirSync5, readdirSync as readdirSync14, statSync as statSync8, appendFileSync as appendFileSync2 } from "fs";
11485
+ import { dirname as dirname7, join as join23 } from "path";
11417
11486
  function id8(value) {
11418
11487
  return value.slice(0, 8);
11419
11488
  }
@@ -11453,7 +11522,7 @@ function writeAdminEntry(input) {
11453
11522
  const result = { usersJsonResult: "noop", accountJsonResult: "noop" };
11454
11523
  try {
11455
11524
  let users = [];
11456
- if (existsSync15(input.usersFile)) {
11525
+ if (existsSync16(input.usersFile)) {
11457
11526
  const raw = readFileSync23(input.usersFile, "utf-8").trim();
11458
11527
  if (raw) {
11459
11528
  const parsed = JSON.parse(raw);
@@ -11485,8 +11554,8 @@ function writeAdminEntry(input) {
11485
11554
  return result;
11486
11555
  }
11487
11556
  try {
11488
- const accountJsonPath = join22(input.accountDir, "account.json");
11489
- if (!existsSync15(accountJsonPath)) {
11557
+ const accountJsonPath = join23(input.accountDir, "account.json");
11558
+ if (!existsSync16(accountJsonPath)) {
11490
11559
  throw new Error(`account.json not found at ${accountJsonPath}`);
11491
11560
  }
11492
11561
  const config = JSON.parse(readFileSync23(accountJsonPath, "utf-8"));
@@ -11509,7 +11578,7 @@ function writeAdminEntry(input) {
11509
11578
  function computeAdminStoreDivergence(input) {
11510
11579
  const result = { divergences: 0, accountWithoutUsers: [], usersWithoutAccount: [], errors: [] };
11511
11580
  const usersUserIds = /* @__PURE__ */ new Set();
11512
- if (existsSync15(input.usersFile)) {
11581
+ if (existsSync16(input.usersFile)) {
11513
11582
  try {
11514
11583
  const raw = readFileSync23(input.usersFile, "utf-8").trim();
11515
11584
  if (raw) {
@@ -11523,24 +11592,24 @@ function computeAdminStoreDivergence(input) {
11523
11592
  }
11524
11593
  }
11525
11594
  const accountUserIds = /* @__PURE__ */ new Set();
11526
- if (existsSync15(input.accountsDir)) {
11595
+ if (existsSync16(input.accountsDir)) {
11527
11596
  let entries;
11528
11597
  try {
11529
- entries = readdirSync13(input.accountsDir);
11598
+ entries = readdirSync14(input.accountsDir);
11530
11599
  } catch (err) {
11531
11600
  result.errors.push({ source: input.accountsDir, detail: err instanceof Error ? err.message : String(err) });
11532
11601
  return result;
11533
11602
  }
11534
11603
  for (const entry of entries) {
11535
11604
  if (entry.startsWith(".")) continue;
11536
- const accountDir = join22(input.accountsDir, entry);
11605
+ const accountDir = join23(input.accountsDir, entry);
11537
11606
  try {
11538
11607
  if (!statSync8(accountDir).isDirectory()) continue;
11539
11608
  } catch {
11540
11609
  continue;
11541
11610
  }
11542
- const accountJsonPath = join22(accountDir, "account.json");
11543
- if (!existsSync15(accountJsonPath)) continue;
11611
+ const accountJsonPath = join23(accountDir, "account.json");
11612
+ if (!existsSync16(accountJsonPath)) continue;
11544
11613
  let admins = [];
11545
11614
  try {
11546
11615
  const config = JSON.parse(readFileSync23(accountJsonPath, "utf-8"));
@@ -11591,7 +11660,7 @@ function hashPin2(pin) {
11591
11660
  return createHash4("sha256").update(pin).digest("hex");
11592
11661
  }
11593
11662
  function readUsersFile2() {
11594
- if (!existsSync16(USERS_FILE)) return null;
11663
+ if (!existsSync17(USERS_FILE)) return null;
11595
11664
  const raw = readFileSync24(USERS_FILE, "utf-8").trim();
11596
11665
  if (!raw) return [];
11597
11666
  return JSON.parse(raw);
@@ -11651,7 +11720,7 @@ app9.post("/claude-auth", async (c) => {
11651
11720
  } catch (err) {
11652
11721
  logoutError = err instanceof Error ? err.message : String(err);
11653
11722
  }
11654
- const credentialsPresent = existsSync16(CLAUDE_CREDENTIALS_FILE);
11723
+ const credentialsPresent = existsSync17(CLAUDE_CREDENTIALS_FILE);
11655
11724
  const ranMs = Date.now() - start;
11656
11725
  console.log(`[onboarding] op=claude-logout credentialsPresent=${credentialsPresent} ranMs=${ranMs} logoutError=${logoutError ? JSON.stringify(logoutError.slice(0, 120)) : "none"}`);
11657
11726
  return c.json({ logged_out: !credentialsPresent });
@@ -11717,7 +11786,7 @@ app9.post("/claude-auth", async (c) => {
11717
11786
  });
11718
11787
  persistKeychainService(
11719
11788
  writebackResult,
11720
- (service) => writeFileSync10(join23(dirname8(CLAUDE_CREDENTIALS_FILE), ".keychain-service"), service, { mode: 384 }),
11789
+ (service) => writeFileSync10(join24(dirname8(CLAUDE_CREDENTIALS_FILE), ".keychain-service"), service, { mode: 384 }),
11721
11790
  (line) => console.log(line)
11722
11791
  );
11723
11792
  if (darwinAuthChild === claudeProc2) darwinAuthChild = null;
@@ -11800,7 +11869,7 @@ app9.post("/set-pin", async (c) => {
11800
11869
  console.log(`[set-pin] wrote users.json + account.json admins: userId=${userId.slice(0, 8)}\u2026 role=owner`);
11801
11870
  if (process.platform === "linux") {
11802
11871
  let installOwner = null;
11803
- if (existsSync16(INSTALL_OWNER_FILE)) {
11872
+ if (existsSync17(INSTALL_OWNER_FILE)) {
11804
11873
  try {
11805
11874
  const raw = readFileSync24(INSTALL_OWNER_FILE, "utf-8").trim();
11806
11875
  if (raw.length > 0) installOwner = raw;
@@ -11948,7 +12017,7 @@ app9.put("/set-pin", requireAdminSession, async (c) => {
11948
12017
  console.log(`[set-pin] changed PIN in place: userId=${sessionUserId.slice(0, 8)}\u2026`);
11949
12018
  if (process.platform === "linux") {
11950
12019
  let installOwner = null;
11951
- if (existsSync16(INSTALL_OWNER_FILE)) {
12020
+ if (existsSync17(INSTALL_OWNER_FILE)) {
11952
12021
  try {
11953
12022
  const raw = readFileSync24(INSTALL_OWNER_FILE, "utf-8").trim();
11954
12023
  if (raw.length > 0) installOwner = raw;
@@ -11982,9 +12051,9 @@ ${body.newPin}
11982
12051
  var onboarding_default = app9;
11983
12052
 
11984
12053
  // server/routes/client-error.ts
11985
- import { appendFileSync as appendFileSync3, existsSync as existsSync17, renameSync as renameSync8, statSync as statSync9 } from "fs";
11986
- import { join as join24 } from "path";
11987
- var CLIENT_ERRORS_LOG = join24(LOG_DIR, "client-errors.log");
12054
+ import { appendFileSync as appendFileSync3, existsSync as existsSync18, renameSync as renameSync8, statSync as statSync9 } from "fs";
12055
+ import { join as join25 } from "path";
12056
+ var CLIENT_ERRORS_LOG = join25(LOG_DIR, "client-errors.log");
11988
12057
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
11989
12058
  var MAX_BODY_SIZE = 8 * 1024;
11990
12059
  var MAX_STACK_LEN = 2e3;
@@ -12032,7 +12101,7 @@ function stackHead(stack) {
12032
12101
  }
12033
12102
  function rotateIfNeeded() {
12034
12103
  try {
12035
- if (!existsSync17(CLIENT_ERRORS_LOG)) return;
12104
+ if (!existsSync18(CLIENT_ERRORS_LOG)) return;
12036
12105
  const stats = statSync9(CLIENT_ERRORS_LOG);
12037
12106
  if (stats.size < MAX_LOG_SIZE) return;
12038
12107
  renameSync8(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
@@ -12352,18 +12421,18 @@ app12.get("/", requireAdminSession, async (c) => {
12352
12421
  var accounts_default = app12;
12353
12422
 
12354
12423
  // server/routes/admin/logs.ts
12355
- import { existsSync as existsSync19, readdirSync as readdirSync14, readFileSync as readFileSync25, statSync as statSync10 } from "fs";
12356
- import { resolve as resolve16, basename as basename8 } from "path";
12424
+ import { existsSync as existsSync20, readdirSync as readdirSync15, readFileSync as readFileSync25, statSync as statSync10 } from "fs";
12425
+ import { resolve as resolve16, basename as basename7 } from "path";
12357
12426
 
12358
12427
  // app/lib/logs-read-resolve.ts
12359
- import { existsSync as existsSync18 } from "fs";
12360
- import { join as join25 } from "path";
12428
+ import { existsSync as existsSync19 } from "fs";
12429
+ import { join as join26 } from "path";
12361
12430
  function resolveSessionLogPaths(filename, logDirs) {
12362
12431
  const tried = [filename];
12363
12432
  const hits = [];
12364
12433
  for (const dir of logDirs) {
12365
- const fullPath = join25(dir, filename);
12366
- if (existsSync18(fullPath)) {
12434
+ const fullPath = join26(dir, filename);
12435
+ if (existsSync19(fullPath)) {
12367
12436
  hits.push({ path: fullPath, dir });
12368
12437
  }
12369
12438
  }
@@ -12385,7 +12454,7 @@ app13.get("/", async (c) => {
12385
12454
  if (accountLogDir) logDirs.push(accountLogDir);
12386
12455
  logDirs.push(LOG_DIR);
12387
12456
  if (fileParam) {
12388
- const safe = basename8(fileParam);
12457
+ const safe = basename7(fileParam);
12389
12458
  const searched = [];
12390
12459
  for (const dir of logDirs) {
12391
12460
  const filePath = resolve16(dir, safe);
@@ -12455,7 +12524,7 @@ app13.get("/", async (c) => {
12455
12524
  if (hit) {
12456
12525
  console.info(`[admin/logs] resolved cacheKey=${cacheKeySlice} sessionId=${sessionIdSlice} via=${primaryId === cacheKey ? "cacheKey" : primaryId === sessionKeyFromConv ? "reverse-lookup" : "sessionId-fallback"}`);
12457
12526
  try {
12458
- const filename = basename8(hit.path);
12527
+ const filename = basename7(hit.path);
12459
12528
  const buffer = readFileSync25(hit.path);
12460
12529
  const onDiskBytes = statSync10(hit.path).size;
12461
12530
  const headers = {
@@ -12491,10 +12560,10 @@ app13.get("/", async (c) => {
12491
12560
  const seen = /* @__PURE__ */ new Set();
12492
12561
  const logs = {};
12493
12562
  for (const dir of logDirs) {
12494
- if (!existsSync19(dir)) continue;
12563
+ if (!existsSync20(dir)) continue;
12495
12564
  let files;
12496
12565
  try {
12497
- files = readdirSync14(dir).filter((f) => f.endsWith(".log"));
12566
+ files = readdirSync15(dir).filter((f) => f.endsWith(".log"));
12498
12567
  } catch (err) {
12499
12568
  const reason = err instanceof Error ? err.message : String(err);
12500
12569
  console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
@@ -12543,7 +12612,7 @@ var claude_info_default = app14;
12543
12612
 
12544
12613
  // server/routes/admin/attachment.ts
12545
12614
  import { readFile as readFile2, readdir } from "fs/promises";
12546
- import { existsSync as existsSync20 } from "fs";
12615
+ import { existsSync as existsSync21 } from "fs";
12547
12616
  import { resolve as resolve17 } from "path";
12548
12617
  var app15 = new Hono();
12549
12618
  var ATTACHMENT_ID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
@@ -12566,12 +12635,12 @@ app15.get("/:attachmentId", requireAdminSession, async (c) => {
12566
12635
  }
12567
12636
  let accountId = pinnedAccountId;
12568
12637
  let dir = uploadsDirFor2(accountId, attachmentId);
12569
- let found = existsSync20(dir);
12638
+ let found = existsSync21(dir);
12570
12639
  if (!found) {
12571
12640
  for (const candidate of listValidAccounts()) {
12572
12641
  if (candidate.accountId === pinnedAccountId) continue;
12573
12642
  const candidateDir = uploadsDirFor2(candidate.accountId, attachmentId);
12574
- if (existsSync20(candidateDir)) {
12643
+ if (existsSync21(candidateDir)) {
12575
12644
  accountId = candidate.accountId;
12576
12645
  dir = candidateDir;
12577
12646
  found = true;
@@ -12586,7 +12655,7 @@ app15.get("/:attachmentId", requireAdminSession, async (c) => {
12586
12655
  return new Response("Not found", { status: 404 });
12587
12656
  }
12588
12657
  const metaPath = resolve17(dir, `${attachmentId}.meta.json`);
12589
- if (!existsSync20(metaPath)) {
12658
+ if (!existsSync21(metaPath)) {
12590
12659
  return new Response("Not found", { status: 404 });
12591
12660
  }
12592
12661
  let meta;
@@ -12614,21 +12683,21 @@ var attachment_default = app15;
12614
12683
 
12615
12684
  // server/routes/admin/agents.ts
12616
12685
  import { resolve as resolve18 } from "path";
12617
- import { readdirSync as readdirSync15, readFileSync as readFileSync26, existsSync as existsSync21, rmSync as rmSync2 } from "fs";
12686
+ import { readdirSync as readdirSync16, readFileSync as readFileSync26, existsSync as existsSync22, rmSync as rmSync2 } from "fs";
12618
12687
  var app16 = new Hono();
12619
12688
  app16.get("/", (c) => {
12620
12689
  const account = resolveAccount();
12621
12690
  if (!account) return c.json({ agents: [] });
12622
12691
  const agentsDir = resolve18(account.accountDir, "agents");
12623
- if (!existsSync21(agentsDir)) return c.json({ agents: [] });
12692
+ if (!existsSync22(agentsDir)) return c.json({ agents: [] });
12624
12693
  const agents = [];
12625
12694
  try {
12626
- const entries = readdirSync15(agentsDir, { withFileTypes: true });
12695
+ const entries = readdirSync16(agentsDir, { withFileTypes: true });
12627
12696
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
12628
12697
  if (!entry.isDirectory()) continue;
12629
12698
  if (entry.name === "admin") continue;
12630
12699
  const configPath2 = resolve18(agentsDir, entry.name, "config.json");
12631
- if (!existsSync21(configPath2)) continue;
12700
+ if (!existsSync22(configPath2)) continue;
12632
12701
  try {
12633
12702
  const config = JSON.parse(readFileSync26(configPath2, "utf-8"));
12634
12703
  agents.push({
@@ -12657,7 +12726,7 @@ app16.delete("/:slug", async (c) => {
12657
12726
  return c.json({ error: "Invalid agent slug" }, 400);
12658
12727
  }
12659
12728
  const agentDir = resolve18(account.accountDir, "agents", slug);
12660
- if (!existsSync21(agentDir)) {
12729
+ if (!existsSync22(agentDir)) {
12661
12730
  return c.json({ error: "Agent not found" }, 404);
12662
12731
  }
12663
12732
  try {
@@ -12687,7 +12756,7 @@ app16.post("/:slug/project", async (c) => {
12687
12756
  return c.json({ error: "Invalid agent slug" }, 400);
12688
12757
  }
12689
12758
  const agentDir = resolve18(account.accountDir, "agents", slug);
12690
- if (!existsSync21(agentDir)) {
12759
+ if (!existsSync22(agentDir)) {
12691
12760
  return c.json({ error: "Agent not found on disk" }, 404);
12692
12761
  }
12693
12762
  try {
@@ -12703,7 +12772,7 @@ var agents_default = app16;
12703
12772
  // server/routes/admin/sessions.ts
12704
12773
  import crypto2 from "crypto";
12705
12774
  import { resolve as resolvePath } from "path";
12706
- import { existsSync as existsSync22, mkdirSync as mkdirSync6, createWriteStream } from "fs";
12775
+ import { existsSync as existsSync23, mkdirSync as mkdirSync6, createWriteStream } from "fs";
12707
12776
 
12708
12777
  // ../lib/admin-conversation-purge/src/index.ts
12709
12778
  async function purgeAdminConversationJsonls(args) {
@@ -12841,7 +12910,7 @@ var replayJsonl = (..._args) => null;
12841
12910
  var resolveJsonlPath = (..._args) => null;
12842
12911
 
12843
12912
  // server/routes/admin/sessions.ts
12844
- import { homedir as homedir2 } from "os";
12913
+ import { homedir as homedir3 } from "os";
12845
12914
 
12846
12915
  // app/lib/claude-agent/component-attachment.ts
12847
12916
  var pickComponentBytes = (..._args) => null;
@@ -12863,7 +12932,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, sessionId, mes
12863
12932
  let reason = null;
12864
12933
  if (!a.attachmentId || !a.filename || !a.mimeType || !a.storagePath) reason = "schema-fail";
12865
12934
  else if (a.accountId !== conversationAccountId) reason = "account-mismatch";
12866
- else if (!existsSync22(a.storagePath)) reason = "missing-file";
12935
+ else if (!existsSync23(a.storagePath)) reason = "missing-file";
12867
12936
  if (reason) {
12868
12937
  invalid++;
12869
12938
  try {
@@ -13156,7 +13225,7 @@ app17.post("/:id/resume", async (c) => {
13156
13225
  return c.json({ error: "Failed to load conversation messages" }, 500);
13157
13226
  }
13158
13227
  if (persistedAgentSessionId) {
13159
- const jsonlPath = resolveJsonlPath(homedir2(), resolvePath(ACCOUNTS_DIR, accountId), persistedAgentSessionId);
13228
+ const jsonlPath = resolveJsonlPath(homedir3(), resolvePath(ACCOUNTS_DIR, accountId), persistedAgentSessionId);
13160
13229
  const replay = replayJsonl(jsonlPath);
13161
13230
  jsonlMissing = replay.jsonlMissing;
13162
13231
  jsonlMalformedLines = replay.malformedLines;
@@ -13389,8 +13458,8 @@ app17.put("/:id/label", requireAdminSession, async (c) => {
13389
13458
  var sessions_default = app17;
13390
13459
 
13391
13460
  // app/lib/claude-agent/spawn-context.ts
13392
- import { existsSync as existsSync23, readFileSync as readFileSync27, readdirSync as readdirSync16, statSync as statSync11 } from "fs";
13393
- import { dirname as dirname9, resolve as resolve19, join as join26 } from "path";
13461
+ import { existsSync as existsSync24, readFileSync as readFileSync27, readdirSync as readdirSync17, statSync as statSync11 } from "fs";
13462
+ import { dirname as dirname9, resolve as resolve19, join as join27 } from "path";
13394
13463
  async function resolveOwnerProfileBlock(accountId, userId) {
13395
13464
  if (!userId) return { ok: false, reason: "missing-user-id" };
13396
13465
  try {
@@ -13431,12 +13500,12 @@ function frontmatterField(manifest, field2) {
13431
13500
  function extractPluginToolDescriptions(pluginDir) {
13432
13501
  const out = /* @__PURE__ */ new Map();
13433
13502
  const candidates = [
13434
- join26(pluginDir, "mcp/dist/index.js"),
13435
- join26(pluginDir, "mcp/src/index.ts")
13503
+ join27(pluginDir, "mcp/dist/index.js"),
13504
+ join27(pluginDir, "mcp/src/index.ts")
13436
13505
  ];
13437
13506
  let raw = null;
13438
13507
  for (const path2 of candidates) {
13439
- if (!existsSync23(path2)) continue;
13508
+ if (!existsSync24(path2)) continue;
13440
13509
  try {
13441
13510
  raw = readFileSync27(path2, "utf-8");
13442
13511
  break;
@@ -13488,9 +13557,9 @@ function parseSkillPathsFromFrontmatter(fm) {
13488
13557
  function listPluginDirs() {
13489
13558
  const out = /* @__PURE__ */ new Map();
13490
13559
  const platformPlugins = resolve19(PLATFORM_ROOT, "plugins");
13491
- if (existsSync23(platformPlugins)) {
13492
- for (const name of readdirSync16(platformPlugins)) {
13493
- const dir = join26(platformPlugins, name);
13560
+ if (existsSync24(platformPlugins)) {
13561
+ for (const name of readdirSync17(platformPlugins)) {
13562
+ const dir = join27(platformPlugins, name);
13494
13563
  try {
13495
13564
  if (statSync11(dir).isDirectory()) out.set(name, dir);
13496
13565
  } catch {
@@ -13498,13 +13567,13 @@ function listPluginDirs() {
13498
13567
  }
13499
13568
  }
13500
13569
  const premiumRoot = resolve19(dirname9(PLATFORM_ROOT), "premium-plugins");
13501
- if (existsSync23(premiumRoot)) {
13502
- for (const bundle of readdirSync16(premiumRoot)) {
13503
- const bundlePlugins = join26(premiumRoot, bundle, "plugins");
13504
- if (!existsSync23(bundlePlugins)) continue;
13570
+ if (existsSync24(premiumRoot)) {
13571
+ for (const bundle of readdirSync17(premiumRoot)) {
13572
+ const bundlePlugins = join27(premiumRoot, bundle, "plugins");
13573
+ if (!existsSync24(bundlePlugins)) continue;
13505
13574
  try {
13506
- for (const name of readdirSync16(bundlePlugins)) {
13507
- const dir = join26(bundlePlugins, name);
13575
+ for (const name of readdirSync17(bundlePlugins)) {
13576
+ const dir = join27(bundlePlugins, name);
13508
13577
  try {
13509
13578
  if (statSync11(dir).isDirectory()) out.set(name, dir);
13510
13579
  } catch {
@@ -13518,7 +13587,7 @@ function listPluginDirs() {
13518
13587
  }
13519
13588
  function readEnabledPlugins(accountId) {
13520
13589
  const accountFile = resolve19(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
13521
- if (!existsSync23(accountFile)) return /* @__PURE__ */ new Set();
13590
+ if (!existsSync24(accountFile)) return /* @__PURE__ */ new Set();
13522
13591
  try {
13523
13592
  const parsed = JSON.parse(readFileSync27(accountFile, "utf-8"));
13524
13593
  return new Set(
@@ -13529,7 +13598,7 @@ function readEnabledPlugins(accountId) {
13529
13598
  }
13530
13599
  }
13531
13600
  function readFrontmatter(path2) {
13532
- if (!existsSync23(path2)) return null;
13601
+ if (!existsSync24(path2)) return null;
13533
13602
  let raw;
13534
13603
  try {
13535
13604
  raw = readFileSync27(path2, "utf-8");
@@ -13547,7 +13616,7 @@ function computeActivePlugins(accountId) {
13547
13616
  for (const name of Array.from(enabled).sort()) {
13548
13617
  const dir = pluginDirs.get(name);
13549
13618
  if (!dir) continue;
13550
- const fm = readFrontmatter(join26(dir, "PLUGIN.md"));
13619
+ const fm = readFrontmatter(join27(dir, "PLUGIN.md"));
13551
13620
  if (!fm) continue;
13552
13621
  const description = frontmatterField(`---
13553
13622
  ${fm}
@@ -13564,7 +13633,7 @@ ${fm}
13564
13633
  `plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
13565
13634
  );
13566
13635
  if (toolNames.length > 0 && descMap.size === 0) {
13567
- const hasSource = existsSync23(join26(dir, "mcp/dist/index.js")) || existsSync23(join26(dir, "mcp/src/index.ts"));
13636
+ const hasSource = existsSync24(join27(dir, "mcp/dist/index.js")) || existsSync24(join27(dir, "mcp/src/index.ts"));
13568
13637
  if (hasSource) {
13569
13638
  console.warn(
13570
13639
  `[spawn-context] WARN plugin=${name} mcp source present but tool-description regex matched zero entries \u2014 SDK upgrade may have changed the registration shape`
@@ -13574,7 +13643,7 @@ ${fm}
13574
13643
  const skillPaths = parseSkillPathsFromFrontmatter(fm);
13575
13644
  const skills = [];
13576
13645
  for (const relPath of skillPaths) {
13577
- const skillPath = join26(dir, relPath);
13646
+ const skillPath = join27(dir, relPath);
13578
13647
  const skillFm = readFrontmatter(skillPath);
13579
13648
  if (!skillFm) continue;
13580
13649
  const skillName = frontmatterField(`---
@@ -13591,10 +13660,10 @@ ${skillFm}
13591
13660
  }
13592
13661
  function computeSpecialistDomains(accountId) {
13593
13662
  const specialistsDir = resolve19(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
13594
- if (!existsSync23(specialistsDir)) return [];
13663
+ if (!existsSync24(specialistsDir)) return [];
13595
13664
  let entries;
13596
13665
  try {
13597
- entries = readdirSync16(specialistsDir);
13666
+ entries = readdirSync17(specialistsDir);
13598
13667
  } catch {
13599
13668
  return [];
13600
13669
  }
@@ -13618,7 +13687,7 @@ function computeSpecialistDomains(accountId) {
13618
13687
  const out = [];
13619
13688
  for (const file of entries.sort()) {
13620
13689
  if (!file.endsWith(".md")) continue;
13621
- const fm = readFrontmatter(join26(specialistsDir, file));
13690
+ const fm = readFrontmatter(join27(specialistsDir, file));
13622
13691
  if (!fm) continue;
13623
13692
  const wrapped = `---
13624
13693
  ${fm}
@@ -13637,7 +13706,7 @@ ${fm}
13637
13706
  }
13638
13707
  function computeDormantPlugins(accountId) {
13639
13708
  const accountFile = resolve19(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
13640
- if (!existsSync23(accountFile)) return [];
13709
+ if (!existsSync24(accountFile)) return [];
13641
13710
  let enabled;
13642
13711
  try {
13643
13712
  const raw = readFileSync27(accountFile, "utf-8");
@@ -13652,10 +13721,10 @@ function computeDormantPlugins(accountId) {
13652
13721
  return [];
13653
13722
  }
13654
13723
  const pluginsDir = resolve19(PLATFORM_ROOT, "plugins");
13655
- if (!existsSync23(pluginsDir)) return [];
13724
+ if (!existsSync24(pluginsDir)) return [];
13656
13725
  let entries;
13657
13726
  try {
13658
- entries = readdirSync16(pluginsDir);
13727
+ entries = readdirSync17(pluginsDir);
13659
13728
  } catch {
13660
13729
  return [];
13661
13730
  }
@@ -13663,7 +13732,7 @@ function computeDormantPlugins(accountId) {
13663
13732
  for (const name of entries) {
13664
13733
  if (enabled.has(name)) continue;
13665
13734
  const manifestPath = resolve19(pluginsDir, name, "PLUGIN.md");
13666
- if (!existsSync23(manifestPath)) continue;
13735
+ if (!existsSync24(manifestPath)) continue;
13667
13736
  let manifest;
13668
13737
  try {
13669
13738
  manifest = readFileSync27(manifestPath, "utf-8");
@@ -13680,11 +13749,11 @@ function computeDormantPlugins(accountId) {
13680
13749
  }
13681
13750
 
13682
13751
  // server/routes/admin/claude-sessions.ts
13683
- import { existsSync as existsSync24, readFileSync as readFileSync28 } from "fs";
13752
+ import { existsSync as existsSync25, readFileSync as readFileSync28 } from "fs";
13684
13753
  import { resolve as resolve20 } from "path";
13685
13754
  function readTunnelState(brandConfigDir) {
13686
13755
  const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
13687
- if (!existsSync24(statePath)) return null;
13756
+ if (!existsSync25(statePath)) return null;
13688
13757
  try {
13689
13758
  const parsed = JSON.parse(readFileSync28(statePath, "utf-8"));
13690
13759
  const tunnelId = typeof parsed.tunnelId === "string" ? parsed.tunnelId : null;
@@ -13909,18 +13978,18 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
13909
13978
  ]);
13910
13979
  var app20 = new Hono();
13911
13980
  app20.post("/", async (c) => {
13912
- const TAG44 = "[admin:events]";
13981
+ const TAG45 = "[admin:events]";
13913
13982
  let body;
13914
13983
  try {
13915
13984
  body = await c.req.json();
13916
13985
  } catch (err) {
13917
13986
  const detail = err instanceof Error ? err.message : String(err);
13918
- console.error(`${TAG44} reject reason=body-not-json detail=${detail}`);
13987
+ console.error(`${TAG45} reject reason=body-not-json detail=${detail}`);
13919
13988
  return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
13920
13989
  }
13921
13990
  const event = typeof body.event === "string" ? body.event : "";
13922
13991
  if (!ALLOWED_EVENTS.has(event)) {
13923
- console.error(`${TAG44} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
13992
+ console.error(`${TAG45} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
13924
13993
  return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
13925
13994
  }
13926
13995
  const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
@@ -13942,11 +14011,11 @@ app20.post("/", async (c) => {
13942
14011
  var events_default = app20;
13943
14012
 
13944
14013
  // server/routes/admin/files.ts
13945
- import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync25 } from "fs";
14014
+ import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync26 } from "fs";
13946
14015
  import { readdir as readdir3, readFile as readFile4, stat as stat4, mkdir as mkdir3, unlink as unlink2, rename } from "fs/promises";
13947
14016
  import { realpathSync as realpathSync5 } from "fs";
13948
14017
  import { randomUUID as randomUUID9 } from "crypto";
13949
- import { basename as basename10, dirname as dirname10, join as join28, relative as relative4, resolve as resolve22, sep as sep6 } from "path";
14018
+ import { basename as basename9, dirname as dirname10, join as join29, relative as relative4, resolve as resolve22, sep as sep6 } from "path";
13950
14019
  import { Readable as Readable2 } from "stream";
13951
14020
 
13952
14021
  // ../lib/graph-trash/src/index.ts
@@ -14264,7 +14333,7 @@ async function cascadeDeleteDocument(params) {
14264
14333
 
14265
14334
  // app/lib/file-index.ts
14266
14335
  import * as fsp from "fs/promises";
14267
- import { resolve as resolve21, relative as relative3, join as join27, basename as basename9, extname as extname2, sep as sep5 } from "path";
14336
+ import { resolve as resolve21, relative as relative3, join as join28, basename as basename8, extname as extname2, sep as sep5 } from "path";
14268
14337
  import { tmpdir as tmpdir2 } from "os";
14269
14338
  import { execFile as execFile2 } from "child_process";
14270
14339
  import { promisify as promisify2 } from "util";
@@ -14346,7 +14415,7 @@ async function extractPdf(absolute) {
14346
14415
  return stdout.trim();
14347
14416
  }
14348
14417
  async function ocrPdf(absolute) {
14349
- const outPdf = join27(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
14418
+ const outPdf = join28(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
14350
14419
  try {
14351
14420
  await execFileAsync2(
14352
14421
  "ocrmypdf",
@@ -14402,13 +14471,13 @@ async function extractFileContent(absolute) {
14402
14471
  }
14403
14472
  }
14404
14473
  async function readDisplayName(absolute) {
14405
- const dir = absolute.slice(0, absolute.length - basename9(absolute).length);
14406
- const base = basename9(absolute);
14474
+ const dir = absolute.slice(0, absolute.length - basename8(absolute).length);
14475
+ const base = basename8(absolute);
14407
14476
  const dot = base.lastIndexOf(".");
14408
14477
  const stem = dot === -1 ? base : base.slice(0, dot);
14409
14478
  if (base === `${stem}.meta.json`) return null;
14410
14479
  try {
14411
- const raw = await fsp.readFile(join27(dir, `${stem}.meta.json`), "utf-8");
14480
+ const raw = await fsp.readFile(join28(dir, `${stem}.meta.json`), "utf-8");
14412
14481
  const meta = JSON.parse(raw);
14413
14482
  const dn = meta.displayName ?? meta.filename;
14414
14483
  return typeof dn === "string" && dn.length > 0 ? dn : null;
@@ -14429,7 +14498,7 @@ async function walkSubtree(root, dataRoot, out) {
14429
14498
  for (const entry of entries) {
14430
14499
  if (entry.isSymbolicLink()) continue;
14431
14500
  if (entry.isDirectory() && entry.name === ".uploads-tmp") continue;
14432
- const abs = join27(root, entry.name);
14501
+ const abs = join28(root, entry.name);
14433
14502
  if (entry.isDirectory()) {
14434
14503
  const sub = await walkSubtree(abs, dataRoot, out);
14435
14504
  if (!sub.clean) clean = false;
@@ -14541,7 +14610,7 @@ async function cascadeTrashLinkedKnowledgeDocs(session, accountId, relativePaths
14541
14610
  return { kds, sections, chunks };
14542
14611
  }
14543
14612
  async function buildArtifact(accountId, wf, embed2) {
14544
- const name = basename9(wf.absolute);
14613
+ const name = basename8(wf.absolute);
14545
14614
  const { content, route } = await extractFileContent(wf.absolute);
14546
14615
  const displayName = await readDisplayName(wf.absolute);
14547
14616
  const embedInput = `${name}
@@ -14785,7 +14854,7 @@ var UPLOAD_TMP_DIR = ".uploads-tmp";
14785
14854
  var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
14786
14855
  async function readMeta(absDir, baseName) {
14787
14856
  try {
14788
- const raw = await readFile4(join28(absDir, `${baseName}.meta.json`), "utf8");
14857
+ const raw = await readFile4(join29(absDir, `${baseName}.meta.json`), "utf8");
14789
14858
  const parsed = JSON.parse(raw);
14790
14859
  if (typeof parsed?.filename === "string") {
14791
14860
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -14823,7 +14892,7 @@ async function readAccountNames() {
14823
14892
  }
14824
14893
  async function enrich(absolute, entry, accountNames) {
14825
14894
  if (entry.kind === "directory" && UUID_RE3.test(entry.name)) {
14826
- const meta = await readMeta(join28(absolute, entry.name), entry.name);
14895
+ const meta = await readMeta(join29(absolute, entry.name), entry.name);
14827
14896
  if (meta?.filename) {
14828
14897
  entry.displayName = meta.filename;
14829
14898
  entry.mimeType = meta.mimeType;
@@ -14987,7 +15056,7 @@ app21.get("/", requireAdminSession, async (c) => {
14987
15056
  const childRel = relPath === "" || relPath === "." ? name : `${relPath}/${name}`;
14988
15057
  const protectedEntry = isProtectedFromDeletion(childRel).protected;
14989
15058
  try {
14990
- const entryPath = join28(absolute, name);
15059
+ const entryPath = join29(absolute, name);
14991
15060
  const s = await stat4(entryPath);
14992
15061
  entries.push({
14993
15062
  name,
@@ -15040,7 +15109,7 @@ app21.get("/download", requireAdminSession, async (c) => {
15040
15109
  console.error(`[data] op=scratchpad-no-session sessionId="${sessionId.slice(0, 8)}\u2026"`);
15041
15110
  return c.json({ error: "Not found" }, 404);
15042
15111
  }
15043
- const meta = readSidecarMeta(join28(projectDir, `${sessionId}.meta.json`));
15112
+ const meta = readSidecarMeta(join29(projectDir, `${sessionId}.meta.json`));
15044
15113
  if (!meta.accountId || meta.accountId !== accountId) {
15045
15114
  console.error(`[data] account-scope-blocked root="scratchpad" sessionId="${sessionId.slice(0, 8)}\u2026" account=${accountId.slice(0, 8)}\u2026`);
15046
15115
  return c.json({ error: "Not found" }, 404);
@@ -15071,7 +15140,7 @@ app21.get("/download", requireAdminSession, async (c) => {
15071
15140
  if (!info.isFile()) {
15072
15141
  return c.json({ error: "Path is not a file" }, 400);
15073
15142
  }
15074
- const filename = basename10(absolute);
15143
+ const filename = basename9(absolute);
15075
15144
  const mimeType = detectMimeType(absolute);
15076
15145
  const nodeStream = createReadStream2(absolute);
15077
15146
  const webStream = Readable2.toWeb(nodeStream);
@@ -15127,7 +15196,7 @@ async function* walkRegularFiles(dirAbsolute) {
15127
15196
  const dirents = await readdir3(dirAbsolute, { withFileTypes: true });
15128
15197
  for (const d of dirents) {
15129
15198
  if (d.isSymbolicLink()) continue;
15130
- const child = join28(dirAbsolute, d.name);
15199
+ const child = join29(dirAbsolute, d.name);
15131
15200
  if (d.isDirectory()) {
15132
15201
  yield* walkRegularFiles(child);
15133
15202
  continue;
@@ -15187,7 +15256,7 @@ app21.get("/download-zip", requireAdminSession, async (c) => {
15187
15256
  if (over) return over;
15188
15257
  }
15189
15258
  } else if (info.isFile()) {
15190
- const over = await addFile(absolute, info.size, basename10(absolute));
15259
+ const over = await addFile(absolute, info.size, basename9(absolute));
15191
15260
  if (over) return over;
15192
15261
  } else {
15193
15262
  return c.json({ error: "Path is not a file or directory" }, 400);
@@ -15216,12 +15285,12 @@ function dataUploadCeiling() {
15216
15285
  }
15217
15286
  async function resolveUploadTarget(c, accountId, uid) {
15218
15287
  const rawName = c.req.query("filename") ?? "";
15219
- const safeName = basename10(rawName).replace(/[\0/\\]/g, "_");
15288
+ const safeName = basename9(rawName).replace(/[\0/\\]/g, "_");
15220
15289
  if (!safeName) return { ok: false, status: 400, error: "filename query param required" };
15221
15290
  const rawRelpath = c.req.query("relpath") ?? "";
15222
15291
  const relpath = rawRelpath !== "" ? rawRelpath : null;
15223
15292
  const token = c.req.query("token") ?? "";
15224
- const finalName = relpath ? basename10(relpath).replace(/[\0/\\]/g, "_") : `${Date.now()}-${safeName}`;
15293
+ const finalName = relpath ? basename9(relpath).replace(/[\0/\\]/g, "_") : `${Date.now()}-${safeName}`;
15225
15294
  const mimeType = (c.req.header("content-type") ?? "").split(";")[0].trim();
15226
15295
  if (!SUPPORTED_MIME_TYPES.has(mimeType)) {
15227
15296
  console.error(`[data-upload] op=reject-mime uid=${uid} mime="${mimeType}" token=${token} rel="${relpath ?? ""}"`);
@@ -15231,7 +15300,7 @@ async function resolveUploadTarget(c, accountId, uid) {
15231
15300
  const base = resolveOwnAccountWrite(rawDir, accountId, "POST /api/admin/files/upload");
15232
15301
  if (!base.ok) return { ok: false, status: base.status, error: base.error };
15233
15302
  const relDir = relpath ? dirname10(relpath) : ".";
15234
- const destRel = relDir === "." ? base.relative : join28(base.relative, relDir);
15303
+ const destRel = relDir === "." ? base.relative : join29(base.relative, relDir);
15235
15304
  if (crossesForeignAccountPartition(destRel, accountId)) {
15236
15305
  console.error(`[data] account-scope-blocked endpoint="POST /api/admin/files/upload" path="${destRel}" account=${accountId.slice(0, 8)}\u2026`);
15237
15306
  return { ok: false, status: 404, error: "Not found" };
@@ -15305,7 +15374,7 @@ app21.post("/upload", requireAdminSession, async (c) => {
15305
15374
  });
15306
15375
  await unlink2(tmpPath).catch(() => {
15307
15376
  });
15308
- const tempRemoved = !existsSync25(tmpPath);
15377
+ const tempRemoved = !existsSync26(tmpPath);
15309
15378
  console.error(`[data-upload] op=cleanup uid=${uid} tempRemoved=${tempRemoved}`);
15310
15379
  };
15311
15380
  const reader = body.getReader();
@@ -15379,7 +15448,7 @@ async function discardChunkUpload(uploadId, state) {
15379
15448
  });
15380
15449
  await unlink2(state.tmpPath).catch(() => {
15381
15450
  });
15382
- const tempRemoved = !existsSync25(state.tmpPath);
15451
+ const tempRemoved = !existsSync26(state.tmpPath);
15383
15452
  console.error(`[data-upload] op=cleanup uid=${uploadId} tempRemoved=${tempRemoved}`);
15384
15453
  }
15385
15454
  async function writeChunkBody(body, out, alreadyReceived, ceiling) {
@@ -15591,7 +15660,7 @@ app21.delete("/", requireAdminSession, async (c) => {
15591
15660
  console.error(`[data] account-scope-blocked endpoint="DELETE /api/admin/files" path="${relPath}" account=${accountId.slice(0, 8)}\u2026`);
15592
15661
  return c.json({ error: "Not found" }, 404);
15593
15662
  }
15594
- const base = basename10(absolute);
15663
+ const base = basename9(absolute);
15595
15664
  const protection = isProtectedFromDeletion(relPath);
15596
15665
  if (protection.protected) {
15597
15666
  console.error(`[data] file-delete blocked path="${relPath}" reason="protected" rule="${protection.rule}"`);
@@ -15607,7 +15676,7 @@ app21.delete("/", requireAdminSession, async (c) => {
15607
15676
  }
15608
15677
  const dot = base.lastIndexOf(".");
15609
15678
  const stem = dot === -1 ? base : base.slice(0, dot);
15610
- const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join28(dirname10(absolute), `${stem}.meta.json`) : null;
15679
+ const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join29(dirname10(absolute), `${stem}.meta.json`) : null;
15611
15680
  await unlink2(absolute);
15612
15681
  if (sidecarPath) {
15613
15682
  try {
@@ -17835,8 +17904,8 @@ var graph_default_view_default = app27;
17835
17904
 
17836
17905
  // server/routes/admin/sidebar-artefacts.ts
17837
17906
  import { readdir as readdir4, stat as stat5 } from "fs/promises";
17838
- import { resolve as resolve23, relative as relative5, isAbsolute as isAbsolute2, sep as sep7, basename as basename11 } from "path";
17839
- import { existsSync as existsSync26 } from "fs";
17907
+ import { resolve as resolve23, relative as relative5, isAbsolute as isAbsolute2, sep as sep7, basename as basename10 } from "path";
17908
+ import { existsSync as existsSync27 } from "fs";
17840
17909
  var LIMIT = 50;
17841
17910
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
17842
17911
  function toDataRootRelPath(absPath) {
@@ -17888,7 +17957,7 @@ async function fetchAccountFileArtefacts(accountId) {
17888
17957
  const modifiedAt = r.get("modifiedAt") ?? "";
17889
17958
  return {
17890
17959
  id: `account-file:${relativePath}`,
17891
- name: displayName ?? basename11(relativePath),
17960
+ name: displayName ?? basename10(relativePath),
17892
17961
  kind: "account-file",
17893
17962
  updatedAt: modifiedAt,
17894
17963
  mimeType,
@@ -17943,7 +18012,7 @@ async function fetchAgentTemplateRows(accountDir) {
17943
18012
  async function unionSpecialistFilenames(overrideDir, bundledDir) {
17944
18013
  const names = /* @__PURE__ */ new Set();
17945
18014
  for (const dir of [overrideDir, bundledDir]) {
17946
- if (!existsSync26(dir)) continue;
18015
+ if (!existsSync27(dir)) continue;
17947
18016
  try {
17948
18017
  const entries = await readdir4(dir);
17949
18018
  for (const entry of entries) {
@@ -17958,7 +18027,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
17958
18027
  }
17959
18028
  async function readAgentTemplateRow(inp) {
17960
18029
  let chosenPath = null;
17961
- if (existsSync26(inp.overridePath)) {
18030
+ if (existsSync27(inp.overridePath)) {
17962
18031
  try {
17963
18032
  validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
17964
18033
  chosenPath = inp.overridePath;
@@ -17969,7 +18038,7 @@ async function readAgentTemplateRow(inp) {
17969
18038
  );
17970
18039
  return null;
17971
18040
  }
17972
- } else if (existsSync26(inp.bundledPath)) {
18041
+ } else if (existsSync27(inp.bundledPath)) {
17973
18042
  if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
17974
18043
  console.error(
17975
18044
  `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
@@ -18572,12 +18641,12 @@ app36.get("/", async (c) => {
18572
18641
  var system_stats_default = app36;
18573
18642
 
18574
18643
  // server/routes/admin/health.ts
18575
- import { existsSync as existsSync27, readFileSync as readFileSync29 } from "fs";
18576
- import { resolve as resolve24, join as join29 } from "path";
18644
+ import { existsSync as existsSync28, readFileSync as readFileSync29 } from "fs";
18645
+ import { resolve as resolve24, join as join30 } from "path";
18577
18646
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve24(process.cwd(), "..");
18578
18647
  var brandHostname = "maxy";
18579
- var brandJsonPath = join29(PLATFORM_ROOT6, "config", "brand.json");
18580
- if (existsSync27(brandJsonPath)) {
18648
+ var brandJsonPath = join30(PLATFORM_ROOT6, "config", "brand.json");
18649
+ if (existsSync28(brandJsonPath)) {
18581
18650
  try {
18582
18651
  const brand = JSON.parse(readFileSync29(brandJsonPath, "utf-8"));
18583
18652
  if (brand.hostname) brandHostname = brand.hostname;
@@ -18588,7 +18657,7 @@ var VERSION_FILE = resolve24(PLATFORM_ROOT6, `config/.${brandHostname}-version`)
18588
18657
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
18589
18658
  var PROBE_TIMEOUT_MS = 1e3;
18590
18659
  function readVersion() {
18591
- if (!existsSync27(VERSION_FILE)) return "unknown";
18660
+ if (!existsSync28(VERSION_FILE)) return "unknown";
18592
18661
  return readFileSync29(VERSION_FILE, "utf-8").trim() || "unknown";
18593
18662
  }
18594
18663
  async function probeConversationDb() {
@@ -19365,8 +19434,8 @@ app44.post("/launch", requireAdminSession, async (c) => {
19365
19434
  var browser_default = app44;
19366
19435
 
19367
19436
  // server/routes/admin/calendar.ts
19368
- import { existsSync as existsSync28 } from "fs";
19369
- import { join as join31 } from "path";
19437
+ import { existsSync as existsSync29 } from "fs";
19438
+ import { join as join32 } from "path";
19370
19439
 
19371
19440
  // server/lib/calendar-ics.ts
19372
19441
  var CRLF = "\r\n";
@@ -19466,7 +19535,7 @@ function countVEvents(ics) {
19466
19535
 
19467
19536
  // server/lib/calendar-availability.ts
19468
19537
  import { readFileSync as readFileSync30 } from "fs";
19469
- import { join as join30 } from "path";
19538
+ import { join as join31 } from "path";
19470
19539
  var AVAILABILITY_FILENAME = "calendar-availability.json";
19471
19540
  var REQUIRED_KEYS = [
19472
19541
  "timezone",
@@ -19475,7 +19544,7 @@ var REQUIRED_KEYS = [
19475
19544
  "weekly"
19476
19545
  ];
19477
19546
  function readAvailabilityConfig(accountDir) {
19478
- const path2 = join30(accountDir, AVAILABILITY_FILENAME);
19547
+ const path2 = join31(accountDir, AVAILABILITY_FILENAME);
19479
19548
  let raw;
19480
19549
  try {
19481
19550
  raw = readFileSync30(path2, "utf-8");
@@ -19837,7 +19906,7 @@ app45.get("/booking-link", requireAdminSession, (c) => {
19837
19906
  console.error('[calendar] op=booking-link-fail err="no account configured"');
19838
19907
  return c.json({ bookingDomain: null });
19839
19908
  }
19840
- if (!existsSync28(join31(account.accountDir, AVAILABILITY_FILENAME))) {
19909
+ if (!existsSync29(join32(account.accountDir, AVAILABILITY_FILENAME))) {
19841
19910
  console.log("[calendar] op=booking-link bookingDomain=none source=availability-config");
19842
19911
  return c.json({ bookingDomain: null });
19843
19912
  }
@@ -19932,7 +20001,6 @@ var tasks_list_default = app46;
19932
20001
 
19933
20002
  // server/routes/admin/task-timer-start.ts
19934
20003
  import { randomUUID as randomUUID13 } from "crypto";
19935
- import neo4j5 from "neo4j-driver";
19936
20004
  var TAG34 = "[task-timer]";
19937
20005
  var app47 = new Hono();
19938
20006
  app47.post("/", requireAdminSession, async (c) => {
@@ -19959,30 +20027,17 @@ app47.post("/", requireAdminSession, async (c) => {
19959
20027
  return c.json({ error: "task-not-found" }, 404);
19960
20028
  }
19961
20029
  const open = await session.run(
19962
- `MATCH (te:TimeEntry {accountId: $accountId}) WHERE te.endedAt IS NULL
19963
- RETURN te.entryId AS entryId, te.taskId AS taskId, te.startedAt AS startedAt
20030
+ `MATCH (te:TimeEntry {accountId: $accountId, taskId: $taskId}) WHERE te.endedAt IS NULL
20031
+ RETURN te.entryId AS entryId, te.startedAt AS startedAt
19964
20032
  ORDER BY te.startedAt LIMIT 1`,
19965
- { accountId }
20033
+ { accountId, taskId }
19966
20034
  );
19967
20035
  const priorEntryId = open.records[0]?.get("entryId");
19968
- const priorTaskId = open.records[0]?.get("taskId");
19969
20036
  const priorStartedAt = open.records[0]?.get("startedAt");
19970
- console.log(`${TAG34} op=start taskId=${taskId} accountId=${accountId} priorOpen=${priorTaskId ?? "none"}`);
19971
- if (priorEntryId && priorTaskId === taskId) {
20037
+ if (priorEntryId) {
20038
+ console.log(`${TAG34} op=start taskId=${taskId} accountId=${accountId} result=already-running`);
19972
20039
  return c.json({ ok: true, running: true, entryId: priorEntryId, startedAt: priorStartedAt });
19973
20040
  }
19974
- if (priorEntryId && priorStartedAt && priorTaskId) {
19975
- const seconds = secondsBetween(priorStartedAt, now);
19976
- await session.run(
19977
- `MATCH (te:TimeEntry {entryId: $priorEntryId}) WHERE te.endedAt IS NULL
19978
- SET te.endedAt = $now, te.seconds = $seconds
19979
- WITH te
19980
- MATCH (t:Task {taskId: $priorTaskId, accountId: $accountId})
19981
- SET t.secondsLogged = coalesce(t.secondsLogged, 0) + $seconds`,
19982
- { priorEntryId, priorTaskId, accountId, now, seconds: neo4j5.int(seconds) }
19983
- );
19984
- console.log(`${TAG34} op=autostop taskId=${priorTaskId} entryId=${priorEntryId} seconds=${seconds}`);
19985
- }
19986
20041
  const entryId = randomUUID13();
19987
20042
  await session.run(
19988
20043
  `MATCH (t:Task {taskId: $taskId, accountId: $accountId})
@@ -20002,7 +20057,7 @@ app47.post("/", requireAdminSession, async (c) => {
20002
20057
  var task_timer_start_default = app47;
20003
20058
 
20004
20059
  // server/routes/admin/task-timer-stop.ts
20005
- import neo4j6 from "neo4j-driver";
20060
+ import neo4j5 from "neo4j-driver";
20006
20061
  var TAG35 = "[task-timer]";
20007
20062
  var app48 = new Hono();
20008
20063
  app48.post("/", requireAdminSession, async (c) => {
@@ -20045,18 +20100,21 @@ app48.post("/", requireAdminSession, async (c) => {
20045
20100
  WITH te
20046
20101
  MATCH (t:Task {taskId: $taskId, accountId: $accountId})
20047
20102
  SET t.secondsLogged = coalesce(t.secondsLogged, 0) + $seconds`,
20048
- { entryId, taskId, accountId, now, seconds: neo4j6.int(seconds) }
20103
+ { entryId, taskId, accountId, now, seconds: neo4j5.int(seconds) }
20049
20104
  );
20050
20105
  const verify = await session.run(
20051
20106
  `MATCH (t:Task {taskId: $taskId, accountId: $accountId})
20052
20107
  OPTIONAL MATCH (te:TimeEntry {taskId: $taskId, accountId: $accountId}) WHERE te.endedAt IS NOT NULL
20053
- RETURN coalesce(sum(te.seconds), 0) AS sumEntries, coalesce(t.secondsLogged, 0) AS secondsLogged`,
20108
+ WITH t, coalesce(sum(te.seconds), 0) AS sumEntries
20109
+ OPTIONAL MATCH (ta:TimeAdjustment {taskId: $taskId, accountId: $accountId})
20110
+ RETURN sumEntries, coalesce(sum(ta.delta), 0) AS sumAdjustments, coalesce(t.secondsLogged, 0) AS secondsLogged`,
20054
20111
  { taskId, accountId }
20055
20112
  );
20056
20113
  const sumEntries = toNum(verify.records[0]?.get("sumEntries"));
20114
+ const sumAdjustments = toNum(verify.records[0]?.get("sumAdjustments"));
20057
20115
  const secondsLogged = toNum(verify.records[0]?.get("secondsLogged"));
20058
20116
  console.log(`${TAG35} op=stop taskId=${taskId} entryId=${entryId} seconds=${seconds} totalAfter=${secondsLogged}`);
20059
- console.log(`${TAG35} op=persisted taskId=${taskId} entryId=${entryId} sumEntries=${sumEntries} secondsLogged=${secondsLogged}`);
20117
+ console.log(`${TAG35} op=persisted taskId=${taskId} entryId=${entryId} sumEntries=${sumEntries} sumAdjustments=${sumAdjustments} secondsLogged=${secondsLogged}`);
20060
20118
  return c.json({ ok: true, running: false, seconds, secondsLogged });
20061
20119
  } catch (err) {
20062
20120
  console.error(`${TAG35} op=stop error="${err instanceof Error ? err.message : String(err)}"`);
@@ -20106,56 +20164,137 @@ app49.post("/", requireAdminSession, async (c) => {
20106
20164
  });
20107
20165
  var task_complete_default = app49;
20108
20166
 
20109
- // server/routes/admin/index.ts
20167
+ // server/routes/admin/task-time-adjust.ts
20168
+ import { randomUUID as randomUUID14 } from "crypto";
20169
+ import neo4j6 from "neo4j-driver";
20170
+ var TAG37 = "[task-time-adjust]";
20110
20171
  var app50 = new Hono();
20111
- app50.route("/session", session_default);
20112
- app50.route("/accounts", accounts_default);
20113
- app50.route("/logs", logs_default);
20114
- app50.route("/claude-info", claude_info_default);
20115
- app50.route("/attachment", attachment_default);
20116
- app50.route("/agents", agents_default);
20117
- app50.route("/sessions", sessions_default);
20118
- app50.route("/claude-sessions", claude_sessions_default);
20119
- app50.route("/log-ingest", log_ingest_default);
20120
- app50.route("/events", events_default);
20121
- app50.route("/files", files_default);
20122
- app50.route("/graph-search", graph_search_default);
20123
- app50.route("/graph-subgraph", graph_subgraph_default);
20124
- app50.route("/graph-delete", graph_delete_default);
20125
- app50.route("/graph-restore", graph_restore_default);
20126
- app50.route("/graph-labels-in-graph", graph_labels_in_graph_default);
20127
- app50.route("/graph-default-view", graph_default_view_default);
20128
- app50.route("/sidebar-artefacts", sidebar_artefacts_default);
20129
- app50.route("/sidebar-sessions", sidebar_sessions_default);
20130
- app50.route("/session-delete", session_delete_default);
20131
- app50.route("/session-stop", session_stop_default);
20132
- app50.route("/session-archive", session_archive_default);
20133
- app50.route("/session-rename", session_rename_default);
20134
- app50.route("/session-usage", session_usage_default);
20135
- app50.route("/browser", browser_default);
20136
- app50.route("/session-rc-spawn", session_rc_spawn_default);
20137
- app50.route("/session-reseat", session_reseat_default);
20138
- app50.route("/system-stats", system_stats_default);
20139
- app50.route("/health-brand", health_default2);
20140
- app50.route("/linkedin-ingest", linkedin_ingest_default);
20141
- app50.route("/post-turn-context", post_turn_context_default);
20142
- app50.route("/public-session-context", public_session_context_default);
20143
- app50.route("/public-session-exit", public_session_exit_default);
20144
- app50.route("/access-session-evict", access_session_evict_default);
20145
- app50.route("/enrol-person", enrol_person_default);
20146
- app50.route("/calendar", calendar_default);
20147
- app50.route("/tasks-list", tasks_list_default);
20148
- app50.route("/task-timer-start", task_timer_start_default);
20149
- app50.route("/task-timer-stop", task_timer_stop_default);
20150
- app50.route("/task-complete", task_complete_default);
20151
- var admin_default = app50;
20172
+ app50.post("/", requireAdminSession, async (c) => {
20173
+ const cacheKey = c.var.cacheKey;
20174
+ const accountId = getAccountIdForSession(cacheKey);
20175
+ if (!accountId) return c.json({ error: "Account not found for session" }, 401);
20176
+ let body;
20177
+ try {
20178
+ body = await c.req.json();
20179
+ } catch {
20180
+ console.error(`${TAG37} op=reject reason=bad-json`);
20181
+ return c.json({ error: "invalid-json" }, 400);
20182
+ }
20183
+ const taskId = typeof body.taskId === "string" ? body.taskId : "";
20184
+ if (!taskId) {
20185
+ console.error(`${TAG37} op=reject reason=no-task`);
20186
+ return c.json({ error: "taskId required" }, 400);
20187
+ }
20188
+ const newSeconds = body.newSeconds;
20189
+ if (typeof newSeconds !== "number" || !Number.isInteger(newSeconds) || newSeconds < 0) {
20190
+ console.error(`${TAG37} op=reject reason=invalid-seconds taskId=${taskId} accountId=${accountId}`);
20191
+ return c.json({ error: "newSeconds must be a non-negative integer" }, 400);
20192
+ }
20193
+ const adjustmentId = randomUUID14();
20194
+ const now = (/* @__PURE__ */ new Date()).toISOString();
20195
+ console.log(`${TAG37} op=request adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId} newSeconds=${newSeconds}`);
20196
+ const session = getSession();
20197
+ try {
20198
+ const guard = await session.run(
20199
+ `MATCH (t:Task {taskId: $taskId, accountId: $accountId})
20200
+ OPTIONAL MATCH (te:TimeEntry {taskId: $taskId, accountId: $accountId}) WHERE te.endedAt IS NULL
20201
+ RETURN t.taskId AS taskId, count(te) AS openCount, coalesce(t.secondsLogged, 0) AS previousSeconds`,
20202
+ { taskId, accountId }
20203
+ );
20204
+ if (guard.records.length === 0) {
20205
+ console.error(`${TAG37} op=reject reason=no-task adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId}`);
20206
+ return c.json({ error: "task-not-found" }, 404);
20207
+ }
20208
+ const openCount = toNum(guard.records[0].get("openCount"));
20209
+ if (openCount > 0) {
20210
+ console.error(`${TAG37} op=reject reason=running adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId}`);
20211
+ return c.json({ error: "task-timer-running" }, 409);
20212
+ }
20213
+ const previousSeconds = toNum(guard.records[0].get("previousSeconds"));
20214
+ const delta = newSeconds - previousSeconds;
20215
+ const write = await session.run(
20216
+ `MATCH (t:Task {taskId: $taskId, accountId: $accountId})
20217
+ CREATE (ta:TimeAdjustment {
20218
+ adjustmentId: $adjustmentId, taskId: $taskId, accountId: $accountId, at: $now,
20219
+ previousSeconds: $previousSeconds, newSeconds: $newSeconds, delta: $delta,
20220
+ sourceSessionKey: $sourceSessionKey
20221
+ })
20222
+ SET t.secondsLogged = $newSeconds
20223
+ RETURN coalesce(t.secondsLogged, 0) AS secondsLoggedAfter`,
20224
+ {
20225
+ taskId,
20226
+ accountId,
20227
+ adjustmentId,
20228
+ now,
20229
+ previousSeconds: neo4j6.int(previousSeconds),
20230
+ newSeconds: neo4j6.int(newSeconds),
20231
+ delta: neo4j6.int(delta),
20232
+ sourceSessionKey: cacheKey
20233
+ }
20234
+ );
20235
+ const secondsLoggedAfter = toNum(write.records[0]?.get("secondsLoggedAfter"));
20236
+ console.log(`${TAG37} op=persisted adjustmentId=${adjustmentId} previousSeconds=${previousSeconds} newSeconds=${newSeconds} delta=${delta} secondsLoggedAfter=${secondsLoggedAfter}`);
20237
+ return c.json({ ok: true, secondsLogged: secondsLoggedAfter });
20238
+ } catch (err) {
20239
+ console.error(`${TAG37} op=error adjustmentId=${adjustmentId} taskId=${taskId} error="${err instanceof Error ? err.message : String(err)}"`);
20240
+ return c.json({ error: "task-time-adjust-failed" }, 500);
20241
+ } finally {
20242
+ await session.close();
20243
+ }
20244
+ });
20245
+ var task_time_adjust_default = app50;
20246
+
20247
+ // server/routes/admin/index.ts
20248
+ var app51 = new Hono();
20249
+ app51.route("/session", session_default);
20250
+ app51.route("/accounts", accounts_default);
20251
+ app51.route("/logs", logs_default);
20252
+ app51.route("/claude-info", claude_info_default);
20253
+ app51.route("/attachment", attachment_default);
20254
+ app51.route("/agents", agents_default);
20255
+ app51.route("/sessions", sessions_default);
20256
+ app51.route("/claude-sessions", claude_sessions_default);
20257
+ app51.route("/log-ingest", log_ingest_default);
20258
+ app51.route("/events", events_default);
20259
+ app51.route("/files", files_default);
20260
+ app51.route("/graph-search", graph_search_default);
20261
+ app51.route("/graph-subgraph", graph_subgraph_default);
20262
+ app51.route("/graph-delete", graph_delete_default);
20263
+ app51.route("/graph-restore", graph_restore_default);
20264
+ app51.route("/graph-labels-in-graph", graph_labels_in_graph_default);
20265
+ app51.route("/graph-default-view", graph_default_view_default);
20266
+ app51.route("/sidebar-artefacts", sidebar_artefacts_default);
20267
+ app51.route("/sidebar-sessions", sidebar_sessions_default);
20268
+ app51.route("/session-delete", session_delete_default);
20269
+ app51.route("/session-stop", session_stop_default);
20270
+ app51.route("/session-archive", session_archive_default);
20271
+ app51.route("/session-rename", session_rename_default);
20272
+ app51.route("/session-usage", session_usage_default);
20273
+ app51.route("/browser", browser_default);
20274
+ app51.route("/session-rc-spawn", session_rc_spawn_default);
20275
+ app51.route("/session-reseat", session_reseat_default);
20276
+ app51.route("/system-stats", system_stats_default);
20277
+ app51.route("/health-brand", health_default2);
20278
+ app51.route("/linkedin-ingest", linkedin_ingest_default);
20279
+ app51.route("/post-turn-context", post_turn_context_default);
20280
+ app51.route("/public-session-context", public_session_context_default);
20281
+ app51.route("/public-session-exit", public_session_exit_default);
20282
+ app51.route("/access-session-evict", access_session_evict_default);
20283
+ app51.route("/enrol-person", enrol_person_default);
20284
+ app51.route("/calendar", calendar_default);
20285
+ app51.route("/tasks-list", tasks_list_default);
20286
+ app51.route("/task-timer-start", task_timer_start_default);
20287
+ app51.route("/task-timer-stop", task_timer_stop_default);
20288
+ app51.route("/task-complete", task_complete_default);
20289
+ app51.route("/task-time-adjust", task_time_adjust_default);
20290
+ var admin_default = app51;
20152
20291
 
20153
20292
  // server/routes/access/verify-token.ts
20154
- var TAG37 = "[access-verify]";
20293
+ var TAG38 = "[access-verify]";
20155
20294
  var MINT_TAG = "[access-session-mint]";
20156
20295
  var COOKIE_NAME = "__access_session";
20157
- var app51 = new Hono();
20158
- app51.post("/", async (c) => {
20296
+ var app52 = new Hono();
20297
+ app52.post("/", async (c) => {
20159
20298
  const ip = c.var.clientIp || "unknown";
20160
20299
  let body;
20161
20300
  try {
@@ -20170,39 +20309,39 @@ app51.post("/", async (c) => {
20170
20309
  }
20171
20310
  const rateMsg = checkAccessRateLimit(ip, agentSlug);
20172
20311
  if (rateMsg) {
20173
- console.error(`${TAG37} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
20312
+ console.error(`${TAG38} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
20174
20313
  return c.json({ error: rateMsg }, 429);
20175
20314
  }
20176
20315
  const grant = await findGrantByMagicToken(token);
20177
20316
  if (!grant) {
20178
20317
  recordAccessFailedAttempt(ip, agentSlug);
20179
- console.error(`${TAG37} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
20318
+ console.error(`${TAG38} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
20180
20319
  return c.json({ error: "invalid-or-expired-link" }, 401);
20181
20320
  }
20182
20321
  if (grant.agentSlug !== agentSlug) {
20183
20322
  recordAccessFailedAttempt(ip, agentSlug);
20184
20323
  console.error(
20185
- `${TAG37} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
20324
+ `${TAG38} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
20186
20325
  );
20187
20326
  return c.json({ error: "invalid-or-expired-link" }, 401);
20188
20327
  }
20189
20328
  if (grant.status === "expired" || grant.status === "revoked") {
20190
20329
  recordAccessFailedAttempt(ip, agentSlug);
20191
20330
  console.error(
20192
- `${TAG37} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
20331
+ `${TAG38} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
20193
20332
  );
20194
20333
  return c.json({ error: "access-no-longer-valid" }, 401);
20195
20334
  }
20196
20335
  if (grant.expiresAt !== null && grant.expiresAt < Date.now()) {
20197
20336
  recordAccessFailedAttempt(ip, agentSlug);
20198
20337
  console.error(
20199
- `${TAG37} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
20338
+ `${TAG38} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
20200
20339
  );
20201
20340
  return c.json({ error: "access-no-longer-valid" }, 401);
20202
20341
  }
20203
20342
  if (!grant.sliceToken) {
20204
20343
  console.error(
20205
- `${TAG37} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
20344
+ `${TAG38} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
20206
20345
  );
20207
20346
  return c.json({ error: "grant-misconfigured" }, 500);
20208
20347
  }
@@ -20218,12 +20357,12 @@ app51.post("/", async (c) => {
20218
20357
  await consumeMagicTokenAndActivate(grant.grantId);
20219
20358
  } catch (err) {
20220
20359
  console.error(
20221
- `${TAG37} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
20360
+ `${TAG38} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
20222
20361
  );
20223
20362
  return c.json({ error: "verification-failed" }, 500);
20224
20363
  }
20225
20364
  clearAccessRateLimit(ip, agentSlug);
20226
- console.log(`${TAG37} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
20365
+ console.log(`${TAG38} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
20227
20366
  console.log(
20228
20367
  `${MINT_TAG} grantId=${grant.grantId} sliceToken=${grant.sliceToken.slice(0, 8)} agentSlug=${agentSlug} personId=${grant.personId ?? "none"}`
20229
20368
  );
@@ -20237,7 +20376,7 @@ app51.post("/", async (c) => {
20237
20376
  displayName: grant.displayName
20238
20377
  });
20239
20378
  });
20240
- var verify_token_default = app51;
20379
+ var verify_token_default = app52;
20241
20380
 
20242
20381
  // app/lib/access-email.ts
20243
20382
  import { spawn as spawn2 } from "child_process";
@@ -20299,10 +20438,10 @@ async function sendMagicLinkEmail(payload) {
20299
20438
  }
20300
20439
 
20301
20440
  // server/routes/access/request-magic-link.ts
20302
- var TAG38 = "[access-request-link]";
20303
- var app52 = new Hono();
20441
+ var TAG39 = "[access-request-link]";
20442
+ var app53 = new Hono();
20304
20443
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
20305
- app52.post("/", async (c) => {
20444
+ app53.post("/", async (c) => {
20306
20445
  let body;
20307
20446
  try {
20308
20447
  body = await c.req.json();
@@ -20316,18 +20455,18 @@ app52.post("/", async (c) => {
20316
20455
  }
20317
20456
  const rateMsg = checkRequestLinkRateLimit(contactValue);
20318
20457
  if (rateMsg) {
20319
- console.error(`${TAG38} contactValue=${maskContact(contactValue)} result=rate-limited`);
20458
+ console.error(`${TAG39} contactValue=${maskContact(contactValue)} result=rate-limited`);
20320
20459
  return c.json({ error: rateMsg }, 429);
20321
20460
  }
20322
20461
  recordRequestLinkAttempt(contactValue);
20323
20462
  const accountId = process.env.ACCOUNT_ID ?? "";
20324
20463
  if (!accountId) {
20325
- console.error(`${TAG38} contactValue=${maskContact(contactValue)} result=no-account-id`);
20464
+ console.error(`${TAG39} contactValue=${maskContact(contactValue)} result=no-account-id`);
20326
20465
  return c.json({ message: VISITOR_MESSAGE }, 200);
20327
20466
  }
20328
20467
  const grant = await findActiveGrantByContact(contactValue, agentSlug, accountId);
20329
20468
  if (!grant) {
20330
- console.log(`${TAG38} contactValue=${maskContact(contactValue)} result=notfound`);
20469
+ console.log(`${TAG39} contactValue=${maskContact(contactValue)} result=notfound`);
20331
20470
  return c.json({ message: VISITOR_MESSAGE }, 200);
20332
20471
  }
20333
20472
  let token;
@@ -20335,7 +20474,7 @@ app52.post("/", async (c) => {
20335
20474
  token = await generateNewMagicToken(grant.grantId);
20336
20475
  } catch (err) {
20337
20476
  console.error(
20338
- `${TAG38} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
20477
+ `${TAG39} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
20339
20478
  );
20340
20479
  return c.json({ message: VISITOR_MESSAGE }, 200);
20341
20480
  }
@@ -20367,25 +20506,25 @@ app52.post("/", async (c) => {
20367
20506
  });
20368
20507
  if (!sendResult.ok) {
20369
20508
  console.error(
20370
- `${TAG38} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
20509
+ `${TAG39} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
20371
20510
  );
20372
20511
  return c.json({ message: VISITOR_MESSAGE }, 200);
20373
20512
  }
20374
20513
  console.log(
20375
- `${TAG38} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
20514
+ `${TAG39} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
20376
20515
  );
20377
20516
  return c.json({ message: VISITOR_MESSAGE }, 200);
20378
20517
  });
20379
- var request_magic_link_default = app52;
20518
+ var request_magic_link_default = app53;
20380
20519
 
20381
20520
  // server/routes/access/index.ts
20382
- var app53 = new Hono();
20383
- app53.route("/verify-token", verify_token_default);
20384
- app53.route("/request-magic-link", request_magic_link_default);
20385
- var access_default = app53;
20521
+ var app54 = new Hono();
20522
+ app54.route("/verify-token", verify_token_default);
20523
+ app54.route("/request-magic-link", request_magic_link_default);
20524
+ var access_default = app54;
20386
20525
 
20387
20526
  // server/routes/sites.ts
20388
- import { existsSync as existsSync29, readFileSync as readFileSync31, realpathSync as realpathSync6, statSync as statSync12 } from "fs";
20527
+ import { existsSync as existsSync30, readFileSync as readFileSync31, realpathSync as realpathSync6, statSync as statSync12 } from "fs";
20389
20528
  import { resolve as resolve26 } from "path";
20390
20529
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
20391
20530
  var MIME = {
@@ -20417,8 +20556,8 @@ function getExt(p) {
20417
20556
  if (idx < p.lastIndexOf("/")) return "";
20418
20557
  return p.slice(idx).toLowerCase();
20419
20558
  }
20420
- var app54 = new Hono();
20421
- app54.get("/:rel{.*}", (c) => {
20559
+ var app55 = new Hono();
20560
+ app55.get("/:rel{.*}", (c) => {
20422
20561
  const reqPath = c.req.path;
20423
20562
  const rawRel = c.req.param("rel") ?? "";
20424
20563
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -20451,7 +20590,7 @@ app54.get("/:rel{.*}", (c) => {
20451
20590
  }
20452
20591
  let stat8;
20453
20592
  try {
20454
- stat8 = existsSync29(filePath) ? statSync12(filePath) : null;
20593
+ stat8 = existsSync30(filePath) ? statSync12(filePath) : null;
20455
20594
  } catch {
20456
20595
  stat8 = null;
20457
20596
  }
@@ -20470,7 +20609,7 @@ app54.get("/:rel{.*}", (c) => {
20470
20609
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
20471
20610
  return c.text("Forbidden", 403);
20472
20611
  }
20473
- if (!existsSync29(filePath)) {
20612
+ if (!existsSync30(filePath)) {
20474
20613
  console.error(`[sites] not-found path=${reqPath} status=404`);
20475
20614
  return c.text("Not found", 404);
20476
20615
  }
@@ -20521,7 +20660,7 @@ app54.get("/:rel{.*}", (c) => {
20521
20660
  "X-Content-Type-Options": "nosniff"
20522
20661
  });
20523
20662
  });
20524
- var sites_default = app54;
20663
+ var sites_default = app55;
20525
20664
 
20526
20665
  // app/lib/visitor-token.ts
20527
20666
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
@@ -20601,8 +20740,8 @@ var VISITOR_COOKIE_NAME = "mxy_v";
20601
20740
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
20602
20741
 
20603
20742
  // app/lib/brand-config.ts
20604
- import { existsSync as existsSync30, readFileSync as readFileSync33 } from "fs";
20605
- import { join as join32 } from "path";
20743
+ import { existsSync as existsSync31, readFileSync as readFileSync33 } from "fs";
20744
+ import { join as join33 } from "path";
20606
20745
  var cached = null;
20607
20746
  var cachedAttempted = false;
20608
20747
  function readBrandConfig() {
@@ -20610,8 +20749,8 @@ function readBrandConfig() {
20610
20749
  cachedAttempted = true;
20611
20750
  const platformRoot3 = process.env.MAXY_PLATFORM_ROOT;
20612
20751
  if (!platformRoot3) return null;
20613
- const brandPath = join32(platformRoot3, "config", "brand.json");
20614
- if (!existsSync30(brandPath)) return null;
20752
+ const brandPath = join33(platformRoot3, "config", "brand.json");
20753
+ if (!existsSync31(brandPath)) return null;
20615
20754
  try {
20616
20755
  cached = JSON.parse(readFileSync33(brandPath, "utf-8"));
20617
20756
  return cached;
@@ -20621,7 +20760,7 @@ function readBrandConfig() {
20621
20760
  }
20622
20761
 
20623
20762
  // server/routes/visitor-consent.ts
20624
- var app55 = new Hono();
20763
+ var app56 = new Hono();
20625
20764
  var CONSENT_COOKIE_NAME = "mxy_consent";
20626
20765
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
20627
20766
  var DEFAULT_CONSENT_COPY = {
@@ -20666,17 +20805,17 @@ function siteSlugFromReferer(referer) {
20666
20805
  return "";
20667
20806
  }
20668
20807
  }
20669
- app55.options("/consent", (c) => {
20808
+ app56.options("/consent", (c) => {
20670
20809
  const origin = getOrigin(c);
20671
20810
  setCorsHeaders(c, origin);
20672
20811
  return c.body(null, 204);
20673
20812
  });
20674
- app55.options("/brand-config", (c) => {
20813
+ app56.options("/brand-config", (c) => {
20675
20814
  const origin = getOrigin(c);
20676
20815
  setCorsHeaders(c, origin);
20677
20816
  return c.body(null, 204);
20678
20817
  });
20679
- app55.post("/consent", async (c) => {
20818
+ app56.post("/consent", async (c) => {
20680
20819
  const origin = getOrigin(c);
20681
20820
  setCorsHeaders(c, origin);
20682
20821
  let raw;
@@ -20716,7 +20855,7 @@ app55.post("/consent", async (c) => {
20716
20855
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
20717
20856
  return c.body(null, 204);
20718
20857
  });
20719
- app55.get("/brand-config", (c) => {
20858
+ app56.get("/brand-config", (c) => {
20720
20859
  const origin = getOrigin(c);
20721
20860
  setCorsHeaders(c, origin);
20722
20861
  const brand = readBrandConfig();
@@ -20726,7 +20865,7 @@ app55.get("/brand-config", (c) => {
20726
20865
  c.header("Cache-Control", "public, max-age=300");
20727
20866
  return c.json({ consent: { copy, palette } });
20728
20867
  });
20729
- var visitor_consent_default = app55;
20868
+ var visitor_consent_default = app56;
20730
20869
 
20731
20870
  // server/routes/listings.ts
20732
20871
  function getCookie(headerValue, name) {
@@ -20753,8 +20892,8 @@ function appendConsentParams(pageUrl, token) {
20753
20892
  }
20754
20893
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
20755
20894
  var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
20756
- var app56 = new Hono();
20757
- app56.get("/:slug/click", async (c) => {
20895
+ var app57 = new Hono();
20896
+ app57.get("/:slug/click", async (c) => {
20758
20897
  const slug = c.req.param("slug") ?? "";
20759
20898
  const rawSession = c.req.query("session") ?? "";
20760
20899
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -20818,10 +20957,10 @@ app56.get("/:slug/click", async (c) => {
20818
20957
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
20819
20958
  return c.redirect(redirectUrl, 302);
20820
20959
  });
20821
- var listings_default = app56;
20960
+ var listings_default = app57;
20822
20961
 
20823
20962
  // server/routes/visitor-event.ts
20824
- var app57 = new Hono();
20963
+ var app58 = new Hono();
20825
20964
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
20826
20965
  var buckets = /* @__PURE__ */ new Map();
20827
20966
  var RATE_LIMIT = 60;
@@ -20888,12 +21027,12 @@ function originAllowed(origin, allowlist) {
20888
21027
  return false;
20889
21028
  }
20890
21029
  }
20891
- app57.options("/event", (c) => {
21030
+ app58.options("/event", (c) => {
20892
21031
  const origin = getOrigin2(c);
20893
21032
  setCorsHeaders2(c, origin);
20894
21033
  return c.body(null, 204);
20895
21034
  });
20896
- app57.post("/event", async (c) => {
21035
+ app58.post("/event", async (c) => {
20897
21036
  const origin = getOrigin2(c);
20898
21037
  setCorsHeaders2(c, origin);
20899
21038
  const ua = c.req.header("user-agent") ?? "";
@@ -21098,11 +21237,11 @@ async function writeEvent(opts) {
21098
21237
  );
21099
21238
  }
21100
21239
  }
21101
- var visitor_event_default = app57;
21240
+ var visitor_event_default = app58;
21102
21241
 
21103
21242
  // server/routes/session.ts
21104
21243
  import { resolve as resolve27 } from "path";
21105
- import { existsSync as existsSync31, writeFileSync as writeFileSync12, mkdirSync as mkdirSync8 } from "fs";
21244
+ import { existsSync as existsSync32, writeFileSync as writeFileSync12, mkdirSync as mkdirSync8 } from "fs";
21106
21245
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
21107
21246
  function writeBrandingCache(accountId, agentSlug, branding) {
21108
21247
  try {
@@ -21144,8 +21283,8 @@ function withVisitorCookie(response, visitorId) {
21144
21283
  headers
21145
21284
  });
21146
21285
  }
21147
- var app58 = new Hono();
21148
- app58.post("/", async (c) => {
21286
+ var app59 = new Hono();
21287
+ app59.post("/", async (c) => {
21149
21288
  let body;
21150
21289
  try {
21151
21290
  body = await c.req.json();
@@ -21186,7 +21325,7 @@ app58.post("/", async (c) => {
21186
21325
  let agentConfig = null;
21187
21326
  if (account) {
21188
21327
  const agentDir = resolve27(account.accountDir, "agents", agentSlug);
21189
- if (!existsSync31(agentDir) || !existsSync31(resolve27(agentDir, "config.json"))) {
21328
+ if (!existsSync32(agentDir) || !existsSync32(resolve27(agentDir, "config.json"))) {
21190
21329
  return c.json({ error: "Agent not found" }, 404);
21191
21330
  }
21192
21331
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -21292,7 +21431,7 @@ app58.post("/", async (c) => {
21292
21431
  newVisitorId
21293
21432
  );
21294
21433
  });
21295
- var session_default2 = app58;
21434
+ var session_default2 = app59;
21296
21435
 
21297
21436
  // server/lib/calendar-slots.ts
21298
21437
  var WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
@@ -21375,17 +21514,17 @@ function computeOpenSlots(config, busy, fromISO, toISO) {
21375
21514
  }
21376
21515
 
21377
21516
  // server/routes/calendar-public.ts
21378
- var app59 = new Hono();
21517
+ var app60 = new Hono();
21379
21518
  function setCors(c) {
21380
21519
  c.header("Access-Control-Allow-Origin", "*");
21381
21520
  c.header("Access-Control-Allow-Methods", "GET, OPTIONS");
21382
21521
  c.header("Access-Control-Allow-Headers", "content-type");
21383
21522
  }
21384
- app59.options("/free-busy", (c) => {
21523
+ app60.options("/free-busy", (c) => {
21385
21524
  setCors(c);
21386
21525
  return c.body(null, 204);
21387
21526
  });
21388
- app59.get("/free-busy", async (c) => {
21527
+ app60.get("/free-busy", async (c) => {
21389
21528
  setCors(c);
21390
21529
  const from = c.req.query("from");
21391
21530
  const to = c.req.query("to");
@@ -21427,10 +21566,10 @@ app59.get("/free-busy", async (c) => {
21427
21566
  await session.close();
21428
21567
  }
21429
21568
  });
21430
- var calendar_public_default = app59;
21569
+ var calendar_public_default = app60;
21431
21570
 
21432
21571
  // app/lib/timeentry-census.ts
21433
- var TAG39 = "[timeentry-census]";
21572
+ var TAG40 = "[timeentry-census]";
21434
21573
  function reconcileTimeEntries(rows, now, horizonMs) {
21435
21574
  const openEntries = rows.openEntries.length;
21436
21575
  let oldestOpenAgeMs = 0;
@@ -21440,9 +21579,9 @@ function reconcileTimeEntries(rows, now, horizonMs) {
21440
21579
  perAccount.set(e.accountId, (perAccount.get(e.accountId) ?? 0) + 1);
21441
21580
  }
21442
21581
  const maxOpenPerAccount = perAccount.size === 0 ? 0 : Math.max(...perAccount.values());
21443
- const driftTasks = rows.taskSums.filter((t) => t.secondsLogged !== t.sumEntries).length;
21582
+ const driftTasks = rows.taskSums.filter((t) => t.secondsLogged !== t.sumEntries + (t.sumAdjustments ?? 0)).length;
21444
21583
  const oldestOpenAgeMin = Math.floor(oldestOpenAgeMs / 6e4);
21445
- const alarm = oldestOpenAgeMs > horizonMs || maxOpenPerAccount > 1 || driftTasks > 0;
21584
+ const alarm = oldestOpenAgeMs > horizonMs || driftTasks > 0;
21446
21585
  return { openEntries, oldestOpenAgeMin, maxOpenPerAccount, driftTasks, alarm };
21447
21586
  }
21448
21587
  async function runTimeEntryCensusOnce(session, now, horizonMs) {
@@ -21458,20 +21597,24 @@ async function runTimeEntryCensusOnce(session, now, horizonMs) {
21458
21597
  const sumRes = await session.run(
21459
21598
  `MATCH (t:Task) WHERE t.secondsLogged IS NOT NULL
21460
21599
  OPTIONAL MATCH (te:TimeEntry {taskId: t.taskId}) WHERE te.endedAt IS NOT NULL
21461
- RETURN t.taskId AS taskId, coalesce(t.secondsLogged, 0) AS secondsLogged, coalesce(sum(te.seconds), 0) AS sumEntries`
21600
+ WITH t, coalesce(sum(te.seconds), 0) AS sumEntries
21601
+ OPTIONAL MATCH (ta:TimeAdjustment {taskId: t.taskId})
21602
+ RETURN t.taskId AS taskId, coalesce(t.secondsLogged, 0) AS secondsLogged,
21603
+ sumEntries, coalesce(sum(ta.delta), 0) AS sumAdjustments`
21462
21604
  );
21463
21605
  const taskSums = sumRes.records.map((r) => ({
21464
21606
  taskId: r.get("taskId") ?? "",
21465
21607
  secondsLogged: toNum(r.get("secondsLogged")),
21466
- sumEntries: toNum(r.get("sumEntries"))
21608
+ sumEntries: toNum(r.get("sumEntries")),
21609
+ sumAdjustments: toNum(r.get("sumAdjustments"))
21467
21610
  }));
21468
21611
  const finding = reconcileTimeEntries({ openEntries, taskSums }, now, horizonMs);
21469
- const line = `${TAG39} openEntries=${finding.openEntries} oldestOpenAgeMin=${finding.oldestOpenAgeMin} maxOpenPerAccount=${finding.maxOpenPerAccount} driftTasks=${finding.driftTasks}`;
21612
+ const line = `${TAG40} openEntries=${finding.openEntries} oldestOpenAgeMin=${finding.oldestOpenAgeMin} maxOpenPerAccount=${finding.maxOpenPerAccount} driftTasks=${finding.driftTasks}`;
21470
21613
  if (finding.alarm) console.error(`${line} alarm=true`);
21471
21614
  else console.log(line);
21472
21615
  return finding;
21473
21616
  } catch (err) {
21474
- console.error(`${TAG39} error="${err instanceof Error ? err.message : String(err)}"`);
21617
+ console.error(`${TAG40} error="${err instanceof Error ? err.message : String(err)}"`);
21475
21618
  return null;
21476
21619
  }
21477
21620
  }
@@ -21485,13 +21628,13 @@ function startTimeEntryCensus(openSession, opts = {}) {
21485
21628
  try {
21486
21629
  session = openSession();
21487
21630
  } catch (err) {
21488
- console.error(`${TAG39} open-session-failed error="${err instanceof Error ? err.message : String(err)}"`);
21631
+ console.error(`${TAG40} open-session-failed error="${err instanceof Error ? err.message : String(err)}"`);
21489
21632
  return;
21490
21633
  }
21491
21634
  try {
21492
21635
  await runTimeEntryCensusOnce(session, Date.now(), horizonMs);
21493
21636
  } catch (err) {
21494
- console.error(`${TAG39} tick-failed error="${err instanceof Error ? err.message : String(err)}"`);
21637
+ console.error(`${TAG40} tick-failed error="${err instanceof Error ? err.message : String(err)}"`);
21495
21638
  } finally {
21496
21639
  try {
21497
21640
  await session.close();
@@ -21854,8 +21997,8 @@ async function migrateUploads(opts = {}) {
21854
21997
 
21855
21998
  // app/lib/migrate-admin-webchat-sidecars.ts
21856
21999
  import { readdir as readdir6, readFile as readFile6, rename as rename3, writeFile as writeFile4, unlink as unlink3 } from "fs/promises";
21857
- import { existsSync as existsSync32 } from "fs";
21858
- import { join as join33 } from "path";
22000
+ import { existsSync as existsSync33 } from "fs";
22001
+ import { join as join34 } from "path";
21859
22002
  var ADMIN_ROLE2 = "admin";
21860
22003
  var WEBCHAT_CHANNEL2 = "webchat";
21861
22004
  var SESSION_META_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.meta\.json$/i;
@@ -21884,7 +22027,7 @@ async function writeRaw(path2, obj) {
21884
22027
  await rename3(tmp, path2);
21885
22028
  } catch (err) {
21886
22029
  try {
21887
- if (existsSync32(tmp)) await unlink3(tmp);
22030
+ if (existsSync33(tmp)) await unlink3(tmp);
21888
22031
  } catch {
21889
22032
  }
21890
22033
  throw err;
@@ -21900,7 +22043,7 @@ async function collectLiveSidecars(projectsRoot) {
21900
22043
  }
21901
22044
  for (const slug of slugs) {
21902
22045
  if (!slug.isDirectory()) continue;
21903
- const slugDir = join33(projectsRoot, slug.name);
22046
+ const slugDir = join34(projectsRoot, slug.name);
21904
22047
  let entries;
21905
22048
  try {
21906
22049
  entries = await readdir6(slugDir, { withFileTypes: true });
@@ -21909,9 +22052,9 @@ async function collectLiveSidecars(projectsRoot) {
21909
22052
  }
21910
22053
  for (const entry of entries) {
21911
22054
  if (entry.isFile() && SESSION_META_RE.test(entry.name)) {
21912
- out.push(join33(slugDir, entry.name));
22055
+ out.push(join34(slugDir, entry.name));
21913
22056
  } else if (entry.isDirectory() && entry.name === "subagents") {
21914
- const subDir = join33(slugDir, entry.name);
22057
+ const subDir = join34(slugDir, entry.name);
21915
22058
  let subs;
21916
22059
  try {
21917
22060
  subs = await readdir6(subDir, { withFileTypes: true });
@@ -21919,7 +22062,7 @@ async function collectLiveSidecars(projectsRoot) {
21919
22062
  continue;
21920
22063
  }
21921
22064
  for (const s of subs) {
21922
- if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join33(subDir, s.name));
22065
+ if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join34(subDir, s.name));
21923
22066
  }
21924
22067
  }
21925
22068
  }
@@ -21931,7 +22074,7 @@ function shortId(path2) {
21931
22074
  return base.slice(0, 8);
21932
22075
  }
21933
22076
  async function migrateAdminWebchatSidecars(opts = {}) {
21934
- const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join33(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
22077
+ const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join34(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
21935
22078
  const usersFile = opts.usersFile ?? USERS_FILE;
21936
22079
  const accountId = opts.accountId ?? resolveAccount()?.accountId ?? null;
21937
22080
  const resolveName = opts.resolveName ?? defaultResolveName;
@@ -22276,8 +22419,8 @@ var streamSSE = (c, cb, onError) => {
22276
22419
 
22277
22420
  // app/lib/whatsapp/gateway/routes.ts
22278
22421
  function createWaChannelRoutes(deps) {
22279
- const app61 = new Hono();
22280
- app61.get("/wa-channel/inbound", (c) => {
22422
+ const app62 = new Hono();
22423
+ app62.get("/wa-channel/inbound", (c) => {
22281
22424
  const senderId = c.req.query("senderId");
22282
22425
  if (!senderId) return c.json({ error: "senderId required" }, 400);
22283
22426
  return streamSSE(c, async (stream2) => {
@@ -22295,7 +22438,7 @@ function createWaChannelRoutes(deps) {
22295
22438
  }
22296
22439
  });
22297
22440
  });
22298
- app61.post("/wa-channel/reply", async (c) => {
22441
+ app62.post("/wa-channel/reply", async (c) => {
22299
22442
  const body = await c.req.json().catch(() => null);
22300
22443
  const senderId = body?.senderId;
22301
22444
  const text = body?.text;
@@ -22316,7 +22459,7 @@ function createWaChannelRoutes(deps) {
22316
22459
  console.error(`[whatsapp-native] op=reply-dispatch senderId=${senderId} bytes=${bytes}`);
22317
22460
  return c.json({ ok: true });
22318
22461
  });
22319
- app61.post("/wa-channel/reply-document", async (c) => {
22462
+ app62.post("/wa-channel/reply-document", async (c) => {
22320
22463
  const body = await c.req.json().catch(() => null);
22321
22464
  const senderId = body?.senderId;
22322
22465
  const files = body?.files;
@@ -22355,7 +22498,7 @@ function createWaChannelRoutes(deps) {
22355
22498
  }
22356
22499
  return c.json({ ok: true, results });
22357
22500
  });
22358
- app61.post("/wa-channel/ready", async (c) => {
22501
+ app62.post("/wa-channel/ready", async (c) => {
22359
22502
  const body = await c.req.json().catch(() => null);
22360
22503
  const senderId = body?.senderId;
22361
22504
  if (typeof senderId !== "string") {
@@ -22364,7 +22507,7 @@ function createWaChannelRoutes(deps) {
22364
22507
  deps.onReady?.(senderId);
22365
22508
  return c.json({ ok: true });
22366
22509
  });
22367
- app61.post("/wa-channel/received", async (c) => {
22510
+ app62.post("/wa-channel/received", async (c) => {
22368
22511
  const body = await c.req.json().catch(() => null);
22369
22512
  const senderId = body?.senderId;
22370
22513
  const waMessageId = body?.waMessageId;
@@ -22374,7 +22517,7 @@ function createWaChannelRoutes(deps) {
22374
22517
  deps.onReceived?.(senderId, waMessageId);
22375
22518
  return c.json({ ok: true });
22376
22519
  });
22377
- app61.post("/wa-channel/turn-end", async (c) => {
22520
+ app62.post("/wa-channel/turn-end", async (c) => {
22378
22521
  const body = await c.req.json().catch(() => null);
22379
22522
  const senderId = body?.senderId;
22380
22523
  const sessionId = body?.sessionId;
@@ -22407,7 +22550,7 @@ function createWaChannelRoutes(deps) {
22407
22550
  console.error(`[whatsapp-native] op=turn-end sessionId=${sid} replied=no delivered=none`);
22408
22551
  return c.json({ ok: true, delivered: "none" });
22409
22552
  });
22410
- return app61;
22553
+ return app62;
22411
22554
  }
22412
22555
 
22413
22556
  // app/lib/whatsapp/gateway/wa-gateway.ts
@@ -22499,10 +22642,12 @@ var WaGateway = class {
22499
22642
  this.docContexts.set(input.senderId, { accountId: input.accountId, maxyAccountId: input.effectiveAccountId });
22500
22643
  let standingRules;
22501
22644
  if (this.deps.fetchStandingRules) {
22502
- standingRules = await this.deps.fetchStandingRules(input.effectiveAccountId) || void 0;
22503
- const injected = standingRules ? (standingRules.match(/^- /gm) ?? []).length : 0;
22645
+ const res = await this.deps.fetchStandingRules(input.effectiveAccountId);
22646
+ standingRules = res.block || void 0;
22647
+ const injected = res.block ? (res.block.match(/^- /gm) ?? []).length : 0;
22648
+ const owner8 = res.ownerUserId ? res.ownerUserId.slice(0, 8) : "-";
22504
22649
  console.error(
22505
- `[preference-inject] op=inject channel=wa accountId=${input.effectiveAccountId} injected=${injected} capped=${injected >= import_dist5.INJECTION_RULE_CAP}`
22650
+ `[preference-inject] op=inject channel=wa accountId=${input.effectiveAccountId} injected=${injected} owner=${owner8} source=${res.source} capped=${injected >= import_dist5.INJECTION_RULE_CAP}`
22506
22651
  );
22507
22652
  }
22508
22653
  this.hub.deliver(
@@ -22748,8 +22893,8 @@ var import_dist6 = __toESM(require_dist(), 1);
22748
22893
 
22749
22894
  // app/lib/webchat/gateway/routes.ts
22750
22895
  function createWebchatChannelRoutes(deps) {
22751
- const app61 = new Hono();
22752
- app61.get("/webchat-channel/inbound", (c) => {
22896
+ const app62 = new Hono();
22897
+ app62.get("/webchat-channel/inbound", (c) => {
22753
22898
  const key = c.req.query("key");
22754
22899
  if (!key) return c.json({ error: "key required" }, 400);
22755
22900
  return streamSSE(c, async (stream2) => {
@@ -22767,7 +22912,7 @@ function createWebchatChannelRoutes(deps) {
22767
22912
  }
22768
22913
  });
22769
22914
  });
22770
- app61.post("/webchat-channel/reply", async (c) => {
22915
+ app62.post("/webchat-channel/reply", async (c) => {
22771
22916
  const body = await c.req.json().catch(() => null);
22772
22917
  const key = body?.key;
22773
22918
  const text = body?.text;
@@ -22777,7 +22922,7 @@ function createWebchatChannelRoutes(deps) {
22777
22922
  deps.onReply?.(key, text);
22778
22923
  return c.json({ ok: true });
22779
22924
  });
22780
- app61.post("/webchat-channel/connector-auth", async (c) => {
22925
+ app62.post("/webchat-channel/connector-auth", async (c) => {
22781
22926
  const body = await c.req.json().catch(() => null);
22782
22927
  const key = body?.key;
22783
22928
  const sessionId = body?.sessionId;
@@ -22790,7 +22935,7 @@ function createWebchatChannelRoutes(deps) {
22790
22935
  const result = await deps.onConnectorAuth({ key, sessionId, name, completed });
22791
22936
  return c.json(result);
22792
22937
  });
22793
- app61.post("/webchat-channel/ready", async (c) => {
22938
+ app62.post("/webchat-channel/ready", async (c) => {
22794
22939
  const body = await c.req.json().catch(() => null);
22795
22940
  const key = body?.key;
22796
22941
  if (typeof key !== "string") {
@@ -22799,7 +22944,7 @@ function createWebchatChannelRoutes(deps) {
22799
22944
  deps.onReady?.(key);
22800
22945
  return c.json({ ok: true });
22801
22946
  });
22802
- app61.post("/webchat-channel/permission-request", async (c) => {
22947
+ app62.post("/webchat-channel/permission-request", async (c) => {
22803
22948
  const body = await c.req.json().catch(() => null);
22804
22949
  const key = body?.key;
22805
22950
  const requestId = body?.request_id;
@@ -22813,7 +22958,7 @@ function createWebchatChannelRoutes(deps) {
22813
22958
  const verdict = await deps.awaitPermissionVerdict({ key, requestId, toolName, description, inputPreview });
22814
22959
  return c.json(verdict);
22815
22960
  });
22816
- app61.post("/webchat-channel/received", async (c) => {
22961
+ app62.post("/webchat-channel/received", async (c) => {
22817
22962
  const body = await c.req.json().catch(() => null);
22818
22963
  const key = body?.key;
22819
22964
  const messageId = body?.messageId;
@@ -22823,7 +22968,7 @@ function createWebchatChannelRoutes(deps) {
22823
22968
  deps.onReceived?.(key, messageId);
22824
22969
  return c.json({ ok: true });
22825
22970
  });
22826
- app61.post("/webchat-channel/turn-end", async (c) => {
22971
+ app62.post("/webchat-channel/turn-end", async (c) => {
22827
22972
  const body = await c.req.json().catch(() => null);
22828
22973
  const key = body?.key;
22829
22974
  const sessionId = body?.sessionId;
@@ -22846,7 +22991,7 @@ function createWebchatChannelRoutes(deps) {
22846
22991
  console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} delivered=none`);
22847
22992
  return c.json({ ok: true, delivered: "none" });
22848
22993
  });
22849
- return app61;
22994
+ return app62;
22850
22995
  }
22851
22996
 
22852
22997
  // app/lib/webchat/gateway/webchat-gateway.ts
@@ -23185,10 +23330,12 @@ var WebchatGateway = class _WebchatGateway {
23185
23330
  const willDeliverNow = this.hub.isReady(input.key);
23186
23331
  let standingRules;
23187
23332
  if (input.role === "admin" && this.deps.fetchStandingRules) {
23188
- standingRules = await this.deps.fetchStandingRules(input.accountId) || void 0;
23189
- const injected = standingRules ? (standingRules.match(/^- /gm) ?? []).length : 0;
23333
+ const res = await this.deps.fetchStandingRules(input.accountId);
23334
+ standingRules = res.block || void 0;
23335
+ const injected = res.block ? (res.block.match(/^- /gm) ?? []).length : 0;
23336
+ const owner8 = res.ownerUserId ? res.ownerUserId.slice(0, 8) : "-";
23190
23337
  console.error(
23191
- `[preference-inject] op=inject channel=web accountId=${input.accountId} injected=${injected} capped=${injected >= import_dist6.INJECTION_RULE_CAP}`
23338
+ `[preference-inject] op=inject channel=web accountId=${input.accountId} injected=${injected} owner=${owner8} source=${res.source} capped=${injected >= import_dist6.INJECTION_RULE_CAP}`
23192
23339
  );
23193
23340
  }
23194
23341
  this.hub.deliver(
@@ -23477,7 +23624,7 @@ function makeFileDelivery(opts) {
23477
23624
  }
23478
23625
 
23479
23626
  // app/lib/whatsapp/inbound/file-delivery-bridge.ts
23480
- var TAG40 = "[whatsapp-adaptor]";
23627
+ var TAG41 = "[whatsapp-adaptor]";
23481
23628
  var SEND_USER_FILE2 = "SendUserFile";
23482
23629
  var WHATSAPP_SEND_DOCUMENT = "whatsapp-send-document";
23483
23630
  function platformRoot() {
@@ -23495,7 +23642,7 @@ function makeWhatsAppSendFile(entry, maxyAccountId) {
23495
23642
  });
23496
23643
  if (result.ok) return { ok: true };
23497
23644
  console.error(
23498
- `${TAG40} file-delivery reject reason=send-failed sender=${entry.senderId} status=${result.status} message=${result.error}`
23645
+ `${TAG41} file-delivery reject reason=send-failed sender=${entry.senderId} status=${result.status} message=${result.error}`
23499
23646
  );
23500
23647
  return { ok: false, error: result.error };
23501
23648
  };
@@ -23503,7 +23650,7 @@ function makeWhatsAppSendFile(entry, maxyAccountId) {
23503
23650
  function makeWhatsAppFileDelivery(entry, maxyAccountId) {
23504
23651
  const shared = makeFileDelivery({
23505
23652
  entry,
23506
- tag: TAG40,
23653
+ tag: TAG41,
23507
23654
  channel: "whatsapp",
23508
23655
  sendFile: makeWhatsAppSendFile(entry, maxyAccountId)
23509
23656
  });
@@ -23538,7 +23685,7 @@ function makeWhatsAppFileDelivery(entry, maxyAccountId) {
23538
23685
  if (!delivered) {
23539
23686
  const fileField = call.filePath !== void 0 ? ` file=${call.filePath}` : "";
23540
23687
  console.error(
23541
- `${TAG40} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
23688
+ `${TAG41} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
23542
23689
  );
23543
23690
  }
23544
23691
  }
@@ -23715,8 +23862,8 @@ var import_dist7 = __toESM(require_dist(), 1);
23715
23862
 
23716
23863
  // app/lib/telegram/gateway/routes.ts
23717
23864
  function createTelegramChannelRoutes(deps) {
23718
- const app61 = new Hono();
23719
- app61.get("/tg-channel/inbound", (c) => {
23865
+ const app62 = new Hono();
23866
+ app62.get("/tg-channel/inbound", (c) => {
23720
23867
  const key = c.req.query("key");
23721
23868
  if (!key) return c.json({ error: "key required" }, 400);
23722
23869
  return streamSSE(c, async (stream2) => {
@@ -23734,7 +23881,7 @@ function createTelegramChannelRoutes(deps) {
23734
23881
  }
23735
23882
  });
23736
23883
  });
23737
- app61.post("/tg-channel/reply", async (c) => {
23884
+ app62.post("/tg-channel/reply", async (c) => {
23738
23885
  const body = await c.req.json().catch(() => null);
23739
23886
  const key = body?.key;
23740
23887
  const text = body?.text;
@@ -23750,7 +23897,7 @@ function createTelegramChannelRoutes(deps) {
23750
23897
  console.error(`[telegram-native] op=reply key=${key} bytes=${Buffer.byteLength(text, "utf8")}`);
23751
23898
  return c.json({ ok: true });
23752
23899
  });
23753
- app61.post("/tg-channel/ready", async (c) => {
23900
+ app62.post("/tg-channel/ready", async (c) => {
23754
23901
  const body = await c.req.json().catch(() => null);
23755
23902
  const key = body?.key;
23756
23903
  if (typeof key !== "string") {
@@ -23759,7 +23906,7 @@ function createTelegramChannelRoutes(deps) {
23759
23906
  deps.onReady?.(key);
23760
23907
  return c.json({ ok: true });
23761
23908
  });
23762
- app61.post("/tg-channel/received", async (c) => {
23909
+ app62.post("/tg-channel/received", async (c) => {
23763
23910
  const body = await c.req.json().catch(() => null);
23764
23911
  const key = body?.key;
23765
23912
  const messageId = body?.messageId;
@@ -23769,7 +23916,7 @@ function createTelegramChannelRoutes(deps) {
23769
23916
  deps.onReceived?.(key, messageId);
23770
23917
  return c.json({ ok: true });
23771
23918
  });
23772
- app61.post("/tg-channel/turn-end", async (c) => {
23919
+ app62.post("/tg-channel/turn-end", async (c) => {
23773
23920
  const body = await c.req.json().catch(() => null);
23774
23921
  const key = body?.key;
23775
23922
  const sessionId = body?.sessionId;
@@ -23802,7 +23949,7 @@ function createTelegramChannelRoutes(deps) {
23802
23949
  console.error(`[telegram-native] op=turn-end key=${key} sessionId=${sid} replied=no delivered=none`);
23803
23950
  return c.json({ ok: true, delivered: "none" });
23804
23951
  });
23805
- return app61;
23952
+ return app62;
23806
23953
  }
23807
23954
 
23808
23955
  // app/lib/telegram/gateway/telegram-gateway.ts
@@ -23862,10 +24009,12 @@ var TelegramGateway = class {
23862
24009
  this.replies.set(input.senderId, input.reply);
23863
24010
  let standingRules;
23864
24011
  if (input.role === "admin" && this.deps.fetchStandingRules) {
23865
- standingRules = await this.deps.fetchStandingRules(input.accountId) || void 0;
23866
- const injected = standingRules ? (standingRules.match(/^- /gm) ?? []).length : 0;
24012
+ const res = await this.deps.fetchStandingRules(input.accountId);
24013
+ standingRules = res.block || void 0;
24014
+ const injected = res.block ? (res.block.match(/^- /gm) ?? []).length : 0;
24015
+ const owner8 = res.ownerUserId ? res.ownerUserId.slice(0, 8) : "-";
23867
24016
  console.error(
23868
- `[preference-inject] op=inject channel=tg accountId=${input.accountId} injected=${injected} capped=${injected >= import_dist7.INJECTION_RULE_CAP}`
24017
+ `[preference-inject] op=inject channel=tg accountId=${input.accountId} injected=${injected} owner=${owner8} source=${res.source} capped=${injected >= import_dist7.INJECTION_RULE_CAP}`
23869
24018
  );
23870
24019
  }
23871
24020
  this.hub.deliver(
@@ -23929,8 +24078,8 @@ function buildTelegramSpawnRequest(input) {
23929
24078
  // app/lib/telegram/outbound/send-document.ts
23930
24079
  import { realpathSync as realpathSync7 } from "fs";
23931
24080
  import { readFile as readFile7, stat as stat7 } from "fs/promises";
23932
- import { resolve as resolve30, basename as basename12 } from "path";
23933
- var TAG41 = "[telegram:outbound]";
24081
+ import { resolve as resolve30, basename as basename11 } from "path";
24082
+ var TAG42 = "[telegram:outbound]";
23934
24083
  var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
23935
24084
  async function sendTelegramDocument(input) {
23936
24085
  const { botToken, chatId, filePath, caption, maxyAccountId, platformRoot: platformRoot3 } = input;
@@ -23946,16 +24095,16 @@ async function sendTelegramDocument(input) {
23946
24095
  resolvedPath = realpathSync7(filePath);
23947
24096
  const accountResolved = realpathSync7(accountDir);
23948
24097
  if (!resolvedPath.startsWith(accountResolved + "/")) {
23949
- console.error(`${TAG41} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
24098
+ console.error(`${TAG42} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
23950
24099
  return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
23951
24100
  }
23952
24101
  } catch (err) {
23953
24102
  const code = err.code;
23954
24103
  if (code === "ENOENT") {
23955
- console.error(`${TAG41} document ENOENT path=${filePath}`);
24104
+ console.error(`${TAG42} document ENOENT path=${filePath}`);
23956
24105
  return { ok: false, status: 404, error: `File not found: ${filePath}` };
23957
24106
  }
23958
- console.error(`${TAG41} document path error: ${String(err)}`);
24107
+ console.error(`${TAG42} document path error: ${String(err)}`);
23959
24108
  return { ok: false, status: 500, error: String(err) };
23960
24109
  }
23961
24110
  const fileStat = await stat7(resolvedPath);
@@ -23966,7 +24115,7 @@ async function sendTelegramDocument(input) {
23966
24115
  error: `File exceeds 50 MB limit (${(fileStat.size / 1024 / 1024).toFixed(1)} MB)`
23967
24116
  };
23968
24117
  }
23969
- const filename = basename12(resolvedPath);
24118
+ const filename = basename11(resolvedPath);
23970
24119
  const buffer = Buffer.from(await readFile7(resolvedPath));
23971
24120
  const form = new FormData();
23972
24121
  form.append("chat_id", String(chatId));
@@ -23988,13 +24137,13 @@ async function sendTelegramDocument(input) {
23988
24137
  error = e instanceof Error ? e.message : String(e);
23989
24138
  }
23990
24139
  console.error(
23991
- `${TAG41} sent document to=${chatId} file=${filename} bytes=${fileStat.size} ok=${ok}` + (messageId !== void 0 ? ` id=${messageId}` : "")
24140
+ `${TAG42} sent document to=${chatId} file=${filename} bytes=${fileStat.size} ok=${ok}` + (messageId !== void 0 ? ` id=${messageId}` : "")
23992
24141
  );
23993
24142
  return ok ? { ok: true, messageId } : { ok: false, status: 500, error };
23994
24143
  }
23995
24144
 
23996
24145
  // app/lib/telegram/outbound/file-delivery.ts
23997
- var TAG42 = "[telegram:outbound]";
24146
+ var TAG43 = "[telegram:outbound]";
23998
24147
  function platformRoot2() {
23999
24148
  return process.env.MAXY_PLATFORM_ROOT || "";
24000
24149
  }
@@ -24006,11 +24155,11 @@ function makeTelegramSendFile(entry) {
24006
24155
  botToken = (entry.role === "admin" ? tg?.adminBotToken : tg?.publicBotToken) ?? null;
24007
24156
  }
24008
24157
  if (!botToken) {
24009
- console.error(`${TAG42} file-delivery reject reason=no-bot-token sender=${entry.senderId} role=${entry.role}`);
24158
+ console.error(`${TAG43} file-delivery reject reason=no-bot-token sender=${entry.senderId} role=${entry.role}`);
24010
24159
  return { ok: false, error: "no-bot-token" };
24011
24160
  }
24012
24161
  if (entry.replyTarget == null) {
24013
- console.error(`${TAG42} file-delivery reject reason=no-reply-target sender=${entry.senderId} role=${entry.role}`);
24162
+ console.error(`${TAG43} file-delivery reject reason=no-reply-target sender=${entry.senderId} role=${entry.role}`);
24014
24163
  return { ok: false, error: "no-reply-target" };
24015
24164
  }
24016
24165
  const result = await sendTelegramDocument({
@@ -24027,7 +24176,7 @@ function makeTelegramSendFile(entry) {
24027
24176
  function makeTelegramFileDelivery(entry) {
24028
24177
  return makeFileDelivery({
24029
24178
  entry,
24030
- tag: TAG42,
24179
+ tag: TAG43,
24031
24180
  channel: "telegram",
24032
24181
  sendFile: makeTelegramSendFile(entry)
24033
24182
  });
@@ -24067,17 +24216,17 @@ function startTelegramNativeFileFollower(input) {
24067
24216
  }
24068
24217
 
24069
24218
  // server/telegram-descriptor.ts
24070
- import { resolve as resolve31, join as join34 } from "path";
24219
+ import { resolve as resolve31, join as join35 } from "path";
24071
24220
  function telegramGatewayUrl() {
24072
24221
  return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
24073
24222
  }
24074
24223
  function telegramServerPath() {
24075
- return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve31(process.env.MAXY_PLATFORM_ROOT ?? join34(__dirname, ".."), "services/telegram-channel/dist/server.js");
24224
+ return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve31(process.env.MAXY_PLATFORM_ROOT ?? join35(__dirname, ".."), "services/telegram-channel/dist/server.js");
24076
24225
  }
24077
24226
 
24078
24227
  // app/lib/channel-pty-bridge/public-session-end-review.ts
24079
- import { randomUUID as randomUUID14 } from "crypto";
24080
- var TAG43 = "[public-session-review]";
24228
+ import { randomUUID as randomUUID15 } from "crypto";
24229
+ var TAG44 = "[public-session-review]";
24081
24230
  var CONSUMED_CAP = 500;
24082
24231
  var consumed = /* @__PURE__ */ new Set();
24083
24232
  function consumeOnce(sessionId) {
@@ -24104,7 +24253,7 @@ async function fetchJsonl(sessionId) {
24104
24253
  return await res.text();
24105
24254
  } catch (err) {
24106
24255
  console.error(
24107
- `${TAG43} jsonl-fetch-failed sessionId=${sessionId} err="${err instanceof Error ? err.message : String(err)}"`
24256
+ `${TAG44} jsonl-fetch-failed sessionId=${sessionId} err="${err instanceof Error ? err.message : String(err)}"`
24108
24257
  );
24109
24258
  return null;
24110
24259
  }
@@ -24128,7 +24277,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
24128
24277
  const res = await fetch(url);
24129
24278
  if (!res.ok) {
24130
24279
  console.error(
24131
- `${TAG43} prior-writes-fetch-failed sliceToken=${sliceToken.slice(0, 8)} status=${res.status}`
24280
+ `${TAG44} prior-writes-fetch-failed sliceToken=${sliceToken.slice(0, 8)} status=${res.status}`
24132
24281
  );
24133
24282
  return [];
24134
24283
  }
@@ -24136,7 +24285,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
24136
24285
  return Array.isArray(body.writes) ? body.writes : [];
24137
24286
  } catch (err) {
24138
24287
  console.error(
24139
- `${TAG43} prior-writes-fetch-threw sliceToken=${sliceToken.slice(0, 8)} err="${err instanceof Error ? err.message : String(err)}"`
24288
+ `${TAG44} prior-writes-fetch-threw sliceToken=${sliceToken.slice(0, 8)} err="${err instanceof Error ? err.message : String(err)}"`
24140
24289
  );
24141
24290
  return [];
24142
24291
  }
@@ -24164,8 +24313,8 @@ function composeInitialMessage(input) {
24164
24313
  ].join("\n");
24165
24314
  }
24166
24315
  async function dispatchReviewer(input, initialMessage) {
24167
- const sessionId = randomUUID14();
24168
- console.log(`${TAG43} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
24316
+ const sessionId = randomUUID15();
24317
+ console.log(`${TAG44} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
24169
24318
  const spawned = await managerRcSpawn({
24170
24319
  sessionId,
24171
24320
  initialMessage,
@@ -24185,21 +24334,21 @@ async function firePublicSessionEndReview(input) {
24185
24334
  const dispatchedAt = Date.now();
24186
24335
  if (consumed.has(input.sessionId)) {
24187
24336
  console.log(
24188
- `${TAG43} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
24337
+ `${TAG44} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
24189
24338
  );
24190
24339
  return;
24191
24340
  }
24192
24341
  const jsonl = await fetchJsonl(input.sessionId);
24193
24342
  if (!jsonl) {
24194
24343
  console.log(
24195
- `${TAG43} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-jsonl-missing`
24344
+ `${TAG44} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-jsonl-missing`
24196
24345
  );
24197
24346
  return;
24198
24347
  }
24199
24348
  const operatorTurns = countOperatorTurns(jsonl);
24200
24349
  if (operatorTurns === 0) {
24201
24350
  console.log(
24202
- `${TAG43} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-no-turns`
24351
+ `${TAG44} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-no-turns`
24203
24352
  );
24204
24353
  return;
24205
24354
  }
@@ -24213,19 +24362,19 @@ async function firePublicSessionEndReview(input) {
24213
24362
  });
24214
24363
  if (!consumeOnce(input.sessionId)) {
24215
24364
  console.log(
24216
- `${TAG43} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
24365
+ `${TAG44} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
24217
24366
  );
24218
24367
  return;
24219
24368
  }
24220
24369
  const dispatched = await dispatchReviewer(input, initialMessage);
24221
24370
  if (!dispatched.ok) {
24222
24371
  console.error(
24223
- `${TAG43} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-spawn-failed reason=${dispatched.reason}`
24372
+ `${TAG44} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-spawn-failed reason=${dispatched.reason}`
24224
24373
  );
24225
24374
  return;
24226
24375
  }
24227
24376
  console.log(
24228
- `${TAG43} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=dispatched managerSessionId=${dispatched.managerSessionId} operatorTurns=${operatorTurns} priorWrites=${priorWrites.length} ms=${Date.now() - dispatchedAt}`
24377
+ `${TAG44} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=dispatched managerSessionId=${dispatched.managerSessionId} operatorTurns=${operatorTurns} priorWrites=${priorWrites.length} ms=${Date.now() - dispatchedAt}`
24229
24378
  );
24230
24379
  }
24231
24380
 
@@ -24334,7 +24483,7 @@ function broadcastAdminShutdown(reason) {
24334
24483
 
24335
24484
  // ../lib/entitlement/src/index.ts
24336
24485
  import { createPublicKey, createHash as createHash6, verify as cryptoVerify } from "crypto";
24337
- import { existsSync as existsSync33, readFileSync as readFileSync34, statSync as statSync13 } from "fs";
24486
+ import { existsSync as existsSync34, readFileSync as readFileSync34, statSync as statSync13 } from "fs";
24338
24487
  import { resolve as resolve32 } from "path";
24339
24488
 
24340
24489
  // ../lib/entitlement/src/canonicalize.ts
@@ -24383,7 +24532,7 @@ function resolveEntitlement(brand, account) {
24383
24532
  return logResolved(implicitTrust(account), null);
24384
24533
  }
24385
24534
  const entitlementPath = resolve32(brand.configDir, "entitlement.json");
24386
- if (!existsSync33(entitlementPath)) {
24535
+ if (!existsSync34(entitlementPath)) {
24387
24536
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
24388
24537
  }
24389
24538
  const stat8 = statSync13(entitlementPath);
@@ -24573,12 +24722,12 @@ function clientFrom(c) {
24573
24722
  );
24574
24723
  }
24575
24724
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
24576
- var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join35(PLATFORM_ROOT8, "config", "brand.json") : "";
24725
+ var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join36(PLATFORM_ROOT8, "config", "brand.json") : "";
24577
24726
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
24578
- if (BRAND_JSON_PATH && !existsSync34(BRAND_JSON_PATH)) {
24727
+ if (BRAND_JSON_PATH && !existsSync35(BRAND_JSON_PATH)) {
24579
24728
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
24580
24729
  }
24581
- if (BRAND_JSON_PATH && existsSync34(BRAND_JSON_PATH)) {
24730
+ if (BRAND_JSON_PATH && existsSync35(BRAND_JSON_PATH)) {
24582
24731
  try {
24583
24732
  const parsed = JSON.parse(readFileSync35(BRAND_JSON_PATH, "utf-8"));
24584
24733
  BRAND = { ...BRAND, ...parsed };
@@ -24612,10 +24761,10 @@ var brandLoginOpts = {
24612
24761
  appleTouchIconPath: brandAppIcon512Path,
24613
24762
  themeColor: BRAND.defaultColors?.primary
24614
24763
  };
24615
- var ALIAS_DOMAINS_PATH = join35(homedir3(), BRAND.configDir, "alias-domains.json");
24764
+ var ALIAS_DOMAINS_PATH = join36(homedir4(), BRAND.configDir, "alias-domains.json");
24616
24765
  function loadAliasDomains() {
24617
24766
  try {
24618
- if (!existsSync34(ALIAS_DOMAINS_PATH)) return null;
24767
+ if (!existsSync35(ALIAS_DOMAINS_PATH)) return null;
24619
24768
  const parsed = JSON.parse(readFileSync35(ALIAS_DOMAINS_PATH, "utf-8"));
24620
24769
  if (!Array.isArray(parsed)) {
24621
24770
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
@@ -24640,18 +24789,18 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
24640
24789
  function isPublicHost(host) {
24641
24790
  return host.startsWith("public.") || aliasDomains.has(host);
24642
24791
  }
24643
- var app60 = new Hono();
24792
+ var app61 = new Hono();
24644
24793
  var nativeFileFollowers = /* @__PURE__ */ new Map();
24645
24794
  async function fetchAccountStandingRules(accountId) {
24646
24795
  const session = getSession();
24647
24796
  try {
24648
- const rules = await (0, import_dist8.activeRuleSet)(session, accountId);
24649
- return (0, import_dist8.formatStandingRulesBlock)(rules);
24797
+ const res = await (0, import_dist8.resolveActiveRules)(session, accountId);
24798
+ return { block: (0, import_dist8.formatStandingRulesBlock)(res.rules), ownerUserId: res.ownerUserId, source: res.source };
24650
24799
  } catch (err) {
24651
24800
  console.error(
24652
24801
  `[preference-inject] op=fetch-failed accountId=${accountId} error=${err instanceof Error ? err.message : String(err)}`
24653
24802
  );
24654
- return "";
24803
+ return { block: "", ownerUserId: null, source: "fetch-error" };
24655
24804
  } finally {
24656
24805
  await session.close();
24657
24806
  }
@@ -24679,7 +24828,7 @@ async function recordPassiveDispatch(input) {
24679
24828
  var waGateway = new WaGateway({
24680
24829
  fetchStandingRules: fetchAccountStandingRules,
24681
24830
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
24682
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve33(process.env.MAXY_PLATFORM_ROOT ?? join35(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
24831
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve33(process.env.MAXY_PLATFORM_ROOT ?? join36(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
24683
24832
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
24684
24833
  // path-validation scope) is the sender's effective SESSION account, resolved
24685
24834
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -24694,7 +24843,7 @@ var waGateway = new WaGateway({
24694
24843
  caption,
24695
24844
  accountId,
24696
24845
  maxyAccountId,
24697
- platformRoot: resolve33(process.env.MAXY_PLATFORM_ROOT ?? join35(__dirname, ".."))
24846
+ platformRoot: resolve33(process.env.MAXY_PLATFORM_ROOT ?? join36(__dirname, ".."))
24698
24847
  });
24699
24848
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
24700
24849
  },
@@ -24775,7 +24924,7 @@ var waGateway = new WaGateway({
24775
24924
  nativeFileFollowers.set(senderId, ac);
24776
24925
  }
24777
24926
  });
24778
- app60.route("/", waGateway.routes());
24927
+ app61.route("/", waGateway.routes());
24779
24928
  waGateway.startSweeper();
24780
24929
  var webchatGateway = new WebchatGateway({
24781
24930
  fetchStandingRules: fetchAccountStandingRules,
@@ -24859,7 +25008,7 @@ var webchatGateway = new WebchatGateway({
24859
25008
  firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
24860
25009
  });
24861
25010
  setWebchatGateway(webchatGateway);
24862
- app60.route("/", webchatGateway.routes());
25011
+ app61.route("/", webchatGateway.routes());
24863
25012
  webchatGateway.startSweeper();
24864
25013
  webchatGateway.startPublicReaper();
24865
25014
  var telegramFileFollowers = /* @__PURE__ */ new Map();
@@ -24893,7 +25042,7 @@ var telegramGateway = new TelegramGateway({
24893
25042
  }
24894
25043
  });
24895
25044
  setTelegramGateway(telegramGateway);
24896
- app60.route("/", telegramGateway.routes());
25045
+ app61.route("/", telegramGateway.routes());
24897
25046
  telegramGateway.startSweeper();
24898
25047
  var chatRoutes = createChatRoutes({
24899
25048
  handleInbound: (input) => webchatGateway.handleInbound(input),
@@ -24926,19 +25075,19 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
24926
25075
  return managed.account;
24927
25076
  }
24928
25077
  });
24929
- app60.route("/api/channel/schedule-inject", scheduleInjectRoutes);
24930
- app60.use("*", clientIpMiddleware);
25078
+ app61.route("/api/channel/schedule-inject", scheduleInjectRoutes);
25079
+ app61.use("*", clientIpMiddleware);
24931
25080
  function allowsSameOriginFraming(path2) {
24932
25081
  return path2 === "/vnc-viewer.html" || path2.startsWith("/api/admin/attachment/") || path2.startsWith("/api/public-reader/attachment/") || path2 === "/api/admin/files/download";
24933
25082
  }
24934
- app60.use("*", async (c, next) => {
25083
+ app61.use("*", async (c, next) => {
24935
25084
  await next();
24936
25085
  c.header("X-Content-Type-Options", "nosniff");
24937
25086
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
24938
25087
  c.header("X-Frame-Options", allowsSameOriginFraming(c.req.path) ? "SAMEORIGIN" : "DENY");
24939
25088
  });
24940
25089
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
24941
- app60.use("*", async (c, next) => {
25090
+ app61.use("*", async (c, next) => {
24942
25091
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
24943
25092
  await next();
24944
25093
  return;
@@ -24956,7 +25105,7 @@ app60.use("*", async (c, next) => {
24956
25105
  });
24957
25106
  }
24958
25107
  });
24959
- app60.use("*", async (c, next) => {
25108
+ app61.use("*", async (c, next) => {
24960
25109
  const host = (c.req.header("host") ?? "").split(":")[0];
24961
25110
  if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
24962
25111
  await next();
@@ -24994,7 +25143,7 @@ function resolveRemoteAuthOpts(c) {
24994
25143
  return { ...brandLoginOpts, origin };
24995
25144
  }
24996
25145
  var MAX_LOGIN_BODY = 8 * 1024;
24997
- app60.post("/__remote-auth/login", async (c) => {
25146
+ app61.post("/__remote-auth/login", async (c) => {
24998
25147
  const client = clientFrom(c);
24999
25148
  const clientIp = client.ip || "unknown";
25000
25149
  if (!requestIsTlsTerminated(c)) {
@@ -25039,7 +25188,7 @@ app60.post("/__remote-auth/login", async (c) => {
25039
25188
  }
25040
25189
  });
25041
25190
  });
25042
- app60.get("/__remote-auth/logout", (c) => {
25191
+ app61.get("/__remote-auth/logout", (c) => {
25043
25192
  const client = clientFrom(c);
25044
25193
  const clientIp = client.ip || "unknown";
25045
25194
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -25052,7 +25201,7 @@ app60.get("/__remote-auth/logout", (c) => {
25052
25201
  }
25053
25202
  });
25054
25203
  });
25055
- app60.post("/__remote-auth/change-password", async (c) => {
25204
+ app61.post("/__remote-auth/change-password", async (c) => {
25056
25205
  const client = clientFrom(c);
25057
25206
  const clientIp = client.ip || "unknown";
25058
25207
  const rateLimited = checkRateLimit(client);
@@ -25111,13 +25260,13 @@ app60.post("/__remote-auth/change-password", async (c) => {
25111
25260
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Failed to save password", redirect }), 200);
25112
25261
  }
25113
25262
  });
25114
- app60.get("/__remote-auth/setup", (c) => {
25263
+ app61.get("/__remote-auth/setup", (c) => {
25115
25264
  if (isRemoteAuthConfigured()) {
25116
25265
  return c.redirect("/");
25117
25266
  }
25118
25267
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup" }), 200);
25119
25268
  });
25120
- app60.post("/__remote-auth/set-initial-password", async (c) => {
25269
+ app61.post("/__remote-auth/set-initial-password", async (c) => {
25121
25270
  if (isRemoteAuthConfigured()) {
25122
25271
  return c.redirect("/");
25123
25272
  }
@@ -25155,10 +25304,10 @@ app60.post("/__remote-auth/set-initial-password", async (c) => {
25155
25304
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
25156
25305
  }
25157
25306
  });
25158
- app60.get("/api/remote-auth/status", (c) => {
25307
+ app61.get("/api/remote-auth/status", (c) => {
25159
25308
  return c.json({ configured: isRemoteAuthConfigured() });
25160
25309
  });
25161
- app60.post("/api/remote-auth/set-password", async (c) => {
25310
+ app61.post("/api/remote-auth/set-password", async (c) => {
25162
25311
  let body;
25163
25312
  try {
25164
25313
  body = await c.req.json();
@@ -25197,10 +25346,10 @@ app60.post("/api/remote-auth/set-password", async (c) => {
25197
25346
  return c.json({ error: "Failed to save password" }, 500);
25198
25347
  }
25199
25348
  });
25200
- app60.route("/api/_client-error", client_error_default);
25349
+ app61.route("/api/_client-error", client_error_default);
25201
25350
  console.log("[client-error-route] mounted");
25202
25351
  var PWA_PUBLIC_PATHS = /* @__PURE__ */ new Set(["/sw.js", ...PWA_SURFACES.map((s) => s.manifestPath)]);
25203
- app60.use("*", async (c, next) => {
25352
+ app61.use("*", async (c, next) => {
25204
25353
  const host = (c.req.header("host") ?? "").split(":")[0];
25205
25354
  const path2 = c.req.path;
25206
25355
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/") || // Public free/busy is read by the booking page (a separate Cloudflare Pages
@@ -25244,26 +25393,26 @@ app60.use("*", async (c, next) => {
25244
25393
  }
25245
25394
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), redirect: path2 }), 200);
25246
25395
  });
25247
- app60.route("/api/health", health_default);
25248
- app60.route("/api/chat", chatRoutes);
25249
- app60.route("/api/whatsapp", whatsapp_default);
25250
- app60.route("/api/whatsapp-reader", whatsapp_reader_default);
25251
- app60.route("/api/public-reader", public_reader_default);
25252
- app60.route("/api/webchat", createWebchatRoutes({
25396
+ app61.route("/api/health", health_default);
25397
+ app61.route("/api/chat", chatRoutes);
25398
+ app61.route("/api/whatsapp", whatsapp_default);
25399
+ app61.route("/api/whatsapp-reader", whatsapp_reader_default);
25400
+ app61.route("/api/public-reader", public_reader_default);
25401
+ app61.route("/api/webchat", createWebchatRoutes({
25253
25402
  handleInbound: (input) => webchatGateway.handleInbound(input),
25254
25403
  // Task 940 — the permission relay's pointer read + verdict write.
25255
25404
  pendingPromptFor: (key) => webchatGateway.pendingPromptFor(key),
25256
25405
  deliveryFailureFor: (key) => webchatGateway.deliveryFailureFor(key),
25257
25406
  resolvePermissionVerdict: (key, requestId, behavior) => webchatGateway.resolvePermissionVerdict(key, requestId, behavior)
25258
25407
  }));
25259
- app60.route("/api/webchat/greeting", webchat_greeting_default);
25260
- app60.route("/api/telegram", telegram_default);
25261
- app60.route("/api/quickbooks", quickbooks_default);
25262
- app60.route("/api/onboarding", onboarding_default);
25263
- app60.route("/api/admin", admin_default);
25264
- app60.route("/api/access", access_default);
25265
- app60.route("/api/session", session_default2);
25266
- app60.route("/api/calendar", calendar_public_default);
25408
+ app61.route("/api/webchat/greeting", webchat_greeting_default);
25409
+ app61.route("/api/telegram", telegram_default);
25410
+ app61.route("/api/quickbooks", quickbooks_default);
25411
+ app61.route("/api/onboarding", onboarding_default);
25412
+ app61.route("/api/admin", admin_default);
25413
+ app61.route("/api/access", access_default);
25414
+ app61.route("/api/session", session_default2);
25415
+ app61.route("/api/calendar", calendar_public_default);
25267
25416
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
25268
25417
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
25269
25418
  var IMAGE_MIME = {
@@ -25275,7 +25424,7 @@ var IMAGE_MIME = {
25275
25424
  ".svg": "image/svg+xml",
25276
25425
  ".ico": "image/x-icon"
25277
25426
  };
25278
- app60.get("/agent-assets/:slug/:filename", (c) => {
25427
+ app61.get("/agent-assets/:slug/:filename", (c) => {
25279
25428
  const slug = c.req.param("slug");
25280
25429
  const filename = c.req.param("filename");
25281
25430
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -25297,7 +25446,7 @@ app60.get("/agent-assets/:slug/:filename", (c) => {
25297
25446
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
25298
25447
  return c.text("Forbidden", 403);
25299
25448
  }
25300
- if (!existsSync34(filePath)) {
25449
+ if (!existsSync35(filePath)) {
25301
25450
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
25302
25451
  return c.text("Not found", 404);
25303
25452
  }
@@ -25310,7 +25459,7 @@ app60.get("/agent-assets/:slug/:filename", (c) => {
25310
25459
  "Cache-Control": "public, max-age=3600"
25311
25460
  });
25312
25461
  });
25313
- app60.get("/generated/:filename", (c) => {
25462
+ app61.get("/generated/:filename", (c) => {
25314
25463
  const filename = c.req.param("filename");
25315
25464
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
25316
25465
  console.error(`[generated] serve file=${filename} status=403`);
@@ -25327,7 +25476,7 @@ app60.get("/generated/:filename", (c) => {
25327
25476
  console.error(`[generated] serve file=${filename} status=403`);
25328
25477
  return c.text("Forbidden", 403);
25329
25478
  }
25330
- if (!existsSync34(filePath)) {
25479
+ if (!existsSync35(filePath)) {
25331
25480
  console.error(`[generated] serve file=${filename} status=404`);
25332
25481
  return c.text("Not found", 404);
25333
25482
  }
@@ -25340,14 +25489,14 @@ app60.get("/generated/:filename", (c) => {
25340
25489
  "Cache-Control": "public, max-age=86400"
25341
25490
  });
25342
25491
  });
25343
- app60.route("/sites", sites_default);
25344
- app60.route("/listings", listings_default);
25345
- app60.route("/v", visitor_event_default);
25346
- app60.route("/v", visitor_consent_default);
25492
+ app61.route("/sites", sites_default);
25493
+ app61.route("/listings", listings_default);
25494
+ app61.route("/v", visitor_event_default);
25495
+ app61.route("/v", visitor_consent_default);
25347
25496
  var htmlCache = /* @__PURE__ */ new Map();
25348
25497
  var brandLogoPath = "/brand/maxy-monochrome.png";
25349
25498
  var brandIconPath = "/brand/maxy-monochrome.png";
25350
- if (BRAND_JSON_PATH && existsSync34(BRAND_JSON_PATH)) {
25499
+ if (BRAND_JSON_PATH && existsSync35(BRAND_JSON_PATH)) {
25351
25500
  try {
25352
25501
  const fullBrand = JSON.parse(readFileSync35(BRAND_JSON_PATH, "utf-8"));
25353
25502
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
@@ -25376,7 +25525,7 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
25376
25525
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
25377
25526
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
25378
25527
  var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
25379
- (p) => existsSync34(resolve33(process.cwd(), "public", p.replace(/^\//, "")))
25528
+ (p) => existsSync35(resolve33(process.cwd(), "public", p.replace(/^\//, "")))
25380
25529
  );
25381
25530
  var SW_SOURCE = (() => {
25382
25531
  try {
@@ -25388,8 +25537,8 @@ var SW_SOURCE = (() => {
25388
25537
  function readInstalledVersion() {
25389
25538
  try {
25390
25539
  if (!PLATFORM_ROOT8) return "unknown";
25391
- const versionFile = join35(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
25392
- if (!existsSync34(versionFile)) return "unknown";
25540
+ const versionFile = join36(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
25541
+ if (!existsSync35(versionFile)) return "unknown";
25393
25542
  const content = readFileSync35(versionFile, "utf-8").trim();
25394
25543
  return content || "unknown";
25395
25544
  } catch {
@@ -25448,12 +25597,12 @@ ${clientErrorReporterScript}
25448
25597
  return html;
25449
25598
  }
25450
25599
  function loadBrandingCache(agentSlug) {
25451
- const configDir2 = join35(homedir3(), BRAND.configDir);
25600
+ const configDir2 = join36(homedir4(), BRAND.configDir);
25452
25601
  try {
25453
25602
  const accountId = getDefaultAccountId();
25454
25603
  if (!accountId) return null;
25455
- const cachePath = join35(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
25456
- if (!existsSync34(cachePath)) return null;
25604
+ const cachePath = join36(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
25605
+ if (!existsSync35(cachePath)) return null;
25457
25606
  return JSON.parse(readFileSync35(cachePath, "utf-8"));
25458
25607
  } catch {
25459
25608
  return null;
@@ -25498,7 +25647,7 @@ function brandedPublicHtml(agentSlug) {
25498
25647
  function agentUnavailableHtml() {
25499
25648
  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>`;
25500
25649
  }
25501
- app60.get("/", (c) => {
25650
+ app61.get("/", (c) => {
25502
25651
  const host = (c.req.header("host") ?? "").split(":")[0];
25503
25652
  const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
25504
25653
  if (klass === "operator") {
@@ -25520,12 +25669,12 @@ app60.get("/", (c) => {
25520
25669
  console.log(`[host-class] host=${host} class=admin served=index.html`);
25521
25670
  return c.html(cachedHtml("index.html"));
25522
25671
  });
25523
- app60.get("/public", (c) => {
25672
+ app61.get("/public", (c) => {
25524
25673
  const host = (c.req.header("host") ?? "").split(":")[0];
25525
25674
  if (isPublicHost(host)) return c.text("Not found", 404);
25526
25675
  return c.html(cachedHtml("public.html"));
25527
25676
  });
25528
- app60.get("/public-chat", (c) => {
25677
+ app61.get("/public-chat", (c) => {
25529
25678
  const host = (c.req.header("host") ?? "").split(":")[0];
25530
25679
  if (isPublicHost(host)) return c.text("Not found", 404);
25531
25680
  return c.html(cachedHtml("public.html"));
@@ -25544,9 +25693,9 @@ async function logViewerFetch(c, next) {
25544
25693
  duration_ms: Date.now() - start
25545
25694
  });
25546
25695
  }
25547
- app60.use("/vnc-viewer.html", logViewerFetch);
25548
- app60.use("/vnc-popout.html", logViewerFetch);
25549
- app60.get("/vnc-popout.html", (c) => {
25696
+ app61.use("/vnc-viewer.html", logViewerFetch);
25697
+ app61.use("/vnc-popout.html", logViewerFetch);
25698
+ app61.get("/vnc-popout.html", (c) => {
25550
25699
  let html = htmlCache.get("vnc-popout.html");
25551
25700
  if (!html) {
25552
25701
  html = readFileSync35(resolve33(process.cwd(), "public", "vnc-popout.html"), "utf-8");
@@ -25559,7 +25708,7 @@ app60.get("/vnc-popout.html", (c) => {
25559
25708
  }
25560
25709
  return c.html(html);
25561
25710
  });
25562
- app60.post("/api/vnc/client-event", async (c) => {
25711
+ app61.post("/api/vnc/client-event", async (c) => {
25563
25712
  let body;
25564
25713
  try {
25565
25714
  body = await c.req.json();
@@ -25580,11 +25729,11 @@ app60.post("/api/vnc/client-event", async (c) => {
25580
25729
  });
25581
25730
  return c.json({ ok: true });
25582
25731
  });
25583
- app60.get("/g/:slug", (c) => {
25732
+ app61.get("/g/:slug", (c) => {
25584
25733
  return c.html(brandedPublicHtml(resolveDefaultSlug() ?? void 0));
25585
25734
  });
25586
25735
  for (const pwa of PWA_SURFACES) {
25587
- app60.get(pwa.manifestPath, (c) => {
25736
+ app61.get(pwa.manifestPath, (c) => {
25588
25737
  const manifest = buildManifest(pwa, {
25589
25738
  productName: BRAND.productName,
25590
25739
  appIcon192: brandAppIcon192Path,
@@ -25600,7 +25749,7 @@ for (const pwa of PWA_SURFACES) {
25600
25749
  return c.body(JSON.stringify(manifest));
25601
25750
  });
25602
25751
  }
25603
- app60.get("/sw.js", (c) => {
25752
+ app61.get("/sw.js", (c) => {
25604
25753
  if (SW_SOURCE == null) {
25605
25754
  console.error("[pwa] op=sw status=500 reason=sw-source-missing");
25606
25755
  return c.text("Service worker unavailable", 500);
@@ -25609,12 +25758,12 @@ app60.get("/sw.js", (c) => {
25609
25758
  console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
25610
25759
  return c.body(SW_SOURCE);
25611
25760
  });
25612
- app60.get("/graph", (c) => {
25761
+ app61.get("/graph", (c) => {
25613
25762
  const host = (c.req.header("host") ?? "").split(":")[0];
25614
25763
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
25615
25764
  return c.html(cachedHtml("graph.html"));
25616
25765
  });
25617
- app60.get("/chat", (c) => {
25766
+ app61.get("/chat", (c) => {
25618
25767
  const host = (c.req.header("host") ?? "").split(":")[0];
25619
25768
  if (isOperatorHost(host, getOperatorDomains())) {
25620
25769
  console.log(`[host-class] host=${host} class=operator served=operator.html`);
@@ -25623,27 +25772,27 @@ app60.get("/chat", (c) => {
25623
25772
  if (isPublicHost(host)) return c.text("Not found", 404);
25624
25773
  return c.html(cachedHtml("chat.html"));
25625
25774
  });
25626
- app60.get("/data", (c) => {
25775
+ app61.get("/data", (c) => {
25627
25776
  const host = (c.req.header("host") ?? "").split(":")[0];
25628
25777
  if (isPublicHost(host)) return c.text("Not found", 404);
25629
25778
  return c.html(cachedHtml("data.html"));
25630
25779
  });
25631
- app60.get("/tasks", (c) => {
25780
+ app61.get("/tasks", (c) => {
25632
25781
  const host = (c.req.header("host") ?? "").split(":")[0];
25633
25782
  if (isPublicHost(host)) return c.text("Not found", 404);
25634
25783
  return c.html(cachedHtml("tasks.html"));
25635
25784
  });
25636
- app60.get("/calendar", (c) => {
25785
+ app61.get("/calendar", (c) => {
25637
25786
  const host = (c.req.header("host") ?? "").split(":")[0];
25638
25787
  if (isPublicHost(host)) return c.text("Not found", 404);
25639
25788
  return c.html(cachedHtml("calendar.html"));
25640
25789
  });
25641
- app60.get("/browser", (c) => {
25790
+ app61.get("/browser", (c) => {
25642
25791
  const host = (c.req.header("host") ?? "").split(":")[0];
25643
25792
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
25644
25793
  return c.html(cachedHtml("browser.html"));
25645
25794
  });
25646
- app60.get("/:slug", async (c, next) => {
25795
+ app61.get("/:slug", async (c, next) => {
25647
25796
  const slug = c.req.param("slug");
25648
25797
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
25649
25798
  const account = resolveAccount();
@@ -25658,13 +25807,13 @@ app60.get("/:slug", async (c, next) => {
25658
25807
  await next();
25659
25808
  });
25660
25809
  if (brandFaviconPath !== "/favicon.ico") {
25661
- app60.get("/favicon.ico", (c) => {
25810
+ app61.get("/favicon.ico", (c) => {
25662
25811
  c.header("Cache-Control", "public, max-age=300");
25663
25812
  return c.redirect(brandFaviconPath, 302);
25664
25813
  });
25665
25814
  }
25666
- app60.use("/*", serveStatic({ root: "./public" }));
25667
- app60.all("*", (c) => {
25815
+ app61.use("/*", serveStatic({ root: "./public" }));
25816
+ app61.all("*", (c) => {
25668
25817
  const host = (c.req.header("host") ?? "").split(":")[0];
25669
25818
  const path2 = c.req.path;
25670
25819
  if (isPublicHost(host)) {
@@ -25678,14 +25827,14 @@ app60.all("*", (c) => {
25678
25827
  });
25679
25828
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
25680
25829
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
25681
- var httpServer = serve({ fetch: app60.fetch, port, hostname });
25830
+ var httpServer = serve({ fetch: app61.fetch, port, hostname });
25682
25831
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
25683
25832
  {
25684
- const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join35(__dirname, "..");
25833
+ const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join36(__dirname, "..");
25685
25834
  const reconcileScript = resolve33(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
25686
25835
  const RECONCILE_INTERVAL_MS = 12e4;
25687
25836
  const runReconcile = () => {
25688
- if (!existsSync34(reconcileScript)) return;
25837
+ if (!existsSync35(reconcileScript)) return;
25689
25838
  try {
25690
25839
  const child = spawn3(process.execPath, [reconcileScript], {
25691
25840
  env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
@@ -25704,12 +25853,12 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
25704
25853
  }
25705
25854
  startTimeEntryCensus(() => getSession());
25706
25855
  {
25707
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join35(__dirname, "..");
25856
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join36(__dirname, "..");
25708
25857
  const auditScript = resolve33(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
25709
25858
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
25710
25859
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
25711
25860
  const runConnectorAudit = () => {
25712
- if (!existsSync34(auditScript)) return;
25861
+ if (!existsSync35(auditScript)) return;
25713
25862
  try {
25714
25863
  const child = spawn3(process.execPath, [auditScript], {
25715
25864
  env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
@@ -25779,7 +25928,7 @@ for (const m of SUBAPP_MANIFEST) {
25779
25928
  }
25780
25929
  try {
25781
25930
  const registered = [];
25782
- for (const r of app60.routes ?? []) {
25931
+ for (const r of app61.routes ?? []) {
25783
25932
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
25784
25933
  if (AGENT_SLUG_PATTERN.test(r.path)) {
25785
25934
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -25819,7 +25968,7 @@ try {
25819
25968
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
25820
25969
  async function runAdminUserReconcileTick() {
25821
25970
  try {
25822
- if (!existsSync34(USERS_FILE)) {
25971
+ if (!existsSync35(USERS_FILE)) {
25823
25972
  console.error("[adminuser-self-heal] skip reason=no-users-file");
25824
25973
  return;
25825
25974
  }
@@ -25852,7 +26001,7 @@ var adminUserReconcileTimer = setInterval(() => {
25852
26001
  if (typeof adminUserReconcileTimer.unref === "function") adminUserReconcileTimer.unref();
25853
26002
  var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
25854
26003
  function countUsersRows() {
25855
- if (!existsSync34(USERS_FILE)) return 0;
26004
+ if (!existsSync35(USERS_FILE)) return 0;
25856
26005
  const raw = readFileSync35(USERS_FILE, "utf-8").trim();
25857
26006
  if (!raw) return 0;
25858
26007
  const users = JSON.parse(raw);
@@ -25909,7 +26058,7 @@ try {
25909
26058
  } catch (err) {
25910
26059
  console.error(`[graph-health] account-enumeration unavailable reason=${err instanceof Error ? err.message : String(err)}`);
25911
26060
  }
25912
- var configDirForWhatsApp = basename13(MAXY_DIR) || ".maxy";
26061
+ var configDirForWhatsApp = basename12(MAXY_DIR) || ".maxy";
25913
26062
  var bootAccount = resolveAccount();
25914
26063
  if (bootAccount) {
25915
26064
  migrateRemovedConfigKeys(bootAccount.accountDir);
@@ -25925,7 +26074,7 @@ var bootEntitlement = bootAccountConfig ? resolveEntitlement(
25925
26074
  }
25926
26075
  ) : null;
25927
26076
  autoDeliverPremiumPlugins();
25928
- reconcileEnabledPlugins(bootAccount?.accountDir, bootAccount?.config, bootAccount?.accountId);
26077
+ reconcileEnabledPluginsForAccounts(listValidAccounts());
25929
26078
  for (const acct of listValidAccounts()) {
25930
26079
  cleanupLeakedPremiumSubs(acct.accountDir, acct.config, acct.accountId);
25931
26080
  }
@@ -25973,7 +26122,7 @@ if (bootAccountConfig?.whatsapp) {
25973
26122
  }
25974
26123
  init({
25975
26124
  configDir: configDirForWhatsApp,
25976
- platformRoot: resolve33(process.env.MAXY_PLATFORM_ROOT ?? join35(__dirname, "..")),
26125
+ platformRoot: resolve33(process.env.MAXY_PLATFORM_ROOT ?? join36(__dirname, "..")),
25977
26126
  accountConfig: bootAccountConfig,
25978
26127
  onMessage: async (msg) => {
25979
26128
  if (msg.isOwnerMirror) {