@rubytech/create-maxy-code 0.1.423 → 0.1.429

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 (333) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/embed-client/dist/index.d.ts +5 -1
  3. package/payload/platform/lib/embed-client/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/embed-client/dist/index.js +114 -36
  5. package/payload/platform/lib/embed-client/dist/index.js.map +1 -1
  6. package/payload/platform/lib/embed-client/src/index.ts +141 -34
  7. package/payload/platform/neo4j/schema.cypher +13 -0
  8. package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
  9. package/payload/platform/plugins/admin/PLUGIN.md +5 -1
  10. package/payload/platform/plugins/admin/hooks/__tests__/datetime-inject.test.sh +119 -0
  11. package/payload/platform/plugins/admin/hooks/datetime-inject.sh +115 -0
  12. package/payload/platform/plugins/admin/mcp/dist/index.js +62 -4
  13. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  14. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.d.ts +44 -0
  15. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.d.ts.map +1 -1
  16. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.js +96 -0
  17. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.js.map +1 -1
  18. package/payload/platform/plugins/admin/skills/datetime/SKILL.md +9 -2
  19. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +17 -3
  20. package/payload/platform/plugins/docs/references/admin-ui.md +2 -0
  21. package/payload/platform/plugins/docs/references/cross-account-authority.md +8 -0
  22. package/payload/platform/plugins/docs/references/internals.md +5 -1
  23. package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
  24. package/payload/platform/plugins/email/PLUGIN.md +2 -2
  25. package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js +73 -4
  26. package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js.map +1 -1
  27. package/payload/platform/plugins/email/mcp/dist/__tests__/mailbox-resolve.test.js +42 -1
  28. package/payload/platform/plugins/email/mcp/dist/__tests__/mailbox-resolve.test.js.map +1 -1
  29. package/payload/platform/plugins/email/mcp/dist/index.js +1 -0
  30. package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
  31. package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts +4 -0
  32. package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts.map +1 -1
  33. package/payload/platform/plugins/email/mcp/dist/lib/credentials.js +5 -0
  34. package/payload/platform/plugins/email/mcp/dist/lib/credentials.js.map +1 -1
  35. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +25 -3
  36. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
  37. package/payload/platform/plugins/email/mcp/dist/lib/imap.js +67 -12
  38. package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
  39. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.d.ts +1 -0
  40. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.d.ts.map +1 -1
  41. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js +1 -0
  42. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js.map +1 -1
  43. package/payload/platform/plugins/email/references/email-reference.md +8 -0
  44. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.d.ts +2 -0
  45. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.d.ts.map +1 -0
  46. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.js +92 -0
  47. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.js.map +1 -0
  48. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-timeout.test.d.ts +2 -0
  49. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-timeout.test.d.ts.map +1 -0
  50. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-timeout.test.js +56 -0
  51. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-timeout.test.js.map +1 -0
  52. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.js +56 -0
  53. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.js.map +1 -1
  54. package/payload/platform/plugins/scheduling/PLUGIN.md +1 -1
  55. package/payload/platform/plugins/scheduling/mcp/dist/index.js +5 -2
  56. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  57. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch.test.js +50 -1
  58. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch.test.js.map +1 -1
  59. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/scheduled-seat-id.test.d.ts +2 -0
  60. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/scheduled-seat-id.test.d.ts.map +1 -0
  61. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/scheduled-seat-id.test.js +22 -0
  62. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/scheduled-seat-id.test.js.map +1 -0
  63. package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.d.ts +35 -0
  64. package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.d.ts.map +1 -1
  65. package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.js +36 -0
  66. package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.js.map +1 -1
  67. package/payload/platform/plugins/scheduling/mcp/dist/lib/scheduled-seat-id.d.ts +11 -0
  68. package/payload/platform/plugins/scheduling/mcp/dist/lib/scheduled-seat-id.d.ts.map +1 -0
  69. package/payload/platform/plugins/scheduling/mcp/dist/lib/scheduled-seat-id.js +19 -0
  70. package/payload/platform/plugins/scheduling/mcp/dist/lib/scheduled-seat-id.js.map +1 -0
  71. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +85 -3
  72. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js.map +1 -1
  73. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/standing-audit.test.js +32 -1
  74. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/standing-audit.test.js.map +1 -1
  75. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +14 -1
  76. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
  77. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +94 -4
  78. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
  79. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +23 -7
  80. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
  81. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel.test.d.ts +2 -0
  82. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel.test.d.ts.map +1 -0
  83. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel.test.js +30 -0
  84. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel.test.js.map +1 -0
  85. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.d.ts +29 -0
  86. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.d.ts.map +1 -1
  87. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js +47 -2
  88. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js.map +1 -1
  89. package/payload/platform/plugins/whatsapp/PLUGIN.md +2 -0
  90. package/payload/platform/plugins/whatsapp/mcp/dist/__tests__/caller-scope-headers.test.d.ts +2 -0
  91. package/payload/platform/plugins/whatsapp/mcp/dist/__tests__/caller-scope-headers.test.d.ts.map +1 -0
  92. package/payload/platform/plugins/whatsapp/mcp/dist/__tests__/caller-scope-headers.test.js +20 -0
  93. package/payload/platform/plugins/whatsapp/mcp/dist/__tests__/caller-scope-headers.test.js.map +1 -0
  94. package/payload/platform/plugins/whatsapp/mcp/dist/call-api.d.ts +1 -1
  95. package/payload/platform/plugins/whatsapp/mcp/dist/call-api.d.ts.map +1 -1
  96. package/payload/platform/plugins/whatsapp/mcp/dist/call-api.js +5 -2
  97. package/payload/platform/plugins/whatsapp/mcp/dist/call-api.js.map +1 -1
  98. package/payload/platform/plugins/whatsapp/mcp/dist/caller-scope-headers.d.ts +9 -0
  99. package/payload/platform/plugins/whatsapp/mcp/dist/caller-scope-headers.d.ts.map +1 -0
  100. package/payload/platform/plugins/whatsapp/mcp/dist/caller-scope-headers.js +18 -0
  101. package/payload/platform/plugins/whatsapp/mcp/dist/caller-scope-headers.js.map +1 -0
  102. package/payload/platform/plugins/whatsapp/mcp/dist/index.js +13 -11
  103. package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
  104. package/payload/platform/plugins/work/PLUGIN.md +1 -1
  105. package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-assigned-admin-env.test.d.ts +2 -0
  106. package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-assigned-admin-env.test.d.ts.map +1 -0
  107. package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-assigned-admin-env.test.js +72 -0
  108. package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-assigned-admin-env.test.js.map +1 -0
  109. package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-client-fields.test.d.ts +2 -0
  110. package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-client-fields.test.d.ts.map +1 -0
  111. package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-client-fields.test.js +67 -0
  112. package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-client-fields.test.js.map +1 -0
  113. package/payload/platform/plugins/work/mcp/dist/index.js +3 -0
  114. package/payload/platform/plugins/work/mcp/dist/index.js.map +1 -1
  115. package/payload/platform/plugins/work/mcp/dist/lib/embeddings.d.ts +9 -3
  116. package/payload/platform/plugins/work/mcp/dist/lib/embeddings.d.ts.map +1 -1
  117. package/payload/platform/plugins/work/mcp/dist/lib/embeddings.js +19 -15
  118. package/payload/platform/plugins/work/mcp/dist/lib/embeddings.js.map +1 -1
  119. package/payload/platform/plugins/work/mcp/dist/tools/work-create.d.ts +6 -0
  120. package/payload/platform/plugins/work/mcp/dist/tools/work-create.d.ts.map +1 -1
  121. package/payload/platform/plugins/work/mcp/dist/tools/work-create.js +34 -1
  122. package/payload/platform/plugins/work/mcp/dist/tools/work-create.js.map +1 -1
  123. package/payload/platform/plugins/workflows/mcp/dist/lib/embeddings.d.ts +1 -1
  124. package/payload/platform/plugins/workflows/mcp/dist/lib/embeddings.d.ts.map +1 -1
  125. package/payload/platform/plugins/workflows/mcp/dist/lib/embeddings.js +7 -18
  126. package/payload/platform/plugins/workflows/mcp/dist/lib/embeddings.js.map +1 -1
  127. package/payload/platform/scripts/lib/provision-account-dir.sh +2 -1
  128. package/payload/platform/services/claude-session-manager/dist/account-admin-census.d.ts +39 -0
  129. package/payload/platform/services/claude-session-manager/dist/account-admin-census.d.ts.map +1 -0
  130. package/payload/platform/services/claude-session-manager/dist/account-admin-census.js +122 -0
  131. package/payload/platform/services/claude-session-manager/dist/account-admin-census.js.map +1 -0
  132. package/payload/platform/services/claude-session-manager/dist/account-timezone.d.ts +40 -0
  133. package/payload/platform/services/claude-session-manager/dist/account-timezone.d.ts.map +1 -0
  134. package/payload/platform/services/claude-session-manager/dist/account-timezone.js +126 -0
  135. package/payload/platform/services/claude-session-manager/dist/account-timezone.js.map +1 -0
  136. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  137. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  138. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  139. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  140. package/payload/platform/services/claude-session-manager/dist/http-server.js +18 -1
  141. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  142. package/payload/platform/services/claude-session-manager/dist/index.js +13 -0
  143. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  144. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +11 -0
  145. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  146. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +28 -0
  147. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  148. package/payload/platform/services/telegram-channel/dist/instructions.d.ts.map +1 -1
  149. package/payload/platform/services/telegram-channel/dist/instructions.js +8 -1
  150. package/payload/platform/services/telegram-channel/dist/instructions.js.map +1 -1
  151. package/payload/platform/services/telegram-channel/dist/notification.d.ts +22 -0
  152. package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -1
  153. package/payload/platform/services/telegram-channel/dist/notification.js +22 -1
  154. package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -1
  155. package/payload/platform/services/webchat-channel/dist/instructions.d.ts.map +1 -1
  156. package/payload/platform/services/webchat-channel/dist/instructions.js +8 -1
  157. package/payload/platform/services/webchat-channel/dist/instructions.js.map +1 -1
  158. package/payload/platform/services/webchat-channel/dist/notification.d.ts +22 -0
  159. package/payload/platform/services/webchat-channel/dist/notification.d.ts.map +1 -1
  160. package/payload/platform/services/webchat-channel/dist/notification.js +22 -1
  161. package/payload/platform/services/webchat-channel/dist/notification.js.map +1 -1
  162. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +28 -2
  163. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
  164. package/payload/platform/services/whatsapp-channel/dist/notification.js +32 -3
  165. package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
  166. package/payload/platform/templates/account.json +2 -1
  167. package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
  168. package/payload/server/{chunk-3Z5WE53X.js → chunk-UUG6ZSO5.js} +65 -9
  169. package/payload/server/maxy-edge.js +1 -1
  170. package/payload/server/public/assets/AdminLoginScreens-C4AZT7cQ.js +1 -0
  171. package/payload/server/public/assets/AdminShell-BfLQQ27Z.js +2 -0
  172. package/payload/server/public/assets/{Checkbox-CgCqOslz.js → Checkbox-BC0c_gbn.js} +1 -1
  173. package/payload/server/public/assets/admin-SaF1F4e-.js +1 -0
  174. package/payload/server/public/assets/{arc-DyzjCWmw.js → arc-qKfXIt8v.js} +1 -1
  175. package/payload/server/public/assets/architecture-YZFGNWBL-FPHT7s-C.js +1 -0
  176. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-qWfElD16.js → architectureDiagram-Q4EWVU46-DkVrGn7G.js} +1 -1
  177. package/payload/server/public/assets/audio-attachment-mime-BBW07eyG.js +2 -0
  178. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DO2fFHC3.js → blockDiagram-DXYQGD6D-DqavswGH.js} +1 -1
  179. package/payload/server/public/assets/browser-CvZxNdKw.js +1 -0
  180. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-Ca-q5gDe.js → c4Diagram-AHTNJAMY-B7fyKiXe.js} +1 -1
  181. package/payload/server/public/assets/calendar-DXxLMF2J.js +1 -0
  182. package/payload/server/public/assets/channel-j70eMvcL.js +1 -0
  183. package/payload/server/public/assets/chat-B9Qjt7C9.js +1 -0
  184. package/payload/server/public/assets/chevron-left-CLPxfjDV.js +1 -0
  185. package/payload/server/public/assets/{chunk-2KRD3SAO-CX2PxuDw.js → chunk-2KRD3SAO-DsgMtGkv.js} +1 -1
  186. package/payload/server/public/assets/{chunk-336JU56O-D8l6U4Ne.js → chunk-336JU56O-CkdISfNt.js} +2 -2
  187. package/payload/server/public/assets/chunk-426QAEUC-D-NcAlTW.js +1 -0
  188. package/payload/server/public/assets/{chunk-4BX2VUAB-CG32Lkbh.js → chunk-4BX2VUAB-CYpiF2bl.js} +1 -1
  189. package/payload/server/public/assets/{chunk-4TB4RGXK-BnAQbO-v.js → chunk-4TB4RGXK-CWyc_F7v.js} +1 -1
  190. package/payload/server/public/assets/{chunk-55IACEB6-ejqRH2M5.js → chunk-55IACEB6-BbzKMw2Z.js} +1 -1
  191. package/payload/server/public/assets/{chunk-5FUZZQ4R-ClkicQ-T.js → chunk-5FUZZQ4R-u19Nai9e.js} +1 -1
  192. package/payload/server/public/assets/{chunk-5PVQY5BW-Be-mE_rx.js → chunk-5PVQY5BW-Ba8by6Uy.js} +1 -1
  193. package/payload/server/public/assets/{chunk-67CJDMHE-DPsemed2.js → chunk-67CJDMHE-BwUuxtyb.js} +1 -1
  194. package/payload/server/public/assets/{chunk-7N4EOEYR-BQRQJETl.js → chunk-7N4EOEYR-BRH9iM9L.js} +1 -1
  195. package/payload/server/public/assets/{chunk-AA7GKIK3-B1wcAVCK.js → chunk-AA7GKIK3-BGoztgLL.js} +1 -1
  196. package/payload/server/public/assets/{chunk-BSJP7CBP-DIua053h.js → chunk-BSJP7CBP-C5GDAZTl.js} +1 -1
  197. package/payload/server/public/assets/{chunk-CIAEETIT-C9GHSCS9.js → chunk-CIAEETIT-ChY32VPS.js} +1 -1
  198. package/payload/server/public/assets/{chunk-EDXVE4YY-C1T3l1xj.js → chunk-EDXVE4YY-CPSD3p6p.js} +1 -1
  199. package/payload/server/public/assets/{chunk-ENJZ2VHE-8kPcXEQC.js → chunk-ENJZ2VHE-D1oL-iUr.js} +1 -1
  200. package/payload/server/public/assets/{chunk-FMBD7UC4-Bhoeq9sD.js → chunk-FMBD7UC4-CPvYEr54.js} +1 -1
  201. package/payload/server/public/assets/{chunk-FOC6F5B3-BIBpJi8I.js → chunk-FOC6F5B3-9Yyj7Vbz.js} +1 -1
  202. package/payload/server/public/assets/{chunk-ICPOFSXX-DELXp6fj.js → chunk-ICPOFSXX-BaYgh8FR.js} +2 -2
  203. package/payload/server/public/assets/{chunk-K5T4RW27-DdckXldP.js → chunk-K5T4RW27-5ucpeRvm.js} +1 -1
  204. package/payload/server/public/assets/{chunk-KGLVRYIC-BJhXejKT.js → chunk-KGLVRYIC-DW-FHk7T.js} +1 -1
  205. package/payload/server/public/assets/{chunk-LIHQZDEY-BSd8nyM2.js → chunk-LIHQZDEY-CGGVfAyG.js} +1 -1
  206. package/payload/server/public/assets/{chunk-ORNJ4GCN-CBi55uxq.js → chunk-ORNJ4GCN-Bv8EUa5d.js} +1 -1
  207. package/payload/server/public/assets/{chunk-OYMX7WX6-Dfbzl8xh.js → chunk-OYMX7WX6-C1mXJnyw.js} +1 -1
  208. package/payload/server/public/assets/chunk-QZHKN3VN-CAwbQBtf.js +1 -0
  209. package/payload/server/public/assets/{chunk-U2HBQHQK-BN1w8_Cq.js → chunk-U2HBQHQK-PwSQz6EP.js} +1 -1
  210. package/payload/server/public/assets/{chunk-X2U36JSP-CrRay1NJ.js → chunk-X2U36JSP--NPHTBlU.js} +1 -1
  211. package/payload/server/public/assets/{chunk-XPW4576I-C_ZE776O.js → chunk-XPW4576I-Bbc7Da32.js} +1 -1
  212. package/payload/server/public/assets/{chunk-YZCP3GAM-CUSlqWBY.js → chunk-YZCP3GAM-D-9v8e--.js} +1 -1
  213. package/payload/server/public/assets/{chunk-ZZ45TVLE-BdPUfSiD.js → chunk-ZZ45TVLE-CMPg670Q.js} +1 -1
  214. package/payload/server/public/assets/classDiagram-6PBFFD2Q-Ct6Rn0vt.js +1 -0
  215. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-B_2XCIFv.js +1 -0
  216. package/payload/server/public/assets/clone-DjPWA_NH.js +1 -0
  217. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-D4E9htTz.js → cose-bilkent-S5V4N54A-NVSb1Bhy.js} +1 -1
  218. package/payload/server/public/assets/{dagre-KV5264BT-ByuvYV7N.js → dagre-KV5264BT-V2Ai1DFl.js} +1 -1
  219. package/payload/server/public/assets/{dagre-D1B5TQL1.js → dagre-QfLcO-1j.js} +1 -1
  220. package/payload/server/public/assets/data-BKE6Sa-g.js +1 -0
  221. package/payload/server/public/assets/{diagram-5BDNPKRD-B-0KduTa.js → diagram-5BDNPKRD-Caw21693.js} +1 -1
  222. package/payload/server/public/assets/{diagram-G4DWMVQ6-CSQmo3eB.js → diagram-G4DWMVQ6-CgwVkT2q.js} +1 -1
  223. package/payload/server/public/assets/{diagram-MMDJMWI5-DK0kWiB3.js → diagram-MMDJMWI5-DFUrLZhs.js} +1 -1
  224. package/payload/server/public/assets/{diagram-TYMM5635-CYbK2reZ.js → diagram-TYMM5635-CEEiEuZJ.js} +1 -1
  225. package/payload/server/public/assets/{dist-CADCHk0t.js → dist-Cvgxm7qv.js} +1 -1
  226. package/payload/server/public/assets/{erDiagram-SMLLAGMA-C-JQHvJF.js → erDiagram-SMLLAGMA-CG10NrT3.js} +1 -1
  227. package/payload/server/public/assets/file-download-B2B2DTar.js +1 -0
  228. package/payload/server/public/assets/{flatten-ROVzlo1u.js → flatten-DAO0sfCM.js} +1 -1
  229. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-OTOd2czg.js → flowDiagram-DWJPFMVM-BqkV9Okv.js} +1 -1
  230. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BWJ778ou.js → ganttDiagram-T4ZO3ILL-DRiCDQF6.js} +1 -1
  231. package/payload/server/public/assets/gitGraph-7Q5UKJZL-B8Hx7f-D.js +1 -0
  232. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CkNcyISe.js → gitGraphDiagram-UUTBAWPF-BZV2voyy.js} +1 -1
  233. package/payload/server/public/assets/graph-DRNzDBTV.js +51 -0
  234. package/payload/server/public/assets/{graph-labels-BfG6FO25.js → graph-labels-DxqDdO7G.js} +1 -1
  235. package/payload/server/public/assets/{graphlib-8z59Ng6C.js → graphlib-DGPThX8M.js} +1 -1
  236. package/payload/server/public/assets/info-OMHHGYJF-BicCJTqU.js +1 -0
  237. package/payload/server/public/assets/infoDiagram-42DDH7IO-tf-8rOez.js +2 -0
  238. package/payload/server/public/assets/{isEmpty-DXf_sApt.js → isEmpty-Cb_U81C6.js} +1 -1
  239. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-Cg7pRRGp.js → ishikawaDiagram-UXIWVN3A-BKsAxSvp.js} +1 -1
  240. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CZT_4r_Z.js → journeyDiagram-VCZTEJTY-CmliuOd-.js} +1 -1
  241. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-Dp1Vd5YM.js → kanban-definition-6JOO6SKY-DAlElMb-.js} +1 -1
  242. package/payload/server/public/assets/{line-UPAcwY66.js → line-DKZqLKAC.js} +1 -1
  243. package/payload/server/public/assets/{linear-BeeahLKw.js → linear-CbSGdh1x.js} +1 -1
  244. package/payload/server/public/assets/{maximize-2-DrBaKD3z.js → maximize-2-DKx6OBKv.js} +1 -1
  245. package/payload/server/public/assets/{mermaid-parser.core-CLKle8df.js → mermaid-parser.core-DFvbao9C.js} +2 -2
  246. package/payload/server/public/assets/{mermaid.core-CwRj5rL5.js → mermaid.core-C0vEBxDm.js} +3 -3
  247. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CNQUY9UJ.js → mindmap-definition-QFDTVHPH-CShASUKd.js} +1 -1
  248. package/payload/server/public/assets/operator-CTJjI8te.js +1 -0
  249. package/payload/server/public/assets/{ordinal-B2r5L1v4.js → ordinal-H0tVmBDP.js} +1 -1
  250. package/payload/server/public/assets/packet-4T2RLAQJ-Ckn_5hq0.js +1 -0
  251. package/payload/server/public/assets/page-CbI1wtef.js +1 -0
  252. package/payload/server/public/assets/page-JzxyFGle.js +32 -0
  253. package/payload/server/public/assets/{pdf-render-m08Xm2Nm.js → pdf-render-jAQU0nXt.js} +1 -1
  254. package/payload/server/public/assets/pie-ZZUOXDRM-DzlGQW3J.js +1 -0
  255. package/payload/server/public/assets/{pieDiagram-DEJITSTG-Scnq58FX.js → pieDiagram-DEJITSTG-CBZHpDAJ.js} +1 -1
  256. package/payload/server/public/assets/play-DHttF4fl.js +1 -0
  257. package/payload/server/public/assets/public-DzeW3_eM.js +1 -0
  258. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-wPfZo_vs.js → quadrantDiagram-34T5L4WZ-n3bB3K91.js} +1 -1
  259. package/payload/server/public/assets/radar-PYXPWWZC-BHo2YD8b.js +1 -0
  260. package/payload/server/public/assets/{reduce-CFlDlJf5.js → reduce-DAvwat-a.js} +1 -1
  261. package/payload/server/public/assets/{requirementDiagram-MS252O5E-yYkH12K2.js → requirementDiagram-MS252O5E-DiDvQK3c.js} +1 -1
  262. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-fVWRBzzV.js → sankeyDiagram-XADWPNL6-DWDQQZmd.js} +1 -1
  263. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-Dbap3X6h.js → sequenceDiagram-FGHM5R23-DmAqRlBT.js} +1 -1
  264. package/payload/server/public/assets/square-CHcQHtK8.js +1 -0
  265. package/payload/server/public/assets/{src-Bi0fLV9t.js → src-DV4LKv2E.js} +1 -1
  266. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DkPLAqIh.js → stateDiagram-FHFEXIEX-D4R-n6bZ.js} +1 -1
  267. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BcFRbGRu.js +1 -0
  268. package/payload/server/public/assets/tasks-ClfJU1CK.js +1 -0
  269. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-DabKBJyd.js → timeline-definition-GMOUNBTQ-CjiHGP4l.js} +1 -1
  270. package/payload/server/public/assets/treeView-SZITEDCU-BtRr5vXp.js +1 -0
  271. package/payload/server/public/assets/treemap-W4RFUUIX-D8p0sbyo.js +1 -0
  272. package/payload/server/public/assets/useCopyFeedback-CPEOUSGU.js +1 -0
  273. package/payload/server/public/assets/useSubAccountSwitcher-CdS1CorH.css +1 -0
  274. package/payload/server/public/assets/useSubAccountSwitcher-DyjTbzQR.js +9 -0
  275. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-CaKT7c-c.js → vennDiagram-DHZGUBPP-CBdDQ7c-.js} +1 -1
  276. package/payload/server/public/assets/wardley-RL74JXVD-DgMn-9ZJ.js +1 -0
  277. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-BZ5TTSOL.js → wardleyDiagram-NUSXRM2D-BlIQPKLb.js} +1 -1
  278. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-CLfeklJ9.js → xychartDiagram-5P7HB3ND-CslKgh9B.js} +1 -1
  279. package/payload/server/public/browser.html +7 -5
  280. package/payload/server/public/calendar.html +8 -6
  281. package/payload/server/public/chat.html +14 -12
  282. package/payload/server/public/data.html +11 -10
  283. package/payload/server/public/graph.html +12 -10
  284. package/payload/server/public/index.html +15 -14
  285. package/payload/server/public/operator.html +16 -14
  286. package/payload/server/public/public.html +14 -12
  287. package/payload/server/public/tasks.html +18 -0
  288. package/payload/server/server.js +832 -233
  289. package/payload/server/public/assets/AdminLoginScreens-B1P6PrZ3.js +0 -1
  290. package/payload/server/public/assets/AdminShell-Y1fHQApK.js +0 -2
  291. package/payload/server/public/assets/Transcript-DZzFjhoq.js +0 -2
  292. package/payload/server/public/assets/admin-BRBjJEci.js +0 -1
  293. package/payload/server/public/assets/admin-types-hioowVct.js +0 -1
  294. package/payload/server/public/assets/architecture-YZFGNWBL-XiVs-N7Z.js +0 -1
  295. package/payload/server/public/assets/browser-ID7iqIi4.js +0 -1
  296. package/payload/server/public/assets/calendar-BEQPMTtd.js +0 -1
  297. package/payload/server/public/assets/channel-CYBkRz7E.js +0 -1
  298. package/payload/server/public/assets/chat-D0GDSWM-.js +0 -1
  299. package/payload/server/public/assets/chevron-left-A0HYKwGY.js +0 -1
  300. package/payload/server/public/assets/chunk-426QAEUC-CPhOHriU.js +0 -1
  301. package/payload/server/public/assets/chunk-QZHKN3VN-CDnAAZVJ.js +0 -1
  302. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BdXUKVrS.js +0 -1
  303. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DAq-uJr_.js +0 -1
  304. package/payload/server/public/assets/clone-DQl28-jK.js +0 -1
  305. package/payload/server/public/assets/data-CV38dClT.js +0 -1
  306. package/payload/server/public/assets/gitGraph-7Q5UKJZL-BM-KaDZy.js +0 -1
  307. package/payload/server/public/assets/graph-BK0MjKRy.js +0 -51
  308. package/payload/server/public/assets/info-OMHHGYJF-CtZajyAB.js +0 -1
  309. package/payload/server/public/assets/infoDiagram-42DDH7IO-C-_WYlmI.js +0 -2
  310. package/payload/server/public/assets/operator-CnpNyIJ8.js +0 -1
  311. package/payload/server/public/assets/packet-4T2RLAQJ-T-SYedp7.js +0 -1
  312. package/payload/server/public/assets/page-DC_L-IS1.js +0 -32
  313. package/payload/server/public/assets/page-DKHLflh7.js +0 -1
  314. package/payload/server/public/assets/pie-ZZUOXDRM-BWECFVVd.js +0 -1
  315. package/payload/server/public/assets/public-ByUJr48E.js +0 -1
  316. package/payload/server/public/assets/radar-PYXPWWZC-Dx0YUklX.js +0 -1
  317. package/payload/server/public/assets/rotate-ccw-D45TbeAI.js +0 -1
  318. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DceWO1u6.js +0 -1
  319. package/payload/server/public/assets/treeView-SZITEDCU-C3197Rac.js +0 -1
  320. package/payload/server/public/assets/treemap-W4RFUUIX-BPrpx29h.js +0 -1
  321. package/payload/server/public/assets/useSubAccountSwitcher-CCn22f98.css +0 -1
  322. package/payload/server/public/assets/useSubAccountSwitcher-CprHkBnZ.js +0 -9
  323. package/payload/server/public/assets/wardley-RL74JXVD-DW4Jlbhw.js +0 -1
  324. /package/payload/server/public/assets/{_baseFor-BVuIxZJh.js → _baseFor-D3BqAOBr.js} +0 -0
  325. /package/payload/server/public/assets/{array-B9UHiPd-.js → array-iYP9fzJp.js} +0 -0
  326. /package/payload/server/public/assets/{chunk-CAM3fms7.js → chunk-Ck5AOu5v.js} +0 -0
  327. /package/payload/server/public/assets/{cytoscape.esm-D5_TRwB-.js → cytoscape.esm-BQSBzPsB.js} +0 -0
  328. /package/payload/server/public/assets/{defaultLocale-5eAKkKJC.js → defaultLocale-BrdA1gDi.js} +0 -0
  329. /package/payload/server/public/assets/{init-DlZdxViB.js → init-Bx0S6pkp.js} +0 -0
  330. /package/payload/server/public/assets/{katex-Xo0SyWvP.js → katex-BsiH_a6d.js} +0 -0
  331. /package/payload/server/public/assets/{path-6uRLdFF7.js → path-BLSgTy3w.js} +0 -0
  332. /package/payload/server/public/assets/{preload-helper-CvXuAEud.js → preload-helper-ClBMtM1g.js} +0 -0
  333. /package/payload/server/public/assets/{rough.esm-Djo4Abte.js → rough.esm-BMOtDaaS.js} +0 -0
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env bash
2
+ # Regression test for datetime-inject.sh.
3
+ #
4
+ # The hook injects a fresh <datetime> block as UserPromptSubmit additionalContext
5
+ # every turn, reporting "now" in $MAXY_ACCOUNT_TZ (the operator's graph timezone,
6
+ # stamped at spawn) or the server zone when that env is empty.
7
+ #
8
+ # Covers:
9
+ # 1. MAXY_ACCOUNT_TZ set -> exit 0, valid JSON, additionalContext has
10
+ # the <datetime> block, the named zone, and a UTC: line; source=graph.
11
+ # 2. MAXY_ACCOUNT_TZ empty -> exit 0, block falls back to the server zone
12
+ # and labels source as server-timezone.
13
+ # 3. Breadcrumb -> $LOG_DIR/datetime-inject.log gains a line
14
+ # with source= and refresh=per-turn.
15
+ # 4. python3 absent -> exit 0, empty stdout (fail-open).
16
+ # 5. node absent -> exit 0, empty stdout (fail-open).
17
+
18
+ set -u
19
+
20
+ HOOK="$(cd "$(dirname "$0")/.." && pwd)/datetime-inject.sh"
21
+ if [[ ! -x "$HOOK" ]]; then
22
+ echo "FAIL: $HOOK not executable" >&2
23
+ exit 1
24
+ fi
25
+
26
+ PASS=0
27
+ FAIL=0
28
+ STDIN='{"hook_event_name":"UserPromptSubmit","prompt":"when is the meeting","session_id":"sess-abc123"}'
29
+
30
+ # Case 1 — MAXY_ACCOUNT_TZ set: block reports that zone, source=graph.
31
+ out=$(printf '%s' "$STDIN" | MAXY_ACCOUNT_TZ="Europe/London" LOG_DIR="" bash "$HOOK" 2>/dev/null); ex=$?
32
+ if [[ "$ex" -eq 0 ]] && printf '%s' "$out" | python3 -c '
33
+ import json, sys
34
+ d = json.load(sys.stdin)
35
+ h = d["hookSpecificOutput"]
36
+ assert h["hookEventName"] == "UserPromptSubmit", "wrong hookEventName"
37
+ ctx = h["additionalContext"]
38
+ assert "<datetime>" in ctx and "</datetime>" in ctx, "no datetime block"
39
+ assert "Europe/London" in ctx, "zone not named"
40
+ assert "UTC:" in ctx, "no UTC line"
41
+ assert "account-timezone" in ctx, "source label missing for graph tz"
42
+ ' 2>/dev/null; then
43
+ echo "PASS: MAXY_ACCOUNT_TZ set -> datetime block in named zone"; PASS=$((PASS+1))
44
+ else
45
+ echo "FAIL: graph-tz injection (exit=$ex stdout=$out)" >&2; FAIL=$((FAIL+1))
46
+ fi
47
+
48
+ # Case 2 — MAXY_ACCOUNT_TZ empty: falls back to the server zone, labels it.
49
+ out2=$(printf '%s' "$STDIN" | MAXY_ACCOUNT_TZ="" LOG_DIR="" bash "$HOOK" 2>/dev/null); ex2=$?
50
+ if [[ "$ex2" -eq 0 ]] && printf '%s' "$out2" | python3 -c '
51
+ import json, sys
52
+ ctx = json.load(sys.stdin)["hookSpecificOutput"]["additionalContext"]
53
+ assert "<datetime>" in ctx, "no datetime block"
54
+ assert "server-timezone" in ctx, "server fallback not labelled"
55
+ assert "UTC:" in ctx, "no UTC line"
56
+ ' 2>/dev/null; then
57
+ echo "PASS: empty MAXY_ACCOUNT_TZ -> server-zone fallback labelled"; PASS=$((PASS+1))
58
+ else
59
+ echo "FAIL: server fallback (exit=$ex2 stdout=$out2)" >&2; FAIL=$((FAIL+1))
60
+ fi
61
+
62
+ # Case 2b — MAXY_ACCOUNT_TZ set but NOT a real IANA zone: the node validation
63
+ # rejects it, falls back to the server zone, and labels the source neutrally as
64
+ # "unavailable" (never falsely "unset" — the value was present, just unusable).
65
+ out2b=$(printf '%s' "$STDIN" | MAXY_ACCOUNT_TZ="Not/AZone" LOG_DIR="" bash "$HOOK" 2>/dev/null); ex2b=$?
66
+ if [[ "$ex2b" -eq 0 ]] && printf '%s' "$out2b" | python3 -c '
67
+ import json, sys
68
+ ctx = json.load(sys.stdin)["hookSpecificOutput"]["additionalContext"]
69
+ assert "<datetime>" in ctx, "no datetime block"
70
+ assert "server-timezone (account timezone unavailable)" in ctx, "invalid tz not labelled unavailable"
71
+ assert "Not/AZone" not in ctx, "rejected zone leaked into the block"
72
+ ' 2>/dev/null; then
73
+ echo "PASS: set-but-invalid MAXY_ACCOUNT_TZ -> server fallback, labelled unavailable"; PASS=$((PASS+1))
74
+ else
75
+ echo "FAIL: invalid-tz fallback (exit=$ex2b stdout=$out2b)" >&2; FAIL=$((FAIL+1))
76
+ fi
77
+
78
+ # Case 3 — breadcrumb carries source= and refresh=per-turn.
79
+ LOGD=$(mktemp -d)
80
+ printf '%s' "$STDIN" | MAXY_ACCOUNT_TZ="Europe/London" LOG_DIR="$LOGD" bash "$HOOK" >/dev/null 2>&1
81
+ if [[ -f "$LOGD/datetime-inject.log" ]] \
82
+ && grep -q "\[datetime-inject\]" "$LOGD/datetime-inject.log" \
83
+ && grep -q "source=" "$LOGD/datetime-inject.log" \
84
+ && grep -q "refresh=per-turn" "$LOGD/datetime-inject.log"; then
85
+ echo "PASS: breadcrumb has source= and refresh=per-turn"; PASS=$((PASS+1))
86
+ else
87
+ echo "FAIL: breadcrumb missing (log=$(cat "$LOGD/datetime-inject.log" 2>/dev/null))" >&2; FAIL=$((FAIL+1))
88
+ fi
89
+ rm -rf "$LOGD"
90
+
91
+ # Case 4 — python3 absent -> fail-open (exit 0, empty stdout).
92
+ FAKEBIN=$(mktemp -d)
93
+ for util in cat printf env bash node date; do
94
+ src=$(command -v "$util" 2>/dev/null) && ln -sf "$src" "$FAKEBIN/$util" 2>/dev/null
95
+ done
96
+ nopy_out=$(printf '%s' "$STDIN" | PATH="$FAKEBIN" MAXY_ACCOUNT_TZ="Europe/London" bash "$HOOK" 2>/dev/null); nopy_exit=$?
97
+ if [[ "$nopy_exit" -eq 0 && -z "$nopy_out" ]]; then
98
+ echo "PASS: python3 absent -> exit 0, empty stdout (fail-open)"; PASS=$((PASS+1))
99
+ else
100
+ echo "FAIL: python3 absent (exit=$nopy_exit stdout=$nopy_out)" >&2; FAIL=$((FAIL+1))
101
+ fi
102
+ rm -rf "$FAKEBIN"
103
+
104
+ # Case 5 — node absent -> fail-open (exit 0, empty stdout).
105
+ FAKEBIN2=$(mktemp -d)
106
+ for util in cat printf env bash python3 date; do
107
+ src=$(command -v "$util" 2>/dev/null) && ln -sf "$src" "$FAKEBIN2/$util" 2>/dev/null
108
+ done
109
+ nonode_out=$(printf '%s' "$STDIN" | PATH="$FAKEBIN2" MAXY_ACCOUNT_TZ="Europe/London" bash "$HOOK" 2>/dev/null); nonode_exit=$?
110
+ if [[ "$nonode_exit" -eq 0 && -z "$nonode_out" ]]; then
111
+ echo "PASS: node absent -> exit 0, empty stdout (fail-open)"; PASS=$((PASS+1))
112
+ else
113
+ echo "FAIL: node absent (exit=$nonode_exit stdout=$nonode_out)" >&2; FAIL=$((FAIL+1))
114
+ fi
115
+ rm -rf "$FAKEBIN2"
116
+
117
+ echo "----"
118
+ echo "PASS=$PASS FAIL=$FAIL"
119
+ [[ "$FAIL" -eq 0 ]]
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env bash
2
+ # Task 1515 — UserPromptSubmit hook: inject a fresh <datetime> block as
3
+ # additionalContext on every turn, so the agent always has the current instant
4
+ # (date, time, timezone, weekday, and the raw UTC ISO) without hand-computing it
5
+ # and without depending on Claude Code's spawn-time "Today's date" line going
6
+ # stale. This is the per-turn current-time surface the datetime skill points at.
7
+ #
8
+ # The instant is computed fresh here every turn (refresh=per-turn). The timezone
9
+ # is NOT computed here — it is the operator's own zone, resolved from their
10
+ # UserProfile on the graph once per admin spawn and stamped into MAXY_ACCOUNT_TZ.
11
+ # When MAXY_ACCOUNT_TZ is empty (a non-admin turn, an unset profile timezone, or
12
+ # a neo4j hiccup at spawn) the block falls back to the server's own zone and
13
+ # labels the source, so a reader can always tell which clock the agent saw.
14
+ #
15
+ # Mirrors prompt-optimiser-directive.sh: emit hookSpecificOutput.additionalContext
16
+ # via python3, fail-open with exit 0 on every path. UserPromptSubmit output is
17
+ # ADDED to the prompt, never substituted — the raw prompt always still reaches
18
+ # the model.
19
+ #
20
+ # Input (stdin, UserPromptSubmit contract): { "session_id": "...", ... } —
21
+ # session_id is used only for the breadcrumb; the prompt text is ignored
22
+ # (the block is standing and prompt-independent).
23
+ # Output (stdout JSON):
24
+ # { "hookSpecificOutput": { "hookEventName": "UserPromptSubmit",
25
+ # "additionalContext": "<datetime>...</datetime>" } }
26
+
27
+ set -uo pipefail
28
+
29
+ # Drain stdin FIRST, before any exit path. Claude Code writes the full
30
+ # UserPromptSubmit payload (which carries the prompt text) to our stdin; if we
31
+ # exit before reading it, a payload larger than the pipe buffer leaves the parent
32
+ # blocked on write and then hit with EPIPE/SIGPIPE. The sibling
33
+ # prompt-optimiser-directive.sh drains first for this exact reason. Only
34
+ # session_id is used here (for the breadcrumb); the block is prompt-independent.
35
+ HOOK_INPUT=$(cat 2>/dev/null || true)
36
+
37
+ # Fail-open if either encoder is unavailable: python3 wraps the JSON envelope,
38
+ # node formats the instant in the target zone (Intl has the full IANA database).
39
+ command -v python3 >/dev/null 2>&1 || exit 0
40
+ command -v node >/dev/null 2>&1 || exit 0
41
+
42
+ # The operator's zone, stamped at spawn from the graph. Empty -> server zone.
43
+ ACCOUNT_TZ="${MAXY_ACCOUNT_TZ:-}"
44
+
45
+ # Format the current instant. node prints two tab-separated fields:
46
+ # 1. the resolved IANA zone actually used (so the server-fallback names a real
47
+ # zone, not the string "server")
48
+ # 2. the assembled block body
49
+ # TZ_IN is passed as argv[1]; empty means "use the runtime's own zone".
50
+ BLOCK=$(TZ_IN="$ACCOUNT_TZ" node -e '
51
+ const tzIn = process.env.TZ_IN && process.env.TZ_IN.trim().length ? process.env.TZ_IN.trim() : null;
52
+ const now = new Date();
53
+ // Resolve the zone actually used. A supplied zone that Intl rejects falls back
54
+ // to the runtime zone, so a bad stamp can never break the turn.
55
+ let zone = tzIn;
56
+ try { if (zone) new Intl.DateTimeFormat("en-GB", { timeZone: zone }); }
57
+ catch { zone = null; }
58
+ if (!zone) zone = Intl.DateTimeFormat().resolvedOptions().timeZone;
59
+ // zone === tzIn only when a non-empty, valid graph timezone was stamped; every
60
+ // other case (env empty on a non-admin turn, or a stamped value Intl rejected)
61
+ // falls back to the runtime zone. Label that neutrally as "unavailable" rather
62
+ // than asserting "unset" — the [datetime-tz] spawn log distinguishes unset from
63
+ // invalid from unavailable; here all the hook knows is the zone is not the graph one.
64
+ const source = tzIn && zone === tzIn ? "account-timezone (graph)" : "server-timezone (account timezone unavailable)";
65
+ const local = new Intl.DateTimeFormat("en-GB", {
66
+ weekday: "long", day: "numeric", month: "long", year: "numeric",
67
+ hour: "2-digit", minute: "2-digit", timeZone: zone, timeZoneName: "longOffset",
68
+ }).format(now);
69
+ const body = [
70
+ "Current date and time, read this rather than computing it by hand:",
71
+ "Now: " + local + " (" + zone + ")",
72
+ "UTC: " + now.toISOString(),
73
+ "Source: " + source,
74
+ ].join("\n");
75
+ process.stdout.write(zone + "\t" + body);
76
+ ' 2>/dev/null) || exit 0
77
+
78
+ [ -n "$BLOCK" ] || exit 0
79
+ ZONE_USED="${BLOCK%%$'\t'*}"
80
+ BODY="${BLOCK#*$'\t'}"
81
+ CONTEXT="<datetime>
82
+ $BODY
83
+ </datetime>"
84
+
85
+ OUT=$(printf '%s' "$CONTEXT" | python3 -c '
86
+ import json, sys
87
+ ctx = sys.stdin.read()
88
+ print(json.dumps({
89
+ "hookSpecificOutput": {
90
+ "hookEventName": "UserPromptSubmit",
91
+ "additionalContext": ctx,
92
+ }
93
+ }))
94
+ ' 2>/dev/null) || exit 0
95
+
96
+ [ -n "$OUT" ] || exit 0
97
+ printf '%s\n' "$OUT"
98
+
99
+ # Breadcrumb: source (graph vs server-fallback) + refresh=per-turn so a future
100
+ # staleness report can tell which clock was live each turn without reproduction.
101
+ # Fail-open: a missing/unwritable LOG_DIR just skips the write.
102
+ SID=$(printf '%s' "$HOOK_INPUT" | python3 -c 'import json,sys
103
+ try:
104
+ print(json.load(sys.stdin).get("session_id","") or "?")
105
+ except Exception:
106
+ print("?")' 2>/dev/null)
107
+ SID=${SID:-?}
108
+ if [ -n "$ACCOUNT_TZ" ] && [ "$ZONE_USED" = "$ACCOUNT_TZ" ]; then SRC=graph; else SRC=server-fallback; fi
109
+ NOW_ISO=$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || echo "?")
110
+ LINE="$NOW_ISO [datetime-inject] injected tz=$ZONE_USED source=$SRC refresh=per-turn session=$SID"
111
+ if [ -n "${LOG_DIR:-}" ] && [ -d "$LOG_DIR" ]; then
112
+ printf '%s\n' "$LINE" >> "$LOG_DIR/datetime-inject.log" 2>/dev/null || true
113
+ fi
114
+ echo "$LINE" >&2 || true
115
+ exit 0
@@ -27,7 +27,7 @@ import { publishSite } from "./tools/publish-site.js";
27
27
  import { resolveCapabilitiesHere } from "./tools/capabilities-here.js";
28
28
  import { runCatalogueCensus } from "./lib/catalogue-census.js";
29
29
  import { lifelineTool } from "../../../../lib/mcp-lifeline/dist/index.js";
30
- import { listAccountsFromDir, isHouseAccount, archiveAccountDir, provisionClientAccount, findHouseAccount, getChannelRoutingAccountId, setChannelRoutingAccountId, seedAccountGraphRoot, ACCOUNT_NODE_COUNT_CYPHER, ACCOUNT_PURGE_CYPHER, } from "./tools/account-lifecycle.js";
30
+ import { listAccountsFromDir, isHouseAccount, archiveAccountDir, provisionClientAccount, findHouseAccount, getChannelRoutingAccountId, setChannelRoutingAccountId, seedAccountGraphRoot, readHouseAdminUserIds, setManagingAdmin, findClientAccountsManagedBy, reassignManagingAdmin, ACCOUNT_NODE_COUNT_CYPHER, ACCOUNT_PURGE_CYPHER, } from "./tools/account-lifecycle.js";
31
31
  function refusalGuidance(kind) {
32
32
  switch (kind) {
33
33
  case "unsafe-slug":
@@ -1085,6 +1085,17 @@ eagerTool(server, "admin-remove", "Remove an admin from this account. Removes th
1085
1085
  if (admins.length <= 1) {
1086
1086
  return { content: [{ type: "text", text: `${TAG} Cannot remove the last admin. At least one admin must remain on the account.` }], isError: true };
1087
1087
  }
1088
+ // Task 1501 — never orphan a managed sub-account. A managing admin is always a
1089
+ // house admin, so this bites only when removing from the house account: if
1090
+ // `userId` is the managing admin of any client sub-account, refuse and name
1091
+ // them so the operator reassigns each (account_reassign_admin) before retrying.
1092
+ if (isHouseAccount(ACCOUNTS_ROOT, ACCOUNT_ID)) {
1093
+ const managed = findClientAccountsManagedBy(ACCOUNTS_ROOT, userId);
1094
+ if (managed.length > 0) {
1095
+ process.stderr.write(`[account-lifecycle] op=admin-remove-reconcile userId=${userId.slice(0, 8)} managedAccounts=${managed.length} action=blocked\n`);
1096
+ return { content: [{ type: "text", text: `${TAG} Cannot remove ${userId}: they are the managing admin of ${managed.length} client sub-account(s): ${managed.join(", ")}. Reassign each to another house admin with account_reassign_admin, then retry.` }], isError: true };
1097
+ }
1098
+ }
1088
1099
  // Resolve the admin's name from Neo4j (canonical) for the confirmation
1089
1100
  // message. Best-effort — fall back to userId if the graph is unreachable.
1090
1101
  let removedName = userId;
@@ -3256,9 +3267,23 @@ eagerTool(server, "account_list", "List every sub-account on this install (one h
3256
3267
  content: [{ type: "text", text: accounts.length ? lines.join("\n") : "No accounts found." }],
3257
3268
  };
3258
3269
  });
3259
- eagerTool(server, "account_create", "Provision a new CLIENT sub-account on this install (managed service). Mints a UUID, scaffolds the account directory (agents, specialists, settings, account.json with role:\"client\"), seeds default plugins, and seeds the account's graph root (a :LocalBusiness plus its owner :AdminUser) so you can populate it immediately. Returns the new accountId. Operator-only; never creates the house sub-account (that is the install itself).", {}, async () => {
3270
+ eagerTool(server, "account_create", "Provision a new CLIENT sub-account on this install (managed service). REQUIRES a managing admin: pass `adminUserId`, the userId of the house team member who will manage this client (get the choices from admin-list; ask the operator which one before creating). Mints a UUID, scaffolds the account directory (agents, specialists, settings, account.json with role:\"client\" and managingAdminUserId), seeds default plugins, and seeds the account's graph root (a :LocalBusiness plus its owner :AdminUser) so you can populate it immediately. Refuses if no adminUserId is given or if it is not a current house admin. Returns the new accountId. Operator-only; never creates the house sub-account (that is the install itself).", {
3271
+ adminUserId: z.string().describe("The userId of the house admin who will manage this client sub-account. Must be a current house admin (see admin-list). Required — creation is refused without it."),
3272
+ }, async ({ adminUserId }) => {
3260
3273
  if (!ACCOUNT_ID)
3261
3274
  return refuseNoAccount("account_create");
3275
+ // Task 1500 — every client sub-account must carry a responsible house admin.
3276
+ // Refuse (tool error, never a silent default) when none is named, or when
3277
+ // the named userId is not a current house admin.
3278
+ if (!adminUserId || !adminUserId.trim()) {
3279
+ process.stderr.write(`[account-lifecycle] op=create-refused reason=no-admin adminUserId=-\n`);
3280
+ return { content: [{ type: "text", text: `account_create refused: name the managing house admin (adminUserId). Call admin-list to see the choices and ask the operator which one manages this client.` }], isError: true };
3281
+ }
3282
+ const houseAdminUserIds = readHouseAdminUserIds(ACCOUNTS_ROOT);
3283
+ if (!houseAdminUserIds.includes(adminUserId)) {
3284
+ process.stderr.write(`[account-lifecycle] op=create-refused reason=unknown-admin adminUserId=${adminUserId.slice(0, 8)}\n`);
3285
+ return { content: [{ type: "text", text: `account_create refused: ${adminUserId} is not a current house admin. Call admin-list for the valid managing-admin choices.` }], isError: true };
3286
+ }
3262
3287
  const newId = randomUUID();
3263
3288
  try {
3264
3289
  const accountDir = provisionClientAccount({
@@ -3302,11 +3327,26 @@ eagerTool(server, "account_create", "Provision a new CLIENT sub-account on this
3302
3327
  finally {
3303
3328
  await seedSession.close();
3304
3329
  }
3305
- process.stderr.write(`[account-lifecycle] op=create accountId=${newId} dir-exists=${dirExists} root-seeded=${rootSeeded}\n`);
3330
+ process.stderr.write(`[account-lifecycle] op=create accountId=${newId} dir-exists=${dirExists} root-seeded=${rootSeeded} managingAdmin=${adminUserId.slice(0, 8)}\n`);
3306
3331
  if (!rootSeeded) {
3307
3332
  return { content: [{ type: "text", text: `account_create FAILED: graph root not seeded for ${newId} (business+admin read-back failed). The account directory was scaffolded but is rootless — run account_delete ${newId} and retry.` }], isError: true };
3308
3333
  }
3309
- return { content: [{ type: "text", text: `Created client sub-account ${newId}. Switch to it from the sub-account picker to work in its data.` }] };
3334
+ // Task 1500 persist the validated managing admin on the new sub-account.
3335
+ // Done after the root seed so a rootless failure never leaves a half-created
3336
+ // account claiming a manager. Its own try: at this point the account is
3337
+ // fully created and seeded, so a write failure must not be reported as a
3338
+ // generic create failure (which would push the operator to retry and
3339
+ // orphan a second account). Report the real state — created but unmanaged —
3340
+ // with the recovery action.
3341
+ try {
3342
+ setManagingAdmin(ACCOUNTS_ROOT, newId, adminUserId);
3343
+ }
3344
+ catch (err) {
3345
+ const msg = err instanceof Error ? err.message : String(err);
3346
+ process.stderr.write(`[account-lifecycle] op=create-admin-write-failed accountId=${newId} error=${msg}\n`);
3347
+ return { content: [{ type: "text", text: `account_create: sub-account ${newId} was created and its graph root seeded, but recording the managing admin failed: ${msg}. The account exists with no managing admin — run account_delete ${newId} and retry.` }], isError: true };
3348
+ }
3349
+ return { content: [{ type: "text", text: `Created client sub-account ${newId}, managed by admin ${adminUserId}. Switch to it from the sub-account picker to work in its data.` }] };
3310
3350
  }
3311
3351
  catch (err) {
3312
3352
  const msg = err instanceof Error ? err.message : String(err);
@@ -3314,6 +3354,24 @@ eagerTool(server, "account_create", "Provision a new CLIENT sub-account on this
3314
3354
  return { content: [{ type: "text", text: `account_create FAILED: ${msg}` }], isError: true };
3315
3355
  }
3316
3356
  });
3357
+ eagerTool(server, "account_reassign_admin", "Reassign a CLIENT sub-account's managing house admin. Pass `accountId` (the client sub-account) and `adminUserId` (the new managing admin's userId — must be a current house admin; get the choices from admin-list and ask the operator which team member takes it). Rewrites the sub-account's managingAdminUserId; the new admin is picked up on the next passive intake. Use it to repair a dangling managing admin (one whose house admin was removed) or to hand a client to a different team member. Refuses if the account is not a client sub-account, or if adminUserId is not a current house admin. Operator-only.", {
3358
+ accountId: z.string().describe("The client sub-account (UUID) whose managing admin changes."),
3359
+ adminUserId: z.string().describe("The userId of the house admin to become the managing admin. Must be a current house admin (see admin-list)."),
3360
+ }, async ({ accountId, adminUserId }) => {
3361
+ if (!ACCOUNT_ID)
3362
+ return refuseNoAccount("account_reassign_admin");
3363
+ const res = reassignManagingAdmin(ACCOUNTS_ROOT, accountId, adminUserId);
3364
+ if (!res.ok) {
3365
+ const msg = res.reason === "no-account"
3366
+ ? `${accountId} is not a registered account on this install.`
3367
+ : res.reason === "not-client"
3368
+ ? `${accountId} is not a client sub-account (the house account has no managing admin).`
3369
+ : `${adminUserId} is not a current house admin. Call admin-list for the valid managing-admin choices.`;
3370
+ return { content: [{ type: "text", text: `account_reassign_admin refused: ${msg}` }], isError: true };
3371
+ }
3372
+ process.stderr.write(`[account-lifecycle] op=reassign accountId=${accountId} from=${res.previousAdminUserId ? res.previousAdminUserId.slice(0, 8) : "-"} to=${adminUserId.slice(0, 8)}\n`);
3373
+ return { content: [{ type: "text", text: `Reassigned client sub-account ${accountId} to managing admin ${adminUserId}. It takes effect on the next passive intake.` }] };
3374
+ });
3317
3375
  eagerTool(server, "account_delete", "Archive a CLIENT sub-account: move its directory to data/accounts/.trash/ so it no longer appears in the sub-account list. Graph data is RETAINED — run account_purge with the typed confirmation to irreversibly delete it. Refuses to archive the house sub-account. Pass the accountId to archive.", {
3318
3376
  accountId: z.string().describe("The client accountId (UUID) to archive."),
3319
3377
  }, async ({ accountId }) => {