@rubytech/create-maxy-code 0.1.279 → 0.1.281

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 (299) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/mcp-spawn-tee/dist/index.d.ts +31 -43
  3. package/payload/platform/lib/mcp-spawn-tee/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/mcp-spawn-tee/dist/index.js +112 -85
  5. package/payload/platform/lib/mcp-spawn-tee/dist/index.js.map +1 -1
  6. package/payload/platform/lib/mcp-spawn-tee/src/__tests__/spawn-tee.test.ts +111 -0
  7. package/payload/platform/lib/mcp-spawn-tee/src/index.ts +113 -84
  8. package/payload/platform/lib/mcp-spawn-tee/tsconfig.json +2 -1
  9. package/payload/platform/plugins/admin/PLUGIN.md +1 -0
  10. package/payload/platform/plugins/admin/hooks/__tests__/prompt-optimiser-directive.test.sh +42 -0
  11. package/payload/platform/plugins/admin/hooks/prompt-optimiser-directive.sh +60 -15
  12. package/payload/platform/plugins/admin/mcp/dist/__tests__/e-sign-discoverable.test.d.ts +2 -0
  13. package/payload/platform/plugins/admin/mcp/dist/__tests__/e-sign-discoverable.test.d.ts.map +1 -0
  14. package/payload/platform/plugins/admin/mcp/dist/__tests__/e-sign-discoverable.test.js +54 -0
  15. package/payload/platform/plugins/admin/mcp/dist/__tests__/e-sign-discoverable.test.js.map +1 -0
  16. package/payload/platform/plugins/admin/mcp/dist/content-producer-authoring-skills.d.ts +2 -0
  17. package/payload/platform/plugins/admin/mcp/dist/content-producer-authoring-skills.d.ts.map +1 -0
  18. package/payload/platform/plugins/admin/mcp/dist/content-producer-authoring-skills.js +19 -0
  19. package/payload/platform/plugins/admin/mcp/dist/content-producer-authoring-skills.js.map +1 -0
  20. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.d.ts.map +1 -1
  21. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js +2 -5
  22. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js.map +1 -1
  23. package/payload/platform/plugins/admin/skills/a4-print-documents/SKILL.md +2 -0
  24. package/payload/platform/plugins/admin/skills/access-manager/SKILL.md +2 -0
  25. package/payload/platform/plugins/admin/skills/admin-user-management/SKILL.md +2 -0
  26. package/payload/platform/plugins/admin/skills/business-profile/SKILL.md +2 -0
  27. package/payload/platform/plugins/admin/skills/capabilities-here/SKILL.md +2 -0
  28. package/payload/platform/plugins/admin/skills/datetime/SKILL.md +2 -0
  29. package/payload/platform/plugins/admin/skills/deck-pages/SKILL.md +2 -0
  30. package/payload/platform/plugins/admin/skills/file-presentation/SKILL.md +2 -0
  31. package/payload/platform/plugins/admin/skills/investigate/SKILL.md +2 -0
  32. package/payload/platform/plugins/admin/skills/plainly/SKILL.md +2 -0
  33. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +5 -1
  34. package/payload/platform/plugins/admin/skills/plugin-management/SKILL.md +2 -0
  35. package/payload/platform/plugins/admin/skills/professional-document/SKILL.md +2 -0
  36. package/payload/platform/plugins/admin/skills/public-agent-manager/SKILL.md +2 -0
  37. package/payload/platform/plugins/admin/skills/qr-code/SKILL.md +2 -0
  38. package/payload/platform/plugins/admin/skills/session-management/SKILL.md +2 -0
  39. package/payload/platform/plugins/admin/skills/skill-builder/SKILL.md +2 -0
  40. package/payload/platform/plugins/admin/skills/specialist-management/SKILL.md +2 -0
  41. package/payload/platform/plugins/admin/skills/stream-log-review/SKILL.md +2 -0
  42. package/payload/platform/plugins/admin/skills/superpowers-sprint/SKILL.md +2 -0
  43. package/payload/platform/plugins/admin/skills/task/SKILL.md +2 -0
  44. package/payload/platform/plugins/admin/skills/update-knowledge/SKILL.md +2 -0
  45. package/payload/platform/plugins/admin/skills/upgrade/SKILL.md +2 -0
  46. package/payload/platform/plugins/aeo/skills/structured-answer/SKILL.md +2 -0
  47. package/payload/platform/plugins/business-assistant/PLUGIN.md +2 -1
  48. package/payload/platform/plugins/business-assistant/{references/e-sign.md → skills/e-sign/SKILL.md} +9 -2
  49. package/payload/platform/plugins/cloudflare/skills/cloudflare/SKILL.md +2 -0
  50. package/payload/platform/plugins/deep-research/skills/academic-verify/SKILL.md +2 -0
  51. package/payload/platform/plugins/deep-research/skills/book-mirror/SKILL.md +2 -0
  52. package/payload/platform/plugins/deep-research/skills/data-research/SKILL.md +2 -0
  53. package/payload/platform/plugins/deep-research/skills/deep-research/SKILL.md +2 -0
  54. package/payload/platform/plugins/deep-research/skills/strategic-reading/SKILL.md +2 -0
  55. package/payload/platform/plugins/docs/references/platform.md +2 -0
  56. package/payload/platform/plugins/email/PLUGIN.md +2 -0
  57. package/payload/platform/plugins/email/mcp/dist/__tests__/attachment-resolve.test.d.ts +2 -0
  58. package/payload/platform/plugins/email/mcp/dist/__tests__/attachment-resolve.test.d.ts.map +1 -0
  59. package/payload/platform/plugins/email/mcp/dist/__tests__/attachment-resolve.test.js +68 -0
  60. package/payload/platform/plugins/email/mcp/dist/__tests__/attachment-resolve.test.js.map +1 -0
  61. package/payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.d.ts +2 -0
  62. package/payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.d.ts.map +1 -0
  63. package/payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.js +55 -0
  64. package/payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.js.map +1 -0
  65. package/payload/platform/plugins/email/mcp/dist/__tests__/providers.test.d.ts +2 -0
  66. package/payload/platform/plugins/email/mcp/dist/__tests__/providers.test.d.ts.map +1 -0
  67. package/payload/platform/plugins/email/mcp/dist/__tests__/providers.test.js +110 -0
  68. package/payload/platform/plugins/email/mcp/dist/__tests__/providers.test.js.map +1 -0
  69. package/payload/platform/plugins/email/mcp/dist/__tests__/recipient-filter.test.d.ts +2 -0
  70. package/payload/platform/plugins/email/mcp/dist/__tests__/recipient-filter.test.d.ts.map +1 -0
  71. package/payload/platform/plugins/email/mcp/dist/__tests__/recipient-filter.test.js +57 -0
  72. package/payload/platform/plugins/email/mcp/dist/__tests__/recipient-filter.test.js.map +1 -0
  73. package/payload/platform/plugins/email/mcp/dist/index.js +8 -1
  74. package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
  75. package/payload/platform/plugins/email/mcp/dist/lib/attachment-resolve.d.ts +5 -0
  76. package/payload/platform/plugins/email/mcp/dist/lib/attachment-resolve.d.ts.map +1 -1
  77. package/payload/platform/plugins/email/mcp/dist/lib/attachment-resolve.js +35 -5
  78. package/payload/platform/plugins/email/mcp/dist/lib/attachment-resolve.js.map +1 -1
  79. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +50 -14
  80. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
  81. package/payload/platform/plugins/email/mcp/dist/lib/imap.js +143 -66
  82. package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
  83. package/payload/platform/plugins/email/mcp/dist/lib/ingest-batch.d.ts +8 -0
  84. package/payload/platform/plugins/email/mcp/dist/lib/ingest-batch.d.ts.map +1 -1
  85. package/payload/platform/plugins/email/mcp/dist/lib/ingest-batch.js.map +1 -1
  86. package/payload/platform/plugins/email/mcp/dist/lib/providers.d.ts +16 -5
  87. package/payload/platform/plugins/email/mcp/dist/lib/providers.d.ts.map +1 -1
  88. package/payload/platform/plugins/email/mcp/dist/lib/providers.js +120 -13
  89. package/payload/platform/plugins/email/mcp/dist/lib/providers.js.map +1 -1
  90. package/payload/platform/plugins/email/mcp/dist/tools/email-fetch.js +3 -3
  91. package/payload/platform/plugins/email/mcp/dist/tools/email-fetch.js.map +1 -1
  92. package/payload/platform/plugins/email/mcp/dist/tools/email-otp-extract.d.ts.map +1 -1
  93. package/payload/platform/plugins/email/mcp/dist/tools/email-otp-extract.js +4 -2
  94. package/payload/platform/plugins/email/mcp/dist/tools/email-otp-extract.js.map +1 -1
  95. package/payload/platform/plugins/email/mcp/dist/tools/email-read.d.ts.map +1 -1
  96. package/payload/platform/plugins/email/mcp/dist/tools/email-read.js +18 -8
  97. package/payload/platform/plugins/email/mcp/dist/tools/email-read.js.map +1 -1
  98. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.d.ts.map +1 -1
  99. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js +5 -3
  100. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js.map +1 -1
  101. package/payload/platform/plugins/email/mcp/dist/tools/email-search.d.ts.map +1 -1
  102. package/payload/platform/plugins/email/mcp/dist/tools/email-search.js +18 -8
  103. package/payload/platform/plugins/email/mcp/dist/tools/email-search.js.map +1 -1
  104. package/payload/platform/plugins/email/mcp/dist/tools/email-send.d.ts.map +1 -1
  105. package/payload/platform/plugins/email/mcp/dist/tools/email-send.js +6 -3
  106. package/payload/platform/plugins/email/mcp/dist/tools/email-send.js.map +1 -1
  107. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.d.ts.map +1 -1
  108. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js +22 -4
  109. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js.map +1 -1
  110. package/payload/platform/plugins/email/mcp/package.json +4 -2
  111. package/payload/platform/plugins/email/mcp/vitest.config.ts +9 -0
  112. package/payload/platform/plugins/email/references/email-reference.md +22 -5
  113. package/payload/platform/plugins/email/skills/email-composition/SKILL.md +3 -1
  114. package/payload/platform/plugins/email/skills/email-ingest/SKILL.md +2 -0
  115. package/payload/platform/plugins/graph/PLUGIN.md +2 -0
  116. package/payload/platform/plugins/graph-viewer/skills/render-graph/SKILL.md +2 -0
  117. package/payload/platform/plugins/linkedin-extension/skills/linkedin-extension/SKILL.md +2 -0
  118. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/kd-classify-account-dir.test.d.ts +2 -0
  119. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/kd-classify-account-dir.test.d.ts.map +1 -0
  120. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/kd-classify-account-dir.test.js +31 -0
  121. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/kd-classify-account-dir.test.js.map +1 -0
  122. package/payload/platform/plugins/memory/mcp/dist/tools/kd-classify.d.ts +5 -0
  123. package/payload/platform/plugins/memory/mcp/dist/tools/kd-classify.d.ts.map +1 -1
  124. package/payload/platform/plugins/memory/mcp/dist/tools/kd-classify.js +21 -2
  125. package/payload/platform/plugins/memory/mcp/dist/tools/kd-classify.js.map +1 -1
  126. package/payload/platform/plugins/memory/skills/archive-crawler/SKILL.md +2 -0
  127. package/payload/platform/plugins/memory/skills/challenge/SKILL.md +2 -0
  128. package/payload/platform/plugins/memory/skills/concept-synthesis/SKILL.md +2 -0
  129. package/payload/platform/plugins/memory/skills/connect/SKILL.md +2 -0
  130. package/payload/platform/plugins/memory/skills/conversational-memory/SKILL.md +2 -0
  131. package/payload/platform/plugins/memory/skills/emerge/SKILL.md +2 -0
  132. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +2 -0
  133. package/payload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/SKILL.md +3 -1
  134. package/payload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/__tests__/restatement-ladder.test.sh +21 -0
  135. package/payload/platform/plugins/scheduling/skills/briefing/SKILL.md +2 -0
  136. package/payload/platform/plugins/scheduling/skills/daily-prep/SKILL.md +2 -0
  137. package/payload/platform/plugins/slides/skills/deck-system/SKILL.md +2 -0
  138. package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.js +5 -5
  139. package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.js.map +1 -1
  140. package/payload/platform/plugins/whatsapp/skills/connect-whatsapp/SKILL.md +2 -0
  141. package/payload/platform/plugins/whatsapp/skills/manage-whatsapp-config/SKILL.md +2 -0
  142. package/payload/platform/plugins/work/skills/execute-task/SKILL.md +2 -0
  143. package/payload/platform/plugins/workflows/skills/workflow-manager/SKILL.md +2 -0
  144. package/payload/platform/scripts/lib/__tests__/admin-skills-bootstrap.test.sh +64 -0
  145. package/payload/platform/scripts/lib/admin-skills-bootstrap.sh +109 -0
  146. package/payload/platform/scripts/setup-account.sh +8 -0
  147. package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts.map +1 -1
  148. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js +43 -11
  149. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js.map +1 -1
  150. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  151. package/payload/platform/services/claude-session-manager/dist/http-server.js +74 -1
  152. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  153. package/payload/platform/services/claude-session-manager/dist/index.js +48 -2
  154. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  155. package/payload/platform/services/claude-session-manager/dist/liveness-divergence.d.ts +19 -0
  156. package/payload/platform/services/claude-session-manager/dist/liveness-divergence.d.ts.map +1 -0
  157. package/payload/platform/services/claude-session-manager/dist/liveness-divergence.js +38 -0
  158. package/payload/platform/services/claude-session-manager/dist/liveness-divergence.js.map +1 -0
  159. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +8 -0
  160. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  161. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +19 -1
  162. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  163. package/payload/platform/services/claude-session-manager/dist/scope-record.d.ts +11 -0
  164. package/payload/platform/services/claude-session-manager/dist/scope-record.d.ts.map +1 -0
  165. package/payload/platform/services/claude-session-manager/dist/scope-record.js +81 -0
  166. package/payload/platform/services/claude-session-manager/dist/scope-record.js.map +1 -0
  167. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +10 -7
  168. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
  169. package/payload/platform/services/whatsapp-channel/dist/notification.js +14 -14
  170. package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
  171. package/payload/platform/templates/agents/admin/IDENTITY.md +2 -6
  172. package/payload/server/public/assets/AdminShell-FO766lOW.js +1 -0
  173. package/payload/server/public/assets/{Checkbox-2reCESkb.js → Checkbox-syHoU9nY.js} +1 -1
  174. package/payload/server/public/assets/{admin-xRCXEFNW.js → admin-0_VxffD5.js} +1 -1
  175. package/payload/server/public/assets/{arc-BgelqC_3.js → arc-BW1WhwmV.js} +1 -1
  176. package/payload/server/public/assets/architecture-YZFGNWBL-xHbVjatf.js +1 -0
  177. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-BabnAZJm.js → architectureDiagram-Q4EWVU46-DsionCio.js} +1 -1
  178. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-BJzZqNsy.js → blockDiagram-DXYQGD6D-NOG5yVZk.js} +1 -1
  179. package/payload/server/public/assets/{browser-DT2XfRpL.js → browser-Cxjkhtsk.js} +1 -1
  180. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-By-xuh9F.js → c4Diagram-AHTNJAMY-DwFV1k9I.js} +1 -1
  181. package/payload/server/public/assets/channel-D8Go_zJk.js +1 -0
  182. package/payload/server/public/assets/{chunk-2KRD3SAO-Gj2dSpBl.js → chunk-2KRD3SAO-CKn-bEkI.js} +1 -1
  183. package/payload/server/public/assets/{chunk-336JU56O-2PXVPCUA.js → chunk-336JU56O-iJ4ISPCi.js} +2 -2
  184. package/payload/server/public/assets/chunk-426QAEUC-sWe0Iexz.js +1 -0
  185. package/payload/server/public/assets/{chunk-4BX2VUAB-9XIBlnC2.js → chunk-4BX2VUAB-B2mSmC97.js} +1 -1
  186. package/payload/server/public/assets/{chunk-4TB4RGXK-Cr3mXPnI.js → chunk-4TB4RGXK-kKNYi2_i.js} +1 -1
  187. package/payload/server/public/assets/{chunk-55IACEB6-Ccg46J3A.js → chunk-55IACEB6-JLT9m7Hd.js} +1 -1
  188. package/payload/server/public/assets/{chunk-5FUZZQ4R-Cz9MvPKc.js → chunk-5FUZZQ4R-Car3r0he.js} +1 -1
  189. package/payload/server/public/assets/{chunk-5PVQY5BW-BleOdlgO.js → chunk-5PVQY5BW-DR9EfLvj.js} +1 -1
  190. package/payload/server/public/assets/{chunk-67CJDMHE-CyCYCQWy.js → chunk-67CJDMHE-CCdP3Pdx.js} +1 -1
  191. package/payload/server/public/assets/{chunk-7N4EOEYR-KpT3uHzH.js → chunk-7N4EOEYR-bXgVzdM9.js} +1 -1
  192. package/payload/server/public/assets/{chunk-AA7GKIK3-BfOzbuxq.js → chunk-AA7GKIK3-CYeDvY8B.js} +1 -1
  193. package/payload/server/public/assets/{chunk-BSJP7CBP-Bq0M3wlv.js → chunk-BSJP7CBP-U0Fi-Ers.js} +1 -1
  194. package/payload/server/public/assets/{chunk-CIAEETIT-CR-2dNaL.js → chunk-CIAEETIT-C8QrV6Gg.js} +1 -1
  195. package/payload/server/public/assets/{chunk-EDXVE4YY-egUGMTOS.js → chunk-EDXVE4YY-DLUWVRZV.js} +1 -1
  196. package/payload/server/public/assets/{chunk-ENJZ2VHE-CQohBEFw.js → chunk-ENJZ2VHE-B4bNJo6C.js} +1 -1
  197. package/payload/server/public/assets/{chunk-FMBD7UC4-DIxBUbLP.js → chunk-FMBD7UC4-DxAQS3UB.js} +1 -1
  198. package/payload/server/public/assets/{chunk-FOC6F5B3-C2694Zoq.js → chunk-FOC6F5B3-CyIK3zeY.js} +1 -1
  199. package/payload/server/public/assets/{chunk-ICPOFSXX-DpXZKHyn.js → chunk-ICPOFSXX-Qzl8Ki0l.js} +2 -2
  200. package/payload/server/public/assets/{chunk-K5T4RW27-CUicG0Rp.js → chunk-K5T4RW27-7GcDzjyJ.js} +1 -1
  201. package/payload/server/public/assets/{chunk-KGLVRYIC-B5mPJhOr.js → chunk-KGLVRYIC-B7pAr9hf.js} +1 -1
  202. package/payload/server/public/assets/{chunk-LIHQZDEY-q81QhuMs.js → chunk-LIHQZDEY-DEoU2jrz.js} +1 -1
  203. package/payload/server/public/assets/{chunk-ORNJ4GCN-DgurdFZs.js → chunk-ORNJ4GCN-BwMFuN24.js} +1 -1
  204. package/payload/server/public/assets/{chunk-OYMX7WX6-CxqMRu2d.js → chunk-OYMX7WX6-BenBO6O_.js} +1 -1
  205. package/payload/server/public/assets/chunk-QZHKN3VN-CHE_iZO7.js +1 -0
  206. package/payload/server/public/assets/{chunk-U2HBQHQK-BSLctJC9.js → chunk-U2HBQHQK-DewM8R0D.js} +1 -1
  207. package/payload/server/public/assets/{chunk-X2U36JSP--0AUeeFl.js → chunk-X2U36JSP-C22Q6Ea4.js} +1 -1
  208. package/payload/server/public/assets/{chunk-XPW4576I-D-hf9Bcn.js → chunk-XPW4576I-BA0a8Ygs.js} +1 -1
  209. package/payload/server/public/assets/{chunk-YZCP3GAM-PvOhSwI9.js → chunk-YZCP3GAM-DfUUNTnA.js} +1 -1
  210. package/payload/server/public/assets/{chunk-ZZ45TVLE-1zPUlNWz.js → chunk-ZZ45TVLE-CUT6zma2.js} +1 -1
  211. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BLb1mzrT.js +1 -0
  212. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-Ctj5qYTS.js +1 -0
  213. package/payload/server/public/assets/clone-DGZ2vydA.js +1 -0
  214. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-Cvo-gkBd.js → cose-bilkent-S5V4N54A-Df_JmB8E.js} +1 -1
  215. package/payload/server/public/assets/{dagre-CMHsNfjP.js → dagre-CYXRIdv0.js} +1 -1
  216. package/payload/server/public/assets/{dagre-KV5264BT-CM1DSx4E.js → dagre-KV5264BT-D4EGb60h.js} +1 -1
  217. package/payload/server/public/assets/{data-Dr7XUvAx.js → data-BOgwOWnw.js} +1 -1
  218. package/payload/server/public/assets/{diagram-5BDNPKRD-VDHiHwEI.js → diagram-5BDNPKRD-BzieCEfT.js} +1 -1
  219. package/payload/server/public/assets/{diagram-G4DWMVQ6-OKdufoeW.js → diagram-G4DWMVQ6-DDbO71XD.js} +1 -1
  220. package/payload/server/public/assets/{diagram-MMDJMWI5-Yg6QdCA1.js → diagram-MMDJMWI5-DqQ_UXDA.js} +1 -1
  221. package/payload/server/public/assets/{diagram-TYMM5635-CpEMZQDu.js → diagram-TYMM5635-CFyxA1aZ.js} +1 -1
  222. package/payload/server/public/assets/{dist-811BIK0R.js → dist-BmvZ8OaX.js} +1 -1
  223. package/payload/server/public/assets/{erDiagram-SMLLAGMA-Dw5gAkFM.js → erDiagram-SMLLAGMA-BMaEBbOK.js} +1 -1
  224. package/payload/server/public/assets/{flatten-BsWEYbBB.js → flatten-Bo6YRmWl.js} +1 -1
  225. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-Cy_R1XHz.js → flowDiagram-DWJPFMVM-De5ChZQP.js} +1 -1
  226. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BYARP_eH.js → ganttDiagram-T4ZO3ILL-CXEMPVaK.js} +1 -1
  227. package/payload/server/public/assets/gitGraph-7Q5UKJZL-CmHdoS27.js +1 -0
  228. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-BGOe0unY.js → gitGraphDiagram-UUTBAWPF-OZedr_6y.js} +1 -1
  229. package/payload/server/public/assets/{graph-DOEjjQHD.js → graph-BqD2GjQd.js} +2 -2
  230. package/payload/server/public/assets/{graph-labels-eOrWYy0R.js → graph-labels-DSDTSBfM.js} +1 -1
  231. package/payload/server/public/assets/{graphlib-DaefxCga.js → graphlib-CN4nhD2U.js} +1 -1
  232. package/payload/server/public/assets/info-OMHHGYJF-DTA9msO-.js +1 -0
  233. package/payload/server/public/assets/infoDiagram-42DDH7IO-CSqg4nRL.js +2 -0
  234. package/payload/server/public/assets/{isEmpty-BWl67LAZ.js → isEmpty-D6Kr-M1M.js} +1 -1
  235. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-YrGuzpiI.js → ishikawaDiagram-UXIWVN3A-ChlzrZyx.js} +1 -1
  236. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-EIykOcqg.js → journeyDiagram-VCZTEJTY-DsrK55ZO.js} +1 -1
  237. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-BR0TC6Je.js → kanban-definition-6JOO6SKY-DYF-_Rym.js} +1 -1
  238. package/payload/server/public/assets/{line-DPGcT5IM.js → line-3zmwI8XK.js} +1 -1
  239. package/payload/server/public/assets/{linear-CPN03uSh.js → linear-COm19-p7.js} +1 -1
  240. package/payload/server/public/assets/{mermaid-parser.core-D7Iu4c9M.js → mermaid-parser.core-BrcX8-cl.js} +2 -2
  241. package/payload/server/public/assets/{mermaid.core-krXRpXn9.js → mermaid.core-CBdz3b1N.js} +3 -3
  242. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-HwiCtPzN.js → mindmap-definition-QFDTVHPH-BqCqlYZb.js} +1 -1
  243. package/payload/server/public/assets/{ordinal-krseTxxN.js → ordinal-BDi6f4xk.js} +1 -1
  244. package/payload/server/public/assets/packet-4T2RLAQJ-6GjqIKgu.js +1 -0
  245. package/payload/server/public/assets/pie-ZZUOXDRM-T72DJ5JR.js +1 -0
  246. package/payload/server/public/assets/{pieDiagram-DEJITSTG-xodxyWLe.js → pieDiagram-DEJITSTG-D5LiILuM.js} +1 -1
  247. package/payload/server/public/assets/{public-xVaPcg6i.js → public-udi_Z7la.js} +3 -3
  248. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-DuYYY4ZZ.js → quadrantDiagram-34T5L4WZ-C3iuI5l_.js} +1 -1
  249. package/payload/server/public/assets/radar-PYXPWWZC-x-6xW1dE.js +1 -0
  250. package/payload/server/public/assets/{reduce-tk-xY6Fv.js → reduce-CGi9ik8i.js} +1 -1
  251. package/payload/server/public/assets/{requirementDiagram-MS252O5E-D0ta3kru.js → requirementDiagram-MS252O5E-CTPOw5qQ.js} +1 -1
  252. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-KdHdlzvT.js → sankeyDiagram-XADWPNL6-D_5aVlYp.js} +1 -1
  253. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-DoSFUTQZ.js → sequenceDiagram-FGHM5R23-D7h5vocM.js} +1 -1
  254. package/payload/server/public/assets/{src-Cpl1JzME.js → src-DLEIsjER.js} +1 -1
  255. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-BLW0KiSA.js → stateDiagram-FHFEXIEX-DyZjuwPj.js} +1 -1
  256. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BiW9pGXy.js +1 -0
  257. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-8QAzhYz1.js → timeline-definition-GMOUNBTQ-BqpVYJz_.js} +1 -1
  258. package/payload/server/public/assets/treeView-SZITEDCU-5-6wEryJ.js +1 -0
  259. package/payload/server/public/assets/treemap-W4RFUUIX-DF48Cc86.js +1 -0
  260. package/payload/server/public/assets/{useSelectionMode-DlJsX-_X.js → useSelectionMode-BPzPjKP_.js} +1 -1
  261. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-BKvfScOi.js → vennDiagram-DHZGUBPP-Czflml0e.js} +1 -1
  262. package/payload/server/public/assets/wardley-RL74JXVD-duKIa6Hq.js +1 -0
  263. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-DaMfDpJ3.js → wardleyDiagram-NUSXRM2D-Cqz3pSTK.js} +1 -1
  264. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BIkNQlLa.js → xychartDiagram-5P7HB3ND-CS5dEuUO.js} +1 -1
  265. package/payload/server/public/browser.html +4 -4
  266. package/payload/server/public/data.html +5 -5
  267. package/payload/server/public/graph.html +6 -6
  268. package/payload/server/public/index.html +5 -5
  269. package/payload/server/public/public.html +4 -4
  270. package/payload/server/server.js +339 -482
  271. package/payload/server/public/assets/AdminShell-DnH3kou-.js +0 -1
  272. package/payload/server/public/assets/architecture-YZFGNWBL-YM-TtgPY.js +0 -1
  273. package/payload/server/public/assets/channel-BRPH0atd.js +0 -1
  274. package/payload/server/public/assets/chunk-426QAEUC-QhauxjvK.js +0 -1
  275. package/payload/server/public/assets/chunk-QZHKN3VN-BDAQvtxz.js +0 -1
  276. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BJv89PB6.js +0 -1
  277. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DNUszH5M.js +0 -1
  278. package/payload/server/public/assets/clone-CREg9jLM.js +0 -1
  279. package/payload/server/public/assets/gitGraph-7Q5UKJZL-CtOPqykB.js +0 -1
  280. package/payload/server/public/assets/info-OMHHGYJF-Jba5enA8.js +0 -1
  281. package/payload/server/public/assets/infoDiagram-42DDH7IO-Df9BlkPA.js +0 -2
  282. package/payload/server/public/assets/packet-4T2RLAQJ-D_eWzeAP.js +0 -1
  283. package/payload/server/public/assets/pie-ZZUOXDRM-BDiy1Ob2.js +0 -1
  284. package/payload/server/public/assets/radar-PYXPWWZC-C5mlfmtg.js +0 -1
  285. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-C5zlCV4X.js +0 -1
  286. package/payload/server/public/assets/treeView-SZITEDCU-CM-9m-cS.js +0 -1
  287. package/payload/server/public/assets/treemap-W4RFUUIX-DDHPB-Xh.js +0 -1
  288. package/payload/server/public/assets/wardley-RL74JXVD-CUb3Br4q.js +0 -1
  289. package/payload/server/public/assets/whatsapp-cDxgZkbM.js +0 -1
  290. package/payload/server/public/whatsapp.html +0 -18
  291. /package/payload/server/public/assets/{_baseFor-BHtDrjIo.js → _baseFor-Cam2PbSt.js} +0 -0
  292. /package/payload/server/public/assets/{array-DetWRiSa.js → array-DYRGGQae.js} +0 -0
  293. /package/payload/server/public/assets/{chunk-CWOGyPgy.js → chunk-CnGqDkHZ.js} +0 -0
  294. /package/payload/server/public/assets/{cytoscape.esm-C9yNhe1u.js → cytoscape.esm-nWsJMTNI.js} +0 -0
  295. /package/payload/server/public/assets/{defaultLocale-_WRwicXn.js → defaultLocale-Du1XY3Dp.js} +0 -0
  296. /package/payload/server/public/assets/{init-sTEcj9YX.js → init-B5BXBRcm.js} +0 -0
  297. /package/payload/server/public/assets/{katex-s61Rgv6l.js → katex-HOUACuRw.js} +0 -0
  298. /package/payload/server/public/assets/{path-B0Ik7Tu9.js → path-CNO468J-.js} +0 -0
  299. /package/payload/server/public/assets/{rough.esm-DKRO8IF-.js → rough.esm-DRO6hWPh.js} +0 -0
@@ -1201,8 +1201,8 @@ var serveStatic = (options = { root: "" }) => {
1201
1201
  };
1202
1202
 
1203
1203
  // server/index.ts
1204
- import { readFileSync as readFileSync24, existsSync as existsSync24, watchFile } from "fs";
1205
- import { resolve as resolve27, join as join19, basename as basename7 } from "path";
1204
+ import { readFileSync as readFileSync23, existsSync as existsSync23, watchFile } from "fs";
1205
+ import { resolve as resolve26, join as join18, basename as basename7 } from "path";
1206
1206
  import { homedir as homedir2 } from "os";
1207
1207
  import { monitorEventLoopDelay } from "perf_hooks";
1208
1208
 
@@ -1763,7 +1763,7 @@ var credsSaveQueue = Promise.resolve();
1763
1763
  async function drainCredsSaveQueue(timeoutMs = 5e3) {
1764
1764
  console.error(`${TAG2} draining credential save queue\u2026`);
1765
1765
  const timer2 = new Promise(
1766
- (resolve28) => setTimeout(() => resolve28("timeout"), timeoutMs)
1766
+ (resolve27) => setTimeout(() => resolve27("timeout"), timeoutMs)
1767
1767
  );
1768
1768
  const result = await Promise.race([
1769
1769
  credsSaveQueue.then(() => "drained"),
@@ -1891,11 +1891,11 @@ async function createWaSocket(opts) {
1891
1891
  return sock;
1892
1892
  }
1893
1893
  async function waitForConnection(sock) {
1894
- return new Promise((resolve28, reject) => {
1894
+ return new Promise((resolve27, reject) => {
1895
1895
  const handler = (update) => {
1896
1896
  if (update.connection === "open") {
1897
1897
  sock.ev.off("connection.update", handler);
1898
- resolve28();
1898
+ resolve27();
1899
1899
  }
1900
1900
  if (update.connection === "close") {
1901
1901
  sock.ev.off("connection.update", handler);
@@ -2009,14 +2009,14 @@ ${inspected}`;
2009
2009
  return inspect2(err, INSPECT_OPTS2);
2010
2010
  }
2011
2011
  function withTimeout(label, promise, timeoutMs) {
2012
- return new Promise((resolve28, reject) => {
2012
+ return new Promise((resolve27, reject) => {
2013
2013
  const timer2 = setTimeout(() => {
2014
2014
  reject(new Error(`${label} timed out after ${timeoutMs}ms`));
2015
2015
  }, timeoutMs);
2016
2016
  promise.then(
2017
2017
  (value) => {
2018
2018
  clearTimeout(timer2);
2019
- resolve28(value);
2019
+ resolve27(value);
2020
2020
  },
2021
2021
  (err) => {
2022
2022
  clearTimeout(timer2);
@@ -2601,8 +2601,8 @@ async function persistWhatsAppMessage(input) {
2601
2601
  const { givenName, familyName } = splitName(input.pushName);
2602
2602
  const prev = sessionWriteLocks.get(input.cacheKey);
2603
2603
  let release;
2604
- const mine = new Promise((resolve28) => {
2605
- release = resolve28;
2604
+ const mine = new Promise((resolve27) => {
2605
+ release = resolve27;
2606
2606
  });
2607
2607
  const chained = (prev ?? Promise.resolve()).then(() => mine);
2608
2608
  sessionWriteLocks.set(input.cacheKey, chained);
@@ -3069,6 +3069,14 @@ function createInboundDebouncer(opts) {
3069
3069
  return { enqueue, flush, destroy, registerPending };
3070
3070
  }
3071
3071
 
3072
+ // app/lib/whatsapp/inbound/combine-batch.ts
3073
+ function combineInboundBatch(entries) {
3074
+ const last = entries[entries.length - 1];
3075
+ const combinedText = entries.map((e) => e.text).filter(Boolean).join("\n");
3076
+ const media = entries.flatMap((e) => e.media);
3077
+ return { ...last, text: combinedText, media };
3078
+ }
3079
+
3072
3080
  // app/lib/whatsapp/opening-hours.ts
3073
3081
  var TAG10 = "[whatsapp:hours]";
3074
3082
  async function isBusinessOpen(accountId) {
@@ -3638,11 +3646,11 @@ async function connectWithReconnect(conn) {
3638
3646
  console.error(
3639
3647
  `${TAG12} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
3640
3648
  );
3641
- await new Promise((resolve28) => {
3642
- const timer2 = setTimeout(resolve28, delay);
3649
+ await new Promise((resolve27) => {
3650
+ const timer2 = setTimeout(resolve27, delay);
3643
3651
  conn.abortController.signal.addEventListener("abort", () => {
3644
3652
  clearTimeout(timer2);
3645
- resolve28();
3653
+ resolve27();
3646
3654
  }, { once: true });
3647
3655
  });
3648
3656
  }
@@ -3650,16 +3658,16 @@ async function connectWithReconnect(conn) {
3650
3658
  }
3651
3659
  }
3652
3660
  function waitForDisconnectEvent(conn) {
3653
- return new Promise((resolve28) => {
3661
+ return new Promise((resolve27) => {
3654
3662
  if (!conn.sock) {
3655
- resolve28();
3663
+ resolve27();
3656
3664
  return;
3657
3665
  }
3658
3666
  const sock = conn.sock;
3659
3667
  const handler = (update) => {
3660
3668
  if (update.connection === "close") {
3661
3669
  sock.ev.off("connection.update", handler);
3662
- resolve28();
3670
+ resolve27();
3663
3671
  }
3664
3672
  };
3665
3673
  sock.ev.on("connection.update", handler);
@@ -3723,21 +3731,10 @@ function monitorInbound(conn) {
3723
3731
  },
3724
3732
  onFlush: (entries) => {
3725
3733
  if (!onInboundMessage) return;
3726
- if (entries.length === 1) {
3727
- onInboundMessage(entries[0]);
3728
- return;
3734
+ if (entries.length > 1) {
3735
+ console.error(`${TAG12} debounce: combining ${entries.length} messages account=${conn.accountId} from=${entries[0].senderPhone}`);
3729
3736
  }
3730
- console.error(`${TAG12} debounce: combining ${entries.length} messages account=${conn.accountId} from=${entries[0].senderPhone}`);
3731
- const last = entries[entries.length - 1];
3732
- const mediaEntry = entries.find((e) => e.mediaPath);
3733
- const combinedText = entries.map((e) => e.text).filter(Boolean).join("\n");
3734
- onInboundMessage({
3735
- ...last,
3736
- text: combinedText,
3737
- mediaPath: mediaEntry?.mediaPath ?? last.mediaPath,
3738
- mediaMimetype: mediaEntry?.mediaMimetype ?? last.mediaMimetype,
3739
- mediaType: mediaEntry?.mediaType ?? last.mediaType
3740
- });
3737
+ onInboundMessage(combineInboundBatch(entries));
3741
3738
  },
3742
3739
  onError: (err) => {
3743
3740
  console.error(`${TAG12} debounce flush error account=${conn.accountId}: ${String(err)}`);
@@ -3899,6 +3896,7 @@ async function handleInboundMessage(conn, msg) {
3899
3896
  groupJid: isGroup2 ? remoteJid : void 0,
3900
3897
  isOwnerMirror: true
3901
3898
  }),
3899
+ media: [],
3902
3900
  isOwnerMirror: true
3903
3901
  });
3904
3902
  return;
@@ -3928,8 +3926,8 @@ async function handleInboundMessage(conn, msg) {
3928
3926
  const conversationKey = isGroup ? remoteJid : senderPhone;
3929
3927
  const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
3930
3928
  let resolvePending;
3931
- const sttPending = new Promise((resolve28) => {
3932
- resolvePending = resolve28;
3929
+ const sttPending = new Promise((resolve27) => {
3930
+ resolvePending = resolve27;
3933
3931
  });
3934
3932
  if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
3935
3933
  try {
@@ -4010,9 +4008,7 @@ async function handleInboundMessage(conn, msg) {
4010
4008
  reply,
4011
4009
  composing,
4012
4010
  cacheKey,
4013
- mediaPath: mediaResult?.path,
4014
- mediaMimetype: mediaResult?.mimetype,
4015
- mediaType: extracted.mediaType,
4011
+ media: mediaResult?.path ? [{ path: mediaResult.path, type: extracted.mediaType, mimetype: mediaResult.mimetype }] : [],
4016
4012
  replyContext: extracted.quotedMessage
4017
4013
  };
4018
4014
  if (accessResult.agentType === "public") {
@@ -4338,20 +4334,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
4338
4334
 
4339
4335
  // server/routes/health.ts
4340
4336
  function checkPort(port2, timeoutMs = 500) {
4341
- return new Promise((resolve28) => {
4337
+ return new Promise((resolve27) => {
4342
4338
  const socket = createConnection2(port2, "127.0.0.1");
4343
4339
  socket.setTimeout(timeoutMs);
4344
4340
  socket.once("connect", () => {
4345
4341
  socket.destroy();
4346
- resolve28(true);
4342
+ resolve27(true);
4347
4343
  });
4348
4344
  socket.once("error", () => {
4349
4345
  socket.destroy();
4350
- resolve28(false);
4346
+ resolve27(false);
4351
4347
  });
4352
4348
  socket.once("timeout", () => {
4353
4349
  socket.destroy();
4354
- resolve28(false);
4350
+ resolve27(false);
4355
4351
  });
4356
4352
  });
4357
4353
  }
@@ -5426,12 +5422,12 @@ async function dispatchOnce(input) {
5426
5422
  });
5427
5423
  if (!entry) return { error: "spawn-failed" };
5428
5424
  entry.lastInboundAt = Date.now();
5429
- let resolve28;
5425
+ let resolve27;
5430
5426
  const turnPromise = new Promise((r) => {
5431
- resolve28 = r;
5427
+ resolve27 = r;
5432
5428
  });
5433
5429
  const listener = (text) => {
5434
- resolve28(text);
5430
+ resolve27(text);
5435
5431
  };
5436
5432
  entry.subscribers.add(listener);
5437
5433
  const writeAtMs = Date.now();
@@ -6269,8 +6265,8 @@ async function startLogin(opts) {
6269
6265
  await clearAuth(authDir);
6270
6266
  let resolveCode = null;
6271
6267
  let rejectCode = null;
6272
- const codePromise = new Promise((resolve28, reject) => {
6273
- resolveCode = resolve28;
6268
+ const codePromise = new Promise((resolve27, reject) => {
6269
+ resolveCode = resolve27;
6274
6270
  rejectCode = reject;
6275
6271
  });
6276
6272
  const codeTimer = setTimeout(
@@ -6994,7 +6990,6 @@ import { basename as basename2, dirname, join as join8, resolve as resolve9, sep
6994
6990
  import { readdirSync as readdirSync4, readFileSync as readFileSync8, statSync as statSync2 } from "fs";
6995
6991
  import { join as join7, resolve as resolve8 } from "path";
6996
6992
  var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.jsonl$/i;
6997
- var PID_FILE_RE = /^([0-9]+)\.json$/;
6998
6993
  var CLI_MARKER_PREFIXES = ["<local-command-", "<command-name>", "<command-message>"];
6999
6994
  var PUBLIC_ROLE = "public";
7000
6995
  var WEBCHAT_CHANNEL = "webchat";
@@ -7044,36 +7039,25 @@ function enumerateJsonls(projectsRoot) {
7044
7039
  }
7045
7040
  return out;
7046
7041
  }
7047
- function sessionIdToPidMap(configDir2) {
7042
+ async function fetchLiveSessions() {
7048
7043
  const out = /* @__PURE__ */ new Map();
7049
- const sessionsDir = join7(configDir2, "sessions");
7050
- let entries;
7044
+ let port2;
7051
7045
  try {
7052
- entries = readdirSync4(sessionsDir, { withFileTypes: true });
7046
+ port2 = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "sidebar-sessions:live" });
7053
7047
  } catch {
7048
+ console.error("[admin-sessions-list] CLAUDE_SESSION_MANAGER_PORT unset; liveness unknown");
7054
7049
  return out;
7055
7050
  }
7056
- for (const entry of entries) {
7057
- if (!entry.isFile()) continue;
7058
- const m = entry.name.match(PID_FILE_RE);
7059
- if (!m) continue;
7060
- const pid = Number(m[1]);
7061
- if (!Number.isFinite(pid) || pid <= 0) continue;
7062
- let body;
7063
- try {
7064
- body = readFileSync8(join7(sessionsDir, entry.name), "utf8");
7065
- } catch {
7066
- continue;
7067
- }
7068
- let parsed;
7069
- try {
7070
- parsed = JSON.parse(body);
7071
- } catch {
7072
- continue;
7051
+ try {
7052
+ const res = await fetch(`http://127.0.0.1:${port2}/live-sessions`);
7053
+ if (!res.ok) {
7054
+ console.error(`[admin-sessions-list] live-sessions status=${res.status}; liveness unknown`);
7055
+ return out;
7073
7056
  }
7074
- if (!parsed || typeof parsed !== "object") continue;
7075
- const sid = parsed.sessionId;
7076
- if (typeof sid === "string" && sid.length > 0) out.set(sid, pid);
7057
+ const body = await res.json();
7058
+ for (const s of body.sessions) out.set(s.sessionId, s.pid);
7059
+ } catch (err) {
7060
+ console.error(`[admin-sessions-list] live-sessions fetch failed: ${err instanceof Error ? err.message : String(err)}; liveness unknown`);
7077
7061
  }
7078
7062
  return out;
7079
7063
  }
@@ -7179,7 +7163,7 @@ app4.get("/", requireAdminSession, async (c) => {
7179
7163
  }
7180
7164
  const projectsRoot = join7(configDir2, "projects");
7181
7165
  const jsonls = enumerateJsonls(projectsRoot);
7182
- const pidsBySession = sessionIdToPidMap(configDir2);
7166
+ const liveSessions = await fetchLiveSessions();
7183
7167
  const accountDir = accountId ? resolve8(ACCOUNTS_DIR, accountId) : null;
7184
7168
  const userTitles = loadUserTitles(accountDir);
7185
7169
  const rows = [];
@@ -7206,8 +7190,8 @@ app4.get("/", requireAdminSession, async (c) => {
7206
7190
  } catch {
7207
7191
  continue;
7208
7192
  }
7209
- const pid = pidsBySession.get(sessionId) ?? null;
7210
- const live = pid !== null;
7193
+ const live = liveSessions.has(sessionId);
7194
+ const pid = live ? liveSessions.get(sessionId) ?? null : null;
7211
7195
  const resolved = resolveTitle(body, sessionId, userTitles);
7212
7196
  titleSourceCounts[resolved.source] += 1;
7213
7197
  const metaPath = join7(projectDir, `${sessionId}.meta.json`);
@@ -7335,8 +7319,14 @@ function splitNewLines(buf, baseOffset) {
7335
7319
  };
7336
7320
  }
7337
7321
 
7338
- // server/routes/whatsapp-reader.ts
7322
+ // server/routes/admin/manager-client.ts
7339
7323
  var SESSION_ID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
7324
+ function managerBase3(tag) {
7325
+ const port2 = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag });
7326
+ return `http://127.0.0.1:${port2}`;
7327
+ }
7328
+
7329
+ // server/routes/whatsapp-reader.ts
7340
7330
  var app5 = new Hono();
7341
7331
  app5.get("/conversations", requireAdminSession, async (c) => {
7342
7332
  const cfg = claudeConfigDir();
@@ -8891,12 +8881,11 @@ app13.delete("/:id", requireAdminSession, async (c) => {
8891
8881
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
8892
8882
  const owned = await verifyConversationOwnership(sessionId, accountId);
8893
8883
  if (!owned) return c.json({ error: "Conversation not found" }, 404);
8894
- const managerPort = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "admin-conversation-delete" });
8895
- const managerBase5 = `http://127.0.0.1:${managerPort}`;
8884
+ const managerBaseUrl = managerBase3("admin-conversation-delete");
8896
8885
  const outcome = await cascadeAdminConversationDelete({
8897
8886
  sessionId,
8898
8887
  accountId,
8899
- managerBase: managerBase5
8888
+ managerBase: managerBaseUrl
8900
8889
  });
8901
8890
  if (outcome.ok) return c.json({ ok: true, claudeSessionIds: outcome.claudeSessionIds });
8902
8891
  if (outcome.reason === "pty-still-alive") {
@@ -9550,10 +9539,6 @@ async function refuseIfClaudeAuthDead(c, route, sessionId) {
9550
9539
  503
9551
9540
  );
9552
9541
  }
9553
- function managerBase3() {
9554
- const port2 = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "claude-session-manager:wrapper" });
9555
- return `http://127.0.0.1:${port2}`;
9556
- }
9557
9542
  var app14 = new Hono();
9558
9543
  async function performSpawnWithInitialMessage(args) {
9559
9544
  const ownerStart = Date.now();
@@ -9592,9 +9577,9 @@ async function performSpawnWithInitialMessage(args) {
9592
9577
  // unshapely values.
9593
9578
  conversationNodeId: args.conversationNodeId
9594
9579
  });
9595
- console.log(`${TAG21} forward-spawn-start managerBase=${managerBase3()} bytes=${upstreamPayload.length} hidden=${args.hidden} specialist=${args.specialist ?? "none"}`);
9580
+ console.log(`${TAG21} forward-spawn-start managerBase=${managerBase3("claude-session-manager:wrapper")} bytes=${upstreamPayload.length} hidden=${args.hidden} specialist=${args.specialist ?? "none"}`);
9596
9581
  const forwardStart = Date.now();
9597
- const upstream = await fetch(`${managerBase3()}/public-spawn`, {
9582
+ const upstream = await fetch(`${managerBase3("claude-session-manager:wrapper")}/public-spawn`, {
9598
9583
  method: "POST",
9599
9584
  headers: { "content-type": "application/json" },
9600
9585
  body: upstreamPayload
@@ -12563,8 +12548,7 @@ app20.post("/", requireAdminSession, async (c) => {
12563
12548
  );
12564
12549
  return c.json({ error: "AdminConversation node is missing sessionId" }, 500);
12565
12550
  }
12566
- const managerPort = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "graph-page-cascade" });
12567
- const managerBase5 = `http://127.0.0.1:${managerPort}`;
12551
+ const managerBaseUrl = managerBase3("graph-page-cascade");
12568
12552
  try {
12569
12553
  await session.close();
12570
12554
  } catch {
@@ -12572,7 +12556,7 @@ app20.post("/", requireAdminSession, async (c) => {
12572
12556
  const outcome = await cascadeAdminConversationDelete({
12573
12557
  sessionId,
12574
12558
  accountId,
12575
- managerBase: managerBase5
12559
+ managerBase: managerBaseUrl
12576
12560
  });
12577
12561
  const elapsed2 = Date.now() - started;
12578
12562
  const labelSummary2 = preflightLabels.join(",");
@@ -13126,106 +13110,50 @@ function isWithin(target, root) {
13126
13110
  var sidebar_artefacts_default = app24;
13127
13111
 
13128
13112
  // server/routes/admin/session-delete.ts
13129
- import { existsSync as existsSync18, readdirSync as readdirSync10, readFileSync as readFileSync17, unlinkSync as unlinkSync2 } from "fs";
13130
- import { join as join16, resolve as resolve19 } from "path";
13131
13113
  var app25 = new Hono();
13132
- var SESSION_ID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
13133
- var PID_FILE_RE2 = /^([0-9]+)\.json$/;
13134
- var SIGTERM_WAIT_MS = 2e3;
13135
- var SIGKILL_WAIT_MS = 1e3;
13136
- var POLL_INTERVAL_MS = 50;
13137
- function findPidForSession(configDir2, sessionId) {
13138
- const sessionsDir = join16(configDir2, "sessions");
13139
- let entries;
13114
+ app25.post("/", requireAdminSession, async (c) => {
13115
+ let body;
13140
13116
  try {
13141
- entries = readdirSync10(sessionsDir, { withFileTypes: true });
13117
+ body = await c.req.json();
13142
13118
  } catch {
13143
- return null;
13119
+ return c.json({ error: "invalid JSON body" }, 400);
13144
13120
  }
13145
- for (const entry of entries) {
13146
- if (!entry.isFile()) continue;
13147
- const m = entry.name.match(PID_FILE_RE2);
13148
- if (!m) continue;
13149
- const pid = Number(m[1]);
13150
- if (!Number.isFinite(pid) || pid <= 0) continue;
13151
- let body;
13152
- try {
13153
- body = readFileSync17(join16(sessionsDir, entry.name), "utf8");
13154
- } catch {
13155
- continue;
13156
- }
13157
- let parsed;
13158
- try {
13159
- parsed = JSON.parse(body);
13160
- } catch {
13161
- continue;
13162
- }
13163
- if (!parsed || typeof parsed !== "object") continue;
13164
- if (parsed.sessionId === sessionId) return pid;
13121
+ const sessionId = typeof body.sessionId === "string" ? body.sessionId : "";
13122
+ if (!SESSION_ID_RE2.test(sessionId)) {
13123
+ return c.json({ error: "sessionId must be a v4 UUID" }, 400);
13165
13124
  }
13166
- return null;
13167
- }
13168
- function isPidAlive(pid) {
13125
+ const base = managerBase3("session-delete:wrapper");
13169
13126
  try {
13170
- process.kill(pid, 0);
13171
- return true;
13127
+ const stop = await fetch(`${base}/${sessionId}/stop`, { method: "POST" });
13128
+ if (stop.status !== 204 && stop.status !== 200 && stop.status !== 404) {
13129
+ console.error(`[session-delete] sessionId=${sessionId} stop-status=${stop.status}`);
13130
+ return c.json({ error: `stop-failed-${stop.status}` }, 502);
13131
+ }
13172
13132
  } catch (err) {
13173
- const code = err.code;
13174
- if (code === "ESRCH") return false;
13175
- return true;
13133
+ console.error(`[session-delete] sessionId=${sessionId} stop-unreachable err=${err instanceof Error ? err.message : String(err)}`);
13134
+ return c.json({ error: "manager-unreachable" }, 502);
13176
13135
  }
13177
- }
13178
- function sleep2(ms) {
13179
- return new Promise((resolve28) => setTimeout(resolve28, ms));
13180
- }
13181
- function sendSignal(pid, signal) {
13136
+ let del;
13182
13137
  try {
13183
- process.kill(pid, signal);
13184
- return true;
13138
+ del = await fetch(`${base}/${sessionId}`, { method: "DELETE" });
13185
13139
  } catch (err) {
13186
- const code = err.code;
13187
- if (code === "ESRCH") return true;
13188
- return false;
13189
- }
13190
- }
13191
- async function killAndWait(pid) {
13192
- const startedAt = Date.now();
13193
- let escalated = false;
13194
- const termSent = sendSignal(pid, "SIGTERM");
13195
- const termDeadline = Date.now() + SIGTERM_WAIT_MS;
13196
- while (Date.now() < termDeadline) {
13197
- if (!isPidAlive(pid)) {
13198
- return {
13199
- pidKilled: termSent ? "true" : "false",
13200
- waitForExitMs: Date.now() - startedAt,
13201
- escalatedToSIGKILL: false,
13202
- exited: true
13203
- };
13204
- }
13205
- await sleep2(POLL_INTERVAL_MS);
13140
+ console.error(`[session-delete] sessionId=${sessionId} delete-unreachable err=${err instanceof Error ? err.message : String(err)}`);
13141
+ return c.json({ error: "manager-unreachable" }, 502);
13206
13142
  }
13207
- escalated = true;
13208
- sendSignal(pid, "SIGKILL");
13209
- const killDeadline = Date.now() + SIGKILL_WAIT_MS;
13210
- while (Date.now() < killDeadline) {
13211
- if (!isPidAlive(pid)) {
13212
- return {
13213
- pidKilled: "true",
13214
- waitForExitMs: Date.now() - startedAt,
13215
- escalatedToSIGKILL: true,
13216
- exited: true
13217
- };
13218
- }
13219
- await sleep2(POLL_INTERVAL_MS);
13143
+ if (del.status === 204) {
13144
+ console.log(`[session-delete] sessionId=${sessionId} deleted`);
13145
+ return c.json({ deleted: true });
13220
13146
  }
13221
- return {
13222
- pidKilled: "false",
13223
- waitForExitMs: Date.now() - startedAt,
13224
- escalatedToSIGKILL: escalated,
13225
- exited: false
13226
- };
13227
- }
13228
- app25.post("/", requireAdminSession, async (c) => {
13147
+ if (del.status === 404) return c.json({ deleted: false, error: "no-transcript" }, 404);
13148
+ if (del.status === 409) return c.json({ deleted: false, error: "pty-still-alive" }, 409);
13149
+ console.error(`[session-delete] sessionId=${sessionId} delete-status=${del.status}`);
13150
+ return c.json({ error: `manager-status-${del.status}` }, 502);
13151
+ });
13152
+ var session_delete_default = app25;
13153
+
13154
+ // server/routes/admin/session-stop.ts
13155
+ var app26 = new Hono();
13156
+ app26.post("/", requireAdminSession, async (c) => {
13229
13157
  let body;
13230
13158
  try {
13231
13159
  body = await c.req.json();
@@ -13233,91 +13161,28 @@ app25.post("/", requireAdminSession, async (c) => {
13233
13161
  return c.json({ error: "invalid JSON body" }, 400);
13234
13162
  }
13235
13163
  const sessionId = typeof body.sessionId === "string" ? body.sessionId : "";
13236
- const projectDir = typeof body.projectDir === "string" ? body.projectDir : "";
13237
- if (!SESSION_ID_RE3.test(sessionId)) {
13164
+ if (!SESSION_ID_RE2.test(sessionId)) {
13238
13165
  return c.json({ error: "sessionId must be a v4 UUID" }, 400);
13239
13166
  }
13240
- if (!projectDir) {
13241
- return c.json({ error: "projectDir is required" }, 400);
13242
- }
13243
- const configDir2 = process.env.CLAUDE_CONFIG_DIR;
13244
- if (!configDir2) {
13245
- return c.json({ error: "CLAUDE_CONFIG_DIR not set" }, 500);
13246
- }
13247
- const projectsRoot = resolve19(join16(configDir2, "projects")) + "/";
13248
- const resolvedProject = resolve19(projectDir) + "/";
13249
- if (!resolvedProject.startsWith(projectsRoot)) {
13250
- console.error(`[sessions-delete] reject reason=projectDir-outside-tree projectDir=${projectDir}`);
13251
- return c.json({ error: "projectDir is not under CLAUDE_CONFIG_DIR/projects/" }, 400);
13252
- }
13253
- const jsonlPath = join16(projectDir, `${sessionId}.jsonl`);
13254
- const sidecarPath = join16(projectDir, `${sessionId}.meta.json`);
13255
- const pid = findPidForSession(configDir2, sessionId);
13256
- let pidKilled = "absent";
13257
- let waitForExitMs = 0;
13258
- let escalatedToSIGKILL = false;
13259
- if (pid !== null) {
13260
- const r = await killAndWait(pid);
13261
- pidKilled = r.pidKilled;
13262
- waitForExitMs = r.waitForExitMs;
13263
- escalatedToSIGKILL = r.escalatedToSIGKILL;
13264
- if (!r.exited) {
13265
- console.error(
13266
- `[sessions-delete] kill-failed sessionId=${sessionId} pid=${pid} waitForExit=${waitForExitMs} escalatedToSIGKILL=${escalatedToSIGKILL}`
13267
- );
13268
- return c.json(
13269
- { error: "kill-failed", pid, waitForExitMs, escalatedToSIGKILL },
13270
- 500
13271
- );
13272
- }
13273
- }
13274
- let deleted = false;
13167
+ let res;
13275
13168
  try {
13276
- if (existsSync18(jsonlPath)) {
13277
- unlinkSync2(jsonlPath);
13278
- deleted = true;
13279
- }
13169
+ res = await fetch(`${managerBase3("session-stop:wrapper")}/${sessionId}/stop`, { method: "POST" });
13280
13170
  } catch (err) {
13281
- const msg = err instanceof Error ? err.message : String(err);
13282
- console.error(`[sessions-delete] unlink-failed path=${jsonlPath} err=${msg}`);
13283
- console.log(
13284
- `[sessions-delete] sessionId=${sessionId} pidKilled=${pidKilled} jsonlPath=${jsonlPath} deleted=false waitForExit=${waitForExitMs} escalatedToSIGKILL=${escalatedToSIGKILL}`
13285
- );
13286
- return c.json({ error: `unlink failed: ${msg}` }, 500);
13171
+ console.error(`[session-stop] sessionId=${sessionId} manager-unreachable err=${err instanceof Error ? err.message : String(err)}`);
13172
+ return c.json({ error: "manager-unreachable" }, 502);
13287
13173
  }
13288
- try {
13289
- if (existsSync18(sidecarPath)) unlinkSync2(sidecarPath);
13290
- } catch {
13291
- }
13292
- if (pid !== null) {
13293
- try {
13294
- const pidFile = join16(configDir2, "sessions", `${pid}.json`);
13295
- if (existsSync18(pidFile)) unlinkSync2(pidFile);
13296
- } catch {
13297
- }
13298
- }
13299
- if (existsSync18(jsonlPath)) {
13300
- console.error(`[sessions-delete] resurrection jsonlPath=${jsonlPath} sessionId=${sessionId}`);
13301
- return c.json(
13302
- { error: "jsonl-resurrected", jsonlPath, pidKilled, waitForExitMs, escalatedToSIGKILL },
13303
- 500
13304
- );
13174
+ if (res.status === 204 || res.status === 200 || res.status === 404) {
13175
+ console.log(`[session-stop] sessionId=${sessionId} stopped manager-status=${res.status}`);
13176
+ return c.json({ stopped: true });
13305
13177
  }
13306
- console.log(
13307
- `[sessions-delete] sessionId=${sessionId} pidKilled=${pidKilled} jsonlPath=${jsonlPath} deleted=${deleted} waitForExit=${waitForExitMs} escalatedToSIGKILL=${escalatedToSIGKILL}`
13308
- );
13309
- return c.json({ deleted, pidKilled, jsonlPath, waitForExitMs, escalatedToSIGKILL });
13178
+ console.error(`[session-stop] sessionId=${sessionId} manager-status=${res.status}`);
13179
+ return c.json({ error: `manager-status-${res.status}` }, 502);
13310
13180
  });
13311
- var session_delete_default = app25;
13181
+ var session_stop_default = app26;
13312
13182
 
13313
13183
  // server/routes/admin/session-rc-spawn.ts
13314
- var app26 = new Hono();
13315
- function managerBase4() {
13316
- const port2 = process.env.CLAUDE_SESSION_MANAGER_PORT;
13317
- if (!port2) throw new Error("CLAUDE_SESSION_MANAGER_PORT is not set");
13318
- return `http://127.0.0.1:${port2}`;
13319
- }
13320
- app26.post("/", requireAdminSession, async (c) => {
13184
+ var app27 = new Hono();
13185
+ app27.post("/", requireAdminSession, async (c) => {
13321
13186
  let body;
13322
13187
  try {
13323
13188
  body = await c.req.json();
@@ -13329,7 +13194,7 @@ app26.post("/", requireAdminSession, async (c) => {
13329
13194
  if (typeof body.name === "string" && body.name.length > 0) payload.name = body.name;
13330
13195
  let res;
13331
13196
  try {
13332
- res = await fetch(`${managerBase4()}/rc-spawn`, {
13197
+ res = await fetch(`${managerBase3("session-rc-spawn:wrapper")}/rc-spawn`, {
13333
13198
  method: "POST",
13334
13199
  headers: { "content-type": "application/json" },
13335
13200
  body: JSON.stringify(payload)
@@ -13351,7 +13216,7 @@ app26.post("/", requireAdminSession, async (c) => {
13351
13216
  }
13352
13217
  return c.json(parsed ?? {});
13353
13218
  });
13354
- var session_rc_spawn_default = app26;
13219
+ var session_rc_spawn_default = app27;
13355
13220
 
13356
13221
  // server/routes/admin/system-stats.ts
13357
13222
  import { readFile as readFile5 } from "fs/promises";
@@ -13448,8 +13313,8 @@ async function sample() {
13448
13313
  if (process.platform === "linux") return sampleLinux();
13449
13314
  return sampleOsFallback();
13450
13315
  }
13451
- var app27 = new Hono();
13452
- app27.get("/", async (c) => {
13316
+ var app28 = new Hono();
13317
+ app28.get("/", async (c) => {
13453
13318
  const started = Date.now();
13454
13319
  if (!inflight) {
13455
13320
  inflight = sample().finally(() => {
@@ -13472,27 +13337,27 @@ app27.get("/", async (c) => {
13472
13337
  return c.json({ degraded: true, reason, sampledAtMs: Date.now() });
13473
13338
  }
13474
13339
  });
13475
- var system_stats_default = app27;
13340
+ var system_stats_default = app28;
13476
13341
 
13477
13342
  // server/routes/admin/health.ts
13478
- import { existsSync as existsSync19, readFileSync as readFileSync18 } from "fs";
13479
- import { resolve as resolve20, join as join17 } from "path";
13480
- var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
13343
+ import { existsSync as existsSync18, readFileSync as readFileSync17 } from "fs";
13344
+ import { resolve as resolve19, join as join16 } from "path";
13345
+ var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve19(process.cwd(), "..");
13481
13346
  var brandHostname = "maxy";
13482
- var brandJsonPath = join17(PLATFORM_ROOT6, "config", "brand.json");
13483
- if (existsSync19(brandJsonPath)) {
13347
+ var brandJsonPath = join16(PLATFORM_ROOT6, "config", "brand.json");
13348
+ if (existsSync18(brandJsonPath)) {
13484
13349
  try {
13485
- const brand = JSON.parse(readFileSync18(brandJsonPath, "utf-8"));
13350
+ const brand = JSON.parse(readFileSync17(brandJsonPath, "utf-8"));
13486
13351
  if (brand.hostname) brandHostname = brand.hostname;
13487
13352
  } catch {
13488
13353
  }
13489
13354
  }
13490
- var VERSION_FILE = resolve20(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
13355
+ var VERSION_FILE = resolve19(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
13491
13356
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
13492
13357
  var PROBE_TIMEOUT_MS = 1e3;
13493
13358
  function readVersion() {
13494
- if (!existsSync19(VERSION_FILE)) return "unknown";
13495
- return readFileSync18(VERSION_FILE, "utf-8").trim() || "unknown";
13359
+ if (!existsSync18(VERSION_FILE)) return "unknown";
13360
+ return readFileSync17(VERSION_FILE, "utf-8").trim() || "unknown";
13496
13361
  }
13497
13362
  async function probeConversationDb() {
13498
13363
  let session;
@@ -13517,8 +13382,8 @@ async function probeConversationDb() {
13517
13382
  });
13518
13383
  }
13519
13384
  }
13520
- var app28 = new Hono();
13521
- app28.get("/", async (c) => {
13385
+ var app29 = new Hono();
13386
+ app29.get("/", async (c) => {
13522
13387
  const version = readVersion();
13523
13388
  const probe = await probeConversationDb();
13524
13389
  const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
@@ -13540,7 +13405,7 @@ app28.get("/", async (c) => {
13540
13405
  uptimeMs
13541
13406
  });
13542
13407
  });
13543
- var health_default2 = app28;
13408
+ var health_default2 = app29;
13544
13409
 
13545
13410
  // server/routes/admin/linkedin-ingest.ts
13546
13411
  import { randomUUID as randomUUID9 } from "crypto";
@@ -13642,8 +13507,8 @@ function buildInitialMessage(env) {
13642
13507
  }
13643
13508
  return header;
13644
13509
  }
13645
- var app29 = new Hono();
13646
- app29.post("/", requireAdminSession, async (c) => {
13510
+ var app30 = new Hono();
13511
+ app30.post("/", requireAdminSession, async (c) => {
13647
13512
  let body;
13648
13513
  try {
13649
13514
  body = await c.req.json();
@@ -13688,7 +13553,7 @@ app29.post("/", requireAdminSession, async (c) => {
13688
13553
  );
13689
13554
  return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: spawned.sessionId }, 202);
13690
13555
  });
13691
- var linkedin_ingest_default = app29;
13556
+ var linkedin_ingest_default = app30;
13692
13557
 
13693
13558
  // server/routes/admin/post-turn-context.ts
13694
13559
  import neo4j2 from "neo4j-driver";
@@ -13730,8 +13595,8 @@ function pruneProperties(raw) {
13730
13595
  }
13731
13596
  return out;
13732
13597
  }
13733
- var app30 = new Hono();
13734
- app30.get("/", async (c) => {
13598
+ var app31 = new Hono();
13599
+ app31.get("/", async (c) => {
13735
13600
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
13736
13601
  if (!isLoopbackAddr2(remoteAddr)) {
13737
13602
  console.error(`${TAG24} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -13791,7 +13656,7 @@ app30.get("/", async (c) => {
13791
13656
  await session.close();
13792
13657
  }
13793
13658
  });
13794
- var post_turn_context_default = app30;
13659
+ var post_turn_context_default = app31;
13795
13660
 
13796
13661
  // server/routes/admin/public-session-context.ts
13797
13662
  import neo4j3 from "neo4j-driver";
@@ -13833,8 +13698,8 @@ function pruneProperties2(raw) {
13833
13698
  }
13834
13699
  return out;
13835
13700
  }
13836
- var app31 = new Hono();
13837
- app31.get("/", async (c) => {
13701
+ var app32 = new Hono();
13702
+ app32.get("/", async (c) => {
13838
13703
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
13839
13704
  if (!isLoopbackAddr3(remoteAddr)) {
13840
13705
  console.error(`${TAG25} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -13893,15 +13758,15 @@ app31.get("/", async (c) => {
13893
13758
  await session.close();
13894
13759
  }
13895
13760
  });
13896
- var public_session_context_default = app31;
13761
+ var public_session_context_default = app32;
13897
13762
 
13898
13763
  // server/routes/admin/public-session-exit.ts
13899
13764
  var TAG26 = "[public-session-exit-route]";
13900
13765
  function isLoopbackAddr4(addr) {
13901
13766
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
13902
13767
  }
13903
- var app32 = new Hono();
13904
- app32.post("/", async (c) => {
13768
+ var app33 = new Hono();
13769
+ app33.post("/", async (c) => {
13905
13770
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
13906
13771
  if (!isLoopbackAddr4(remoteAddr)) {
13907
13772
  console.error(`${TAG26} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -13928,15 +13793,15 @@ app32.post("/", async (c) => {
13928
13793
  handlePublicSessionExit(sessionId);
13929
13794
  return c.json({ ok: true });
13930
13795
  });
13931
- var public_session_exit_default = app32;
13796
+ var public_session_exit_default = app33;
13932
13797
 
13933
13798
  // server/routes/admin/access-session-evict.ts
13934
13799
  var TAG27 = "[access-session-evict]";
13935
13800
  function isLoopbackAddr5(addr) {
13936
13801
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
13937
13802
  }
13938
- var app33 = new Hono();
13939
- app33.post("/", async (c) => {
13803
+ var app34 = new Hono();
13804
+ app34.post("/", async (c) => {
13940
13805
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
13941
13806
  if (!isLoopbackAddr5(remoteAddr)) {
13942
13807
  console.error(`${TAG27} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -13964,11 +13829,11 @@ app33.post("/", async (c) => {
13964
13829
  console.log(`${TAG27} grantId=${grantId} dropped=${dropped}`);
13965
13830
  return c.json({ ok: true, dropped });
13966
13831
  });
13967
- var access_session_evict_default = app33;
13832
+ var access_session_evict_default = app34;
13968
13833
 
13969
13834
  // server/routes/admin/browser.ts
13970
- var app34 = new Hono();
13971
- app34.post("/launch", requireAdminSession, async (c) => {
13835
+ var app35 = new Hono();
13836
+ app35.post("/launch", requireAdminSession, async (c) => {
13972
13837
  try {
13973
13838
  const transport = resolveBrowserTransport(c.req.raw, c.env?.incoming?.socket?.remoteAddress);
13974
13839
  console.error(`[admin/browser/launch] op=request transport=${transport}`);
@@ -13996,52 +13861,53 @@ app34.post("/launch", requireAdminSession, async (c) => {
13996
13861
  );
13997
13862
  }
13998
13863
  });
13999
- var browser_default = app34;
13864
+ var browser_default = app35;
14000
13865
 
14001
13866
  // server/routes/admin/index.ts
14002
- var app35 = new Hono();
14003
- app35.route("/session", session_default);
14004
- app35.route("/logs", logs_default);
14005
- app35.route("/claude-info", claude_info_default);
14006
- app35.route("/attachment", attachment_default);
14007
- app35.route("/agents", agents_default);
14008
- app35.route("/sessions", sessions_default);
14009
- app35.route("/claude-sessions", claude_sessions_default);
14010
- app35.route("/log-ingest", log_ingest_default);
14011
- app35.route("/events", events_default);
14012
- app35.route("/files", files_default);
14013
- app35.route("/graph-search", graph_search_default);
14014
- app35.route("/graph-subgraph", graph_subgraph_default);
14015
- app35.route("/graph-delete", graph_delete_default);
14016
- app35.route("/graph-restore", graph_restore_default);
14017
- app35.route("/graph-labels-in-graph", graph_labels_in_graph_default);
14018
- app35.route("/graph-default-view", graph_default_view_default);
14019
- app35.route("/sidebar-artefacts", sidebar_artefacts_default);
14020
- app35.route("/sidebar-sessions", sidebar_sessions_default);
14021
- app35.route("/session-delete", session_delete_default);
14022
- app35.route("/browser", browser_default);
14023
- app35.route("/session-rc-spawn", session_rc_spawn_default);
14024
- app35.route("/system-stats", system_stats_default);
14025
- app35.route("/health-brand", health_default2);
14026
- app35.route("/linkedin-ingest", linkedin_ingest_default);
14027
- app35.route("/post-turn-context", post_turn_context_default);
14028
- app35.route("/public-session-context", public_session_context_default);
14029
- app35.route("/public-session-exit", public_session_exit_default);
14030
- app35.route("/access-session-evict", access_session_evict_default);
14031
- var admin_default = app35;
13867
+ var app36 = new Hono();
13868
+ app36.route("/session", session_default);
13869
+ app36.route("/logs", logs_default);
13870
+ app36.route("/claude-info", claude_info_default);
13871
+ app36.route("/attachment", attachment_default);
13872
+ app36.route("/agents", agents_default);
13873
+ app36.route("/sessions", sessions_default);
13874
+ app36.route("/claude-sessions", claude_sessions_default);
13875
+ app36.route("/log-ingest", log_ingest_default);
13876
+ app36.route("/events", events_default);
13877
+ app36.route("/files", files_default);
13878
+ app36.route("/graph-search", graph_search_default);
13879
+ app36.route("/graph-subgraph", graph_subgraph_default);
13880
+ app36.route("/graph-delete", graph_delete_default);
13881
+ app36.route("/graph-restore", graph_restore_default);
13882
+ app36.route("/graph-labels-in-graph", graph_labels_in_graph_default);
13883
+ app36.route("/graph-default-view", graph_default_view_default);
13884
+ app36.route("/sidebar-artefacts", sidebar_artefacts_default);
13885
+ app36.route("/sidebar-sessions", sidebar_sessions_default);
13886
+ app36.route("/session-delete", session_delete_default);
13887
+ app36.route("/session-stop", session_stop_default);
13888
+ app36.route("/browser", browser_default);
13889
+ app36.route("/session-rc-spawn", session_rc_spawn_default);
13890
+ app36.route("/system-stats", system_stats_default);
13891
+ app36.route("/health-brand", health_default2);
13892
+ app36.route("/linkedin-ingest", linkedin_ingest_default);
13893
+ app36.route("/post-turn-context", post_turn_context_default);
13894
+ app36.route("/public-session-context", public_session_context_default);
13895
+ app36.route("/public-session-exit", public_session_exit_default);
13896
+ app36.route("/access-session-evict", access_session_evict_default);
13897
+ var admin_default = app36;
14032
13898
 
14033
13899
  // app/lib/access-gate.ts
14034
13900
  import neo4j4 from "neo4j-driver";
14035
- import { readFileSync as readFileSync19 } from "fs";
14036
- import { resolve as resolve21 } from "path";
13901
+ import { readFileSync as readFileSync18 } from "fs";
13902
+ import { resolve as resolve20 } from "path";
14037
13903
  import { randomUUID as randomUUID10 } from "crypto";
14038
- var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve21(process.cwd(), "..");
13904
+ var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
14039
13905
  var driver = null;
14040
13906
  function readPassword() {
14041
13907
  if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
14042
- const passwordFile = resolve21(PLATFORM_ROOT7, "config/.neo4j-password");
13908
+ const passwordFile = resolve20(PLATFORM_ROOT7, "config/.neo4j-password");
14043
13909
  try {
14044
- return readFileSync19(passwordFile, "utf-8").trim();
13910
+ return readFileSync18(passwordFile, "utf-8").trim();
14045
13911
  } catch {
14046
13912
  throw new Error(
14047
13913
  `Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`
@@ -14242,8 +14108,8 @@ async function generateNewMagicToken(grantId) {
14242
14108
  var TAG28 = "[access-verify]";
14243
14109
  var MINT_TAG = "[access-session-mint]";
14244
14110
  var COOKIE_NAME = "__access_session";
14245
- var app36 = new Hono();
14246
- app36.post("/", async (c) => {
14111
+ var app37 = new Hono();
14112
+ app37.post("/", async (c) => {
14247
14113
  const ip = c.var.clientIp || "unknown";
14248
14114
  let body;
14249
14115
  try {
@@ -14325,13 +14191,13 @@ app36.post("/", async (c) => {
14325
14191
  displayName: grant.displayName
14326
14192
  });
14327
14193
  });
14328
- var verify_token_default = app36;
14194
+ var verify_token_default = app37;
14329
14195
 
14330
14196
  // app/lib/access-email.ts
14331
14197
  import { spawn as spawn2 } from "child_process";
14332
- import { resolve as resolve22 } from "path";
14333
- var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT ?? resolve22(process.cwd(), "..");
14334
- var SEND_SCRIPT = resolve22(
14198
+ import { resolve as resolve21 } from "path";
14199
+ var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT ?? resolve21(process.cwd(), "..");
14200
+ var SEND_SCRIPT = resolve21(
14335
14201
  PLATFORM_ROOT8,
14336
14202
  "plugins",
14337
14203
  "email",
@@ -14388,9 +14254,9 @@ async function sendMagicLinkEmail(payload) {
14388
14254
 
14389
14255
  // server/routes/access/request-magic-link.ts
14390
14256
  var TAG29 = "[access-request-link]";
14391
- var app37 = new Hono();
14257
+ var app38 = new Hono();
14392
14258
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
14393
- app37.post("/", async (c) => {
14259
+ app38.post("/", async (c) => {
14394
14260
  let body;
14395
14261
  try {
14396
14262
  body = await c.req.json();
@@ -14464,17 +14330,17 @@ app37.post("/", async (c) => {
14464
14330
  );
14465
14331
  return c.json({ message: VISITOR_MESSAGE }, 200);
14466
14332
  });
14467
- var request_magic_link_default = app37;
14333
+ var request_magic_link_default = app38;
14468
14334
 
14469
14335
  // server/routes/access/index.ts
14470
- var app38 = new Hono();
14471
- app38.route("/verify-token", verify_token_default);
14472
- app38.route("/request-magic-link", request_magic_link_default);
14473
- var access_default = app38;
14336
+ var app39 = new Hono();
14337
+ app39.route("/verify-token", verify_token_default);
14338
+ app39.route("/request-magic-link", request_magic_link_default);
14339
+ var access_default = app39;
14474
14340
 
14475
14341
  // server/routes/sites.ts
14476
- import { existsSync as existsSync20, readFileSync as readFileSync20, realpathSync as realpathSync5, statSync as statSync9 } from "fs";
14477
- import { resolve as resolve23 } from "path";
14342
+ import { existsSync as existsSync19, readFileSync as readFileSync19, realpathSync as realpathSync5, statSync as statSync9 } from "fs";
14343
+ import { resolve as resolve22 } from "path";
14478
14344
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
14479
14345
  var MIME = {
14480
14346
  ".html": "text/html; charset=utf-8",
@@ -14505,8 +14371,8 @@ function getExt(p) {
14505
14371
  if (idx < p.lastIndexOf("/")) return "";
14506
14372
  return p.slice(idx).toLowerCase();
14507
14373
  }
14508
- var app39 = new Hono();
14509
- app39.get("/:rel{.*}", (c) => {
14374
+ var app40 = new Hono();
14375
+ app40.get("/:rel{.*}", (c) => {
14510
14376
  const reqPath = c.req.path;
14511
14377
  const rawRel = c.req.param("rel") ?? "";
14512
14378
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -14531,15 +14397,15 @@ app39.get("/:rel{.*}", (c) => {
14531
14397
  }
14532
14398
  segments.push(seg);
14533
14399
  }
14534
- const rootDir = resolve23(account.accountDir, "sites");
14535
- let filePath = segments.length === 0 ? rootDir : resolve23(rootDir, ...segments);
14400
+ const rootDir = resolve22(account.accountDir, "sites");
14401
+ let filePath = segments.length === 0 ? rootDir : resolve22(rootDir, ...segments);
14536
14402
  if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
14537
14403
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
14538
14404
  return c.text("Forbidden", 403);
14539
14405
  }
14540
14406
  let stat7;
14541
14407
  try {
14542
- stat7 = existsSync20(filePath) ? statSync9(filePath) : null;
14408
+ stat7 = existsSync19(filePath) ? statSync9(filePath) : null;
14543
14409
  } catch {
14544
14410
  stat7 = null;
14545
14411
  }
@@ -14552,13 +14418,13 @@ app39.get("/:rel{.*}", (c) => {
14552
14418
  return c.redirect(target, 301);
14553
14419
  }
14554
14420
  if (stat7?.isDirectory()) {
14555
- filePath = resolve23(filePath, "index.html");
14421
+ filePath = resolve22(filePath, "index.html");
14556
14422
  }
14557
14423
  if (!filePath.startsWith(rootDir + "/")) {
14558
14424
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
14559
14425
  return c.text("Forbidden", 403);
14560
14426
  }
14561
- if (!existsSync20(filePath)) {
14427
+ if (!existsSync19(filePath)) {
14562
14428
  console.error(`[sites] not-found path=${reqPath} status=404`);
14563
14429
  return c.text("Not found", 404);
14564
14430
  }
@@ -14577,7 +14443,7 @@ app39.get("/:rel{.*}", (c) => {
14577
14443
  }
14578
14444
  let body;
14579
14445
  try {
14580
- body = readFileSync20(realPath);
14446
+ body = readFileSync19(realPath);
14581
14447
  } catch (err) {
14582
14448
  const code = err?.code;
14583
14449
  if (code === "EISDIR") {
@@ -14609,11 +14475,11 @@ app39.get("/:rel{.*}", (c) => {
14609
14475
  "X-Content-Type-Options": "nosniff"
14610
14476
  });
14611
14477
  });
14612
- var sites_default = app39;
14478
+ var sites_default = app40;
14613
14479
 
14614
14480
  // app/lib/visitor-token.ts
14615
14481
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
14616
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync21, writeFileSync as writeFileSync7 } from "fs";
14482
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync20, writeFileSync as writeFileSync7 } from "fs";
14617
14483
  import { dirname as dirname5 } from "path";
14618
14484
  var TOKEN_PREFIX = "v1.";
14619
14485
  var SECRET_BYTES = 32;
@@ -14622,7 +14488,7 @@ var cachedSecret = null;
14622
14488
  function getSecret() {
14623
14489
  if (cachedSecret) return cachedSecret;
14624
14490
  try {
14625
- const hex2 = readFileSync21(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
14491
+ const hex2 = readFileSync20(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
14626
14492
  if (hex2.length === SECRET_BYTES * 2) {
14627
14493
  cachedSecret = Buffer.from(hex2, "hex");
14628
14494
  return cachedSecret;
@@ -14636,7 +14502,7 @@ function getSecret() {
14636
14502
  console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
14637
14503
  } catch {
14638
14504
  }
14639
- const hex = readFileSync21(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
14505
+ const hex = readFileSync20(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
14640
14506
  cachedSecret = Buffer.from(hex, "hex");
14641
14507
  return cachedSecret;
14642
14508
  }
@@ -14689,8 +14555,8 @@ var VISITOR_COOKIE_NAME = "mxy_v";
14689
14555
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
14690
14556
 
14691
14557
  // app/lib/brand-config.ts
14692
- import { existsSync as existsSync21, readFileSync as readFileSync22 } from "fs";
14693
- import { join as join18 } from "path";
14558
+ import { existsSync as existsSync20, readFileSync as readFileSync21 } from "fs";
14559
+ import { join as join17 } from "path";
14694
14560
  var cached2 = null;
14695
14561
  var cachedAttempted = false;
14696
14562
  function readBrandConfig() {
@@ -14698,10 +14564,10 @@ function readBrandConfig() {
14698
14564
  cachedAttempted = true;
14699
14565
  const platformRoot2 = process.env.MAXY_PLATFORM_ROOT;
14700
14566
  if (!platformRoot2) return null;
14701
- const brandPath = join18(platformRoot2, "config", "brand.json");
14702
- if (!existsSync21(brandPath)) return null;
14567
+ const brandPath = join17(platformRoot2, "config", "brand.json");
14568
+ if (!existsSync20(brandPath)) return null;
14703
14569
  try {
14704
- cached2 = JSON.parse(readFileSync22(brandPath, "utf-8"));
14570
+ cached2 = JSON.parse(readFileSync21(brandPath, "utf-8"));
14705
14571
  return cached2;
14706
14572
  } catch {
14707
14573
  return null;
@@ -14709,7 +14575,7 @@ function readBrandConfig() {
14709
14575
  }
14710
14576
 
14711
14577
  // server/routes/visitor-consent.ts
14712
- var app40 = new Hono();
14578
+ var app41 = new Hono();
14713
14579
  var CONSENT_COOKIE_NAME = "mxy_consent";
14714
14580
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
14715
14581
  var DEFAULT_CONSENT_COPY = {
@@ -14754,17 +14620,17 @@ function siteSlugFromReferer(referer) {
14754
14620
  return "";
14755
14621
  }
14756
14622
  }
14757
- app40.options("/consent", (c) => {
14623
+ app41.options("/consent", (c) => {
14758
14624
  const origin = getOrigin(c);
14759
14625
  setCorsHeaders(c, origin);
14760
14626
  return c.body(null, 204);
14761
14627
  });
14762
- app40.options("/brand-config", (c) => {
14628
+ app41.options("/brand-config", (c) => {
14763
14629
  const origin = getOrigin(c);
14764
14630
  setCorsHeaders(c, origin);
14765
14631
  return c.body(null, 204);
14766
14632
  });
14767
- app40.post("/consent", async (c) => {
14633
+ app41.post("/consent", async (c) => {
14768
14634
  const origin = getOrigin(c);
14769
14635
  setCorsHeaders(c, origin);
14770
14636
  let raw;
@@ -14804,7 +14670,7 @@ app40.post("/consent", async (c) => {
14804
14670
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
14805
14671
  return c.body(null, 204);
14806
14672
  });
14807
- app40.get("/brand-config", (c) => {
14673
+ app41.get("/brand-config", (c) => {
14808
14674
  const origin = getOrigin(c);
14809
14675
  setCorsHeaders(c, origin);
14810
14676
  const brand = readBrandConfig();
@@ -14814,7 +14680,7 @@ app40.get("/brand-config", (c) => {
14814
14680
  c.header("Cache-Control", "public, max-age=300");
14815
14681
  return c.json({ consent: { copy, palette } });
14816
14682
  });
14817
- var visitor_consent_default = app40;
14683
+ var visitor_consent_default = app41;
14818
14684
 
14819
14685
  // server/routes/listings.ts
14820
14686
  function getCookie(headerValue, name) {
@@ -14841,8 +14707,8 @@ function appendConsentParams(pageUrl, token) {
14841
14707
  }
14842
14708
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
14843
14709
  var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
14844
- var app41 = new Hono();
14845
- app41.get("/:slug/click", async (c) => {
14710
+ var app42 = new Hono();
14711
+ app42.get("/:slug/click", async (c) => {
14846
14712
  const slug = c.req.param("slug") ?? "";
14847
14713
  const rawSession = c.req.query("session") ?? "";
14848
14714
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -14906,10 +14772,10 @@ app41.get("/:slug/click", async (c) => {
14906
14772
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
14907
14773
  return c.redirect(redirectUrl, 302);
14908
14774
  });
14909
- var listings_default = app41;
14775
+ var listings_default = app42;
14910
14776
 
14911
14777
  // server/routes/visitor-event.ts
14912
- var app42 = new Hono();
14778
+ var app43 = new Hono();
14913
14779
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
14914
14780
  var buckets = /* @__PURE__ */ new Map();
14915
14781
  var RATE_LIMIT = 60;
@@ -14976,12 +14842,12 @@ function originAllowed(origin, allowlist) {
14976
14842
  return false;
14977
14843
  }
14978
14844
  }
14979
- app42.options("/event", (c) => {
14845
+ app43.options("/event", (c) => {
14980
14846
  const origin = getOrigin2(c);
14981
14847
  setCorsHeaders2(c, origin);
14982
14848
  return c.body(null, 204);
14983
14849
  });
14984
- app42.post("/event", async (c) => {
14850
+ app43.post("/event", async (c) => {
14985
14851
  const origin = getOrigin2(c);
14986
14852
  setCorsHeaders2(c, origin);
14987
14853
  const ua = c.req.header("user-agent") ?? "";
@@ -15186,17 +15052,17 @@ async function writeEvent(opts) {
15186
15052
  );
15187
15053
  }
15188
15054
  }
15189
- var visitor_event_default = app42;
15055
+ var visitor_event_default = app43;
15190
15056
 
15191
15057
  // server/routes/session.ts
15192
- import { resolve as resolve24 } from "path";
15193
- import { existsSync as existsSync22, writeFileSync as writeFileSync8, mkdirSync as mkdirSync5 } from "fs";
15058
+ import { resolve as resolve23 } from "path";
15059
+ import { existsSync as existsSync21, writeFileSync as writeFileSync8, mkdirSync as mkdirSync5 } from "fs";
15194
15060
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
15195
15061
  function writeBrandingCache(accountId, agentSlug, branding) {
15196
15062
  try {
15197
- const cacheDir = resolve24(MAXY_DIR, "branding-cache", accountId);
15063
+ const cacheDir = resolve23(MAXY_DIR, "branding-cache", accountId);
15198
15064
  mkdirSync5(cacheDir, { recursive: true });
15199
- writeFileSync8(resolve24(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
15065
+ writeFileSync8(resolve23(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
15200
15066
  } catch (err) {
15201
15067
  console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
15202
15068
  }
@@ -15232,8 +15098,8 @@ function withVisitorCookie(response, visitorId) {
15232
15098
  headers
15233
15099
  });
15234
15100
  }
15235
- var app43 = new Hono();
15236
- app43.post("/", async (c) => {
15101
+ var app44 = new Hono();
15102
+ app44.post("/", async (c) => {
15237
15103
  let body;
15238
15104
  try {
15239
15105
  body = await c.req.json();
@@ -15284,8 +15150,8 @@ app43.post("/", async (c) => {
15284
15150
  }
15285
15151
  let agentConfig = null;
15286
15152
  if (account) {
15287
- const agentDir = resolve24(account.accountDir, "agents", agentSlug);
15288
- if (!existsSync22(agentDir) || !existsSync22(resolve24(agentDir, "config.json"))) {
15153
+ const agentDir = resolve23(account.accountDir, "agents", agentSlug);
15154
+ if (!existsSync21(agentDir) || !existsSync21(resolve23(agentDir, "config.json"))) {
15289
15155
  return c.json({ error: "Agent not found" }, 404);
15290
15156
  }
15291
15157
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -15444,7 +15310,7 @@ app43.post("/", async (c) => {
15444
15310
  newVisitorId
15445
15311
  );
15446
15312
  });
15447
- var session_default2 = app43;
15313
+ var session_default2 = app44;
15448
15314
 
15449
15315
  // app/lib/graph-health.ts
15450
15316
  var import_dist4 = __toESM(require_dist3(), 1);
@@ -15565,7 +15431,7 @@ function startGraphHealthTimer() {
15565
15431
 
15566
15432
  // app/lib/file-watcher.ts
15567
15433
  import * as fsp2 from "fs/promises";
15568
- import { resolve as resolve25, sep as sep7 } from "path";
15434
+ import { resolve as resolve24, sep as sep7 } from "path";
15569
15435
  var ACCOUNT_UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
15570
15436
  var DEFAULT_COALESCE_MS = 500;
15571
15437
  var ROOTS = ["uploads", "accounts"];
@@ -15584,7 +15450,7 @@ async function startFileWatcher(opts = {}) {
15584
15450
  const dropFn = opts.drop ?? dropFileIndex;
15585
15451
  for (const r of ROOTS) {
15586
15452
  try {
15587
- await fsp2.mkdir(resolve25(dataRoot, r), { recursive: true });
15453
+ await fsp2.mkdir(resolve24(dataRoot, r), { recursive: true });
15588
15454
  } catch (err) {
15589
15455
  console.error(
15590
15456
  `[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
@@ -15605,7 +15471,7 @@ async function startFileWatcher(opts = {}) {
15605
15471
  timers.set(relativePath, t);
15606
15472
  }
15607
15473
  async function runHook(relativePath, accountId) {
15608
- const absolute = resolve25(dataRoot, relativePath);
15474
+ const absolute = resolve24(dataRoot, relativePath);
15609
15475
  let exists = false;
15610
15476
  try {
15611
15477
  const st = await fsp2.stat(absolute);
@@ -15629,7 +15495,7 @@ async function startFileWatcher(opts = {}) {
15629
15495
  }
15630
15496
  }
15631
15497
  async function watchRoot(rootName) {
15632
- const absRoot = resolve25(dataRoot, rootName);
15498
+ const absRoot = resolve24(dataRoot, rootName);
15633
15499
  try {
15634
15500
  const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
15635
15501
  for await (const event of iter) {
@@ -15666,11 +15532,6 @@ async function startFileWatcher(opts = {}) {
15666
15532
  return { stop };
15667
15533
  }
15668
15534
 
15669
- // app/lib/whatsapp/inbound/claude-bridge.ts
15670
- function startReaper2() {
15671
- startReaper();
15672
- }
15673
-
15674
15535
  // app/lib/whatsapp/gateway/inbound-hub.ts
15675
15536
  var InboundHub = class {
15676
15537
  senders = /* @__PURE__ */ new Map();
@@ -15939,8 +15800,8 @@ var streamSSE = (c, cb, onError) => {
15939
15800
 
15940
15801
  // app/lib/whatsapp/gateway/routes.ts
15941
15802
  function createWaChannelRoutes(deps) {
15942
- const app45 = new Hono();
15943
- app45.get("/wa-channel/inbound", (c) => {
15803
+ const app46 = new Hono();
15804
+ app46.get("/wa-channel/inbound", (c) => {
15944
15805
  const senderId = c.req.query("senderId");
15945
15806
  if (!senderId) return c.json({ error: "senderId required" }, 400);
15946
15807
  return streamSSE(c, async (stream2) => {
@@ -15958,7 +15819,7 @@ function createWaChannelRoutes(deps) {
15958
15819
  }
15959
15820
  });
15960
15821
  });
15961
- app45.post("/wa-channel/reply", async (c) => {
15822
+ app46.post("/wa-channel/reply", async (c) => {
15962
15823
  const body = await c.req.json().catch(() => null);
15963
15824
  const senderId = body?.senderId;
15964
15825
  const text = body?.text;
@@ -15977,7 +15838,7 @@ function createWaChannelRoutes(deps) {
15977
15838
  console.error(`[whatsapp-native] op=reply-dispatch senderId=${senderId} bytes=${bytes}`);
15978
15839
  return c.json({ ok: true });
15979
15840
  });
15980
- app45.post("/wa-channel/ready", async (c) => {
15841
+ app46.post("/wa-channel/ready", async (c) => {
15981
15842
  const body = await c.req.json().catch(() => null);
15982
15843
  const senderId = body?.senderId;
15983
15844
  if (typeof senderId !== "string") {
@@ -15986,7 +15847,7 @@ function createWaChannelRoutes(deps) {
15986
15847
  deps.onReady?.(senderId);
15987
15848
  return c.json({ ok: true });
15988
15849
  });
15989
- app45.post("/wa-channel/received", async (c) => {
15850
+ app46.post("/wa-channel/received", async (c) => {
15990
15851
  const body = await c.req.json().catch(() => null);
15991
15852
  const senderId = body?.senderId;
15992
15853
  const waMessageId = body?.waMessageId;
@@ -15996,7 +15857,7 @@ function createWaChannelRoutes(deps) {
15996
15857
  deps.onReceived?.(senderId, waMessageId);
15997
15858
  return c.json({ ok: true });
15998
15859
  });
15999
- return app45;
15860
+ return app46;
16000
15861
  }
16001
15862
 
16002
15863
  // app/lib/whatsapp/gateway/wa-gateway.ts
@@ -16057,17 +15918,15 @@ var WaGateway = class {
16057
15918
  const bytes = Buffer.byteLength(input.text, "utf8");
16058
15919
  const hadSubscriber = this.hub.hasSubscriber(input.senderId);
16059
15920
  const willDeliverNow = this.hub.isReady(input.senderId);
16060
- const hasFileMedia = !!input.mediaPath && input.mediaType !== "audio";
16061
- const mediaField = hasFileMedia ? `media=${input.mediaType} mediaPath=${input.mediaPath}` : input.mediaType === "audio" ? "media=audio mediaPath=transcribed" : "media=none";
15921
+ const openable = input.media.filter((m) => m.type !== "audio");
15922
+ const mediaField = openable.length > 0 ? `media=${openable.map((m) => m.type).join(",")} mediaPaths=${openable.map((m) => m.path).join(",")}` : input.media.some((m) => m.type === "audio") ? "media=audio mediaPath=transcribed" : "media=none";
16062
15923
  this.replies.set(input.senderId, input.reply);
16063
15924
  this.hub.deliver(
16064
15925
  {
16065
15926
  senderId: input.senderId,
16066
15927
  text: input.text,
16067
15928
  waMessageId: `wa-${++this.seq}`,
16068
- mediaPath: input.mediaPath,
16069
- mediaType: input.mediaType,
16070
- mediaMimetype: input.mediaMimetype
15929
+ media: input.media
16071
15930
  },
16072
15931
  Date.now()
16073
15932
  );
@@ -16191,8 +16050,8 @@ function broadcastAdminShutdown(reason) {
16191
16050
 
16192
16051
  // ../lib/entitlement/src/index.ts
16193
16052
  import { createPublicKey, createHash as createHash5, verify as cryptoVerify } from "crypto";
16194
- import { existsSync as existsSync23, readFileSync as readFileSync23, statSync as statSync10 } from "fs";
16195
- import { resolve as resolve26 } from "path";
16053
+ import { existsSync as existsSync22, readFileSync as readFileSync22, statSync as statSync10 } from "fs";
16054
+ import { resolve as resolve25 } from "path";
16196
16055
 
16197
16056
  // ../lib/entitlement/src/canonicalize.ts
16198
16057
  function canonicalize(value) {
@@ -16227,7 +16086,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
16227
16086
  var GRACE_DAYS = 7;
16228
16087
  var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
16229
16088
  function pubkeyPath(brand) {
16230
- return resolve26(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
16089
+ return resolve25(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
16231
16090
  }
16232
16091
  var memo = null;
16233
16092
  function memoKey(mtimeMs, account) {
@@ -16239,8 +16098,8 @@ function resolveEntitlement(brand, account) {
16239
16098
  if (brand.commercialMode !== true) {
16240
16099
  return logResolved(implicitTrust(account), null);
16241
16100
  }
16242
- const entitlementPath = resolve26(brand.configDir, "entitlement.json");
16243
- if (!existsSync23(entitlementPath)) {
16101
+ const entitlementPath = resolve25(brand.configDir, "entitlement.json");
16102
+ if (!existsSync22(entitlementPath)) {
16244
16103
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
16245
16104
  }
16246
16105
  const stat7 = statSync10(entitlementPath);
@@ -16255,7 +16114,7 @@ function resolveEntitlement(brand, account) {
16255
16114
  function verifyAndResolve(brand, entitlementPath, account) {
16256
16115
  let pubkeyPem;
16257
16116
  try {
16258
- pubkeyPem = readFileSync23(pubkeyPath(brand), "utf-8");
16117
+ pubkeyPem = readFileSync22(pubkeyPath(brand), "utf-8");
16259
16118
  } catch (err) {
16260
16119
  return logResolved(anonymousFallback("pubkey-missing"), {
16261
16120
  reason: "pubkey-missing"
@@ -16269,7 +16128,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
16269
16128
  }
16270
16129
  let envelope;
16271
16130
  try {
16272
- envelope = JSON.parse(readFileSync23(entitlementPath, "utf-8"));
16131
+ envelope = JSON.parse(readFileSync22(entitlementPath, "utf-8"));
16273
16132
  } catch {
16274
16133
  return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
16275
16134
  }
@@ -16430,14 +16289,14 @@ function clientFrom(c) {
16430
16289
  );
16431
16290
  }
16432
16291
  var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT || "";
16433
- var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join19(PLATFORM_ROOT9, "config", "brand.json") : "";
16292
+ var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join18(PLATFORM_ROOT9, "config", "brand.json") : "";
16434
16293
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
16435
- if (BRAND_JSON_PATH && !existsSync24(BRAND_JSON_PATH)) {
16294
+ if (BRAND_JSON_PATH && !existsSync23(BRAND_JSON_PATH)) {
16436
16295
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
16437
16296
  }
16438
- if (BRAND_JSON_PATH && existsSync24(BRAND_JSON_PATH)) {
16297
+ if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
16439
16298
  try {
16440
- const parsed = JSON.parse(readFileSync24(BRAND_JSON_PATH, "utf-8"));
16299
+ const parsed = JSON.parse(readFileSync23(BRAND_JSON_PATH, "utf-8"));
16441
16300
  BRAND = { ...BRAND, ...parsed };
16442
16301
  } catch (err) {
16443
16302
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -16456,11 +16315,11 @@ var brandLoginOpts = {
16456
16315
  bodyFont: BRAND.defaultFonts?.body,
16457
16316
  logoContainsName: !!BRAND.logoContainsName
16458
16317
  };
16459
- var ALIAS_DOMAINS_PATH = join19(homedir2(), BRAND.configDir, "alias-domains.json");
16318
+ var ALIAS_DOMAINS_PATH = join18(homedir2(), BRAND.configDir, "alias-domains.json");
16460
16319
  function loadAliasDomains() {
16461
16320
  try {
16462
- if (!existsSync24(ALIAS_DOMAINS_PATH)) return null;
16463
- const parsed = JSON.parse(readFileSync24(ALIAS_DOMAINS_PATH, "utf-8"));
16321
+ if (!existsSync23(ALIAS_DOMAINS_PATH)) return null;
16322
+ const parsed = JSON.parse(readFileSync23(ALIAS_DOMAINS_PATH, "utf-8"));
16464
16323
  if (!Array.isArray(parsed)) {
16465
16324
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
16466
16325
  return null;
@@ -16484,10 +16343,10 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
16484
16343
  function isPublicHost(host) {
16485
16344
  return host.startsWith("public.") || aliasDomains.has(host);
16486
16345
  }
16487
- var app44 = new Hono();
16346
+ var app45 = new Hono();
16488
16347
  var waGateway = new WaGateway({
16489
16348
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
16490
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve27(process.env.MAXY_PLATFORM_ROOT ?? join19(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
16349
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve26(process.env.MAXY_PLATFORM_ROOT ?? join18(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
16491
16350
  ensureChannelSession: async ({ accountId, senderId, gatewayUrl, serverPath }) => {
16492
16351
  const userId = resolveAdminUserId({ accountId, senderPhone: senderId }) ?? void 0;
16493
16352
  console.error(`[whatsapp-native] op=admin-identity senderId=${senderId} userId=${userId ?? "owner-fallback"}`);
@@ -16502,10 +16361,10 @@ var waGateway = new WaGateway({
16502
16361
  }
16503
16362
  }
16504
16363
  });
16505
- app44.route("/", waGateway.routes());
16364
+ app45.route("/", waGateway.routes());
16506
16365
  waGateway.startSweeper();
16507
- app44.use("*", clientIpMiddleware);
16508
- app44.use("*", async (c, next) => {
16366
+ app45.use("*", clientIpMiddleware);
16367
+ app45.use("*", async (c, next) => {
16509
16368
  await next();
16510
16369
  c.header("X-Content-Type-Options", "nosniff");
16511
16370
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
@@ -16515,7 +16374,7 @@ app44.use("*", async (c, next) => {
16515
16374
  );
16516
16375
  });
16517
16376
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
16518
- app44.use("*", async (c, next) => {
16377
+ app45.use("*", async (c, next) => {
16519
16378
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
16520
16379
  await next();
16521
16380
  return;
@@ -16533,7 +16392,7 @@ app44.use("*", async (c, next) => {
16533
16392
  });
16534
16393
  }
16535
16394
  });
16536
- app44.use("*", async (c, next) => {
16395
+ app45.use("*", async (c, next) => {
16537
16396
  const host = (c.req.header("host") ?? "").split(":")[0];
16538
16397
  if (!isPublicHost(host)) {
16539
16398
  await next();
@@ -16564,7 +16423,7 @@ function resolveRemoteAuthOpts() {
16564
16423
  return brandLoginOpts;
16565
16424
  }
16566
16425
  var MAX_LOGIN_BODY = 8 * 1024;
16567
- app44.post("/__remote-auth/login", async (c) => {
16426
+ app45.post("/__remote-auth/login", async (c) => {
16568
16427
  const client = clientFrom(c);
16569
16428
  const clientIp = client.ip || "unknown";
16570
16429
  if (!requestIsTlsTerminated(c)) {
@@ -16609,7 +16468,7 @@ app44.post("/__remote-auth/login", async (c) => {
16609
16468
  }
16610
16469
  });
16611
16470
  });
16612
- app44.get("/__remote-auth/logout", (c) => {
16471
+ app45.get("/__remote-auth/logout", (c) => {
16613
16472
  const client = clientFrom(c);
16614
16473
  const clientIp = client.ip || "unknown";
16615
16474
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -16622,7 +16481,7 @@ app44.get("/__remote-auth/logout", (c) => {
16622
16481
  }
16623
16482
  });
16624
16483
  });
16625
- app44.post("/__remote-auth/change-password", async (c) => {
16484
+ app45.post("/__remote-auth/change-password", async (c) => {
16626
16485
  const client = clientFrom(c);
16627
16486
  const clientIp = client.ip || "unknown";
16628
16487
  const rateLimited = checkRateLimit(client);
@@ -16673,13 +16532,13 @@ app44.post("/__remote-auth/change-password", async (c) => {
16673
16532
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
16674
16533
  }
16675
16534
  });
16676
- app44.get("/__remote-auth/setup", (c) => {
16535
+ app45.get("/__remote-auth/setup", (c) => {
16677
16536
  if (isRemoteAuthConfigured()) {
16678
16537
  return c.redirect("/");
16679
16538
  }
16680
16539
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
16681
16540
  });
16682
- app44.post("/__remote-auth/set-initial-password", async (c) => {
16541
+ app45.post("/__remote-auth/set-initial-password", async (c) => {
16683
16542
  if (isRemoteAuthConfigured()) {
16684
16543
  return c.redirect("/");
16685
16544
  }
@@ -16717,10 +16576,10 @@ app44.post("/__remote-auth/set-initial-password", async (c) => {
16717
16576
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
16718
16577
  }
16719
16578
  });
16720
- app44.get("/api/remote-auth/status", (c) => {
16579
+ app45.get("/api/remote-auth/status", (c) => {
16721
16580
  return c.json({ configured: isRemoteAuthConfigured() });
16722
16581
  });
16723
- app44.post("/api/remote-auth/set-password", async (c) => {
16582
+ app45.post("/api/remote-auth/set-password", async (c) => {
16724
16583
  let body;
16725
16584
  try {
16726
16585
  body = await c.req.json();
@@ -16751,9 +16610,9 @@ app44.post("/api/remote-auth/set-password", async (c) => {
16751
16610
  return c.json({ error: "Failed to save password" }, 500);
16752
16611
  }
16753
16612
  });
16754
- app44.route("/api/_client-error", client_error_default);
16613
+ app45.route("/api/_client-error", client_error_default);
16755
16614
  console.log("[client-error-route] mounted");
16756
- app44.use("*", async (c, next) => {
16615
+ app45.use("*", async (c, next) => {
16757
16616
  const host = (c.req.header("host") ?? "").split(":")[0];
16758
16617
  const path2 = c.req.path;
16759
16618
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
@@ -16786,14 +16645,14 @@ app44.use("*", async (c, next) => {
16786
16645
  console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
16787
16646
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
16788
16647
  });
16789
- app44.route("/api/health", health_default);
16790
- app44.route("/api/chat", chat_default);
16791
- app44.route("/api/whatsapp", whatsapp_default);
16792
- app44.route("/api/whatsapp-reader", whatsapp_reader_default);
16793
- app44.route("/api/onboarding", onboarding_default);
16794
- app44.route("/api/admin", admin_default);
16795
- app44.route("/api/access", access_default);
16796
- app44.route("/api/session", session_default2);
16648
+ app45.route("/api/health", health_default);
16649
+ app45.route("/api/chat", chat_default);
16650
+ app45.route("/api/whatsapp", whatsapp_default);
16651
+ app45.route("/api/whatsapp-reader", whatsapp_reader_default);
16652
+ app45.route("/api/onboarding", onboarding_default);
16653
+ app45.route("/api/admin", admin_default);
16654
+ app45.route("/api/access", access_default);
16655
+ app45.route("/api/session", session_default2);
16797
16656
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
16798
16657
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
16799
16658
  var IMAGE_MIME = {
@@ -16805,7 +16664,7 @@ var IMAGE_MIME = {
16805
16664
  ".svg": "image/svg+xml",
16806
16665
  ".ico": "image/x-icon"
16807
16666
  };
16808
- app44.get("/agent-assets/:slug/:filename", (c) => {
16667
+ app45.get("/agent-assets/:slug/:filename", (c) => {
16809
16668
  const slug = c.req.param("slug");
16810
16669
  const filename = c.req.param("filename");
16811
16670
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -16821,26 +16680,26 @@ app44.get("/agent-assets/:slug/:filename", (c) => {
16821
16680
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
16822
16681
  return c.text("Not found", 404);
16823
16682
  }
16824
- const filePath = resolve27(account.accountDir, "agents", slug, "assets", filename);
16825
- const expectedDir = resolve27(account.accountDir, "agents", slug, "assets");
16683
+ const filePath = resolve26(account.accountDir, "agents", slug, "assets", filename);
16684
+ const expectedDir = resolve26(account.accountDir, "agents", slug, "assets");
16826
16685
  if (!filePath.startsWith(expectedDir + "/")) {
16827
16686
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
16828
16687
  return c.text("Forbidden", 403);
16829
16688
  }
16830
- if (!existsSync24(filePath)) {
16689
+ if (!existsSync23(filePath)) {
16831
16690
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
16832
16691
  return c.text("Not found", 404);
16833
16692
  }
16834
16693
  const ext = "." + filename.split(".").pop()?.toLowerCase();
16835
16694
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
16836
16695
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
16837
- const body = readFileSync24(filePath);
16696
+ const body = readFileSync23(filePath);
16838
16697
  return c.body(body, 200, {
16839
16698
  "Content-Type": contentType,
16840
16699
  "Cache-Control": "public, max-age=3600"
16841
16700
  });
16842
16701
  });
16843
- app44.get("/generated/:filename", (c) => {
16702
+ app45.get("/generated/:filename", (c) => {
16844
16703
  const filename = c.req.param("filename");
16845
16704
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
16846
16705
  console.error(`[generated] serve file=${filename} status=403`);
@@ -16851,35 +16710,35 @@ app44.get("/generated/:filename", (c) => {
16851
16710
  console.error(`[generated] serve file=${filename} status=404`);
16852
16711
  return c.text("Not found", 404);
16853
16712
  }
16854
- const filePath = resolve27(account.accountDir, "generated", filename);
16855
- const expectedDir = resolve27(account.accountDir, "generated");
16713
+ const filePath = resolve26(account.accountDir, "generated", filename);
16714
+ const expectedDir = resolve26(account.accountDir, "generated");
16856
16715
  if (!filePath.startsWith(expectedDir + "/")) {
16857
16716
  console.error(`[generated] serve file=${filename} status=403`);
16858
16717
  return c.text("Forbidden", 403);
16859
16718
  }
16860
- if (!existsSync24(filePath)) {
16719
+ if (!existsSync23(filePath)) {
16861
16720
  console.error(`[generated] serve file=${filename} status=404`);
16862
16721
  return c.text("Not found", 404);
16863
16722
  }
16864
16723
  const ext = "." + filename.split(".").pop()?.toLowerCase();
16865
16724
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
16866
16725
  console.log(`[generated] serve file=${filename} status=200`);
16867
- const body = readFileSync24(filePath);
16726
+ const body = readFileSync23(filePath);
16868
16727
  return c.body(body, 200, {
16869
16728
  "Content-Type": contentType,
16870
16729
  "Cache-Control": "public, max-age=86400"
16871
16730
  });
16872
16731
  });
16873
- app44.route("/sites", sites_default);
16874
- app44.route("/listings", listings_default);
16875
- app44.route("/v", visitor_event_default);
16876
- app44.route("/v", visitor_consent_default);
16732
+ app45.route("/sites", sites_default);
16733
+ app45.route("/listings", listings_default);
16734
+ app45.route("/v", visitor_event_default);
16735
+ app45.route("/v", visitor_consent_default);
16877
16736
  var htmlCache = /* @__PURE__ */ new Map();
16878
16737
  var brandLogoPath = "/brand/maxy-monochrome.png";
16879
16738
  var brandIconPath = "/brand/maxy-monochrome.png";
16880
- if (BRAND_JSON_PATH && existsSync24(BRAND_JSON_PATH)) {
16739
+ if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
16881
16740
  try {
16882
- const fullBrand = JSON.parse(readFileSync24(BRAND_JSON_PATH, "utf-8"));
16741
+ const fullBrand = JSON.parse(readFileSync23(BRAND_JSON_PATH, "utf-8"));
16883
16742
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
16884
16743
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
16885
16744
  } catch {
@@ -16896,9 +16755,9 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
16896
16755
  function readInstalledVersion() {
16897
16756
  try {
16898
16757
  if (!PLATFORM_ROOT9) return "unknown";
16899
- const versionFile = join19(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
16900
- if (!existsSync24(versionFile)) return "unknown";
16901
- const content = readFileSync24(versionFile, "utf-8").trim();
16758
+ const versionFile = join18(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
16759
+ if (!existsSync23(versionFile)) return "unknown";
16760
+ const content = readFileSync23(versionFile, "utf-8").trim();
16902
16761
  return content || "unknown";
16903
16762
  } catch {
16904
16763
  return "unknown";
@@ -16939,7 +16798,7 @@ var clientErrorReporterScript = `<script>
16939
16798
  function cachedHtml(file) {
16940
16799
  let html = htmlCache.get(file);
16941
16800
  if (!html) {
16942
- html = readFileSync24(resolve27(process.cwd(), "public", file), "utf-8");
16801
+ html = readFileSync23(resolve26(process.cwd(), "public", file), "utf-8");
16943
16802
  const productNameEsc = escapeHtml(BRAND.productName);
16944
16803
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
16945
16804
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -16955,13 +16814,13 @@ ${clientErrorReporterScript}
16955
16814
  }
16956
16815
  var brandedHtmlCache = /* @__PURE__ */ new Map();
16957
16816
  function loadBrandingCache(agentSlug) {
16958
- const configDir2 = join19(homedir2(), BRAND.configDir);
16817
+ const configDir2 = join18(homedir2(), BRAND.configDir);
16959
16818
  try {
16960
16819
  const accountId = getDefaultAccountId();
16961
16820
  if (!accountId) return null;
16962
- const cachePath = join19(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
16963
- if (!existsSync24(cachePath)) return null;
16964
- return JSON.parse(readFileSync24(cachePath, "utf-8"));
16821
+ const cachePath = join18(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
16822
+ if (!existsSync23(cachePath)) return null;
16823
+ return JSON.parse(readFileSync23(cachePath, "utf-8"));
16965
16824
  } catch {
16966
16825
  return null;
16967
16826
  }
@@ -17004,7 +16863,7 @@ function escapeHtml(s) {
17004
16863
  function agentUnavailableHtml() {
17005
16864
  return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${escapeHtml(BRAND.productName)}</title></head><body style="font-family:system-ui,sans-serif;max-width:32rem;margin:4rem auto;padding:0 1.5rem;color:#222"><h1 style="font-size:1.25rem">Agent unavailable</h1><p>This agent isn't available right now. If you reached this page from a saved link, the agent may have been turned off.</p></body></html>`;
17006
16865
  }
17007
- app44.get("/", (c) => {
16866
+ app45.get("/", (c) => {
17008
16867
  const host = (c.req.header("host") ?? "").split(":")[0];
17009
16868
  if (isPublicHost(host)) {
17010
16869
  const defaultSlug = resolveDefaultSlug();
@@ -17020,12 +16879,12 @@ app44.get("/", (c) => {
17020
16879
  }
17021
16880
  return c.html(cachedHtml("index.html"));
17022
16881
  });
17023
- app44.get("/public", (c) => {
16882
+ app45.get("/public", (c) => {
17024
16883
  const host = (c.req.header("host") ?? "").split(":")[0];
17025
16884
  if (isPublicHost(host)) return c.text("Not found", 404);
17026
16885
  return c.html(cachedHtml("public.html"));
17027
16886
  });
17028
- app44.get("/chat", (c) => {
16887
+ app45.get("/chat", (c) => {
17029
16888
  const host = (c.req.header("host") ?? "").split(":")[0];
17030
16889
  if (isPublicHost(host)) return c.text("Not found", 404);
17031
16890
  return c.html(cachedHtml("public.html"));
@@ -17044,12 +16903,12 @@ async function logViewerFetch(c, next) {
17044
16903
  duration_ms: Date.now() - start
17045
16904
  });
17046
16905
  }
17047
- app44.use("/vnc-viewer.html", logViewerFetch);
17048
- app44.use("/vnc-popout.html", logViewerFetch);
17049
- app44.get("/vnc-popout.html", (c) => {
16906
+ app45.use("/vnc-viewer.html", logViewerFetch);
16907
+ app45.use("/vnc-popout.html", logViewerFetch);
16908
+ app45.get("/vnc-popout.html", (c) => {
17050
16909
  let html = htmlCache.get("vnc-popout.html");
17051
16910
  if (!html) {
17052
- html = readFileSync24(resolve27(process.cwd(), "public", "vnc-popout.html"), "utf-8");
16911
+ html = readFileSync23(resolve26(process.cwd(), "public", "vnc-popout.html"), "utf-8");
17053
16912
  const name = escapeHtml(BRAND.productName);
17054
16913
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
17055
16914
  html = html.replace("</head>", ` ${brandScript}
@@ -17059,7 +16918,7 @@ app44.get("/vnc-popout.html", (c) => {
17059
16918
  }
17060
16919
  return c.html(html);
17061
16920
  });
17062
- app44.post("/api/vnc/client-event", async (c) => {
16921
+ app45.post("/api/vnc/client-event", async (c) => {
17063
16922
  let body;
17064
16923
  try {
17065
16924
  body = await c.req.json();
@@ -17080,30 +16939,30 @@ app44.post("/api/vnc/client-event", async (c) => {
17080
16939
  });
17081
16940
  return c.json({ ok: true });
17082
16941
  });
17083
- app44.get("/g/:slug", (c) => {
16942
+ app45.get("/g/:slug", (c) => {
17084
16943
  return c.html(brandedPublicHtml());
17085
16944
  });
17086
- app44.get("/graph", (c) => {
16945
+ app45.get("/graph", (c) => {
17087
16946
  const host = (c.req.header("host") ?? "").split(":")[0];
17088
16947
  if (isPublicHost(host)) return c.text("Not found", 404);
17089
16948
  return c.html(cachedHtml("graph.html"));
17090
16949
  });
17091
- app44.get("/sessions", (c) => {
16950
+ app45.get("/sessions", (c) => {
17092
16951
  const host = (c.req.header("host") ?? "").split(":")[0];
17093
16952
  if (isPublicHost(host)) return c.text("Not found", 404);
17094
16953
  return c.html(cachedHtml("sessions.html"));
17095
16954
  });
17096
- app44.get("/data", (c) => {
16955
+ app45.get("/data", (c) => {
17097
16956
  const host = (c.req.header("host") ?? "").split(":")[0];
17098
16957
  if (isPublicHost(host)) return c.text("Not found", 404);
17099
16958
  return c.html(cachedHtml("data.html"));
17100
16959
  });
17101
- app44.get("/browser", (c) => {
16960
+ app45.get("/browser", (c) => {
17102
16961
  const host = (c.req.header("host") ?? "").split(":")[0];
17103
16962
  if (isPublicHost(host)) return c.text("Not found", 404);
17104
16963
  return c.html(cachedHtml("browser.html"));
17105
16964
  });
17106
- app44.get("/:slug", async (c, next) => {
16965
+ app45.get("/:slug", async (c, next) => {
17107
16966
  const slug = c.req.param("slug");
17108
16967
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
17109
16968
  const account = resolveAccount();
@@ -17118,13 +16977,13 @@ app44.get("/:slug", async (c, next) => {
17118
16977
  await next();
17119
16978
  });
17120
16979
  if (brandFaviconPath !== "/favicon.ico") {
17121
- app44.get("/favicon.ico", (c) => {
16980
+ app45.get("/favicon.ico", (c) => {
17122
16981
  c.header("Cache-Control", "public, max-age=300");
17123
16982
  return c.redirect(brandFaviconPath, 302);
17124
16983
  });
17125
16984
  }
17126
- app44.use("/*", serveStatic({ root: "./public" }));
17127
- app44.all("*", (c) => {
16985
+ app45.use("/*", serveStatic({ root: "./public" }));
16986
+ app45.all("*", (c) => {
17128
16987
  const host = (c.req.header("host") ?? "").split(":")[0];
17129
16988
  const path2 = c.req.path;
17130
16989
  if (isPublicHost(host)) {
@@ -17138,7 +16997,7 @@ app44.all("*", (c) => {
17138
16997
  });
17139
16998
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
17140
16999
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
17141
- var httpServer = serve({ fetch: app44.fetch, port, hostname });
17000
+ var httpServer = serve({ fetch: app45.fetch, port, hostname });
17142
17001
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
17143
17002
  startAuthHealthHeartbeat();
17144
17003
  {
@@ -17176,7 +17035,7 @@ for (const m of SUBAPP_MANIFEST) {
17176
17035
  }
17177
17036
  try {
17178
17037
  const registered = [];
17179
- for (const r of app44.routes ?? []) {
17038
+ for (const r of app45.routes ?? []) {
17180
17039
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
17181
17040
  if (AGENT_SLUG_PATTERN.test(r.path)) {
17182
17041
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -17204,11 +17063,11 @@ try {
17204
17063
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
17205
17064
  async function runAdminUserReconcileTick() {
17206
17065
  try {
17207
- if (!existsSync24(USERS_FILE)) {
17066
+ if (!existsSync23(USERS_FILE)) {
17208
17067
  console.error("[adminuser-self-heal] skip reason=no-users-file");
17209
17068
  return;
17210
17069
  }
17211
- const usersRaw = readFileSync24(USERS_FILE, "utf-8").trim();
17070
+ const usersRaw = readFileSync23(USERS_FILE, "utf-8").trim();
17212
17071
  if (!usersRaw) {
17213
17072
  console.error("[adminuser-self-heal] skip reason=empty-users-file");
17214
17073
  return;
@@ -17315,7 +17174,7 @@ if (bootAccountConfig?.whatsapp) {
17315
17174
  }
17316
17175
  init({
17317
17176
  configDir: configDirForWhatsApp,
17318
- platformRoot: resolve27(process.env.MAXY_PLATFORM_ROOT ?? join19(__dirname, "..")),
17177
+ platformRoot: resolve26(process.env.MAXY_PLATFORM_ROOT ?? join18(__dirname, "..")),
17319
17178
  accountConfig: bootAccountConfig,
17320
17179
  onMessage: async (msg) => {
17321
17180
  if (msg.isOwnerMirror) {
@@ -17326,9 +17185,9 @@ init({
17326
17185
  console.error(`[whatsapp:route] dropped reason=non-admin-sender senderId=${msg.senderPhone} agentType=${msg.agentType}`);
17327
17186
  return;
17328
17187
  }
17329
- const hasFileMedia = !!msg.mediaPath && msg.mediaType !== "audio";
17188
+ const hasFileMedia = msg.media.some((m) => m.type !== "audio");
17330
17189
  if (!msg.text && !hasFileMedia) {
17331
- console.error(`[whatsapp:route] dropped reason=no-text-no-media senderId=${msg.senderPhone} media=${msg.mediaType ?? "none"}`);
17190
+ console.error(`[whatsapp:route] dropped reason=no-text-no-media senderId=${msg.senderPhone} mediaCount=${msg.media.length}`);
17332
17191
  return;
17333
17192
  }
17334
17193
  try {
@@ -17339,9 +17198,7 @@ init({
17339
17198
  senderId: msg.senderPhone,
17340
17199
  text: msg.text,
17341
17200
  reply: msg.reply,
17342
- mediaPath: msg.mediaPath,
17343
- mediaType: msg.mediaType,
17344
- mediaMimetype: msg.mediaMimetype
17201
+ media: msg.media
17345
17202
  });
17346
17203
  } catch (err) {
17347
17204
  console.error(
@@ -17352,7 +17209,7 @@ init({
17352
17209
  }).catch((err) => {
17353
17210
  console.error(`[whatsapp] init failed: ${String(err)}`);
17354
17211
  });
17355
- startReaper2();
17212
+ startReaper();
17356
17213
  var shuttingDown = false;
17357
17214
  process.on("SIGTERM", async () => {
17358
17215
  if (shuttingDown) {