@rubytech/create-sitedesk-code 0.1.528 → 0.1.530

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 (282) hide show
  1. package/dist/index.js +13 -0
  2. package/package.json +1 -1
  3. package/payload/platform/lib/account-ingest-token/dist/index.d.ts +21 -0
  4. package/payload/platform/lib/account-ingest-token/dist/index.d.ts.map +1 -0
  5. package/payload/platform/lib/account-ingest-token/dist/index.js +128 -0
  6. package/payload/platform/lib/account-ingest-token/dist/index.js.map +1 -0
  7. package/payload/platform/lib/account-ingest-token/src/index.ts +137 -0
  8. package/payload/platform/lib/account-ingest-token/tsconfig.json +8 -0
  9. package/payload/platform/lib/agent-dispatch-rule/dist/index.d.ts +5 -0
  10. package/payload/platform/lib/agent-dispatch-rule/dist/index.d.ts.map +1 -1
  11. package/payload/platform/lib/agent-dispatch-rule/dist/index.js.map +1 -1
  12. package/payload/platform/lib/agent-dispatch-rule/src/index.ts +5 -0
  13. package/payload/platform/lib/routine-templates/dist/index.d.ts +19 -3
  14. package/payload/platform/lib/routine-templates/dist/index.d.ts.map +1 -1
  15. package/payload/platform/lib/routine-templates/dist/index.js +22 -4
  16. package/payload/platform/lib/routine-templates/dist/index.js.map +1 -1
  17. package/payload/platform/lib/routine-templates/dist/roster.d.ts +19 -6
  18. package/payload/platform/lib/routine-templates/dist/roster.d.ts.map +1 -1
  19. package/payload/platform/lib/routine-templates/dist/roster.js +127 -17
  20. package/payload/platform/lib/routine-templates/dist/roster.js.map +1 -1
  21. package/payload/platform/lib/routine-templates/src/__tests__/roster.test.ts +46 -3
  22. package/payload/platform/lib/routine-templates/src/__tests__/seed.test.ts +52 -10
  23. package/payload/platform/lib/routine-templates/src/index.ts +30 -4
  24. package/payload/platform/lib/routine-templates/src/roster.ts +147 -17
  25. package/payload/platform/package.json +2 -2
  26. package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
  27. package/payload/platform/plugins/admin/PLUGIN.md +5 -1
  28. package/payload/platform/plugins/admin/mcp/dist/index.js +37 -0
  29. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  30. package/payload/platform/plugins/admin/mcp/dist/tools/linkedin-ingest-token.d.ts +10 -0
  31. package/payload/platform/plugins/admin/mcp/dist/tools/linkedin-ingest-token.d.ts.map +1 -0
  32. package/payload/platform/plugins/admin/mcp/dist/tools/linkedin-ingest-token.js +22 -0
  33. package/payload/platform/plugins/admin/mcp/dist/tools/linkedin-ingest-token.js.map +1 -0
  34. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +31 -6
  35. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +12 -0
  36. package/payload/platform/plugins/docs/references/admin-ui.md +28 -3
  37. package/payload/platform/plugins/docs/references/linkedin-extension.md +2 -2
  38. package/payload/platform/plugins/linkedin-extension/extension/README.md +3 -3
  39. package/payload/platform/plugins/linkedin-extension/extension/background/sw.js +12 -7
  40. package/payload/platform/plugins/linkedin-extension/extension/content/profile.js +4 -1
  41. package/payload/platform/plugins/linkedin-extension/extension/content/thread.js +4 -1
  42. package/payload/platform/plugins/linkedin-extension/extension/options/options.html +3 -3
  43. package/payload/platform/plugins/linkedin-extension/extension/options/options.js +24 -16
  44. package/payload/platform/plugins/scheduling/PLUGIN.md +2 -0
  45. package/payload/platform/plugins/scheduling/mcp/dist/index.js +5 -0
  46. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  47. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/normalise-start-date.test.d.ts +2 -0
  48. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/normalise-start-date.test.d.ts.map +1 -0
  49. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/normalise-start-date.test.js +100 -0
  50. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/normalise-start-date.test.js.map +1 -0
  51. package/payload/platform/plugins/scheduling/mcp/dist/lib/dispatcher-env.d.ts +36 -0
  52. package/payload/platform/plugins/scheduling/mcp/dist/lib/dispatcher-env.d.ts.map +1 -0
  53. package/payload/platform/plugins/scheduling/mcp/dist/lib/dispatcher-env.js +82 -0
  54. package/payload/platform/plugins/scheduling/mcp/dist/lib/dispatcher-env.js.map +1 -0
  55. package/payload/platform/plugins/scheduling/mcp/dist/lib/time-format.d.ts +31 -0
  56. package/payload/platform/plugins/scheduling/mcp/dist/lib/time-format.d.ts.map +1 -1
  57. package/payload/platform/plugins/scheduling/mcp/dist/lib/time-format.js +99 -0
  58. package/payload/platform/plugins/scheduling/mcp/dist/lib/time-format.js.map +1 -1
  59. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +12 -12
  60. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js.map +1 -1
  61. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/converge-startdate-utc.test.d.ts +2 -0
  62. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/converge-startdate-utc.test.d.ts.map +1 -0
  63. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/converge-startdate-utc.test.js +79 -0
  64. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/converge-startdate-utc.test.js.map +1 -0
  65. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/dispatch-lateness.test.d.ts +2 -0
  66. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/dispatch-lateness.test.d.ts.map +1 -0
  67. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/dispatch-lateness.test.js +23 -0
  68. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/dispatch-lateness.test.js.map +1 -0
  69. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js +61 -1
  70. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js.map +1 -1
  71. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/suspension-census.test.js +45 -2
  72. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/suspension-census.test.js.map +1 -1
  73. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +33 -1
  74. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
  75. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +111 -9
  76. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
  77. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +21 -69
  78. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
  79. package/payload/platform/plugins/scheduling/mcp/dist/scripts/converge-startdate-utc.d.ts +24 -0
  80. package/payload/platform/plugins/scheduling/mcp/dist/scripts/converge-startdate-utc.d.ts.map +1 -0
  81. package/payload/platform/plugins/scheduling/mcp/dist/scripts/converge-startdate-utc.js +87 -0
  82. package/payload/platform/plugins/scheduling/mcp/dist/scripts/converge-startdate-utc.js.map +1 -0
  83. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-startdate.test.d.ts +2 -0
  84. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-startdate.test.d.ts.map +1 -0
  85. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-startdate.test.js +123 -0
  86. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-startdate.test.js.map +1 -0
  87. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-startdate.test.d.ts +2 -0
  88. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-startdate.test.d.ts.map +1 -0
  89. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-startdate.test.js +71 -0
  90. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-startdate.test.js.map +1 -0
  91. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-status.test.js +14 -3
  92. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-status.test.js.map +1 -1
  93. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +9 -0
  94. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
  95. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +19 -3
  96. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
  97. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts.map +1 -1
  98. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js +24 -9
  99. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
  100. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  101. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  102. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  103. package/payload/server/{chunk-UTIHI6KV.js → chunk-2YMGNYA3.js} +12 -12
  104. package/payload/server/{manager-B4LRDZKC.js → manager-XPRN5UF5.js} +1 -1
  105. package/payload/server/package.json +1 -1
  106. package/payload/server/public/activity.html +5 -5
  107. package/payload/server/public/agents.html +4 -4
  108. package/payload/server/public/assets/{AdminLoginScreens-Bx9vPuUg.js → AdminLoginScreens-7Czw3MAC.js} +1 -1
  109. package/payload/server/public/assets/AdminLoginScreens-7Czw3MAC.js.br +0 -0
  110. package/payload/server/public/assets/AdminLoginScreens-7Czw3MAC.js.gz +0 -0
  111. package/payload/server/public/assets/{AdminShell-BxJPbC3p.js → AdminShell-D5GApZ_n.js} +1 -1
  112. package/payload/server/public/assets/AdminShell-D5GApZ_n.js.br +0 -0
  113. package/payload/server/public/assets/AdminShell-D5GApZ_n.js.gz +0 -0
  114. package/payload/server/public/assets/{CdpScreencastSurface-5HLhTQTV.js → CdpScreencastSurface-BbekDUFw.js} +1 -1
  115. package/payload/server/public/assets/CdpScreencastSurface-BbekDUFw.js.br +0 -0
  116. package/payload/server/public/assets/CdpScreencastSurface-BbekDUFw.js.gz +0 -0
  117. package/payload/server/public/assets/{activity-BaSYn62l.js → activity-ClI-RgJu.js} +1 -1
  118. package/payload/server/public/assets/activity-ClI-RgJu.js.br +0 -0
  119. package/payload/server/public/assets/activity-ClI-RgJu.js.gz +0 -0
  120. package/payload/server/public/assets/{admin-CYCKrV_x.js → admin-svtCmBPk.js} +1 -1
  121. package/payload/server/public/assets/admin-svtCmBPk.js.br +0 -0
  122. package/payload/server/public/assets/admin-svtCmBPk.js.gz +0 -0
  123. package/payload/server/public/assets/{agents-D8EJG-ta.js → agents-BO8YBj8d.js} +1 -1
  124. package/payload/server/public/assets/agents-BO8YBj8d.js.br +0 -0
  125. package/payload/server/public/assets/agents-BO8YBj8d.js.gz +0 -0
  126. package/payload/server/public/assets/{browser-D6Y_Zu8C.js → browser-Bj8oTG5R.js} +1 -1
  127. package/payload/server/public/assets/browser-Bj8oTG5R.js.br +0 -0
  128. package/payload/server/public/assets/browser-Bj8oTG5R.js.gz +0 -0
  129. package/payload/server/public/assets/{calendar-DD4oVa-r.js → calendar-CrkSY8U7.js} +1 -1
  130. package/payload/server/public/assets/calendar-CrkSY8U7.js.br +0 -0
  131. package/payload/server/public/assets/calendar-CrkSY8U7.js.gz +0 -0
  132. package/payload/server/public/assets/chat-Bvxoni2e.js +1 -0
  133. package/payload/server/public/assets/chat-Bvxoni2e.js.br +0 -0
  134. package/payload/server/public/assets/chat-Bvxoni2e.js.gz +0 -0
  135. package/payload/server/public/assets/chevron-left-CdUzxzeB.js +1 -0
  136. package/payload/server/public/assets/chevron-left-CdUzxzeB.js.br +0 -0
  137. package/payload/server/public/assets/chevron-right-CKGwd-M0.js +1 -0
  138. package/payload/server/public/assets/chevron-right-CKGwd-M0.js.br +0 -0
  139. package/payload/server/public/assets/clock-Cf8Oe9qi.js +1 -0
  140. package/payload/server/public/assets/clock-Cf8Oe9qi.js.br +0 -0
  141. package/payload/server/public/assets/clock-Cf8Oe9qi.js.gz +0 -0
  142. package/payload/server/public/assets/data-DF0Pstdp.js +1 -0
  143. package/payload/server/public/assets/data-DF0Pstdp.js.br +1 -0
  144. package/payload/server/public/assets/data-DF0Pstdp.js.gz +0 -0
  145. package/payload/server/public/assets/{file-download-sXU3_umF.js → file-download-Di_s0_4w.js} +1 -1
  146. package/payload/server/public/assets/file-download-Di_s0_4w.js.br +0 -0
  147. package/payload/server/public/assets/file-download-Di_s0_4w.js.gz +0 -0
  148. package/payload/server/public/assets/{file-text-CeXBviDH.js → file-text-CP1KIrJV.js} +1 -1
  149. package/payload/server/public/assets/file-text-CP1KIrJV.js.br +1 -0
  150. package/payload/server/public/assets/file-text-CP1KIrJV.js.gz +0 -0
  151. package/payload/server/public/assets/{graph-BSuDP6k7.js → graph-BCMscnCV.js} +1 -1
  152. package/payload/server/public/assets/graph-BCMscnCV.js.br +0 -0
  153. package/payload/server/public/assets/graph-BCMscnCV.js.gz +0 -0
  154. package/payload/server/public/assets/{graph-labels-D2pQkgYW.js → graph-labels-CgP17xHK.js} +1 -1
  155. package/payload/server/public/assets/graph-labels-CgP17xHK.js.br +0 -0
  156. package/payload/server/public/assets/graph-labels-CgP17xHK.js.gz +0 -0
  157. package/payload/server/public/assets/{maximize-2-DlzSNygU.js → maximize-2-DkQzDv-g.js} +1 -1
  158. package/payload/server/public/assets/maximize-2-DkQzDv-g.js.br +0 -0
  159. package/payload/server/public/assets/maximize-2-DkQzDv-g.js.gz +0 -0
  160. package/payload/server/public/assets/{operator-BP61-xjz.js → operator-CLbCar9e.js} +1 -1
  161. package/payload/server/public/assets/operator-CLbCar9e.js.br +0 -0
  162. package/payload/server/public/assets/operator-CLbCar9e.js.gz +0 -0
  163. package/payload/server/public/assets/{page-DX7ArY_s.js → page-CNJl3tWT.js} +1 -1
  164. package/payload/server/public/assets/page-CNJl3tWT.js.br +0 -0
  165. package/payload/server/public/assets/page-CNJl3tWT.js.gz +0 -0
  166. package/payload/server/public/assets/{page-eQ4OVros.js → page-CPVUAwb8.js} +1 -1
  167. package/payload/server/public/assets/page-CPVUAwb8.js.br +0 -0
  168. package/payload/server/public/assets/page-CPVUAwb8.js.gz +0 -0
  169. package/payload/server/public/assets/{public-DPDKFKM2.js → public-DQea3Ybz.js} +1 -1
  170. package/payload/server/public/assets/public-DQea3Ybz.js.br +0 -0
  171. package/payload/server/public/assets/public-DQea3Ybz.js.gz +0 -0
  172. package/payload/server/public/assets/{rotate-ccw-BR0JbPFV.js → rotate-ccw-DPw0vXC0.js} +1 -1
  173. package/payload/server/public/assets/rotate-ccw-DPw0vXC0.js.br +0 -0
  174. package/payload/server/public/assets/rotate-ccw-DPw0vXC0.js.gz +0 -0
  175. package/payload/server/public/assets/routines-CwiiYpfK.js +2 -0
  176. package/payload/server/public/assets/routines-CwiiYpfK.js.br +0 -0
  177. package/payload/server/public/assets/routines-CwiiYpfK.js.gz +0 -0
  178. package/payload/server/public/assets/{skills-fH0uA7cj.js → skills-0FOjKUM-.js} +1 -1
  179. package/payload/server/public/assets/skills-0FOjKUM-.js.br +0 -0
  180. package/payload/server/public/assets/skills-0FOjKUM-.js.gz +0 -0
  181. package/payload/server/public/assets/{tasks-CrVzFrTR.js → tasks-BUVsPEGm.js} +1 -1
  182. package/payload/server/public/assets/tasks-BUVsPEGm.js.br +0 -0
  183. package/payload/server/public/assets/tasks-BUVsPEGm.js.gz +0 -0
  184. package/payload/server/public/assets/{time-entry-format-C_0jiMpQ.js → time-entry-format-B6fX_19a.js} +1 -1
  185. package/payload/server/public/assets/time-entry-format-B6fX_19a.js.br +0 -0
  186. package/payload/server/public/assets/time-entry-format-B6fX_19a.js.gz +0 -0
  187. package/payload/server/public/assets/{triangle-alert-eLJHC_QJ.js → triangle-alert-vAaSDhVq.js} +1 -1
  188. package/payload/server/public/assets/triangle-alert-vAaSDhVq.js.br +0 -0
  189. package/payload/server/public/assets/triangle-alert-vAaSDhVq.js.gz +0 -0
  190. package/payload/server/public/assets/{useCopyFeedback-vPCmdOmY.js → useCopyFeedback-BvIRgs7W.js} +1 -1
  191. package/payload/server/public/assets/useCopyFeedback-BvIRgs7W.js.br +0 -0
  192. package/payload/server/public/assets/useCopyFeedback-BvIRgs7W.js.gz +0 -0
  193. package/payload/server/public/assets/{useSubAccountSwitcher-DxuUS_C7.css → useSubAccountSwitcher-DM5Y9eio.css} +1 -1
  194. package/payload/server/public/assets/useSubAccountSwitcher-DM5Y9eio.css.br +0 -0
  195. package/payload/server/public/assets/{useSubAccountSwitcher-DxuUS_C7.css.gz → useSubAccountSwitcher-DM5Y9eio.css.gz} +0 -0
  196. package/payload/server/public/assets/{useVoiceRecorder-D5bFDRqL.js → useVoiceRecorder-CiDOh8PG.js} +1 -1
  197. package/payload/server/public/assets/useVoiceRecorder-CiDOh8PG.js.br +0 -0
  198. package/payload/server/public/assets/useVoiceRecorder-CiDOh8PG.js.gz +0 -0
  199. package/payload/server/public/assets/{wrench-sXisQXkf.js → wrench-BNBtwT2p.js} +1 -1
  200. package/payload/server/public/assets/wrench-BNBtwT2p.js.br +0 -0
  201. package/payload/server/public/assets/wrench-BNBtwT2p.js.gz +0 -0
  202. package/payload/server/public/browser.html +5 -5
  203. package/payload/server/public/calendar.html +7 -7
  204. package/payload/server/public/chat.html +13 -13
  205. package/payload/server/public/data.html +12 -12
  206. package/payload/server/public/graph.html +9 -9
  207. package/payload/server/public/index.html +16 -16
  208. package/payload/server/public/operator.html +15 -15
  209. package/payload/server/public/public.html +13 -13
  210. package/payload/server/public/routines.html +7 -7
  211. package/payload/server/public/skills.html +5 -5
  212. package/payload/server/public/tasks.html +6 -6
  213. package/payload/server/server.js +353 -209
  214. package/payload/server/public/assets/AdminLoginScreens-Bx9vPuUg.js.br +0 -0
  215. package/payload/server/public/assets/AdminLoginScreens-Bx9vPuUg.js.gz +0 -0
  216. package/payload/server/public/assets/AdminShell-BxJPbC3p.js.br +0 -0
  217. package/payload/server/public/assets/AdminShell-BxJPbC3p.js.gz +0 -0
  218. package/payload/server/public/assets/CdpScreencastSurface-5HLhTQTV.js.br +0 -0
  219. package/payload/server/public/assets/CdpScreencastSurface-5HLhTQTV.js.gz +0 -0
  220. package/payload/server/public/assets/activity-BaSYn62l.js.br +0 -0
  221. package/payload/server/public/assets/activity-BaSYn62l.js.gz +0 -0
  222. package/payload/server/public/assets/admin-CYCKrV_x.js.br +0 -0
  223. package/payload/server/public/assets/admin-CYCKrV_x.js.gz +0 -0
  224. package/payload/server/public/assets/agents-D8EJG-ta.js.br +0 -0
  225. package/payload/server/public/assets/agents-D8EJG-ta.js.gz +0 -0
  226. package/payload/server/public/assets/browser-D6Y_Zu8C.js.br +0 -0
  227. package/payload/server/public/assets/browser-D6Y_Zu8C.js.gz +0 -0
  228. package/payload/server/public/assets/calendar-DD4oVa-r.js.br +0 -0
  229. package/payload/server/public/assets/calendar-DD4oVa-r.js.gz +0 -0
  230. package/payload/server/public/assets/chat-CwWs69PO.js +0 -1
  231. package/payload/server/public/assets/chat-CwWs69PO.js.br +0 -0
  232. package/payload/server/public/assets/chat-CwWs69PO.js.gz +0 -0
  233. package/payload/server/public/assets/chevron-left-ClfIy5Fx.js +0 -1
  234. package/payload/server/public/assets/chevron-right-B0QvXpxl.js +0 -1
  235. package/payload/server/public/assets/chevron-right-B0QvXpxl.js.br +0 -0
  236. package/payload/server/public/assets/clock-BIaRnIP_.js +0 -1
  237. package/payload/server/public/assets/clock-BIaRnIP_.js.br +0 -0
  238. package/payload/server/public/assets/clock-BIaRnIP_.js.gz +0 -0
  239. package/payload/server/public/assets/data-O_9Kiicl.js +0 -1
  240. package/payload/server/public/assets/data-O_9Kiicl.js.br +0 -2
  241. package/payload/server/public/assets/data-O_9Kiicl.js.gz +0 -0
  242. package/payload/server/public/assets/file-download-sXU3_umF.js.br +0 -0
  243. package/payload/server/public/assets/file-download-sXU3_umF.js.gz +0 -0
  244. package/payload/server/public/assets/file-text-CeXBviDH.js.br +0 -0
  245. package/payload/server/public/assets/file-text-CeXBviDH.js.gz +0 -0
  246. package/payload/server/public/assets/graph-BSuDP6k7.js.br +0 -0
  247. package/payload/server/public/assets/graph-BSuDP6k7.js.gz +0 -0
  248. package/payload/server/public/assets/graph-labels-D2pQkgYW.js.br +0 -0
  249. package/payload/server/public/assets/graph-labels-D2pQkgYW.js.gz +0 -0
  250. package/payload/server/public/assets/maximize-2-DlzSNygU.js.br +0 -0
  251. package/payload/server/public/assets/maximize-2-DlzSNygU.js.gz +0 -0
  252. package/payload/server/public/assets/operator-BP61-xjz.js.br +0 -0
  253. package/payload/server/public/assets/operator-BP61-xjz.js.gz +0 -0
  254. package/payload/server/public/assets/page-DX7ArY_s.js.br +0 -0
  255. package/payload/server/public/assets/page-DX7ArY_s.js.gz +0 -0
  256. package/payload/server/public/assets/page-eQ4OVros.js.br +0 -0
  257. package/payload/server/public/assets/page-eQ4OVros.js.gz +0 -0
  258. package/payload/server/public/assets/public-DPDKFKM2.js.br +0 -0
  259. package/payload/server/public/assets/public-DPDKFKM2.js.gz +0 -0
  260. package/payload/server/public/assets/rotate-ccw-BR0JbPFV.js.br +0 -0
  261. package/payload/server/public/assets/rotate-ccw-BR0JbPFV.js.gz +0 -0
  262. package/payload/server/public/assets/routines-y413YZa-.js +0 -1
  263. package/payload/server/public/assets/routines-y413YZa-.js.br +0 -0
  264. package/payload/server/public/assets/routines-y413YZa-.js.gz +0 -0
  265. package/payload/server/public/assets/skills-fH0uA7cj.js.br +0 -0
  266. package/payload/server/public/assets/skills-fH0uA7cj.js.gz +0 -0
  267. package/payload/server/public/assets/tasks-CrVzFrTR.js.br +0 -0
  268. package/payload/server/public/assets/tasks-CrVzFrTR.js.gz +0 -0
  269. package/payload/server/public/assets/time-entry-format-C_0jiMpQ.js.br +0 -1
  270. package/payload/server/public/assets/time-entry-format-C_0jiMpQ.js.gz +0 -0
  271. package/payload/server/public/assets/triangle-alert-eLJHC_QJ.js.br +0 -1
  272. package/payload/server/public/assets/triangle-alert-eLJHC_QJ.js.gz +0 -0
  273. package/payload/server/public/assets/useCopyFeedback-vPCmdOmY.js.br +0 -0
  274. package/payload/server/public/assets/useCopyFeedback-vPCmdOmY.js.gz +0 -0
  275. package/payload/server/public/assets/useSubAccountSwitcher-DxuUS_C7.css.br +0 -0
  276. package/payload/server/public/assets/useVoiceRecorder-D5bFDRqL.js.br +0 -0
  277. package/payload/server/public/assets/useVoiceRecorder-D5bFDRqL.js.gz +0 -0
  278. package/payload/server/public/assets/wrench-sXisQXkf.js.br +0 -0
  279. package/payload/server/public/assets/wrench-sXisQXkf.js.gz +0 -0
  280. /package/payload/server/public/assets/{useSubAccountSwitcher-DMr3DR5N.js → useSubAccountSwitcher-BEwQMRMo.js} +0 -0
  281. /package/payload/server/public/assets/{useSubAccountSwitcher-DMr3DR5N.js.br → useSubAccountSwitcher-BEwQMRMo.js.br} +0 -0
  282. /package/payload/server/public/assets/{useSubAccountSwitcher-DMr3DR5N.js.gz → useSubAccountSwitcher-BEwQMRMo.js.gz} +0 -0
@@ -183,7 +183,7 @@ import {
183
183
  waitForConnection,
184
184
  warnNonUuidAccount,
185
185
  writeChatMetadataMerged
186
- } from "./chunk-UTIHI6KV.js";
186
+ } from "./chunk-2YMGNYA3.js";
187
187
  import {
188
188
  ACCOUNTS_DIR,
189
189
  BIN_DIR,
@@ -1800,10 +1800,10 @@ var require_dist5 = __commonJS({
1800
1800
  });
1801
1801
 
1802
1802
  // server/index.ts
1803
- import { readFileSync as readFileSync45, existsSync as existsSync48, watchFile, readdirSync as readdirSync28, statSync as statSync25 } from "fs";
1803
+ import { readFileSync as readFileSync46, existsSync as existsSync49, watchFile, readdirSync as readdirSync29, statSync as statSync25 } from "fs";
1804
1804
  import { spawn as spawn3 } from "child_process";
1805
1805
  import { createHash as createHash7 } from "crypto";
1806
- import { resolve as resolve43, join as join52, basename as basename16 } from "path";
1806
+ import { resolve as resolve45, join as join52, basename as basename16 } from "path";
1807
1807
  import { homedir as homedir4 } from "os";
1808
1808
 
1809
1809
  // server/lib/route-cache-watchers.ts
@@ -3299,20 +3299,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
3299
3299
 
3300
3300
  // server/routes/health.ts
3301
3301
  function checkPort(port2, timeoutMs = 500) {
3302
- return new Promise((resolve44) => {
3302
+ return new Promise((resolve46) => {
3303
3303
  const socket = createConnection2(port2, "127.0.0.1");
3304
3304
  socket.setTimeout(timeoutMs);
3305
3305
  socket.once("connect", () => {
3306
3306
  socket.destroy();
3307
- resolve44(true);
3307
+ resolve46(true);
3308
3308
  });
3309
3309
  socket.once("error", () => {
3310
3310
  socket.destroy();
3311
- resolve44(false);
3311
+ resolve46(false);
3312
3312
  });
3313
3313
  socket.once("timeout", () => {
3314
3314
  socket.destroy();
3315
- resolve44(false);
3315
+ resolve46(false);
3316
3316
  });
3317
3317
  });
3318
3318
  }
@@ -4999,11 +4999,11 @@ async function defaultHttpGet(url) {
4999
4999
  }
5000
5000
  }
5001
5001
  async function defaultResolve(accountId) {
5002
- const { resolveSocket: resolveSocket2 } = await import("./manager-B4LRDZKC.js");
5002
+ const { resolveSocket: resolveSocket2 } = await import("./manager-XPRN5UF5.js");
5003
5003
  return resolveSocket2(accountId);
5004
5004
  }
5005
5005
  async function fetchAvatar(accountId, jid, deps = {}) {
5006
- const resolve44 = deps.resolve;
5006
+ const resolve46 = deps.resolve;
5007
5007
  const httpGet = deps.httpGet ?? defaultHttpGet;
5008
5008
  const maxAgeMs = deps.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
5009
5009
  const cached3 = readAvatar(accountId, jid);
@@ -5013,7 +5013,7 @@ async function fetchAvatar(accountId, jid, deps = {}) {
5013
5013
  return "fresh";
5014
5014
  }
5015
5015
  console.log(`${TAG6} op=cache jid=${jid} hit=false ageMs=${ageMs2}`);
5016
- const res = resolve44 ? resolve44(accountId) : await defaultResolve(accountId);
5016
+ const res = resolve46 ? resolve46(accountId) : await defaultResolve(accountId);
5017
5017
  if (!res.ok) {
5018
5018
  console.log(`${TAG6} op=no-socket jid=${jid} account=${accountId.slice(0, 8)} reason=${res.reason}`);
5019
5019
  return "no-socket";
@@ -5982,8 +5982,8 @@ async function startLogin(opts) {
5982
5982
  await clearAuth(authDir);
5983
5983
  let resolveCode = null;
5984
5984
  let rejectCode = null;
5985
- const codePromise = new Promise((resolve44, reject) => {
5986
- resolveCode = resolve44;
5985
+ const codePromise = new Promise((resolve46, reject) => {
5986
+ resolveCode = resolve46;
5987
5987
  rejectCode = reject;
5988
5988
  });
5989
5989
  const codeTimer = setTimeout(
@@ -6729,10 +6729,10 @@ app3.post("/config", async (c) => {
6729
6729
  const entries2 = readdirSync7(agentsDir, { withFileTypes: true });
6730
6730
  for (const entry of entries2.sort((a, b) => a.name.localeCompare(b.name))) {
6731
6731
  if (!entry.isDirectory() || entry.name === "admin") continue;
6732
- const configPath2 = resolve7(agentsDir, entry.name, "config.json");
6733
- if (!existsSync7(configPath2)) continue;
6732
+ const configPath3 = resolve7(agentsDir, entry.name, "config.json");
6733
+ if (!existsSync7(configPath3)) continue;
6734
6734
  try {
6735
- const config = JSON.parse(readFileSync9(configPath2, "utf-8"));
6735
+ const config = JSON.parse(readFileSync9(configPath3, "utf-8"));
6736
6736
  agents.push({ slug: entry.name, displayName: config.displayName ?? entry.name });
6737
6737
  } catch {
6738
6738
  console.error(`${TAG14} config action=list-public-agents error="failed to parse config.json for agent ${entry.name}" \u2014 skipping`);
@@ -7905,10 +7905,10 @@ function discoverPortalAccounts(accountsDir, shared = null) {
7905
7905
  if (!existsSync8(accountsDir)) return [];
7906
7906
  const found = [];
7907
7907
  for (const accountId of readdirSync8(accountsDir)) {
7908
- const configPath2 = join15(accountsDir, accountId, "data-portal.json");
7909
- if (!existsSync8(configPath2)) continue;
7908
+ const configPath3 = join15(accountsDir, accountId, "data-portal.json");
7909
+ if (!existsSync8(configPath3)) continue;
7910
7910
  try {
7911
- const cfg = JSON.parse(readFileSync10(configPath2, "utf-8"));
7911
+ const cfg = JSON.parse(readFileSync10(configPath3, "utf-8"));
7912
7912
  if (typeof cfg.portalDbName === "string" && cfg.portalDbName.length > 0 && typeof cfg.bucketName === "string" && cfg.bucketName.length > 0) {
7913
7913
  found.push({
7914
7914
  accountId,
@@ -13037,7 +13037,7 @@ app13.post("/", async (c) => {
13037
13037
  const safe = typeof v === "string" ? truncate(v, 200) : typeof v === "number" || typeof v === "boolean" ? String(v) : JSON.stringify(v).slice(0, 200);
13038
13038
  return `${k}=${safe}`;
13039
13039
  }).join(" ");
13040
- const TAGGED_PREFIX_SOURCES = /* @__PURE__ */ new Set(["stream-log-click", "pwa", "graph-settle", "dashboard-load"]);
13040
+ const TAGGED_PREFIX_SOURCES = /* @__PURE__ */ new Set(["stream-log-click", "pwa", "graph-settle", "dashboard-load", "routines"]);
13041
13041
  if (TAGGED_PREFIX_SOURCES.has(source)) {
13042
13042
  console.log(
13043
13043
  `[${source}] ts=${ts} ip=${ip} version=${version || "unknown"}${extra ? " " + extra : ""}`
@@ -13136,15 +13136,15 @@ function operatorRoleFor(config, userId) {
13136
13136
  async function buildAccountOptionList(accounts, userId) {
13137
13137
  const houseAccount = accounts.find((a) => a.config.role === "house");
13138
13138
  console.log(`[admin-accounts] op=list count=${accounts.length} house=${houseAccount?.accountId ?? "none"}`);
13139
- const resolve44 = async (a) => {
13139
+ const resolve46 = async (a) => {
13140
13140
  const businessName = await fetchAccountName(a.accountId) || void 0;
13141
13141
  return { accountId: a.accountId, businessName, role: operatorRoleFor(a.config, userId), isHouse: a.config.role === "house" };
13142
13142
  };
13143
13143
  const houseOptions = await Promise.all(
13144
- accounts.filter((a) => a.config.role === "house").map(resolve44)
13144
+ accounts.filter((a) => a.config.role === "house").map(resolve46)
13145
13145
  );
13146
13146
  const nonHouseOptions = await Promise.all(
13147
- accounts.filter((a) => a.config.role !== "house").map(resolve44)
13147
+ accounts.filter((a) => a.config.role !== "house").map(resolve46)
13148
13148
  );
13149
13149
  const sortKey = (o) => (o.businessName || o.accountId).toLowerCase();
13150
13150
  nonHouseOptions.sort((x, y) => {
@@ -14269,10 +14269,10 @@ app20.get("/", requireAdminSession, (c) => {
14269
14269
  for (const entry of entries2.sort((a, b) => a.name.localeCompare(b.name))) {
14270
14270
  if (!entry.isDirectory()) continue;
14271
14271
  if (entry.name === "admin") continue;
14272
- const configPath2 = resolve20(agentsDir, entry.name, "config.json");
14273
- if (!existsSync30(configPath2)) continue;
14272
+ const configPath3 = resolve20(agentsDir, entry.name, "config.json");
14273
+ if (!existsSync30(configPath3)) continue;
14274
14274
  try {
14275
- const config = JSON.parse(readFileSync28(configPath2, "utf-8"));
14275
+ const config = JSON.parse(readFileSync28(configPath3, "utf-8"));
14276
14276
  agents.push({
14277
14277
  slug: entry.name,
14278
14278
  displayName: config.displayName ?? entry.name,
@@ -14406,11 +14406,11 @@ app20.get("/:slug", requireAdminSession, (c) => {
14406
14406
  });
14407
14407
  }
14408
14408
  const agentDir = resolve20(account.accountDir, "agents", slug);
14409
- const configPath2 = resolve20(agentDir, "config.json");
14410
- if (!existsSync30(configPath2)) return c.json({ error: "Agent not found" }, 404);
14409
+ const configPath3 = resolve20(agentDir, "config.json");
14410
+ if (!existsSync30(configPath3)) return c.json({ error: "Agent not found" }, 404);
14411
14411
  let config;
14412
14412
  try {
14413
- config = JSON.parse(readFileSync28(configPath2, "utf-8"));
14413
+ config = JSON.parse(readFileSync28(configPath3, "utf-8"));
14414
14414
  } catch {
14415
14415
  console.error(`[admin/agents] op=detail slug=${slug} error="config.json parse failed"`);
14416
14416
  return c.json({ error: "Agent config unreadable" }, 500);
@@ -16907,9 +16907,9 @@ async function readAccountNames() {
16907
16907
  }
16908
16908
  for (const name of names) {
16909
16909
  if (!UUID_RE3.test(name)) continue;
16910
- const configPath2 = resolve24(accountsDir, name, "account.json");
16910
+ const configPath3 = resolve24(accountsDir, name, "account.json");
16911
16911
  try {
16912
- const raw = await readFile9(configPath2, "utf8");
16912
+ const raw = await readFile9(configPath3, "utf8");
16913
16913
  const parsed = JSON.parse(raw);
16914
16914
  if (typeof parsed?.name === "string" && parsed.name.length > 0) {
16915
16915
  map.set(name, parsed.name);
@@ -21259,6 +21259,56 @@ var health_default2 = app41;
21259
21259
  // server/routes/admin/linkedin-ingest.ts
21260
21260
  import { randomUUID as randomUUID9 } from "crypto";
21261
21261
 
21262
+ // ../lib/account-ingest-token/src/index.ts
21263
+ import { randomBytes, timingSafeEqual } from "crypto";
21264
+ import { existsSync as existsSync37, readdirSync as readdirSync24, readFileSync as readFileSync34, writeFileSync as writeFileSync14 } from "fs";
21265
+ import { resolve as resolve30 } from "path";
21266
+ var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
21267
+ var INGEST_TOKEN_FIELD = "ingestToken";
21268
+ var TOKEN_RE = /^[0-9a-f]{64}$/;
21269
+ function configPath2(accountsDir, accountId) {
21270
+ return resolve30(accountsDir, accountId, "account.json");
21271
+ }
21272
+ function readConfig2(accountsDir, accountId) {
21273
+ const path = configPath2(accountsDir, accountId);
21274
+ if (!existsSync37(path)) return null;
21275
+ try {
21276
+ const parsed = JSON.parse(readFileSync34(path, "utf-8"));
21277
+ return parsed !== null && typeof parsed === "object" ? parsed : null;
21278
+ } catch {
21279
+ return null;
21280
+ }
21281
+ }
21282
+ function readIngestToken(accountsDir, accountId) {
21283
+ const value = readConfig2(accountsDir, accountId)?.[INGEST_TOKEN_FIELD];
21284
+ return typeof value === "string" && TOKEN_RE.test(value) ? value : null;
21285
+ }
21286
+ function listAccountIdsOnDisk(accountsDir) {
21287
+ if (!existsSync37(accountsDir)) return [];
21288
+ let entries2;
21289
+ try {
21290
+ entries2 = readdirSync24(accountsDir);
21291
+ } catch {
21292
+ return [];
21293
+ }
21294
+ return entries2.filter(
21295
+ (name) => UUID_RE4.test(name) && existsSync37(resolve30(accountsDir, name, "account.json"))
21296
+ );
21297
+ }
21298
+ function resolveAccountIdByIngestToken(accountsDir, token) {
21299
+ if (typeof token !== "string" || !TOKEN_RE.test(token)) return null;
21300
+ const probe = Buffer.from(token, "utf-8");
21301
+ for (const accountId of listAccountIdsOnDisk(accountsDir)) {
21302
+ const stored = readIngestToken(accountsDir, accountId);
21303
+ if (!stored) continue;
21304
+ const candidate = Buffer.from(stored, "utf-8");
21305
+ if (candidate.length === probe.length && timingSafeEqual(candidate, probe)) {
21306
+ return accountId;
21307
+ }
21308
+ }
21309
+ return null;
21310
+ }
21311
+
21262
21312
  // app/lib/channel-pty-bridge/manager-client.ts
21263
21313
  function managerBase2() {
21264
21314
  const port2 = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "channel-pty-bridge:manager-client" });
@@ -21483,8 +21533,29 @@ function buildInitialMessage(env) {
21483
21533
  }
21484
21534
  return header;
21485
21535
  }
21536
+ var AUTH_TAG = "[linkedin-ingest-auth]";
21537
+ var requireIngestToken = async (c, next) => {
21538
+ let token = "";
21539
+ try {
21540
+ const body = await c.req.json();
21541
+ if (body && typeof body.ingest_token === "string") token = body.ingest_token;
21542
+ } catch {
21543
+ }
21544
+ if (!token) {
21545
+ console.error(`${AUTH_TAG} outcome=reject status=400 code=token-missing path=${c.req.path}`);
21546
+ return c.json({ ok: false, error: "auth", code: "token-missing" }, 400);
21547
+ }
21548
+ const accountId = resolveAccountIdByIngestToken(ACCOUNTS_DIR, token);
21549
+ if (!accountId) {
21550
+ console.error(`${AUTH_TAG} outcome=reject status=401 code=token-unknown path=${c.req.path}`);
21551
+ return c.json({ ok: false, error: "auth", code: "token-unknown" }, 401);
21552
+ }
21553
+ c.set("ingestAccountId", accountId);
21554
+ console.log(`${AUTH_TAG} outcome=accept accountId=${accountId.slice(0, 8)} path=${c.req.path}`);
21555
+ await next();
21556
+ };
21486
21557
  var app42 = new Hono();
21487
- app42.post("/", requireAdminSession, async (c) => {
21558
+ app42.post("/", requireIngestToken, async (c) => {
21488
21559
  let body;
21489
21560
  try {
21490
21561
  body = await c.req.json();
@@ -21498,8 +21569,7 @@ app42.post("/", requireAdminSession, async (c) => {
21498
21569
  return c.json({ ok: false, error: v.error, reason: v.reason, missing: v.missing }, v.status);
21499
21570
  }
21500
21571
  const envelope = v.envelope;
21501
- const cacheKey = c.var.cacheKey ?? "";
21502
- const senderId = getAccountIdForSession(cacheKey) ?? "";
21572
+ const senderId = c.var.ingestAccountId ?? "";
21503
21573
  if (!senderId) {
21504
21574
  console.error(TAG22 + " rejected status=500 reason=admin-account-not-resolved");
21505
21575
  return c.json({ ok: false, error: "admin-account-not-resolved" }, 500);
@@ -22009,7 +22079,7 @@ app48.post("/screencast-event", requireAdminSession, async (c) => {
22009
22079
  var browser_default = app48;
22010
22080
 
22011
22081
  // server/routes/admin/calendar.ts
22012
- import { existsSync as existsSync37 } from "fs";
22082
+ import { existsSync as existsSync38 } from "fs";
22013
22083
  import { join as join44 } from "path";
22014
22084
 
22015
22085
  // server/lib/calendar-ics.ts
@@ -22109,7 +22179,7 @@ function countVEvents(ics) {
22109
22179
  }
22110
22180
 
22111
22181
  // server/lib/calendar-availability.ts
22112
- import { readFileSync as readFileSync34 } from "fs";
22182
+ import { readFileSync as readFileSync35 } from "fs";
22113
22183
  import { join as join43 } from "path";
22114
22184
  var AVAILABILITY_FILENAME = "calendar-availability.json";
22115
22185
  var REQUIRED_KEYS = [
@@ -22122,7 +22192,7 @@ function readAvailabilityConfig(accountDir) {
22122
22192
  const path = join43(accountDir, AVAILABILITY_FILENAME);
22123
22193
  let raw;
22124
22194
  try {
22125
- raw = readFileSync34(path, "utf-8");
22195
+ raw = readFileSync35(path, "utf-8");
22126
22196
  } catch {
22127
22197
  throw new Error(`availability not configured: ${path} not found`);
22128
22198
  }
@@ -22482,7 +22552,7 @@ app49.get("/booking-link", requireAdminSession, (c) => {
22482
22552
  }
22483
22553
  const id82 = account.accountId.slice(0, 8);
22484
22554
  try {
22485
- if (!existsSync37(join44(account.accountDir, AVAILABILITY_FILENAME))) {
22555
+ if (!existsSync38(join44(account.accountDir, AVAILABILITY_FILENAME))) {
22486
22556
  console.log(`[calendar] op=booking-link accountId=${id82} bookingDomain=none source=availability-config`);
22487
22557
  return c.json({ bookingDomain: null });
22488
22558
  }
@@ -22501,7 +22571,7 @@ app49.get("/booking-link", requireAdminSession, (c) => {
22501
22571
  var calendar_default = app49;
22502
22572
 
22503
22573
  // server/routes/admin/data-portal.ts
22504
- import { existsSync as existsSync38, readFileSync as readFileSync35 } from "fs";
22574
+ import { existsSync as existsSync39, readFileSync as readFileSync36 } from "fs";
22505
22575
  import { join as join45 } from "path";
22506
22576
  var app50 = new Hono();
22507
22577
  var PORTAL_FILENAME = "data-portal.json";
@@ -22514,11 +22584,11 @@ app50.get("/portal-link", requireAdminSession, (c) => {
22514
22584
  const id82 = account.accountId.slice(0, 8);
22515
22585
  try {
22516
22586
  const path = join45(account.accountDir, PORTAL_FILENAME);
22517
- if (!existsSync38(path)) {
22587
+ if (!existsSync39(path)) {
22518
22588
  console.log(`[data-portal] op=portal-link accountId=${id82} portalDomain=none source=data-portal-config`);
22519
22589
  return c.json({ portalDomain: null });
22520
22590
  }
22521
- const cfg = JSON.parse(readFileSync35(path, "utf-8"));
22591
+ const cfg = JSON.parse(readFileSync36(path, "utf-8"));
22522
22592
  const portalDomain = typeof cfg.portalDomain === "string" && cfg.portalDomain.trim() ? cfg.portalDomain.trim() : null;
22523
22593
  console.log(`[data-portal] op=portal-link accountId=${id82} portalDomain=${portalDomain ?? "none"} source=data-portal-config`);
22524
22594
  return c.json({ portalDomain });
@@ -22535,8 +22605,8 @@ import cronParser from "cron-parser";
22535
22605
  import { int as int2 } from "neo4j-driver";
22536
22606
 
22537
22607
  // ../lib/agent-dispatch-rule/src/index.ts
22538
- import { readFileSync as readFileSync36 } from "fs";
22539
- import { resolve as resolve30 } from "path";
22608
+ import { readFileSync as readFileSync37 } from "fs";
22609
+ import { resolve as resolve31 } from "path";
22540
22610
  function normalizeE1642(value) {
22541
22611
  let candidate = value.trim().replace(/[\s\-().]/g, "");
22542
22612
  candidate = candidate.replace(/^whatsapp:/i, "");
@@ -22553,7 +22623,7 @@ function phonesMatch2(a, b) {
22553
22623
  function readChannelAdmins(accountDir, channel) {
22554
22624
  let config = {};
22555
22625
  try {
22556
- config = JSON.parse(readFileSync36(resolve30(accountDir, "account.json"), "utf-8"));
22626
+ config = JSON.parse(readFileSync37(resolve31(accountDir, "account.json"), "utf-8"));
22557
22627
  } catch {
22558
22628
  config = {};
22559
22629
  }
@@ -22585,9 +22655,16 @@ function registeredAccountForDestination(houseDir, houseAccountId, destination)
22585
22655
  if (adminPhones.some((p) => phonesMatch2(p, destination))) return houseAccountId;
22586
22656
  return null;
22587
22657
  }
22658
+ function boundSubAccountFor(accountDir, destination) {
22659
+ const { accountManagers } = readChannelAdmins(accountDir, "whatsapp");
22660
+ for (const [managerPhone, subAccountId] of Object.entries(accountManagers)) {
22661
+ if (subAccountId && phonesMatch2(managerPhone, destination)) return subAccountId;
22662
+ }
22663
+ return null;
22664
+ }
22588
22665
  function validateAgentDestination(accountsDir, houseAccountId, creatingAccountId, channel, destination) {
22589
22666
  if (channel === "whatsapp") {
22590
- const houseDir = resolve30(accountsDir, houseAccountId);
22667
+ const houseDir = resolve31(accountsDir, houseAccountId);
22591
22668
  const registered = registeredAccountForDestination(houseDir, houseAccountId, destination);
22592
22669
  if (registered === null) return { valid: false, reason: "not-registered" };
22593
22670
  if (creatingAccountId === houseAccountId) return { valid: true };
@@ -22599,7 +22676,7 @@ function validateAgentDestination(accountsDir, houseAccountId, creatingAccountId
22599
22676
  scheduleAccount: creatingAccountId
22600
22677
  };
22601
22678
  }
22602
- const { adminUsers } = readChannelAdmins(resolve30(accountsDir, creatingAccountId), "telegram");
22679
+ const { adminUsers } = readChannelAdmins(resolve31(accountsDir, creatingAccountId), "telegram");
22603
22680
  const asNumber = Number(destination);
22604
22681
  const ok = Number.isInteger(asNumber) && adminUsers.includes(asNumber);
22605
22682
  return ok ? { valid: true } : { valid: false, reason: "not-registered" };
@@ -22609,7 +22686,7 @@ function listDispatchDestinations(input) {
22609
22686
  const managers = [];
22610
22687
  const admins = [];
22611
22688
  if (houseAccountId !== null) {
22612
- const houseDir = resolve30(accountsDir, houseAccountId);
22689
+ const houseDir = resolve31(accountsDir, houseAccountId);
22613
22690
  const { adminPhones, accountManagers } = readChannelAdmins(houseDir, "whatsapp");
22614
22691
  const seen = /* @__PURE__ */ new Set();
22615
22692
  for (const [phone, subAccountId] of Object.entries(accountManagers)) {
@@ -22627,7 +22704,7 @@ function listDispatchDestinations(input) {
22627
22704
  admins.push({ channel: "whatsapp", destination: phone, label: "House admin" });
22628
22705
  }
22629
22706
  }
22630
- const { adminUsers } = readChannelAdmins(resolve30(accountsDir, accountId), "telegram");
22707
+ const { adminUsers } = readChannelAdmins(resolve31(accountsDir, accountId), "telegram");
22631
22708
  const telegram = [...adminUsers].sort((a, b) => a - b).map((id) => ({ channel: "telegram", destination: String(id), label: "Telegram admin" }));
22632
22709
  const byDestination = (a, b) => a.destination.localeCompare(b.destination);
22633
22710
  return [...managers.sort(byDestination), ...admins.sort(byDestination), ...telegram];
@@ -22643,7 +22720,8 @@ var ROUTINE_COLS = `e.eventId AS eventId, e.name AS name, e.eventStatus AS event
22643
22720
  e.timezone AS timezone, e.startDate AS startDate,
22644
22721
  e.agentChannel AS agentChannel, e.agentDestination AS agentDestination, e.agentPrompt AS agentPrompt,
22645
22722
  e.actionPlugin AS actionPlugin, e.actionTool AS actionTool, e.actionArgs AS actionArgs,
22646
- e.notes AS notes, e.lastDispatchResult AS lastDispatchResult, e.lastDispatchAt AS lastDispatchAt,
22723
+ e.notes AS notes, e.routineDescription AS routineDescription,
22724
+ e.lastDispatchResult AS lastDispatchResult, e.lastDispatchAt AS lastDispatchAt,
22647
22725
  e.suspendedInBulk AS suspendedInBulk`;
22648
22726
  function mapRoutine(r) {
22649
22727
  const g = (k) => r.get(k) ?? null;
@@ -22663,11 +22741,16 @@ function mapRoutine(r) {
22663
22741
  actionTool: g("actionTool"),
22664
22742
  actionArgs: g("actionArgs"),
22665
22743
  notes: g("notes"),
22744
+ // Task 2214 — read-only on the wire. Deliberately absent from the PATCH
22745
+ // field set below: the roster is its only writer, so a PATCH that accepted
22746
+ // it would be discarded by the next seed, and silently accepting an edit
22747
+ // that the next upgrade throws away is worse than refusing it.
22748
+ routineDescription: g("routineDescription"),
22666
22749
  lastDispatchResult: g("lastDispatchResult"),
22667
22750
  lastDispatchAt: g("lastDispatchAt"),
22668
22751
  // Task 2106 — on the wire so the page can gate Resume all on the set the
22669
22752
  // server will actually act on. Without it the control reads `suspended`,
22670
- // which includes the ten seeded roster rows on every fresh install, and
22753
+ // which includes the thirteen seeded roster rows on every fresh install, and
22671
22754
  // pressing it reports restoring nothing.
22672
22755
  suspendedInBulk: r.get("suspendedInBulk") === true
22673
22756
  };
@@ -23294,8 +23377,8 @@ app51.delete("/:eventId", requireAdminSession, async (c) => {
23294
23377
  var routines_default = app51;
23295
23378
 
23296
23379
  // server/routes/admin/skills.ts
23297
- import { existsSync as existsSync39, readdirSync as readdirSync24, readFileSync as readFileSync37, rmSync as rmSync5 } from "fs";
23298
- import { resolve as resolve31 } from "path";
23380
+ import { existsSync as existsSync40, readdirSync as readdirSync25, readFileSync as readFileSync38, rmSync as rmSync5 } from "fs";
23381
+ import { resolve as resolve32 } from "path";
23299
23382
  var app52 = new Hono();
23300
23383
  var NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
23301
23384
  function splitSkillMd(text) {
@@ -23318,9 +23401,9 @@ function stripQuotes(s) {
23318
23401
  return s;
23319
23402
  }
23320
23403
  function subdirs2(dir) {
23321
- if (!existsSync39(dir)) return [];
23404
+ if (!existsSync40(dir)) return [];
23322
23405
  try {
23323
- return readdirSync24(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
23406
+ return readdirSync25(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
23324
23407
  } catch {
23325
23408
  return [];
23326
23409
  }
@@ -23333,19 +23416,19 @@ app52.get("/", requireAdminSession, async (c) => {
23333
23416
  }
23334
23417
  ensureAccountWatchers(acct.accountId, acct.accountDir);
23335
23418
  const { value, state } = await getOrCompute("skills", acct.accountId, async () => {
23336
- const pluginsDir = resolve31(acct.accountDir, "plugins");
23419
+ const pluginsDir = resolve32(acct.accountDir, "plugins");
23337
23420
  const skills = [];
23338
23421
  let pluginCount = 0;
23339
23422
  for (const plugin of subdirs2(pluginsDir)) {
23340
23423
  pluginCount++;
23341
- const skillsDir = resolve31(pluginsDir, plugin, "skills");
23424
+ const skillsDir = resolve32(pluginsDir, plugin, "skills");
23342
23425
  for (const skill of subdirs2(skillsDir)) {
23343
- const skillMd = resolve31(skillsDir, skill, "SKILL.md");
23344
- if (!existsSync39(skillMd)) continue;
23426
+ const skillMd = resolve32(skillsDir, skill, "SKILL.md");
23427
+ if (!existsSync40(skillMd)) continue;
23345
23428
  try {
23346
- const { frontmatter } = splitSkillMd(readFileSync37(skillMd, "utf-8"));
23347
- const refsDir = resolve31(skillsDir, skill, "references");
23348
- const refCount = existsSync39(refsDir) ? readdirSync24(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).length : 0;
23429
+ const { frontmatter } = splitSkillMd(readFileSync38(skillMd, "utf-8"));
23430
+ const refsDir = resolve32(skillsDir, skill, "references");
23431
+ const refCount = existsSync40(refsDir) ? readdirSync25(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).length : 0;
23349
23432
  skills.push({ plugin, skill, description: frontmatter.description, refCount });
23350
23433
  } catch (err) {
23351
23434
  console.error(`[admin:skills] op=list-skip plugin=${plugin} skill=${skill} reason="${err instanceof Error ? err.message : String(err)}"`);
@@ -23367,15 +23450,15 @@ app52.get("/:plugin/:skill", requireAdminSession, async (c) => {
23367
23450
  console.error(`[admin:skills] op=get outcome=rejected reason=invalid-name plugin="${plugin}" skill="${skill}"`);
23368
23451
  return c.json({ error: "Invalid plugin or skill name" }, 400);
23369
23452
  }
23370
- const skillDir = resolve31(acct.accountDir, "plugins", plugin, "skills", skill);
23371
- const skillMd = resolve31(skillDir, "SKILL.md");
23372
- const found = existsSync39(skillMd);
23453
+ const skillDir = resolve32(acct.accountDir, "plugins", plugin, "skills", skill);
23454
+ const skillMd = resolve32(skillDir, "SKILL.md");
23455
+ const found = existsSync40(skillMd);
23373
23456
  console.log(`[admin:skills] op=get plugin=${plugin} skill=${skill} found=${found}`);
23374
23457
  if (!found) return c.json({ error: "Skill not found" }, 404);
23375
23458
  try {
23376
- const { frontmatter, body } = splitSkillMd(readFileSync37(skillMd, "utf-8"));
23377
- const refsDir = resolve31(skillDir, "references");
23378
- const references = existsSync39(refsDir) ? readdirSync24(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).map((e) => e.name).sort() : [];
23459
+ const { frontmatter, body } = splitSkillMd(readFileSync38(skillMd, "utf-8"));
23460
+ const refsDir = resolve32(skillDir, "references");
23461
+ const references = existsSync40(refsDir) ? readdirSync25(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).map((e) => e.name).sort() : [];
23379
23462
  return c.json({ skill: { plugin, skill, frontmatter, body, references } });
23380
23463
  } catch (err) {
23381
23464
  const message = err instanceof Error ? err.message : String(err);
@@ -23392,10 +23475,10 @@ app52.delete("/:plugin/:skill", requireAdminSession, async (c) => {
23392
23475
  console.error(`[admin:skills] op=delete outcome=rejected reason=invalid-name plugin="${plugin}" skill="${skill}"`);
23393
23476
  return c.json({ error: "Invalid plugin or skill name" }, 400);
23394
23477
  }
23395
- const pluginDir = resolve31(acct.accountDir, "plugins", plugin);
23396
- const skillsDir = resolve31(pluginDir, "skills");
23397
- const skillDir = resolve31(skillsDir, skill);
23398
- if (!existsSync39(resolve31(skillDir, "SKILL.md"))) {
23478
+ const pluginDir = resolve32(acct.accountDir, "plugins", plugin);
23479
+ const skillsDir = resolve32(pluginDir, "skills");
23480
+ const skillDir = resolve32(skillsDir, skill);
23481
+ if (!existsSync40(resolve32(skillDir, "SKILL.md"))) {
23399
23482
  console.error(`[admin:skills] op=delete outcome=rejected reason=not-found plugin=${plugin} skill=${skill}`);
23400
23483
  return c.json({ error: "Skill not found" }, 404);
23401
23484
  }
@@ -23403,7 +23486,7 @@ app52.delete("/:plugin/:skill", requireAdminSession, async (c) => {
23403
23486
  rmSync5(skillDir, { recursive: true, force: true });
23404
23487
  const pluginDirRemoved = subdirs2(skillsDir).length === 0;
23405
23488
  if (pluginDirRemoved) rmSync5(pluginDir, { recursive: true, force: true });
23406
- const skillDirGone = !existsSync39(skillDir);
23489
+ const skillDirGone = !existsSync40(skillDir);
23407
23490
  if (!skillDirGone) {
23408
23491
  console.error(`[admin:skills] op=delete plugin=${plugin} skill=${skill} outcome=rejected reason=rm-incomplete skillDirGone=false`);
23409
23492
  return c.json({ error: "Delete did not remove the skill directory" }, 503);
@@ -23875,20 +23958,20 @@ app57.post("/", requireAdminSession, async (c) => {
23875
23958
  var task_time_adjust_default = app57;
23876
23959
 
23877
23960
  // app/lib/admin-roster.ts
23878
- import { existsSync as existsSync40, readdirSync as readdirSync25, readFileSync as readFileSync38 } from "fs";
23879
- import { resolve as resolve32 } from "path";
23961
+ import { existsSync as existsSync41, readdirSync as readdirSync26, readFileSync as readFileSync39 } from "fs";
23962
+ import { resolve as resolve33 } from "path";
23880
23963
  function readHouseAdminUserIds(accountsDir = ACCOUNTS_DIR) {
23881
23964
  let entries2;
23882
23965
  try {
23883
- entries2 = readdirSync25(accountsDir);
23966
+ entries2 = readdirSync26(accountsDir);
23884
23967
  } catch {
23885
23968
  return [];
23886
23969
  }
23887
23970
  for (const entry of entries2) {
23888
- const cfgPath = resolve32(accountsDir, entry, "account.json");
23889
- if (!existsSync40(cfgPath)) continue;
23971
+ const cfgPath = resolve33(accountsDir, entry, "account.json");
23972
+ if (!existsSync41(cfgPath)) continue;
23890
23973
  try {
23891
- const cfg = JSON.parse(readFileSync38(cfgPath, "utf-8"));
23974
+ const cfg = JSON.parse(readFileSync39(cfgPath, "utf-8"));
23892
23975
  if (cfg.role !== "house") continue;
23893
23976
  if (!Array.isArray(cfg.admins)) return [];
23894
23977
  return cfg.admins.map(
@@ -24218,7 +24301,21 @@ app61.get("/", requireAdminSession, async (c) => {
24218
24301
  var admin_users_list_default = app61;
24219
24302
 
24220
24303
  // server/routes/admin/dispatch-destinations.ts
24304
+ import { resolve as resolve34 } from "path";
24221
24305
  var TAG37 = "[admin:routines]";
24306
+ function scopeFor(d, houseDir, houseAccountId) {
24307
+ if (d.channel !== "whatsapp") return null;
24308
+ if (d.label === "Account manager") return boundSubAccountFor(houseDir, d.destination);
24309
+ return houseAccountId;
24310
+ }
24311
+ function telephoneVariants(destination) {
24312
+ const digits = normalizeE1642(destination);
24313
+ if (digits.length === 0) return [destination];
24314
+ return [.../* @__PURE__ */ new Set([destination, digits, `+${digits}`])];
24315
+ }
24316
+ function scrubDigitRuns(message) {
24317
+ return message.replace(/\d{7,}/g, "<redacted>");
24318
+ }
24222
24319
  var app62 = new Hono();
24223
24320
  app62.get("/", requireAdminSession, async (c) => {
24224
24321
  const accountId = getAccountIdForSession(c.var.cacheKey);
@@ -24234,15 +24331,62 @@ app62.get("/", requireAdminSession, async (c) => {
24234
24331
  console.error(`${TAG37} op=destinations account=${accountId.slice(0, 8)} outcome=house-unresolved reason="${message}"`);
24235
24332
  }
24236
24333
  const destinations = listDispatchDestinations({ accountsDir: ACCOUNTS_DIR, houseAccountId, accountId });
24334
+ const houseDir = houseAccountId === null ? null : resolve34(ACCOUNTS_DIR, houseAccountId);
24335
+ const byScope = /* @__PURE__ */ new Map();
24336
+ for (const d of destinations) {
24337
+ const scope = houseDir === null || houseAccountId === null ? null : scopeFor(d, houseDir, houseAccountId);
24338
+ if (scope === null) continue;
24339
+ const list = byScope.get(scope);
24340
+ if (list) list.push(d);
24341
+ else byScope.set(scope, [d]);
24342
+ }
24343
+ let namesUnresolved = null;
24344
+ let named = 0;
24345
+ if (byScope.size > 0) {
24346
+ let session = null;
24347
+ try {
24348
+ session = getSession();
24349
+ for (const [scopeAccountId, rows] of byScope) {
24350
+ const telephones = [...new Set(rows.flatMap((d) => telephoneVariants(d.destination)))];
24351
+ const result = await session.run(
24352
+ `MATCH (p:Person {accountId: $accountId}) WHERE p.telephone IN $telephones
24353
+ RETURN p.telephone AS telephone, p.givenName AS givenName, p.familyName AS familyName`,
24354
+ { accountId: scopeAccountId, telephones }
24355
+ );
24356
+ const found = /* @__PURE__ */ new Map();
24357
+ for (const rec of result.records) {
24358
+ const tel = rec.get("telephone");
24359
+ if (!tel) continue;
24360
+ const name = [rec.get("givenName"), rec.get("familyName")].filter(Boolean).join(" ");
24361
+ if (name.length > 0) found.set(normalizeE1642(tel), name);
24362
+ }
24363
+ for (const d of rows) {
24364
+ const hit = found.get(normalizeE1642(d.destination));
24365
+ if (hit) {
24366
+ d.name = hit;
24367
+ named += 1;
24368
+ }
24369
+ }
24370
+ }
24371
+ } catch (err) {
24372
+ namesUnresolved = scrubDigitRuns(err instanceof Error ? err.message : String(err));
24373
+ for (const d of destinations) delete d.name;
24374
+ named = 0;
24375
+ } finally {
24376
+ if (session) await session.close();
24377
+ }
24378
+ }
24379
+ const scopes = [...byScope.keys()];
24380
+ const nameScope = scopes.length === 0 ? "none" : scopes.every((s) => s === houseAccountId) ? "house" : scopes.some((s) => s === houseAccountId) ? "mixed" : "account";
24237
24381
  console.log(
24238
- `${TAG37} op=destinations account=${accountId.slice(0, 8)} count=${destinations.length}` + (houseAccountId === null ? " outcome=house-unresolved" : "")
24382
+ `${TAG37} op=destinations account=${accountId.slice(0, 8)} count=${destinations.length} named=${named} unnamed=${destinations.length - named} nameScope=${nameScope}` + (houseAccountId === null ? " outcome=house-unresolved" : "") + (namesUnresolved === null ? "" : ` outcome=names-unresolved reason="${namesUnresolved}"`)
24239
24383
  );
24240
24384
  return c.json({ destinations });
24241
24385
  });
24242
24386
  var dispatch_destinations_default = app62;
24243
24387
 
24244
24388
  // server/routes/admin/activity.ts
24245
- import { readdirSync as readdirSync26 } from "fs";
24389
+ import { readdirSync as readdirSync27 } from "fs";
24246
24390
  var app63 = new Hono();
24247
24391
  var TAG38 = "[activity]";
24248
24392
  function resolveHouseAccountId(accounts) {
@@ -24258,7 +24402,7 @@ function requestToken() {
24258
24402
  var short = (id) => id ? id.slice(0, 8) : "unset";
24259
24403
  function countAccountDirsOnDisk() {
24260
24404
  try {
24261
- return readdirSync26(ACCOUNTS_DIR, { withFileTypes: true }).filter(
24405
+ return readdirSync27(ACCOUNTS_DIR, { withFileTypes: true }).filter(
24262
24406
  (e) => e.isDirectory() && !e.name.startsWith(".")
24263
24407
  ).length;
24264
24408
  } catch {
@@ -24522,9 +24666,9 @@ var verify_token_default = app65;
24522
24666
 
24523
24667
  // app/lib/access-email.ts
24524
24668
  import { spawn as spawn2 } from "child_process";
24525
- import { resolve as resolve33 } from "path";
24526
- var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve33(process.cwd(), "..");
24527
- var SEND_SCRIPT = resolve33(
24669
+ import { resolve as resolve35 } from "path";
24670
+ var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve35(process.cwd(), "..");
24671
+ var SEND_SCRIPT = resolve35(
24528
24672
  PLATFORM_ROOT5,
24529
24673
  "plugins",
24530
24674
  "email",
@@ -24666,8 +24810,8 @@ app67.route("/request-magic-link", request_magic_link_default);
24666
24810
  var access_default = app67;
24667
24811
 
24668
24812
  // server/routes/sites.ts
24669
- import { existsSync as existsSync41, readFileSync as readFileSync39, realpathSync as realpathSync8, statSync as statSync22 } from "fs";
24670
- import { resolve as resolve34 } from "path";
24813
+ import { existsSync as existsSync42, readFileSync as readFileSync40, realpathSync as realpathSync8, statSync as statSync22 } from "fs";
24814
+ import { resolve as resolve36 } from "path";
24671
24815
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
24672
24816
  var MIME = {
24673
24817
  ".html": "text/html; charset=utf-8",
@@ -24724,15 +24868,15 @@ app68.get("/:rel{.*}", (c) => {
24724
24868
  }
24725
24869
  segments.push(seg);
24726
24870
  }
24727
- const rootDir = resolve34(account.accountDir, "sites");
24728
- let filePath = segments.length === 0 ? rootDir : resolve34(rootDir, ...segments);
24871
+ const rootDir = resolve36(account.accountDir, "sites");
24872
+ let filePath = segments.length === 0 ? rootDir : resolve36(rootDir, ...segments);
24729
24873
  if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
24730
24874
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
24731
24875
  return c.text("Forbidden", 403);
24732
24876
  }
24733
24877
  let stat11;
24734
24878
  try {
24735
- stat11 = existsSync41(filePath) ? statSync22(filePath) : null;
24879
+ stat11 = existsSync42(filePath) ? statSync22(filePath) : null;
24736
24880
  } catch {
24737
24881
  stat11 = null;
24738
24882
  }
@@ -24745,13 +24889,13 @@ app68.get("/:rel{.*}", (c) => {
24745
24889
  return c.redirect(target, 301);
24746
24890
  }
24747
24891
  if (stat11?.isDirectory()) {
24748
- filePath = resolve34(filePath, "index.html");
24892
+ filePath = resolve36(filePath, "index.html");
24749
24893
  }
24750
24894
  if (!filePath.startsWith(rootDir + "/")) {
24751
24895
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
24752
24896
  return c.text("Forbidden", 403);
24753
24897
  }
24754
- if (!existsSync41(filePath)) {
24898
+ if (!existsSync42(filePath)) {
24755
24899
  console.error(`[sites] not-found path=${reqPath} status=404`);
24756
24900
  return c.text("Not found", 404);
24757
24901
  }
@@ -24770,7 +24914,7 @@ app68.get("/:rel{.*}", (c) => {
24770
24914
  }
24771
24915
  let body;
24772
24916
  try {
24773
- body = readFileSync39(realPath);
24917
+ body = readFileSync40(realPath);
24774
24918
  } catch (err) {
24775
24919
  const code = err?.code;
24776
24920
  if (code === "EISDIR") {
@@ -24805,8 +24949,8 @@ app68.get("/:rel{.*}", (c) => {
24805
24949
  var sites_default = app68;
24806
24950
 
24807
24951
  // app/lib/visitor-token.ts
24808
- import { createHmac, randomBytes, timingSafeEqual } from "crypto";
24809
- import { mkdirSync as mkdirSync8, readFileSync as readFileSync40, writeFileSync as writeFileSync14 } from "fs";
24952
+ import { createHmac, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "crypto";
24953
+ import { mkdirSync as mkdirSync8, readFileSync as readFileSync41, writeFileSync as writeFileSync15 } from "fs";
24810
24954
  import { dirname as dirname15 } from "path";
24811
24955
  var TOKEN_PREFIX = "v1.";
24812
24956
  var SECRET_BYTES = 32;
@@ -24815,21 +24959,21 @@ var cachedSecret = null;
24815
24959
  function getSecret() {
24816
24960
  if (cachedSecret) return cachedSecret;
24817
24961
  try {
24818
- const hex2 = readFileSync40(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
24962
+ const hex2 = readFileSync41(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
24819
24963
  if (hex2.length === SECRET_BYTES * 2) {
24820
24964
  cachedSecret = Buffer.from(hex2, "hex");
24821
24965
  return cachedSecret;
24822
24966
  }
24823
24967
  } catch {
24824
24968
  }
24825
- const fresh = randomBytes(SECRET_BYTES).toString("hex");
24969
+ const fresh = randomBytes2(SECRET_BYTES).toString("hex");
24826
24970
  try {
24827
24971
  mkdirSync8(dirname15(VISITOR_TOKEN_SECRET_FILE), { recursive: true, mode: 448 });
24828
- writeFileSync14(VISITOR_TOKEN_SECRET_FILE, fresh, { mode: 384, flag: "wx" });
24972
+ writeFileSync15(VISITOR_TOKEN_SECRET_FILE, fresh, { mode: 384, flag: "wx" });
24829
24973
  console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
24830
24974
  } catch {
24831
24975
  }
24832
- const hex = readFileSync40(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
24976
+ const hex = readFileSync41(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
24833
24977
  cachedSecret = Buffer.from(hex, "hex");
24834
24978
  return cachedSecret;
24835
24979
  }
@@ -24862,7 +25006,7 @@ function verifyVisitorToken(token, now = Date.now()) {
24862
25006
  const expected = signPayload(payloadJson, getSecret());
24863
25007
  const expectedBuf = Buffer.from(expected, "utf-8");
24864
25008
  const provBuf = Buffer.from(sigB64, "utf-8");
24865
- if (expectedBuf.length !== provBuf.length || !timingSafeEqual(expectedBuf, provBuf)) {
25009
+ if (expectedBuf.length !== provBuf.length || !timingSafeEqual2(expectedBuf, provBuf)) {
24866
25010
  return { ok: false, reason: "bad-sig" };
24867
25011
  }
24868
25012
  let payload;
@@ -24882,7 +25026,7 @@ var VISITOR_COOKIE_NAME = "mxy_v";
24882
25026
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
24883
25027
 
24884
25028
  // app/lib/brand-config.ts
24885
- import { existsSync as existsSync42, readFileSync as readFileSync41 } from "fs";
25029
+ import { existsSync as existsSync43, readFileSync as readFileSync42 } from "fs";
24886
25030
  import { join as join47 } from "path";
24887
25031
  var cached2 = null;
24888
25032
  var cachedAttempted = false;
@@ -24892,9 +25036,9 @@ function readBrandConfig() {
24892
25036
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
24893
25037
  if (!platformRoot5) return null;
24894
25038
  const brandPath = join47(platformRoot5, "config", "brand.json");
24895
- if (!existsSync42(brandPath)) return null;
25039
+ if (!existsSync43(brandPath)) return null;
24896
25040
  try {
24897
- cached2 = JSON.parse(readFileSync41(brandPath, "utf-8"));
25041
+ cached2 = JSON.parse(readFileSync42(brandPath, "utf-8"));
24898
25042
  return cached2;
24899
25043
  } catch {
24900
25044
  return null;
@@ -25391,14 +25535,14 @@ async function writeEvent(opts) {
25391
25535
  var visitor_event_default = app71;
25392
25536
 
25393
25537
  // server/routes/session.ts
25394
- import { resolve as resolve35 } from "path";
25395
- import { existsSync as existsSync43, writeFileSync as writeFileSync15, mkdirSync as mkdirSync9 } from "fs";
25396
- var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
25538
+ import { resolve as resolve37 } from "path";
25539
+ import { existsSync as existsSync44, writeFileSync as writeFileSync16, mkdirSync as mkdirSync9 } from "fs";
25540
+ var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
25397
25541
  function writeBrandingCache(accountId, agentSlug, branding) {
25398
25542
  try {
25399
- const cacheDir = resolve35(MAXY_DIR, "branding-cache", accountId);
25543
+ const cacheDir = resolve37(MAXY_DIR, "branding-cache", accountId);
25400
25544
  mkdirSync9(cacheDir, { recursive: true });
25401
- writeFileSync15(resolve35(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
25545
+ writeFileSync16(resolve37(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
25402
25546
  } catch (err) {
25403
25547
  console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
25404
25548
  }
@@ -25408,7 +25552,7 @@ function parseVisitorCookie2(cookieHeader) {
25408
25552
  const match = cookieHeader.match(/(?:^|;\s*)maxy_visitor=([^;]*)/);
25409
25553
  if (!match) return null;
25410
25554
  const value = decodeURIComponent(match[1]).trim();
25411
- return UUID_RE4.test(value) ? value : null;
25555
+ return UUID_RE5.test(value) ? value : null;
25412
25556
  }
25413
25557
  function parseAccessSessionId2(cookieHeader) {
25414
25558
  if (!cookieHeader) return null;
@@ -25475,8 +25619,8 @@ app72.post("/", async (c) => {
25475
25619
  }
25476
25620
  let agentConfig = null;
25477
25621
  if (account) {
25478
- const agentDir = resolve35(account.accountDir, "agents", agentSlug);
25479
- if (!existsSync43(agentDir) || !existsSync43(resolve35(agentDir, "config.json"))) {
25622
+ const agentDir = resolve37(account.accountDir, "agents", agentSlug);
25623
+ if (!existsSync44(agentDir) || !existsSync44(resolve37(agentDir, "config.json"))) {
25480
25624
  return c.json({ error: "Agent not found" }, 404);
25481
25625
  }
25482
25626
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -25506,7 +25650,7 @@ app72.post("/", async (c) => {
25506
25650
  );
25507
25651
  }
25508
25652
  }
25509
- if (body.session_key && typeof body.session_key === "string" && UUID_RE4.test(body.session_key)) {
25653
+ if (body.session_key && typeof body.session_key === "string" && UUID_RE5.test(body.session_key)) {
25510
25654
  if (visitorId) {
25511
25655
  const recent = await findRecentConversation(visitorId, accountId, agentSlug).catch(() => null);
25512
25656
  if (recent) {
@@ -25736,7 +25880,7 @@ var calendar_public_default = app73;
25736
25880
  // server/routes/portal-fetch.ts
25737
25881
  import { createReadStream as createReadStream3 } from "fs";
25738
25882
  import { stat as stat8, readFile as readFile11, realpath } from "fs/promises";
25739
- import { join as join48, resolve as resolve36, sep as sep11 } from "path";
25883
+ import { join as join48, resolve as resolve38, sep as sep11 } from "path";
25740
25884
  import { Readable as Readable3 } from "stream";
25741
25885
  var app74 = new Hono();
25742
25886
  var TAG41 = "[portal-fetch]";
@@ -25789,7 +25933,7 @@ ${expiresAtMs}`)
25789
25933
  return diff === 0;
25790
25934
  }
25791
25935
  async function readAccountSecret(accountId) {
25792
- const path = resolve36(DATA_ROOT, "accounts", accountId, "secrets", "data-portal.env");
25936
+ const path = resolve38(DATA_ROOT, "accounts", accountId, "secrets", "data-portal.env");
25793
25937
  let text;
25794
25938
  try {
25795
25939
  text = await readFile11(path, "utf8");
@@ -25825,7 +25969,7 @@ async function resolveFetchTarget(accountDir, relPath, ownerId) {
25825
25969
  const exposeFolders = await readExposeFolders2(accountDir);
25826
25970
  const { exposed } = resolveExposedDirs(schemaText, exposeFolders);
25827
25971
  if (exposed.length === 0 && !ownerId) return { ok: false, reason: "not-exposed" };
25828
- const lexical = resolve36(accountDir, relPath);
25972
+ const lexical = resolve38(accountDir, relPath);
25829
25973
  let root;
25830
25974
  let absolute;
25831
25975
  try {
@@ -25874,7 +26018,7 @@ async function handle(c, headOnly) {
25874
26018
  return c.json({ ok: false, error: "denied" }, 401);
25875
26019
  }
25876
26020
  const target = await resolveFetchTarget(
25877
- resolve36(DATA_ROOT, "accounts", accountId),
26021
+ resolve38(DATA_ROOT, "accounts", accountId),
25878
26022
  relPath,
25879
26023
  owner || void 0
25880
26024
  );
@@ -25988,7 +26132,7 @@ function startTimeEntryCensus(openSession, opts = {}) {
25988
26132
  }
25989
26133
 
25990
26134
  // app/lib/ledger-census.ts
25991
- import { readdirSync as readdirSync27, readFileSync as readFileSync42, statSync as statSync23 } from "fs";
26135
+ import { readdirSync as readdirSync28, readFileSync as readFileSync43, statSync as statSync23 } from "fs";
25992
26136
  import { join as join49 } from "path";
25993
26137
 
25994
26138
  // ../lib/ledger-core/dist/reconcile.js
@@ -26037,7 +26181,7 @@ var DAY_MS = 864e5;
26037
26181
  function countWriteRejects24h(logDir, now) {
26038
26182
  let entries2;
26039
26183
  try {
26040
- entries2 = readdirSync27(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
26184
+ entries2 = readdirSync28(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
26041
26185
  } catch {
26042
26186
  return 0;
26043
26187
  }
@@ -26046,7 +26190,7 @@ function countWriteRejects24h(logDir, now) {
26046
26190
  const path = join49(logDir, name);
26047
26191
  try {
26048
26192
  if (now - statSync23(path).mtimeMs > DAY_MS) continue;
26049
- for (const line of readFileSync42(path, "utf8").split("\n")) {
26193
+ for (const line of readFileSync43(path, "utf8").split("\n")) {
26050
26194
  if (line.includes("[graph-write] reject")) total += 1;
26051
26195
  }
26052
26196
  } catch {
@@ -26315,7 +26459,7 @@ function startGraphHealthTimer() {
26315
26459
 
26316
26460
  // app/lib/file-watcher.ts
26317
26461
  import * as fsp2 from "fs/promises";
26318
- import { resolve as resolve37, sep as sep12 } from "path";
26462
+ import { resolve as resolve39, sep as sep12 } from "path";
26319
26463
  var ACCOUNT_UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
26320
26464
  var DEFAULT_COALESCE_MS = 500;
26321
26465
  var ROOTS = ["accounts"];
@@ -26334,7 +26478,7 @@ async function startFileWatcher(opts = {}) {
26334
26478
  const dropFn = opts.drop ?? dropFileIndex;
26335
26479
  for (const r of ROOTS) {
26336
26480
  try {
26337
- await fsp2.mkdir(resolve37(dataRoot, r), { recursive: true });
26481
+ await fsp2.mkdir(resolve39(dataRoot, r), { recursive: true });
26338
26482
  } catch (err) {
26339
26483
  console.error(
26340
26484
  `[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
@@ -26355,7 +26499,7 @@ async function startFileWatcher(opts = {}) {
26355
26499
  timers.set(relativePath, t);
26356
26500
  }
26357
26501
  async function runHook(relativePath, accountId) {
26358
- const absolute = resolve37(dataRoot, relativePath);
26502
+ const absolute = resolve39(dataRoot, relativePath);
26359
26503
  let exists = false;
26360
26504
  try {
26361
26505
  const st = await fsp2.stat(absolute);
@@ -26379,7 +26523,7 @@ async function startFileWatcher(opts = {}) {
26379
26523
  }
26380
26524
  }
26381
26525
  async function watchRoot(rootName) {
26382
- const absRoot = resolve37(dataRoot, rootName);
26526
+ const absRoot = resolve39(dataRoot, rootName);
26383
26527
  try {
26384
26528
  const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
26385
26529
  for await (const event of iter) {
@@ -26418,7 +26562,7 @@ async function startFileWatcher(opts = {}) {
26418
26562
 
26419
26563
  // app/lib/migrate-uploads.ts
26420
26564
  import { mkdir as mkdir4, readdir as readdir6, rename as rename4, rm as rm3 } from "fs/promises";
26421
- import { dirname as dirname16, relative as relative8, resolve as resolve38 } from "path";
26565
+ import { dirname as dirname16, relative as relative8, resolve as resolve40 } from "path";
26422
26566
  var ACCOUNT_UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
26423
26567
  async function walkFiles(dir) {
26424
26568
  const out = [];
@@ -26429,7 +26573,7 @@ async function walkFiles(dir) {
26429
26573
  return out;
26430
26574
  }
26431
26575
  for (const e of entries2) {
26432
- const abs = resolve38(dir, e.name);
26576
+ const abs = resolve40(dir, e.name);
26433
26577
  if (e.isDirectory()) {
26434
26578
  out.push(...await walkFiles(abs));
26435
26579
  } else if (e.isFile()) {
@@ -26449,7 +26593,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
26449
26593
  let moved = 0;
26450
26594
  for (const oldAbs of files) {
26451
26595
  const suffix = relative8(srcDir, oldAbs);
26452
- const newAbs = resolve38(destDir, suffix);
26596
+ const newAbs = resolve40(destDir, suffix);
26453
26597
  await mkdir4(dirname16(newAbs), { recursive: true });
26454
26598
  await rename4(oldAbs, newAbs);
26455
26599
  moved++;
@@ -26476,7 +26620,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
26476
26620
  }
26477
26621
  async function migrateUploads(opts = {}) {
26478
26622
  const dataRoot = opts.dataRoot ?? DATA_ROOT;
26479
- const oldRoot = resolve38(dataRoot, "uploads");
26623
+ const oldRoot = resolve40(dataRoot, "uploads");
26480
26624
  let topEntries;
26481
26625
  try {
26482
26626
  topEntries = await readdir6(oldRoot, { withFileTypes: true });
@@ -26497,8 +26641,8 @@ async function migrateUploads(opts = {}) {
26497
26641
  const name = entry.name;
26498
26642
  if (ACCOUNT_UUID_RE4.test(name)) {
26499
26643
  moved += await relocateTree(
26500
- resolve38(oldRoot, name),
26501
- resolve38(dataRoot, "accounts", name, "uploads"),
26644
+ resolve40(oldRoot, name),
26645
+ resolve40(dataRoot, "accounts", name, "uploads"),
26502
26646
  dataRoot,
26503
26647
  name,
26504
26648
  session
@@ -26510,8 +26654,8 @@ async function migrateUploads(opts = {}) {
26510
26654
  continue;
26511
26655
  }
26512
26656
  moved += await relocateTree(
26513
- resolve38(oldRoot, "public"),
26514
- resolve38(dataRoot, "accounts", installAccountId, "uploads", "public"),
26657
+ resolve40(oldRoot, "public"),
26658
+ resolve40(dataRoot, "accounts", installAccountId, "uploads", "public"),
26515
26659
  dataRoot,
26516
26660
  null,
26517
26661
  // public uploads carry no graph nodes
@@ -26541,7 +26685,7 @@ async function migrateUploads(opts = {}) {
26541
26685
 
26542
26686
  // app/lib/migrate-admin-webchat-sidecars.ts
26543
26687
  import { readdir as readdir7, readFile as readFile12, rename as rename5, writeFile as writeFile4, unlink as unlink4 } from "fs/promises";
26544
- import { existsSync as existsSync44 } from "fs";
26688
+ import { existsSync as existsSync45 } from "fs";
26545
26689
  import { join as join50 } from "path";
26546
26690
  var ADMIN_ROLE2 = "admin";
26547
26691
  var WEBCHAT_CHANNEL2 = "webchat";
@@ -26571,7 +26715,7 @@ async function writeRaw(path, obj) {
26571
26715
  await rename5(tmp, path);
26572
26716
  } catch (err) {
26573
26717
  try {
26574
- if (existsSync44(tmp)) await unlink4(tmp);
26718
+ if (existsSync45(tmp)) await unlink4(tmp);
26575
26719
  } catch {
26576
26720
  }
26577
26721
  throw err;
@@ -26694,7 +26838,7 @@ async function migrateAdminWebchatSidecars(opts = {}) {
26694
26838
 
26695
26839
  // app/lib/migrate-sidecar-account-ids.ts
26696
26840
  import { readdir as readdir8, readFile as readFile13, rename as rename6, writeFile as writeFile5, unlink as unlink5 } from "fs/promises";
26697
- import { existsSync as existsSync45 } from "fs";
26841
+ import { existsSync as existsSync46 } from "fs";
26698
26842
  import { join as join51 } from "path";
26699
26843
  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;
26700
26844
  function projectSlugForCwd(cwd) {
@@ -26721,7 +26865,7 @@ async function writeRaw2(path, obj) {
26721
26865
  await rename6(tmp, path);
26722
26866
  } catch (err) {
26723
26867
  try {
26724
- if (existsSync45(tmp)) await unlink5(tmp);
26868
+ if (existsSync46(tmp)) await unlink5(tmp);
26725
26869
  } catch {
26726
26870
  }
26727
26871
  throw err;
@@ -27897,16 +28041,16 @@ var WebchatGateway = class _WebchatGateway {
27897
28041
  * The public /api/chat route awaits this to return the reply on the same SSE
27898
28042
  * response, preserving the pre-756 POST→single-blob browser contract. */
27899
28043
  awaitReply(key, timeoutMs) {
27900
- return new Promise((resolve44) => {
28044
+ return new Promise((resolve46) => {
27901
28045
  const timer = setTimeout(() => {
27902
28046
  this.replyAwaiters.delete(key);
27903
- resolve44({ timeout: true });
28047
+ resolve46({ timeout: true });
27904
28048
  }, timeoutMs);
27905
28049
  if (timer.unref) timer.unref();
27906
28050
  this.replyAwaiters.set(key, (r) => {
27907
28051
  clearTimeout(timer);
27908
28052
  this.replyAwaiters.delete(key);
27909
- resolve44(r);
28053
+ resolve46(r);
27910
28054
  });
27911
28055
  });
27912
28056
  }
@@ -27917,11 +28061,11 @@ var WebchatGateway = class _WebchatGateway {
27917
28061
  * terminal dialog stays answerable). */
27918
28062
  awaitPermissionVerdict(p, timeoutMs) {
27919
28063
  const k = _WebchatGateway.promptKey(p.key, p.requestId);
27920
- return new Promise((resolve44) => {
28064
+ return new Promise((resolve46) => {
27921
28065
  this.pendingPrompts.get(k)?.resolve({ timeout: true });
27922
28066
  const timer = setTimeout(() => {
27923
28067
  this.pendingPrompts.delete(k);
27924
- resolve44({ timeout: true });
28068
+ resolve46({ timeout: true });
27925
28069
  }, timeoutMs);
27926
28070
  if (timer.unref) timer.unref();
27927
28071
  this.pendingPrompts.set(k, {
@@ -27931,7 +28075,7 @@ var WebchatGateway = class _WebchatGateway {
27931
28075
  clearTimeout(timer);
27932
28076
  this.pendingPrompts.delete(k);
27933
28077
  this.deps.onPointerChange?.(p.key);
27934
- resolve44(r);
28078
+ resolve46(r);
27935
28079
  }
27936
28080
  });
27937
28081
  console.error(`[webchat:perm] op=open key=${keyDisplay(p.key)} id=${p.requestId} tool=${p.toolName}`);
@@ -28507,7 +28651,7 @@ async function fanOut(subscribers, text, onError, tag) {
28507
28651
 
28508
28652
  // app/lib/webchat/file-delivery.ts
28509
28653
  import { realpathSync as realpathSync9 } from "fs";
28510
- import { resolve as resolve39 } from "path";
28654
+ import { resolve as resolve41 } from "path";
28511
28655
 
28512
28656
  // app/lib/channel-pty-bridge/file-delivery.ts
28513
28657
  var SEND_USER_FILE = "SendUserFile";
@@ -28608,7 +28752,7 @@ function makeWebchatSendFile(entry) {
28608
28752
  console.error(`${TAG45} file-delivery reject reason=no-account sender=${entry.senderId}`);
28609
28753
  return { ok: false, error: "no-account" };
28610
28754
  }
28611
- const accountDir = resolve39(platformRoot2(), "..", "data/accounts", entry.accountId);
28755
+ const accountDir = resolve41(platformRoot2(), "..", "data/accounts", entry.accountId);
28612
28756
  try {
28613
28757
  const resolved = realpathSync9(filePath);
28614
28758
  const accountResolved = realpathSync9(accountDir);
@@ -29172,7 +29316,7 @@ function buildTelegramSpawnRequest(input) {
29172
29316
  // app/lib/telegram/outbound/send-document.ts
29173
29317
  import { realpathSync as realpathSync10 } from "fs";
29174
29318
  import { readFile as readFile14, stat as stat10 } from "fs/promises";
29175
- import { resolve as resolve40, basename as basename15 } from "path";
29319
+ import { resolve as resolve42, basename as basename15 } from "path";
29176
29320
  var TAG47 = "[telegram:outbound]";
29177
29321
  var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
29178
29322
  async function sendTelegramDocument(input) {
@@ -29183,7 +29327,7 @@ async function sendTelegramDocument(input) {
29183
29327
  if (!maxyAccountId || !platformRoot5) {
29184
29328
  return { ok: false, status: 400, error: "Cannot validate file path: missing account or platform context" };
29185
29329
  }
29186
- const accountDir = resolve40(platformRoot5, "..", "data/accounts", maxyAccountId);
29330
+ const accountDir = resolve42(platformRoot5, "..", "data/accounts", maxyAccountId);
29187
29331
  let accountResolved;
29188
29332
  try {
29189
29333
  accountResolved = realpathSync10(accountDir);
@@ -29591,14 +29735,14 @@ function resolveScheduledEffectiveAccountForInstall(accountDir, destination) {
29591
29735
  }
29592
29736
 
29593
29737
  // server/lib/booking-site-accounts.ts
29594
- import { existsSync as existsSync46, readFileSync as readFileSync43 } from "fs";
29595
- import { resolve as resolve41 } from "path";
29738
+ import { existsSync as existsSync47, readFileSync as readFileSync44 } from "fs";
29739
+ import { resolve as resolve43 } from "path";
29596
29740
  function listBookingSiteAccounts(accounts) {
29597
29741
  return accounts.filter((a) => {
29598
- const availPath = resolve41(a.accountDir, "calendar-availability.json");
29599
- if (!existsSync46(availPath)) return false;
29742
+ const availPath = resolve43(a.accountDir, "calendar-availability.json");
29743
+ if (!existsSync47(availPath)) return false;
29600
29744
  try {
29601
- const cfg = JSON.parse(readFileSync43(availPath, "utf-8"));
29745
+ const cfg = JSON.parse(readFileSync44(availPath, "utf-8"));
29602
29746
  return typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
29603
29747
  } catch {
29604
29748
  return false;
@@ -29636,8 +29780,8 @@ function broadcastAdminShutdown(reason) {
29636
29780
 
29637
29781
  // ../lib/entitlement/src/index.ts
29638
29782
  import { createPublicKey, createHash as createHash6, verify as cryptoVerify } from "crypto";
29639
- import { existsSync as existsSync47, readFileSync as readFileSync44, statSync as statSync24 } from "fs";
29640
- import { resolve as resolve42 } from "path";
29783
+ import { existsSync as existsSync48, readFileSync as readFileSync45, statSync as statSync24 } from "fs";
29784
+ import { resolve as resolve44 } from "path";
29641
29785
 
29642
29786
  // ../lib/entitlement/src/canonicalize.ts
29643
29787
  function canonicalize(value) {
@@ -29672,7 +29816,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
29672
29816
  var GRACE_DAYS = 7;
29673
29817
  var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
29674
29818
  function pubkeyPath(brand) {
29675
- return resolve42(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
29819
+ return resolve44(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
29676
29820
  }
29677
29821
  var memo = null;
29678
29822
  function memoKey(mtimeMs, account) {
@@ -29684,8 +29828,8 @@ function resolveEntitlement(brand, account) {
29684
29828
  if (brand.commercialMode !== true) {
29685
29829
  return logResolved(implicitTrust(account), null);
29686
29830
  }
29687
- const entitlementPath = resolve42(brand.configDir, "entitlement.json");
29688
- if (!existsSync47(entitlementPath)) {
29831
+ const entitlementPath = resolve44(brand.configDir, "entitlement.json");
29832
+ if (!existsSync48(entitlementPath)) {
29689
29833
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
29690
29834
  }
29691
29835
  const stat11 = statSync24(entitlementPath);
@@ -29700,7 +29844,7 @@ function resolveEntitlement(brand, account) {
29700
29844
  function verifyAndResolve(brand, entitlementPath, account) {
29701
29845
  let pubkeyPem;
29702
29846
  try {
29703
- pubkeyPem = readFileSync44(pubkeyPath(brand), "utf-8");
29847
+ pubkeyPem = readFileSync45(pubkeyPath(brand), "utf-8");
29704
29848
  } catch (err) {
29705
29849
  return logResolved(anonymousFallback("pubkey-missing"), {
29706
29850
  reason: "pubkey-missing"
@@ -29714,7 +29858,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
29714
29858
  }
29715
29859
  let envelope;
29716
29860
  try {
29717
- envelope = JSON.parse(readFileSync44(entitlementPath, "utf-8"));
29861
+ envelope = JSON.parse(readFileSync45(entitlementPath, "utf-8"));
29718
29862
  } catch {
29719
29863
  return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
29720
29864
  }
@@ -29878,12 +30022,12 @@ installMediaDownloadGuard();
29878
30022
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT || "";
29879
30023
  var BRAND_JSON_PATH = PLATFORM_ROOT6 ? join52(PLATFORM_ROOT6, "config", "brand.json") : "";
29880
30024
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
29881
- if (BRAND_JSON_PATH && !existsSync48(BRAND_JSON_PATH)) {
30025
+ if (BRAND_JSON_PATH && !existsSync49(BRAND_JSON_PATH)) {
29882
30026
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
29883
30027
  }
29884
- if (BRAND_JSON_PATH && existsSync48(BRAND_JSON_PATH)) {
30028
+ if (BRAND_JSON_PATH && existsSync49(BRAND_JSON_PATH)) {
29885
30029
  try {
29886
- const parsed = JSON.parse(readFileSync45(BRAND_JSON_PATH, "utf-8"));
30030
+ const parsed = JSON.parse(readFileSync46(BRAND_JSON_PATH, "utf-8"));
29887
30031
  BRAND = { ...BRAND, ...parsed };
29888
30032
  } catch (err) {
29889
30033
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -29918,8 +30062,8 @@ var brandLoginOpts = {
29918
30062
  var ALIAS_DOMAINS_PATH = join52(homedir4(), BRAND.configDir, "alias-domains.json");
29919
30063
  function loadAliasDomains() {
29920
30064
  try {
29921
- if (!existsSync48(ALIAS_DOMAINS_PATH)) return null;
29922
- const parsed = JSON.parse(readFileSync45(ALIAS_DOMAINS_PATH, "utf-8"));
30065
+ if (!existsSync49(ALIAS_DOMAINS_PATH)) return null;
30066
+ const parsed = JSON.parse(readFileSync46(ALIAS_DOMAINS_PATH, "utf-8"));
29923
30067
  if (!Array.isArray(parsed)) {
29924
30068
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
29925
30069
  return null;
@@ -29994,7 +30138,7 @@ var waGateway = new WaGateway({
29994
30138
  fetchStandingRules: fetchAccountStandingRules,
29995
30139
  resolveSessionOverride: (accountId, senderId) => resolveChannelOverride(accountId, "whatsapp", senderId),
29996
30140
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
29997
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve43(process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
30141
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve45(process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
29998
30142
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
29999
30143
  // path-validation scope) is the sender's effective SESSION account, resolved
30000
30144
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -30009,7 +30153,7 @@ var waGateway = new WaGateway({
30009
30153
  caption,
30010
30154
  accountId,
30011
30155
  maxyAccountId,
30012
- platformRoot: resolve43(process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, ".."))
30156
+ platformRoot: resolve45(process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, ".."))
30013
30157
  });
30014
30158
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
30015
30159
  },
@@ -30711,20 +30855,20 @@ app75.get("/agent-assets/:slug/:filename", (c) => {
30711
30855
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
30712
30856
  return c.text("Not found", 404);
30713
30857
  }
30714
- const filePath = resolve43(account.accountDir, "agents", slug, "assets", filename);
30715
- const expectedDir = resolve43(account.accountDir, "agents", slug, "assets");
30858
+ const filePath = resolve45(account.accountDir, "agents", slug, "assets", filename);
30859
+ const expectedDir = resolve45(account.accountDir, "agents", slug, "assets");
30716
30860
  if (!filePath.startsWith(expectedDir + "/")) {
30717
30861
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
30718
30862
  return c.text("Forbidden", 403);
30719
30863
  }
30720
- if (!existsSync48(filePath)) {
30864
+ if (!existsSync49(filePath)) {
30721
30865
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
30722
30866
  return c.text("Not found", 404);
30723
30867
  }
30724
30868
  const ext = "." + filename.split(".").pop()?.toLowerCase();
30725
30869
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
30726
30870
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
30727
- const body = readFileSync45(filePath);
30871
+ const body = readFileSync46(filePath);
30728
30872
  return c.body(body, 200, {
30729
30873
  "Content-Type": contentType,
30730
30874
  "Cache-Control": "public, max-age=3600"
@@ -30741,20 +30885,20 @@ app75.get("/generated/:filename", (c) => {
30741
30885
  console.error(`[generated] serve file=${filename} status=404`);
30742
30886
  return c.text("Not found", 404);
30743
30887
  }
30744
- const filePath = resolve43(account.accountDir, "generated", filename);
30745
- const expectedDir = resolve43(account.accountDir, "generated");
30888
+ const filePath = resolve45(account.accountDir, "generated", filename);
30889
+ const expectedDir = resolve45(account.accountDir, "generated");
30746
30890
  if (!filePath.startsWith(expectedDir + "/")) {
30747
30891
  console.error(`[generated] serve file=${filename} status=403`);
30748
30892
  return c.text("Forbidden", 403);
30749
30893
  }
30750
- if (!existsSync48(filePath)) {
30894
+ if (!existsSync49(filePath)) {
30751
30895
  console.error(`[generated] serve file=${filename} status=404`);
30752
30896
  return c.text("Not found", 404);
30753
30897
  }
30754
30898
  const ext = "." + filename.split(".").pop()?.toLowerCase();
30755
30899
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
30756
30900
  console.log(`[generated] serve file=${filename} status=200`);
30757
- const body = readFileSync45(filePath);
30901
+ const body = readFileSync46(filePath);
30758
30902
  return c.body(body, 200, {
30759
30903
  "Content-Type": contentType,
30760
30904
  "Cache-Control": "public, max-age=86400"
@@ -30767,9 +30911,9 @@ app75.route("/v", visitor_consent_default);
30767
30911
  var htmlCache = /* @__PURE__ */ new Map();
30768
30912
  var brandLogoPath = "/brand/maxy-monochrome.png";
30769
30913
  var brandIconPath = "/brand/maxy-monochrome.png";
30770
- if (BRAND_JSON_PATH && existsSync48(BRAND_JSON_PATH)) {
30914
+ if (BRAND_JSON_PATH && existsSync49(BRAND_JSON_PATH)) {
30771
30915
  try {
30772
- const fullBrand = JSON.parse(readFileSync45(BRAND_JSON_PATH, "utf-8"));
30916
+ const fullBrand = JSON.parse(readFileSync46(BRAND_JSON_PATH, "utf-8"));
30773
30917
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
30774
30918
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
30775
30919
  } catch {
@@ -30796,11 +30940,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
30796
30940
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
30797
30941
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
30798
30942
  var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
30799
- (p) => existsSync48(resolve43(process.cwd(), "public", p.replace(/^\//, "")))
30943
+ (p) => existsSync49(resolve45(process.cwd(), "public", p.replace(/^\//, "")))
30800
30944
  );
30801
30945
  var SW_SOURCE = (() => {
30802
30946
  try {
30803
- return readFileSync45(resolve43(process.cwd(), "public", "sw.js"), "utf-8");
30947
+ return readFileSync46(resolve45(process.cwd(), "public", "sw.js"), "utf-8");
30804
30948
  } catch {
30805
30949
  return null;
30806
30950
  }
@@ -30809,8 +30953,8 @@ function readInstalledVersion() {
30809
30953
  try {
30810
30954
  if (!PLATFORM_ROOT6) return "unknown";
30811
30955
  const versionFile = join52(PLATFORM_ROOT6, "config", `.${BRAND.hostname}-version`);
30812
- if (!existsSync48(versionFile)) return "unknown";
30813
- const content = readFileSync45(versionFile, "utf-8").trim();
30956
+ if (!existsSync49(versionFile)) return "unknown";
30957
+ const content = readFileSync46(versionFile, "utf-8").trim();
30814
30958
  return content || "unknown";
30815
30959
  } catch {
30816
30960
  return "unknown";
@@ -30821,7 +30965,7 @@ var versionScript = `<script>window.__MAXY_VERSION__=${JSON.stringify(INSTALLED_
30821
30965
  function cachedHtml(file) {
30822
30966
  let html = htmlCache.get(file);
30823
30967
  if (!html) {
30824
- html = readFileSync45(resolve43(process.cwd(), "public", file), "utf-8");
30968
+ html = readFileSync46(resolve45(process.cwd(), "public", file), "utf-8");
30825
30969
  const productNameEsc = escapeHtml(BRAND.productName);
30826
30970
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
30827
30971
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -30843,8 +30987,8 @@ function loadBrandingCache(agentSlug) {
30843
30987
  const accountId = getDefaultAccountId();
30844
30988
  if (!accountId) return null;
30845
30989
  const cachePath = join52(configDir, "branding-cache", accountId, `${agentSlug}.json`);
30846
- if (!existsSync48(cachePath)) return null;
30847
- return JSON.parse(readFileSync45(cachePath, "utf-8"));
30990
+ if (!existsSync49(cachePath)) return null;
30991
+ return JSON.parse(readFileSync46(cachePath, "utf-8"));
30848
30992
  } catch {
30849
30993
  return null;
30850
30994
  }
@@ -30939,7 +31083,7 @@ app75.use("/vnc-popout.html", logViewerFetch);
30939
31083
  app75.get("/vnc-popout.html", (c) => {
30940
31084
  let html = htmlCache.get("vnc-popout.html");
30941
31085
  if (!html) {
30942
- html = readFileSync45(resolve43(process.cwd(), "public", "vnc-popout.html"), "utf-8");
31086
+ html = readFileSync46(resolve45(process.cwd(), "public", "vnc-popout.html"), "utf-8");
30943
31087
  const name = escapeHtml(BRAND.productName);
30944
31088
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
30945
31089
  html = html.replace("</head>", ` ${brandScript}
@@ -31092,9 +31236,9 @@ var httpServer = serve({ fetch: app75.fetch, port, hostname });
31092
31236
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
31093
31237
  {
31094
31238
  const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, "..");
31095
- const reconcileScript = resolve43(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
31239
+ const reconcileScript = resolve45(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
31096
31240
  const runReconcile = (ctx) => {
31097
- if (!existsSync48(reconcileScript)) return;
31241
+ if (!existsSync49(reconcileScript)) return;
31098
31242
  try {
31099
31243
  const child = spawn3(process.execPath, [reconcileScript], {
31100
31244
  env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
@@ -31133,14 +31277,14 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
31133
31277
  {
31134
31278
  const DREAM_CYCLE_SWEEP_INTERVAL_MS = 36e5;
31135
31279
  const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, "..");
31136
- const dreamSweepScript = resolve43(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
31280
+ const dreamSweepScript = resolve45(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
31137
31281
  registerLoop({
31138
31282
  name: "dream-cycle-sweep",
31139
31283
  intervalMs: DREAM_CYCLE_SWEEP_INTERVAL_MS,
31140
31284
  firstRunDelayMs: 3e4,
31141
31285
  detached: true,
31142
31286
  run: (ctx) => {
31143
- if (!existsSync48(dreamSweepScript)) return;
31287
+ if (!existsSync49(dreamSweepScript)) return;
31144
31288
  try {
31145
31289
  const child = spawn3(process.execPath, [dreamSweepScript], {
31146
31290
  env: { ...process.env, PLATFORM_ROOT: dreamPlatformRoot },
@@ -31157,10 +31301,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
31157
31301
  }
31158
31302
  {
31159
31303
  const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, "..");
31160
- const outlookScript = resolve43(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
31304
+ const outlookScript = resolve45(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
31161
31305
  const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
31162
31306
  const runOutlookComplete = (ctx) => {
31163
- if (!existsSync48(outlookScript)) return;
31307
+ if (!existsSync49(outlookScript)) return;
31164
31308
  try {
31165
31309
  const child = spawn3(process.execPath, [outlookScript], {
31166
31310
  env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
@@ -31183,18 +31327,18 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
31183
31327
  }
31184
31328
  {
31185
31329
  const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, "..");
31186
- const strandedAccountsDir = resolve43(auditRoot, "..", "data/accounts");
31330
+ const strandedAccountsDir = resolve45(auditRoot, "..", "data/accounts");
31187
31331
  const STRANDED_AUDIT_INTERVAL_MS = 3e5;
31188
31332
  const STRANDED_AGE_MS = 16 * 6e4;
31189
31333
  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;
31190
31334
  const runStrandedAudit = () => {
31191
31335
  try {
31192
- if (!existsSync48(strandedAccountsDir)) return;
31336
+ if (!existsSync49(strandedAccountsDir)) return;
31193
31337
  const now = Date.now();
31194
- for (const name of readdirSync28(strandedAccountsDir)) {
31338
+ for (const name of readdirSync29(strandedAccountsDir)) {
31195
31339
  if (!STRANDED_UUID_RE.test(name)) continue;
31196
- const pendingPath2 = resolve43(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
31197
- if (!existsSync48(pendingPath2)) continue;
31340
+ const pendingPath2 = resolve45(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
31341
+ if (!existsSync49(pendingPath2)) continue;
31198
31342
  const ageMs2 = now - statSync25(pendingPath2).mtimeMs;
31199
31343
  if (ageMs2 > STRANDED_AGE_MS) {
31200
31344
  console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs2 / 1e3)}`);
@@ -31213,7 +31357,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
31213
31357
  }
31214
31358
  {
31215
31359
  const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, "..");
31216
- const googleAccountsDir = resolve43(googleRoot, "..", "data/accounts");
31360
+ const googleAccountsDir = resolve45(googleRoot, "..", "data/accounts");
31217
31361
  const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
31218
31362
  const runGooglePendingAuditSafe = () => {
31219
31363
  try {
@@ -31228,10 +31372,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
31228
31372
  firstRunDelayMs: 27e3,
31229
31373
  run: runGooglePendingAuditSafe
31230
31374
  });
31231
- const googleAuditScript = resolve43(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
31375
+ const googleAuditScript = resolve45(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
31232
31376
  const GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS = 36e5;
31233
31377
  const runGoogleAccountAudit = (ctx) => {
31234
- if (!existsSync48(googleAuditScript)) return;
31378
+ if (!existsSync49(googleAuditScript)) return;
31235
31379
  try {
31236
31380
  const child = spawn3(process.execPath, [googleAuditScript], {
31237
31381
  env: { ...process.env, PLATFORM_ROOT: googleRoot },
@@ -31324,7 +31468,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
31324
31468
  }
31325
31469
  {
31326
31470
  const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, "..");
31327
- const publishScript = resolve43(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
31471
+ const publishScript = resolve45(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
31328
31472
  const PUBLISH_INTERVAL_MS = 3e5;
31329
31473
  const bookingAccounts = () => {
31330
31474
  try {
@@ -31335,7 +31479,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
31335
31479
  }
31336
31480
  };
31337
31481
  const spawnPublish = (account, ctx) => {
31338
- if (!existsSync48(publishScript)) return;
31482
+ if (!existsSync49(publishScript)) return;
31339
31483
  try {
31340
31484
  const child = spawn3(process.execPath, [publishScript], {
31341
31485
  env: {
@@ -31354,21 +31498,21 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
31354
31498
  }
31355
31499
  };
31356
31500
  const auditSnapshotAge = (account) => {
31357
- const availPath = resolve43(account.accountDir, "calendar-availability.json");
31501
+ const availPath = resolve45(account.accountDir, "calendar-availability.json");
31358
31502
  let hasBookingSite = false;
31359
31503
  try {
31360
- if (existsSync48(availPath)) {
31361
- const cfg = JSON.parse(readFileSync45(availPath, "utf-8"));
31504
+ if (existsSync49(availPath)) {
31505
+ const cfg = JSON.parse(readFileSync46(availPath, "utf-8"));
31362
31506
  hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
31363
31507
  }
31364
31508
  } catch {
31365
31509
  }
31366
31510
  if (!hasBookingSite) return;
31367
- const statePath = resolve43(account.accountDir, "state", "booking-availability", "last-publish.json");
31511
+ const statePath = resolve45(account.accountDir, "state", "booking-availability", "last-publish.json");
31368
31512
  let lastSuccessAt = null;
31369
- if (existsSync48(statePath)) {
31513
+ if (existsSync49(statePath)) {
31370
31514
  try {
31371
- const rec = JSON.parse(readFileSync45(statePath, "utf-8"));
31515
+ const rec = JSON.parse(readFileSync46(statePath, "utf-8"));
31372
31516
  lastSuccessAt = rec.lastSuccessAt ?? null;
31373
31517
  } catch {
31374
31518
  console.error(`[calendar-availability] op=audit accountId=${account.accountId} snapshotAgeMs=na reason=bad-state-file`);
@@ -31401,11 +31545,11 @@ startTimeEntryCensus(() => getSession());
31401
31545
  startLedgerCensus(() => getSession());
31402
31546
  {
31403
31547
  const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, "..");
31404
- const auditScript = resolve43(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
31548
+ const auditScript = resolve45(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
31405
31549
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
31406
31550
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
31407
31551
  const runConnectorAudit = (ctx) => {
31408
- if (!existsSync48(auditScript)) return;
31552
+ if (!existsSync49(auditScript)) return;
31409
31553
  try {
31410
31554
  const child = spawn3(process.execPath, [auditScript], {
31411
31555
  env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
@@ -31525,11 +31669,11 @@ try {
31525
31669
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
31526
31670
  async function runAdminUserReconcileTick() {
31527
31671
  try {
31528
- if (!existsSync48(USERS_FILE)) {
31672
+ if (!existsSync49(USERS_FILE)) {
31529
31673
  console.error("[adminuser-self-heal] skip reason=no-users-file");
31530
31674
  return;
31531
31675
  }
31532
- const usersRaw = readFileSync45(USERS_FILE, "utf-8").trim();
31676
+ const usersRaw = readFileSync46(USERS_FILE, "utf-8").trim();
31533
31677
  if (!usersRaw) {
31534
31678
  console.error("[adminuser-self-heal] skip reason=empty-users-file");
31535
31679
  return;
@@ -31581,8 +31725,8 @@ registerLoop({
31581
31725
  });
31582
31726
  var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
31583
31727
  function countUsersRows() {
31584
- if (!existsSync48(USERS_FILE)) return 0;
31585
- const raw = readFileSync45(USERS_FILE, "utf-8").trim();
31728
+ if (!existsSync49(USERS_FILE)) return 0;
31729
+ const raw = readFileSync46(USERS_FILE, "utf-8").trim();
31586
31730
  if (!raw) return 0;
31587
31731
  const users = JSON.parse(raw);
31588
31732
  return users.filter((u) => typeof u.userId === "string").length;
@@ -31716,7 +31860,7 @@ if (bootAccountConfig?.whatsapp) {
31716
31860
  }
31717
31861
  init({
31718
31862
  configDir: configDirForWhatsApp,
31719
- platformRoot: resolve43(process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, "..")),
31863
+ platformRoot: resolve45(process.env.MAXY_PLATFORM_ROOT ?? join52(__dirname, "..")),
31720
31864
  accountConfig: bootAccountConfig,
31721
31865
  // Task 2074 — enrich with the sub-account name and fan out to every open
31722
31866
  // admin SSE stream. Fire-and-forget: the manager's persist path must not