@rubytech/create-sitedesk-code 0.1.508 → 0.1.510

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 (326) hide show
  1. package/dist/index.js +53 -0
  2. package/package.json +1 -1
  3. package/payload/platform/docs/superpowers/plans/2026-07-26-task-1902-account-owned-entry-declarations.md +555 -0
  4. package/payload/platform/docs/superpowers/plans/2026-07-26-task-1926-portal-push-concurrency-guard.md +482 -0
  5. package/payload/platform/docs/superpowers/plans/2026-07-26-task-2023-sidebar-sessions-async-reads.md +394 -0
  6. package/payload/platform/docs/superpowers/specs/2026-07-26-task-1902-account-owned-entry-declarations-design.md +232 -0
  7. package/payload/platform/docs/superpowers/specs/2026-07-26-task-1926-portal-push-concurrency-guard-design.md +200 -0
  8. package/payload/platform/docs/superpowers/specs/2026-07-26-task-2014-ui-suite-nondeterminism-design.md +169 -0
  9. package/payload/platform/plugins/admin/PLUGIN.md +1 -0
  10. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +12 -7
  11. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +12 -0
  12. package/payload/platform/plugins/business-assistant/PLUGIN.md +1 -0
  13. package/payload/platform/plugins/cloudflare/PLUGIN.md +1 -0
  14. package/payload/platform/plugins/cloudflare/bin/portal-index-push.mjs +68 -28
  15. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-index-push.test.ts +271 -29
  16. package/payload/platform/plugins/cloudflare/mcp/__tests__/schema-exposed-dirs.test.ts +21 -0
  17. package/payload/platform/plugins/cloudflare/skills/data-portal/schema.sql +5 -4
  18. package/payload/platform/plugins/docs/references/admin-ui.md +10 -5
  19. package/payload/platform/plugins/docs/references/troubleshooting.md +1 -1
  20. package/payload/platform/plugins/scheduling/PLUGIN.md +1 -0
  21. package/payload/platform/scripts/__tests__/account-schema-owned-dirs.test.sh +112 -4
  22. package/payload/platform/scripts/__tests__/check-brand-cache.test.sh +231 -0
  23. package/payload/platform/scripts/check-brand-cache.sh +138 -0
  24. package/payload/platform/scripts/lib/account-schema-owned-dirs.py +61 -32
  25. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts.map +1 -1
  26. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js +17 -30
  27. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js.map +1 -1
  28. package/payload/platform/services/claude-session-manager/dist/config.d.ts +50 -4
  29. package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
  30. package/payload/platform/services/claude-session-manager/dist/config.js +58 -15
  31. package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
  32. package/payload/server/maxy-edge.js +26 -11
  33. package/payload/server/public/activity.html +5 -5
  34. package/payload/server/public/agents.html +4 -4
  35. package/payload/server/public/assets/AdminLoginScreens-CWMpccrR.css.br +0 -0
  36. package/payload/server/public/assets/AdminLoginScreens-CWMpccrR.css.gz +0 -0
  37. package/payload/server/public/assets/AdminLoginScreens-bksN0XPe.js +1 -0
  38. package/payload/server/public/assets/AdminLoginScreens-bksN0XPe.js.br +0 -0
  39. package/payload/server/public/assets/AdminLoginScreens-bksN0XPe.js.gz +0 -0
  40. package/payload/server/public/assets/{AdminShell-HeELCCjJ.js → AdminShell-BMPEWNZk.js} +1 -1
  41. package/payload/server/public/assets/AdminShell-BMPEWNZk.js.br +0 -0
  42. package/payload/server/public/assets/AdminShell-BMPEWNZk.js.gz +0 -0
  43. package/payload/server/public/assets/_baseFor-Be3EKK3K.js.br +0 -0
  44. package/payload/server/public/assets/_baseFor-Be3EKK3K.js.gz +0 -0
  45. package/payload/server/public/assets/{activity-BEIDAxDA.js → activity-ByWYF5dC.js} +1 -1
  46. package/payload/server/public/assets/activity-ByWYF5dC.js.br +0 -0
  47. package/payload/server/public/assets/activity-ByWYF5dC.js.gz +0 -0
  48. package/payload/server/public/assets/admin-DGr1HuPg.js +1 -0
  49. package/payload/server/public/assets/admin-DGr1HuPg.js.br +0 -0
  50. package/payload/server/public/assets/admin-DGr1HuPg.js.gz +0 -0
  51. package/payload/server/public/assets/agents-C0rTfrYd.js +1 -0
  52. package/payload/server/public/assets/agents-C0rTfrYd.js.br +0 -0
  53. package/payload/server/public/assets/agents-C0rTfrYd.js.gz +0 -0
  54. package/payload/server/public/assets/arc-DaI5MLTq.js.br +0 -0
  55. package/payload/server/public/assets/arc-DaI5MLTq.js.gz +0 -0
  56. package/payload/server/public/assets/architecture-YZFGNWBL-DWZIX5aV.js.br +0 -0
  57. package/payload/server/public/assets/architectureDiagram-Q4EWVU46-CBGVUEN9.js.br +0 -0
  58. package/payload/server/public/assets/architectureDiagram-Q4EWVU46-CBGVUEN9.js.gz +0 -0
  59. package/payload/server/public/assets/array-X0JlPOfd.js.br +0 -0
  60. package/payload/server/public/assets/blockDiagram-DXYQGD6D-DS6dS4GZ.js.br +0 -0
  61. package/payload/server/public/assets/blockDiagram-DXYQGD6D-DS6dS4GZ.js.gz +0 -0
  62. package/payload/server/public/assets/{browser-GkVTGqlb.js → browser-4tTaem8N.js} +1 -1
  63. package/payload/server/public/assets/browser-4tTaem8N.js.br +0 -0
  64. package/payload/server/public/assets/browser-4tTaem8N.js.gz +0 -0
  65. package/payload/server/public/assets/c4Diagram-AHTNJAMY-hBSBUZPt.js.br +0 -0
  66. package/payload/server/public/assets/c4Diagram-AHTNJAMY-hBSBUZPt.js.gz +0 -0
  67. package/payload/server/public/assets/{calendar-CSqJeFEg.js → calendar-BEjnkKG1.js} +1 -1
  68. package/payload/server/public/assets/calendar-BEjnkKG1.js.br +0 -0
  69. package/payload/server/public/assets/calendar-BEjnkKG1.js.gz +0 -0
  70. package/payload/server/public/assets/channel-BEokjAeE.js.br +0 -0
  71. package/payload/server/public/assets/chat-DBgzjDIE.js +1 -0
  72. package/payload/server/public/assets/chat-DBgzjDIE.js.br +0 -0
  73. package/payload/server/public/assets/chat-DBgzjDIE.js.gz +0 -0
  74. package/payload/server/public/assets/chevron-left-DqYv3oFh.js +1 -0
  75. package/payload/server/public/assets/chevron-right-CQfPGsFb.js +1 -0
  76. package/payload/server/public/assets/chevron-right-CQfPGsFb.js.br +0 -0
  77. package/payload/server/public/assets/chunk-2KRD3SAO-B6koUoB7.js.br +0 -0
  78. package/payload/server/public/assets/chunk-2KRD3SAO-B6koUoB7.js.gz +0 -0
  79. package/payload/server/public/assets/chunk-336JU56O-BF6BRh8u.js.br +0 -0
  80. package/payload/server/public/assets/chunk-336JU56O-BF6BRh8u.js.gz +0 -0
  81. package/payload/server/public/assets/chunk-426QAEUC-pbQ4PWBU.js.br +0 -0
  82. package/payload/server/public/assets/chunk-426QAEUC-pbQ4PWBU.js.gz +0 -0
  83. package/payload/server/public/assets/chunk-4BX2VUAB-7sO95xR2.js.br +0 -0
  84. package/payload/server/public/assets/chunk-4BX2VUAB-7sO95xR2.js.gz +0 -0
  85. package/payload/server/public/assets/chunk-4TB4RGXK-GCTndJYx.js.br +0 -0
  86. package/payload/server/public/assets/chunk-4TB4RGXK-GCTndJYx.js.gz +0 -0
  87. package/payload/server/public/assets/chunk-55IACEB6-ggIJf_TC.js.br +0 -0
  88. package/payload/server/public/assets/chunk-55IACEB6-ggIJf_TC.js.gz +0 -0
  89. package/payload/server/public/assets/chunk-5FUZZQ4R-DeGmkimt.js.br +0 -0
  90. package/payload/server/public/assets/chunk-5FUZZQ4R-DeGmkimt.js.gz +0 -0
  91. package/payload/server/public/assets/chunk-5PVQY5BW-aFIQKk_U.js.br +0 -0
  92. package/payload/server/public/assets/chunk-5PVQY5BW-aFIQKk_U.js.gz +0 -0
  93. package/payload/server/public/assets/chunk-67CJDMHE-LS8rUbii.js.br +2 -0
  94. package/payload/server/public/assets/chunk-67CJDMHE-LS8rUbii.js.gz +0 -0
  95. package/payload/server/public/assets/chunk-7N4EOEYR-JKOVngS0.js.br +2 -0
  96. package/payload/server/public/assets/chunk-7N4EOEYR-JKOVngS0.js.gz +0 -0
  97. package/payload/server/public/assets/chunk-AA7GKIK3-CoXnTVK6.js.br +0 -0
  98. package/payload/server/public/assets/chunk-AA7GKIK3-CoXnTVK6.js.gz +0 -0
  99. package/payload/server/public/assets/chunk-BSJP7CBP-CcsqObFg.js.br +0 -0
  100. package/payload/server/public/assets/chunk-BSJP7CBP-CcsqObFg.js.gz +0 -0
  101. package/payload/server/public/assets/chunk-CIAEETIT-CpsybR7q.js.br +0 -0
  102. package/payload/server/public/assets/chunk-CIAEETIT-CpsybR7q.js.gz +0 -0
  103. package/payload/server/public/assets/chunk-CltuBf4Z.js.br +0 -0
  104. package/payload/server/public/assets/chunk-CltuBf4Z.js.gz +0 -0
  105. package/payload/server/public/assets/chunk-EDXVE4YY-BZ2I9PSq.js.br +0 -0
  106. package/payload/server/public/assets/chunk-EDXVE4YY-BZ2I9PSq.js.gz +0 -0
  107. package/payload/server/public/assets/chunk-ENJZ2VHE-DbTwt6OZ.js.br +0 -0
  108. package/payload/server/public/assets/chunk-ENJZ2VHE-DbTwt6OZ.js.gz +0 -0
  109. package/payload/server/public/assets/chunk-FMBD7UC4-D27VnSCa.js.br +0 -0
  110. package/payload/server/public/assets/chunk-FMBD7UC4-D27VnSCa.js.gz +0 -0
  111. package/payload/server/public/assets/chunk-FOC6F5B3-C0tU2UFl.js.br +0 -0
  112. package/payload/server/public/assets/chunk-FOC6F5B3-C0tU2UFl.js.gz +0 -0
  113. package/payload/server/public/assets/chunk-ICPOFSXX-UPPu2OIq.js.br +0 -0
  114. package/payload/server/public/assets/chunk-ICPOFSXX-UPPu2OIq.js.gz +0 -0
  115. package/payload/server/public/assets/chunk-K5T4RW27-DIKxqyYw.js.br +0 -0
  116. package/payload/server/public/assets/chunk-K5T4RW27-DIKxqyYw.js.gz +0 -0
  117. package/payload/server/public/assets/chunk-KGLVRYIC-CiL4YVLo.js.br +0 -0
  118. package/payload/server/public/assets/chunk-KGLVRYIC-CiL4YVLo.js.gz +0 -0
  119. package/payload/server/public/assets/chunk-LIHQZDEY-ejKezVlD.js.br +0 -0
  120. package/payload/server/public/assets/chunk-LIHQZDEY-ejKezVlD.js.gz +0 -0
  121. package/payload/server/public/assets/chunk-ORNJ4GCN-Cc0vqc-D.js.br +0 -0
  122. package/payload/server/public/assets/chunk-ORNJ4GCN-Cc0vqc-D.js.gz +0 -0
  123. package/payload/server/public/assets/chunk-OYMX7WX6-Drxn1qG0.js.br +0 -0
  124. package/payload/server/public/assets/chunk-OYMX7WX6-Drxn1qG0.js.gz +0 -0
  125. package/payload/server/public/assets/chunk-QZHKN3VN-Dhlh7Pkk.js.br +0 -0
  126. package/payload/server/public/assets/chunk-QZHKN3VN-Dhlh7Pkk.js.gz +0 -0
  127. package/payload/server/public/assets/chunk-U2HBQHQK-DnbQIkRP.js.br +0 -0
  128. package/payload/server/public/assets/chunk-U2HBQHQK-DnbQIkRP.js.gz +0 -0
  129. package/payload/server/public/assets/chunk-X2U36JSP-CauTSVWg.js.br +0 -0
  130. package/payload/server/public/assets/chunk-X2U36JSP-CauTSVWg.js.gz +0 -0
  131. package/payload/server/public/assets/chunk-XPW4576I-DZqqB9Zi.js.br +0 -0
  132. package/payload/server/public/assets/chunk-XPW4576I-DZqqB9Zi.js.gz +0 -0
  133. package/payload/server/public/assets/chunk-YZCP3GAM-BGHo4Li-.js.br +0 -0
  134. package/payload/server/public/assets/chunk-YZCP3GAM-BGHo4Li-.js.gz +0 -0
  135. package/payload/server/public/assets/chunk-ZZ45TVLE-DWGJKPd7.js.br +0 -0
  136. package/payload/server/public/assets/chunk-ZZ45TVLE-DWGJKPd7.js.gz +0 -0
  137. package/payload/server/public/assets/classDiagram-6PBFFD2Q-D2z_ZV1x.js.br +0 -0
  138. package/payload/server/public/assets/classDiagram-6PBFFD2Q-D2z_ZV1x.js.gz +0 -0
  139. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BJwJoNEK.js.br +0 -0
  140. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BJwJoNEK.js.gz +0 -0
  141. package/payload/server/public/assets/clock-Dn6FHB51.js +1 -0
  142. package/payload/server/public/assets/clock-Dn6FHB51.js.br +0 -0
  143. package/payload/server/public/assets/clock-Dn6FHB51.js.gz +0 -0
  144. package/payload/server/public/assets/clone-Bn7XXVhr.js.br +0 -0
  145. package/payload/server/public/assets/cose-bilkent-S5V4N54A-D-95BzXL.js.br +0 -0
  146. package/payload/server/public/assets/cose-bilkent-S5V4N54A-D-95BzXL.js.gz +0 -0
  147. package/payload/server/public/assets/cytoscape.esm-CI2IWMLB.js.br +0 -0
  148. package/payload/server/public/assets/cytoscape.esm-CI2IWMLB.js.gz +0 -0
  149. package/payload/server/public/assets/dagre-BZYNBHvT.js.br +0 -0
  150. package/payload/server/public/assets/dagre-BZYNBHvT.js.gz +0 -0
  151. package/payload/server/public/assets/dagre-KV5264BT-DyU4HQLQ.js.br +0 -0
  152. package/payload/server/public/assets/dagre-KV5264BT-DyU4HQLQ.js.gz +0 -0
  153. package/payload/server/public/assets/data-D_e6Vdfd.js +1 -0
  154. package/payload/server/public/assets/data-D_e6Vdfd.js.br +0 -0
  155. package/payload/server/public/assets/data-D_e6Vdfd.js.gz +0 -0
  156. package/payload/server/public/assets/defaultLocale-B6RGN4id.js.br +0 -0
  157. package/payload/server/public/assets/defaultLocale-B6RGN4id.js.gz +0 -0
  158. package/payload/server/public/assets/diagram-5BDNPKRD-CCttJ9XA.js.br +0 -0
  159. package/payload/server/public/assets/diagram-5BDNPKRD-CCttJ9XA.js.gz +0 -0
  160. package/payload/server/public/assets/diagram-G4DWMVQ6-DvkpgSLO.js.br +0 -0
  161. package/payload/server/public/assets/diagram-G4DWMVQ6-DvkpgSLO.js.gz +0 -0
  162. package/payload/server/public/assets/diagram-MMDJMWI5-DHmW5Y9k.js.br +0 -0
  163. package/payload/server/public/assets/diagram-MMDJMWI5-DHmW5Y9k.js.gz +0 -0
  164. package/payload/server/public/assets/diagram-TYMM5635-C6T4hwzO.js.br +0 -0
  165. package/payload/server/public/assets/diagram-TYMM5635-C6T4hwzO.js.gz +0 -0
  166. package/payload/server/public/assets/dist-QvbmK1IP.js.br +0 -0
  167. package/payload/server/public/assets/dist-QvbmK1IP.js.gz +0 -0
  168. package/payload/server/public/assets/erDiagram-SMLLAGMA-5v_o7s3T.js.br +0 -0
  169. package/payload/server/public/assets/erDiagram-SMLLAGMA-5v_o7s3T.js.gz +0 -0
  170. package/payload/server/public/assets/{file-text-DiscM2pP.js → file-text-DMKw3nIk.js} +1 -1
  171. package/payload/server/public/assets/file-text-DMKw3nIk.js.br +0 -0
  172. package/payload/server/public/assets/file-text-DMKw3nIk.js.gz +0 -0
  173. package/payload/server/public/assets/flatten-BtIc9jX7.js.br +0 -0
  174. package/payload/server/public/assets/flatten-BtIc9jX7.js.gz +0 -0
  175. package/payload/server/public/assets/flowDiagram-DWJPFMVM-3UhCDsjt.js.br +0 -0
  176. package/payload/server/public/assets/flowDiagram-DWJPFMVM-3UhCDsjt.js.gz +0 -0
  177. package/payload/server/public/assets/ganttDiagram-T4ZO3ILL-F2zgHIIQ.js.br +0 -0
  178. package/payload/server/public/assets/ganttDiagram-T4ZO3ILL-F2zgHIIQ.js.gz +0 -0
  179. package/payload/server/public/assets/gitGraph-7Q5UKJZL-C-FvNTHZ.js.br +0 -0
  180. package/payload/server/public/assets/gitGraphDiagram-UUTBAWPF-oQc1N3dT.js.br +0 -0
  181. package/payload/server/public/assets/gitGraphDiagram-UUTBAWPF-oQc1N3dT.js.gz +0 -0
  182. package/payload/server/public/assets/{graph-CRP5DM8C.js → graph-C3vW8lvw.js} +1 -1
  183. package/payload/server/public/assets/graph-C3vW8lvw.js.br +0 -0
  184. package/payload/server/public/assets/graph-C3vW8lvw.js.gz +0 -0
  185. package/payload/server/public/assets/{graph-labels-Du-6KoBE.js → graph-labels-BZgd0L6n.js} +1 -1
  186. package/payload/server/public/assets/graph-labels-BZgd0L6n.js.br +0 -0
  187. package/payload/server/public/assets/graph-labels-BZgd0L6n.js.gz +0 -0
  188. package/payload/server/public/assets/graphlib-DY4-AT2Q.js.br +0 -0
  189. package/payload/server/public/assets/graphlib-DY4-AT2Q.js.gz +0 -0
  190. package/payload/server/public/assets/info-OMHHGYJF-BjLPgHAC.js.br +0 -0
  191. package/payload/server/public/assets/infoDiagram-42DDH7IO-CXNKLTui.js.br +0 -0
  192. package/payload/server/public/assets/infoDiagram-42DDH7IO-CXNKLTui.js.gz +0 -0
  193. package/payload/server/public/assets/init-BmUWJJHz.js.br +0 -0
  194. package/payload/server/public/assets/init-BmUWJJHz.js.gz +0 -0
  195. package/payload/server/public/assets/isEmpty-Bu4fZ8Kf.js.br +0 -0
  196. package/payload/server/public/assets/isEmpty-Bu4fZ8Kf.js.gz +0 -0
  197. package/payload/server/public/assets/ishikawaDiagram-UXIWVN3A-wJhSOkuw.js.br +0 -0
  198. package/payload/server/public/assets/ishikawaDiagram-UXIWVN3A-wJhSOkuw.js.gz +0 -0
  199. package/payload/server/public/assets/journeyDiagram-VCZTEJTY-DgadC6Pz.js.br +0 -0
  200. package/payload/server/public/assets/journeyDiagram-VCZTEJTY-DgadC6Pz.js.gz +0 -0
  201. package/payload/server/public/assets/kanban-definition-6JOO6SKY-Bs4nQqXI.js.br +0 -0
  202. package/payload/server/public/assets/kanban-definition-6JOO6SKY-Bs4nQqXI.js.gz +0 -0
  203. package/payload/server/public/assets/katex-BjZuzSQn.js.br +0 -0
  204. package/payload/server/public/assets/katex-BjZuzSQn.js.gz +0 -0
  205. package/payload/server/public/assets/line-Bnmxy1hO.js.br +0 -0
  206. package/payload/server/public/assets/line-Bnmxy1hO.js.gz +0 -0
  207. package/payload/server/public/assets/linear-RvwZxFzh.js.br +0 -0
  208. package/payload/server/public/assets/linear-RvwZxFzh.js.gz +0 -0
  209. package/payload/server/public/assets/{maximize-2-D-H_uIV-.js → maximize-2-la3IBA3M.js} +1 -1
  210. package/payload/server/public/assets/maximize-2-la3IBA3M.js.br +0 -0
  211. package/payload/server/public/assets/maximize-2-la3IBA3M.js.gz +0 -0
  212. package/payload/server/public/assets/mermaid-parser.core-DeNV8RtA.js.br +0 -0
  213. package/payload/server/public/assets/mermaid-parser.core-DeNV8RtA.js.gz +0 -0
  214. package/payload/server/public/assets/mermaid.core-BU9IiSCP.js.br +0 -0
  215. package/payload/server/public/assets/mermaid.core-BU9IiSCP.js.gz +0 -0
  216. package/payload/server/public/assets/mindmap-definition-QFDTVHPH-D1PMUxxm.js.br +0 -0
  217. package/payload/server/public/assets/mindmap-definition-QFDTVHPH-D1PMUxxm.js.gz +0 -0
  218. package/payload/server/public/assets/{operator-D5rA76YY.js → operator-D9NgVL9_.js} +1 -1
  219. package/payload/server/public/assets/operator-D9NgVL9_.js.br +0 -0
  220. package/payload/server/public/assets/operator-D9NgVL9_.js.gz +0 -0
  221. package/payload/server/public/assets/ordinal-C2TEWKNu.js.br +0 -0
  222. package/payload/server/public/assets/ordinal-C2TEWKNu.js.gz +0 -0
  223. package/payload/server/public/assets/packet-4T2RLAQJ-BBAZASfb.js.br +0 -0
  224. package/payload/server/public/assets/{page-CHK1415C.js → page-BWFHRIAH.js} +1 -1
  225. package/payload/server/public/assets/page-BWFHRIAH.js.br +0 -0
  226. package/payload/server/public/assets/page-BWFHRIAH.js.gz +0 -0
  227. package/payload/server/public/assets/{page-DZE3H_n4.js → page-DC11gesX.js} +1 -1
  228. package/payload/server/public/assets/page-DC11gesX.js.br +0 -0
  229. package/payload/server/public/assets/page-DC11gesX.js.gz +0 -0
  230. package/payload/server/public/assets/path-CoPyR7c2.js.br +0 -0
  231. package/payload/server/public/assets/path-CoPyR7c2.js.gz +0 -0
  232. package/payload/server/public/assets/pdf-render-C257cidb.js.br +0 -0
  233. package/payload/server/public/assets/pdf-render-C257cidb.js.gz +0 -0
  234. package/payload/server/public/assets/pdf.worker.min-yatZIOMy.mjs.br +0 -0
  235. package/payload/server/public/assets/pdf.worker.min-yatZIOMy.mjs.gz +0 -0
  236. package/payload/server/public/assets/pie-ZZUOXDRM-CCJUnMeG.js.br +0 -0
  237. package/payload/server/public/assets/pieDiagram-DEJITSTG-BzdNzoKA.js.br +0 -0
  238. package/payload/server/public/assets/pieDiagram-DEJITSTG-BzdNzoKA.js.gz +0 -0
  239. package/payload/server/public/assets/preload-helper-BQrMkyGX.js.br +0 -0
  240. package/payload/server/public/assets/preload-helper-BQrMkyGX.js.gz +0 -0
  241. package/payload/server/public/assets/{public-DFHXVkdD.js → public-DQbbLHQN.js} +1 -1
  242. package/payload/server/public/assets/public-DQbbLHQN.js.br +0 -0
  243. package/payload/server/public/assets/public-DQbbLHQN.js.gz +0 -0
  244. package/payload/server/public/assets/quadrantDiagram-34T5L4WZ-oFr1MJRO.js.br +0 -0
  245. package/payload/server/public/assets/quadrantDiagram-34T5L4WZ-oFr1MJRO.js.gz +0 -0
  246. package/payload/server/public/assets/radar-PYXPWWZC-BsRU8Aep.js.br +0 -0
  247. package/payload/server/public/assets/reduce-BGpN5lgn.js.br +0 -0
  248. package/payload/server/public/assets/reduce-BGpN5lgn.js.gz +0 -0
  249. package/payload/server/public/assets/requirementDiagram-MS252O5E-C9QBQxDh.js.br +0 -0
  250. package/payload/server/public/assets/requirementDiagram-MS252O5E-C9QBQxDh.js.gz +0 -0
  251. package/payload/server/public/assets/{rotate-ccw-CesEJsuO.js → rotate-ccw-OQD5si8N.js} +1 -1
  252. package/payload/server/public/assets/rotate-ccw-OQD5si8N.js.br +0 -0
  253. package/payload/server/public/assets/rotate-ccw-OQD5si8N.js.gz +0 -0
  254. package/payload/server/public/assets/rough.esm-jSt7UMyi.js.br +0 -0
  255. package/payload/server/public/assets/rough.esm-jSt7UMyi.js.gz +0 -0
  256. package/payload/server/public/assets/{routines-DYMYY_r8.js → routines-asrBGZUR.js} +1 -1
  257. package/payload/server/public/assets/routines-asrBGZUR.js.br +0 -0
  258. package/payload/server/public/assets/routines-asrBGZUR.js.gz +0 -0
  259. package/payload/server/public/assets/sankeyDiagram-XADWPNL6-c_y3bvVv.js.br +0 -0
  260. package/payload/server/public/assets/sankeyDiagram-XADWPNL6-c_y3bvVv.js.gz +0 -0
  261. package/payload/server/public/assets/sequenceDiagram-FGHM5R23-YwlCBPHE.js.br +0 -0
  262. package/payload/server/public/assets/sequenceDiagram-FGHM5R23-YwlCBPHE.js.gz +0 -0
  263. package/payload/server/public/assets/{skills-67jtJ16D.js → skills-D4ECwoxa.js} +1 -1
  264. package/payload/server/public/assets/skills-D4ECwoxa.js.br +0 -0
  265. package/payload/server/public/assets/skills-D4ECwoxa.js.gz +0 -0
  266. package/payload/server/public/assets/src-C2WwTWSY.js.br +0 -0
  267. package/payload/server/public/assets/src-C2WwTWSY.js.gz +0 -0
  268. package/payload/server/public/assets/stateDiagram-FHFEXIEX-BFE3e-FM.js.br +0 -0
  269. package/payload/server/public/assets/stateDiagram-FHFEXIEX-BFE3e-FM.js.gz +0 -0
  270. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CpjB4ykI.js.br +4 -0
  271. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CpjB4ykI.js.gz +0 -0
  272. package/payload/server/public/assets/{tasks-D2C2a-uk.js → tasks-U3QdbUsO.js} +1 -1
  273. package/payload/server/public/assets/tasks-U3QdbUsO.js.br +0 -0
  274. package/payload/server/public/assets/tasks-U3QdbUsO.js.gz +0 -0
  275. package/payload/server/public/assets/{time-entry-format-BixTGQAd.js → time-entry-format-BgdTKgYr.js} +1 -1
  276. package/payload/server/public/assets/time-entry-format-BgdTKgYr.js.br +0 -0
  277. package/payload/server/public/assets/time-entry-format-BgdTKgYr.js.gz +0 -0
  278. package/payload/server/public/assets/timeline-definition-GMOUNBTQ-azqhmRwZ.js.br +0 -0
  279. package/payload/server/public/assets/timeline-definition-GMOUNBTQ-azqhmRwZ.js.gz +0 -0
  280. package/payload/server/public/assets/treeView-SZITEDCU-BDzhKA6v.js.br +0 -0
  281. package/payload/server/public/assets/treemap-W4RFUUIX-epHpdeWa.js.br +0 -0
  282. package/payload/server/public/assets/{triangle-alert-Co9RWb9q.js → triangle-alert-Ck_3VhT9.js} +1 -1
  283. package/payload/server/public/assets/triangle-alert-Ck_3VhT9.js.br +0 -0
  284. package/payload/server/public/assets/triangle-alert-Ck_3VhT9.js.gz +0 -0
  285. package/payload/server/public/assets/{useCopyFeedback-7zwf9_w4.js → useCopyFeedback-BdUwyNpa.js} +1 -1
  286. package/payload/server/public/assets/useCopyFeedback-BdUwyNpa.js.br +0 -0
  287. package/payload/server/public/assets/useCopyFeedback-BdUwyNpa.js.gz +0 -0
  288. package/payload/server/public/assets/useSubAccountSwitcher-CJKjEPNN.js.br +0 -0
  289. package/payload/server/public/assets/useSubAccountSwitcher-CJKjEPNN.js.gz +0 -0
  290. package/payload/server/public/assets/{useSubAccountSwitcher-DE4v5_Fz.css → useSubAccountSwitcher-DOWQXDT8.css} +1 -1
  291. package/payload/server/public/assets/useSubAccountSwitcher-DOWQXDT8.css.br +0 -0
  292. package/payload/server/public/assets/useSubAccountSwitcher-DOWQXDT8.css.gz +0 -0
  293. package/payload/server/public/assets/{useVoiceRecorder-CZDDiwMD.js → useVoiceRecorder-ChnBrzbZ.js} +1 -1
  294. package/payload/server/public/assets/useVoiceRecorder-ChnBrzbZ.js.br +0 -0
  295. package/payload/server/public/assets/useVoiceRecorder-ChnBrzbZ.js.gz +0 -0
  296. package/payload/server/public/assets/vennDiagram-DHZGUBPP-Da2RfFs8.js.br +0 -0
  297. package/payload/server/public/assets/vennDiagram-DHZGUBPP-Da2RfFs8.js.gz +0 -0
  298. package/payload/server/public/assets/wardley-RL74JXVD-DNSZCrxV.js.br +0 -0
  299. package/payload/server/public/assets/wardleyDiagram-NUSXRM2D-HdrdBYES.js.br +0 -0
  300. package/payload/server/public/assets/wardleyDiagram-NUSXRM2D-HdrdBYES.js.gz +0 -0
  301. package/payload/server/public/assets/{wrench-CjQqdj4P.js → wrench-Cpee3C3J.js} +1 -1
  302. package/payload/server/public/assets/wrench-Cpee3C3J.js.br +2 -0
  303. package/payload/server/public/assets/wrench-Cpee3C3J.js.gz +0 -0
  304. package/payload/server/public/assets/xychartDiagram-5P7HB3ND-DMk6rTcQ.js.br +0 -0
  305. package/payload/server/public/assets/xychartDiagram-5P7HB3ND-DMk6rTcQ.js.gz +0 -0
  306. package/payload/server/public/browser.html +4 -4
  307. package/payload/server/public/calendar.html +7 -7
  308. package/payload/server/public/chat.html +13 -13
  309. package/payload/server/public/data.html +11 -11
  310. package/payload/server/public/graph.html +9 -9
  311. package/payload/server/public/index.html +14 -14
  312. package/payload/server/public/operator.html +14 -14
  313. package/payload/server/public/public.html +13 -13
  314. package/payload/server/public/routines.html +6 -6
  315. package/payload/server/public/skills.html +5 -5
  316. package/payload/server/public/tasks.html +6 -6
  317. package/payload/server/server.js +817 -715
  318. package/payload/server/public/assets/AdminLoginScreens-DKeCt1uf.js +0 -1
  319. package/payload/server/public/assets/admin-C0-WU1sf.js +0 -1
  320. package/payload/server/public/assets/agents-DjUvMFTj.js +0 -1
  321. package/payload/server/public/assets/chat-C0Ps84U5.js +0 -1
  322. package/payload/server/public/assets/chevron-left-DQ2uNlu9.js +0 -1
  323. package/payload/server/public/assets/chevron-right-C4QCiRGD.js +0 -1
  324. package/payload/server/public/assets/clock-BEeQ7JxX.js +0 -1
  325. package/payload/server/public/assets/data-CGuNfym7.js +0 -1
  326. /package/payload/server/public/assets/{useSubAccountSwitcher-Bg72hdQ8.js → useSubAccountSwitcher-CJKjEPNN.js} +0 -0
@@ -1601,233 +1601,11 @@ var require_dist5 = __commonJS({
1601
1601
  }
1602
1602
  });
1603
1603
 
1604
- // node_modules/hono/dist/utils/mime.js
1605
- var getMimeType = (filename, mimes = baseMimes) => {
1606
- const regexp = /\.([a-zA-Z0-9]+?)$/;
1607
- const match = filename.match(regexp);
1608
- if (!match) {
1609
- return;
1610
- }
1611
- let mimeType = mimes[match[1].toLowerCase()];
1612
- if (mimeType && mimeType.startsWith("text")) {
1613
- mimeType += "; charset=utf-8";
1614
- }
1615
- return mimeType;
1616
- };
1617
- var _baseMimes = {
1618
- aac: "audio/aac",
1619
- avi: "video/x-msvideo",
1620
- avif: "image/avif",
1621
- av1: "video/av1",
1622
- bin: "application/octet-stream",
1623
- bmp: "image/bmp",
1624
- css: "text/css",
1625
- csv: "text/csv",
1626
- eot: "application/vnd.ms-fontobject",
1627
- epub: "application/epub+zip",
1628
- gif: "image/gif",
1629
- gz: "application/gzip",
1630
- htm: "text/html",
1631
- html: "text/html",
1632
- ico: "image/x-icon",
1633
- ics: "text/calendar",
1634
- jpeg: "image/jpeg",
1635
- jpg: "image/jpeg",
1636
- js: "text/javascript",
1637
- json: "application/json",
1638
- jsonld: "application/ld+json",
1639
- map: "application/json",
1640
- mid: "audio/x-midi",
1641
- midi: "audio/x-midi",
1642
- mjs: "text/javascript",
1643
- mp3: "audio/mpeg",
1644
- mp4: "video/mp4",
1645
- mpeg: "video/mpeg",
1646
- oga: "audio/ogg",
1647
- ogv: "video/ogg",
1648
- ogx: "application/ogg",
1649
- opus: "audio/opus",
1650
- otf: "font/otf",
1651
- pdf: "application/pdf",
1652
- png: "image/png",
1653
- rtf: "application/rtf",
1654
- svg: "image/svg+xml",
1655
- tif: "image/tiff",
1656
- tiff: "image/tiff",
1657
- ts: "video/mp2t",
1658
- ttf: "font/ttf",
1659
- txt: "text/plain",
1660
- wasm: "application/wasm",
1661
- webm: "video/webm",
1662
- weba: "audio/webm",
1663
- webmanifest: "application/manifest+json",
1664
- webp: "image/webp",
1665
- woff: "font/woff",
1666
- woff2: "font/woff2",
1667
- xhtml: "application/xhtml+xml",
1668
- xml: "application/xml",
1669
- zip: "application/zip",
1670
- "3gp": "video/3gpp",
1671
- "3g2": "video/3gpp2",
1672
- gltf: "model/gltf+json",
1673
- glb: "model/gltf-binary"
1674
- };
1675
- var baseMimes = _baseMimes;
1676
-
1677
- // node_modules/@hono/node-server/dist/serve-static.mjs
1678
- import { createReadStream, statSync, existsSync } from "fs";
1679
- import { join } from "path";
1680
- import { versions } from "process";
1681
- import { Readable } from "stream";
1682
- var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
1683
- var ENCODINGS = {
1684
- br: ".br",
1685
- zstd: ".zst",
1686
- gzip: ".gz"
1687
- };
1688
- var ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
1689
- var pr54206Applied = () => {
1690
- const [major, minor] = versions.node.split(".").map((component) => parseInt(component));
1691
- return major >= 23 || major === 22 && minor >= 7 || major === 20 && minor >= 18;
1692
- };
1693
- var useReadableToWeb = pr54206Applied();
1694
- var createStreamBody = (stream2) => {
1695
- if (useReadableToWeb) {
1696
- return Readable.toWeb(stream2);
1697
- }
1698
- const body = new ReadableStream({
1699
- start(controller) {
1700
- stream2.on("data", (chunk) => {
1701
- controller.enqueue(chunk);
1702
- });
1703
- stream2.on("error", (err) => {
1704
- controller.error(err);
1705
- });
1706
- stream2.on("end", () => {
1707
- controller.close();
1708
- });
1709
- },
1710
- cancel() {
1711
- stream2.destroy();
1712
- }
1713
- });
1714
- return body;
1715
- };
1716
- var getStats = (path3) => {
1717
- let stats;
1718
- try {
1719
- stats = statSync(path3);
1720
- } catch {
1721
- }
1722
- return stats;
1723
- };
1724
- var tryDecode = (str, decoder) => {
1725
- try {
1726
- return decoder(str);
1727
- } catch {
1728
- return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
1729
- try {
1730
- return decoder(match);
1731
- } catch {
1732
- return match;
1733
- }
1734
- });
1735
- }
1736
- };
1737
- var tryDecodeURI = (str) => tryDecode(str, decodeURI);
1738
- var serveStatic = (options = { root: "" }) => {
1739
- const root = options.root || "";
1740
- const optionPath = options.path;
1741
- if (root !== "" && !existsSync(root)) {
1742
- console.error(`serveStatic: root path '${root}' is not found, are you sure it's correct?`);
1743
- }
1744
- return async (c, next) => {
1745
- if (c.finalized) {
1746
- return next();
1747
- }
1748
- let filename;
1749
- if (optionPath) {
1750
- filename = optionPath;
1751
- } else {
1752
- try {
1753
- filename = tryDecodeURI(c.req.path);
1754
- if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
1755
- throw new Error();
1756
- }
1757
- } catch {
1758
- await options.onNotFound?.(c.req.path, c);
1759
- return next();
1760
- }
1761
- }
1762
- let path3 = join(
1763
- root,
1764
- !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename
1765
- );
1766
- let stats = getStats(path3);
1767
- if (stats && stats.isDirectory()) {
1768
- const indexFile2 = options.index ?? "index.html";
1769
- path3 = join(path3, indexFile2);
1770
- stats = getStats(path3);
1771
- }
1772
- if (!stats) {
1773
- await options.onNotFound?.(path3, c);
1774
- return next();
1775
- }
1776
- const mimeType = getMimeType(path3);
1777
- c.header("Content-Type", mimeType || "application/octet-stream");
1778
- if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
1779
- const acceptEncodingSet = new Set(
1780
- c.req.header("Accept-Encoding")?.split(",").map((encoding) => encoding.trim())
1781
- );
1782
- for (const encoding of ENCODINGS_ORDERED_KEYS) {
1783
- if (!acceptEncodingSet.has(encoding)) {
1784
- continue;
1785
- }
1786
- const precompressedStats = getStats(path3 + ENCODINGS[encoding]);
1787
- if (precompressedStats) {
1788
- c.header("Content-Encoding", encoding);
1789
- c.header("Vary", "Accept-Encoding", { append: true });
1790
- stats = precompressedStats;
1791
- path3 = path3 + ENCODINGS[encoding];
1792
- break;
1793
- }
1794
- }
1795
- }
1796
- let result;
1797
- const size = stats.size;
1798
- const range = c.req.header("range") || "";
1799
- if (c.req.method == "HEAD" || c.req.method == "OPTIONS") {
1800
- c.header("Content-Length", size.toString());
1801
- c.status(200);
1802
- result = c.body(null);
1803
- } else if (!range) {
1804
- c.header("Content-Length", size.toString());
1805
- result = c.body(createStreamBody(createReadStream(path3)), 200);
1806
- } else {
1807
- c.header("Accept-Ranges", "bytes");
1808
- c.header("Date", stats.birthtime.toUTCString());
1809
- const parts = range.replace(/bytes=/, "").split("-", 2);
1810
- const start = parseInt(parts[0], 10) || 0;
1811
- let end = parseInt(parts[1], 10) || size - 1;
1812
- if (size < end - start + 1) {
1813
- end = size - 1;
1814
- }
1815
- const chunksize = end - start + 1;
1816
- const stream2 = createReadStream(path3, { start, end });
1817
- c.header("Content-Length", chunksize.toString());
1818
- c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`);
1819
- result = c.body(createStreamBody(stream2), 206);
1820
- }
1821
- await options.onFound?.(path3, c);
1822
- return result;
1823
- };
1824
- };
1825
-
1826
1604
  // server/index.ts
1827
1605
  import { readFileSync as readFileSync48, existsSync as existsSync47, watchFile, readdirSync as readdirSync29, statSync as statSync21 } from "fs";
1828
1606
  import { spawn as spawn3 } from "child_process";
1829
1607
  import { createHash as createHash8 } from "crypto";
1830
- import { resolve as resolve45, join as join48, basename as basename14 } from "path";
1608
+ import { resolve as resolve45, join as join49, basename as basename14 } from "path";
1831
1609
  import { homedir as homedir4 } from "os";
1832
1610
 
1833
1611
  // server/lib/route-cache-watchers.ts
@@ -1950,21 +1728,21 @@ function onInvalidate(fn) {
1950
1728
  }
1951
1729
 
1952
1730
  // app/lib/whatsapp/message-store.ts
1953
- import { existsSync as existsSync2, mkdirSync, readFileSync, appendFileSync, readdirSync, statSync as statSync2 } from "fs";
1954
- import { dirname, join as join2 } from "path";
1731
+ import { existsSync, mkdirSync, readFileSync, appendFileSync, readdirSync, statSync } from "fs";
1732
+ import { dirname, join } from "path";
1955
1733
  function isReactionRecord(r) {
1956
1734
  return r.kind === "reaction";
1957
1735
  }
1958
- var STORE_ROOT = () => join2(process.env.MAXY_DIR_OVERRIDE ?? MAXY_DIR, "data", "whatsapp-messages");
1736
+ var STORE_ROOT = () => join(process.env.MAXY_DIR_OVERRIDE ?? MAXY_DIR, "data", "whatsapp-messages");
1959
1737
  function conversationFile(platformAccountId, remoteJid) {
1960
- return join2(STORE_ROOT(), platformAccountId, `${remoteJid}.jsonl`);
1738
+ return join(STORE_ROOT(), platformAccountId, `${remoteJid}.jsonl`);
1961
1739
  }
1962
1740
  function listStoredAccountIds() {
1963
1741
  const root = STORE_ROOT();
1964
- if (!existsSync2(root)) return [];
1742
+ if (!existsSync(root)) return [];
1965
1743
  return readdirSync(root).filter((name) => {
1966
1744
  try {
1967
- return statSync2(join2(root, name)).isDirectory();
1745
+ return statSync(join(root, name)).isDirectory();
1968
1746
  } catch {
1969
1747
  return false;
1970
1748
  }
@@ -2000,7 +1778,7 @@ function appendMessage(platformAccountId, record, altDedupeRemoteJids = []) {
2000
1778
  try {
2001
1779
  const filesToCheck = [file, ...altDedupeRemoteJids.filter((jid) => jid && jid !== record.remoteJid).map((jid) => conversationFile(platformAccountId, jid))];
2002
1780
  for (const candidate of new Set(filesToCheck)) {
2003
- if (!existsSync2(candidate)) continue;
1781
+ if (!existsSync(candidate)) continue;
2004
1782
  const existing = parseLines(readFileSync(candidate, "utf8"));
2005
1783
  if (existing.some((r) => r.messageId === record.messageId)) {
2006
1784
  return { created: false };
@@ -2023,7 +1801,7 @@ function appendMessage(platformAccountId, record, altDedupeRemoteJids = []) {
2023
1801
  function readConversation(platformAccountId, remoteJid) {
2024
1802
  const file = conversationFile(platformAccountId, remoteJid);
2025
1803
  try {
2026
- if (!existsSync2(file)) return [];
1804
+ if (!existsSync(file)) return [];
2027
1805
  return parseLines(readFileSync(file, "utf8")).sort(byDateSentAsc);
2028
1806
  } catch (err) {
2029
1807
  const reason = err instanceof Error ? err.message : String(err);
@@ -2048,7 +1826,7 @@ function appendReaction(platformAccountId, record) {
2048
1826
  function readReactions(platformAccountId, remoteJid) {
2049
1827
  const file = conversationFile(platformAccountId, remoteJid);
2050
1828
  try {
2051
- if (!existsSync2(file)) return [];
1829
+ if (!existsSync(file)) return [];
2052
1830
  const out = [];
2053
1831
  for (const line of readFileSync(file, "utf8").split("\n")) {
2054
1832
  if (!line.trim()) continue;
@@ -2094,23 +1872,23 @@ function summariseRecords(records) {
2094
1872
  };
2095
1873
  }
2096
1874
  function readConversationSummaries(platformAccountId) {
2097
- const dir = join2(STORE_ROOT(), platformAccountId);
1875
+ const dir = join(STORE_ROOT(), platformAccountId);
2098
1876
  const out = /* @__PURE__ */ new Map();
2099
1877
  const seen = /* @__PURE__ */ new Set();
2100
1878
  let fullReads = 0;
2101
1879
  let cacheHits = 0;
2102
1880
  let bytesRead = 0;
2103
1881
  try {
2104
- if (!existsSync2(dir)) return out;
1882
+ if (!existsSync(dir)) return out;
2105
1883
  for (const entry of readdirSync(dir)) {
2106
1884
  if (!entry.endsWith(".jsonl")) continue;
2107
1885
  const remoteJid = entry.slice(0, -".jsonl".length);
2108
- const file = join2(dir, entry);
1886
+ const file = join(dir, entry);
2109
1887
  seen.add(file);
2110
1888
  let size;
2111
1889
  let mtimeMs;
2112
1890
  try {
2113
- const st = statSync2(file);
1891
+ const st = statSync(file);
2114
1892
  size = st.size;
2115
1893
  mtimeMs = st.mtimeMs;
2116
1894
  } catch {
@@ -2150,10 +1928,10 @@ function readConversationSummaries(platformAccountId) {
2150
1928
  return out;
2151
1929
  }
2152
1930
  function readAllConversations(platformAccountId) {
2153
- const dir = join2(STORE_ROOT(), platformAccountId);
1931
+ const dir = join(STORE_ROOT(), platformAccountId);
2154
1932
  const out = /* @__PURE__ */ new Map();
2155
1933
  try {
2156
- if (!existsSync2(dir)) return out;
1934
+ if (!existsSync(dir)) return out;
2157
1935
  for (const entry of readdirSync(dir)) {
2158
1936
  if (!entry.endsWith(".jsonl")) continue;
2159
1937
  const remoteJid = entry.slice(0, -".jsonl".length);
@@ -2281,110 +2059,417 @@ function attachRouteCacheWatchers() {
2281
2059
  watchDirInto(resolve2(PLATFORM_ROOT, "templates", "specialists", "agents"), "sidebar-artefacts", null);
2282
2060
  let houseId = null;
2283
2061
  try {
2284
- houseId = resolveHouseOrSoleAccountId(ACCOUNTS_DIR);
2062
+ houseId = resolveHouseOrSoleAccountId(ACCOUNTS_DIR);
2063
+ } catch {
2064
+ houseId = null;
2065
+ }
2066
+ if (houseId) {
2067
+ watchDirInto(STORE_ROOT(), "conversations-all", houseId);
2068
+ } else {
2069
+ console.error("[admin-events] op=watch-failed resource=conversations-all reason=house-account-unresolved");
2070
+ }
2071
+ }
2072
+
2073
+ // server/lib/manager-events-subscriber.ts
2074
+ var TAG = "[webchat-pointer]";
2075
+ var TURN_EVENTS = /* @__PURE__ */ new Set(["row-updated", "row-created"]);
2076
+ var MAX_BACKOFF_MS = 3e4;
2077
+ var STABLE_CONNECTION_MS = 3e4;
2078
+ var lastStatusBySession = /* @__PURE__ */ new Map();
2079
+ function handleManagerFrame(raw) {
2080
+ const lines = raw.split("\n");
2081
+ const eventLine = lines.find((l) => l.startsWith("event: "));
2082
+ const dataLine = lines.find((l) => l.startsWith("data: "));
2083
+ if (!eventLine || !dataLine) return null;
2084
+ if (!TURN_EVENTS.has(eventLine.slice("event: ".length).trim())) return null;
2085
+ let body;
2086
+ try {
2087
+ body = JSON.parse(dataLine.slice("data: ".length));
2088
+ } catch {
2089
+ console.error(`${TAG} op=skip reason=unparseable-frame`);
2090
+ return null;
2091
+ }
2092
+ const sessionId = String(body.sessionId ?? "unknown").slice(0, 8);
2093
+ const accountId = typeof body.accountId === "string" && body.accountId ? body.accountId : null;
2094
+ if (!accountId) {
2095
+ console.error(`${TAG} op=skip reason=no-account sessionId=${sessionId}`);
2096
+ return null;
2097
+ }
2098
+ const status = String(body.status ?? "unknown");
2099
+ const fullSessionId = String(body.sessionId ?? "");
2100
+ if (fullSessionId && lastStatusBySession.get(fullSessionId) === status) {
2101
+ return null;
2102
+ }
2103
+ if (fullSessionId) lastStatusBySession.set(fullSessionId, status);
2104
+ console.log(
2105
+ `${TAG} op=event sessionId=${sessionId} accountId=${accountId.slice(0, 8)} activity=${status}`
2106
+ );
2107
+ notify("webchat-pointer", accountId);
2108
+ return { resource: "webchat-pointer", accountId };
2109
+ }
2110
+ var connections = 0;
2111
+ var started = false;
2112
+ var abort = null;
2113
+ function startManagerEventsSubscriber() {
2114
+ if (started) return;
2115
+ started = true;
2116
+ abort = new AbortController();
2117
+ void connectLoop(abort.signal);
2118
+ }
2119
+ async function connectLoop(signal) {
2120
+ let backoffMs = 1e3;
2121
+ for (; ; ) {
2122
+ if (signal.aborted) return;
2123
+ let port2;
2124
+ try {
2125
+ port2 = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "webchat-pointer" });
2126
+ } catch {
2127
+ console.error(`${TAG} op=drop reason=manager-port-unset`);
2128
+ return;
2129
+ }
2130
+ const connectedAt = Date.now();
2131
+ try {
2132
+ const res = await fetch(`http://127.0.0.1:${port2}/events`, { signal });
2133
+ if (!res.ok || !res.body) throw new Error(`status ${res.status}`);
2134
+ connections += 1;
2135
+ console.log(`${TAG} op=subscribe upstream-count=${connections}`);
2136
+ const reader = res.body.getReader();
2137
+ const decoder = new TextDecoder();
2138
+ let buffer = "";
2139
+ for (; ; ) {
2140
+ const { done, value } = await reader.read();
2141
+ if (done) break;
2142
+ buffer += decoder.decode(value, { stream: true });
2143
+ let cut = buffer.indexOf("\n\n");
2144
+ while (cut !== -1) {
2145
+ handleManagerFrame(buffer.slice(0, cut));
2146
+ buffer = buffer.slice(cut + 2);
2147
+ cut = buffer.indexOf("\n\n");
2148
+ }
2149
+ }
2150
+ connections -= 1;
2151
+ } catch (err) {
2152
+ if (connections > 0) connections -= 1;
2153
+ if (signal.aborted) return;
2154
+ console.error(`${TAG} op=drop reason=${err instanceof Error ? err.message : String(err)}`);
2155
+ }
2156
+ if (signal.aborted) return;
2157
+ if (Date.now() - connectedAt >= STABLE_CONNECTION_MS) backoffMs = 1e3;
2158
+ console.log(`${TAG} op=reconnect inMs=${backoffMs} upstream-count=${connections}`);
2159
+ await new Promise((r) => setTimeout(r, backoffMs));
2160
+ backoffMs = Math.min(backoffMs * 2, MAX_BACKOFF_MS);
2161
+ }
2162
+ }
2163
+
2164
+ // server/index.ts
2165
+ import { monitorEventLoopDelay } from "perf_hooks";
2166
+
2167
+ // server/lib/event-loop-lag.ts
2168
+ function readAndResetWindow(hist, windowMs) {
2169
+ const toMs = (ns) => Math.round(ns / 1e6);
2170
+ const w = {
2171
+ p50Ms: toMs(hist.percentile(50)),
2172
+ p99Ms: toMs(hist.percentile(99)),
2173
+ maxMs: toMs(hist.max),
2174
+ // Read before the reset.
2175
+ count: hist.count,
2176
+ windowMs
2177
+ };
2178
+ hist.reset();
2179
+ return w;
2180
+ }
2181
+ function formatLagWindow(w) {
2182
+ return `[event-loop] op=lag-window p50=${w.p50Ms} p99=${w.p99Ms} max=${w.maxMs} n=${w.count} windowMs=${w.windowMs}`;
2183
+ }
2184
+
2185
+ // node_modules/hono/dist/utils/mime.js
2186
+ var getMimeType = (filename, mimes = baseMimes) => {
2187
+ const regexp = /\.([a-zA-Z0-9]+?)$/;
2188
+ const match = filename.match(regexp);
2189
+ if (!match) {
2190
+ return;
2191
+ }
2192
+ let mimeType = mimes[match[1].toLowerCase()];
2193
+ if (mimeType && mimeType.startsWith("text")) {
2194
+ mimeType += "; charset=utf-8";
2195
+ }
2196
+ return mimeType;
2197
+ };
2198
+ var _baseMimes = {
2199
+ aac: "audio/aac",
2200
+ avi: "video/x-msvideo",
2201
+ avif: "image/avif",
2202
+ av1: "video/av1",
2203
+ bin: "application/octet-stream",
2204
+ bmp: "image/bmp",
2205
+ css: "text/css",
2206
+ csv: "text/csv",
2207
+ eot: "application/vnd.ms-fontobject",
2208
+ epub: "application/epub+zip",
2209
+ gif: "image/gif",
2210
+ gz: "application/gzip",
2211
+ htm: "text/html",
2212
+ html: "text/html",
2213
+ ico: "image/x-icon",
2214
+ ics: "text/calendar",
2215
+ jpeg: "image/jpeg",
2216
+ jpg: "image/jpeg",
2217
+ js: "text/javascript",
2218
+ json: "application/json",
2219
+ jsonld: "application/ld+json",
2220
+ map: "application/json",
2221
+ mid: "audio/x-midi",
2222
+ midi: "audio/x-midi",
2223
+ mjs: "text/javascript",
2224
+ mp3: "audio/mpeg",
2225
+ mp4: "video/mp4",
2226
+ mpeg: "video/mpeg",
2227
+ oga: "audio/ogg",
2228
+ ogv: "video/ogg",
2229
+ ogx: "application/ogg",
2230
+ opus: "audio/opus",
2231
+ otf: "font/otf",
2232
+ pdf: "application/pdf",
2233
+ png: "image/png",
2234
+ rtf: "application/rtf",
2235
+ svg: "image/svg+xml",
2236
+ tif: "image/tiff",
2237
+ tiff: "image/tiff",
2238
+ ts: "video/mp2t",
2239
+ ttf: "font/ttf",
2240
+ txt: "text/plain",
2241
+ wasm: "application/wasm",
2242
+ webm: "video/webm",
2243
+ weba: "audio/webm",
2244
+ webmanifest: "application/manifest+json",
2245
+ webp: "image/webp",
2246
+ woff: "font/woff",
2247
+ woff2: "font/woff2",
2248
+ xhtml: "application/xhtml+xml",
2249
+ xml: "application/xml",
2250
+ zip: "application/zip",
2251
+ "3gp": "video/3gpp",
2252
+ "3g2": "video/3gpp2",
2253
+ gltf: "model/gltf+json",
2254
+ glb: "model/gltf-binary"
2255
+ };
2256
+ var baseMimes = _baseMimes;
2257
+
2258
+ // node_modules/@hono/node-server/dist/serve-static.mjs
2259
+ import { createReadStream, statSync as statSync2, existsSync as existsSync2 } from "fs";
2260
+ import { join as join2 } from "path";
2261
+ import { versions } from "process";
2262
+ import { Readable } from "stream";
2263
+ var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
2264
+ var ENCODINGS = {
2265
+ br: ".br",
2266
+ zstd: ".zst",
2267
+ gzip: ".gz"
2268
+ };
2269
+ var ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
2270
+ var pr54206Applied = () => {
2271
+ const [major, minor] = versions.node.split(".").map((component) => parseInt(component));
2272
+ return major >= 23 || major === 22 && minor >= 7 || major === 20 && minor >= 18;
2273
+ };
2274
+ var useReadableToWeb = pr54206Applied();
2275
+ var createStreamBody = (stream2) => {
2276
+ if (useReadableToWeb) {
2277
+ return Readable.toWeb(stream2);
2278
+ }
2279
+ const body = new ReadableStream({
2280
+ start(controller) {
2281
+ stream2.on("data", (chunk) => {
2282
+ controller.enqueue(chunk);
2283
+ });
2284
+ stream2.on("error", (err) => {
2285
+ controller.error(err);
2286
+ });
2287
+ stream2.on("end", () => {
2288
+ controller.close();
2289
+ });
2290
+ },
2291
+ cancel() {
2292
+ stream2.destroy();
2293
+ }
2294
+ });
2295
+ return body;
2296
+ };
2297
+ var getStats = (path3) => {
2298
+ let stats;
2299
+ try {
2300
+ stats = statSync2(path3);
2301
+ } catch {
2302
+ }
2303
+ return stats;
2304
+ };
2305
+ var tryDecode = (str, decoder) => {
2306
+ try {
2307
+ return decoder(str);
2308
+ } catch {
2309
+ return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
2310
+ try {
2311
+ return decoder(match);
2312
+ } catch {
2313
+ return match;
2314
+ }
2315
+ });
2316
+ }
2317
+ };
2318
+ var tryDecodeURI = (str) => tryDecode(str, decodeURI);
2319
+ var serveStatic = (options = { root: "" }) => {
2320
+ const root = options.root || "";
2321
+ const optionPath = options.path;
2322
+ if (root !== "" && !existsSync2(root)) {
2323
+ console.error(`serveStatic: root path '${root}' is not found, are you sure it's correct?`);
2324
+ }
2325
+ return async (c, next) => {
2326
+ if (c.finalized) {
2327
+ return next();
2328
+ }
2329
+ let filename;
2330
+ if (optionPath) {
2331
+ filename = optionPath;
2332
+ } else {
2333
+ try {
2334
+ filename = tryDecodeURI(c.req.path);
2335
+ if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
2336
+ throw new Error();
2337
+ }
2338
+ } catch {
2339
+ await options.onNotFound?.(c.req.path, c);
2340
+ return next();
2341
+ }
2342
+ }
2343
+ let path3 = join2(
2344
+ root,
2345
+ !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename
2346
+ );
2347
+ let stats = getStats(path3);
2348
+ if (stats && stats.isDirectory()) {
2349
+ const indexFile2 = options.index ?? "index.html";
2350
+ path3 = join2(path3, indexFile2);
2351
+ stats = getStats(path3);
2352
+ }
2353
+ if (!stats) {
2354
+ await options.onNotFound?.(path3, c);
2355
+ return next();
2356
+ }
2357
+ const mimeType = getMimeType(path3);
2358
+ c.header("Content-Type", mimeType || "application/octet-stream");
2359
+ if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
2360
+ const acceptEncodingSet = new Set(
2361
+ c.req.header("Accept-Encoding")?.split(",").map((encoding) => encoding.trim())
2362
+ );
2363
+ for (const encoding of ENCODINGS_ORDERED_KEYS) {
2364
+ if (!acceptEncodingSet.has(encoding)) {
2365
+ continue;
2366
+ }
2367
+ const precompressedStats = getStats(path3 + ENCODINGS[encoding]);
2368
+ if (precompressedStats) {
2369
+ c.header("Content-Encoding", encoding);
2370
+ c.header("Vary", "Accept-Encoding", { append: true });
2371
+ stats = precompressedStats;
2372
+ path3 = path3 + ENCODINGS[encoding];
2373
+ break;
2374
+ }
2375
+ }
2376
+ }
2377
+ let result;
2378
+ const size = stats.size;
2379
+ const range = c.req.header("range") || "";
2380
+ if (c.req.method == "HEAD" || c.req.method == "OPTIONS") {
2381
+ c.header("Content-Length", size.toString());
2382
+ c.status(200);
2383
+ result = c.body(null);
2384
+ } else if (!range) {
2385
+ c.header("Content-Length", size.toString());
2386
+ result = c.body(createStreamBody(createReadStream(path3)), 200);
2387
+ } else {
2388
+ c.header("Accept-Ranges", "bytes");
2389
+ c.header("Date", stats.birthtime.toUTCString());
2390
+ const parts = range.replace(/bytes=/, "").split("-", 2);
2391
+ const start = parseInt(parts[0], 10) || 0;
2392
+ let end = parseInt(parts[1], 10) || size - 1;
2393
+ if (size < end - start + 1) {
2394
+ end = size - 1;
2395
+ }
2396
+ const chunksize = end - start + 1;
2397
+ const stream2 = createReadStream(path3, { start, end });
2398
+ c.header("Content-Length", chunksize.toString());
2399
+ c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`);
2400
+ result = c.body(createStreamBody(stream2), 206);
2401
+ }
2402
+ await options.onFound?.(path3, c);
2403
+ return result;
2404
+ };
2405
+ };
2406
+
2407
+ // server/lib/static-cache.ts
2408
+ import { statSync as statSync3 } from "fs";
2409
+ import { join as join3 } from "path";
2410
+ var IMMUTABLE = "public, max-age=31536000, immutable";
2411
+ var REVALIDATE = "public, no-cache";
2412
+ function statOrNull(path3) {
2413
+ try {
2414
+ return statSync3(path3);
2285
2415
  } catch {
2286
- houseId = null;
2287
- }
2288
- if (houseId) {
2289
- watchDirInto(STORE_ROOT(), "conversations-all", houseId);
2290
- } else {
2291
- console.error("[admin-events] op=watch-failed resource=conversations-all reason=house-account-unresolved");
2416
+ return null;
2292
2417
  }
2293
2418
  }
2294
-
2295
- // server/lib/manager-events-subscriber.ts
2296
- var TAG = "[webchat-pointer]";
2297
- var TURN_EVENTS = /* @__PURE__ */ new Set(["row-updated", "row-created"]);
2298
- var MAX_BACKOFF_MS = 3e4;
2299
- var STABLE_CONNECTION_MS = 3e4;
2300
- var lastStatusBySession = /* @__PURE__ */ new Map();
2301
- function handleManagerFrame(raw) {
2302
- const lines = raw.split("\n");
2303
- const eventLine = lines.find((l) => l.startsWith("event: "));
2304
- const dataLine = lines.find((l) => l.startsWith("data: "));
2305
- if (!eventLine || !dataLine) return null;
2306
- if (!TURN_EVENTS.has(eventLine.slice("event: ".length).trim())) return null;
2307
- let body;
2419
+ function tryDecodeURI2(str) {
2308
2420
  try {
2309
- body = JSON.parse(dataLine.slice("data: ".length));
2421
+ return decodeURI(str);
2310
2422
  } catch {
2311
- console.error(`${TAG} op=skip reason=unparseable-frame`);
2312
- return null;
2313
- }
2314
- const sessionId = String(body.sessionId ?? "unknown").slice(0, 8);
2315
- const accountId = typeof body.accountId === "string" && body.accountId ? body.accountId : null;
2316
- if (!accountId) {
2317
- console.error(`${TAG} op=skip reason=no-account sessionId=${sessionId}`);
2318
- return null;
2319
- }
2320
- const status = String(body.status ?? "unknown");
2321
- const fullSessionId = String(body.sessionId ?? "");
2322
- if (fullSessionId && lastStatusBySession.get(fullSessionId) === status) {
2323
- return null;
2423
+ return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
2424
+ try {
2425
+ return decodeURI(match);
2426
+ } catch {
2427
+ return match;
2428
+ }
2429
+ });
2324
2430
  }
2325
- if (fullSessionId) lastStatusBySession.set(fullSessionId, status);
2326
- console.log(
2327
- `${TAG} op=event sessionId=${sessionId} accountId=${accountId.slice(0, 8)} activity=${status}`
2328
- );
2329
- notify("webchat-pointer", accountId);
2330
- return { resource: "webchat-pointer", accountId };
2331
2431
  }
2332
- var connections = 0;
2333
- var started = false;
2334
- var abort = null;
2335
- function startManagerEventsSubscriber() {
2336
- if (started) return;
2337
- started = true;
2338
- abort = new AbortController();
2339
- void connectLoop(abort.signal);
2432
+ function resolveStaticFile(root, reqPath) {
2433
+ const filename = tryDecodeURI2(reqPath);
2434
+ if (/(?:^|[/\\])\.\.(?:$|[/\\])/.test(filename)) return null;
2435
+ let path3 = join3(root, filename);
2436
+ let stats = statOrNull(path3);
2437
+ if (stats?.isDirectory()) {
2438
+ path3 = join3(path3, "index.html");
2439
+ stats = statOrNull(path3);
2440
+ }
2441
+ if (!stats?.isFile()) return null;
2442
+ return { path: path3, stats, filename };
2340
2443
  }
2341
- async function connectLoop(signal) {
2342
- let backoffMs = 1e3;
2343
- for (; ; ) {
2344
- if (signal.aborted) return;
2345
- let port2;
2346
- try {
2347
- port2 = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "webchat-pointer" });
2348
- } catch {
2349
- console.error(`${TAG} op=drop reason=manager-port-unset`);
2350
- return;
2351
- }
2352
- const connectedAt = Date.now();
2353
- try {
2354
- const res = await fetch(`http://127.0.0.1:${port2}/events`, { signal });
2355
- if (!res.ok || !res.body) throw new Error(`status ${res.status}`);
2356
- connections += 1;
2357
- console.log(`${TAG} op=subscribe upstream-count=${connections}`);
2358
- const reader = res.body.getReader();
2359
- const decoder = new TextDecoder();
2360
- let buffer = "";
2361
- for (; ; ) {
2362
- const { done, value } = await reader.read();
2363
- if (done) break;
2364
- buffer += decoder.decode(value, { stream: true });
2365
- let cut = buffer.indexOf("\n\n");
2366
- while (cut !== -1) {
2367
- handleManagerFrame(buffer.slice(0, cut));
2368
- buffer = buffer.slice(cut + 2);
2369
- cut = buffer.indexOf("\n\n");
2370
- }
2371
- }
2372
- connections -= 1;
2373
- } catch (err) {
2374
- if (connections > 0) connections -= 1;
2375
- if (signal.aborted) return;
2376
- console.error(`${TAG} op=drop reason=${err instanceof Error ? err.message : String(err)}`);
2444
+ function staticCacheHeaders(root) {
2445
+ return async (c, next) => {
2446
+ if (c.finalized) return next();
2447
+ const hit = resolveStaticFile(root, c.req.path);
2448
+ if (!hit) return next();
2449
+ if (hit.filename.startsWith("/assets/")) {
2450
+ c.header("Cache-Control", IMMUTABLE);
2451
+ return next();
2377
2452
  }
2378
- if (signal.aborted) return;
2379
- if (Date.now() - connectedAt >= STABLE_CONNECTION_MS) backoffMs = 1e3;
2380
- console.log(`${TAG} op=reconnect inMs=${backoffMs} upstream-count=${connections}`);
2381
- await new Promise((r) => setTimeout(r, backoffMs));
2382
- backoffMs = Math.min(backoffMs * 2, MAX_BACKOFF_MS);
2383
- }
2453
+ const etag = `"${hit.stats.size}-${hit.stats.mtimeMs}"`;
2454
+ c.header("Cache-Control", REVALIDATE);
2455
+ c.header("Last-Modified", hit.stats.mtime.toUTCString());
2456
+ c.header("ETag", etag);
2457
+ if (c.req.header("If-None-Match") === etag) return c.body(null, 304);
2458
+ return next();
2459
+ };
2384
2460
  }
2385
2461
 
2386
- // server/index.ts
2387
- import { monitorEventLoopDelay } from "perf_hooks";
2462
+ // server/lib/static-mounts.ts
2463
+ function mountStaticFiles(app70, root) {
2464
+ app70.use("/*", staticCacheHeaders(root));
2465
+ app70.use("/assets/*", assetsVary);
2466
+ app70.use("/assets/*", serveStatic({ root, precompressed: true }));
2467
+ app70.use("/*", serveStatic({ root }));
2468
+ }
2469
+ var assetsVary = async (c, next) => {
2470
+ await next();
2471
+ if (!c.res.headers.has("Vary")) c.res.headers.set("Vary", "Accept-Encoding");
2472
+ };
2388
2473
 
2389
2474
  // app/lib/whatsapp/inbound/media-download-guard.ts
2390
2475
  var TAG2 = "[media-guard]";
@@ -2452,14 +2537,14 @@ function installMediaDownloadGuard() {
2452
2537
  }
2453
2538
 
2454
2539
  // app/lib/whatsapp/ingest-audit.ts
2455
- import { readdirSync as readdirSync4, readFileSync as readFileSync4, statSync as statSync3 } from "fs";
2456
- import { join as join4 } from "path";
2540
+ import { readdirSync as readdirSync4, readFileSync as readFileSync4, statSync as statSync4 } from "fs";
2541
+ import { join as join5 } from "path";
2457
2542
 
2458
2543
  // app/lib/whatsapp/ingest-ledger.ts
2459
2544
  import { existsSync as existsSync3, mkdirSync as mkdirSync2, appendFileSync as appendFileSync2, readFileSync as readFileSync3, writeFileSync, readdirSync as readdirSync3 } from "fs";
2460
- import { join as join3 } from "path";
2545
+ import { join as join4 } from "path";
2461
2546
  var TAG3 = "[wa-ingest-ledger]";
2462
- var LEDGER_ROOT = () => join3(process.env.MAXY_DIR_OVERRIDE ?? MAXY_DIR, "data", "whatsapp-ingest-ledger");
2547
+ var LEDGER_ROOT = () => join4(process.env.MAXY_DIR_OVERRIDE ?? MAXY_DIR, "data", "whatsapp-ingest-ledger");
2463
2548
  var ensuredRoots = /* @__PURE__ */ new Set();
2464
2549
  function ledgerFilePath(account) {
2465
2550
  const root = LEDGER_ROOT();
@@ -2467,7 +2552,7 @@ function ledgerFilePath(account) {
2467
2552
  if (!existsSync3(root)) mkdirSync2(root, { recursive: true });
2468
2553
  ensuredRoots.add(root);
2469
2554
  }
2470
- return join3(root, `${account}.jsonl`);
2555
+ return join4(root, `${account}.jsonl`);
2471
2556
  }
2472
2557
  function appendStanza(entry) {
2473
2558
  try {
@@ -2573,21 +2658,21 @@ function readAllConversationsCached(accountId) {
2573
2658
  const out = /* @__PURE__ */ new Map();
2574
2659
  let dir;
2575
2660
  try {
2576
- dir = readdirSync4(join4(STORE_ROOT(), accountId));
2661
+ dir = readdirSync4(join5(STORE_ROOT(), accountId));
2577
2662
  } catch {
2578
2663
  return out;
2579
2664
  }
2580
2665
  for (const file of dir) {
2581
2666
  if (!file.endsWith(".jsonl")) continue;
2582
- const path3 = join4(STORE_ROOT(), accountId, file);
2583
- let stat11;
2667
+ const path3 = join5(STORE_ROOT(), accountId, file);
2668
+ let stat12;
2584
2669
  try {
2585
- stat11 = statSync3(path3);
2670
+ stat12 = statSync4(path3);
2586
2671
  } catch {
2587
2672
  continue;
2588
2673
  }
2589
2674
  const hit = idCache.get(path3);
2590
- if (hit && hit.size === stat11.size && hit.mtimeMs === stat11.mtimeMs) {
2675
+ if (hit && hit.size === stat12.size && hit.mtimeMs === stat12.mtimeMs) {
2591
2676
  out.set(file, hit.ids);
2592
2677
  continue;
2593
2678
  }
@@ -2604,7 +2689,7 @@ function readAllConversationsCached(accountId) {
2604
2689
  } catch {
2605
2690
  continue;
2606
2691
  }
2607
- idCache.set(path3, { size: stat11.size, mtimeMs: stat11.mtimeMs, ids: parsed });
2692
+ idCache.set(path3, { size: stat12.size, mtimeMs: stat12.mtimeMs, ids: parsed });
2608
2693
  out.set(file, parsed);
2609
2694
  }
2610
2695
  return out;
@@ -2756,12 +2841,12 @@ function pwaCensus(d) {
2756
2841
  }
2757
2842
 
2758
2843
  // server/webchat-descriptor.ts
2759
- import { resolve as resolve3, join as join5 } from "path";
2844
+ import { resolve as resolve3, join as join6 } from "path";
2760
2845
  function webchatGatewayUrl() {
2761
2846
  return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
2762
2847
  }
2763
2848
  function webchatServerPath() {
2764
- return process.env.MAXY_WEBCHAT_CHANNEL_SERVER_PATH ?? resolve3(process.env.MAXY_PLATFORM_ROOT ?? join5(__dirname, ".."), "services/webchat-channel/dist/server.js");
2849
+ return process.env.MAXY_WEBCHAT_CHANNEL_SERVER_PATH ?? resolve3(process.env.MAXY_PLATFORM_ROOT ?? join6(__dirname, ".."), "services/webchat-channel/dist/server.js");
2765
2850
  }
2766
2851
  function webchatChannelDescriptor(key) {
2767
2852
  return { key, gatewayUrl: webchatGatewayUrl(), serverPath: webchatServerPath() };
@@ -4983,7 +5068,7 @@ function resolvePlatformAccountId(accountsDir = ACCOUNTS_DIR) {
4983
5068
  }
4984
5069
 
4985
5070
  // app/lib/managed-service.ts
4986
- import { join as join6 } from "path";
5071
+ import { join as join7 } from "path";
4987
5072
  import { readFileSync as readFileSync9 } from "fs";
4988
5073
  function isHouseManagedService(accountsDir = ACCOUNTS_DIR) {
4989
5074
  let houseId;
@@ -4994,7 +5079,7 @@ function isHouseManagedService(accountsDir = ACCOUNTS_DIR) {
4994
5079
  }
4995
5080
  try {
4996
5081
  const cfg = JSON.parse(
4997
- readFileSync9(join6(accountsDir, houseId, "account.json"), "utf-8")
5082
+ readFileSync9(join7(accountsDir, houseId, "account.json"), "utf-8")
4998
5083
  );
4999
5084
  return cfg.managedService === true;
5000
5085
  } catch {
@@ -5008,7 +5093,7 @@ function isCustomerTurnSuppressed(role, managedService) {
5008
5093
  // app/lib/whatsapp/inbound/media.ts
5009
5094
  import { randomUUID as randomUUID4, createHash } from "crypto";
5010
5095
  import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
5011
- import { join as join8 } from "path";
5096
+ import { join as join9 } from "path";
5012
5097
  import {
5013
5098
  downloadMediaMessage,
5014
5099
  downloadContentFromMessage,
@@ -5023,7 +5108,7 @@ import { resolve as resolve7, extname } from "path";
5023
5108
 
5024
5109
  // app/lib/data-path.ts
5025
5110
  import { realpathSync } from "fs";
5026
- import { resolve as resolve6, normalize, sep as sep2, relative, basename, join as join7 } from "path";
5111
+ import { resolve as resolve6, normalize, sep as sep2, relative, basename, join as join8 } from "path";
5027
5112
  var PLATFORM_ROOT3 = process.env.MAXY_PLATFORM_ROOT ?? resolve6(process.cwd(), "../platform");
5028
5113
  var DATA_ROOT = resolve6(PLATFORM_ROOT3, "..", "data");
5029
5114
  var CLAUDE_UPLOADS_ROOT = process.env.CLAUDE_CONFIG_DIR ? resolve6(process.env.CLAUDE_CONFIG_DIR, "uploads") : null;
@@ -5091,7 +5176,7 @@ function scratchpadTmpBase() {
5091
5176
  }
5092
5177
  function sessionScratchpadRoot(projectDir, sessionId) {
5093
5178
  const uid = typeof process.geteuid === "function" ? process.geteuid() : 0;
5094
- return join7(scratchpadTmpBase(), `claude-${uid}`, basename(projectDir), sessionId, "scratchpad");
5179
+ return join8(scratchpadTmpBase(), `claude-${uid}`, basename(projectDir), sessionId, "scratchpad");
5095
5180
  }
5096
5181
  function resolveScratchpadPath(raw, scratchpadRootAbs) {
5097
5182
  return resolveUnderRoot(raw, scratchpadRootAbs, "scratchpad");
@@ -5634,7 +5719,7 @@ async function downloadInboundMedia(msg, sock, opts) {
5634
5719
  if (!res) return void 0;
5635
5720
  await mkdir2(MEDIA_DIR, { recursive: true });
5636
5721
  const ext = mimeToExt(res.mimetype);
5637
- const filePath = join8(MEDIA_DIR, `${randomUUID4()}.${ext}`);
5722
+ const filePath = join9(MEDIA_DIR, `${randomUUID4()}.${ext}`);
5638
5723
  await writeFile2(filePath, res.buffer);
5639
5724
  const sizeKB = (res.buffer.length / 1024).toFixed(0);
5640
5725
  console.error(`${TAG14} media downloaded type=${res.mimetype} size=${sizeKB}KB path=${filePath}`);
@@ -7436,7 +7521,7 @@ var health_default = app;
7436
7521
  // app/lib/stt/voice-note.ts
7437
7522
  import { writeFile as writeFile3, mkdtemp, rm } from "fs/promises";
7438
7523
  import { tmpdir } from "os";
7439
- import { join as join9 } from "path";
7524
+ import { join as join10 } from "path";
7440
7525
 
7441
7526
  // app/lib/stt/audio-mime.ts
7442
7527
  var AUDIO_MIME_TYPES = /* @__PURE__ */ new Set([
@@ -7490,9 +7575,9 @@ async function transcribeVoiceNote(file, source) {
7490
7575
  let tempDir;
7491
7576
  let tempPath;
7492
7577
  try {
7493
- tempDir = await mkdtemp(join9(tmpdir(), "voice-"));
7578
+ tempDir = await mkdtemp(join10(tmpdir(), "voice-"));
7494
7579
  const ext = audioExtension(mimeType);
7495
- tempPath = join9(tempDir, `recording${ext}`);
7580
+ tempPath = join10(tempDir, `recording${ext}`);
7496
7581
  const buffer = Buffer.from(await file.arrayBuffer());
7497
7582
  await writeFile3(tempPath, buffer);
7498
7583
  } catch (err) {
@@ -8068,7 +8153,7 @@ async function sendTelegramText(botToken, chatId, text) {
8068
8153
  }
8069
8154
 
8070
8155
  // server/routes/whatsapp.ts
8071
- import { join as join12, resolve as resolve11 } from "path";
8156
+ import { join as join13, resolve as resolve11 } from "path";
8072
8157
  import { readdirSync as readdirSync7, readFileSync as readFileSync14, existsSync as existsSync8 } from "fs";
8073
8158
 
8074
8159
  // app/lib/whatsapp/login.ts
@@ -8076,7 +8161,7 @@ import { randomUUID as randomUUID6 } from "crypto";
8076
8161
 
8077
8162
  // app/lib/whatsapp/config-persist.ts
8078
8163
  import { readFileSync as readFileSync13, writeFileSync as writeFileSync5, existsSync as existsSync7 } from "fs";
8079
- import { resolve as resolve9, join as join10, dirname as dirname2, basename as basename2 } from "path";
8164
+ import { resolve as resolve9, join as join11, dirname as dirname2, basename as basename2 } from "path";
8080
8165
  var TAG22 = "[whatsapp:config]";
8081
8166
  function configPath(accountDir) {
8082
8167
  return resolve9(accountDir, "account.json");
@@ -8423,7 +8508,7 @@ function setPublicAgent(accountDir, slug) {
8423
8508
  if (!trimmed) {
8424
8509
  return { ok: false, error: "Agent slug cannot be empty." };
8425
8510
  }
8426
- const agentConfigPath = join10(accountDir, "agents", trimmed, "config.json");
8511
+ const agentConfigPath = join11(accountDir, "agents", trimmed, "config.json");
8427
8512
  if (!existsSync7(agentConfigPath)) {
8428
8513
  return { ok: false, error: `Agent "${trimmed}" not found \u2014 no config.json at ${agentConfigPath}. Check the agent slug and try again.` };
8429
8514
  }
@@ -9060,12 +9145,12 @@ function serializeWhatsAppSchema() {
9060
9145
 
9061
9146
  // app/lib/whatsapp/status-reconcile.ts
9062
9147
  import { readdirSync as readdirSync6 } from "fs";
9063
- import { join as join11 } from "path";
9148
+ import { join as join12 } from "path";
9064
9149
  var TAG25 = "[whatsapp:reconcile]";
9065
9150
  var HALF_REGISTERED_MIN_AGE_MS = 5 * 6e4;
9066
9151
  function listCredsAccountIds(credsRoot) {
9067
9152
  try {
9068
- return readdirSync6(credsRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && hasCredsSync(join11(credsRoot, e.name))).map((e) => e.name);
9153
+ return readdirSync6(credsRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && hasCredsSync(join12(credsRoot, e.name))).map((e) => e.name);
9069
9154
  } catch {
9070
9155
  return [];
9071
9156
  }
@@ -9080,7 +9165,7 @@ function reconcileCredsOnDisk(opts) {
9080
9165
  const entries2 = [];
9081
9166
  for (const accountId of listCredsAccountIds(credsRoot)) {
9082
9167
  if (liveAccountIds.has(accountId)) continue;
9083
- const authDir = join11(credsRoot, accountId);
9168
+ const authDir = join12(credsRoot, accountId);
9084
9169
  const census = credsCensus(authDir);
9085
9170
  if (census.registered && !census.hasAccountSignature) {
9086
9171
  const inFlight3 = activeLoginAccountIds.has(accountId);
@@ -9317,7 +9402,7 @@ app2.get("/status", (c) => {
9317
9402
  const live = getStatus();
9318
9403
  const liveIds = new Set(live.map((a) => a.accountId));
9319
9404
  const activeLoginIds = new Set(listActiveLoginAccountIds());
9320
- const credsRoot = join12(MAXY_DIR, "credentials", "whatsapp");
9405
+ const credsRoot = join13(MAXY_DIR, "credentials", "whatsapp");
9321
9406
  const accountDir = resolveAccount()?.accountDir ?? null;
9322
9407
  const reconciled = reconcileCredsOnDisk({ credsRoot, accountDir, liveAccountIds: liveIds, activeLoginAccountIds: activeLoginIds });
9323
9408
  const cfg = getWhatsAppConfig();
@@ -9354,7 +9439,7 @@ app2.post("/login/start", async (c) => {
9354
9439
  if (!phone) {
9355
9440
  return c.json({ error: 'Missing required field "phone" (E.164, e.g. +441234567890).' }, 400);
9356
9441
  }
9357
- const authDir = join12(MAXY_DIR, "credentials", "whatsapp", accountId);
9442
+ const authDir = join13(MAXY_DIR, "credentials", "whatsapp", accountId);
9358
9443
  const accountDir = resolveAccount()?.accountDir ?? null;
9359
9444
  const result = await startLogin({ accountId, authDir, phone, accountDir, force });
9360
9445
  console.error(`${TAG26} login/start result account=${accountId} hasCode=${!!result.pairingCode}${result.selfPhone ? ` phone=${result.selfPhone}` : ""}`);
@@ -10001,12 +10086,12 @@ var bodyLimit = (options) => {
10001
10086
  };
10002
10087
 
10003
10088
  // server/routes/storage-broker.ts
10004
- import { join as join13, resolve as resolve12 } from "path";
10089
+ import { join as join14, resolve as resolve12 } from "path";
10005
10090
  import { readdirSync as readdirSync8, readFileSync as readFileSync15, existsSync as existsSync9, realpathSync as realpathSync4 } from "fs";
10006
10091
  import { randomUUID as randomUUID7 } from "crypto";
10007
10092
  var app3 = new Hono();
10008
10093
  function platformRoot() {
10009
- return process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? join13(__dirname, "..", "..");
10094
+ return process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? join14(__dirname, "..", "..");
10010
10095
  }
10011
10096
  function caller(c) {
10012
10097
  return c.req.header("x-maxy-caller-account")?.trim() || null;
@@ -10541,7 +10626,7 @@ async function runStorageAudit(root) {
10541
10626
  if (!existsSync9(accountsDir)) return [];
10542
10627
  const files = [];
10543
10628
  for (const accountId of readdirSync8(accountsDir)) {
10544
- const p = join13(accountsDir, accountId, "secrets", "cloudflare.env");
10629
+ const p = join14(accountsDir, accountId, "secrets", "cloudflare.env");
10545
10630
  if (existsSync9(p)) files.push({ accountId, path: p, contents: readFileSync15(p, "utf8") });
10546
10631
  }
10547
10632
  return files;
@@ -10640,7 +10725,7 @@ function discoverPortalAccounts(accountsDir) {
10640
10725
  if (!existsSync9(accountsDir)) return [];
10641
10726
  const found = [];
10642
10727
  for (const accountId of readdirSync8(accountsDir)) {
10643
- const configPath2 = join13(accountsDir, accountId, "data-portal.json");
10728
+ const configPath2 = join14(accountsDir, accountId, "data-portal.json");
10644
10729
  if (!existsSync9(configPath2)) continue;
10645
10730
  try {
10646
10731
  const cfg = JSON.parse(readFileSync15(configPath2, "utf-8"));
@@ -10723,7 +10808,7 @@ async function runDataPortalAudit(root) {
10723
10808
  // server/portal-uploads-pull.ts
10724
10809
  import { existsSync as existsSync10 } from "fs";
10725
10810
  import { mkdir as mkdir3, readFile as readFile2, rename, stat as stat3, unlink as unlink2, writeFile as writeFile4 } from "fs/promises";
10726
- import { basename as basename4, dirname as dirname4, join as join14, relative as relative2, resolve as resolve13, sep as sep3 } from "path";
10811
+ import { basename as basename4, dirname as dirname4, join as join15, relative as relative2, resolve as resolve13, sep as sep3 } from "path";
10727
10812
 
10728
10813
  // ../plugins/cloudflare/bin/schema-exposed-dirs.mjs
10729
10814
  var ONT_START = "<!-- ontology-buckets:start -->";
@@ -10821,19 +10906,19 @@ function resolveDestination(accountDir, row, exposed) {
10821
10906
  if (!segments.every(safeSegment)) return { ok: false, reason: "bad-target" };
10822
10907
  if (!exposed.includes(segments[0])) return { ok: false, reason: "bad-target" };
10823
10908
  root = resolve13(accountDir);
10824
- dir = join14(root, ...segments);
10909
+ dir = join15(root, ...segments);
10825
10910
  } else {
10826
10911
  root = resolve13(accountDir, "uploads");
10827
- dir = join14(root, row.ownerId);
10912
+ dir = join15(root, row.ownerId);
10828
10913
  }
10829
- const final = join14(dir, row.filename);
10914
+ const final = join15(dir, row.filename);
10830
10915
  if (!final.startsWith(root + sep3)) {
10831
10916
  return { ok: false, reason: row.targetPath ? "bad-target" : "bad-filename" };
10832
10917
  }
10833
10918
  return {
10834
10919
  ok: true,
10835
10920
  dir,
10836
- tmp: join14(dir, ".uploads-tmp", row.filename),
10921
+ tmp: join15(dir, ".uploads-tmp", row.filename),
10837
10922
  final,
10838
10923
  relative: relative2(resolve13(accountDir), final).split(sep3).join("/")
10839
10924
  };
@@ -10846,7 +10931,7 @@ function nextFreePath(final) {
10846
10931
  const stem = dot > 0 ? base.slice(0, dot) : base;
10847
10932
  const ext = dot > 0 ? base.slice(dot) : "";
10848
10933
  for (let n = 2; ; n++) {
10849
- const candidate = join14(dir, `${stem} (${n})${ext}`);
10934
+ const candidate = join15(dir, `${stem} (${n})${ext}`);
10850
10935
  if (!existsSync10(candidate)) return candidate;
10851
10936
  }
10852
10937
  }
@@ -10950,7 +11035,7 @@ async function withdrawRow(opts) {
10950
11035
  log2(`${head} removed=false result=bad-path`);
10951
11036
  return false;
10952
11037
  }
10953
- const absolute = join14(resolve13(accountDir), ...segments);
11038
+ const absolute = join15(resolve13(accountDir), ...segments);
10954
11039
  if (!absolute.startsWith(resolve13(accountDir) + sep3)) {
10955
11040
  log2(`${head} removed=false result=bad-path`);
10956
11041
  return false;
@@ -11015,13 +11100,13 @@ function parsePendingRows(raw) {
11015
11100
  async function readExposedDirs(accountDir) {
11016
11101
  let schemaText = null;
11017
11102
  try {
11018
- schemaText = await readFile2(join14(accountDir, "SCHEMA.md"), "utf8");
11103
+ schemaText = await readFile2(join15(accountDir, "SCHEMA.md"), "utf8");
11019
11104
  } catch {
11020
11105
  schemaText = null;
11021
11106
  }
11022
11107
  let exposeFolders = [];
11023
11108
  try {
11024
- const cfg = JSON.parse(await readFile2(join14(accountDir, "data-portal.json"), "utf8"));
11109
+ const cfg = JSON.parse(await readFile2(join15(accountDir, "data-portal.json"), "utf8"));
11025
11110
  exposeFolders = Array.isArray(cfg?.exposeFolders) ? cfg.exposeFolders.filter((f) => typeof f === "string") : [];
11026
11111
  } catch {
11027
11112
  exposeFolders = [];
@@ -11046,7 +11131,7 @@ async function runPortalUploadsPull(root) {
11046
11131
  console.error(`${TAG27} op=malformed account=${portal.accountId} rows=${malformed}`);
11047
11132
  }
11048
11133
  if (rows.length === 0) continue;
11049
- const accountDir = join14(accountsRoot, portal.accountId);
11134
+ const accountDir = join15(accountsRoot, portal.accountId);
11050
11135
  const r = await pullAccount({
11051
11136
  accountDir,
11052
11137
  accountId: portal.accountId,
@@ -11079,7 +11164,7 @@ async function runPortalUploadsPull(root) {
11079
11164
  import { readFile as readFile3, readdir, stat as stat4 } from "fs/promises";
11080
11165
  import { existsSync as existsSync11, readFileSync as readFileSync16, writeFileSync as writeFileSync6 } from "fs";
11081
11166
  import { execFileSync as execFileSync2 } from "child_process";
11082
- import { join as join15, resolve as resolve14 } from "path";
11167
+ import { join as join16, resolve as resolve14 } from "path";
11083
11168
  import { fileURLToPath } from "url";
11084
11169
 
11085
11170
  // ../plugins/cloudflare/bin/d1-http.mjs
@@ -11155,7 +11240,7 @@ function readEnvFile(path3) {
11155
11240
  }
11156
11241
  async function readExposeFolders(accountDir) {
11157
11242
  try {
11158
- const cfg = JSON.parse(await readFile3(join15(accountDir, "data-portal.json"), "utf8"));
11243
+ const cfg = JSON.parse(await readFile3(join16(accountDir, "data-portal.json"), "utf8"));
11159
11244
  return Array.isArray(cfg?.exposeFolders) ? cfg.exposeFolders.filter((f) => typeof f === "string") : [];
11160
11245
  } catch {
11161
11246
  return [];
@@ -11166,12 +11251,12 @@ async function walkExposed(accountDir, exposed) {
11166
11251
  async function walk(rel) {
11167
11252
  let entries2;
11168
11253
  try {
11169
- entries2 = await readdir(join15(accountDir, rel), { withFileTypes: true });
11254
+ entries2 = await readdir(join16(accountDir, rel), { withFileTypes: true });
11170
11255
  } catch {
11171
11256
  return;
11172
11257
  }
11173
11258
  try {
11174
- const st = await stat4(join15(accountDir, rel));
11259
+ const st = await stat4(join16(accountDir, rel));
11175
11260
  out.push({ relPath: rel, sizeBytes: 0, modifiedAt: st.mtime.toISOString(), isDir: true });
11176
11261
  } catch {
11177
11262
  }
@@ -11182,7 +11267,7 @@ async function walkExposed(accountDir, exposed) {
11182
11267
  await walk(childRel);
11183
11268
  } else if (e.isFile()) {
11184
11269
  try {
11185
- const st = await stat4(join15(accountDir, childRel));
11270
+ const st = await stat4(join16(accountDir, childRel));
11186
11271
  out.push({
11187
11272
  relPath: childRel,
11188
11273
  sizeBytes: st.size,
@@ -11201,7 +11286,7 @@ async function pushAccount(opts) {
11201
11286
  const { accountDir, accountId, client, log: log2, nowIso } = opts;
11202
11287
  let schemaText = null;
11203
11288
  try {
11204
- schemaText = await readFile3(join15(accountDir, "SCHEMA.md"), "utf8");
11289
+ schemaText = await readFile3(join16(accountDir, "SCHEMA.md"), "utf8");
11205
11290
  } catch {
11206
11291
  schemaText = null;
11207
11292
  }
@@ -11231,19 +11316,11 @@ async function pushAccount(opts) {
11231
11316
  [accountId]
11232
11317
  );
11233
11318
  const current = Number(state[0]?.currentGeneration ?? 0);
11234
- const next = current + 1;
11235
- const orphan = await client.query(
11236
- "SELECT COUNT(*) AS n FROM directory WHERE accountId = ? AND generation = ?",
11237
- [accountId, next]
11319
+ const staged = await client.query(
11320
+ "SELECT MAX(generation) AS g FROM directory WHERE accountId = ?",
11321
+ [accountId]
11238
11322
  );
11239
- const orphanCount = Number(orphan[0]?.n ?? 0);
11240
- if (orphanCount > 0) {
11241
- await client.query("DELETE FROM directory WHERE accountId = ? AND generation = ?", [
11242
- accountId,
11243
- next
11244
- ]);
11245
- log2(`${TAG28} op=stage-clear account=${accountId} generation=${next} cleared=${orphanCount}`);
11246
- }
11323
+ const next = Math.max(current, Number(staged[0]?.g ?? 0)) + 1;
11247
11324
  for (const row of rows) {
11248
11325
  await client.query(
11249
11326
  "INSERT INTO directory (accountId, relPath, sizeBytes, modifiedAt, indexedAt, isDir, generation) VALUES (?, ?, ?, ?, ?, ?, ?)",
@@ -11252,12 +11329,29 @@ async function pushAccount(opts) {
11252
11329
  }
11253
11330
  log2(`${TAG28} op=stage account=${accountId} generation=${next} inserted=${rows.length}`);
11254
11331
  await client.query(
11255
- "INSERT INTO directory_state (accountId, currentGeneration) VALUES (?, ?) ON CONFLICT (accountId) DO UPDATE SET currentGeneration = excluded.currentGeneration",
11332
+ "INSERT INTO directory_state (accountId, currentGeneration) VALUES (?, ?) ON CONFLICT (accountId) DO UPDATE SET currentGeneration = excluded.currentGeneration WHERE excluded.currentGeneration > directory_state.currentGeneration",
11256
11333
  [accountId, next]
11257
11334
  );
11335
+ const flipped = await client.query(
11336
+ "SELECT currentGeneration FROM directory_state WHERE accountId = ?",
11337
+ [accountId]
11338
+ );
11339
+ const pointer = Number(flipped[0]?.currentGeneration ?? 0);
11340
+ if (pointer !== next) {
11341
+ log2(
11342
+ `${TAG28} op=stage-contended account=${accountId} generation=${next} pointer=${pointer} action=superseded`
11343
+ );
11344
+ return {
11345
+ exposed: r.exposed,
11346
+ rows: rows.length,
11347
+ schemaPresent: true,
11348
+ generation: next,
11349
+ superseded: true
11350
+ };
11351
+ }
11258
11352
  log2(`${TAG28} op=flip account=${accountId} generation=${next}`);
11259
11353
  try {
11260
- await client.query("DELETE FROM directory WHERE accountId = ? AND generation != ?", [
11354
+ await client.query("DELETE FROM directory WHERE accountId = ? AND generation < ?", [
11261
11355
  accountId,
11262
11356
  next
11263
11357
  ]);
@@ -11309,9 +11403,9 @@ async function portalAccounts(accountsRoot) {
11309
11403
  return out;
11310
11404
  }
11311
11405
  for (const accountId of names) {
11312
- const accountDir = join15(accountsRoot, accountId);
11406
+ const accountDir = join16(accountsRoot, accountId);
11313
11407
  try {
11314
- const cfg = JSON.parse(await readFile3(join15(accountDir, "data-portal.json"), "utf8"));
11408
+ const cfg = JSON.parse(await readFile3(join16(accountDir, "data-portal.json"), "utf8"));
11315
11409
  if (typeof cfg?.portalDbName === "string" && cfg.portalDbName) {
11316
11410
  const exposeFolders = Array.isArray(cfg?.exposeFolders) ? cfg.exposeFolders.filter((f) => typeof f === "string") : [];
11317
11411
  out.push({ accountDir, accountId, dbName: cfg.portalDbName, exposeFolders });
@@ -11324,11 +11418,11 @@ async function portalAccounts(accountsRoot) {
11324
11418
  return out;
11325
11419
  }
11326
11420
  function resolveCloudflareCredentials(platformRoot5) {
11327
- const houseEnvPath = join15(platformRoot5, "config", "cloudflare-house.env");
11421
+ const houseEnvPath = join16(platformRoot5, "config", "cloudflare-house.env");
11328
11422
  const house = readEnvFile(houseEnvPath);
11329
11423
  if (!house.CLOUDFLARE_API_TOKEN) return { error: "no-house-cloudflare-credential" };
11330
11424
  if (!house.CLOUDFLARE_ACCOUNT_ID) return { error: "no-house-cloudflare-account-id" };
11331
- const cfTokenSh = join15(platformRoot5, "plugins", "cloudflare", "bin", "cf-token.sh");
11425
+ const cfTokenSh = join16(platformRoot5, "plugins", "cloudflare", "bin", "cf-token.sh");
11332
11426
  if (!existsSync11(cfTokenSh)) return { error: "cf-token-sh-missing" };
11333
11427
  let keyName;
11334
11428
  try {
@@ -11434,17 +11528,17 @@ async function runPortalIndexPush(root) {
11434
11528
  }
11435
11529
 
11436
11530
  // server/google-pending-audit.ts
11437
- import { existsSync as existsSync12, readdirSync as readdirSync9, statSync as statSync4 } from "fs";
11438
- import { join as join16 } from "path";
11531
+ import { existsSync as existsSync12, readdirSync as readdirSync9, statSync as statSync5 } from "fs";
11532
+ import { join as join17 } from "path";
11439
11533
  var GOOGLE_PENDING_LIFETIME_SEC = 600;
11440
11534
  var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
11441
- function runGooglePendingAudit(accountsDir, nowMs, emit, readMtimeMs = (path3) => statSync4(path3).mtimeMs) {
11535
+ function runGooglePendingAudit(accountsDir, nowMs, emit, readMtimeMs = (path3) => statSync5(path3).mtimeMs) {
11442
11536
  let scanned = 0;
11443
11537
  let stranded = 0;
11444
11538
  if (existsSync12(accountsDir)) {
11445
11539
  for (const accountId of readdirSync9(accountsDir)) {
11446
11540
  if (!UUID_RE2.test(accountId)) continue;
11447
- const pendingPath2 = join16(accountsDir, accountId, "secrets", "google", "pending-oauth.enc");
11541
+ const pendingPath2 = join17(accountsDir, accountId, "secrets", "google", "pending-oauth.enc");
11448
11542
  try {
11449
11543
  if (!existsSync12(pendingPath2)) continue;
11450
11544
  const ageSec = Math.max(0, Math.floor((nowMs - readMtimeMs(pendingPath2)) / 1e3));
@@ -11502,18 +11596,19 @@ function runReconcileLivenessAudit(statePath, nowMs, intervalMs, emit) {
11502
11596
 
11503
11597
  // server/routes/whatsapp-reader.ts
11504
11598
  import { readFileSync as readFileSync21, watch as watch2, statSync as statSync8, openSync, readSync, closeSync, existsSync as existsSync17, readdirSync as readdirSync14, realpathSync as realpathSync6 } from "fs";
11505
- import { basename as basename6, dirname as dirname7, isAbsolute, join as join21, relative as relative3, resolve as resolve17, sep as sep5 } from "path";
11599
+ import { basename as basename6, dirname as dirname7, isAbsolute, join as join22, relative as relative3, resolve as resolve17, sep as sep5 } from "path";
11506
11600
 
11507
11601
  // server/routes/admin/sidebar-sessions.ts
11508
- import { readdirSync as readdirSync12, readFileSync as readFileSync19, statSync as statSync6 } from "fs";
11509
- import { dirname as dirname5, join as join19, resolve as resolve15 } from "path";
11602
+ import { readdirSync as readdirSync12, readFileSync as readFileSync19 } from "fs";
11603
+ import { readFile as readFile4, stat as stat5 } from "fs/promises";
11604
+ import { dirname as dirname5, join as join20, resolve as resolve15 } from "path";
11510
11605
 
11511
11606
  // ../services/claude-session-manager/src/jsonl-path.ts
11512
11607
  import { existsSync as existsSync14, readdirSync as readdirSync10 } from "fs";
11513
11608
  import { homedir } from "os";
11514
- import { join as join17 } from "path";
11609
+ import { join as join18 } from "path";
11515
11610
  function findExistingJsonlForSessionId(claudeConfigDir2, sessionId) {
11516
- const projectsRoot = join17(claudeConfigDir2, "projects");
11611
+ const projectsRoot = join18(claudeConfigDir2, "projects");
11517
11612
  if (!existsSync14(projectsRoot)) return null;
11518
11613
  let slugs;
11519
11614
  try {
@@ -11523,9 +11618,9 @@ function findExistingJsonlForSessionId(claudeConfigDir2, sessionId) {
11523
11618
  }
11524
11619
  const basename15 = `${sessionId}.jsonl`;
11525
11620
  for (const slug of slugs) {
11526
- const live = join17(projectsRoot, slug, basename15);
11621
+ const live = join18(projectsRoot, slug, basename15);
11527
11622
  if (existsSync14(live)) return live;
11528
- const archived = join17(projectsRoot, slug, "archive", basename15);
11623
+ const archived = join18(projectsRoot, slug, "archive", basename15);
11529
11624
  if (existsSync14(archived)) return archived;
11530
11625
  }
11531
11626
  return null;
@@ -11533,8 +11628,8 @@ function findExistingJsonlForSessionId(claudeConfigDir2, sessionId) {
11533
11628
 
11534
11629
  // app/lib/admin-identity/pin-validator.ts
11535
11630
  import { createHash as createHash3 } from "crypto";
11536
- import { existsSync as existsSync15, readFileSync as readFileSync18, readdirSync as readdirSync11, statSync as statSync5 } from "fs";
11537
- import { join as join18 } from "path";
11631
+ import { existsSync as existsSync15, readFileSync as readFileSync18, readdirSync as readdirSync11, statSync as statSync6 } from "fs";
11632
+ import { join as join19 } from "path";
11538
11633
  function hashPin(pin) {
11539
11634
  return createHash3("sha256").update(pin).digest("hex");
11540
11635
  }
@@ -11665,7 +11760,7 @@ function enumerateJsonls(projectsRoot) {
11665
11760
  throw err;
11666
11761
  }
11667
11762
  for (const slug of slugs) {
11668
- const slugDir = join19(projectsRoot, slug);
11763
+ const slugDir = join20(projectsRoot, slug);
11669
11764
  let entries2;
11670
11765
  try {
11671
11766
  entries2 = readdirSync12(slugDir, { withFileTypes: true });
@@ -11676,9 +11771,9 @@ function enumerateJsonls(projectsRoot) {
11676
11771
  }
11677
11772
  for (const entry of entries2) {
11678
11773
  if (entry.isFile() && SESSION_ID_RE.test(entry.name)) {
11679
- out.push({ path: join19(slugDir, entry.name), isSubagent: false, archived: false });
11774
+ out.push({ path: join20(slugDir, entry.name), isSubagent: false, archived: false });
11680
11775
  } else if (entry.isDirectory() && entry.name === "subagents") {
11681
- const subDir = join19(slugDir, entry.name);
11776
+ const subDir = join20(slugDir, entry.name);
11682
11777
  let subEntries;
11683
11778
  try {
11684
11779
  subEntries = readdirSync12(subDir, { withFileTypes: true });
@@ -11689,11 +11784,11 @@ function enumerateJsonls(projectsRoot) {
11689
11784
  }
11690
11785
  for (const sub of subEntries) {
11691
11786
  if (sub.isFile() && SESSION_ID_RE.test(sub.name)) {
11692
- out.push({ path: join19(subDir, sub.name), isSubagent: true, archived: false });
11787
+ out.push({ path: join20(subDir, sub.name), isSubagent: true, archived: false });
11693
11788
  }
11694
11789
  }
11695
11790
  } else if (entry.isDirectory() && entry.name === "archive") {
11696
- const archiveDir = join19(slugDir, entry.name);
11791
+ const archiveDir = join20(slugDir, entry.name);
11697
11792
  let archiveEntries;
11698
11793
  try {
11699
11794
  archiveEntries = readdirSync12(archiveDir, { withFileTypes: true });
@@ -11704,7 +11799,7 @@ function enumerateJsonls(projectsRoot) {
11704
11799
  }
11705
11800
  for (const arc of archiveEntries) {
11706
11801
  if (arc.isFile() && SESSION_ID_RE.test(arc.name)) {
11707
- out.push({ path: join19(archiveDir, arc.name), isSubagent: false, archived: true });
11802
+ out.push({ path: join20(archiveDir, arc.name), isSubagent: false, archived: true });
11708
11803
  }
11709
11804
  }
11710
11805
  }
@@ -11735,15 +11830,27 @@ async function fetchLiveSessions() {
11735
11830
  return out;
11736
11831
  }
11737
11832
  function loadUserTitles(accountDir) {
11738
- const out = /* @__PURE__ */ new Map();
11739
- if (!accountDir) return out;
11740
- const path3 = join19(accountDir, "session-titles.json");
11833
+ if (!accountDir) return /* @__PURE__ */ new Map();
11741
11834
  let raw;
11742
11835
  try {
11743
- raw = readFileSync19(path3, "utf8");
11836
+ raw = readFileSync19(join20(accountDir, "session-titles.json"), "utf8");
11744
11837
  } catch {
11745
- return out;
11838
+ return /* @__PURE__ */ new Map();
11839
+ }
11840
+ return parseUserTitles(raw);
11841
+ }
11842
+ async function loadUserTitlesAsync(accountDir) {
11843
+ if (!accountDir) return /* @__PURE__ */ new Map();
11844
+ let raw;
11845
+ try {
11846
+ raw = await readFile4(join20(accountDir, "session-titles.json"), "utf8");
11847
+ } catch {
11848
+ return /* @__PURE__ */ new Map();
11746
11849
  }
11850
+ return parseUserTitles(raw);
11851
+ }
11852
+ function parseUserTitles(raw) {
11853
+ const out = /* @__PURE__ */ new Map();
11747
11854
  let parsed;
11748
11855
  try {
11749
11856
  parsed = JSON.parse(raw);
@@ -11763,20 +11870,34 @@ function loadUserTitles(accountDir) {
11763
11870
  return out;
11764
11871
  }
11765
11872
  function readSidecarMeta(metaPath) {
11766
- const empty = { bridgeIds: [], role: null, channel: null, senderId: null, startedAt: null, personId: null, adminUserId: null, visitorId: null, agentSlug: null, accountId: null };
11767
11873
  let raw;
11768
11874
  try {
11769
11875
  raw = readFileSync19(metaPath, "utf8");
11770
11876
  } catch {
11771
- return empty;
11877
+ return emptySidecarMeta();
11878
+ }
11879
+ return parseSidecarMeta(raw);
11880
+ }
11881
+ function emptySidecarMeta() {
11882
+ return { bridgeIds: [], role: null, channel: null, senderId: null, startedAt: null, personId: null, adminUserId: null, visitorId: null, agentSlug: null, accountId: null };
11883
+ }
11884
+ async function readSidecarMetaAsync(metaPath) {
11885
+ let raw;
11886
+ try {
11887
+ raw = await readFile4(metaPath, "utf8");
11888
+ } catch {
11889
+ return emptySidecarMeta();
11772
11890
  }
11891
+ return parseSidecarMeta(raw);
11892
+ }
11893
+ function parseSidecarMeta(raw) {
11773
11894
  let parsed;
11774
11895
  try {
11775
11896
  parsed = JSON.parse(raw);
11776
11897
  } catch {
11777
- return empty;
11898
+ return emptySidecarMeta();
11778
11899
  }
11779
- if (!parsed || typeof parsed !== "object") return empty;
11900
+ if (!parsed || typeof parsed !== "object") return emptySidecarMeta();
11780
11901
  const r = parsed;
11781
11902
  const bridgeIds = Array.isArray(r.bridgeIds) ? r.bridgeIds.filter((b) => typeof b === "string" && b.length > 0) : [];
11782
11903
  return {
@@ -11877,12 +11998,12 @@ async function computeSessionList(scopeAccountId) {
11877
11998
  console.error("[admin-sessions-list] CLAUDE_CONFIG_DIR not set; returning empty list");
11878
11999
  return { sessions: [], accountId: scopeAccountId };
11879
12000
  }
11880
- const projectsRoot = join19(configDir2, "projects");
12001
+ const projectsRoot = join20(configDir2, "projects");
11881
12002
  const jsonls = enumerateJsonls(projectsRoot);
11882
12003
  const liveSessions = await fetchLiveSessions();
11883
12004
  const accountDir = scopeAccountId ? resolve15(ACCOUNTS_DIR, scopeAccountId) : null;
11884
- const userTitles = loadUserTitles(accountDir);
11885
- const account = multiAccount ? validAccounts.find((a) => a.accountId === scopeAccountId) ?? null : resolveAccount();
12005
+ const userTitles = await loadUserTitlesAsync(accountDir);
12006
+ const account = multiAccount ? validAccounts.find((a) => a.accountId === scopeAccountId) ?? null : validAccounts[0] ?? null;
11886
12007
  let channelUsers = [];
11887
12008
  if (account) {
11888
12009
  try {
@@ -11921,8 +12042,8 @@ async function computeSessionList(scopeAccountId) {
11921
12042
  let body;
11922
12043
  let mtimeMs;
11923
12044
  try {
11924
- body = readFileSync19(path3, "utf8");
11925
- mtimeMs = statSync6(path3).mtimeMs;
12045
+ body = await readFile4(path3, "utf8");
12046
+ mtimeMs = (await stat5(path3)).mtimeMs;
11926
12047
  } catch {
11927
12048
  continue;
11928
12049
  }
@@ -11930,8 +12051,8 @@ async function computeSessionList(scopeAccountId) {
11930
12051
  const pid = live ? liveSessions.get(sessionId) ?? null : null;
11931
12052
  const resolved = resolveTitle(body, sessionId, userTitles);
11932
12053
  titleSourceCounts[resolved.source] += 1;
11933
- const metaPath = join19(projectDir, `${sessionId}.meta.json`);
11934
- const { bridgeIds, role, channel: sidecarChannel, senderId, personId, adminUserId, accountId: rowAccountId } = readSidecarMeta(metaPath);
12054
+ const metaPath = join20(projectDir, `${sessionId}.meta.json`);
12055
+ const { bridgeIds, role, channel: sidecarChannel, senderId, personId, adminUserId, accountId: rowAccountId } = await readSidecarMetaAsync(metaPath);
11935
12056
  if (multiAccount) {
11936
12057
  if (rowAccountId === null) untaggedCount += 1;
11937
12058
  if (rowAccountId !== scopeAccountId) continue;
@@ -12333,7 +12454,7 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
12333
12454
 
12334
12455
  // app/lib/whatsapp-reader/enrich-attachments.ts
12335
12456
  import { readFileSync as readFileSync20, readdirSync as readdirSync13, existsSync as existsSync16, statSync as statSync7, realpathSync as realpathSync5 } from "fs";
12336
- import { basename as basename5, dirname as dirname6, join as join20, resolve as resolve16, sep as sep4 } from "path";
12457
+ import { basename as basename5, dirname as dirname6, join as join21, resolve as resolve16, sep as sep4 } from "path";
12337
12458
  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;
12338
12459
  function adminAttachmentIds(text) {
12339
12460
  const ids = [];
@@ -12346,7 +12467,7 @@ function adminAttachmentIds(text) {
12346
12467
  function adminAttachmentsFromText(text, uploadsBase) {
12347
12468
  const out = [];
12348
12469
  for (const id of adminAttachmentIds(text)) {
12349
- const meta = readAttachmentMeta(join20(uploadsBase, id));
12470
+ const meta = readAttachmentMeta(join21(uploadsBase, id));
12350
12471
  if (meta) out.push(meta);
12351
12472
  }
12352
12473
  return out;
@@ -12396,7 +12517,7 @@ function claudeUploadAttachmentsFromText(text, sessionId) {
12396
12517
  function readSidecar(dir, attachmentId) {
12397
12518
  let parsed;
12398
12519
  try {
12399
- parsed = JSON.parse(readFileSync20(join20(dir, `${attachmentId}.meta.json`), "utf8"));
12520
+ parsed = JSON.parse(readFileSync20(join21(dir, `${attachmentId}.meta.json`), "utf8"));
12400
12521
  } catch {
12401
12522
  return null;
12402
12523
  }
@@ -12425,7 +12546,7 @@ function listSessionAttachmentsInDir(dir) {
12425
12546
  }
12426
12547
  const sidecars = [];
12427
12548
  for (const name of entries2) {
12428
- const sidecar = readSidecar(join20(dir, name), name);
12549
+ const sidecar = readSidecar(join21(dir, name), name);
12429
12550
  if (sidecar) sidecars.push(sidecar);
12430
12551
  }
12431
12552
  sidecars.sort((a, b) => a.storedAt.localeCompare(b.storedAt));
@@ -12585,14 +12706,14 @@ app5.get("/conversations", requireAdminSession, async (c) => {
12585
12706
  }
12586
12707
  const cfg = claudeConfigDir();
12587
12708
  if (!cfg) return c.json({ conversations: [] });
12588
- const projectsRoot = join21(cfg, "projects");
12709
+ const projectsRoot = join22(cfg, "projects");
12589
12710
  const userTitles = loadUserTitles(ACCOUNTS_DIR ?? null);
12590
12711
  const rows = [];
12591
12712
  let sessionRowsExcludedUntagged = 0;
12592
12713
  for (const { path: path3 } of enumerateJsonls(projectsRoot)) {
12593
12714
  const sessionId = basename6(path3).replace(/\.jsonl$/, "");
12594
12715
  const projectDir = dirname7(path3);
12595
- const meta = readSidecarMeta(join21(projectDir, `${sessionId}.meta.json`));
12716
+ const meta = readSidecarMeta(join22(projectDir, `${sessionId}.meta.json`));
12596
12717
  if (!isReaderChannelSession(meta.role, meta.channel)) continue;
12597
12718
  if (multiAccount) {
12598
12719
  if (meta.accountId === null) sessionRowsExcludedUntagged += 1;
@@ -12723,7 +12844,7 @@ app5.get("/conversations-all", requireAdminSession, async (c) => {
12723
12844
  const { value, state } = await getOrCompute("conversations-all", houseId, async () => {
12724
12845
  const cfg = claudeConfigDir();
12725
12846
  if (!cfg) return { conversations: [] };
12726
- const projectsRoot = join21(cfg, "projects");
12847
+ const projectsRoot = join22(cfg, "projects");
12727
12848
  const userTitles = loadUserTitles(ACCOUNTS_DIR ?? null);
12728
12849
  const validAccounts = listValidAccounts();
12729
12850
  const validIds = new Set(validAccounts.map((a) => a.accountId));
@@ -12732,7 +12853,7 @@ app5.get("/conversations-all", requireAdminSession, async (c) => {
12732
12853
  for (const { path: path3 } of enumerateJsonls(projectsRoot)) {
12733
12854
  const sessionId = basename6(path3).replace(/\.jsonl$/, "");
12734
12855
  const projectDir = dirname7(path3);
12735
- const meta = readSidecarMeta(join21(projectDir, `${sessionId}.meta.json`));
12856
+ const meta = readSidecarMeta(join22(projectDir, `${sessionId}.meta.json`));
12736
12857
  if (!isReaderChannelSession(meta.role, meta.channel)) continue;
12737
12858
  if (meta.accountId === null || !validIds.has(meta.accountId)) continue;
12738
12859
  let body = "";
@@ -12897,7 +13018,7 @@ function openTaskKey(turns) {
12897
13018
  }
12898
13019
  function readSubagentMeta(dir, hex) {
12899
13020
  try {
12900
- const m = JSON.parse(readFileSync21(join21(dir, `agent-${hex}.meta.json`), "utf8"));
13021
+ const m = JSON.parse(readFileSync21(join22(dir, `agent-${hex}.meta.json`), "utf8"));
12901
13022
  if (typeof m.agentType === "string" && typeof m.description === "string" && typeof m.toolUseId === "string") {
12902
13023
  return { agentType: m.agentType, description: m.description, toolUseId: m.toolUseId };
12903
13024
  }
@@ -12929,7 +13050,7 @@ function runActivityTick(c) {
12929
13050
  let size = 0;
12930
13051
  let mtimeMs = 0;
12931
13052
  try {
12932
- const st = statSync8(join21(c.subagentsDir, name));
13053
+ const st = statSync8(join22(c.subagentsDir, name));
12933
13054
  size = st.size;
12934
13055
  mtimeMs = st.mtimeMs;
12935
13056
  } catch {
@@ -12974,11 +13095,11 @@ app5.get("/stream", requireAdminSession, (c) => {
12974
13095
  const sessionId = c.req.query("sessionId") ?? "";
12975
13096
  const projectDir = c.req.query("projectDir") ?? "";
12976
13097
  const cfg = claudeConfigDir();
12977
- const projectsRoot = cfg ? resolve17(join21(cfg, "projects")) : null;
13098
+ const projectsRoot = cfg ? resolve17(join22(cfg, "projects")) : null;
12978
13099
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
12979
13100
  return c.json({ error: "bad session reference" }, 400);
12980
13101
  }
12981
- const jsonlPath = resolve17(join21(projectDir, `${sessionId}.jsonl`));
13102
+ const jsonlPath = resolve17(join22(projectDir, `${sessionId}.jsonl`));
12982
13103
  if (!jsonlPath.startsWith(projectsRoot + sep5)) {
12983
13104
  return c.json({ error: "bad session reference" }, 400);
12984
13105
  }
@@ -13005,7 +13126,7 @@ data: ${JSON.stringify(turn)}
13005
13126
  let offset = resumeOffset(lastEventId, fileEnd0);
13006
13127
  console.log(`[wa-stream] op=open conn=${connId} sessionId=${sessionId} channel=reader resume=${offset}`);
13007
13128
  const sessionKey = c.req.query("session_key") ?? "";
13008
- const subagentsDir = resolve17(join21(projectDir, sessionId, "subagents"));
13129
+ const subagentsDir = resolve17(join22(projectDir, sessionId, "subagents"));
13009
13130
  console.log(
13010
13131
  `[webchat-activity] op=watch-subagents key=${sessionKey} dir=${subagentsDir} exists=${existsSync17(subagentsDir)}`
13011
13132
  );
@@ -13134,7 +13255,7 @@ app5.get("/directives", requireAdminSession, (c) => {
13134
13255
  const pid = Number(pidPart);
13135
13256
  let len = 0;
13136
13257
  try {
13137
- len = statSync8(join21(dir, name)).size;
13258
+ len = statSync8(join22(dir, name)).size;
13138
13259
  } catch {
13139
13260
  }
13140
13261
  return { name, secs, pid, ts: Number.isFinite(secs) ? new Date(secs * 1e3).toISOString() : null, len };
@@ -13149,7 +13270,7 @@ app5.get("/directive", requireAdminSession, (c) => {
13149
13270
  }
13150
13271
  const dir = directiveStoreDir(sessionId);
13151
13272
  if (!dir) return c.json({ error: "no account" }, 404);
13152
- const path3 = resolve17(join21(dir, name));
13273
+ const path3 = resolve17(join22(dir, name));
13153
13274
  if (!path3.startsWith(dir + sep5)) return c.json({ error: "bad reference" }, 400);
13154
13275
  let body;
13155
13276
  try {
@@ -13207,7 +13328,7 @@ app5.get("/store-stream", requireAdminSession, (c) => {
13207
13328
  console.log(`[wa-reader] op=store-quote msgId=${r.msgKeyId} quoted=${!!q2}`);
13208
13329
  }
13209
13330
  if (r.attachmentId) {
13210
- const meta = readAttachmentMeta(join21(uploadsBase, r.attachmentId));
13331
+ const meta = readAttachmentMeta(join22(uploadsBase, r.attachmentId));
13211
13332
  if (meta) return { ...turn, attachments: [meta] };
13212
13333
  }
13213
13334
  return turn;
@@ -13588,7 +13709,7 @@ var whatsapp_reader_default = app5;
13588
13709
 
13589
13710
  // server/routes/public-reader.ts
13590
13711
  import { statSync as statSync9, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, watch as watch3, readFileSync as readFileSync22, readdirSync as readdirSync15 } from "fs";
13591
- import { basename as basename7, dirname as dirname8, join as join22, resolve as resolve18, sep as sep6 } from "path";
13712
+ import { basename as basename7, dirname as dirname8, join as join23, resolve as resolve18, sep as sep6 } from "path";
13592
13713
 
13593
13714
  // app/lib/whatsapp-reader/delivered-kinds.ts
13594
13715
  var PUBLIC_DELIVERED_KINDS = /* @__PURE__ */ new Set([
@@ -13662,10 +13783,10 @@ function enumeratePublicRows() {
13662
13783
  const cfg = claudeConfigDir();
13663
13784
  if (!cfg) return [];
13664
13785
  const rows = [];
13665
- for (const { path: path3 } of enumerateJsonls(join22(cfg, "projects"))) {
13786
+ for (const { path: path3 } of enumerateJsonls(join23(cfg, "projects"))) {
13666
13787
  const sessionId = basename7(path3).replace(/\.jsonl$/, "");
13667
13788
  const projectDir = dirname8(path3);
13668
- const meta = readSidecarMeta(join22(projectDir, `${sessionId}.meta.json`));
13789
+ const meta = readSidecarMeta(join23(projectDir, `${sessionId}.meta.json`));
13669
13790
  rows.push({
13670
13791
  sessionId,
13671
13792
  projectDir,
@@ -13741,15 +13862,15 @@ app6.get("/stream", (c) => {
13741
13862
  const sessionId = c.req.query("sessionId") ?? "";
13742
13863
  const projectDir = c.req.query("projectDir") ?? "";
13743
13864
  const cfg = claudeConfigDir();
13744
- const projectsRoot = cfg ? resolve18(join22(cfg, "projects")) : null;
13865
+ const projectsRoot = cfg ? resolve18(join23(cfg, "projects")) : null;
13745
13866
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
13746
13867
  return c.json({ error: "bad session reference" }, 400);
13747
13868
  }
13748
- const jsonlPath = resolve18(join22(projectDir, `${sessionId}.jsonl`));
13869
+ const jsonlPath = resolve18(join23(projectDir, `${sessionId}.jsonl`));
13749
13870
  if (!jsonlPath.startsWith(projectsRoot + sep6)) {
13750
13871
  return c.json({ error: "bad session reference" }, 400);
13751
13872
  }
13752
- const meta = readSidecarMeta(join22(projectDir, `${sessionId}.meta.json`));
13873
+ const meta = readSidecarMeta(join23(projectDir, `${sessionId}.meta.json`));
13753
13874
  const isPublicWebchat = meta.role === "public" && meta.channel === "webchat";
13754
13875
  const owns = visitor.kind === "person" ? meta.personId === visitor.personId : meta.personId === null && meta.visitorId === visitor.visitorId;
13755
13876
  if (!(isPublicWebchat && owns)) {
@@ -13886,16 +14007,16 @@ var public_reader_default = app6;
13886
14007
 
13887
14008
  // server/routes/webchat.ts
13888
14009
  import { basename as basename8, dirname as dirname9 } from "path";
13889
- import { join as join25 } from "path";
14010
+ import { join as join26 } from "path";
13890
14011
  import { existsSync as existsSync19, readdirSync as readdirSync17, readFileSync as readFileSync25, renameSync as renameSync4, statSync as statSync10, writeFileSync as writeFileSync9 } from "fs";
13891
14012
 
13892
14013
  // server/canonical-webchat-override.ts
13893
14014
  import { readFileSync as readFileSync23, writeFileSync as writeFileSync7, renameSync as renameSync2 } from "fs";
13894
- import { join as join23 } from "path";
14015
+ import { join as join24 } from "path";
13895
14016
  var FILE = "canonical-webchat-session.json";
13896
14017
  var UUID2 = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
13897
14018
  function canonicalOverridePath(accountDir) {
13898
- return join23(accountDir, FILE);
14019
+ return join24(accountDir, FILE);
13899
14020
  }
13900
14021
  function readRaw(accountDir) {
13901
14022
  try {
@@ -13931,6 +14052,31 @@ function writeCanonicalOverrideId(accountDir, userId, sessionId) {
13931
14052
  renameSync2(tmp, path3);
13932
14053
  }
13933
14054
 
14055
+ // server/routes/admin/_account-scope.ts
14056
+ function accountDirForSession(cacheKey) {
14057
+ const accountId = getAccountIdForSession(cacheKey);
14058
+ if (!accountId) return null;
14059
+ const match = listValidAccounts().find((a) => a.accountId === accountId);
14060
+ return match ? { accountId, accountDir: match.accountDir, config: match.config } : null;
14061
+ }
14062
+ function validateAccountId2(accountId) {
14063
+ if (!accountId) return null;
14064
+ const match = listValidAccounts().find((a) => a.accountId === accountId);
14065
+ return match ? { accountId, accountDir: match.accountDir, config: match.config } : null;
14066
+ }
14067
+ async function authorizeAccountWrite(c, accountId) {
14068
+ const remote = c.env?.incoming?.socket?.remoteAddress ?? "";
14069
+ const peerIsLoopback = remote === "127.0.0.1" || remote === "::1" || remote === "::ffff:127.0.0.1";
14070
+ if (peerIsLoopback && !c.req.header("x-forwarded-for")) return { ok: true, via: "on-device" };
14071
+ const { fingerprint, signedSessionToken } = await resolveCacheKey(c);
14072
+ if (!fingerprint || !validateSession(fingerprint, "admin", signedSessionToken).ok) {
14073
+ return { ok: false, reason: "no-session" };
14074
+ }
14075
+ const acct = accountDirForSession(fingerprint);
14076
+ if (!acct || acct.accountId !== accountId) return { ok: false, reason: "account-mismatch" };
14077
+ return { ok: true, via: "session" };
14078
+ }
14079
+
13934
14080
  // ../lib/models/src/index.ts
13935
14081
  var OPUS_MODEL = "claude-opus-5[1m]";
13936
14082
  var SONNET_MODEL = "claude-sonnet-5";
@@ -13975,7 +14121,7 @@ function isNewSessionEffortLevel(value) {
13975
14121
 
13976
14122
  // ../services/claude-session-manager/src/sidecar-store.ts
13977
14123
  import { existsSync as existsSync18, mkdirSync as mkdirSync4, readdirSync as readdirSync16, readFileSync as readFileSync24, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync8 } from "fs";
13978
- import { join as join24 } from "path";
14124
+ import { join as join25 } from "path";
13979
14125
  function escapeRegExp(s) {
13980
14126
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
13981
14127
  }
@@ -13983,7 +14129,7 @@ function createSidecarStore(config) {
13983
14129
  const { suffix, validate: validate2 } = config;
13984
14130
  const suffixRe = new RegExp(`${escapeRegExp(suffix)}$`);
13985
14131
  function pathFor(sessionsDir, id) {
13986
- return join24(sessionsDir, `${id}${suffix}`);
14132
+ return join25(sessionsDir, `${id}${suffix}`);
13987
14133
  }
13988
14134
  function write(sessionsDir, id, record) {
13989
14135
  mkdirSync4(sessionsDir, { recursive: true });
@@ -14027,7 +14173,7 @@ function createSidecarStore(config) {
14027
14173
  const out = [];
14028
14174
  for (const name of names) {
14029
14175
  if (!suffixRe.test(name)) continue;
14030
- const path3 = join24(sessionsDir, name);
14176
+ const path3 = join25(sessionsDir, name);
14031
14177
  let raw;
14032
14178
  try {
14033
14179
  raw = readFileSync24(path3, "utf8");
@@ -14104,13 +14250,13 @@ var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9
14104
14250
  function locateSession(sessionId) {
14105
14251
  const dir = findSessionProjectDir(sessionId);
14106
14252
  if (!dir) return { projectDir: null, channel: null, accountId: null };
14107
- const meta = readSidecarMeta(join25(dir, `${sessionId}.meta.json`));
14253
+ const meta = readSidecarMeta(join26(dir, `${sessionId}.meta.json`));
14108
14254
  return { projectDir: dir, channel: meta.channel, accountId: meta.accountId };
14109
14255
  }
14110
14256
  function locateSidecar(sessionId) {
14111
14257
  const cfg = claudeConfigDir();
14112
14258
  if (!cfg) return null;
14113
- const projectsRoot = join25(cfg, "projects");
14259
+ const projectsRoot = join26(cfg, "projects");
14114
14260
  let slugs;
14115
14261
  try {
14116
14262
  slugs = readdirSync17(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
@@ -14118,7 +14264,7 @@ function locateSidecar(sessionId) {
14118
14264
  return null;
14119
14265
  }
14120
14266
  for (const slug of slugs) {
14121
- const metaPath = join25(projectsRoot, slug, `${sessionId}.meta.json`);
14267
+ const metaPath = join26(projectsRoot, slug, `${sessionId}.meta.json`);
14122
14268
  if (existsSync19(metaPath)) return readSidecarMeta(metaPath);
14123
14269
  }
14124
14270
  return null;
@@ -14128,7 +14274,7 @@ function readTargetOwner(sessionId) {
14128
14274
  if (sidecar !== null) return { found: true, owner: sidecar.adminUserId };
14129
14275
  const { projectDir } = locateSession(sessionId);
14130
14276
  if (projectDir !== null) {
14131
- return { found: true, owner: readSidecarMeta(join25(projectDir, `${sessionId}.meta.json`)).adminUserId };
14277
+ return { found: true, owner: readSidecarMeta(join26(projectDir, `${sessionId}.meta.json`)).adminUserId };
14132
14278
  }
14133
14279
  return { found: false, owner: null };
14134
14280
  }
@@ -14136,7 +14282,7 @@ function readSourceRowMeta(sessionId) {
14136
14282
  const sidecar = locateSidecar(sessionId);
14137
14283
  if (sidecar !== null) return sidecar;
14138
14284
  const { projectDir } = locateSession(sessionId);
14139
- if (projectDir !== null) return readSidecarMeta(join25(projectDir, `${sessionId}.meta.json`));
14285
+ if (projectDir !== null) return readSidecarMeta(join26(projectDir, `${sessionId}.meta.json`));
14140
14286
  return null;
14141
14287
  }
14142
14288
  function ownedByRequester(owner, requesterUserId, primaryUserId) {
@@ -14149,7 +14295,7 @@ function sessionSidecarExists(sessionId) {
14149
14295
  function jsonlSizeBytes(projectDir, sessionId) {
14150
14296
  if (projectDir === null) return null;
14151
14297
  try {
14152
- return statSync10(join25(projectDir, `${sessionId}.jsonl`)).size;
14298
+ return statSync10(join26(projectDir, `${sessionId}.jsonl`)).size;
14153
14299
  } catch {
14154
14300
  return null;
14155
14301
  }
@@ -14252,15 +14398,7 @@ async function managerInterrupt(sessionId, trigger, escalate = false) {
14252
14398
  }
14253
14399
  }
14254
14400
  var MODEL_ID_PATTERN = /^claude-[a-z0-9][a-z0-9.-]*(\[1m\])?$/;
14255
- function readLevers(preResolved) {
14256
- let account = preResolved;
14257
- if (account === void 0) {
14258
- try {
14259
- account = resolveAccount();
14260
- } catch {
14261
- return { leverModel: null, leverEffort: null, leverMode: null };
14262
- }
14263
- }
14401
+ function readLevers(account) {
14264
14402
  if (!account) return { leverModel: null, leverEffort: null, leverMode: null };
14265
14403
  const model = account.config.adminModel;
14266
14404
  const effort = account.config.effort;
@@ -14285,10 +14423,10 @@ function latestAdminWebchatSessionId(requesterUserId, primaryUserId, scopeAccoun
14285
14423
  const cfg = claudeConfigDir();
14286
14424
  if (!cfg) return null;
14287
14425
  let best = null;
14288
- for (const { path: path3, isSubagent, archived } of enumerateJsonls(join25(cfg, "projects"))) {
14426
+ for (const { path: path3, isSubagent, archived } of enumerateJsonls(join26(cfg, "projects"))) {
14289
14427
  if (isSubagent || archived) continue;
14290
14428
  const id = basename8(path3).slice(0, -".jsonl".length);
14291
- const meta = readSidecarMeta(join25(dirname9(path3), `${id}.meta.json`));
14429
+ const meta = readSidecarMeta(join26(dirname9(path3), `${id}.meta.json`));
14292
14430
  if (meta.role !== "admin" || meta.channel !== "webchat") continue;
14293
14431
  if (multiAccount && meta.accountId !== scopeAccountId) continue;
14294
14432
  let mtimeMs;
@@ -14526,12 +14664,7 @@ ${note}` : note;
14526
14664
  const sendId = sendIdFromResolve ?? ++sendSeq;
14527
14665
  let turnSessionId = deliverySessionId;
14528
14666
  if (turnSessionId === void 0) {
14529
- let canonAccount;
14530
- try {
14531
- canonAccount = resolveAccount();
14532
- } catch {
14533
- canonAccount = null;
14534
- }
14667
+ const canonAccount = scopeAccountId ? validateAccountId2(scopeAccountId) : null;
14535
14668
  turnSessionId = resolveCanonical(accountId, canonAccount?.accountDir ?? null, requesterUserId, primaryUserId, scopeAccountId, multiAccount).sessionId;
14536
14669
  }
14537
14670
  const keyDisplay2 = deliveryKey.startsWith("session:") ? deliveryKey.slice(0, "session:".length + 8) : WEBCHAT_ADMIN_KEY;
@@ -14591,17 +14724,13 @@ ${note}` : note;
14591
14724
  console.error(`[webchat:settings] op=${op} outcome=refused value=${JSON.stringify(value)} reason=invalid-value`);
14592
14725
  return c.json({ error: `invalid ${op} value` }, 400);
14593
14726
  }
14594
- let account;
14595
- try {
14596
- account = resolveAccount();
14597
- } catch {
14598
- account = null;
14599
- }
14727
+ const cacheKey = c.get("cacheKey");
14728
+ const account = cacheKey ? accountDirForSession(cacheKey) : null;
14600
14729
  if (!account) {
14601
- console.error(`[webchat:settings] op=${op} outcome=refused value=${value} reason=account-unresolved`);
14730
+ console.error(`[webchat:settings] op=${op} outcome=refused value=${value} accountId=none reason=no-account-for-session`);
14602
14731
  return c.json({ error: "account unresolved" }, 503);
14603
14732
  }
14604
- const accountJsonPath = join25(account.accountDir, "account.json");
14733
+ const accountJsonPath = join26(account.accountDir, "account.json");
14605
14734
  try {
14606
14735
  const parsed = JSON.parse(readFileSync25(accountJsonPath, "utf8"));
14607
14736
  if (op === "model") parsed.adminModel = value;
@@ -14616,7 +14745,7 @@ ${note}` : note;
14616
14745
  return c.json({ error: "persist failed" }, 500);
14617
14746
  }
14618
14747
  const settingsApplied = await reapplyLeversViaManager();
14619
- console.log(`[webchat:settings] op=${op} outcome=accepted value=${value} settingsApplied=${settingsApplied}`);
14748
+ console.log(`[webchat:settings] op=${op} outcome=accepted accountId=${account.accountId.slice(0, 8)} value=${value} settingsApplied=${settingsApplied}`);
14620
14749
  return c.json({ ok: true, settingsApplied });
14621
14750
  });
14622
14751
  app70.get("/session", requireAdminSession, async (c) => {
@@ -14649,7 +14778,7 @@ ${note}` : note;
14649
14778
  const cfg2 = claudeConfigDir();
14650
14779
  if (cfg2) {
14651
14780
  const source2 = resolveBridgeSource(
14652
- join25(cfg2, "sessions"),
14781
+ join26(cfg2, "sessions"),
14653
14782
  target,
14654
14783
  (id) => locateSession(id).projectDir !== null
14655
14784
  );
@@ -14662,14 +14791,9 @@ ${note}` : note;
14662
14791
  }
14663
14792
  const known = resolvedProjectDir !== null || sessionSidecarExists(target);
14664
14793
  const indicators2 = await fetchComposerIndicators(target);
14665
- return c.json({ sessionId: target, projectDir: resolvedProjectDir, transcriptSessionId, channelBinding: conflictingBinding(channel), known, sizeBytes: jsonlSizeBytes(projectDir2, target), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${target}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${target}`) ?? null, ...indicators2, ...readLevers() });
14666
- }
14667
- let account;
14668
- try {
14669
- account = resolveAccount();
14670
- } catch {
14671
- account = null;
14794
+ return c.json({ sessionId: target, projectDir: resolvedProjectDir, transcriptSessionId, channelBinding: conflictingBinding(channel), known, sizeBytes: jsonlSizeBytes(projectDir2, target), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${target}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${target}`) ?? null, ...indicators2, ...readLevers(scopeAccountId ? validateAccountId2(scopeAccountId) : null) });
14672
14795
  }
14796
+ const account = scopeAccountId ? validateAccountId2(scopeAccountId) : null;
14673
14797
  const { sessionId, source } = resolveCanonical(accountId, account?.accountDir ?? null, requesterUserId, primaryUserId, scopeAccountId, multiAccount);
14674
14798
  if (requesterUserId === null) {
14675
14799
  console.error(`[webchat:inbound] op=session-resolve-no-identity key=${sessionId.slice(0, 8)}`);
@@ -14681,7 +14805,7 @@ ${note}` : note;
14681
14805
  const cfg = claudeConfigDir();
14682
14806
  let projectDir = null;
14683
14807
  if (cfg) {
14684
- for (const { path: path3 } of enumerateJsonls(join25(cfg, "projects"))) {
14808
+ for (const { path: path3 } of enumerateJsonls(join26(cfg, "projects"))) {
14685
14809
  if (basename8(path3) === `${sessionId}.jsonl`) {
14686
14810
  projectDir = dirname9(path3);
14687
14811
  break;
@@ -14689,7 +14813,7 @@ ${note}` : note;
14689
14813
  }
14690
14814
  }
14691
14815
  if (source === "latest" && requesterUserId !== null) {
14692
- const owner = readSidecarMeta(join25(projectDir ?? "", `${sessionId}.meta.json`)).adminUserId;
14816
+ const owner = readSidecarMeta(join26(projectDir ?? "", `${sessionId}.meta.json`)).adminUserId;
14693
14817
  if (owner !== null && owner !== requesterUserId && requesterUserId !== primaryUserId) {
14694
14818
  console.error(`[webchat:inbound] op=session-resolve-foreign key=${sessionId.slice(0, 8)} owner=${owner.slice(0, 8)} requester=${requesterUserId.slice(0, 8)}`);
14695
14819
  }
@@ -14722,7 +14846,7 @@ import { resolve as resolve19 } from "path";
14722
14846
 
14723
14847
  // app/lib/claude-agent/specialist-roster.ts
14724
14848
  import { existsSync as existsSync20, readFileSync as readFileSync26, readdirSync as readdirSync18 } from "fs";
14725
- import { join as join26 } from "path";
14849
+ import { join as join27 } from "path";
14726
14850
  function field(fm, name) {
14727
14851
  const m = fm.match(new RegExp(`^${name}:\\s*(.*?)\\r?$`, "m"));
14728
14852
  if (!m) return null;
@@ -14741,7 +14865,7 @@ function readSpecialistRoster(specialistsDir) {
14741
14865
  if (!file.endsWith(".md")) continue;
14742
14866
  let raw;
14743
14867
  try {
14744
- raw = readFileSync26(join26(specialistsDir, file), "utf-8");
14868
+ raw = readFileSync26(join27(specialistsDir, file), "utf-8");
14745
14869
  } catch (err) {
14746
14870
  skipped.push({ file, reason: err instanceof Error ? err.message : String(err) });
14747
14871
  continue;
@@ -14858,7 +14982,7 @@ var webchat_greeting_default = app7;
14858
14982
 
14859
14983
  // server/routes/telegram.ts
14860
14984
  import { homedir as homedir2 } from "os";
14861
- import { resolve as resolve20, join as join27 } from "path";
14985
+ import { resolve as resolve20, join as join28 } from "path";
14862
14986
  import { existsSync as existsSync21, readFileSync as readFileSync27 } from "fs";
14863
14987
 
14864
14988
  // app/lib/telegram/gateway/instance.ts
@@ -14918,7 +15042,7 @@ function routeTelegramUpdate(input) {
14918
15042
  var TAG30 = "[telegram-inbound]";
14919
15043
  function configDirName() {
14920
15044
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
14921
- const brandPath = join27(platformRoot5, "config", "brand.json");
15045
+ const brandPath = join28(platformRoot5, "config", "brand.json");
14922
15046
  if (existsSync21(brandPath)) {
14923
15047
  try {
14924
15048
  return JSON.parse(readFileSync27(brandPath, "utf-8")).configDir ?? ".maxy";
@@ -15007,16 +15131,16 @@ app8.post("/", async (c) => {
15007
15131
  var telegram_default = app8;
15008
15132
 
15009
15133
  // server/routes/quickbooks.ts
15010
- import { join as join28 } from "path";
15134
+ import { join as join29 } from "path";
15011
15135
  import { existsSync as existsSync22, readFileSync as readFileSync28, writeFileSync as writeFileSync10, mkdirSync as mkdirSync5, rmSync, renameSync as renameSync5 } from "fs";
15012
15136
  var TAG31 = "[quickbooks]";
15013
15137
  var INTUIT_TOKEN_URL = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer";
15014
15138
  var STATE_RE = /^[A-Za-z0-9_-]+$/;
15015
15139
  function pendingPath(accountDir, state) {
15016
- return join28(accountDir, "secrets", "quickbooks-pending", `${state}.json`);
15140
+ return join29(accountDir, "secrets", "quickbooks-pending", `${state}.json`);
15017
15141
  }
15018
15142
  function storePath(accountDir) {
15019
- return join28(accountDir, "secrets", "quickbooks.json");
15143
+ return join29(accountDir, "secrets", "quickbooks.json");
15020
15144
  }
15021
15145
  async function completeConsent(args) {
15022
15146
  const { accountDir, code, realmId } = args;
@@ -15083,7 +15207,7 @@ async function completeConsent(args) {
15083
15207
  refreshTokenExpiry: now + (body.x_refresh_token_expires_in ?? 864e4) * 1e3,
15084
15208
  lastRefresh: now
15085
15209
  };
15086
- mkdirSync5(join28(accountDir, "secrets"), { recursive: true });
15210
+ mkdirSync5(join29(accountDir, "secrets"), { recursive: true });
15087
15211
  writeFileSync10(storePath(accountDir), JSON.stringify(store2, null, 2), { mode: 384 });
15088
15212
  const persisted = JSON.parse(readFileSync28(storePath(accountDir), "utf-8")).connections?.[realmId]?.refreshToken === body.refresh_token;
15089
15213
  console.error(`${TAG31} op=token-exchange realmId=${realmId} persisted=${persisted}`);
@@ -15125,7 +15249,7 @@ function claudeBin() {
15125
15249
  }
15126
15250
 
15127
15251
  // server/routes/onboarding.ts
15128
- import { dirname as dirname11, join as join30 } from "path";
15252
+ import { dirname as dirname11, join as join31 } from "path";
15129
15253
 
15130
15254
  // app/lib/claude-keychain.ts
15131
15255
  import { execFileSync as execFileSync3 } from "child_process";
@@ -15255,7 +15379,7 @@ function readHostCredsBlob(service) {
15255
15379
 
15256
15380
  // ../lib/admins-write/src/index.ts
15257
15381
  import { existsSync as existsSync23, readFileSync as readFileSync29, writeFileSync as writeFileSync11, renameSync as renameSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync19, statSync as statSync11, appendFileSync as appendFileSync3 } from "fs";
15258
- import { dirname as dirname10, join as join29 } from "path";
15382
+ import { dirname as dirname10, join as join30 } from "path";
15259
15383
  function id8(value) {
15260
15384
  return value.slice(0, 8);
15261
15385
  }
@@ -15328,7 +15452,7 @@ function writeAdminEntry(input) {
15328
15452
  return result;
15329
15453
  }
15330
15454
  try {
15331
- const accountJsonPath = join29(input.accountDir, "account.json");
15455
+ const accountJsonPath = join30(input.accountDir, "account.json");
15332
15456
  if (!existsSync23(accountJsonPath)) {
15333
15457
  throw new Error(`account.json not found at ${accountJsonPath}`);
15334
15458
  }
@@ -15376,13 +15500,13 @@ function computeAdminStoreDivergence(input) {
15376
15500
  }
15377
15501
  for (const entry of entries2) {
15378
15502
  if (entry.startsWith(".")) continue;
15379
- const accountDir = join29(input.accountsDir, entry);
15503
+ const accountDir = join30(input.accountsDir, entry);
15380
15504
  try {
15381
15505
  if (!statSync11(accountDir).isDirectory()) continue;
15382
15506
  } catch {
15383
15507
  continue;
15384
15508
  }
15385
- const accountJsonPath = join29(accountDir, "account.json");
15509
+ const accountJsonPath = join30(accountDir, "account.json");
15386
15510
  if (!existsSync23(accountJsonPath)) continue;
15387
15511
  let admins = [];
15388
15512
  try {
@@ -15560,7 +15684,7 @@ app10.post("/claude-auth", async (c) => {
15560
15684
  });
15561
15685
  persistKeychainService(
15562
15686
  writebackResult,
15563
- (service) => writeFileSync12(join30(dirname11(CLAUDE_CREDENTIALS_FILE), ".keychain-service"), service, { mode: 384 }),
15687
+ (service) => writeFileSync12(join31(dirname11(CLAUDE_CREDENTIALS_FILE), ".keychain-service"), service, { mode: 384 }),
15564
15688
  (line) => console.log(line)
15565
15689
  );
15566
15690
  if (darwinAuthChild === claudeProc2) darwinAuthChild = null;
@@ -15826,8 +15950,8 @@ var onboarding_default = app10;
15826
15950
 
15827
15951
  // server/routes/client-error.ts
15828
15952
  import { appendFileSync as appendFileSync4, existsSync as existsSync25, renameSync as renameSync8, statSync as statSync12 } from "fs";
15829
- import { join as join31 } from "path";
15830
- var CLIENT_ERRORS_LOG = join31(LOG_DIR, "client-errors.log");
15953
+ import { join as join32 } from "path";
15954
+ var CLIENT_ERRORS_LOG = join32(LOG_DIR, "client-errors.log");
15831
15955
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
15832
15956
  var MAX_BODY_SIZE = 8 * 1024;
15833
15957
  var MAX_STACK_LEN = 2e3;
@@ -15971,7 +16095,7 @@ app11.post("/", async (c) => {
15971
16095
  const safe = typeof v === "string" ? truncate(v, 200) : typeof v === "number" || typeof v === "boolean" ? String(v) : JSON.stringify(v).slice(0, 200);
15972
16096
  return `${k}=${safe}`;
15973
16097
  }).join(" ");
15974
- const TAGGED_PREFIX_SOURCES = /* @__PURE__ */ new Set(["stream-log-click", "pwa", "graph-settle"]);
16098
+ const TAGGED_PREFIX_SOURCES = /* @__PURE__ */ new Set(["stream-log-click", "pwa", "graph-settle", "dashboard-load"]);
15975
16099
  if (TAGGED_PREFIX_SOURCES.has(source)) {
15976
16100
  console.log(
15977
16101
  `[${source}] ts=${ts} ip=${ip} version=${version || "unknown"}${extra ? " " + extra : ""}`
@@ -16026,7 +16150,7 @@ async function resolveUserIdentity(accountId, userId) {
16026
16150
  return { userName, avatar: null };
16027
16151
  }
16028
16152
  async function createAdminSession(accountId, thinkingView, userId, userName, role, avatar) {
16029
- const account = resolveAccount();
16153
+ const account = validateAccountId2(accountId);
16030
16154
  const effectiveThinkingView = thinkingView ?? account?.config.thinkingView ?? "default";
16031
16155
  const signedSessionToken = randomUUID9();
16032
16156
  const cacheKey = fingerprintSessionKey(signedSessionToken);
@@ -16102,11 +16226,11 @@ app12.get("/", async (c) => {
16102
16226
  if (!accountId) {
16103
16227
  return c.json({ error: "Session has no account binding" }, 401);
16104
16228
  }
16105
- const account = resolveAccount();
16229
+ const account = validateAccountId2(accountId);
16106
16230
  const thinkingView = account?.config.thinkingView ?? "default";
16107
16231
  const businessName = await fetchAccountName(accountId) || void 0;
16108
16232
  const role = getRoleForSession(cacheKey);
16109
- console.log(`[admin-session] role=${role ?? "null"} cacheKey=${cacheKey.slice(0, 8)} phase=restore`);
16233
+ console.log(`[admin-session] role=${role ?? "null"} accountId=${accountId.slice(0, 8)} cacheKey=${cacheKey.slice(0, 8)} phase=restore`);
16110
16234
  const restoredUserId = getUserIdForSession(cacheKey);
16111
16235
  let restoredUserName = getUserNameForSession(cacheKey);
16112
16236
  let restoredAvatar = null;
@@ -16216,12 +16340,12 @@ import { resolve as resolve21, basename as basename9 } from "path";
16216
16340
 
16217
16341
  // app/lib/logs-read-resolve.ts
16218
16342
  import { existsSync as existsSync26 } from "fs";
16219
- import { join as join32 } from "path";
16343
+ import { join as join33 } from "path";
16220
16344
  function resolveSessionLogPaths(filename, logDirs) {
16221
16345
  const tried = [filename];
16222
16346
  const hits = [];
16223
16347
  for (const dir of logDirs) {
16224
- const fullPath = join32(dir, filename);
16348
+ const fullPath = join33(dir, filename);
16225
16349
  if (existsSync26(fullPath)) {
16226
16350
  hits.push({ path: fullPath, dir });
16227
16351
  }
@@ -16238,10 +16362,7 @@ app14.get("/", async (c) => {
16238
16362
  const sessionIdParam = c.req.query("sessionId");
16239
16363
  const cacheKeyParam = c.req.query("cacheKey");
16240
16364
  const download = c.req.query("download") === "1";
16241
- const account = resolveAccount();
16242
- const accountLogDir = account ? resolve21(account.accountDir, "logs") : null;
16243
- const logDirs = [];
16244
- if (accountLogDir) logDirs.push(accountLogDir);
16365
+ const logDirs = listValidAccounts().slice().sort((a, b) => a.accountId.localeCompare(b.accountId)).map((a) => resolve21(a.accountDir, "logs"));
16245
16366
  logDirs.push(LOG_DIR);
16246
16367
  if (fileParam) {
16247
16368
  const safe = basename9(fileParam);
@@ -16257,7 +16378,7 @@ app14.get("/", async (c) => {
16257
16378
  "Content-Length": String(buffer.byteLength)
16258
16379
  };
16259
16380
  if (download) headers["Content-Disposition"] = `attachment; filename="${safe}"`;
16260
- console.info(`[stream-log-download] file=${safe} bytesServed=${buffer.byteLength} onDiskBytes=${onDiskBytes}`);
16381
+ console.info(`[stream-log-download] file=${safe} dir=${dir} bytesServed=${buffer.byteLength} onDiskBytes=${onDiskBytes}`);
16261
16382
  return new Response(buffer, { headers });
16262
16383
  } catch (err) {
16263
16384
  const reason = err instanceof Error ? err.message : String(err);
@@ -16322,7 +16443,7 @@ app14.get("/", async (c) => {
16322
16443
  "Content-Length": String(buffer.byteLength)
16323
16444
  };
16324
16445
  if (download) headers["Content-Disposition"] = `attachment; filename="${filename}"`;
16325
- console.info(`[stream-log-download] file=${filename} bytesServed=${buffer.byteLength} onDiskBytes=${onDiskBytes}`);
16446
+ console.info(`[stream-log-download] file=${filename} dir=${hit.dir} bytesServed=${buffer.byteLength} onDiskBytes=${onDiskBytes}`);
16326
16447
  return new Response(buffer, { headers });
16327
16448
  } catch (err) {
16328
16449
  const reason2 = err instanceof Error ? err.message : String(err);
@@ -16379,7 +16500,12 @@ var logs_default = app14;
16379
16500
  // server/routes/admin/claude-info.ts
16380
16501
  import { execFileSync as execFileSync5 } from "child_process";
16381
16502
  var app15 = new Hono();
16382
- app15.get("/", (c) => {
16503
+ app15.get("/", requireAdminSession, (c) => {
16504
+ const account = accountDirForSession(c.var.cacheKey);
16505
+ if (!account) {
16506
+ console.error("[admin/claude-info] auth-rejected reason=no-account-for-session accountId=none");
16507
+ return c.json({ error: "no account for session", reason: "no-account-for-session" }, 401);
16508
+ }
16383
16509
  const claudeEnv = { ...process.env };
16384
16510
  let version = "unknown";
16385
16511
  try {
@@ -16387,21 +16513,21 @@ app15.get("/", (c) => {
16387
16513
  version = raw.trim().replace(" (Claude Code)", "");
16388
16514
  } catch {
16389
16515
  }
16390
- let account = {};
16516
+ let claudeAccount = {};
16391
16517
  try {
16392
16518
  const raw = execFileSync5(claudeBin(), ["auth", "status"], { env: claudeEnv, encoding: "utf-8", timeout: 5e3 });
16393
- account = JSON.parse(raw);
16519
+ claudeAccount = JSON.parse(raw);
16394
16520
  } catch {
16395
16521
  }
16396
- const resolvedAccount = resolveAccount();
16397
- const model = resolvedAccount?.config.adminModel ?? "unknown";
16398
- const thinkingView = resolvedAccount?.config.thinkingView ?? "default";
16399
- return c.json({ version, account, model, thinkingView });
16522
+ const model = account.config.adminModel ?? "unknown";
16523
+ const thinkingView = account.config.thinkingView ?? "default";
16524
+ console.log(`[admin/claude-info] op=read accountId=${account.accountId.slice(0, 8)} model=${model}`);
16525
+ return c.json({ version, account: claudeAccount, model, thinkingView });
16400
16526
  });
16401
16527
  var claude_info_default = app15;
16402
16528
 
16403
16529
  // server/routes/admin/attachment.ts
16404
- import { readFile as readFile4, readdir as readdir2 } from "fs/promises";
16530
+ import { readFile as readFile5, readdir as readdir2 } from "fs/promises";
16405
16531
  import { existsSync as existsSync28 } from "fs";
16406
16532
  import { resolve as resolve22 } from "path";
16407
16533
  var app16 = new Hono();
@@ -16450,7 +16576,7 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
16450
16576
  }
16451
16577
  let meta;
16452
16578
  try {
16453
- meta = JSON.parse(await readFile4(metaPath, "utf-8"));
16579
+ meta = JSON.parse(await readFile5(metaPath, "utf-8"));
16454
16580
  } catch {
16455
16581
  return new Response("Not found", { status: 404 });
16456
16582
  }
@@ -16460,7 +16586,7 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
16460
16586
  return new Response("Not found", { status: 404 });
16461
16587
  }
16462
16588
  const filePath = resolve22(dir, dataFile);
16463
- const buffer = await readFile4(filePath);
16589
+ const buffer = await readFile5(filePath);
16464
16590
  const inlineSafe = isInlineSafeMime(meta.mimeType);
16465
16591
  const safeName = meta.filename.replace(/["\\\r\n]/g, "_");
16466
16592
  if (!inlineSafe) {
@@ -16478,7 +16604,7 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
16478
16604
  var attachment_default = app16;
16479
16605
 
16480
16606
  // server/routes/admin/session-upload.ts
16481
- import { readFile as readFile5 } from "fs/promises";
16607
+ import { readFile as readFile6 } from "fs/promises";
16482
16608
  import { existsSync as existsSync29, statSync as statSync14 } from "fs";
16483
16609
  var app17 = new Hono();
16484
16610
  app17.get("/", requireAdminSession, async (c) => {
@@ -16508,7 +16634,7 @@ app17.get("/", requireAdminSession, async (c) => {
16508
16634
  const inlineSafe = isInlineSafeMime(mimeType);
16509
16635
  const safeName = file.replace(/["\\\r\n]/g, "_");
16510
16636
  console.log(`[session-upload] op=served session=${short2} file=${file} disposition=${inlineSafe ? "inline" : "attachment"} mime=${mimeType}`);
16511
- const buffer = await readFile5(resolution.absolute);
16637
+ const buffer = await readFile6(resolution.absolute);
16512
16638
  return new Response(new Uint8Array(buffer), {
16513
16639
  headers: {
16514
16640
  "Content-Type": mimeType,
@@ -16524,35 +16650,10 @@ var session_upload_default = app17;
16524
16650
  import { resolve as resolve23 } from "path";
16525
16651
  import { readdirSync as readdirSync22, readFileSync as readFileSync33, existsSync as existsSync31, rmSync as rmSync2, renameSync as renameSync9, mkdirSync as mkdirSync7, writeFileSync as writeFileSync13 } from "fs";
16526
16652
 
16527
- // server/routes/admin/_account-scope.ts
16528
- function accountDirForSession(cacheKey) {
16529
- const accountId = getAccountIdForSession(cacheKey);
16530
- if (!accountId) return null;
16531
- const match = listValidAccounts().find((a) => a.accountId === accountId);
16532
- return match ? { accountId, accountDir: match.accountDir } : null;
16533
- }
16534
- function validateAccountId2(accountId) {
16535
- if (!accountId) return null;
16536
- const match = listValidAccounts().find((a) => a.accountId === accountId);
16537
- return match ? { accountId, accountDir: match.accountDir } : null;
16538
- }
16539
- async function authorizeAccountWrite(c, accountId) {
16540
- const remote = c.env?.incoming?.socket?.remoteAddress ?? "";
16541
- const peerIsLoopback = remote === "127.0.0.1" || remote === "::1" || remote === "::ffff:127.0.0.1";
16542
- if (peerIsLoopback && !c.req.header("x-forwarded-for")) return { ok: true, via: "on-device" };
16543
- const { fingerprint, signedSessionToken } = await resolveCacheKey(c);
16544
- if (!fingerprint || !validateSession(fingerprint, "admin", signedSessionToken).ok) {
16545
- return { ok: false, reason: "no-session" };
16546
- }
16547
- const acct = accountDirForSession(fingerprint);
16548
- if (!acct || acct.accountId !== accountId) return { ok: false, reason: "account-mismatch" };
16549
- return { ok: true, via: "session" };
16550
- }
16551
-
16552
16653
  // ../services/claude-session-manager/src/tool-surface.ts
16553
16654
  import { readFileSync as readFileSync32, readdirSync as readdirSync21, statSync as statSync15, existsSync as existsSync30 } from "fs";
16554
16655
  import { createHash as createHash5 } from "crypto";
16555
- import { join as join33 } from "path";
16656
+ import { join as join34 } from "path";
16556
16657
 
16557
16658
  // ../services/claude-session-manager/src/canonical-tool-names.ts
16558
16659
  function canonicalToolName(plugin, tool) {
@@ -16805,13 +16906,13 @@ function loadToolSurface(pluginsRoots) {
16805
16906
  const riskByTool = /* @__PURE__ */ new Map();
16806
16907
  const manifestPaths = /* @__PURE__ */ new Map();
16807
16908
  const loadOne = (pluginsRoot, plugin) => {
16808
- const pluginDir = join33(pluginsRoot, plugin);
16909
+ const pluginDir = join34(pluginsRoot, plugin);
16809
16910
  try {
16810
16911
  if (!statSync15(pluginDir).isDirectory()) return;
16811
16912
  } catch {
16812
16913
  return;
16813
16914
  }
16814
- const manifestPath = join33(pluginDir, "PLUGIN.md");
16915
+ const manifestPath = join34(pluginDir, "PLUGIN.md");
16815
16916
  if (!existsSync30(manifestPath)) return;
16816
16917
  const raw = readFileSync32(manifestPath, "utf-8");
16817
16918
  const frontmatter = extractFrontmatter(raw, plugin);
@@ -16857,9 +16958,9 @@ function loadToolSurface(pluginsRoots) {
16857
16958
  for (const root of roots) {
16858
16959
  const entries2 = readdirSync21(root).sort();
16859
16960
  for (const plugin of entries2) {
16860
- const pluginDir = join33(root, plugin);
16961
+ const pluginDir = join34(root, plugin);
16861
16962
  loadOne(root, plugin);
16862
- const subRoot = join33(pluginDir, "plugins");
16963
+ const subRoot = join34(pluginDir, "plugins");
16863
16964
  let subEntries;
16864
16965
  try {
16865
16966
  if (!statSync15(subRoot).isDirectory()) continue;
@@ -16905,7 +17006,7 @@ function agentRiskClass(tools, riskByTool) {
16905
17006
  const byTool = [];
16906
17007
  const unresolved = [];
16907
17008
  let worst = null;
16908
- let worstTool = null;
17009
+ let riskiestTool = null;
16909
17010
  for (const tool of tools) {
16910
17011
  const cls = BUILTIN_TOOL_RISK[tool] ?? riskByTool.get(tool) ?? null;
16911
17012
  byTool.push({ tool, risk: cls });
@@ -16915,16 +17016,16 @@ function agentRiskClass(tools, riskByTool) {
16915
17016
  }
16916
17017
  if (worst === null || SEVERITY[cls] > SEVERITY[worst]) {
16917
17018
  worst = cls;
16918
- worstTool = tool;
17019
+ riskiestTool = tool;
16919
17020
  }
16920
17021
  }
16921
17022
  if (unresolved.length > 0) {
16922
- return { risk: "red", worstTool: unresolved[0], unresolved, byTool };
17023
+ return { risk: "red", riskiestTool: unresolved[0], unresolved, byTool };
16923
17024
  }
16924
17025
  if (worst === null) {
16925
- return { risk: "red", worstTool: null, unresolved, byTool };
17026
+ return { risk: "red", riskiestTool: null, unresolved, byTool };
16926
17027
  }
16927
- return { risk: AGENT_CLASS[worst], worstTool, unresolved, byTool };
17028
+ return { risk: AGENT_CLASS[worst], riskiestTool, unresolved, byTool };
16928
17029
  }
16929
17030
 
16930
17031
  // server/routes/admin/agents.ts
@@ -17024,7 +17125,7 @@ function listShipped(accountDir, riskByTool, disabled, riskSurfaceFailed) {
17024
17125
  plugin: "",
17025
17126
  description: fm.description ?? "",
17026
17127
  risk: r.risk,
17027
- worstTool: r.worstTool,
17128
+ riskiestTool: r.riskiestTool,
17028
17129
  unresolved: r.unresolved,
17029
17130
  toolCount: tools.length,
17030
17131
  // The DIRECTORY is the ground truth, not the store. `spawn-context.ts`
@@ -17046,7 +17147,7 @@ function parseToolsLine(raw) {
17046
17147
  }
17047
17148
  function classify(tools, riskByTool, riskSurfaceFailed) {
17048
17149
  if (riskSurfaceFailed) {
17049
- return { risk: "red", worstTool: null, unresolved: [], byTool: tools.map((t) => ({ tool: t, risk: null })) };
17150
+ return { risk: "red", riskiestTool: null, unresolved: [], byTool: tools.map((t) => ({ tool: t, risk: null })) };
17050
17151
  }
17051
17152
  return agentRiskClass(tools, riskByTool);
17052
17153
  }
@@ -17082,7 +17183,7 @@ function listSpecialists(accountDir, riskByTool, riskSurfaceFailed) {
17082
17183
  plugin,
17083
17184
  description: fm.description ?? "",
17084
17185
  risk: r.risk,
17085
- worstTool: r.worstTool,
17186
+ riskiestTool: r.riskiestTool,
17086
17187
  unresolved: r.unresolved,
17087
17188
  toolCount: specialistTools.length,
17088
17189
  // A user-created specialist lives under the account plugins tree,
@@ -17133,7 +17234,7 @@ app18.get("/", requireAdminSession, (c) => {
17133
17234
  kind: "public",
17134
17235
  origin: "public",
17135
17236
  risk: null,
17136
- worstTool: null,
17237
+ riskiestTool: null,
17137
17238
  unresolved: [],
17138
17239
  disabled: false
17139
17240
  });
@@ -17153,7 +17254,7 @@ app18.get("/", requireAdminSession, (c) => {
17153
17254
  for (const row of rows) {
17154
17255
  if (row.risk === null) continue;
17155
17256
  console.log(
17156
- `[admin/agents] op=classify account=${acct} agent=${row.slug} origin=${row.origin} risk=${row.risk} worstTool=${row.worstTool ?? "none"} tools=${row.toolCount} unresolved=${row.unresolved.length > 0 ? row.unresolved.join(",") : "none"} disabled=${row.disabled}`
17257
+ `[admin/agents] op=classify account=${acct} agent=${row.slug} origin=${row.origin} risk=${row.risk} riskiestTool=${row.riskiestTool ?? "none"} tools=${row.toolCount} unresolved=${row.unresolved.length > 0 ? row.unresolved.join(",") : "none"} disabled=${row.disabled}`
17157
17258
  );
17158
17259
  }
17159
17260
  console.log(`[admin/agents] op=list accountId=${acct} agents=${agents.length} specialists=${specialists.length} shipped=${shipped.length} skipped=${skipped} specialistsSkipped=${specialistsSkipped} shippedSkipped=${shippedSkipped}`);
@@ -17196,7 +17297,7 @@ app18.get("/:slug", requireAdminSession, (c) => {
17196
17297
  systemPrompt: body.trim(),
17197
17298
  skills: [],
17198
17299
  risk: r.risk,
17199
- worstTool: r.worstTool,
17300
+ riskiestTool: r.riskiestTool,
17200
17301
  unresolved: r.unresolved,
17201
17302
  byTool: r.byTool,
17202
17303
  disabled: readDisabledStore(account.accountDir).has(`${slug}.md`)
@@ -17227,7 +17328,7 @@ app18.get("/:slug", requireAdminSession, (c) => {
17227
17328
  systemPrompt: body.trim(),
17228
17329
  skills,
17229
17330
  risk: r.risk,
17230
- worstTool: r.worstTool,
17331
+ riskiestTool: r.riskiestTool,
17231
17332
  unresolved: r.unresolved,
17232
17333
  byTool: r.byTool,
17233
17334
  disabled: false
@@ -18127,7 +18228,7 @@ var sessions_default = app19;
18127
18228
 
18128
18229
  // app/lib/claude-agent/spawn-context.ts
18129
18230
  import { existsSync as existsSync33, readFileSync as readFileSync34, readdirSync as readdirSync23, statSync as statSync16 } from "fs";
18130
- import { dirname as dirname12, resolve as resolve24, join as join34 } from "path";
18231
+ import { dirname as dirname12, resolve as resolve24, join as join35 } from "path";
18131
18232
  async function resolveOwnerProfileBlock(accountId, userId) {
18132
18233
  if (!userId) return { ok: false, reason: "missing-user-id" };
18133
18234
  try {
@@ -18168,8 +18269,8 @@ function frontmatterField(manifest, field2) {
18168
18269
  function extractPluginToolDescriptions(pluginDir) {
18169
18270
  const out = /* @__PURE__ */ new Map();
18170
18271
  const candidates = [
18171
- join34(pluginDir, "mcp/dist/index.js"),
18172
- join34(pluginDir, "mcp/src/index.ts")
18272
+ join35(pluginDir, "mcp/dist/index.js"),
18273
+ join35(pluginDir, "mcp/src/index.ts")
18173
18274
  ];
18174
18275
  let raw = null;
18175
18276
  for (const path3 of candidates) {
@@ -18227,7 +18328,7 @@ function listPluginDirs(accountPluginsDir) {
18227
18328
  const platformPlugins = resolve24(PLATFORM_ROOT, "plugins");
18228
18329
  if (existsSync33(platformPlugins)) {
18229
18330
  for (const name of readdirSync23(platformPlugins)) {
18230
- const dir = join34(platformPlugins, name);
18331
+ const dir = join35(platformPlugins, name);
18231
18332
  try {
18232
18333
  if (statSync16(dir).isDirectory()) out.set(name, dir);
18233
18334
  } catch {
@@ -18237,11 +18338,11 @@ function listPluginDirs(accountPluginsDir) {
18237
18338
  const premiumRoot = resolve24(dirname12(PLATFORM_ROOT), "premium-plugins");
18238
18339
  if (existsSync33(premiumRoot)) {
18239
18340
  for (const bundle of readdirSync23(premiumRoot)) {
18240
- const bundlePlugins = join34(premiumRoot, bundle, "plugins");
18341
+ const bundlePlugins = join35(premiumRoot, bundle, "plugins");
18241
18342
  if (!existsSync33(bundlePlugins)) continue;
18242
18343
  try {
18243
18344
  for (const name of readdirSync23(bundlePlugins)) {
18244
- const dir = join34(bundlePlugins, name);
18345
+ const dir = join35(bundlePlugins, name);
18245
18346
  try {
18246
18347
  if (statSync16(dir).isDirectory()) out.set(name, dir);
18247
18348
  } catch {
@@ -18255,7 +18356,7 @@ function listPluginDirs(accountPluginsDir) {
18255
18356
  try {
18256
18357
  for (const name of readdirSync23(accountPluginsDir)) {
18257
18358
  if (out.has(name)) continue;
18258
- const dir = join34(accountPluginsDir, name);
18359
+ const dir = join35(accountPluginsDir, name);
18259
18360
  try {
18260
18361
  if (statSync16(dir).isDirectory()) out.set(name, dir);
18261
18362
  } catch {
@@ -18274,7 +18375,7 @@ function listAccountPluginNames(accountPluginsDir) {
18274
18375
  try {
18275
18376
  return readdirSync23(accountPluginsDir).filter((name) => {
18276
18377
  try {
18277
- return statSync16(join34(accountPluginsDir, name)).isDirectory();
18378
+ return statSync16(join35(accountPluginsDir, name)).isDirectory();
18278
18379
  } catch {
18279
18380
  return false;
18280
18381
  }
@@ -18317,7 +18418,7 @@ function computeActivePlugins(accountId) {
18317
18418
  for (const name of emitNames) {
18318
18419
  const dir = pluginDirs.get(name);
18319
18420
  if (!dir) continue;
18320
- const fm = readFrontmatter(join34(dir, "PLUGIN.md"));
18421
+ const fm = readFrontmatter(join35(dir, "PLUGIN.md"));
18321
18422
  if (!fm) continue;
18322
18423
  const description = frontmatterField(`---
18323
18424
  ${fm}
@@ -18334,7 +18435,7 @@ ${fm}
18334
18435
  `plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
18335
18436
  );
18336
18437
  if (toolNames.length > 0 && descMap.size === 0) {
18337
- const hasSource = existsSync33(join34(dir, "mcp/dist/index.js")) || existsSync33(join34(dir, "mcp/src/index.ts"));
18438
+ const hasSource = existsSync33(join35(dir, "mcp/dist/index.js")) || existsSync33(join35(dir, "mcp/src/index.ts"));
18338
18439
  if (hasSource) {
18339
18440
  console.warn(
18340
18441
  `[spawn-context] WARN plugin=${name} mcp source present but tool-description regex matched zero entries \u2014 SDK upgrade may have changed the registration shape`
@@ -18344,7 +18445,7 @@ ${fm}
18344
18445
  const skillPaths = parseSkillPathsFromFrontmatter(fm);
18345
18446
  const skills = [];
18346
18447
  for (const relPath of skillPaths) {
18347
- const skillPath = join34(dir, relPath);
18448
+ const skillPath = join35(dir, relPath);
18348
18449
  const skillFm = readFrontmatter(skillPath);
18349
18450
  if (!skillFm) continue;
18350
18451
  const skillName = frontmatterField(`---
@@ -18388,7 +18489,7 @@ function computeSpecialistDomains(accountId) {
18388
18489
  const out = [];
18389
18490
  for (const file of entries2.sort()) {
18390
18491
  if (!file.endsWith(".md")) continue;
18391
- const fm = readFrontmatter(join34(specialistsDir, file));
18492
+ const fm = readFrontmatter(join35(specialistsDir, file));
18392
18493
  if (!fm) continue;
18393
18494
  const wrapped = `---
18394
18495
  ${fm}
@@ -18784,10 +18885,10 @@ var events_default = app22;
18784
18885
 
18785
18886
  // server/routes/admin/files.ts
18786
18887
  import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync35 } from "fs";
18787
- import { readdir as readdir4, readFile as readFile7, stat as stat6, mkdir as mkdir4, unlink as unlink3, rename as rename2, rmdir } from "fs/promises";
18888
+ import { readdir as readdir4, readFile as readFile8, stat as stat7, mkdir as mkdir4, unlink as unlink3, rename as rename2, rmdir } from "fs/promises";
18788
18889
  import { realpathSync as realpathSync7 } from "fs";
18789
18890
  import { randomUUID as randomUUID10 } from "crypto";
18790
- import { basename as basename11, dirname as dirname13, join as join36, relative as relative5, resolve as resolve27, sep as sep8 } from "path";
18891
+ import { basename as basename11, dirname as dirname13, join as join37, relative as relative5, resolve as resolve27, sep as sep8 } from "path";
18791
18892
  import { Readable as Readable2 } from "stream";
18792
18893
 
18793
18894
  // ../lib/graph-trash/src/index.ts
@@ -19105,7 +19206,7 @@ async function cascadeDeleteDocument(params) {
19105
19206
 
19106
19207
  // app/lib/file-index.ts
19107
19208
  import * as fsp from "fs/promises";
19108
- import { resolve as resolve26, relative as relative4, join as join35, basename as basename10, extname as extname2, sep as sep7 } from "path";
19209
+ import { resolve as resolve26, relative as relative4, join as join36, basename as basename10, extname as extname2, sep as sep7 } from "path";
19109
19210
  import { tmpdir as tmpdir2 } from "os";
19110
19211
  import { execFile as execFile2 } from "child_process";
19111
19212
  import { promisify as promisify2 } from "util";
@@ -19187,7 +19288,7 @@ async function extractPdf(absolute) {
19187
19288
  return stdout.trim();
19188
19289
  }
19189
19290
  async function ocrPdf(absolute) {
19190
- const outPdf = join35(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
19291
+ const outPdf = join36(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
19191
19292
  try {
19192
19293
  await execFileAsync2(
19193
19294
  "ocrmypdf",
@@ -19249,7 +19350,7 @@ async function readDisplayName(absolute) {
19249
19350
  const stem = dot === -1 ? base : base.slice(0, dot);
19250
19351
  if (base === `${stem}.meta.json`) return null;
19251
19352
  try {
19252
- const raw = await fsp.readFile(join35(dir, `${stem}.meta.json`), "utf-8");
19353
+ const raw = await fsp.readFile(join36(dir, `${stem}.meta.json`), "utf-8");
19253
19354
  const meta = JSON.parse(raw);
19254
19355
  const dn = meta.displayName ?? meta.filename;
19255
19356
  return typeof dn === "string" && dn.length > 0 ? dn : null;
@@ -19270,7 +19371,7 @@ async function walkSubtree(root, dataRoot, out) {
19270
19371
  for (const entry of entries2) {
19271
19372
  if (entry.isSymbolicLink()) continue;
19272
19373
  if (entry.isDirectory() && entry.name === ".uploads-tmp") continue;
19273
- const abs = join35(root, entry.name);
19374
+ const abs = join36(root, entry.name);
19274
19375
  if (entry.isDirectory()) {
19275
19376
  const sub = await walkSubtree(abs, dataRoot, out);
19276
19377
  if (!sub.clean) clean = false;
@@ -19643,7 +19744,7 @@ var UPLOAD_TMP_DIR = ".uploads-tmp";
19643
19744
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
19644
19745
  async function readMeta(absDir, baseName) {
19645
19746
  try {
19646
- const raw = await readFile7(join36(absDir, `${baseName}.meta.json`), "utf8");
19747
+ const raw = await readFile8(join37(absDir, `${baseName}.meta.json`), "utf8");
19647
19748
  const parsed = JSON.parse(raw);
19648
19749
  if (typeof parsed?.filename === "string") {
19649
19750
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -19665,7 +19766,7 @@ async function readAccountNames() {
19665
19766
  if (!UUID_RE4.test(name)) continue;
19666
19767
  const configPath2 = resolve27(accountsDir, name, "account.json");
19667
19768
  try {
19668
- const raw = await readFile7(configPath2, "utf8");
19769
+ const raw = await readFile8(configPath2, "utf8");
19669
19770
  const parsed = JSON.parse(raw);
19670
19771
  if (typeof parsed?.name === "string" && parsed.name.length > 0) {
19671
19772
  map.set(name, parsed.name);
@@ -19698,7 +19799,7 @@ async function servableFilesIn(dirAbs, uuid) {
19698
19799
  }
19699
19800
  async function enrich(absolute, entry, accountNames) {
19700
19801
  if (entry.kind === "directory" && UUID_RE4.test(entry.name)) {
19701
- const dirAbs = join36(absolute, entry.name);
19802
+ const dirAbs = join37(absolute, entry.name);
19702
19803
  const meta = await readMeta(dirAbs, entry.name);
19703
19804
  if (meta?.filename) {
19704
19805
  const servable = await servableFilesIn(dirAbs, entry.name);
@@ -19707,7 +19808,7 @@ async function enrich(absolute, entry, accountNames) {
19707
19808
  let size = null;
19708
19809
  let modifiedAt = entry.modifiedAt;
19709
19810
  try {
19710
- const st = await stat6(join36(dirAbs, innerName));
19811
+ const st = await stat7(join37(dirAbs, innerName));
19711
19812
  size = st.size;
19712
19813
  modifiedAt = st.mtime.toISOString();
19713
19814
  } catch {
@@ -19882,7 +19983,7 @@ app23.get("/", requireAdminSession, async (c) => {
19882
19983
  return c.json({ error: "Not found" }, 404);
19883
19984
  }
19884
19985
  try {
19885
- const info = await stat6(absolute);
19986
+ const info = await stat7(absolute);
19886
19987
  if (!info.isDirectory()) {
19887
19988
  return c.json({ error: "Path is not a directory \u2014 use /api/admin/files/download for files" }, 400);
19888
19989
  }
@@ -19900,8 +20001,8 @@ app23.get("/", requireAdminSession, async (c) => {
19900
20001
  const childRel = relPath === "" || relPath === "." ? name : `${relPath}/${name}`;
19901
20002
  const protectedEntry = isProtectedFromDeletion(childRel).protected;
19902
20003
  try {
19903
- const entryPath = join36(absolute, name);
19904
- const s = await stat6(entryPath);
20004
+ const entryPath = join37(absolute, name);
20005
+ const s = await stat7(entryPath);
19905
20006
  entries2.push({
19906
20007
  name,
19907
20008
  kind: s.isDirectory() ? "directory" : s.isFile() ? "file" : "other",
@@ -19929,7 +20030,7 @@ app23.get("/", requireAdminSession, async (c) => {
19929
20030
  const displayPath = buildDisplayPath(relPath, accountNames);
19930
20031
  if (groupReq || isAccountRoot(relPath)) {
19931
20032
  const acctId = relPath.split("/")[1] ?? accountId;
19932
- const schemaMd = await readFile7(join36(absolute, "SCHEMA.md"), "utf8").catch(() => null);
20033
+ const schemaMd = await readFile8(join37(absolute, "SCHEMA.md"), "utf8").catch(() => null);
19933
20034
  const groups = classifyAccountRoot(schemaMd, entries2.map((e) => e.name));
19934
20035
  console.error(
19935
20036
  `[data-schema] op=classify account=${acctId} status=${groups.parsed ? "ok" : "parse-failed"} reason=${groups.reason} entries=${entries2.length} home=${groups.home.join(",") || "none"} system=${groups.system.length} unknown=${groups.unknown.join(",") || "none"}`
@@ -19967,7 +20068,7 @@ app23.get("/", requireAdminSession, async (c) => {
19967
20068
  for (const name of homeDirs) {
19968
20069
  const base = byName.get(name);
19969
20070
  try {
19970
- const dirents = await readdir4(join36(absolute, name), { withFileTypes: true });
20071
+ const dirents = await readdir4(join37(absolute, name), { withFileTypes: true });
19971
20072
  const visible = dirents.filter((d) => !d.name.startsWith("."));
19972
20073
  visible.sort((a, b) => {
19973
20074
  const ad = a.isDirectory() ? 0 : 1;
@@ -20032,7 +20133,7 @@ app23.get("/download", requireAdminSession, async (c) => {
20032
20133
  console.error(`[data] op=scratchpad-no-session sessionId="${sessionId.slice(0, 8)}\u2026"`);
20033
20134
  return c.json({ error: "Not found" }, 404);
20034
20135
  }
20035
- const meta = readSidecarMeta(join36(projectDir, `${sessionId}.meta.json`));
20136
+ const meta = readSidecarMeta(join37(projectDir, `${sessionId}.meta.json`));
20036
20137
  if (!meta.accountId || meta.accountId !== accountId) {
20037
20138
  console.error(`[data] account-scope-blocked root="scratchpad" sessionId="${sessionId.slice(0, 8)}\u2026" account=${accountId.slice(0, 8)}\u2026`);
20038
20139
  return c.json({ error: "Not found" }, 404);
@@ -20059,7 +20160,7 @@ app23.get("/download", requireAdminSession, async (c) => {
20059
20160
  return c.json({ error: "Not found" }, 404);
20060
20161
  }
20061
20162
  try {
20062
- const info = await stat6(absolute);
20163
+ const info = await stat7(absolute);
20063
20164
  if (!info.isFile()) {
20064
20165
  return c.json({ error: "Path is not a file" }, 400);
20065
20166
  }
@@ -20127,7 +20228,7 @@ async function* walkRegularFiles(dirAbsolute) {
20127
20228
  const dirents = await readdir4(dirAbsolute, { withFileTypes: true });
20128
20229
  for (const d of dirents) {
20129
20230
  if (d.isSymbolicLink()) continue;
20130
- const child = join36(dirAbsolute, d.name);
20231
+ const child = join37(dirAbsolute, d.name);
20131
20232
  if (d.isDirectory()) {
20132
20233
  yield* walkRegularFiles(child);
20133
20234
  continue;
@@ -20156,7 +20257,7 @@ app23.get("/download-zip", requireAdminSession, async (c) => {
20156
20257
  if (entries2.length >= maxFiles) return c.json({ error: `Too many files (max ${maxFiles})` }, 413);
20157
20258
  total += size;
20158
20259
  if (total > maxTotalBytes) return c.json({ error: "Selection too large to zip" }, 413);
20159
- entries2.push({ name: member, data: await readFile7(absolute) });
20260
+ entries2.push({ name: member, data: await readFile8(absolute) });
20160
20261
  return null;
20161
20262
  };
20162
20263
  for (const rawPath of rawPaths) {
@@ -20173,7 +20274,7 @@ app23.get("/download-zip", requireAdminSession, async (c) => {
20173
20274
  return c.json({ error: "Not found" }, 404);
20174
20275
  }
20175
20276
  try {
20176
- const info = await stat6(absolute);
20277
+ const info = await stat7(absolute);
20177
20278
  if (info.isDirectory()) {
20178
20279
  dirsWalked++;
20179
20280
  const parentAbs = dirname13(absolute);
@@ -20181,7 +20282,7 @@ app23.get("/download-zip", requireAdminSession, async (c) => {
20181
20282
  const within = relative5(absolute, fileAbs).split(sep8).join("/");
20182
20283
  const fileRel = relPath === "" || relPath === "." ? within : `${relPath}/${within}`;
20183
20284
  if (crossesForeignAccountPartition(fileRel, accountId)) continue;
20184
- const fileInfo = await stat6(fileAbs);
20285
+ const fileInfo = await stat7(fileAbs);
20185
20286
  const member = relative5(parentAbs, fileAbs).split(sep8).join("/");
20186
20287
  const over = await addFile(fileAbs, fileInfo.size, member);
20187
20288
  if (over) return over;
@@ -20237,7 +20338,7 @@ async function resolveUploadTarget(c, accountId, uid) {
20237
20338
  const base = resolveOwnAccountWrite(rawDir, accountId, "POST /api/admin/files/upload");
20238
20339
  if (!base.ok) return { ok: false, status: base.status, error: base.error };
20239
20340
  const relDir = relpath ? dirname13(relpath) : ".";
20240
- const destRel = relDir === "." ? base.relative : join36(base.relative, relDir);
20341
+ const destRel = relDir === "." ? base.relative : join37(base.relative, relDir);
20241
20342
  if (crossesForeignAccountPartition(destRel, accountId)) {
20242
20343
  console.error(`[data] account-scope-blocked endpoint="POST /api/admin/files/upload" path="${destRel}" account=${accountId.slice(0, 8)}\u2026`);
20243
20344
  return { ok: false, status: 404, error: "Not found" };
@@ -20252,7 +20353,7 @@ async function resolveUploadTarget(c, accountId, uid) {
20252
20353
  const firstCreated = await mkdir4(destDir, { recursive: true });
20253
20354
  if (firstCreated) console.error(`[data-upload] op=mkdir uid=${uid} token=${token} dir="${destRel}"`);
20254
20355
  } else {
20255
- const info = await stat6(destDir).catch(() => null);
20356
+ const info = await stat7(destDir).catch(() => null);
20256
20357
  if (!info || !info.isDirectory()) return { ok: false, status: 400, error: "Upload destination is not a directory" };
20257
20358
  }
20258
20359
  const dataRootReal = realpathSync7(DATA_ROOT);
@@ -20604,7 +20705,7 @@ app23.delete("/", requireAdminSession, async (c) => {
20604
20705
  return c.json({ error: "Protected file \u2014 refusing to delete" }, 403);
20605
20706
  }
20606
20707
  try {
20607
- const info = await stat6(absolute);
20708
+ const info = await stat7(absolute);
20608
20709
  if (info.isDirectory()) {
20609
20710
  return c.json({ error: "Directory deletion not supported" }, 400);
20610
20711
  }
@@ -20614,7 +20715,7 @@ app23.delete("/", requireAdminSession, async (c) => {
20614
20715
  const dot = base.lastIndexOf(".");
20615
20716
  const stem = dot === -1 ? base : base.slice(0, dot);
20616
20717
  const containerDir = dirname13(absolute);
20617
- const sidecarPath = UUID_RE4.test(stem) && base !== `${stem}.meta.json` ? join36(containerDir, `${stem}.meta.json`) : null;
20718
+ const sidecarPath = UUID_RE4.test(stem) && base !== `${stem}.meta.json` ? join37(containerDir, `${stem}.meta.json`) : null;
20618
20719
  const isAttachmentContainer = UUID_RE4.test(stem) && basename11(containerDir) === stem;
20619
20720
  await unlink3(absolute);
20620
20721
  if (sidecarPath) {
@@ -20624,7 +20725,7 @@ app23.delete("/", requireAdminSession, async (c) => {
20624
20725
  }
20625
20726
  }
20626
20727
  if (isAttachmentContainer) {
20627
- await unlink3(join36(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
20728
+ await unlink3(join37(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
20628
20729
  });
20629
20730
  await rmdir(containerDir).catch(() => {
20630
20731
  });
@@ -20681,7 +20782,7 @@ app23.post("/folder", requireAdminSession, async (c) => {
20681
20782
  const newAbs = resolve27(parent.absolute, name);
20682
20783
  const newRel = `${parent.relative}/${name}`;
20683
20784
  try {
20684
- const info = await stat6(parent.absolute);
20785
+ const info = await stat7(parent.absolute);
20685
20786
  if (!info.isDirectory()) return c.json({ error: "Parent is not a directory" }, 400);
20686
20787
  await mkdir4(newAbs, { recursive: false });
20687
20788
  } catch (err) {
@@ -20726,7 +20827,7 @@ app23.post("/rename", requireAdminSession, async (c) => {
20726
20827
  try {
20727
20828
  let collision = true;
20728
20829
  try {
20729
- await stat6(destAbs);
20830
+ await stat7(destAbs);
20730
20831
  } catch (e) {
20731
20832
  if (e.code === "ENOENT") collision = false;
20732
20833
  }
@@ -21734,7 +21835,7 @@ function isHiddenByDefault(label) {
21734
21835
  // server/lib/top-level-labels.ts
21735
21836
  var import_dist5 = __toESM(require_dist4(), 1);
21736
21837
  import { readdirSync as readdirSync24, readFileSync as readFileSync36 } from "fs";
21737
- import { join as join37, resolve as resolve28 } from "path";
21838
+ import { join as join38, resolve as resolve28 } from "path";
21738
21839
  var STATIC_TOP_LEVEL_LABELS = Object.freeze(
21739
21840
  /* @__PURE__ */ new Set([
21740
21841
  // Base-schema infra (schema-base.md has no top-level section).
@@ -21838,7 +21939,7 @@ function parseTopLevelLabels(content) {
21838
21939
  }
21839
21940
  function resolveReferencesDir() {
21840
21941
  if (process.env.MAXY_PLATFORM_ROOT) {
21841
- return join37(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
21942
+ return join38(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
21842
21943
  }
21843
21944
  return resolve28(import.meta.dirname, "../../../plugins/memory/references");
21844
21945
  }
@@ -21848,7 +21949,7 @@ function parseTableTopLevelLabels(referencesDir) {
21848
21949
  try {
21849
21950
  const fileNames = readdirSync24(referencesDir).filter((f) => f.startsWith("schema-") && f.endsWith(".md")).sort();
21850
21951
  for (const fileName of fileNames) {
21851
- const content = readFileSync36(join37(referencesDir, fileName), "utf-8");
21952
+ const content = readFileSync36(join38(referencesDir, fileName), "utf-8");
21852
21953
  const parsed = parseTopLevelLabels(content);
21853
21954
  if (parsed.length > 0) contributingFiles.push(fileName);
21854
21955
  for (const label of parsed) labels.add(label);
@@ -23004,7 +23105,7 @@ var WRITE_CYPHER = `
23004
23105
  var graph_default_view_default = app29;
23005
23106
 
23006
23107
  // server/routes/admin/sidebar-artefacts.ts
23007
- import { readdir as readdir5, stat as stat7 } from "fs/promises";
23108
+ import { readdir as readdir5, stat as stat8 } from "fs/promises";
23008
23109
  import { resolve as resolve29, relative as relative6, isAbsolute as isAbsolute2, sep as sep9, basename as basename12 } from "path";
23009
23110
  import { existsSync as existsSync36 } from "fs";
23010
23111
  var LIMIT = 50;
@@ -23155,7 +23256,7 @@ async function readAgentTemplateRow(inp) {
23155
23256
  }
23156
23257
  if (!chosenPath) return null;
23157
23258
  try {
23158
- const st = await stat7(chosenPath);
23259
+ const st = await stat8(chosenPath);
23159
23260
  const dlPath = toDataRootRelPath(chosenPath);
23160
23261
  return {
23161
23262
  id: inp.id,
@@ -23187,11 +23288,11 @@ var sidebar_artefacts_default = app30;
23187
23288
 
23188
23289
  // server/channel-session-override.ts
23189
23290
  import { readFileSync as readFileSync37, writeFileSync as writeFileSync14, renameSync as renameSync10 } from "fs";
23190
- import { join as join38 } from "path";
23291
+ import { join as join39 } from "path";
23191
23292
  var FILE2 = "channel-session-override.json";
23192
23293
  var UUID3 = /^[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}$/;
23193
23294
  function channelOverridePath(accountDir) {
23194
- return join38(accountDir, FILE2);
23295
+ return join39(accountDir, FILE2);
23195
23296
  }
23196
23297
  function senderKey(channel, senderId) {
23197
23298
  return `${channel}:${senderId}`;
@@ -23587,24 +23688,24 @@ var session_rc_spawn_default = app36;
23587
23688
  import { randomUUID as randomUUID12 } from "crypto";
23588
23689
 
23589
23690
  // server/wa-descriptor.ts
23590
- import { resolve as resolve30, join as join39 } from "path";
23691
+ import { resolve as resolve30, join as join40 } from "path";
23591
23692
  function waGatewayUrl() {
23592
23693
  return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
23593
23694
  }
23594
23695
  function waServerPath() {
23595
- return process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve30(process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, ".."), "services/whatsapp-channel/dist/server.js");
23696
+ return process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve30(process.env.MAXY_PLATFORM_ROOT ?? join40(__dirname, ".."), "services/whatsapp-channel/dist/server.js");
23596
23697
  }
23597
23698
  function waChannelDescriptor(senderId) {
23598
23699
  return { senderId, gatewayUrl: waGatewayUrl(), serverPath: waServerPath() };
23599
23700
  }
23600
23701
 
23601
23702
  // server/telegram-descriptor.ts
23602
- import { resolve as resolve31, join as join40 } from "path";
23703
+ import { resolve as resolve31, join as join41 } from "path";
23603
23704
  function telegramGatewayUrl() {
23604
23705
  return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
23605
23706
  }
23606
23707
  function telegramServerPath() {
23607
- return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve31(process.env.MAXY_PLATFORM_ROOT ?? join40(__dirname, ".."), "services/telegram-channel/dist/server.js");
23708
+ return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve31(process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, ".."), "services/telegram-channel/dist/server.js");
23608
23709
  }
23609
23710
  function telegramChannelDescriptor(senderId) {
23610
23711
  return { senderId, gatewayUrl: telegramGatewayUrl(), serverPath: telegramServerPath() };
@@ -23721,16 +23822,18 @@ app37.post("/", requireAdminSession, async (c) => {
23721
23822
  return c.json(parsed ?? { error: text }, res.status);
23722
23823
  }
23723
23824
  try {
23724
- const account = resolveAccount();
23825
+ const account = cacheKey ? accountDirForSession(cacheKey) : null;
23725
23826
  if (account && adminUserId) {
23726
- const accountId2 = resolvePlatformAccountId();
23827
+ const platformAccountId = resolvePlatformAccountId();
23727
23828
  const primaryUserId = resolvePrimaryAdminUserId();
23728
- const canonicalId = adminSessionIdFor(accountId2, WEBCHAT_ADMIN_KEY, adminUserId);
23829
+ const canonicalId = adminSessionIdFor(platformAccountId, WEBCHAT_ADMIN_KEY, adminUserId);
23729
23830
  const currentOverride = readCanonicalOverrideId(account.accountDir, adminUserId, primaryUserId);
23730
23831
  if (fromSessionId === canonicalId || fromSessionId === currentOverride) {
23731
23832
  writeCanonicalOverrideId(account.accountDir, adminUserId, plan.sessionId);
23732
- console.log(`[chat-reseat] op=canonical-forward reseatReqId=${reseatReqId} from=${fromSessionId} to=${plan.sessionId}`);
23833
+ console.log(`[chat-reseat] op=canonical-forward reseatReqId=${reseatReqId} accountId=${account.accountId.slice(0, 8)} from=${fromSessionId} to=${plan.sessionId}`);
23733
23834
  }
23835
+ } else if (!account) {
23836
+ console.error(`[chat-reseat] op=canonical-forward-skipped reseatReqId=${reseatReqId} accountId=none reason=no-account-for-session`);
23734
23837
  }
23735
23838
  } catch (err) {
23736
23839
  console.error(`[session-reseat] canonical-forward-failed err=${err instanceof Error ? err.message : String(err)}`);
@@ -23767,7 +23870,7 @@ app37.post("/", requireAdminSession, async (c) => {
23767
23870
  var session_reseat_default = app37;
23768
23871
 
23769
23872
  // server/routes/admin/system-stats.ts
23770
- import { readFile as readFile8 } from "fs/promises";
23873
+ import { readFile as readFile9 } from "fs/promises";
23771
23874
  import { cpus, loadavg, totalmem, freemem } from "os";
23772
23875
  function parseCpuStat(blob) {
23773
23876
  const line = blob.split("\n", 1)[0] ?? "";
@@ -23811,11 +23914,11 @@ function parseMeminfo(blob) {
23811
23914
  }
23812
23915
  var SAMPLE_DELAY_MS = 100;
23813
23916
  async function sampleLinux() {
23814
- const a = parseCpuStat(await readFile8("/proc/stat", "utf-8"));
23917
+ const a = parseCpuStat(await readFile9("/proc/stat", "utf-8"));
23815
23918
  await new Promise((r) => setTimeout(r, SAMPLE_DELAY_MS));
23816
- const b = parseCpuStat(await readFile8("/proc/stat", "utf-8"));
23817
- const meminfo = parseMeminfo(await readFile8("/proc/meminfo", "utf-8"));
23818
- const loadavgRaw = (await readFile8("/proc/loadavg", "utf-8")).trim();
23919
+ const b = parseCpuStat(await readFile9("/proc/stat", "utf-8"));
23920
+ const meminfo = parseMeminfo(await readFile9("/proc/meminfo", "utf-8"));
23921
+ const loadavgRaw = (await readFile9("/proc/loadavg", "utf-8")).trim();
23819
23922
  const [l1, l5, l15] = loadavgRaw.split(/\s+/, 3).map(Number);
23820
23923
  if (![l1, l5, l15].every(Number.isFinite)) {
23821
23924
  throw new Error(`malformed /proc/loadavg: ${loadavgRaw}`);
@@ -23889,10 +23992,10 @@ var system_stats_default = app38;
23889
23992
 
23890
23993
  // server/routes/admin/health.ts
23891
23994
  import { existsSync as existsSync37, readFileSync as readFileSync38 } from "fs";
23892
- import { resolve as resolve32, join as join41 } from "path";
23995
+ import { resolve as resolve32, join as join42 } from "path";
23893
23996
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve32(process.cwd(), "..");
23894
23997
  var brandHostname = "maxy";
23895
- var brandJsonPath = join41(PLATFORM_ROOT6, "config", "brand.json");
23998
+ var brandJsonPath = join42(PLATFORM_ROOT6, "config", "brand.json");
23896
23999
  if (existsSync37(brandJsonPath)) {
23897
24000
  try {
23898
24001
  const brand = JSON.parse(readFileSync38(brandJsonPath, "utf-8"));
@@ -24682,7 +24785,7 @@ var browser_default = app46;
24682
24785
 
24683
24786
  // server/routes/admin/calendar.ts
24684
24787
  import { existsSync as existsSync38 } from "fs";
24685
- import { join as join43 } from "path";
24788
+ import { join as join44 } from "path";
24686
24789
 
24687
24790
  // server/lib/calendar-ics.ts
24688
24791
  var CRLF = "\r\n";
@@ -24782,7 +24885,7 @@ function countVEvents(ics) {
24782
24885
 
24783
24886
  // server/lib/calendar-availability.ts
24784
24887
  import { readFileSync as readFileSync39 } from "fs";
24785
- import { join as join42 } from "path";
24888
+ import { join as join43 } from "path";
24786
24889
  var AVAILABILITY_FILENAME = "calendar-availability.json";
24787
24890
  var REQUIRED_KEYS = [
24788
24891
  "timezone",
@@ -24791,7 +24894,7 @@ var REQUIRED_KEYS = [
24791
24894
  "weekly"
24792
24895
  ];
24793
24896
  function readAvailabilityConfig(accountDir) {
24794
- const path3 = join42(accountDir, AVAILABILITY_FILENAME);
24897
+ const path3 = join43(accountDir, AVAILABILITY_FILENAME);
24795
24898
  let raw;
24796
24899
  try {
24797
24900
  raw = readFileSync39(path3, "utf-8");
@@ -25147,25 +25250,26 @@ app47.delete("/meetings/:id", requireAdminSession, async (c) => {
25147
25250
  }
25148
25251
  });
25149
25252
  app47.get("/booking-link", requireAdminSession, (c) => {
25253
+ const account = accountDirForSession(c.var.cacheKey);
25254
+ if (!account) {
25255
+ console.error("[calendar] op=booking-link auth-rejected reason=no-account-for-session accountId=none");
25256
+ return c.json({ error: "no account for session", reason: "no-account-for-session" }, 401);
25257
+ }
25258
+ const id82 = account.accountId.slice(0, 8);
25150
25259
  try {
25151
- const account = resolveAccount();
25152
- if (!account) {
25153
- console.error('[calendar] op=booking-link-fail err="no account configured"');
25154
- return c.json({ bookingDomain: null });
25155
- }
25156
- if (!existsSync38(join43(account.accountDir, AVAILABILITY_FILENAME))) {
25157
- console.log("[calendar] op=booking-link bookingDomain=none source=availability-config");
25260
+ if (!existsSync38(join44(account.accountDir, AVAILABILITY_FILENAME))) {
25261
+ console.log(`[calendar] op=booking-link accountId=${id82} bookingDomain=none source=availability-config`);
25158
25262
  return c.json({ bookingDomain: null });
25159
25263
  }
25160
25264
  const config = readAvailabilityConfig(account.accountDir);
25161
25265
  const bookingDomain = typeof config.bookingDomain === "string" && config.bookingDomain.trim() ? config.bookingDomain.trim() : null;
25162
25266
  console.log(
25163
- `[calendar] op=booking-link bookingDomain=${bookingDomain ?? "none"} source=availability-config`
25267
+ `[calendar] op=booking-link accountId=${id82} bookingDomain=${bookingDomain ?? "none"} source=availability-config`
25164
25268
  );
25165
25269
  return c.json({ bookingDomain });
25166
25270
  } catch (err) {
25167
25271
  const message = err instanceof Error ? err.message : String(err);
25168
- console.error(`[calendar] op=booking-link-fail err="${message}"`);
25272
+ console.error(`[calendar] op=booking-link-fail accountId=${id82} err="${message}"`);
25169
25273
  return c.json({ bookingDomain: null });
25170
25274
  }
25171
25275
  });
@@ -26550,13 +26654,13 @@ app62.get("/:rel{.*}", (c) => {
26550
26654
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
26551
26655
  return c.text("Forbidden", 403);
26552
26656
  }
26553
- let stat11;
26657
+ let stat12;
26554
26658
  try {
26555
- stat11 = existsSync41(filePath) ? statSync18(filePath) : null;
26659
+ stat12 = existsSync41(filePath) ? statSync18(filePath) : null;
26556
26660
  } catch {
26557
- stat11 = null;
26661
+ stat12 = null;
26558
26662
  }
26559
- if (stat11?.isDirectory() && !reqPath.endsWith("/")) {
26663
+ if (stat12?.isDirectory() && !reqPath.endsWith("/")) {
26560
26664
  const search = new URL(c.req.url).search;
26561
26665
  const target = `${reqPath}/${search}`;
26562
26666
  console.log(
@@ -26564,7 +26668,7 @@ app62.get("/:rel{.*}", (c) => {
26564
26668
  );
26565
26669
  return c.redirect(target, 301);
26566
26670
  }
26567
- if (stat11?.isDirectory()) {
26671
+ if (stat12?.isDirectory()) {
26568
26672
  filePath = resolve36(filePath, "index.html");
26569
26673
  }
26570
26674
  if (!filePath.startsWith(rootDir + "/")) {
@@ -26703,7 +26807,7 @@ var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
26703
26807
 
26704
26808
  // app/lib/brand-config.ts
26705
26809
  import { existsSync as existsSync42, readFileSync as readFileSync44 } from "fs";
26706
- import { join as join44 } from "path";
26810
+ import { join as join45 } from "path";
26707
26811
  var cached2 = null;
26708
26812
  var cachedAttempted = false;
26709
26813
  function readBrandConfig() {
@@ -26711,7 +26815,7 @@ function readBrandConfig() {
26711
26815
  cachedAttempted = true;
26712
26816
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
26713
26817
  if (!platformRoot5) return null;
26714
- const brandPath = join44(platformRoot5, "config", "brand.json");
26818
+ const brandPath = join45(platformRoot5, "config", "brand.json");
26715
26819
  if (!existsSync42(brandPath)) return null;
26716
26820
  try {
26717
26821
  cached2 = JSON.parse(readFileSync44(brandPath, "utf-8"));
@@ -27555,8 +27659,8 @@ var calendar_public_default = app67;
27555
27659
 
27556
27660
  // server/routes/portal-fetch.ts
27557
27661
  import { createReadStream as createReadStream3 } from "fs";
27558
- import { stat as stat8, readFile as readFile9, realpath } from "fs/promises";
27559
- import { join as join45, resolve as resolve38, sep as sep10 } from "path";
27662
+ import { stat as stat9, readFile as readFile10, realpath } from "fs/promises";
27663
+ import { join as join46, resolve as resolve38, sep as sep10 } from "path";
27560
27664
  import { Readable as Readable3 } from "stream";
27561
27665
  var app68 = new Hono();
27562
27666
  var TAG50 = "[portal-fetch]";
@@ -27612,7 +27716,7 @@ async function readAccountSecret(accountId) {
27612
27716
  const path3 = resolve38(DATA_ROOT, "accounts", accountId, "secrets", "data-portal.env");
27613
27717
  let text;
27614
27718
  try {
27615
- text = await readFile9(path3, "utf8");
27719
+ text = await readFile10(path3, "utf8");
27616
27720
  } catch {
27617
27721
  console.error(`${TAG50} op=no-secret account="${accountId}" path="${path3}"`);
27618
27722
  return "";
@@ -27629,7 +27733,7 @@ function isValidAccountId2(value) {
27629
27733
  }
27630
27734
  async function readExposeFolders2(accountDir) {
27631
27735
  try {
27632
- const cfg = JSON.parse(await readFile9(join45(accountDir, "data-portal.json"), "utf8"));
27736
+ const cfg = JSON.parse(await readFile10(join46(accountDir, "data-portal.json"), "utf8"));
27633
27737
  return Array.isArray(cfg?.exposeFolders) ? cfg.exposeFolders.filter((f) => typeof f === "string") : [];
27634
27738
  } catch {
27635
27739
  return [];
@@ -27638,7 +27742,7 @@ async function readExposeFolders2(accountDir) {
27638
27742
  async function resolveFetchTarget(accountDir, relPath, ownerId) {
27639
27743
  let schemaText = null;
27640
27744
  try {
27641
- schemaText = await readFile9(join45(accountDir, "SCHEMA.md"), "utf8");
27745
+ schemaText = await readFile10(join46(accountDir, "SCHEMA.md"), "utf8");
27642
27746
  } catch {
27643
27747
  schemaText = null;
27644
27748
  }
@@ -27664,7 +27768,7 @@ async function resolveFetchTarget(accountDir, relPath, ownerId) {
27664
27768
  return { ok: false, reason: "not-exposed" };
27665
27769
  }
27666
27770
  try {
27667
- const st = await stat8(absolute);
27771
+ const st = await stat9(absolute);
27668
27772
  if (!st.isFile()) return { ok: false, reason: "enoent" };
27669
27773
  return { ok: true, absolute, sizeBytes: st.size };
27670
27774
  } catch {
@@ -27809,7 +27913,7 @@ function startTimeEntryCensus(openSession, opts = {}) {
27809
27913
 
27810
27914
  // app/lib/ledger-census.ts
27811
27915
  import { readdirSync as readdirSync28, readFileSync as readFileSync45, statSync as statSync19 } from "fs";
27812
- import { join as join46 } from "path";
27916
+ import { join as join47 } from "path";
27813
27917
 
27814
27918
  // ../lib/ledger-core/dist/reconcile.js
27815
27919
  var LEDGER_INDEX_NAMES = [
@@ -27863,7 +27967,7 @@ function countWriteRejects24h(logDir, now) {
27863
27967
  }
27864
27968
  let total = 0;
27865
27969
  for (const name of entries2) {
27866
- const path3 = join46(logDir, name);
27970
+ const path3 = join47(logDir, name);
27867
27971
  try {
27868
27972
  if (now - statSync19(path3).mtimeMs > DAY_MS) continue;
27869
27973
  for (const line of readFileSync45(path3, "utf8").split("\n")) {
@@ -28360,9 +28464,9 @@ async function migrateUploads(opts = {}) {
28360
28464
  }
28361
28465
 
28362
28466
  // app/lib/migrate-admin-webchat-sidecars.ts
28363
- import { readdir as readdir7, readFile as readFile10, rename as rename4, writeFile as writeFile5, unlink as unlink4 } from "fs/promises";
28467
+ import { readdir as readdir7, readFile as readFile11, rename as rename4, writeFile as writeFile5, unlink as unlink4 } from "fs/promises";
28364
28468
  import { existsSync as existsSync44 } from "fs";
28365
- import { join as join47 } from "path";
28469
+ import { join as join48 } from "path";
28366
28470
  var ADMIN_ROLE2 = "admin";
28367
28471
  var WEBCHAT_CHANNEL2 = "webchat";
28368
28472
  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;
@@ -28373,7 +28477,7 @@ var defaultResolveName = async (_accountId, userId) => {
28373
28477
  async function readRaw3(path3) {
28374
28478
  let raw;
28375
28479
  try {
28376
- raw = await readFile10(path3, "utf8");
28480
+ raw = await readFile11(path3, "utf8");
28377
28481
  } catch {
28378
28482
  return null;
28379
28483
  }
@@ -28407,7 +28511,7 @@ async function collectLiveSidecars(projectsRoot) {
28407
28511
  }
28408
28512
  for (const slug of slugs) {
28409
28513
  if (!slug.isDirectory()) continue;
28410
- const slugDir = join47(projectsRoot, slug.name);
28514
+ const slugDir = join48(projectsRoot, slug.name);
28411
28515
  let entries2;
28412
28516
  try {
28413
28517
  entries2 = await readdir7(slugDir, { withFileTypes: true });
@@ -28416,9 +28520,9 @@ async function collectLiveSidecars(projectsRoot) {
28416
28520
  }
28417
28521
  for (const entry of entries2) {
28418
28522
  if (entry.isFile() && SESSION_META_RE.test(entry.name)) {
28419
- out.push(join47(slugDir, entry.name));
28523
+ out.push(join48(slugDir, entry.name));
28420
28524
  } else if (entry.isDirectory() && entry.name === "subagents") {
28421
- const subDir = join47(slugDir, entry.name);
28525
+ const subDir = join48(slugDir, entry.name);
28422
28526
  let subs;
28423
28527
  try {
28424
28528
  subs = await readdir7(subDir, { withFileTypes: true });
@@ -28426,7 +28530,7 @@ async function collectLiveSidecars(projectsRoot) {
28426
28530
  continue;
28427
28531
  }
28428
28532
  for (const s of subs) {
28429
- if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join47(subDir, s.name));
28533
+ if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join48(subDir, s.name));
28430
28534
  }
28431
28535
  }
28432
28536
  }
@@ -28438,7 +28542,7 @@ function shortId(path3) {
28438
28542
  return base.slice(0, 8);
28439
28543
  }
28440
28544
  async function migrateAdminWebchatSidecars(opts = {}) {
28441
- const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join47(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
28545
+ const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join48(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
28442
28546
  const usersFile = opts.usersFile ?? USERS_FILE;
28443
28547
  const accountId = opts.accountId ?? resolveAccount()?.accountId ?? null;
28444
28548
  const resolveName = opts.resolveName ?? defaultResolveName;
@@ -30737,7 +30841,7 @@ function buildTelegramSpawnRequest(input) {
30737
30841
 
30738
30842
  // app/lib/telegram/outbound/send-document.ts
30739
30843
  import { realpathSync as realpathSync10 } from "fs";
30740
- import { readFile as readFile11, stat as stat10 } from "fs/promises";
30844
+ import { readFile as readFile12, stat as stat11 } from "fs/promises";
30741
30845
  import { resolve as resolve42, basename as basename13 } from "path";
30742
30846
  var TAG56 = "[telegram:outbound]";
30743
30847
  var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
@@ -30778,7 +30882,7 @@ async function sendTelegramDocument(input) {
30778
30882
  console.error(`${TAG56} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
30779
30883
  return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
30780
30884
  }
30781
- const fileStat = await stat10(resolvedPath);
30885
+ const fileStat = await stat11(resolvedPath);
30782
30886
  if (fileStat.size > TELEGRAM_DOCUMENT_MAX_BYTES) {
30783
30887
  return {
30784
30888
  ok: false,
@@ -30787,7 +30891,7 @@ async function sendTelegramDocument(input) {
30787
30891
  };
30788
30892
  }
30789
30893
  const filename = basename13(resolvedPath);
30790
- const buffer = Buffer.from(await readFile11(resolvedPath));
30894
+ const buffer = Buffer.from(await readFile12(resolvedPath));
30791
30895
  const form = new FormData();
30792
30896
  form.append("chat_id", String(chatId));
30793
30897
  if (caption) form.append("caption", caption);
@@ -31238,8 +31342,8 @@ function resolveEntitlement(brand, account) {
31238
31342
  if (!existsSync46(entitlementPath)) {
31239
31343
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
31240
31344
  }
31241
- const stat11 = statSync20(entitlementPath);
31242
- const key = memoKey(stat11.mtimeMs, account);
31345
+ const stat12 = statSync20(entitlementPath);
31346
+ const key = memoKey(stat12.mtimeMs, account);
31243
31347
  if (memo && memo.key === key) {
31244
31348
  return memo.result;
31245
31349
  }
@@ -31426,7 +31530,7 @@ function clientFrom(c) {
31426
31530
  }
31427
31531
  installMediaDownloadGuard();
31428
31532
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
31429
- var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join48(PLATFORM_ROOT8, "config", "brand.json") : "";
31533
+ var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join49(PLATFORM_ROOT8, "config", "brand.json") : "";
31430
31534
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
31431
31535
  if (BRAND_JSON_PATH && !existsSync47(BRAND_JSON_PATH)) {
31432
31536
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
@@ -31465,7 +31569,7 @@ var brandLoginOpts = {
31465
31569
  appleTouchIconPath: brandAppIcon512Path,
31466
31570
  themeColor: BRAND.defaultColors?.primary
31467
31571
  };
31468
- var ALIAS_DOMAINS_PATH = join48(homedir4(), BRAND.configDir, "alias-domains.json");
31572
+ var ALIAS_DOMAINS_PATH = join49(homedir4(), BRAND.configDir, "alias-domains.json");
31469
31573
  function loadAliasDomains() {
31470
31574
  try {
31471
31575
  if (!existsSync47(ALIAS_DOMAINS_PATH)) return null;
@@ -31544,7 +31648,7 @@ var waGateway = new WaGateway({
31544
31648
  fetchStandingRules: fetchAccountStandingRules,
31545
31649
  resolveSessionOverride: (accountId, senderId) => resolveChannelOverride(accountId, "whatsapp", senderId),
31546
31650
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
31547
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve45(process.env.MAXY_PLATFORM_ROOT ?? join48(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
31651
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve45(process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
31548
31652
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
31549
31653
  // path-validation scope) is the sender's effective SESSION account, resolved
31550
31654
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -31559,7 +31663,7 @@ var waGateway = new WaGateway({
31559
31663
  caption,
31560
31664
  accountId,
31561
31665
  maxyAccountId,
31562
- platformRoot: resolve45(process.env.MAXY_PLATFORM_ROOT ?? join48(__dirname, ".."))
31666
+ platformRoot: resolve45(process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, ".."))
31563
31667
  });
31564
31668
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
31565
31669
  },
@@ -31677,7 +31781,7 @@ function runDuplicateSenderAudit() {
31677
31781
  try {
31678
31782
  const configDir2 = process.env.CLAUDE_CONFIG_DIR;
31679
31783
  if (!configDir2) return;
31680
- const projectsRoot = join48(configDir2, "projects");
31784
+ const projectsRoot = join49(configDir2, "projects");
31681
31785
  const records = [];
31682
31786
  for (const { path: jsonlPath, isSubagent, archived } of enumerateJsonls(projectsRoot)) {
31683
31787
  if (isSubagent || archived) continue;
@@ -32343,7 +32447,7 @@ var SW_SOURCE = (() => {
32343
32447
  function readInstalledVersion() {
32344
32448
  try {
32345
32449
  if (!PLATFORM_ROOT8) return "unknown";
32346
- const versionFile = join48(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
32450
+ const versionFile = join49(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
32347
32451
  if (!existsSync47(versionFile)) return "unknown";
32348
32452
  const content = readFileSync48(versionFile, "utf-8").trim();
32349
32453
  return content || "unknown";
@@ -32403,11 +32507,11 @@ ${clientErrorReporterScript}
32403
32507
  return html;
32404
32508
  }
32405
32509
  function loadBrandingCache(agentSlug) {
32406
- const configDir2 = join48(homedir4(), BRAND.configDir);
32510
+ const configDir2 = join49(homedir4(), BRAND.configDir);
32407
32511
  try {
32408
32512
  const accountId = getDefaultAccountId();
32409
32513
  if (!accountId) return null;
32410
- const cachePath = join48(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
32514
+ const cachePath = join49(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
32411
32515
  if (!existsSync47(cachePath)) return null;
32412
32516
  return JSON.parse(readFileSync48(cachePath, "utf-8"));
32413
32517
  } catch {
@@ -32638,7 +32742,7 @@ if (brandFaviconPath !== "/favicon.ico") {
32638
32742
  return c.redirect(brandFaviconPath, 302);
32639
32743
  });
32640
32744
  }
32641
- app69.use("/*", serveStatic({ root: "./public" }));
32745
+ mountStaticFiles(app69, "./public");
32642
32746
  app69.all("*", (c) => {
32643
32747
  const host = (c.req.header("host") ?? "").split(":")[0];
32644
32748
  const path3 = c.req.path;
@@ -32656,7 +32760,7 @@ var hostname = process.env.HOSTNAME ?? "127.0.0.1";
32656
32760
  var httpServer = serve({ fetch: app69.fetch, port, hostname });
32657
32761
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
32658
32762
  {
32659
- const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join48(__dirname, "..");
32763
+ const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
32660
32764
  const reconcileScript = resolve45(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
32661
32765
  const runReconcile = (ctx) => {
32662
32766
  if (!existsSync47(reconcileScript)) return;
@@ -32679,7 +32783,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
32679
32783
  detached: true,
32680
32784
  run: runReconcile
32681
32785
  });
32682
- const reconcileStatePath = join48(MAXY_DIR, "booking-reconcile-state.json");
32786
+ const reconcileStatePath = join49(MAXY_DIR, "booking-reconcile-state.json");
32683
32787
  registerLoop({
32684
32788
  name: "calendar-reconcile-liveness",
32685
32789
  intervalMs: 6e5,
@@ -32697,7 +32801,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
32697
32801
  }
32698
32802
  {
32699
32803
  const DREAM_CYCLE_SWEEP_INTERVAL_MS = 36e5;
32700
- const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join48(__dirname, "..");
32804
+ const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
32701
32805
  const dreamSweepScript = resolve45(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
32702
32806
  registerLoop({
32703
32807
  name: "dream-cycle-sweep",
@@ -32721,7 +32825,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
32721
32825
  });
32722
32826
  }
32723
32827
  {
32724
- const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join48(__dirname, "..");
32828
+ const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
32725
32829
  const outlookScript = resolve45(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
32726
32830
  const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
32727
32831
  const runOutlookComplete = (ctx) => {
@@ -32747,7 +32851,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
32747
32851
  });
32748
32852
  }
32749
32853
  {
32750
- const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join48(__dirname, "..");
32854
+ const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
32751
32855
  const strandedAccountsDir = resolve45(auditRoot, "..", "data/accounts");
32752
32856
  const STRANDED_AUDIT_INTERVAL_MS = 3e5;
32753
32857
  const STRANDED_AGE_MS = 16 * 6e4;
@@ -32777,7 +32881,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
32777
32881
  });
32778
32882
  }
32779
32883
  {
32780
- const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join48(__dirname, "..");
32884
+ const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
32781
32885
  const googleAccountsDir = resolve45(googleRoot, "..", "data/accounts");
32782
32886
  const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
32783
32887
  const runGooglePendingAuditSafe = () => {
@@ -32821,7 +32925,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
32821
32925
  });
32822
32926
  }
32823
32927
  {
32824
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join48(__dirname, "..");
32928
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
32825
32929
  const STORAGE_AUDIT_INTERVAL_MS = 3e5;
32826
32930
  const runStorageAuditSafe = () => runStorageAudit(auditPlatformRoot).catch((err) => {
32827
32931
  console.error(`[storage-audit] error="${err.message}"`);
@@ -32867,7 +32971,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
32867
32971
  });
32868
32972
  }
32869
32973
  {
32870
- const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join48(__dirname, "..");
32974
+ const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
32871
32975
  const publishScript = resolve45(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
32872
32976
  const PUBLISH_INTERVAL_MS = 3e5;
32873
32977
  const bookingAccounts = () => {
@@ -32944,7 +33048,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
32944
33048
  startTimeEntryCensus(() => getSession());
32945
33049
  startLedgerCensus(() => getSession());
32946
33050
  {
32947
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join48(__dirname, "..");
33051
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
32948
33052
  const auditScript = resolve45(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
32949
33053
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
32950
33054
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
@@ -32989,19 +33093,17 @@ startAuthHealthHeartbeat();
32989
33093
  {
32990
33094
  const loopHist = monitorEventLoopDelay({ resolution: 50 });
32991
33095
  loopHist.enable();
32992
- const LOG_THRESHOLD_MS = 1e3;
33096
+ const LOUD_THRESHOLD_MS = 1e3;
32993
33097
  const WINDOW_MS2 = 3e4;
32994
33098
  registerLoop({
32995
33099
  name: "event-loop-lag",
32996
33100
  intervalMs: WINDOW_MS2,
32997
33101
  run: () => {
32998
- const maxMs = loopHist.max / 1e6;
32999
- const p99Ms = loopHist.percentile(99) / 1e6;
33000
- loopHist.reset();
33001
- if (maxMs >= LOG_THRESHOLD_MS) {
33002
- console.error(`[event-loop] lag p99=${Math.round(p99Ms)} max=${Math.round(maxMs)} window=${WINDOW_MS2 / 1e3}s`);
33003
- }
33004
- return `p99 ${Math.round(p99Ms)}ms, max ${Math.round(maxMs)}ms`;
33102
+ const w = readAndResetWindow(loopHist, WINDOW_MS2);
33103
+ const line = formatLagWindow(w);
33104
+ if (w.maxMs >= LOUD_THRESHOLD_MS) console.error(line);
33105
+ else console.log(line);
33106
+ return `p99 ${w.p99Ms}ms, max ${w.maxMs}ms`;
33005
33107
  }
33006
33108
  });
33007
33109
  }
@@ -33254,7 +33356,7 @@ if (bootAccountConfig?.whatsapp) {
33254
33356
  }
33255
33357
  init({
33256
33358
  configDir: configDirForWhatsApp,
33257
- platformRoot: resolve45(process.env.MAXY_PLATFORM_ROOT ?? join48(__dirname, "..")),
33359
+ platformRoot: resolve45(process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..")),
33258
33360
  accountConfig: bootAccountConfig,
33259
33361
  onMessage: async (msg) => {
33260
33362
  if (isObserveAccount(msg.accountId)) {