@rubytech/create-sitedesk-code 0.1.519 → 0.1.520

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 (289) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/docs/superpowers/plans/2026-07-28-task-2097-email-signature-set.md +65 -0
  3. package/payload/platform/docs/superpowers/specs/2026-07-28-task-2097-email-signature-set-design.md +155 -0
  4. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +6 -0
  5. package/payload/platform/plugins/cloudflare/bin/portal-assemble.mjs +187 -0
  6. package/payload/platform/plugins/cloudflare/bin/portal-enrol.mjs +46 -5
  7. package/payload/platform/plugins/cloudflare/mcp/__tests__/auth-route.test.ts +19 -7
  8. package/payload/platform/plugins/cloudflare/mcp/__tests__/authorize.test.ts +154 -38
  9. package/payload/platform/plugins/cloudflare/mcp/__tests__/file-routes.test.ts +100 -29
  10. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-assemble.test.ts +143 -0
  11. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-delete-withdraw.test.ts +12 -5
  12. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-directory-listing.test.ts +15 -3
  13. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-enrol.test.ts +105 -11
  14. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-indexed-download.test.ts +15 -2
  15. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-moved-download.test.ts +9 -5
  16. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-schema-shape.test.ts +47 -5
  17. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-session-grant.test.ts +26 -2
  18. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-target.test.ts +12 -4
  19. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-upload-multipart.test.ts +23 -15
  20. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-upload-target.test.ts +23 -15
  21. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-uploads-listing.test.ts +8 -0
  22. package/payload/platform/plugins/cloudflare/mcp/__tests__/skill-contract.test.ts +23 -6
  23. package/payload/platform/plugins/cloudflare/mcp/__tests__/upload-route.test.ts +36 -20
  24. package/payload/platform/plugins/cloudflare/skills/data-portal/SKILL.md +85 -22
  25. package/payload/platform/plugins/cloudflare/skills/data-portal/schema.sql +47 -7
  26. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/authorize.ts +27 -18
  27. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/ratelimit.ts +10 -3
  28. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/session.ts +27 -11
  29. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/target.ts +18 -9
  30. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/types.ts +16 -0
  31. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/auth.ts +16 -4
  32. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/delete.ts +26 -11
  33. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/download.ts +14 -10
  34. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/files.ts +13 -9
  35. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/upload.ts +42 -22
  36. package/payload/platform/plugins/cloudflare/skills/data-portal/template/wrangler.toml +17 -4
  37. package/payload/platform/plugins/email/.claude-plugin/plugin.json +1 -1
  38. package/payload/platform/plugins/email/PLUGIN.md +20 -1
  39. package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-list-tool.test.d.ts +2 -0
  40. package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-list-tool.test.d.ts.map +1 -0
  41. package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-list-tool.test.js +142 -0
  42. package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-list-tool.test.js.map +1 -0
  43. package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-list.test.d.ts +2 -0
  44. package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-list.test.d.ts.map +1 -0
  45. package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-list.test.js +153 -0
  46. package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-list.test.js.map +1 -0
  47. package/payload/platform/plugins/email/mcp/dist/__tests__/email-signature-set.test.d.ts +2 -0
  48. package/payload/platform/plugins/email/mcp/dist/__tests__/email-signature-set.test.d.ts.map +1 -0
  49. package/payload/platform/plugins/email/mcp/dist/__tests__/email-signature-set.test.js +203 -0
  50. package/payload/platform/plugins/email/mcp/dist/__tests__/email-signature-set.test.js.map +1 -0
  51. package/payload/platform/plugins/email/mcp/dist/index.js +69 -0
  52. package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
  53. package/payload/platform/plugins/email/mcp/dist/lib/compose.d.ts.map +1 -1
  54. package/payload/platform/plugins/email/mcp/dist/lib/compose.js +5 -7
  55. package/payload/platform/plugins/email/mcp/dist/lib/compose.js.map +1 -1
  56. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +42 -0
  57. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
  58. package/payload/platform/plugins/email/mcp/dist/lib/imap.js +76 -0
  59. package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
  60. package/payload/platform/plugins/email/mcp/dist/lib/signature.d.ts +38 -0
  61. package/payload/platform/plugins/email/mcp/dist/lib/signature.d.ts.map +1 -1
  62. package/payload/platform/plugins/email/mcp/dist/lib/signature.js +67 -2
  63. package/payload/platform/plugins/email/mcp/dist/lib/signature.js.map +1 -1
  64. package/payload/platform/plugins/email/mcp/dist/tools/email-draft-list.d.ts +10 -0
  65. package/payload/platform/plugins/email/mcp/dist/tools/email-draft-list.d.ts.map +1 -0
  66. package/payload/platform/plugins/email/mcp/dist/tools/email-draft-list.js +73 -0
  67. package/payload/platform/plugins/email/mcp/dist/tools/email-draft-list.js.map +1 -0
  68. package/payload/platform/plugins/email/mcp/dist/tools/email-signature-set.d.ts +18 -0
  69. package/payload/platform/plugins/email/mcp/dist/tools/email-signature-set.d.ts.map +1 -0
  70. package/payload/platform/plugins/email/mcp/dist/tools/email-signature-set.js +38 -0
  71. package/payload/platform/plugins/email/mcp/dist/tools/email-signature-set.js.map +1 -0
  72. package/payload/platform/plugins/email/references/email-reference.md +14 -2
  73. package/payload/platform/plugins/email/skills/email-composition/SKILL.md +10 -0
  74. package/payload/platform/plugins/email/skills/email-signature/SKILL.md +61 -0
  75. package/payload/platform/plugins/scheduling/PLUGIN.md +8 -0
  76. package/payload/platform/plugins/scheduling/mcp/dist/index.js +26 -15
  77. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  78. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-audit.test.d.ts +2 -0
  79. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-audit.test.d.ts.map +1 -0
  80. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-audit.test.js +48 -0
  81. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-audit.test.js.map +1 -0
  82. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts +24 -0
  83. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts.map +1 -0
  84. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js +33 -0
  85. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js.map +1 -0
  86. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +22 -1
  87. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  88. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel-meeting.test.d.ts +2 -0
  89. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel-meeting.test.d.ts.map +1 -0
  90. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel-meeting.test.js +30 -0
  91. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel-meeting.test.js.map +1 -0
  92. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-get-meeting.test.d.ts +2 -0
  93. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-get-meeting.test.d.ts.map +1 -0
  94. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-get-meeting.test.js +43 -0
  95. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-get-meeting.test.js.map +1 -0
  96. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-list.test.d.ts +2 -0
  97. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-list.test.d.ts.map +1 -0
  98. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-list.test.js +87 -0
  99. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-list.test.js.map +1 -0
  100. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-meeting.test.d.ts +2 -0
  101. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-meeting.test.d.ts.map +1 -0
  102. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-meeting.test.js +48 -0
  103. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-meeting.test.js.map +1 -0
  104. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.d.ts.map +1 -1
  105. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js +14 -1
  106. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js.map +1 -1
  107. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.d.ts +4 -1
  108. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.d.ts.map +1 -1
  109. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.js +39 -2
  110. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.js.map +1 -1
  111. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.d.ts +4 -1
  112. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.d.ts.map +1 -1
  113. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.js +50 -1
  114. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.js.map +1 -1
  115. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts.map +1 -1
  116. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js +43 -1
  117. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
  118. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  119. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +2 -0
  120. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  121. package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
  122. package/payload/server/public/activity.html +5 -5
  123. package/payload/server/public/agents.html +4 -4
  124. package/payload/server/public/assets/AdminLoginScreens-SW7mEMcP.js +1 -0
  125. package/payload/server/public/assets/AdminLoginScreens-SW7mEMcP.js.br +0 -0
  126. package/payload/server/public/assets/AdminLoginScreens-SW7mEMcP.js.gz +0 -0
  127. package/payload/server/public/assets/{AdminShell-Bpo_wgxm.js → AdminShell-Djg6ndne.js} +1 -1
  128. package/payload/server/public/assets/AdminShell-Djg6ndne.js.br +0 -0
  129. package/payload/server/public/assets/AdminShell-Djg6ndne.js.gz +0 -0
  130. package/payload/server/public/assets/{activity-DOsfKzT3.js → activity-sqbyX0pX.js} +1 -1
  131. package/payload/server/public/assets/activity-sqbyX0pX.js.br +0 -0
  132. package/payload/server/public/assets/activity-sqbyX0pX.js.gz +0 -0
  133. package/payload/server/public/assets/admin-D9Bt47GY.js +1 -0
  134. package/payload/server/public/assets/admin-D9Bt47GY.js.br +0 -0
  135. package/payload/server/public/assets/admin-D9Bt47GY.js.gz +0 -0
  136. package/payload/server/public/assets/{agents-DqDnZTH_.js → agents-BFYM5EDA.js} +1 -1
  137. package/payload/server/public/assets/agents-BFYM5EDA.js.br +0 -0
  138. package/payload/server/public/assets/agents-BFYM5EDA.js.gz +0 -0
  139. package/payload/server/public/assets/{browser-FL17Dfp0.js → browser-DP5GZe4G.js} +1 -1
  140. package/payload/server/public/assets/browser-DP5GZe4G.js.br +0 -0
  141. package/payload/server/public/assets/browser-DP5GZe4G.js.gz +0 -0
  142. package/payload/server/public/assets/{calendar-CLfLvsnV.js → calendar-BKaemLDG.js} +1 -1
  143. package/payload/server/public/assets/calendar-BKaemLDG.js.br +0 -0
  144. package/payload/server/public/assets/calendar-BKaemLDG.js.gz +0 -0
  145. package/payload/server/public/assets/chat-DPhT6urD.js +1 -0
  146. package/payload/server/public/assets/chat-DPhT6urD.js.br +1 -0
  147. package/payload/server/public/assets/chat-DPhT6urD.js.gz +0 -0
  148. package/payload/server/public/assets/chevron-left-BSdXvJcH.js +1 -0
  149. package/payload/server/public/assets/chevron-right-DI7vI3IB.js +1 -0
  150. package/payload/server/public/assets/chevron-right-DI7vI3IB.js.br +0 -0
  151. package/payload/server/public/assets/clock-YUTPXZH5.js +1 -0
  152. package/payload/server/public/assets/clock-YUTPXZH5.js.br +0 -0
  153. package/payload/server/public/assets/clock-YUTPXZH5.js.gz +0 -0
  154. package/payload/server/public/assets/data-CfjttTvR.js +1 -0
  155. package/payload/server/public/assets/data-CfjttTvR.js.br +2 -0
  156. package/payload/server/public/assets/data-CfjttTvR.js.gz +0 -0
  157. package/payload/server/public/assets/{file-text-DNm0AzUz.js → file-text-BKK7R-k_.js} +1 -1
  158. package/payload/server/public/assets/file-text-BKK7R-k_.js.br +0 -0
  159. package/payload/server/public/assets/file-text-BKK7R-k_.js.gz +0 -0
  160. package/payload/server/public/assets/{graph-fAvmlVzh.js → graph-FuxYySjK.js} +1 -1
  161. package/payload/server/public/assets/graph-FuxYySjK.js.br +0 -0
  162. package/payload/server/public/assets/graph-FuxYySjK.js.gz +0 -0
  163. package/payload/server/public/assets/{graph-labels-CwdkCxfs.js → graph-labels-Cip6fmKK.js} +1 -1
  164. package/payload/server/public/assets/graph-labels-Cip6fmKK.js.br +0 -0
  165. package/payload/server/public/assets/graph-labels-Cip6fmKK.js.gz +0 -0
  166. package/payload/server/public/assets/{maximize-2-B6tAPhC2.js → maximize-2-D79AhVDo.js} +1 -1
  167. package/payload/server/public/assets/maximize-2-D79AhVDo.js.br +0 -0
  168. package/payload/server/public/assets/maximize-2-D79AhVDo.js.gz +0 -0
  169. package/payload/server/public/assets/{operator-CTKvBVjk.js → operator-BPAfgFhP.js} +1 -1
  170. package/payload/server/public/assets/operator-BPAfgFhP.js.br +0 -0
  171. package/payload/server/public/assets/operator-BPAfgFhP.js.gz +0 -0
  172. package/payload/server/public/assets/{page-BWoNW3sa.js → page--78CbdFs.js} +1 -1
  173. package/payload/server/public/assets/page--78CbdFs.js.br +0 -0
  174. package/payload/server/public/assets/page--78CbdFs.js.gz +0 -0
  175. package/payload/server/public/assets/{page-O5HkHQw4.js → page-BqEyS0W4.js} +1 -1
  176. package/payload/server/public/assets/page-BqEyS0W4.js.br +0 -0
  177. package/payload/server/public/assets/page-BqEyS0W4.js.gz +0 -0
  178. package/payload/server/public/assets/{public-BF1rnVPa.js → public-D1xs3FzD.js} +1 -1
  179. package/payload/server/public/assets/public-D1xs3FzD.js.br +0 -0
  180. package/payload/server/public/assets/public-D1xs3FzD.js.gz +0 -0
  181. package/payload/server/public/assets/{rotate-ccw-B8TqfCy4.js → rotate-ccw-CcU_XD8B.js} +1 -1
  182. package/payload/server/public/assets/rotate-ccw-CcU_XD8B.js.br +0 -0
  183. package/payload/server/public/assets/rotate-ccw-CcU_XD8B.js.gz +0 -0
  184. package/payload/server/public/assets/{routines-4R7BLZyH.js → routines-CA7D0myr.js} +1 -1
  185. package/payload/server/public/assets/routines-CA7D0myr.js.br +0 -0
  186. package/payload/server/public/assets/routines-CA7D0myr.js.gz +0 -0
  187. package/payload/server/public/assets/{skills-CQ9Qs2tg.js → skills-CfVPPSxO.js} +1 -1
  188. package/payload/server/public/assets/skills-CfVPPSxO.js.br +0 -0
  189. package/payload/server/public/assets/skills-CfVPPSxO.js.gz +0 -0
  190. package/payload/server/public/assets/{tasks-DePyOrRk.js → tasks-DgieyZqz.js} +1 -1
  191. package/payload/server/public/assets/tasks-DgieyZqz.js.br +0 -0
  192. package/payload/server/public/assets/tasks-DgieyZqz.js.gz +0 -0
  193. package/payload/server/public/assets/{time-entry-format-D9gtnG01.js → time-entry-format-IFqinQJj.js} +1 -1
  194. package/payload/server/public/assets/time-entry-format-IFqinQJj.js.br +0 -0
  195. package/payload/server/public/assets/time-entry-format-IFqinQJj.js.gz +0 -0
  196. package/payload/server/public/assets/{triangle-alert-DAtm2mLL.js → triangle-alert-C5vH__sq.js} +1 -1
  197. package/payload/server/public/assets/triangle-alert-C5vH__sq.js.br +0 -0
  198. package/payload/server/public/assets/triangle-alert-C5vH__sq.js.gz +0 -0
  199. package/payload/server/public/assets/{useCopyFeedback-uMJT-p6i.js → useCopyFeedback-BeL2gPl6.js} +1 -1
  200. package/payload/server/public/assets/useCopyFeedback-BeL2gPl6.js.br +0 -0
  201. package/payload/server/public/assets/useCopyFeedback-BeL2gPl6.js.gz +0 -0
  202. package/payload/server/public/assets/{useSubAccountSwitcher-iCzsV96x.css → useSubAccountSwitcher-DLqUQzOl.css} +1 -1
  203. package/payload/server/public/assets/useSubAccountSwitcher-DLqUQzOl.css.br +0 -0
  204. package/payload/server/public/assets/useSubAccountSwitcher-DLqUQzOl.css.gz +0 -0
  205. package/payload/server/public/assets/{useVoiceRecorder-BFrPC-s7.js → useVoiceRecorder-Cpw3aOSt.js} +1 -1
  206. package/payload/server/public/assets/useVoiceRecorder-Cpw3aOSt.js.br +0 -0
  207. package/payload/server/public/assets/useVoiceRecorder-Cpw3aOSt.js.gz +0 -0
  208. package/payload/server/public/assets/{wrench-CYgaN7K9.js → wrench-BBEup3hd.js} +1 -1
  209. package/payload/server/public/assets/wrench-BBEup3hd.js.br +0 -0
  210. package/payload/server/public/assets/wrench-BBEup3hd.js.gz +0 -0
  211. package/payload/server/public/browser.html +4 -4
  212. package/payload/server/public/calendar.html +7 -7
  213. package/payload/server/public/chat.html +13 -13
  214. package/payload/server/public/data.html +11 -11
  215. package/payload/server/public/graph.html +9 -9
  216. package/payload/server/public/index.html +14 -14
  217. package/payload/server/public/operator.html +14 -14
  218. package/payload/server/public/public.html +13 -13
  219. package/payload/server/public/routines.html +6 -6
  220. package/payload/server/public/skills.html +5 -5
  221. package/payload/server/public/tasks.html +6 -6
  222. package/payload/server/server.js +454 -352
  223. package/payload/server/public/assets/AdminLoginScreens-BZPbCk8g.js +0 -1
  224. package/payload/server/public/assets/AdminLoginScreens-BZPbCk8g.js.br +0 -0
  225. package/payload/server/public/assets/AdminLoginScreens-BZPbCk8g.js.gz +0 -0
  226. package/payload/server/public/assets/AdminShell-Bpo_wgxm.js.br +0 -0
  227. package/payload/server/public/assets/AdminShell-Bpo_wgxm.js.gz +0 -0
  228. package/payload/server/public/assets/activity-DOsfKzT3.js.br +0 -0
  229. package/payload/server/public/assets/activity-DOsfKzT3.js.gz +0 -0
  230. package/payload/server/public/assets/admin-COgD1z5a.js +0 -1
  231. package/payload/server/public/assets/admin-COgD1z5a.js.br +0 -0
  232. package/payload/server/public/assets/admin-COgD1z5a.js.gz +0 -0
  233. package/payload/server/public/assets/agents-DqDnZTH_.js.br +0 -0
  234. package/payload/server/public/assets/agents-DqDnZTH_.js.gz +0 -0
  235. package/payload/server/public/assets/browser-FL17Dfp0.js.br +0 -0
  236. package/payload/server/public/assets/browser-FL17Dfp0.js.gz +0 -0
  237. package/payload/server/public/assets/calendar-CLfLvsnV.js.br +0 -0
  238. package/payload/server/public/assets/calendar-CLfLvsnV.js.gz +0 -0
  239. package/payload/server/public/assets/chat-DYq4FxMG.js +0 -1
  240. package/payload/server/public/assets/chat-DYq4FxMG.js.br +0 -0
  241. package/payload/server/public/assets/chat-DYq4FxMG.js.gz +0 -0
  242. package/payload/server/public/assets/chevron-left-DWt5cdUo.js +0 -1
  243. package/payload/server/public/assets/chevron-right-B9suVrYy.js +0 -1
  244. package/payload/server/public/assets/chevron-right-B9suVrYy.js.br +0 -0
  245. package/payload/server/public/assets/clock-DW6qVXtv.js +0 -1
  246. package/payload/server/public/assets/clock-DW6qVXtv.js.br +0 -0
  247. package/payload/server/public/assets/clock-DW6qVXtv.js.gz +0 -0
  248. package/payload/server/public/assets/data-C8rbOgds.js +0 -1
  249. package/payload/server/public/assets/data-C8rbOgds.js.br +0 -0
  250. package/payload/server/public/assets/data-C8rbOgds.js.gz +0 -0
  251. package/payload/server/public/assets/file-text-DNm0AzUz.js.br +0 -0
  252. package/payload/server/public/assets/file-text-DNm0AzUz.js.gz +0 -0
  253. package/payload/server/public/assets/graph-fAvmlVzh.js.br +0 -0
  254. package/payload/server/public/assets/graph-fAvmlVzh.js.gz +0 -0
  255. package/payload/server/public/assets/graph-labels-CwdkCxfs.js.br +0 -0
  256. package/payload/server/public/assets/graph-labels-CwdkCxfs.js.gz +0 -0
  257. package/payload/server/public/assets/maximize-2-B6tAPhC2.js.br +0 -0
  258. package/payload/server/public/assets/maximize-2-B6tAPhC2.js.gz +0 -0
  259. package/payload/server/public/assets/operator-CTKvBVjk.js.br +0 -0
  260. package/payload/server/public/assets/operator-CTKvBVjk.js.gz +0 -0
  261. package/payload/server/public/assets/page-BWoNW3sa.js.br +0 -0
  262. package/payload/server/public/assets/page-BWoNW3sa.js.gz +0 -0
  263. package/payload/server/public/assets/page-O5HkHQw4.js.br +0 -0
  264. package/payload/server/public/assets/page-O5HkHQw4.js.gz +0 -0
  265. package/payload/server/public/assets/public-BF1rnVPa.js.br +0 -0
  266. package/payload/server/public/assets/public-BF1rnVPa.js.gz +0 -0
  267. package/payload/server/public/assets/rotate-ccw-B8TqfCy4.js.br +0 -0
  268. package/payload/server/public/assets/rotate-ccw-B8TqfCy4.js.gz +0 -0
  269. package/payload/server/public/assets/routines-4R7BLZyH.js.br +0 -0
  270. package/payload/server/public/assets/routines-4R7BLZyH.js.gz +0 -0
  271. package/payload/server/public/assets/skills-CQ9Qs2tg.js.br +0 -0
  272. package/payload/server/public/assets/skills-CQ9Qs2tg.js.gz +0 -0
  273. package/payload/server/public/assets/tasks-DePyOrRk.js.br +0 -0
  274. package/payload/server/public/assets/tasks-DePyOrRk.js.gz +0 -0
  275. package/payload/server/public/assets/time-entry-format-D9gtnG01.js.br +0 -0
  276. package/payload/server/public/assets/time-entry-format-D9gtnG01.js.gz +0 -0
  277. package/payload/server/public/assets/triangle-alert-DAtm2mLL.js.br +0 -0
  278. package/payload/server/public/assets/triangle-alert-DAtm2mLL.js.gz +0 -0
  279. package/payload/server/public/assets/useCopyFeedback-uMJT-p6i.js.br +0 -0
  280. package/payload/server/public/assets/useCopyFeedback-uMJT-p6i.js.gz +0 -0
  281. package/payload/server/public/assets/useSubAccountSwitcher-iCzsV96x.css.br +0 -0
  282. package/payload/server/public/assets/useSubAccountSwitcher-iCzsV96x.css.gz +0 -0
  283. package/payload/server/public/assets/useVoiceRecorder-BFrPC-s7.js.br +0 -0
  284. package/payload/server/public/assets/useVoiceRecorder-BFrPC-s7.js.gz +0 -0
  285. package/payload/server/public/assets/wrench-CYgaN7K9.js.br +0 -1
  286. package/payload/server/public/assets/wrench-CYgaN7K9.js.gz +0 -0
  287. /package/payload/server/public/assets/{useSubAccountSwitcher-BufCPDDH.js → useSubAccountSwitcher-CH9qm2Ad.js} +0 -0
  288. /package/payload/server/public/assets/{useSubAccountSwitcher-BufCPDDH.js.br → useSubAccountSwitcher-CH9qm2Ad.js.br} +0 -0
  289. /package/payload/server/public/assets/{useSubAccountSwitcher-BufCPDDH.js.gz → useSubAccountSwitcher-CH9qm2Ad.js.gz} +0 -0
@@ -1719,10 +1719,10 @@ var require_dist5 = __commonJS({
1719
1719
  });
1720
1720
 
1721
1721
  // server/index.ts
1722
- import { readFileSync as readFileSync43, existsSync as existsSync47, watchFile, readdirSync as readdirSync28, statSync as statSync24 } from "fs";
1722
+ import { readFileSync as readFileSync44, existsSync as existsSync48, watchFile, readdirSync as readdirSync28, statSync as statSync24 } from "fs";
1723
1723
  import { spawn as spawn3 } from "child_process";
1724
1724
  import { createHash as createHash7 } from "crypto";
1725
- import { resolve as resolve42, join as join49, basename as basename15 } from "path";
1725
+ import { resolve as resolve42, join as join50, basename as basename15 } from "path";
1726
1726
  import { homedir as homedir4 } from "os";
1727
1727
 
1728
1728
  // server/lib/route-cache-watchers.ts
@@ -2288,11 +2288,11 @@ function staticCacheHeaders(root) {
2288
2288
  }
2289
2289
 
2290
2290
  // server/lib/static-mounts.ts
2291
- function mountStaticFiles(app72, root) {
2292
- app72.use("/*", staticCacheHeaders(root));
2293
- app72.use("/assets/*", assetsVary);
2294
- app72.use("/assets/*", serveStatic({ root, precompressed: true }));
2295
- app72.use("/*", serveStatic({ root }));
2291
+ function mountStaticFiles(app73, root) {
2292
+ app73.use("/*", staticCacheHeaders(root));
2293
+ app73.use("/assets/*", assetsVary);
2294
+ app73.use("/assets/*", serveStatic({ root, precompressed: true }));
2295
+ app73.use("/*", serveStatic({ root }));
2296
2296
  }
2297
2297
  var assetsVary = async (c, next) => {
2298
2298
  await next();
@@ -3503,8 +3503,8 @@ function webchatTurnTimeoutMs() {
3503
3503
  return Number(process.env.WEBCHAT_TURN_TIMEOUT_MS ?? String(2 * 6e4));
3504
3504
  }
3505
3505
  function createChatRoutes(deps) {
3506
- const app72 = new Hono();
3507
- app72.post("/", async (c) => {
3506
+ const app73 = new Hono();
3507
+ app73.post("/", async (c) => {
3508
3508
  console.log(`[chat-route] entered route=public method=POST`);
3509
3509
  const contentType = c.req.header("content-type") ?? "";
3510
3510
  const account = resolveAccount();
@@ -3776,7 +3776,7 @@ ${result.result.text}` : result.result.text;
3776
3776
  }
3777
3777
  });
3778
3778
  });
3779
- return app72;
3779
+ return app73;
3780
3780
  }
3781
3781
 
3782
3782
  // app/lib/channel-pty-bridge/admin-session-id.ts
@@ -3810,8 +3810,8 @@ function isLoopbackAddr(addr) {
3810
3810
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
3811
3811
  }
3812
3812
  function createScheduleInjectRoutes(deps) {
3813
- const app72 = new Hono();
3814
- app72.post("/", async (c) => {
3813
+ const app73 = new Hono();
3814
+ app73.post("/", async (c) => {
3815
3815
  const env = c.env;
3816
3816
  const remoteAddr = env?.incoming?.socket?.remoteAddress ?? "";
3817
3817
  if (!isLoopbackAddr(remoteAddr)) {
@@ -3912,7 +3912,7 @@ function createScheduleInjectRoutes(deps) {
3912
3912
  console.error(`${TAG5} op=inject-spawn eventId=${eventId} sessionId=${sessionId} result=ok status=-`);
3913
3913
  return c.json({ ok: true }, 200);
3914
3914
  });
3915
- return app72;
3915
+ return app73;
3916
3916
  }
3917
3917
 
3918
3918
  // server/index.ts
@@ -6813,7 +6813,51 @@ function countConfigAbsent(platformRoot5, present) {
6813
6813
  return 0;
6814
6814
  }
6815
6815
  }
6816
- function discoverPortalAccounts(accountsDir) {
6816
+ var SAFE_AUDIT_ACCOUNT_ID = /^[a-z0-9-]+$/;
6817
+ function auditAccountClause(portal) {
6818
+ if (portal.storageModel !== "shared") {
6819
+ return { manifestWhere: "", directoryWhere: "", objectPrefix: void 0 };
6820
+ }
6821
+ if (!SAFE_AUDIT_ACCOUNT_ID.test(portal.accountId)) {
6822
+ throw new Error(
6823
+ `storage-broker: refusing to audit unsafe accountId "${portal.accountId}"`
6824
+ );
6825
+ }
6826
+ return {
6827
+ manifestWhere: ` WHERE accountId = '${portal.accountId}'`,
6828
+ directoryWhere: ` WHERE d.accountId = '${portal.accountId}'`,
6829
+ objectPrefix: `${portal.accountId}/`
6830
+ };
6831
+ }
6832
+ function readSharedStoreNames(platformRootDir) {
6833
+ let raw;
6834
+ try {
6835
+ raw = readFileSync8(join10(platformRootDir, "config", "cloudflare-house.env"), "utf-8");
6836
+ } catch {
6837
+ return null;
6838
+ }
6839
+ const env = {};
6840
+ for (const line of raw.split("\n")) {
6841
+ const m = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
6842
+ if (m) env[m[1]] = m[2].trim();
6843
+ }
6844
+ const dbName = env.DATA_PORTAL_DB_NAME;
6845
+ const bucket = env.DATA_PORTAL_BUCKET;
6846
+ return dbName && bucket ? { dbName, bucket } : null;
6847
+ }
6848
+ function resolveStorageModel(cfg, shared, onDisagree) {
6849
+ const labelled = cfg.storageModel === "shared" ? "shared" : "dedicated";
6850
+ if (!shared) return labelled;
6851
+ const namesShared = cfg.portalDbName === shared.dbName || cfg.bucketName === shared.bucket;
6852
+ const derived = namesShared ? "shared" : "dedicated";
6853
+ if (derived !== labelled && onDisagree) {
6854
+ onDisagree(
6855
+ `[storage-broker] op=storage-model result=overridden labelled=${labelled} derived=${derived} db=${cfg.portalDbName} bucket=${cfg.bucketName}`
6856
+ );
6857
+ }
6858
+ return derived;
6859
+ }
6860
+ function discoverPortalAccounts(accountsDir, shared = null) {
6817
6861
  if (!existsSync6(accountsDir)) return [];
6818
6862
  const found = [];
6819
6863
  for (const accountId of readdirSync5(accountsDir)) {
@@ -6822,7 +6866,20 @@ function discoverPortalAccounts(accountsDir) {
6822
6866
  try {
6823
6867
  const cfg = JSON.parse(readFileSync8(configPath2, "utf-8"));
6824
6868
  if (typeof cfg.portalDbName === "string" && cfg.portalDbName.length > 0 && typeof cfg.bucketName === "string" && cfg.bucketName.length > 0) {
6825
- found.push({ accountId, portalDbName: cfg.portalDbName, bucketName: cfg.bucketName });
6869
+ found.push({
6870
+ accountId,
6871
+ portalDbName: cfg.portalDbName,
6872
+ bucketName: cfg.bucketName,
6873
+ storageModel: resolveStorageModel(
6874
+ {
6875
+ portalDbName: cfg.portalDbName,
6876
+ bucketName: cfg.bucketName,
6877
+ storageModel: cfg.storageModel
6878
+ },
6879
+ shared,
6880
+ (line) => console.error(`${line} account=${accountId}`)
6881
+ )
6882
+ });
6826
6883
  }
6827
6884
  } catch {
6828
6885
  }
@@ -6830,7 +6887,10 @@ function discoverPortalAccounts(accountsDir) {
6830
6887
  return found;
6831
6888
  }
6832
6889
  async function runDataPortalAudit(root) {
6833
- const portals = discoverPortalAccounts(resolve7(root, "..", "data", "accounts"));
6890
+ const portals = discoverPortalAccounts(
6891
+ resolve7(root, "..", "data", "accounts"),
6892
+ readSharedStoreNames(root)
6893
+ );
6834
6894
  const configAbsent = countConfigAbsent(root, portals);
6835
6895
  if (portals.length === 0) {
6836
6896
  if (configAbsent > 0) {
@@ -6841,13 +6901,14 @@ async function runDataPortalAudit(root) {
6841
6901
  const cf = await makeHouseCfExec(root);
6842
6902
  let degraded = 0;
6843
6903
  for (const portal of portals) {
6904
+ const scope = auditAccountClause(portal);
6844
6905
  let rows = null;
6845
6906
  let d1Error = null;
6846
6907
  try {
6847
6908
  rows = parseManifestRows(
6848
6909
  await cf.d1Query(
6849
6910
  portal.portalDbName,
6850
- "SELECT objectKey, ingested, uploadedAt, devicePath, deleted FROM manifest"
6911
+ "SELECT objectKey, ingested, uploadedAt, devicePath, deleted FROM manifest" + scope.manifestWhere
6851
6912
  )
6852
6913
  );
6853
6914
  } catch (err) {
@@ -6857,7 +6918,7 @@ async function runDataPortalAudit(root) {
6857
6918
  try {
6858
6919
  const published = await cf.d1Query(
6859
6920
  portal.portalDbName,
6860
- "SELECT d.relPath AS relPath FROM directory d JOIN directory_state s ON s.accountId = d.accountId AND s.currentGeneration = d.generation"
6921
+ "SELECT d.relPath AS relPath FROM directory d JOIN directory_state s ON s.accountId = d.accountId AND s.currentGeneration = d.generation" + scope.directoryWhere
6861
6922
  );
6862
6923
  const envelope = Array.isArray(published) ? published[0] : null;
6863
6924
  const results = envelope?.results;
@@ -6872,7 +6933,7 @@ async function runDataPortalAudit(root) {
6872
6933
  let objects = null;
6873
6934
  let r2Error = null;
6874
6935
  try {
6875
- objects = await cf.r2ObjectList(portal.bucketName);
6936
+ objects = await cf.r2ObjectList(portal.bucketName, scope.objectPrefix);
6876
6937
  } catch (err) {
6877
6938
  r2Error = err.message;
6878
6939
  }
@@ -7157,7 +7218,17 @@ function exposedOrOwnUploads(segments, exposed, ownerId) {
7157
7218
  if (exposed.includes(segments[0])) return true;
7158
7219
  return segments.length > 2 && segments[0] === "uploads" && segments[1] === ownerId;
7159
7220
  }
7160
- var PENDING_SELECT = "SELECT fileId, ownerId, filename, objectKey, size, targetPath, devicePath, deleted FROM manifest WHERE ingested = 0 OR deleted = 1";
7221
+ var PENDING_COLUMNS = "SELECT fileId, ownerId, filename, objectKey, size, targetPath, devicePath, deleted FROM manifest WHERE (ingested = 0 OR deleted = 1)";
7222
+ var SAFE_ACCOUNT_ID = /^[a-z0-9-]+$/;
7223
+ function pendingSelect(portal) {
7224
+ if (portal.storageModel !== "shared") return PENDING_COLUMNS;
7225
+ if (!SAFE_ACCOUNT_ID.test(portal.accountId)) {
7226
+ throw new Error(
7227
+ `portal-uploads-pull: refusing to build a query for unsafe accountId "${portal.accountId}"`
7228
+ );
7229
+ }
7230
+ return `${PENDING_COLUMNS} AND accountId = '${portal.accountId}'`;
7231
+ }
7161
7232
  function parsePendingRows(raw) {
7162
7233
  const envelope = Array.isArray(raw) ? raw[0] : null;
7163
7234
  const results = envelope?.results;
@@ -7208,7 +7279,7 @@ async function readExposedDirs(accountDir) {
7208
7279
  }
7209
7280
  async function runPortalUploadsPull(root) {
7210
7281
  const accountsRoot = resolve8(root, "..", "data", "accounts");
7211
- const portals = discoverPortalAccounts(accountsRoot);
7282
+ const portals = discoverPortalAccounts(accountsRoot, readSharedStoreNames(root));
7212
7283
  if (portals.length === 0) return "portals=0 pulled=0";
7213
7284
  const cf = await makeHouseCfExec(root);
7214
7285
  let pulledTotal = 0;
@@ -7217,7 +7288,7 @@ async function runPortalUploadsPull(root) {
7217
7288
  for (const portal of portals) {
7218
7289
  try {
7219
7290
  const { rows, malformed } = parsePendingRows(
7220
- await cf.d1Query(portal.portalDbName, PENDING_SELECT)
7291
+ await cf.d1Query(portal.portalDbName, pendingSelect(portal))
7221
7292
  );
7222
7293
  if (malformed > 0) {
7223
7294
  console.error(`${TAG14} op=malformed account=${portal.accountId} rows=${malformed}`);
@@ -11009,8 +11080,8 @@ async function reapplyLeversViaManager() {
11009
11080
  var WEBCHAT_SEND_TURN_WINDOW_MS = Number(process.env.WEBCHAT_SEND_TURN_WINDOW_MS ?? String(15e3));
11010
11081
  var sendSeq = 0;
11011
11082
  function createWebchatRoutes(deps) {
11012
- const app72 = new Hono();
11013
- app72.post("/send", requireAdminSession, async (c) => {
11083
+ const app73 = new Hono();
11084
+ app73.post("/send", requireAdminSession, async (c) => {
11014
11085
  let accountId;
11015
11086
  try {
11016
11087
  accountId = resolvePlatformAccountId();
@@ -11208,7 +11279,7 @@ ${note}` : note;
11208
11279
  if (turnTimer.unref) turnTimer.unref();
11209
11280
  return c.json({ ok: true });
11210
11281
  });
11211
- app72.post("/interrupt", requireAdminSession, async (c) => {
11282
+ app73.post("/interrupt", requireAdminSession, async (c) => {
11212
11283
  const cacheKey = c.get("cacheKey");
11213
11284
  const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
11214
11285
  const primaryUserId = resolvePrimaryAdminUserId();
@@ -11236,7 +11307,7 @@ ${note}` : note;
11236
11307
  }
11237
11308
  return c.json({ ok: true, stopped: outcome.stopped, intId: outcome.intId, deadChild: outcome.deadChild }, 200);
11238
11309
  });
11239
- app72.post("/settings", requireAdminSession, async (c) => {
11310
+ app73.post("/settings", requireAdminSession, async (c) => {
11240
11311
  const body = await c.req.json().catch(() => null);
11241
11312
  const op = body?.op;
11242
11313
  const value = body?.value;
@@ -11272,7 +11343,7 @@ ${note}` : note;
11272
11343
  console.log(`[webchat:settings] op=${op} outcome=accepted accountId=${account.accountId.slice(0, 8)} value=${value} settingsApplied=${settingsApplied}`);
11273
11344
  return c.json({ ok: true, settingsApplied });
11274
11345
  });
11275
- app72.get("/session", requireAdminSession, async (c) => {
11346
+ app73.get("/session", requireAdminSession, async (c) => {
11276
11347
  let accountId;
11277
11348
  try {
11278
11349
  accountId = resolvePlatformAccountId();
@@ -11345,7 +11416,7 @@ ${note}` : note;
11345
11416
  const indicators = await fetchComposerIndicators(sessionId);
11346
11417
  return c.json({ sessionId, projectDir, source, sizeBytes: jsonlSizeBytes(projectDir, sessionId), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${sessionId}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${sessionId}`) ?? null, ...indicators, ...readLevers(account) });
11347
11418
  });
11348
- app72.post("/permission-verdict", requireAdminSession, async (c) => {
11419
+ app73.post("/permission-verdict", requireAdminSession, async (c) => {
11349
11420
  const body = await c.req.json().catch(() => null);
11350
11421
  const sessionId = body?.sessionId;
11351
11422
  const requestId = body?.request_id;
@@ -11362,7 +11433,7 @@ ${note}` : note;
11362
11433
  const ok = deps.resolvePermissionVerdict?.(`session:${sessionId}`, requestId, behavior) ?? false;
11363
11434
  return c.json({ ok });
11364
11435
  });
11365
- return app72;
11436
+ return app73;
11366
11437
  }
11367
11438
 
11368
11439
  // server/routes/webchat-greeting.ts
@@ -21877,10 +21948,40 @@ app49.get("/booking-link", requireAdminSession, (c) => {
21877
21948
  });
21878
21949
  var calendar_default = app49;
21879
21950
 
21951
+ // server/routes/admin/data-portal.ts
21952
+ import { existsSync as existsSync38, readFileSync as readFileSync35 } from "fs";
21953
+ import { join as join44 } from "path";
21954
+ var app50 = new Hono();
21955
+ var PORTAL_FILENAME = "data-portal.json";
21956
+ app50.get("/portal-link", requireAdminSession, (c) => {
21957
+ const account = accountDirForSession(c.var.cacheKey);
21958
+ if (!account) {
21959
+ console.error("[data-portal] op=portal-link auth-rejected reason=no-account-for-session accountId=none");
21960
+ return c.json({ error: "no account for session", reason: "no-account-for-session" }, 401);
21961
+ }
21962
+ const id82 = account.accountId.slice(0, 8);
21963
+ try {
21964
+ const path = join44(account.accountDir, PORTAL_FILENAME);
21965
+ if (!existsSync38(path)) {
21966
+ console.log(`[data-portal] op=portal-link accountId=${id82} portalDomain=none source=data-portal-config`);
21967
+ return c.json({ portalDomain: null });
21968
+ }
21969
+ const cfg = JSON.parse(readFileSync35(path, "utf-8"));
21970
+ const portalDomain = typeof cfg.portalDomain === "string" && cfg.portalDomain.trim() ? cfg.portalDomain.trim() : null;
21971
+ console.log(`[data-portal] op=portal-link accountId=${id82} portalDomain=${portalDomain ?? "none"} source=data-portal-config`);
21972
+ return c.json({ portalDomain });
21973
+ } catch (err) {
21974
+ const message = err instanceof Error ? err.message : String(err);
21975
+ console.error(`[data-portal] op=portal-link-fail accountId=${id82} err="${message}"`);
21976
+ return c.json({ portalDomain: null });
21977
+ }
21978
+ });
21979
+ var data_portal_default = app50;
21980
+
21880
21981
  // server/routes/admin/routines.ts
21881
21982
  import cronParser from "cron-parser";
21882
21983
  var { parseExpression } = cronParser;
21883
- var app50 = new Hono();
21984
+ var app51 = new Hono();
21884
21985
  var AUTOMATION_WHERE = "(e.recurrence IS NOT NULL OR e.agentChannel IS NOT NULL OR e.actionPlugin IS NOT NULL)";
21885
21986
  var ROUTINE_COLS = `e.eventId AS eventId, e.name AS name, e.eventStatus AS eventStatus,
21886
21987
  e.recurrence AS recurrence, e.nextRun AS nextRun, e.lastTriggered AS lastTriggered,
@@ -21910,7 +22011,7 @@ function mapRoutine(r) {
21910
22011
  lastDispatchAt: g("lastDispatchAt")
21911
22012
  };
21912
22013
  }
21913
- app50.get("/", requireAdminSession, async (c) => {
22014
+ app51.get("/", requireAdminSession, async (c) => {
21914
22015
  const accountId = getAccountIdForSession(c.var.cacheKey);
21915
22016
  if (!accountId) {
21916
22017
  console.error('[admin:routines] op=list auth-rejected reason="no account for session"');
@@ -21936,7 +22037,7 @@ app50.get("/", requireAdminSession, async (c) => {
21936
22037
  await session.close();
21937
22038
  }
21938
22039
  });
21939
- app50.get("/:eventId", requireAdminSession, async (c) => {
22040
+ app51.get("/:eventId", requireAdminSession, async (c) => {
21940
22041
  const accountId = getAccountIdForSession(c.var.cacheKey);
21941
22042
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
21942
22043
  const eventId = c.req.param("eventId");
@@ -21960,7 +22061,7 @@ app50.get("/:eventId", requireAdminSession, async (c) => {
21960
22061
  await session.close();
21961
22062
  }
21962
22063
  });
21963
- app50.patch("/:eventId", requireAdminSession, async (c) => {
22064
+ app51.patch("/:eventId", requireAdminSession, async (c) => {
21964
22065
  const accountId = getAccountIdForSession(c.var.cacheKey);
21965
22066
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
21966
22067
  const eventId = c.req.param("eventId");
@@ -22030,7 +22131,7 @@ app50.patch("/:eventId", requireAdminSession, async (c) => {
22030
22131
  await session.close();
22031
22132
  }
22032
22133
  });
22033
- app50.delete("/:eventId", requireAdminSession, async (c) => {
22134
+ app51.delete("/:eventId", requireAdminSession, async (c) => {
22034
22135
  const accountId = getAccountIdForSession(c.var.cacheKey);
22035
22136
  if (!accountId) {
22036
22137
  console.error('[admin:routines] op=delete auth-rejected reason="no account for session"');
@@ -22058,12 +22159,12 @@ app50.delete("/:eventId", requireAdminSession, async (c) => {
22058
22159
  await session.close();
22059
22160
  }
22060
22161
  });
22061
- var routines_default = app50;
22162
+ var routines_default = app51;
22062
22163
 
22063
22164
  // server/routes/admin/skills.ts
22064
- import { existsSync as existsSync38, readdirSync as readdirSync24, readFileSync as readFileSync35, rmSync as rmSync3 } from "fs";
22165
+ import { existsSync as existsSync39, readdirSync as readdirSync24, readFileSync as readFileSync36, rmSync as rmSync3 } from "fs";
22065
22166
  import { resolve as resolve30 } from "path";
22066
- var app51 = new Hono();
22167
+ var app52 = new Hono();
22067
22168
  var NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
22068
22169
  function splitSkillMd(text) {
22069
22170
  const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
@@ -22085,14 +22186,14 @@ function stripQuotes(s) {
22085
22186
  return s;
22086
22187
  }
22087
22188
  function subdirs2(dir) {
22088
- if (!existsSync38(dir)) return [];
22189
+ if (!existsSync39(dir)) return [];
22089
22190
  try {
22090
22191
  return readdirSync24(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
22091
22192
  } catch {
22092
22193
  return [];
22093
22194
  }
22094
22195
  }
22095
- app51.get("/", requireAdminSession, async (c) => {
22196
+ app52.get("/", requireAdminSession, async (c) => {
22096
22197
  const acct = accountDirForSession(c.var.cacheKey);
22097
22198
  if (!acct) {
22098
22199
  console.error('[admin:skills] op=list auth-rejected reason="no account for session"');
@@ -22108,11 +22209,11 @@ app51.get("/", requireAdminSession, async (c) => {
22108
22209
  const skillsDir = resolve30(pluginsDir, plugin, "skills");
22109
22210
  for (const skill of subdirs2(skillsDir)) {
22110
22211
  const skillMd = resolve30(skillsDir, skill, "SKILL.md");
22111
- if (!existsSync38(skillMd)) continue;
22212
+ if (!existsSync39(skillMd)) continue;
22112
22213
  try {
22113
- const { frontmatter } = splitSkillMd(readFileSync35(skillMd, "utf-8"));
22214
+ const { frontmatter } = splitSkillMd(readFileSync36(skillMd, "utf-8"));
22114
22215
  const refsDir = resolve30(skillsDir, skill, "references");
22115
- const refCount = existsSync38(refsDir) ? readdirSync24(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).length : 0;
22216
+ const refCount = existsSync39(refsDir) ? readdirSync24(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).length : 0;
22116
22217
  skills.push({ plugin, skill, description: frontmatter.description, refCount });
22117
22218
  } catch (err) {
22118
22219
  console.error(`[admin:skills] op=list-skip plugin=${plugin} skill=${skill} reason="${err instanceof Error ? err.message : String(err)}"`);
@@ -22125,7 +22226,7 @@ app51.get("/", requireAdminSession, async (c) => {
22125
22226
  console.log(`[admin:skills] op=list accountId=${acct.accountId.slice(0, 8)} plugins=${value.pluginCount} skills=${value.skills.length} cache=${state}`);
22126
22227
  return c.json({ skills: value.skills });
22127
22228
  });
22128
- app51.get("/:plugin/:skill", requireAdminSession, async (c) => {
22229
+ app52.get("/:plugin/:skill", requireAdminSession, async (c) => {
22129
22230
  const acct = accountDirForSession(c.var.cacheKey);
22130
22231
  if (!acct) return c.json({ error: "Account not found for session" }, 401);
22131
22232
  const plugin = c.req.param("plugin");
@@ -22136,13 +22237,13 @@ app51.get("/:plugin/:skill", requireAdminSession, async (c) => {
22136
22237
  }
22137
22238
  const skillDir = resolve30(acct.accountDir, "plugins", plugin, "skills", skill);
22138
22239
  const skillMd = resolve30(skillDir, "SKILL.md");
22139
- const found = existsSync38(skillMd);
22240
+ const found = existsSync39(skillMd);
22140
22241
  console.log(`[admin:skills] op=get plugin=${plugin} skill=${skill} found=${found}`);
22141
22242
  if (!found) return c.json({ error: "Skill not found" }, 404);
22142
22243
  try {
22143
- const { frontmatter, body } = splitSkillMd(readFileSync35(skillMd, "utf-8"));
22244
+ const { frontmatter, body } = splitSkillMd(readFileSync36(skillMd, "utf-8"));
22144
22245
  const refsDir = resolve30(skillDir, "references");
22145
- const references = existsSync38(refsDir) ? readdirSync24(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).map((e) => e.name).sort() : [];
22246
+ const references = existsSync39(refsDir) ? readdirSync24(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).map((e) => e.name).sort() : [];
22146
22247
  return c.json({ skill: { plugin, skill, frontmatter, body, references } });
22147
22248
  } catch (err) {
22148
22249
  const message = err instanceof Error ? err.message : String(err);
@@ -22150,7 +22251,7 @@ app51.get("/:plugin/:skill", requireAdminSession, async (c) => {
22150
22251
  return c.json({ error: `Skill unavailable: ${message}` }, 503);
22151
22252
  }
22152
22253
  });
22153
- app51.delete("/:plugin/:skill", requireAdminSession, async (c) => {
22254
+ app52.delete("/:plugin/:skill", requireAdminSession, async (c) => {
22154
22255
  const acct = accountDirForSession(c.var.cacheKey);
22155
22256
  if (!acct) return c.json({ error: "Account not found for session" }, 401);
22156
22257
  const plugin = c.req.param("plugin");
@@ -22162,7 +22263,7 @@ app51.delete("/:plugin/:skill", requireAdminSession, async (c) => {
22162
22263
  const pluginDir = resolve30(acct.accountDir, "plugins", plugin);
22163
22264
  const skillsDir = resolve30(pluginDir, "skills");
22164
22265
  const skillDir = resolve30(skillsDir, skill);
22165
- if (!existsSync38(resolve30(skillDir, "SKILL.md"))) {
22266
+ if (!existsSync39(resolve30(skillDir, "SKILL.md"))) {
22166
22267
  console.error(`[admin:skills] op=delete outcome=rejected reason=not-found plugin=${plugin} skill=${skill}`);
22167
22268
  return c.json({ error: "Skill not found" }, 404);
22168
22269
  }
@@ -22170,7 +22271,7 @@ app51.delete("/:plugin/:skill", requireAdminSession, async (c) => {
22170
22271
  rmSync3(skillDir, { recursive: true, force: true });
22171
22272
  const pluginDirRemoved = subdirs2(skillsDir).length === 0;
22172
22273
  if (pluginDirRemoved) rmSync3(pluginDir, { recursive: true, force: true });
22173
- const skillDirGone = !existsSync38(skillDir);
22274
+ const skillDirGone = !existsSync39(skillDir);
22174
22275
  if (!skillDirGone) {
22175
22276
  console.error(`[admin:skills] op=delete plugin=${plugin} skill=${skill} outcome=rejected reason=rm-incomplete skillDirGone=false`);
22176
22277
  return c.json({ error: "Delete did not remove the skill directory" }, 503);
@@ -22183,7 +22284,7 @@ app51.delete("/:plugin/:skill", requireAdminSession, async (c) => {
22183
22284
  return c.json({ error: `Delete failed: ${message}` }, 503);
22184
22285
  }
22185
22286
  });
22186
- var skills_default = app51;
22287
+ var skills_default = app52;
22187
22288
 
22188
22289
  // app/lib/time-entry-format.ts
22189
22290
  function secondsBetween(startIso, endIso) {
@@ -22206,8 +22307,8 @@ function toNum(v) {
22206
22307
  var TAG27 = "[task-timer]";
22207
22308
  var COMPLETED = /* @__PURE__ */ new Set(["completed"]);
22208
22309
  var HIDDEN_FROM_OPEN = /* @__PURE__ */ new Set(["completed", "cancelled"]);
22209
- var app52 = new Hono();
22210
- app52.get("/", requireAdminSession, async (c) => {
22310
+ var app53 = new Hono();
22311
+ app53.get("/", requireAdminSession, async (c) => {
22211
22312
  const cacheKey = c.var.cacheKey;
22212
22313
  const accountId = getAccountIdForSession(cacheKey);
22213
22314
  if (!accountId) {
@@ -22313,13 +22414,13 @@ async function computeTaskList(accountId) {
22313
22414
  await session.close();
22314
22415
  }
22315
22416
  }
22316
- var tasks_list_default = app52;
22417
+ var tasks_list_default = app53;
22317
22418
 
22318
22419
  // server/routes/admin/task-timer-start.ts
22319
22420
  import { randomUUID as randomUUID10 } from "crypto";
22320
22421
  var TAG28 = "[task-timer]";
22321
- var app53 = new Hono();
22322
- app53.post("/", requireAdminSession, async (c) => {
22422
+ var app54 = new Hono();
22423
+ app54.post("/", requireAdminSession, async (c) => {
22323
22424
  const cacheKey = c.var.cacheKey;
22324
22425
  const accountId = getAccountIdForSession(cacheKey);
22325
22426
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -22376,13 +22477,13 @@ app53.post("/", requireAdminSession, async (c) => {
22376
22477
  await session.close();
22377
22478
  }
22378
22479
  });
22379
- var task_timer_start_default = app53;
22480
+ var task_timer_start_default = app54;
22380
22481
 
22381
22482
  // server/routes/admin/task-timer-stop.ts
22382
22483
  import neo4j4 from "neo4j-driver";
22383
22484
  var TAG29 = "[task-timer]";
22384
- var app54 = new Hono();
22385
- app54.post("/", requireAdminSession, async (c) => {
22485
+ var app55 = new Hono();
22486
+ app55.post("/", requireAdminSession, async (c) => {
22386
22487
  const cacheKey = c.var.cacheKey;
22387
22488
  const accountId = getAccountIdForSession(cacheKey);
22388
22489
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -22451,12 +22552,12 @@ app54.post("/", requireAdminSession, async (c) => {
22451
22552
  await session.close();
22452
22553
  }
22453
22554
  });
22454
- var task_timer_stop_default = app54;
22555
+ var task_timer_stop_default = app55;
22455
22556
 
22456
22557
  // server/routes/admin/task-complete.ts
22457
22558
  var TAG30 = "[task-timer]";
22458
- var app55 = new Hono();
22459
- app55.post("/", requireAdminSession, async (c) => {
22559
+ var app56 = new Hono();
22560
+ app56.post("/", requireAdminSession, async (c) => {
22460
22561
  const cacheKey = c.var.cacheKey;
22461
22562
  const accountId = getAccountIdForSession(cacheKey);
22462
22563
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -22495,14 +22596,14 @@ app55.post("/", requireAdminSession, async (c) => {
22495
22596
  await session.close();
22496
22597
  }
22497
22598
  });
22498
- var task_complete_default = app55;
22599
+ var task_complete_default = app56;
22499
22600
 
22500
22601
  // server/routes/admin/task-time-adjust.ts
22501
22602
  import { randomUUID as randomUUID11 } from "crypto";
22502
22603
  import neo4j5 from "neo4j-driver";
22503
22604
  var TAG31 = "[task-time-adjust]";
22504
- var app56 = new Hono();
22505
- app56.post("/", requireAdminSession, async (c) => {
22605
+ var app57 = new Hono();
22606
+ app57.post("/", requireAdminSession, async (c) => {
22506
22607
  const cacheKey = c.var.cacheKey;
22507
22608
  const accountId = getAccountIdForSession(cacheKey);
22508
22609
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -22577,10 +22678,10 @@ app56.post("/", requireAdminSession, async (c) => {
22577
22678
  await session.close();
22578
22679
  }
22579
22680
  });
22580
- var task_time_adjust_default = app56;
22681
+ var task_time_adjust_default = app57;
22581
22682
 
22582
22683
  // app/lib/admin-roster.ts
22583
- import { existsSync as existsSync39, readdirSync as readdirSync25, readFileSync as readFileSync36 } from "fs";
22684
+ import { existsSync as existsSync40, readdirSync as readdirSync25, readFileSync as readFileSync37 } from "fs";
22584
22685
  import { resolve as resolve31 } from "path";
22585
22686
  function readHouseAdminUserIds(accountsDir = ACCOUNTS_DIR) {
22586
22687
  let entries2;
@@ -22591,9 +22692,9 @@ function readHouseAdminUserIds(accountsDir = ACCOUNTS_DIR) {
22591
22692
  }
22592
22693
  for (const entry of entries2) {
22593
22694
  const cfgPath = resolve31(accountsDir, entry, "account.json");
22594
- if (!existsSync39(cfgPath)) continue;
22695
+ if (!existsSync40(cfgPath)) continue;
22595
22696
  try {
22596
- const cfg = JSON.parse(readFileSync36(cfgPath, "utf-8"));
22697
+ const cfg = JSON.parse(readFileSync37(cfgPath, "utf-8"));
22597
22698
  if (cfg.role !== "house") continue;
22598
22699
  if (!Array.isArray(cfg.admins)) return [];
22599
22700
  return cfg.admins.map(
@@ -22665,8 +22766,8 @@ async function resolveAssignableAdmins(accountId, accountsDir = ACCOUNTS_DIR) {
22665
22766
 
22666
22767
  // server/routes/admin/task-assign.ts
22667
22768
  var TAG32 = "[task-assign]";
22668
- var app57 = new Hono();
22669
- app57.post("/", requireAdminSession, async (c) => {
22769
+ var app58 = new Hono();
22770
+ app58.post("/", requireAdminSession, async (c) => {
22670
22771
  const cacheKey = c.var.cacheKey;
22671
22772
  const accountId = getAccountIdForSession(cacheKey);
22672
22773
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -22748,12 +22849,12 @@ app57.post("/", requireAdminSession, async (c) => {
22748
22849
  await session.close();
22749
22850
  }
22750
22851
  });
22751
- var task_assign_default = app57;
22852
+ var task_assign_default = app58;
22752
22853
 
22753
22854
  // server/routes/admin/admin-users-list.ts
22754
22855
  var TAG33 = "[admin-users]";
22755
- var app58 = new Hono();
22756
- app58.get("/", requireAdminSession, async (c) => {
22856
+ var app59 = new Hono();
22857
+ app59.get("/", requireAdminSession, async (c) => {
22757
22858
  const cacheKey = c.var.cacheKey;
22758
22859
  const accountId = getAccountIdForSession(cacheKey);
22759
22860
  if (!accountId) {
@@ -22769,11 +22870,11 @@ app58.get("/", requireAdminSession, async (c) => {
22769
22870
  return c.json({ error: "admin-users-list-failed" }, 500);
22770
22871
  }
22771
22872
  });
22772
- var admin_users_list_default = app58;
22873
+ var admin_users_list_default = app59;
22773
22874
 
22774
22875
  // server/routes/admin/activity.ts
22775
22876
  import { readdirSync as readdirSync26 } from "fs";
22776
- var app59 = new Hono();
22877
+ var app60 = new Hono();
22777
22878
  var TAG34 = "[activity]";
22778
22879
  function resolveHouseAccountId(accounts) {
22779
22880
  const houses = accounts.filter((a) => a.config.role === "house");
@@ -22795,7 +22896,7 @@ function countAccountDirsOnDisk() {
22795
22896
  return null;
22796
22897
  }
22797
22898
  }
22798
- app59.get("/", requireAdminSession, async (c) => {
22899
+ app60.get("/", requireAdminSession, async (c) => {
22799
22900
  const req = requestToken();
22800
22901
  const cacheKey = c.var.cacheKey;
22801
22902
  const caller2 = getAccountIdForSession(cacheKey) ?? null;
@@ -22904,65 +23005,66 @@ app59.get("/", requireAdminSession, async (c) => {
22904
23005
  }
22905
23006
  });
22906
23007
  });
22907
- var activity_default = app59;
23008
+ var activity_default = app60;
22908
23009
 
22909
23010
  // server/routes/admin/index.ts
22910
- var app60 = new Hono();
22911
- app60.route("/session", session_default);
22912
- app60.route("/accounts", accounts_default);
22913
- app60.route("/logs", logs_default);
22914
- app60.route("/claude-info", claude_info_default);
22915
- app60.route("/attachment", attachment_default);
22916
- app60.route("/session-upload", session_upload_default);
22917
- app60.route("/agents", agents_default);
22918
- app60.route("/sessions", sessions_default);
22919
- app60.route("/claude-sessions", claude_sessions_default);
22920
- app60.route("/log-ingest", log_ingest_default);
22921
- app60.route("/events", events_default);
22922
- app60.route("/files", files_default);
22923
- app60.route("/graph-search", graph_search_default);
22924
- app60.route("/graph-subgraph", graph_subgraph_default);
22925
- app60.route("/graph-delete", graph_delete_default);
22926
- app60.route("/graph-restore", graph_restore_default);
22927
- app60.route("/graph-labels-in-graph", graph_labels_in_graph_default);
22928
- app60.route("/graph-default-view", graph_default_view_default);
22929
- app60.route("/sidebar-artefacts", sidebar_artefacts_default);
22930
- app60.route("/sidebar-sessions", sidebar_sessions_default);
22931
- app60.route("/session-delete", session_delete_default);
22932
- app60.route("/session-stop", session_stop_default);
22933
- app60.route("/session-archive", session_archive_default);
22934
- app60.route("/session-rename", session_rename_default);
22935
- app60.route("/session-usage", session_usage_default);
22936
- app60.route("/browser", browser_default);
22937
- app60.route("/session-rc-spawn", session_rc_spawn_default);
22938
- app60.route("/session-reseat", session_reseat_default);
22939
- app60.route("/system-stats", system_stats_default);
22940
- app60.route("/health-brand", health_default2);
22941
- app60.route("/linkedin-ingest", linkedin_ingest_default);
22942
- app60.route("/post-turn-context", post_turn_context_default);
22943
- app60.route("/public-session-context", public_session_context_default);
22944
- app60.route("/public-session-exit", public_session_exit_default);
22945
- app60.route("/access-session-evict", access_session_evict_default);
22946
- app60.route("/enrol-person", enrol_person_default);
22947
- app60.route("/calendar", calendar_default);
22948
- app60.route("/routines", routines_default);
22949
- app60.route("/skills", skills_default);
22950
- app60.route("/tasks-list", tasks_list_default);
22951
- app60.route("/task-timer-start", task_timer_start_default);
22952
- app60.route("/task-timer-stop", task_timer_stop_default);
22953
- app60.route("/task-complete", task_complete_default);
22954
- app60.route("/task-time-adjust", task_time_adjust_default);
22955
- app60.route("/task-assign", task_assign_default);
22956
- app60.route("/admin-users-list", admin_users_list_default);
22957
- app60.route("/activity", activity_default);
22958
- var admin_default = app60;
23011
+ var app61 = new Hono();
23012
+ app61.route("/session", session_default);
23013
+ app61.route("/accounts", accounts_default);
23014
+ app61.route("/logs", logs_default);
23015
+ app61.route("/claude-info", claude_info_default);
23016
+ app61.route("/attachment", attachment_default);
23017
+ app61.route("/session-upload", session_upload_default);
23018
+ app61.route("/agents", agents_default);
23019
+ app61.route("/sessions", sessions_default);
23020
+ app61.route("/claude-sessions", claude_sessions_default);
23021
+ app61.route("/log-ingest", log_ingest_default);
23022
+ app61.route("/events", events_default);
23023
+ app61.route("/files", files_default);
23024
+ app61.route("/graph-search", graph_search_default);
23025
+ app61.route("/graph-subgraph", graph_subgraph_default);
23026
+ app61.route("/graph-delete", graph_delete_default);
23027
+ app61.route("/graph-restore", graph_restore_default);
23028
+ app61.route("/graph-labels-in-graph", graph_labels_in_graph_default);
23029
+ app61.route("/graph-default-view", graph_default_view_default);
23030
+ app61.route("/sidebar-artefacts", sidebar_artefacts_default);
23031
+ app61.route("/sidebar-sessions", sidebar_sessions_default);
23032
+ app61.route("/session-delete", session_delete_default);
23033
+ app61.route("/session-stop", session_stop_default);
23034
+ app61.route("/session-archive", session_archive_default);
23035
+ app61.route("/session-rename", session_rename_default);
23036
+ app61.route("/session-usage", session_usage_default);
23037
+ app61.route("/browser", browser_default);
23038
+ app61.route("/session-rc-spawn", session_rc_spawn_default);
23039
+ app61.route("/session-reseat", session_reseat_default);
23040
+ app61.route("/system-stats", system_stats_default);
23041
+ app61.route("/health-brand", health_default2);
23042
+ app61.route("/linkedin-ingest", linkedin_ingest_default);
23043
+ app61.route("/post-turn-context", post_turn_context_default);
23044
+ app61.route("/public-session-context", public_session_context_default);
23045
+ app61.route("/public-session-exit", public_session_exit_default);
23046
+ app61.route("/access-session-evict", access_session_evict_default);
23047
+ app61.route("/enrol-person", enrol_person_default);
23048
+ app61.route("/calendar", calendar_default);
23049
+ app61.route("/data-portal", data_portal_default);
23050
+ app61.route("/routines", routines_default);
23051
+ app61.route("/skills", skills_default);
23052
+ app61.route("/tasks-list", tasks_list_default);
23053
+ app61.route("/task-timer-start", task_timer_start_default);
23054
+ app61.route("/task-timer-stop", task_timer_stop_default);
23055
+ app61.route("/task-complete", task_complete_default);
23056
+ app61.route("/task-time-adjust", task_time_adjust_default);
23057
+ app61.route("/task-assign", task_assign_default);
23058
+ app61.route("/admin-users-list", admin_users_list_default);
23059
+ app61.route("/activity", activity_default);
23060
+ var admin_default = app61;
22959
23061
 
22960
23062
  // server/routes/access/verify-token.ts
22961
23063
  var TAG35 = "[access-verify]";
22962
23064
  var MINT_TAG = "[access-session-mint]";
22963
23065
  var COOKIE_NAME = "__access_session";
22964
- var app61 = new Hono();
22965
- app61.post("/", async (c) => {
23066
+ var app62 = new Hono();
23067
+ app62.post("/", async (c) => {
22966
23068
  const ip = c.var.clientIp || "unknown";
22967
23069
  let body;
22968
23070
  try {
@@ -23044,7 +23146,7 @@ app61.post("/", async (c) => {
23044
23146
  displayName: grant.displayName
23045
23147
  });
23046
23148
  });
23047
- var verify_token_default = app61;
23149
+ var verify_token_default = app62;
23048
23150
 
23049
23151
  // app/lib/access-email.ts
23050
23152
  import { spawn as spawn2 } from "child_process";
@@ -23107,9 +23209,9 @@ async function sendMagicLinkEmail(payload) {
23107
23209
 
23108
23210
  // server/routes/access/request-magic-link.ts
23109
23211
  var TAG36 = "[access-request-link]";
23110
- var app62 = new Hono();
23212
+ var app63 = new Hono();
23111
23213
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
23112
- app62.post("/", async (c) => {
23214
+ app63.post("/", async (c) => {
23113
23215
  let body;
23114
23216
  try {
23115
23217
  body = await c.req.json();
@@ -23183,16 +23285,16 @@ app62.post("/", async (c) => {
23183
23285
  );
23184
23286
  return c.json({ message: VISITOR_MESSAGE }, 200);
23185
23287
  });
23186
- var request_magic_link_default = app62;
23288
+ var request_magic_link_default = app63;
23187
23289
 
23188
23290
  // server/routes/access/index.ts
23189
- var app63 = new Hono();
23190
- app63.route("/verify-token", verify_token_default);
23191
- app63.route("/request-magic-link", request_magic_link_default);
23192
- var access_default = app63;
23291
+ var app64 = new Hono();
23292
+ app64.route("/verify-token", verify_token_default);
23293
+ app64.route("/request-magic-link", request_magic_link_default);
23294
+ var access_default = app64;
23193
23295
 
23194
23296
  // server/routes/sites.ts
23195
- import { existsSync as existsSync40, readFileSync as readFileSync37, realpathSync as realpathSync8, statSync as statSync21 } from "fs";
23297
+ import { existsSync as existsSync41, readFileSync as readFileSync38, realpathSync as realpathSync8, statSync as statSync21 } from "fs";
23196
23298
  import { resolve as resolve33 } from "path";
23197
23299
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
23198
23300
  var MIME = {
@@ -23224,8 +23326,8 @@ function getExt(p) {
23224
23326
  if (idx < p.lastIndexOf("/")) return "";
23225
23327
  return p.slice(idx).toLowerCase();
23226
23328
  }
23227
- var app64 = new Hono();
23228
- app64.get("/:rel{.*}", (c) => {
23329
+ var app65 = new Hono();
23330
+ app65.get("/:rel{.*}", (c) => {
23229
23331
  const reqPath = c.req.path;
23230
23332
  const rawRel = c.req.param("rel") ?? "";
23231
23333
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -23258,7 +23360,7 @@ app64.get("/:rel{.*}", (c) => {
23258
23360
  }
23259
23361
  let stat11;
23260
23362
  try {
23261
- stat11 = existsSync40(filePath) ? statSync21(filePath) : null;
23363
+ stat11 = existsSync41(filePath) ? statSync21(filePath) : null;
23262
23364
  } catch {
23263
23365
  stat11 = null;
23264
23366
  }
@@ -23277,7 +23379,7 @@ app64.get("/:rel{.*}", (c) => {
23277
23379
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
23278
23380
  return c.text("Forbidden", 403);
23279
23381
  }
23280
- if (!existsSync40(filePath)) {
23382
+ if (!existsSync41(filePath)) {
23281
23383
  console.error(`[sites] not-found path=${reqPath} status=404`);
23282
23384
  return c.text("Not found", 404);
23283
23385
  }
@@ -23296,7 +23398,7 @@ app64.get("/:rel{.*}", (c) => {
23296
23398
  }
23297
23399
  let body;
23298
23400
  try {
23299
- body = readFileSync37(realPath);
23401
+ body = readFileSync38(realPath);
23300
23402
  } catch (err) {
23301
23403
  const code = err?.code;
23302
23404
  if (code === "EISDIR") {
@@ -23328,11 +23430,11 @@ app64.get("/:rel{.*}", (c) => {
23328
23430
  "X-Content-Type-Options": "nosniff"
23329
23431
  });
23330
23432
  });
23331
- var sites_default = app64;
23433
+ var sites_default = app65;
23332
23434
 
23333
23435
  // app/lib/visitor-token.ts
23334
23436
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
23335
- import { mkdirSync as mkdirSync8, readFileSync as readFileSync38, writeFileSync as writeFileSync14 } from "fs";
23437
+ import { mkdirSync as mkdirSync8, readFileSync as readFileSync39, writeFileSync as writeFileSync14 } from "fs";
23336
23438
  import { dirname as dirname15 } from "path";
23337
23439
  var TOKEN_PREFIX = "v1.";
23338
23440
  var SECRET_BYTES = 32;
@@ -23341,7 +23443,7 @@ var cachedSecret = null;
23341
23443
  function getSecret() {
23342
23444
  if (cachedSecret) return cachedSecret;
23343
23445
  try {
23344
- const hex2 = readFileSync38(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
23446
+ const hex2 = readFileSync39(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
23345
23447
  if (hex2.length === SECRET_BYTES * 2) {
23346
23448
  cachedSecret = Buffer.from(hex2, "hex");
23347
23449
  return cachedSecret;
@@ -23355,7 +23457,7 @@ function getSecret() {
23355
23457
  console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
23356
23458
  } catch {
23357
23459
  }
23358
- const hex = readFileSync38(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
23460
+ const hex = readFileSync39(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
23359
23461
  cachedSecret = Buffer.from(hex, "hex");
23360
23462
  return cachedSecret;
23361
23463
  }
@@ -23408,8 +23510,8 @@ var VISITOR_COOKIE_NAME = "mxy_v";
23408
23510
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
23409
23511
 
23410
23512
  // app/lib/brand-config.ts
23411
- import { existsSync as existsSync41, readFileSync as readFileSync39 } from "fs";
23412
- import { join as join44 } from "path";
23513
+ import { existsSync as existsSync42, readFileSync as readFileSync40 } from "fs";
23514
+ import { join as join45 } from "path";
23413
23515
  var cached2 = null;
23414
23516
  var cachedAttempted = false;
23415
23517
  function readBrandConfig() {
@@ -23417,10 +23519,10 @@ function readBrandConfig() {
23417
23519
  cachedAttempted = true;
23418
23520
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
23419
23521
  if (!platformRoot5) return null;
23420
- const brandPath = join44(platformRoot5, "config", "brand.json");
23421
- if (!existsSync41(brandPath)) return null;
23522
+ const brandPath = join45(platformRoot5, "config", "brand.json");
23523
+ if (!existsSync42(brandPath)) return null;
23422
23524
  try {
23423
- cached2 = JSON.parse(readFileSync39(brandPath, "utf-8"));
23525
+ cached2 = JSON.parse(readFileSync40(brandPath, "utf-8"));
23424
23526
  return cached2;
23425
23527
  } catch {
23426
23528
  return null;
@@ -23428,7 +23530,7 @@ function readBrandConfig() {
23428
23530
  }
23429
23531
 
23430
23532
  // server/routes/visitor-consent.ts
23431
- var app65 = new Hono();
23533
+ var app66 = new Hono();
23432
23534
  var CONSENT_COOKIE_NAME = "mxy_consent";
23433
23535
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
23434
23536
  var DEFAULT_CONSENT_COPY = {
@@ -23473,17 +23575,17 @@ function siteSlugFromReferer(referer) {
23473
23575
  return "";
23474
23576
  }
23475
23577
  }
23476
- app65.options("/consent", (c) => {
23578
+ app66.options("/consent", (c) => {
23477
23579
  const origin = getOrigin(c);
23478
23580
  setCorsHeaders(c, origin);
23479
23581
  return c.body(null, 204);
23480
23582
  });
23481
- app65.options("/brand-config", (c) => {
23583
+ app66.options("/brand-config", (c) => {
23482
23584
  const origin = getOrigin(c);
23483
23585
  setCorsHeaders(c, origin);
23484
23586
  return c.body(null, 204);
23485
23587
  });
23486
- app65.post("/consent", async (c) => {
23588
+ app66.post("/consent", async (c) => {
23487
23589
  const origin = getOrigin(c);
23488
23590
  setCorsHeaders(c, origin);
23489
23591
  let raw;
@@ -23523,7 +23625,7 @@ app65.post("/consent", async (c) => {
23523
23625
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
23524
23626
  return c.body(null, 204);
23525
23627
  });
23526
- app65.get("/brand-config", (c) => {
23628
+ app66.get("/brand-config", (c) => {
23527
23629
  const origin = getOrigin(c);
23528
23630
  setCorsHeaders(c, origin);
23529
23631
  const brand = readBrandConfig();
@@ -23533,7 +23635,7 @@ app65.get("/brand-config", (c) => {
23533
23635
  c.header("Cache-Control", "public, max-age=300");
23534
23636
  return c.json({ consent: { copy, palette } });
23535
23637
  });
23536
- var visitor_consent_default = app65;
23638
+ var visitor_consent_default = app66;
23537
23639
 
23538
23640
  // server/routes/listings.ts
23539
23641
  function getCookie(headerValue, name) {
@@ -23560,8 +23662,8 @@ function appendConsentParams(pageUrl, token) {
23560
23662
  }
23561
23663
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
23562
23664
  var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
23563
- var app66 = new Hono();
23564
- app66.get("/:slug/click", async (c) => {
23665
+ var app67 = new Hono();
23666
+ app67.get("/:slug/click", async (c) => {
23565
23667
  const slug = c.req.param("slug") ?? "";
23566
23668
  const rawSession = c.req.query("session") ?? "";
23567
23669
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -23625,10 +23727,10 @@ app66.get("/:slug/click", async (c) => {
23625
23727
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
23626
23728
  return c.redirect(redirectUrl, 302);
23627
23729
  });
23628
- var listings_default = app66;
23730
+ var listings_default = app67;
23629
23731
 
23630
23732
  // server/routes/visitor-event.ts
23631
- var app67 = new Hono();
23733
+ var app68 = new Hono();
23632
23734
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
23633
23735
  var buckets = /* @__PURE__ */ new Map();
23634
23736
  var RATE_LIMIT = 60;
@@ -23704,12 +23806,12 @@ function originAllowed(origin, allowlist) {
23704
23806
  return false;
23705
23807
  }
23706
23808
  }
23707
- app67.options("/event", (c) => {
23809
+ app68.options("/event", (c) => {
23708
23810
  const origin = getOrigin2(c);
23709
23811
  setCorsHeaders2(c, origin);
23710
23812
  return c.body(null, 204);
23711
23813
  });
23712
- app67.post("/event", async (c) => {
23814
+ app68.post("/event", async (c) => {
23713
23815
  const origin = getOrigin2(c);
23714
23816
  setCorsHeaders2(c, origin);
23715
23817
  const ua = c.req.header("user-agent") ?? "";
@@ -23914,11 +24016,11 @@ async function writeEvent(opts) {
23914
24016
  );
23915
24017
  }
23916
24018
  }
23917
- var visitor_event_default = app67;
24019
+ var visitor_event_default = app68;
23918
24020
 
23919
24021
  // server/routes/session.ts
23920
24022
  import { resolve as resolve34 } from "path";
23921
- import { existsSync as existsSync42, writeFileSync as writeFileSync15, mkdirSync as mkdirSync9 } from "fs";
24023
+ import { existsSync as existsSync43, writeFileSync as writeFileSync15, mkdirSync as mkdirSync9 } from "fs";
23922
24024
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
23923
24025
  function writeBrandingCache(accountId, agentSlug, branding) {
23924
24026
  try {
@@ -23960,8 +24062,8 @@ function withVisitorCookie(response, visitorId) {
23960
24062
  headers
23961
24063
  });
23962
24064
  }
23963
- var app68 = new Hono();
23964
- app68.post("/", async (c) => {
24065
+ var app69 = new Hono();
24066
+ app69.post("/", async (c) => {
23965
24067
  let body;
23966
24068
  try {
23967
24069
  body = await c.req.json();
@@ -24002,7 +24104,7 @@ app68.post("/", async (c) => {
24002
24104
  let agentConfig = null;
24003
24105
  if (account) {
24004
24106
  const agentDir = resolve34(account.accountDir, "agents", agentSlug);
24005
- if (!existsSync42(agentDir) || !existsSync42(resolve34(agentDir, "config.json"))) {
24107
+ if (!existsSync43(agentDir) || !existsSync43(resolve34(agentDir, "config.json"))) {
24006
24108
  return c.json({ error: "Agent not found" }, 404);
24007
24109
  }
24008
24110
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -24108,7 +24210,7 @@ app68.post("/", async (c) => {
24108
24210
  newVisitorId
24109
24211
  );
24110
24212
  });
24111
- var session_default2 = app68;
24213
+ var session_default2 = app69;
24112
24214
 
24113
24215
  // server/lib/calendar-slots.ts
24114
24216
  var WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
@@ -24191,17 +24293,17 @@ function computeOpenSlots(config, busy, fromISO, toISO) {
24191
24293
  }
24192
24294
 
24193
24295
  // server/routes/calendar-public.ts
24194
- var app69 = new Hono();
24296
+ var app70 = new Hono();
24195
24297
  function setCors(c) {
24196
24298
  c.header("Access-Control-Allow-Origin", "*");
24197
24299
  c.header("Access-Control-Allow-Methods", "GET, OPTIONS");
24198
24300
  c.header("Access-Control-Allow-Headers", "content-type");
24199
24301
  }
24200
- app69.options("/free-busy", (c) => {
24302
+ app70.options("/free-busy", (c) => {
24201
24303
  setCors(c);
24202
24304
  return c.body(null, 204);
24203
24305
  });
24204
- app69.get("/free-busy", async (c) => {
24306
+ app70.get("/free-busy", async (c) => {
24205
24307
  setCors(c);
24206
24308
  const from = c.req.query("from");
24207
24309
  const to = c.req.query("to");
@@ -24257,14 +24359,14 @@ app69.get("/free-busy", async (c) => {
24257
24359
  await session.close();
24258
24360
  }
24259
24361
  });
24260
- var calendar_public_default = app69;
24362
+ var calendar_public_default = app70;
24261
24363
 
24262
24364
  // server/routes/portal-fetch.ts
24263
24365
  import { createReadStream as createReadStream3 } from "fs";
24264
24366
  import { stat as stat8, readFile as readFile11, realpath } from "fs/promises";
24265
- import { join as join45, resolve as resolve35, sep as sep11 } from "path";
24367
+ import { join as join46, resolve as resolve35, sep as sep11 } from "path";
24266
24368
  import { Readable as Readable3 } from "stream";
24267
- var app70 = new Hono();
24369
+ var app71 = new Hono();
24268
24370
  var TAG37 = "[portal-fetch]";
24269
24371
  async function verifySignature(secret, accountId, relPath, expiresAtMs, signature, nowMs) {
24270
24372
  if (!secret || !signature) return false;
@@ -24335,7 +24437,7 @@ function isValidAccountId2(value) {
24335
24437
  }
24336
24438
  async function readExposeFolders2(accountDir) {
24337
24439
  try {
24338
- const cfg = JSON.parse(await readFile11(join45(accountDir, "data-portal.json"), "utf8"));
24440
+ const cfg = JSON.parse(await readFile11(join46(accountDir, "data-portal.json"), "utf8"));
24339
24441
  return Array.isArray(cfg?.exposeFolders) ? cfg.exposeFolders.filter((f) => typeof f === "string") : [];
24340
24442
  } catch {
24341
24443
  return [];
@@ -24344,7 +24446,7 @@ async function readExposeFolders2(accountDir) {
24344
24446
  async function resolveFetchTarget(accountDir, relPath, ownerId) {
24345
24447
  let schemaText = null;
24346
24448
  try {
24347
- schemaText = await readFile11(join45(accountDir, "SCHEMA.md"), "utf8");
24449
+ schemaText = await readFile11(join46(accountDir, "SCHEMA.md"), "utf8");
24348
24450
  } catch {
24349
24451
  schemaText = null;
24350
24452
  }
@@ -24427,9 +24529,9 @@ async function handle(c, headOnly) {
24427
24529
  }
24428
24530
  });
24429
24531
  }
24430
- app70.get("/fetch", (c) => handle(c, false));
24431
- app70.on("HEAD", "/fetch", (c) => handle(c, true));
24432
- var portal_fetch_default = app70;
24532
+ app71.get("/fetch", (c) => handle(c, false));
24533
+ app71.on("HEAD", "/fetch", (c) => handle(c, true));
24534
+ var portal_fetch_default = app71;
24433
24535
 
24434
24536
  // app/lib/timeentry-census.ts
24435
24537
  var TAG38 = "[timeentry-census]";
@@ -24514,8 +24616,8 @@ function startTimeEntryCensus(openSession, opts = {}) {
24514
24616
  }
24515
24617
 
24516
24618
  // app/lib/ledger-census.ts
24517
- import { readdirSync as readdirSync27, readFileSync as readFileSync40, statSync as statSync22 } from "fs";
24518
- import { join as join46 } from "path";
24619
+ import { readdirSync as readdirSync27, readFileSync as readFileSync41, statSync as statSync22 } from "fs";
24620
+ import { join as join47 } from "path";
24519
24621
 
24520
24622
  // ../lib/ledger-core/dist/reconcile.js
24521
24623
  var LEDGER_INDEX_NAMES = [
@@ -24569,10 +24671,10 @@ function countWriteRejects24h(logDir, now) {
24569
24671
  }
24570
24672
  let total = 0;
24571
24673
  for (const name of entries2) {
24572
- const path = join46(logDir, name);
24674
+ const path = join47(logDir, name);
24573
24675
  try {
24574
24676
  if (now - statSync22(path).mtimeMs > DAY_MS) continue;
24575
- for (const line of readFileSync40(path, "utf8").split("\n")) {
24677
+ for (const line of readFileSync41(path, "utf8").split("\n")) {
24576
24678
  if (line.includes("[graph-write] reject")) total += 1;
24577
24679
  }
24578
24680
  } catch {
@@ -25067,8 +25169,8 @@ async function migrateUploads(opts = {}) {
25067
25169
 
25068
25170
  // app/lib/migrate-admin-webchat-sidecars.ts
25069
25171
  import { readdir as readdir7, readFile as readFile12, rename as rename5, writeFile as writeFile4, unlink as unlink4 } from "fs/promises";
25070
- import { existsSync as existsSync43 } from "fs";
25071
- import { join as join47 } from "path";
25172
+ import { existsSync as existsSync44 } from "fs";
25173
+ import { join as join48 } from "path";
25072
25174
  var ADMIN_ROLE2 = "admin";
25073
25175
  var WEBCHAT_CHANNEL2 = "webchat";
25074
25176
  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;
@@ -25097,7 +25199,7 @@ async function writeRaw(path, obj) {
25097
25199
  await rename5(tmp, path);
25098
25200
  } catch (err) {
25099
25201
  try {
25100
- if (existsSync43(tmp)) await unlink4(tmp);
25202
+ if (existsSync44(tmp)) await unlink4(tmp);
25101
25203
  } catch {
25102
25204
  }
25103
25205
  throw err;
@@ -25113,7 +25215,7 @@ async function collectLiveSidecars(projectsRoot) {
25113
25215
  }
25114
25216
  for (const slug of slugs) {
25115
25217
  if (!slug.isDirectory()) continue;
25116
- const slugDir = join47(projectsRoot, slug.name);
25218
+ const slugDir = join48(projectsRoot, slug.name);
25117
25219
  let entries2;
25118
25220
  try {
25119
25221
  entries2 = await readdir7(slugDir, { withFileTypes: true });
@@ -25122,9 +25224,9 @@ async function collectLiveSidecars(projectsRoot) {
25122
25224
  }
25123
25225
  for (const entry of entries2) {
25124
25226
  if (entry.isFile() && SESSION_META_RE.test(entry.name)) {
25125
- out.push(join47(slugDir, entry.name));
25227
+ out.push(join48(slugDir, entry.name));
25126
25228
  } else if (entry.isDirectory() && entry.name === "subagents") {
25127
- const subDir = join47(slugDir, entry.name);
25229
+ const subDir = join48(slugDir, entry.name);
25128
25230
  let subs;
25129
25231
  try {
25130
25232
  subs = await readdir7(subDir, { withFileTypes: true });
@@ -25132,7 +25234,7 @@ async function collectLiveSidecars(projectsRoot) {
25132
25234
  continue;
25133
25235
  }
25134
25236
  for (const s of subs) {
25135
- if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join47(subDir, s.name));
25237
+ if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join48(subDir, s.name));
25136
25238
  }
25137
25239
  }
25138
25240
  }
@@ -25144,7 +25246,7 @@ function shortId(path) {
25144
25246
  return base.slice(0, 8);
25145
25247
  }
25146
25248
  async function migrateAdminWebchatSidecars(opts = {}) {
25147
- const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join47(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
25249
+ const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join48(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
25148
25250
  const usersFile = opts.usersFile ?? USERS_FILE;
25149
25251
  const accountId = opts.accountId ?? resolveAccount()?.accountId ?? null;
25150
25252
  const resolveName = opts.resolveName ?? defaultResolveName;
@@ -25220,8 +25322,8 @@ async function migrateAdminWebchatSidecars(opts = {}) {
25220
25322
 
25221
25323
  // app/lib/migrate-sidecar-account-ids.ts
25222
25324
  import { readdir as readdir8, readFile as readFile13, rename as rename6, writeFile as writeFile5, unlink as unlink5 } from "fs/promises";
25223
- import { existsSync as existsSync44 } from "fs";
25224
- import { join as join48 } from "path";
25325
+ import { existsSync as existsSync45 } from "fs";
25326
+ import { join as join49 } from "path";
25225
25327
  var SESSION_META_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.meta\.json$/i;
25226
25328
  function projectSlugForCwd(cwd) {
25227
25329
  return cwd.replace(/\//g, "-");
@@ -25247,7 +25349,7 @@ async function writeRaw2(path, obj) {
25247
25349
  await rename6(tmp, path);
25248
25350
  } catch (err) {
25249
25351
  try {
25250
- if (existsSync44(tmp)) await unlink5(tmp);
25352
+ if (existsSync45(tmp)) await unlink5(tmp);
25251
25353
  } catch {
25252
25354
  }
25253
25355
  throw err;
@@ -25267,7 +25369,7 @@ async function collectSidecars(projectsRoot) {
25267
25369
  }
25268
25370
  for (const slug of slugs) {
25269
25371
  if (!slug.isDirectory()) continue;
25270
- const slugDir = join48(projectsRoot, slug.name);
25372
+ const slugDir = join49(projectsRoot, slug.name);
25271
25373
  let entries2;
25272
25374
  try {
25273
25375
  entries2 = await readdir8(slugDir, { withFileTypes: true });
@@ -25276,9 +25378,9 @@ async function collectSidecars(projectsRoot) {
25276
25378
  }
25277
25379
  for (const entry of entries2) {
25278
25380
  if (entry.isFile() && SESSION_META_RE2.test(entry.name)) {
25279
- out.push({ path: join48(slugDir, entry.name), slug: slug.name });
25381
+ out.push({ path: join49(slugDir, entry.name), slug: slug.name });
25280
25382
  } else if (entry.isDirectory() && (entry.name === "subagents" || entry.name === "archive")) {
25281
- const subDir = join48(slugDir, entry.name);
25383
+ const subDir = join49(slugDir, entry.name);
25282
25384
  let subs;
25283
25385
  try {
25284
25386
  subs = await readdir8(subDir, { withFileTypes: true });
@@ -25287,7 +25389,7 @@ async function collectSidecars(projectsRoot) {
25287
25389
  }
25288
25390
  for (const s of subs) {
25289
25391
  if (s.isFile() && SESSION_META_RE2.test(s.name)) {
25290
- out.push({ path: join48(subDir, s.name), slug: slug.name });
25392
+ out.push({ path: join49(subDir, s.name), slug: slug.name });
25291
25393
  }
25292
25394
  }
25293
25395
  }
@@ -25296,7 +25398,7 @@ async function collectSidecars(projectsRoot) {
25296
25398
  return out;
25297
25399
  }
25298
25400
  async function migrateSidecarAccountIds(opts = {}) {
25299
- const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join48(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
25401
+ const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join49(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
25300
25402
  const accounts = opts.accounts ?? listValidAccounts();
25301
25403
  const result = {
25302
25404
  scanned: 0,
@@ -25609,8 +25711,8 @@ var streamSSE = (c, cb, onError) => {
25609
25711
 
25610
25712
  // app/lib/whatsapp/gateway/routes.ts
25611
25713
  function createWaChannelRoutes(deps) {
25612
- const app72 = new Hono();
25613
- app72.get("/wa-channel/inbound", (c) => {
25714
+ const app73 = new Hono();
25715
+ app73.get("/wa-channel/inbound", (c) => {
25614
25716
  const senderId = c.req.query("senderId");
25615
25717
  if (!senderId) return c.json({ error: "senderId required" }, 400);
25616
25718
  return streamSSE(c, async (stream2) => {
@@ -25628,7 +25730,7 @@ function createWaChannelRoutes(deps) {
25628
25730
  }
25629
25731
  });
25630
25732
  });
25631
- app72.post("/wa-channel/reply", async (c) => {
25733
+ app73.post("/wa-channel/reply", async (c) => {
25632
25734
  const body = await c.req.json().catch(() => null);
25633
25735
  const senderId = body?.senderId;
25634
25736
  const text = body?.text;
@@ -25649,7 +25751,7 @@ function createWaChannelRoutes(deps) {
25649
25751
  console.error(`[whatsapp-native] op=reply-dispatch senderId=${senderId} bytes=${bytes}`);
25650
25752
  return c.json({ ok: true });
25651
25753
  });
25652
- app72.post("/wa-channel/reply-document", async (c) => {
25754
+ app73.post("/wa-channel/reply-document", async (c) => {
25653
25755
  const body = await c.req.json().catch(() => null);
25654
25756
  const senderId = body?.senderId;
25655
25757
  const files = body?.files;
@@ -25688,7 +25790,7 @@ function createWaChannelRoutes(deps) {
25688
25790
  }
25689
25791
  return c.json({ ok: true, results });
25690
25792
  });
25691
- app72.post("/wa-channel/ready", async (c) => {
25793
+ app73.post("/wa-channel/ready", async (c) => {
25692
25794
  const body = await c.req.json().catch(() => null);
25693
25795
  const senderId = body?.senderId;
25694
25796
  if (typeof senderId !== "string") {
@@ -25697,7 +25799,7 @@ function createWaChannelRoutes(deps) {
25697
25799
  deps.onReady?.(senderId);
25698
25800
  return c.json({ ok: true });
25699
25801
  });
25700
- app72.post("/wa-channel/received", async (c) => {
25802
+ app73.post("/wa-channel/received", async (c) => {
25701
25803
  const body = await c.req.json().catch(() => null);
25702
25804
  const senderId = body?.senderId;
25703
25805
  const waMessageId = body?.waMessageId;
@@ -25707,7 +25809,7 @@ function createWaChannelRoutes(deps) {
25707
25809
  deps.onReceived?.(senderId, waMessageId);
25708
25810
  return c.json({ ok: true });
25709
25811
  });
25710
- app72.post("/wa-channel/turn-end", async (c) => {
25812
+ app73.post("/wa-channel/turn-end", async (c) => {
25711
25813
  const body = await c.req.json().catch(() => null);
25712
25814
  const senderId = body?.senderId;
25713
25815
  const sessionId = body?.sessionId;
@@ -25751,7 +25853,7 @@ function createWaChannelRoutes(deps) {
25751
25853
  console.error(`[whatsapp-native] op=turn-end ${decision} delivered=none`);
25752
25854
  return c.json({ ok: true, delivered: "none" });
25753
25855
  });
25754
- return app72;
25856
+ return app73;
25755
25857
  }
25756
25858
 
25757
25859
  // app/lib/whatsapp/gateway/wa-gateway.ts
@@ -26181,8 +26283,8 @@ var InboundHub2 = class {
26181
26283
 
26182
26284
  // app/lib/webchat/gateway/routes.ts
26183
26285
  function createWebchatChannelRoutes(deps) {
26184
- const app72 = new Hono();
26185
- app72.get("/webchat-channel/inbound", (c) => {
26286
+ const app73 = new Hono();
26287
+ app73.get("/webchat-channel/inbound", (c) => {
26186
26288
  const key = c.req.query("key");
26187
26289
  if (!key) return c.json({ error: "key required" }, 400);
26188
26290
  const role = c.req.query("role");
@@ -26207,7 +26309,7 @@ function createWebchatChannelRoutes(deps) {
26207
26309
  }
26208
26310
  });
26209
26311
  });
26210
- app72.post("/webchat-channel/reply", async (c) => {
26312
+ app73.post("/webchat-channel/reply", async (c) => {
26211
26313
  const body = await c.req.json().catch(() => null);
26212
26314
  const key = body?.key;
26213
26315
  const text = body?.text;
@@ -26217,7 +26319,7 @@ function createWebchatChannelRoutes(deps) {
26217
26319
  deps.onReply?.(key, text);
26218
26320
  return c.json({ ok: true });
26219
26321
  });
26220
- app72.post("/webchat-channel/connector-auth", async (c) => {
26322
+ app73.post("/webchat-channel/connector-auth", async (c) => {
26221
26323
  const body = await c.req.json().catch(() => null);
26222
26324
  const key = body?.key;
26223
26325
  const sessionId = body?.sessionId;
@@ -26230,7 +26332,7 @@ function createWebchatChannelRoutes(deps) {
26230
26332
  const result = await deps.onConnectorAuth({ key, sessionId, name, completed });
26231
26333
  return c.json(result);
26232
26334
  });
26233
- app72.post("/webchat-channel/ready", async (c) => {
26335
+ app73.post("/webchat-channel/ready", async (c) => {
26234
26336
  const body = await c.req.json().catch(() => null);
26235
26337
  const key = body?.key;
26236
26338
  if (typeof key !== "string") {
@@ -26239,7 +26341,7 @@ function createWebchatChannelRoutes(deps) {
26239
26341
  deps.onReady?.(key);
26240
26342
  return c.json({ ok: true });
26241
26343
  });
26242
- app72.post("/webchat-channel/permission-request", async (c) => {
26344
+ app73.post("/webchat-channel/permission-request", async (c) => {
26243
26345
  const body = await c.req.json().catch(() => null);
26244
26346
  const key = body?.key;
26245
26347
  const requestId = body?.request_id;
@@ -26253,7 +26355,7 @@ function createWebchatChannelRoutes(deps) {
26253
26355
  const verdict = await deps.awaitPermissionVerdict({ key, requestId, toolName, description, inputPreview });
26254
26356
  return c.json(verdict);
26255
26357
  });
26256
- app72.post("/webchat-channel/received", async (c) => {
26358
+ app73.post("/webchat-channel/received", async (c) => {
26257
26359
  const body = await c.req.json().catch(() => null);
26258
26360
  const key = body?.key;
26259
26361
  const messageId = body?.messageId;
@@ -26263,7 +26365,7 @@ function createWebchatChannelRoutes(deps) {
26263
26365
  deps.onReceived?.(key, messageId);
26264
26366
  return c.json({ ok: true });
26265
26367
  });
26266
- app72.post("/webchat-channel/turn-end", async (c) => {
26368
+ app73.post("/webchat-channel/turn-end", async (c) => {
26267
26369
  const body = await c.req.json().catch(() => null);
26268
26370
  const key = body?.key;
26269
26371
  const sessionId = body?.sessionId;
@@ -26283,7 +26385,7 @@ function createWebchatChannelRoutes(deps) {
26283
26385
  deps.onTurnEnd?.(key, role);
26284
26386
  return c.json({ ok: true });
26285
26387
  });
26286
- return app72;
26388
+ return app73;
26287
26389
  }
26288
26390
 
26289
26391
  // app/lib/webchat/gateway/webchat-gateway.ts
@@ -27379,8 +27481,8 @@ var InboundHub3 = class {
27379
27481
 
27380
27482
  // app/lib/telegram/gateway/routes.ts
27381
27483
  function createTelegramChannelRoutes(deps) {
27382
- const app72 = new Hono();
27383
- app72.get("/tg-channel/inbound", (c) => {
27484
+ const app73 = new Hono();
27485
+ app73.get("/tg-channel/inbound", (c) => {
27384
27486
  const key = c.req.query("key");
27385
27487
  if (!key) return c.json({ error: "key required" }, 400);
27386
27488
  return streamSSE(c, async (stream2) => {
@@ -27398,7 +27500,7 @@ function createTelegramChannelRoutes(deps) {
27398
27500
  }
27399
27501
  });
27400
27502
  });
27401
- app72.post("/tg-channel/reply", async (c) => {
27503
+ app73.post("/tg-channel/reply", async (c) => {
27402
27504
  const body = await c.req.json().catch(() => null);
27403
27505
  const key = body?.key;
27404
27506
  const text = body?.text;
@@ -27414,7 +27516,7 @@ function createTelegramChannelRoutes(deps) {
27414
27516
  console.error(`[telegram-native] op=reply key=${key} bytes=${Buffer.byteLength(text, "utf8")}`);
27415
27517
  return c.json({ ok: true });
27416
27518
  });
27417
- app72.post("/tg-channel/ready", async (c) => {
27519
+ app73.post("/tg-channel/ready", async (c) => {
27418
27520
  const body = await c.req.json().catch(() => null);
27419
27521
  const key = body?.key;
27420
27522
  if (typeof key !== "string") {
@@ -27423,7 +27525,7 @@ function createTelegramChannelRoutes(deps) {
27423
27525
  deps.onReady?.(key);
27424
27526
  return c.json({ ok: true });
27425
27527
  });
27426
- app72.post("/tg-channel/received", async (c) => {
27528
+ app73.post("/tg-channel/received", async (c) => {
27427
27529
  const body = await c.req.json().catch(() => null);
27428
27530
  const key = body?.key;
27429
27531
  const messageId = body?.messageId;
@@ -27433,7 +27535,7 @@ function createTelegramChannelRoutes(deps) {
27433
27535
  deps.onReceived?.(key, messageId);
27434
27536
  return c.json({ ok: true });
27435
27537
  });
27436
- app72.post("/tg-channel/turn-end", async (c) => {
27538
+ app73.post("/tg-channel/turn-end", async (c) => {
27437
27539
  const body = await c.req.json().catch(() => null);
27438
27540
  const key = body?.key;
27439
27541
  const sessionId = body?.sessionId;
@@ -27466,7 +27568,7 @@ function createTelegramChannelRoutes(deps) {
27466
27568
  console.error(`[telegram-native] op=turn-end key=${key} sessionId=${sid} replied=no delivered=none`);
27467
27569
  return c.json({ ok: true, delivered: "none" });
27468
27570
  });
27469
- return app72;
27571
+ return app73;
27470
27572
  }
27471
27573
 
27472
27574
  // app/lib/telegram/gateway/telegram-gateway.ts
@@ -28035,14 +28137,14 @@ function resolveScheduledEffectiveAccountForInstall(accountDir, destination) {
28035
28137
  }
28036
28138
 
28037
28139
  // server/lib/booking-site-accounts.ts
28038
- import { existsSync as existsSync45, readFileSync as readFileSync41 } from "fs";
28140
+ import { existsSync as existsSync46, readFileSync as readFileSync42 } from "fs";
28039
28141
  import { resolve as resolve40 } from "path";
28040
28142
  function listBookingSiteAccounts(accounts) {
28041
28143
  return accounts.filter((a) => {
28042
28144
  const availPath = resolve40(a.accountDir, "calendar-availability.json");
28043
- if (!existsSync45(availPath)) return false;
28145
+ if (!existsSync46(availPath)) return false;
28044
28146
  try {
28045
- const cfg = JSON.parse(readFileSync41(availPath, "utf-8"));
28147
+ const cfg = JSON.parse(readFileSync42(availPath, "utf-8"));
28046
28148
  return typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
28047
28149
  } catch {
28048
28150
  return false;
@@ -28080,7 +28182,7 @@ function broadcastAdminShutdown(reason) {
28080
28182
 
28081
28183
  // ../lib/entitlement/src/index.ts
28082
28184
  import { createPublicKey, createHash as createHash6, verify as cryptoVerify } from "crypto";
28083
- import { existsSync as existsSync46, readFileSync as readFileSync42, statSync as statSync23 } from "fs";
28185
+ import { existsSync as existsSync47, readFileSync as readFileSync43, statSync as statSync23 } from "fs";
28084
28186
  import { resolve as resolve41 } from "path";
28085
28187
 
28086
28188
  // ../lib/entitlement/src/canonicalize.ts
@@ -28129,7 +28231,7 @@ function resolveEntitlement(brand, account) {
28129
28231
  return logResolved(implicitTrust(account), null);
28130
28232
  }
28131
28233
  const entitlementPath = resolve41(brand.configDir, "entitlement.json");
28132
- if (!existsSync46(entitlementPath)) {
28234
+ if (!existsSync47(entitlementPath)) {
28133
28235
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
28134
28236
  }
28135
28237
  const stat11 = statSync23(entitlementPath);
@@ -28144,7 +28246,7 @@ function resolveEntitlement(brand, account) {
28144
28246
  function verifyAndResolve(brand, entitlementPath, account) {
28145
28247
  let pubkeyPem;
28146
28248
  try {
28147
- pubkeyPem = readFileSync42(pubkeyPath(brand), "utf-8");
28249
+ pubkeyPem = readFileSync43(pubkeyPath(brand), "utf-8");
28148
28250
  } catch (err) {
28149
28251
  return logResolved(anonymousFallback("pubkey-missing"), {
28150
28252
  reason: "pubkey-missing"
@@ -28158,7 +28260,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
28158
28260
  }
28159
28261
  let envelope;
28160
28262
  try {
28161
- envelope = JSON.parse(readFileSync42(entitlementPath, "utf-8"));
28263
+ envelope = JSON.parse(readFileSync43(entitlementPath, "utf-8"));
28162
28264
  } catch {
28163
28265
  return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
28164
28266
  }
@@ -28320,14 +28422,14 @@ function clientFrom(c) {
28320
28422
  }
28321
28423
  installMediaDownloadGuard();
28322
28424
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT || "";
28323
- var BRAND_JSON_PATH = PLATFORM_ROOT6 ? join49(PLATFORM_ROOT6, "config", "brand.json") : "";
28425
+ var BRAND_JSON_PATH = PLATFORM_ROOT6 ? join50(PLATFORM_ROOT6, "config", "brand.json") : "";
28324
28426
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
28325
- if (BRAND_JSON_PATH && !existsSync47(BRAND_JSON_PATH)) {
28427
+ if (BRAND_JSON_PATH && !existsSync48(BRAND_JSON_PATH)) {
28326
28428
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
28327
28429
  }
28328
- if (BRAND_JSON_PATH && existsSync47(BRAND_JSON_PATH)) {
28430
+ if (BRAND_JSON_PATH && existsSync48(BRAND_JSON_PATH)) {
28329
28431
  try {
28330
- const parsed = JSON.parse(readFileSync43(BRAND_JSON_PATH, "utf-8"));
28432
+ const parsed = JSON.parse(readFileSync44(BRAND_JSON_PATH, "utf-8"));
28331
28433
  BRAND = { ...BRAND, ...parsed };
28332
28434
  } catch (err) {
28333
28435
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -28359,11 +28461,11 @@ var brandLoginOpts = {
28359
28461
  appleTouchIconPath: brandAppIcon512Path,
28360
28462
  themeColor: BRAND.defaultColors?.primary
28361
28463
  };
28362
- var ALIAS_DOMAINS_PATH = join49(homedir4(), BRAND.configDir, "alias-domains.json");
28464
+ var ALIAS_DOMAINS_PATH = join50(homedir4(), BRAND.configDir, "alias-domains.json");
28363
28465
  function loadAliasDomains() {
28364
28466
  try {
28365
- if (!existsSync47(ALIAS_DOMAINS_PATH)) return null;
28366
- const parsed = JSON.parse(readFileSync43(ALIAS_DOMAINS_PATH, "utf-8"));
28467
+ if (!existsSync48(ALIAS_DOMAINS_PATH)) return null;
28468
+ const parsed = JSON.parse(readFileSync44(ALIAS_DOMAINS_PATH, "utf-8"));
28367
28469
  if (!Array.isArray(parsed)) {
28368
28470
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
28369
28471
  return null;
@@ -28389,7 +28491,7 @@ startManagerEventsSubscriber();
28389
28491
  function isPublicHost(host) {
28390
28492
  return host.startsWith("public.") || aliasDomains.has(host);
28391
28493
  }
28392
- var app71 = new Hono();
28494
+ var app72 = new Hono();
28393
28495
  function resolveChannelOverride(accountId, channel, senderId) {
28394
28496
  try {
28395
28497
  const dir = listValidAccounts().find((a) => a.accountId === accountId)?.accountDir;
@@ -28438,7 +28540,7 @@ var waGateway = new WaGateway({
28438
28540
  fetchStandingRules: fetchAccountStandingRules,
28439
28541
  resolveSessionOverride: (accountId, senderId) => resolveChannelOverride(accountId, "whatsapp", senderId),
28440
28542
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
28441
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve42(process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
28543
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve42(process.env.MAXY_PLATFORM_ROOT ?? join50(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
28442
28544
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
28443
28545
  // path-validation scope) is the sender's effective SESSION account, resolved
28444
28546
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -28453,7 +28555,7 @@ var waGateway = new WaGateway({
28453
28555
  caption,
28454
28556
  accountId,
28455
28557
  maxyAccountId,
28456
- platformRoot: resolve42(process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, ".."))
28558
+ platformRoot: resolve42(process.env.MAXY_PLATFORM_ROOT ?? join50(__dirname, ".."))
28457
28559
  });
28458
28560
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
28459
28561
  },
@@ -28566,13 +28668,13 @@ var waGateway = new WaGateway({
28566
28668
  nativeFileFollowers.set(senderId, ac);
28567
28669
  }
28568
28670
  });
28569
- app71.route("/", waGateway.routes());
28671
+ app72.route("/", waGateway.routes());
28570
28672
  waGateway.startSweeper();
28571
28673
  function runDuplicateSenderAudit() {
28572
28674
  try {
28573
28675
  const configDir = process.env.CLAUDE_CONFIG_DIR;
28574
28676
  if (!configDir) return;
28575
- const projectsRoot = join49(configDir, "projects");
28677
+ const projectsRoot = join50(configDir, "projects");
28576
28678
  const records = [];
28577
28679
  for (const { path: jsonlPath, isSubagent, archived } of enumerateJsonls(projectsRoot)) {
28578
28680
  if (isSubagent || archived) continue;
@@ -28696,7 +28798,7 @@ var webchatGateway = new WebchatGateway({
28696
28798
  firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
28697
28799
  });
28698
28800
  setWebchatGateway(webchatGateway);
28699
- app71.route("/", webchatGateway.routes());
28801
+ app72.route("/", webchatGateway.routes());
28700
28802
  webchatGateway.startSweeper();
28701
28803
  webchatGateway.startPublicReaper();
28702
28804
  var telegramFileFollowers = /* @__PURE__ */ new Map();
@@ -28740,7 +28842,7 @@ var telegramGateway = new TelegramGateway({
28740
28842
  }
28741
28843
  });
28742
28844
  setTelegramGateway(telegramGateway);
28743
- app71.route("/", telegramGateway.routes());
28845
+ app72.route("/", telegramGateway.routes());
28744
28846
  telegramGateway.startSweeper();
28745
28847
  var chatRoutes = createChatRoutes({
28746
28848
  handleInbound: (input) => webchatGateway.handleInbound(input),
@@ -28774,19 +28876,19 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
28774
28876
  // and why the real dependencies are bound there rather than assembled here.
28775
28877
  effectiveAccountFor: resolveScheduledEffectiveAccountForInstall
28776
28878
  });
28777
- app71.route("/api/channel/schedule-inject", scheduleInjectRoutes);
28778
- app71.use("*", clientIpMiddleware);
28879
+ app72.route("/api/channel/schedule-inject", scheduleInjectRoutes);
28880
+ app72.use("*", clientIpMiddleware);
28779
28881
  function allowsSameOriginFraming(path) {
28780
28882
  return path === "/vnc-viewer.html" || path.startsWith("/api/admin/attachment/") || path.startsWith("/api/public-reader/attachment/") || path === "/api/admin/files/download" || path === "/api/admin/session-upload";
28781
28883
  }
28782
- app71.use("*", async (c, next) => {
28884
+ app72.use("*", async (c, next) => {
28783
28885
  await next();
28784
28886
  c.header("X-Content-Type-Options", "nosniff");
28785
28887
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
28786
28888
  c.header("X-Frame-Options", allowsSameOriginFraming(c.req.path) ? "SAMEORIGIN" : "DENY");
28787
28889
  });
28788
28890
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
28789
- app71.use("*", async (c, next) => {
28891
+ app72.use("*", async (c, next) => {
28790
28892
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
28791
28893
  await next();
28792
28894
  return;
@@ -28804,7 +28906,7 @@ app71.use("*", async (c, next) => {
28804
28906
  });
28805
28907
  }
28806
28908
  });
28807
- app71.use("*", async (c, next) => {
28909
+ app72.use("*", async (c, next) => {
28808
28910
  const host = (c.req.header("host") ?? "").split(":")[0];
28809
28911
  if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
28810
28912
  await next();
@@ -28842,7 +28944,7 @@ function resolveRemoteAuthOpts(c) {
28842
28944
  return { ...brandLoginOpts, origin };
28843
28945
  }
28844
28946
  var MAX_LOGIN_BODY = 8 * 1024;
28845
- app71.post("/__remote-auth/login", async (c) => {
28947
+ app72.post("/__remote-auth/login", async (c) => {
28846
28948
  const client = clientFrom(c);
28847
28949
  const clientIp = client.ip || "unknown";
28848
28950
  if (!requestIsTlsTerminated(c)) {
@@ -28887,7 +28989,7 @@ app71.post("/__remote-auth/login", async (c) => {
28887
28989
  }
28888
28990
  });
28889
28991
  });
28890
- app71.get("/__remote-auth/logout", (c) => {
28992
+ app72.get("/__remote-auth/logout", (c) => {
28891
28993
  const client = clientFrom(c);
28892
28994
  const clientIp = client.ip || "unknown";
28893
28995
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -28900,7 +29002,7 @@ app71.get("/__remote-auth/logout", (c) => {
28900
29002
  }
28901
29003
  });
28902
29004
  });
28903
- app71.post("/__remote-auth/change-password", async (c) => {
29005
+ app72.post("/__remote-auth/change-password", async (c) => {
28904
29006
  const client = clientFrom(c);
28905
29007
  const clientIp = client.ip || "unknown";
28906
29008
  const rateLimited = checkRateLimit(client);
@@ -28959,13 +29061,13 @@ app71.post("/__remote-auth/change-password", async (c) => {
28959
29061
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Failed to save password", redirect }), 200);
28960
29062
  }
28961
29063
  });
28962
- app71.get("/__remote-auth/setup", (c) => {
29064
+ app72.get("/__remote-auth/setup", (c) => {
28963
29065
  if (isRemoteAuthConfigured()) {
28964
29066
  return c.redirect("/");
28965
29067
  }
28966
29068
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup" }), 200);
28967
29069
  });
28968
- app71.post("/__remote-auth/set-initial-password", async (c) => {
29070
+ app72.post("/__remote-auth/set-initial-password", async (c) => {
28969
29071
  if (isRemoteAuthConfigured()) {
28970
29072
  return c.redirect("/");
28971
29073
  }
@@ -29003,10 +29105,10 @@ app71.post("/__remote-auth/set-initial-password", async (c) => {
29003
29105
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
29004
29106
  }
29005
29107
  });
29006
- app71.get("/api/remote-auth/status", (c) => {
29108
+ app72.get("/api/remote-auth/status", (c) => {
29007
29109
  return c.json({ configured: isRemoteAuthConfigured() });
29008
29110
  });
29009
- app71.post("/api/remote-auth/set-password", async (c) => {
29111
+ app72.post("/api/remote-auth/set-password", async (c) => {
29010
29112
  let body;
29011
29113
  try {
29012
29114
  body = await c.req.json();
@@ -29045,10 +29147,10 @@ app71.post("/api/remote-auth/set-password", async (c) => {
29045
29147
  return c.json({ error: "Failed to save password" }, 500);
29046
29148
  }
29047
29149
  });
29048
- app71.route("/api/_client-error", client_error_default);
29150
+ app72.route("/api/_client-error", client_error_default);
29049
29151
  console.log("[client-error-route] mounted");
29050
29152
  var PWA_PUBLIC_PATHS = /* @__PURE__ */ new Set(["/sw.js", ...PWA_SURFACES.map((s) => s.manifestPath)]);
29051
- app71.use("*", async (c, next) => {
29153
+ app72.use("*", async (c, next) => {
29052
29154
  const host = (c.req.header("host") ?? "").split(":")[0];
29053
29155
  const path = c.req.path;
29054
29156
  if (path === "/favicon.ico" || path.startsWith("/assets/") || path.startsWith("/brand/") || // Public free/busy is read by the booking page (a separate Cloudflare Pages
@@ -29092,30 +29194,30 @@ app71.use("*", async (c, next) => {
29092
29194
  }
29093
29195
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), redirect: path }), 200);
29094
29196
  });
29095
- app71.route("/api/health", health_default);
29096
- app71.route("/api/chat", chatRoutes);
29097
- app71.route("/api/whatsapp", whatsapp_default);
29098
- app71.route("/api/storage", storage_broker_default);
29099
- app71.route("/api/whatsapp-reader", whatsapp_reader_default);
29100
- app71.route("/api/session-reader", session_reader_default);
29101
- app71.route("/api/operator-conversations", operator_conversations_default);
29102
- app71.route("/api/public-reader", public_reader_default);
29103
- app71.route("/api/webchat", createWebchatRoutes({
29197
+ app72.route("/api/health", health_default);
29198
+ app72.route("/api/chat", chatRoutes);
29199
+ app72.route("/api/whatsapp", whatsapp_default);
29200
+ app72.route("/api/storage", storage_broker_default);
29201
+ app72.route("/api/whatsapp-reader", whatsapp_reader_default);
29202
+ app72.route("/api/session-reader", session_reader_default);
29203
+ app72.route("/api/operator-conversations", operator_conversations_default);
29204
+ app72.route("/api/public-reader", public_reader_default);
29205
+ app72.route("/api/webchat", createWebchatRoutes({
29104
29206
  handleInbound: (input) => webchatGateway.handleInbound(input),
29105
29207
  // Task 940 — the permission relay's pointer read + verdict write.
29106
29208
  pendingPromptFor: (key) => webchatGateway.pendingPromptFor(key),
29107
29209
  deliveryFailureFor: (key) => webchatGateway.deliveryFailureFor(key),
29108
29210
  resolvePermissionVerdict: (key, requestId, behavior) => webchatGateway.resolvePermissionVerdict(key, requestId, behavior)
29109
29211
  }));
29110
- app71.route("/api/webchat/greeting", webchat_greeting_default);
29111
- app71.route("/api/telegram", telegram_default);
29112
- app71.route("/api/quickbooks", quickbooks_default);
29113
- app71.route("/api/onboarding", onboarding_default);
29114
- app71.route("/api/admin", admin_default);
29115
- app71.route("/api/access", access_default);
29116
- app71.route("/api/session", session_default2);
29117
- app71.route("/api/calendar", calendar_public_default);
29118
- app71.route("/api/portal", portal_fetch_default);
29212
+ app72.route("/api/webchat/greeting", webchat_greeting_default);
29213
+ app72.route("/api/telegram", telegram_default);
29214
+ app72.route("/api/quickbooks", quickbooks_default);
29215
+ app72.route("/api/onboarding", onboarding_default);
29216
+ app72.route("/api/admin", admin_default);
29217
+ app72.route("/api/access", access_default);
29218
+ app72.route("/api/session", session_default2);
29219
+ app72.route("/api/calendar", calendar_public_default);
29220
+ app72.route("/api/portal", portal_fetch_default);
29119
29221
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
29120
29222
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
29121
29223
  var IMAGE_MIME = {
@@ -29127,7 +29229,7 @@ var IMAGE_MIME = {
29127
29229
  ".svg": "image/svg+xml",
29128
29230
  ".ico": "image/x-icon"
29129
29231
  };
29130
- app71.get("/agent-assets/:slug/:filename", (c) => {
29232
+ app72.get("/agent-assets/:slug/:filename", (c) => {
29131
29233
  const slug = c.req.param("slug");
29132
29234
  const filename = c.req.param("filename");
29133
29235
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -29149,20 +29251,20 @@ app71.get("/agent-assets/:slug/:filename", (c) => {
29149
29251
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
29150
29252
  return c.text("Forbidden", 403);
29151
29253
  }
29152
- if (!existsSync47(filePath)) {
29254
+ if (!existsSync48(filePath)) {
29153
29255
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
29154
29256
  return c.text("Not found", 404);
29155
29257
  }
29156
29258
  const ext = "." + filename.split(".").pop()?.toLowerCase();
29157
29259
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
29158
29260
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
29159
- const body = readFileSync43(filePath);
29261
+ const body = readFileSync44(filePath);
29160
29262
  return c.body(body, 200, {
29161
29263
  "Content-Type": contentType,
29162
29264
  "Cache-Control": "public, max-age=3600"
29163
29265
  });
29164
29266
  });
29165
- app71.get("/generated/:filename", (c) => {
29267
+ app72.get("/generated/:filename", (c) => {
29166
29268
  const filename = c.req.param("filename");
29167
29269
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
29168
29270
  console.error(`[generated] serve file=${filename} status=403`);
@@ -29179,29 +29281,29 @@ app71.get("/generated/:filename", (c) => {
29179
29281
  console.error(`[generated] serve file=${filename} status=403`);
29180
29282
  return c.text("Forbidden", 403);
29181
29283
  }
29182
- if (!existsSync47(filePath)) {
29284
+ if (!existsSync48(filePath)) {
29183
29285
  console.error(`[generated] serve file=${filename} status=404`);
29184
29286
  return c.text("Not found", 404);
29185
29287
  }
29186
29288
  const ext = "." + filename.split(".").pop()?.toLowerCase();
29187
29289
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
29188
29290
  console.log(`[generated] serve file=${filename} status=200`);
29189
- const body = readFileSync43(filePath);
29291
+ const body = readFileSync44(filePath);
29190
29292
  return c.body(body, 200, {
29191
29293
  "Content-Type": contentType,
29192
29294
  "Cache-Control": "public, max-age=86400"
29193
29295
  });
29194
29296
  });
29195
- app71.route("/sites", sites_default);
29196
- app71.route("/listings", listings_default);
29197
- app71.route("/v", visitor_event_default);
29198
- app71.route("/v", visitor_consent_default);
29297
+ app72.route("/sites", sites_default);
29298
+ app72.route("/listings", listings_default);
29299
+ app72.route("/v", visitor_event_default);
29300
+ app72.route("/v", visitor_consent_default);
29199
29301
  var htmlCache = /* @__PURE__ */ new Map();
29200
29302
  var brandLogoPath = "/brand/maxy-monochrome.png";
29201
29303
  var brandIconPath = "/brand/maxy-monochrome.png";
29202
- if (BRAND_JSON_PATH && existsSync47(BRAND_JSON_PATH)) {
29304
+ if (BRAND_JSON_PATH && existsSync48(BRAND_JSON_PATH)) {
29203
29305
  try {
29204
- const fullBrand = JSON.parse(readFileSync43(BRAND_JSON_PATH, "utf-8"));
29306
+ const fullBrand = JSON.parse(readFileSync44(BRAND_JSON_PATH, "utf-8"));
29205
29307
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
29206
29308
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
29207
29309
  } catch {
@@ -29228,11 +29330,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
29228
29330
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
29229
29331
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
29230
29332
  var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
29231
- (p) => existsSync47(resolve42(process.cwd(), "public", p.replace(/^\//, "")))
29333
+ (p) => existsSync48(resolve42(process.cwd(), "public", p.replace(/^\//, "")))
29232
29334
  );
29233
29335
  var SW_SOURCE = (() => {
29234
29336
  try {
29235
- return readFileSync43(resolve42(process.cwd(), "public", "sw.js"), "utf-8");
29337
+ return readFileSync44(resolve42(process.cwd(), "public", "sw.js"), "utf-8");
29236
29338
  } catch {
29237
29339
  return null;
29238
29340
  }
@@ -29240,9 +29342,9 @@ var SW_SOURCE = (() => {
29240
29342
  function readInstalledVersion() {
29241
29343
  try {
29242
29344
  if (!PLATFORM_ROOT6) return "unknown";
29243
- const versionFile = join49(PLATFORM_ROOT6, "config", `.${BRAND.hostname}-version`);
29244
- if (!existsSync47(versionFile)) return "unknown";
29245
- const content = readFileSync43(versionFile, "utf-8").trim();
29345
+ const versionFile = join50(PLATFORM_ROOT6, "config", `.${BRAND.hostname}-version`);
29346
+ if (!existsSync48(versionFile)) return "unknown";
29347
+ const content = readFileSync44(versionFile, "utf-8").trim();
29246
29348
  return content || "unknown";
29247
29349
  } catch {
29248
29350
  return "unknown";
@@ -29253,7 +29355,7 @@ var versionScript = `<script>window.__MAXY_VERSION__=${JSON.stringify(INSTALLED_
29253
29355
  function cachedHtml(file) {
29254
29356
  let html = htmlCache.get(file);
29255
29357
  if (!html) {
29256
- html = readFileSync43(resolve42(process.cwd(), "public", file), "utf-8");
29358
+ html = readFileSync44(resolve42(process.cwd(), "public", file), "utf-8");
29257
29359
  const productNameEsc = escapeHtml(BRAND.productName);
29258
29360
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
29259
29361
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -29270,13 +29372,13 @@ ${clientErrorReporterScript}
29270
29372
  return html;
29271
29373
  }
29272
29374
  function loadBrandingCache(agentSlug) {
29273
- const configDir = join49(homedir4(), BRAND.configDir);
29375
+ const configDir = join50(homedir4(), BRAND.configDir);
29274
29376
  try {
29275
29377
  const accountId = getDefaultAccountId();
29276
29378
  if (!accountId) return null;
29277
- const cachePath = join49(configDir, "branding-cache", accountId, `${agentSlug}.json`);
29278
- if (!existsSync47(cachePath)) return null;
29279
- return JSON.parse(readFileSync43(cachePath, "utf-8"));
29379
+ const cachePath = join50(configDir, "branding-cache", accountId, `${agentSlug}.json`);
29380
+ if (!existsSync48(cachePath)) return null;
29381
+ return JSON.parse(readFileSync44(cachePath, "utf-8"));
29280
29382
  } catch {
29281
29383
  return null;
29282
29384
  }
@@ -29320,7 +29422,7 @@ function brandedPublicHtml(agentSlug) {
29320
29422
  function agentUnavailableHtml() {
29321
29423
  return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${escapeHtml(BRAND.productName)}</title></head><body style="font-family:system-ui,sans-serif;max-width:32rem;margin:4rem auto;padding:0 1.5rem;color:#222"><h1 style="font-size:1.25rem">Agent unavailable</h1><p>This agent isn't available right now. If you reached this page from a saved link, the agent may have been turned off.</p></body></html>`;
29322
29424
  }
29323
- app71.get("/", (c) => {
29425
+ app72.get("/", (c) => {
29324
29426
  const host = (c.req.header("host") ?? "").split(":")[0];
29325
29427
  const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
29326
29428
  if (klass === "operator") {
@@ -29342,12 +29444,12 @@ app71.get("/", (c) => {
29342
29444
  console.log(`[host-class] host=${host} class=admin served=index.html`);
29343
29445
  return c.html(cachedHtml("index.html"));
29344
29446
  });
29345
- app71.get("/public", (c) => {
29447
+ app72.get("/public", (c) => {
29346
29448
  const host = (c.req.header("host") ?? "").split(":")[0];
29347
29449
  if (isPublicHost(host)) return c.text("Not found", 404);
29348
29450
  return c.html(cachedHtml("public.html"));
29349
29451
  });
29350
- app71.get("/public-chat", (c) => {
29452
+ app72.get("/public-chat", (c) => {
29351
29453
  const host = (c.req.header("host") ?? "").split(":")[0];
29352
29454
  if (isPublicHost(host)) return c.text("Not found", 404);
29353
29455
  return c.html(cachedHtml("public.html"));
@@ -29366,12 +29468,12 @@ async function logViewerFetch(c, next) {
29366
29468
  duration_ms: Date.now() - start
29367
29469
  });
29368
29470
  }
29369
- app71.use("/vnc-viewer.html", logViewerFetch);
29370
- app71.use("/vnc-popout.html", logViewerFetch);
29371
- app71.get("/vnc-popout.html", (c) => {
29471
+ app72.use("/vnc-viewer.html", logViewerFetch);
29472
+ app72.use("/vnc-popout.html", logViewerFetch);
29473
+ app72.get("/vnc-popout.html", (c) => {
29372
29474
  let html = htmlCache.get("vnc-popout.html");
29373
29475
  if (!html) {
29374
- html = readFileSync43(resolve42(process.cwd(), "public", "vnc-popout.html"), "utf-8");
29476
+ html = readFileSync44(resolve42(process.cwd(), "public", "vnc-popout.html"), "utf-8");
29375
29477
  const name = escapeHtml(BRAND.productName);
29376
29478
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
29377
29479
  html = html.replace("</head>", ` ${brandScript}
@@ -29381,7 +29483,7 @@ app71.get("/vnc-popout.html", (c) => {
29381
29483
  }
29382
29484
  return c.html(html);
29383
29485
  });
29384
- app71.post("/api/vnc/client-event", async (c) => {
29486
+ app72.post("/api/vnc/client-event", async (c) => {
29385
29487
  let body;
29386
29488
  try {
29387
29489
  body = await c.req.json();
@@ -29402,11 +29504,11 @@ app71.post("/api/vnc/client-event", async (c) => {
29402
29504
  });
29403
29505
  return c.json({ ok: true });
29404
29506
  });
29405
- app71.get("/g/:slug", (c) => {
29507
+ app72.get("/g/:slug", (c) => {
29406
29508
  return c.html(brandedPublicHtml(resolveDefaultSlug() ?? void 0));
29407
29509
  });
29408
29510
  for (const pwa of PWA_SURFACES) {
29409
- app71.get(pwa.manifestPath, (c) => {
29511
+ app72.get(pwa.manifestPath, (c) => {
29410
29512
  const manifest = buildManifest(pwa, {
29411
29513
  productName: BRAND.productName,
29412
29514
  appIcon192: brandAppIcon192Path,
@@ -29422,7 +29524,7 @@ for (const pwa of PWA_SURFACES) {
29422
29524
  return c.body(JSON.stringify(manifest));
29423
29525
  });
29424
29526
  }
29425
- app71.get("/sw.js", (c) => {
29527
+ app72.get("/sw.js", (c) => {
29426
29528
  if (SW_SOURCE == null) {
29427
29529
  console.error("[pwa] op=sw status=500 reason=sw-source-missing");
29428
29530
  return c.text("Service worker unavailable", 500);
@@ -29431,12 +29533,12 @@ app71.get("/sw.js", (c) => {
29431
29533
  console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
29432
29534
  return c.body(SW_SOURCE);
29433
29535
  });
29434
- app71.get("/graph", (c) => {
29536
+ app72.get("/graph", (c) => {
29435
29537
  const host = (c.req.header("host") ?? "").split(":")[0];
29436
29538
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
29437
29539
  return c.html(cachedHtml("graph.html"));
29438
29540
  });
29439
- app71.get("/chat", (c) => {
29541
+ app72.get("/chat", (c) => {
29440
29542
  const host = (c.req.header("host") ?? "").split(":")[0];
29441
29543
  if (isOperatorHost(host, getOperatorDomains())) {
29442
29544
  console.log(`[host-class] host=${host} class=operator served=operator.html`);
@@ -29445,47 +29547,47 @@ app71.get("/chat", (c) => {
29445
29547
  if (isPublicHost(host)) return c.text("Not found", 404);
29446
29548
  return c.html(cachedHtml("chat.html"));
29447
29549
  });
29448
- app71.get("/data", (c) => {
29550
+ app72.get("/data", (c) => {
29449
29551
  const host = (c.req.header("host") ?? "").split(":")[0];
29450
29552
  if (isPublicHost(host)) return c.text("Not found", 404);
29451
29553
  return c.html(cachedHtml("data.html"));
29452
29554
  });
29453
- app71.get("/tasks", (c) => {
29555
+ app72.get("/tasks", (c) => {
29454
29556
  const host = (c.req.header("host") ?? "").split(":")[0];
29455
29557
  if (isPublicHost(host)) return c.text("Not found", 404);
29456
29558
  return c.html(cachedHtml("tasks.html"));
29457
29559
  });
29458
- app71.get("/activity", (c) => {
29560
+ app72.get("/activity", (c) => {
29459
29561
  const host = (c.req.header("host") ?? "").split(":")[0];
29460
29562
  if (isPublicHost(host)) return c.text("Not found", 404);
29461
29563
  return c.html(cachedHtml("activity.html"));
29462
29564
  });
29463
- app71.get("/calendar", (c) => {
29565
+ app72.get("/calendar", (c) => {
29464
29566
  const host = (c.req.header("host") ?? "").split(":")[0];
29465
29567
  if (isPublicHost(host)) return c.text("Not found", 404);
29466
29568
  return c.html(cachedHtml("calendar.html"));
29467
29569
  });
29468
- app71.get("/routines", (c) => {
29570
+ app72.get("/routines", (c) => {
29469
29571
  const host = (c.req.header("host") ?? "").split(":")[0];
29470
29572
  if (isPublicHost(host)) return c.text("Not found", 404);
29471
29573
  return c.html(cachedHtml("routines.html"));
29472
29574
  });
29473
- app71.get("/skills", (c) => {
29575
+ app72.get("/skills", (c) => {
29474
29576
  const host = (c.req.header("host") ?? "").split(":")[0];
29475
29577
  if (isPublicHost(host)) return c.text("Not found", 404);
29476
29578
  return c.html(cachedHtml("skills.html"));
29477
29579
  });
29478
- app71.get("/agents", (c) => {
29580
+ app72.get("/agents", (c) => {
29479
29581
  const host = (c.req.header("host") ?? "").split(":")[0];
29480
29582
  if (isPublicHost(host)) return c.text("Not found", 404);
29481
29583
  return c.html(cachedHtml("agents.html"));
29482
29584
  });
29483
- app71.get("/browser", (c) => {
29585
+ app72.get("/browser", (c) => {
29484
29586
  const host = (c.req.header("host") ?? "").split(":")[0];
29485
29587
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
29486
29588
  return c.html(cachedHtml("browser.html"));
29487
29589
  });
29488
- app71.get("/:slug", async (c, next) => {
29590
+ app72.get("/:slug", async (c, next) => {
29489
29591
  const slug = c.req.param("slug");
29490
29592
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
29491
29593
  const account = resolveAccount();
@@ -29500,13 +29602,13 @@ app71.get("/:slug", async (c, next) => {
29500
29602
  await next();
29501
29603
  });
29502
29604
  if (brandFaviconPath !== "/favicon.ico") {
29503
- app71.get("/favicon.ico", (c) => {
29605
+ app72.get("/favicon.ico", (c) => {
29504
29606
  c.header("Cache-Control", "public, max-age=300");
29505
29607
  return c.redirect(brandFaviconPath, 302);
29506
29608
  });
29507
29609
  }
29508
- mountStaticFiles(app71, "./public");
29509
- app71.all("*", (c) => {
29610
+ mountStaticFiles(app72, "./public");
29611
+ app72.all("*", (c) => {
29510
29612
  const host = (c.req.header("host") ?? "").split(":")[0];
29511
29613
  const path = c.req.path;
29512
29614
  if (isPublicHost(host)) {
@@ -29520,13 +29622,13 @@ app71.all("*", (c) => {
29520
29622
  });
29521
29623
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
29522
29624
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
29523
- var httpServer = serve({ fetch: app71.fetch, port, hostname });
29625
+ var httpServer = serve({ fetch: app72.fetch, port, hostname });
29524
29626
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29525
29627
  {
29526
- const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
29628
+ const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join50(__dirname, "..");
29527
29629
  const reconcileScript = resolve42(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
29528
29630
  const runReconcile = (ctx) => {
29529
- if (!existsSync47(reconcileScript)) return;
29631
+ if (!existsSync48(reconcileScript)) return;
29530
29632
  try {
29531
29633
  const child = spawn3(process.execPath, [reconcileScript], {
29532
29634
  env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
@@ -29546,7 +29648,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29546
29648
  detached: true,
29547
29649
  run: runReconcile
29548
29650
  });
29549
- const reconcileStatePath = join49(MAXY_DIR, "booking-reconcile-state.json");
29651
+ const reconcileStatePath = join50(MAXY_DIR, "booking-reconcile-state.json");
29550
29652
  registerLoop({
29551
29653
  name: "calendar-reconcile-liveness",
29552
29654
  intervalMs: 6e5,
@@ -29564,7 +29666,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29564
29666
  }
29565
29667
  {
29566
29668
  const DREAM_CYCLE_SWEEP_INTERVAL_MS = 36e5;
29567
- const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
29669
+ const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join50(__dirname, "..");
29568
29670
  const dreamSweepScript = resolve42(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
29569
29671
  registerLoop({
29570
29672
  name: "dream-cycle-sweep",
@@ -29572,7 +29674,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29572
29674
  firstRunDelayMs: 3e4,
29573
29675
  detached: true,
29574
29676
  run: (ctx) => {
29575
- if (!existsSync47(dreamSweepScript)) return;
29677
+ if (!existsSync48(dreamSweepScript)) return;
29576
29678
  try {
29577
29679
  const child = spawn3(process.execPath, [dreamSweepScript], {
29578
29680
  env: { ...process.env, PLATFORM_ROOT: dreamPlatformRoot },
@@ -29588,11 +29690,11 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29588
29690
  });
29589
29691
  }
29590
29692
  {
29591
- const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
29693
+ const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join50(__dirname, "..");
29592
29694
  const outlookScript = resolve42(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
29593
29695
  const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
29594
29696
  const runOutlookComplete = (ctx) => {
29595
- if (!existsSync47(outlookScript)) return;
29697
+ if (!existsSync48(outlookScript)) return;
29596
29698
  try {
29597
29699
  const child = spawn3(process.execPath, [outlookScript], {
29598
29700
  env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
@@ -29614,19 +29716,19 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29614
29716
  });
29615
29717
  }
29616
29718
  {
29617
- const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
29719
+ const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join50(__dirname, "..");
29618
29720
  const strandedAccountsDir = resolve42(auditRoot, "..", "data/accounts");
29619
29721
  const STRANDED_AUDIT_INTERVAL_MS = 3e5;
29620
29722
  const STRANDED_AGE_MS = 16 * 6e4;
29621
29723
  const STRANDED_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
29622
29724
  const runStrandedAudit = () => {
29623
29725
  try {
29624
- if (!existsSync47(strandedAccountsDir)) return;
29726
+ if (!existsSync48(strandedAccountsDir)) return;
29625
29727
  const now = Date.now();
29626
29728
  for (const name of readdirSync28(strandedAccountsDir)) {
29627
29729
  if (!STRANDED_UUID_RE.test(name)) continue;
29628
29730
  const pendingPath2 = resolve42(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
29629
- if (!existsSync47(pendingPath2)) continue;
29731
+ if (!existsSync48(pendingPath2)) continue;
29630
29732
  const ageMs2 = now - statSync24(pendingPath2).mtimeMs;
29631
29733
  if (ageMs2 > STRANDED_AGE_MS) {
29632
29734
  console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs2 / 1e3)}`);
@@ -29644,7 +29746,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29644
29746
  });
29645
29747
  }
29646
29748
  {
29647
- const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
29749
+ const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join50(__dirname, "..");
29648
29750
  const googleAccountsDir = resolve42(googleRoot, "..", "data/accounts");
29649
29751
  const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
29650
29752
  const runGooglePendingAuditSafe = () => {
@@ -29663,7 +29765,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29663
29765
  const googleAuditScript = resolve42(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
29664
29766
  const GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS = 36e5;
29665
29767
  const runGoogleAccountAudit = (ctx) => {
29666
- if (!existsSync47(googleAuditScript)) return;
29768
+ if (!existsSync48(googleAuditScript)) return;
29667
29769
  try {
29668
29770
  const child = spawn3(process.execPath, [googleAuditScript], {
29669
29771
  env: { ...process.env, PLATFORM_ROOT: googleRoot },
@@ -29688,7 +29790,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29688
29790
  });
29689
29791
  }
29690
29792
  {
29691
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
29793
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join50(__dirname, "..");
29692
29794
  const STORAGE_AUDIT_INTERVAL_MS = 3e5;
29693
29795
  const runStorageAuditSafe = () => runStorageAudit(auditPlatformRoot).catch((err) => {
29694
29796
  console.error(`[storage-audit] error="${err.message}"`);
@@ -29749,7 +29851,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29749
29851
  });
29750
29852
  }
29751
29853
  {
29752
- const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
29854
+ const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join50(__dirname, "..");
29753
29855
  const publishScript = resolve42(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
29754
29856
  const PUBLISH_INTERVAL_MS = 3e5;
29755
29857
  const bookingAccounts = () => {
@@ -29761,7 +29863,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29761
29863
  }
29762
29864
  };
29763
29865
  const spawnPublish = (account, ctx) => {
29764
- if (!existsSync47(publishScript)) return;
29866
+ if (!existsSync48(publishScript)) return;
29765
29867
  try {
29766
29868
  const child = spawn3(process.execPath, [publishScript], {
29767
29869
  env: {
@@ -29783,8 +29885,8 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29783
29885
  const availPath = resolve42(account.accountDir, "calendar-availability.json");
29784
29886
  let hasBookingSite = false;
29785
29887
  try {
29786
- if (existsSync47(availPath)) {
29787
- const cfg = JSON.parse(readFileSync43(availPath, "utf-8"));
29888
+ if (existsSync48(availPath)) {
29889
+ const cfg = JSON.parse(readFileSync44(availPath, "utf-8"));
29788
29890
  hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
29789
29891
  }
29790
29892
  } catch {
@@ -29792,9 +29894,9 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29792
29894
  if (!hasBookingSite) return;
29793
29895
  const statePath = resolve42(account.accountDir, "state", "booking-availability", "last-publish.json");
29794
29896
  let lastSuccessAt = null;
29795
- if (existsSync47(statePath)) {
29897
+ if (existsSync48(statePath)) {
29796
29898
  try {
29797
- const rec = JSON.parse(readFileSync43(statePath, "utf-8"));
29899
+ const rec = JSON.parse(readFileSync44(statePath, "utf-8"));
29798
29900
  lastSuccessAt = rec.lastSuccessAt ?? null;
29799
29901
  } catch {
29800
29902
  console.error(`[calendar-availability] op=audit accountId=${account.accountId} snapshotAgeMs=na reason=bad-state-file`);
@@ -29826,12 +29928,12 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29826
29928
  startTimeEntryCensus(() => getSession());
29827
29929
  startLedgerCensus(() => getSession());
29828
29930
  {
29829
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..");
29931
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join50(__dirname, "..");
29830
29932
  const auditScript = resolve42(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
29831
29933
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
29832
29934
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
29833
29935
  const runConnectorAudit = (ctx) => {
29834
- if (!existsSync47(auditScript)) return;
29936
+ if (!existsSync48(auditScript)) return;
29835
29937
  try {
29836
29938
  const child = spawn3(process.execPath, [auditScript], {
29837
29939
  env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
@@ -29911,7 +30013,7 @@ for (const m of SUBAPP_MANIFEST) {
29911
30013
  }
29912
30014
  try {
29913
30015
  const registered = [];
29914
- for (const r of app71.routes ?? []) {
30016
+ for (const r of app72.routes ?? []) {
29915
30017
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
29916
30018
  if (AGENT_SLUG_PATTERN.test(r.path)) {
29917
30019
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -29951,11 +30053,11 @@ try {
29951
30053
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
29952
30054
  async function runAdminUserReconcileTick() {
29953
30055
  try {
29954
- if (!existsSync47(USERS_FILE)) {
30056
+ if (!existsSync48(USERS_FILE)) {
29955
30057
  console.error("[adminuser-self-heal] skip reason=no-users-file");
29956
30058
  return;
29957
30059
  }
29958
- const usersRaw = readFileSync43(USERS_FILE, "utf-8").trim();
30060
+ const usersRaw = readFileSync44(USERS_FILE, "utf-8").trim();
29959
30061
  if (!usersRaw) {
29960
30062
  console.error("[adminuser-self-heal] skip reason=empty-users-file");
29961
30063
  return;
@@ -30007,8 +30109,8 @@ registerLoop({
30007
30109
  });
30008
30110
  var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
30009
30111
  function countUsersRows() {
30010
- if (!existsSync47(USERS_FILE)) return 0;
30011
- const raw = readFileSync43(USERS_FILE, "utf-8").trim();
30112
+ if (!existsSync48(USERS_FILE)) return 0;
30113
+ const raw = readFileSync44(USERS_FILE, "utf-8").trim();
30012
30114
  if (!raw) return 0;
30013
30115
  const users = JSON.parse(raw);
30014
30116
  return users.filter((u) => typeof u.userId === "string").length;
@@ -30142,7 +30244,7 @@ if (bootAccountConfig?.whatsapp) {
30142
30244
  }
30143
30245
  init({
30144
30246
  configDir: configDirForWhatsApp,
30145
- platformRoot: resolve42(process.env.MAXY_PLATFORM_ROOT ?? join49(__dirname, "..")),
30247
+ platformRoot: resolve42(process.env.MAXY_PLATFORM_ROOT ?? join50(__dirname, "..")),
30146
30248
  accountConfig: bootAccountConfig,
30147
30249
  // Task 2074 — enrich with the sub-account name and fan out to every open
30148
30250
  // admin SSE stream. Fire-and-forget: the manager's persist path must not