@rubytech/create-sitedesk-code 0.1.529 → 0.1.530
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +13 -0
- package/package.json +1 -1
- package/payload/platform/lib/routine-templates/dist/index.d.ts +19 -3
- package/payload/platform/lib/routine-templates/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/routine-templates/dist/index.js +22 -4
- package/payload/platform/lib/routine-templates/dist/index.js.map +1 -1
- package/payload/platform/lib/routine-templates/dist/roster.d.ts +19 -6
- package/payload/platform/lib/routine-templates/dist/roster.d.ts.map +1 -1
- package/payload/platform/lib/routine-templates/dist/roster.js +127 -17
- package/payload/platform/lib/routine-templates/dist/roster.js.map +1 -1
- package/payload/platform/lib/routine-templates/src/__tests__/roster.test.ts +46 -3
- package/payload/platform/lib/routine-templates/src/__tests__/seed.test.ts +52 -10
- package/payload/platform/lib/routine-templates/src/index.ts +30 -4
- package/payload/platform/lib/routine-templates/src/roster.ts +147 -17
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +7 -3
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +6 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +6 -2
- package/payload/platform/plugins/scheduling/PLUGIN.md +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +5 -0
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/normalise-start-date.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/normalise-start-date.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/normalise-start-date.test.js +100 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/normalise-start-date.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/dispatcher-env.d.ts +36 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/dispatcher-env.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/dispatcher-env.js +82 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/dispatcher-env.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/time-format.d.ts +31 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/time-format.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/time-format.js +99 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/time-format.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +12 -12
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/converge-startdate-utc.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/converge-startdate-utc.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/converge-startdate-utc.test.js +79 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/converge-startdate-utc.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/dispatch-lateness.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/dispatch-lateness.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/dispatch-lateness.test.js +23 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/dispatch-lateness.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js +61 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +33 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +96 -7
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +21 -69
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/converge-startdate-utc.d.ts +24 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/converge-startdate-utc.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/converge-startdate-utc.js +87 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/converge-startdate-utc.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-startdate.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-startdate.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-startdate.test.js +123 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-startdate.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-startdate.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-startdate.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-startdate.test.js +71 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-startdate.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-status.test.js +14 -3
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-status.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +9 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +19 -3
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js +24 -9
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
- package/payload/server/{chunk-UTIHI6KV.js → chunk-2YMGNYA3.js} +12 -12
- package/payload/server/{manager-B4LRDZKC.js → manager-XPRN5UF5.js} +1 -1
- package/payload/server/package.json +1 -1
- package/payload/server/public/activity.html +5 -5
- package/payload/server/public/agents.html +4 -4
- package/payload/server/public/assets/{AdminLoginScreens-zfexKfbT.js → AdminLoginScreens-7Czw3MAC.js} +1 -1
- package/payload/server/public/assets/AdminLoginScreens-7Czw3MAC.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-7Czw3MAC.js.gz +0 -0
- package/payload/server/public/assets/{AdminShell-Cbk0TL1B.js → AdminShell-D5GApZ_n.js} +1 -1
- package/payload/server/public/assets/AdminShell-D5GApZ_n.js.br +0 -0
- package/payload/server/public/assets/AdminShell-D5GApZ_n.js.gz +0 -0
- package/payload/server/public/assets/{CdpScreencastSurface-CLSQHh4e.js → CdpScreencastSurface-BbekDUFw.js} +1 -1
- package/payload/server/public/assets/CdpScreencastSurface-BbekDUFw.js.br +0 -0
- package/payload/server/public/assets/CdpScreencastSurface-BbekDUFw.js.gz +0 -0
- package/payload/server/public/assets/{activity-u275Oc-u.js → activity-ClI-RgJu.js} +1 -1
- package/payload/server/public/assets/activity-ClI-RgJu.js.br +0 -0
- package/payload/server/public/assets/activity-ClI-RgJu.js.gz +0 -0
- package/payload/server/public/assets/{admin-Du1nR_hP.js → admin-svtCmBPk.js} +1 -1
- package/payload/server/public/assets/admin-svtCmBPk.js.br +0 -0
- package/payload/server/public/assets/admin-svtCmBPk.js.gz +0 -0
- package/payload/server/public/assets/{agents-DJTxRLLU.js → agents-BO8YBj8d.js} +1 -1
- package/payload/server/public/assets/agents-BO8YBj8d.js.br +0 -0
- package/payload/server/public/assets/agents-BO8YBj8d.js.gz +0 -0
- package/payload/server/public/assets/{browser-Bft6zVkX.js → browser-Bj8oTG5R.js} +1 -1
- package/payload/server/public/assets/browser-Bj8oTG5R.js.br +0 -0
- package/payload/server/public/assets/browser-Bj8oTG5R.js.gz +0 -0
- package/payload/server/public/assets/{calendar-Ct-DCCqY.js → calendar-CrkSY8U7.js} +1 -1
- package/payload/server/public/assets/calendar-CrkSY8U7.js.br +0 -0
- package/payload/server/public/assets/calendar-CrkSY8U7.js.gz +0 -0
- package/payload/server/public/assets/chat-Bvxoni2e.js +1 -0
- package/payload/server/public/assets/chat-Bvxoni2e.js.br +0 -0
- package/payload/server/public/assets/chat-Bvxoni2e.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-CdUzxzeB.js +1 -0
- package/payload/server/public/assets/chevron-left-CdUzxzeB.js.br +0 -0
- package/payload/server/public/assets/chevron-right-CKGwd-M0.js +1 -0
- package/payload/server/public/assets/chevron-right-CKGwd-M0.js.br +0 -0
- package/payload/server/public/assets/clock-Cf8Oe9qi.js +1 -0
- package/payload/server/public/assets/clock-Cf8Oe9qi.js.br +0 -0
- package/payload/server/public/assets/clock-Cf8Oe9qi.js.gz +0 -0
- package/payload/server/public/assets/data-DF0Pstdp.js +1 -0
- package/payload/server/public/assets/data-DF0Pstdp.js.br +1 -0
- package/payload/server/public/assets/data-DF0Pstdp.js.gz +0 -0
- package/payload/server/public/assets/{file-download-C_fSe4dm.js → file-download-Di_s0_4w.js} +1 -1
- package/payload/server/public/assets/file-download-Di_s0_4w.js.br +0 -0
- package/payload/server/public/assets/file-download-Di_s0_4w.js.gz +0 -0
- package/payload/server/public/assets/{file-text-D7GbEcqj.js → file-text-CP1KIrJV.js} +1 -1
- package/payload/server/public/assets/file-text-CP1KIrJV.js.br +1 -0
- package/payload/server/public/assets/file-text-CP1KIrJV.js.gz +0 -0
- package/payload/server/public/assets/{graph-yl5qU1kO.js → graph-BCMscnCV.js} +1 -1
- package/payload/server/public/assets/graph-BCMscnCV.js.br +0 -0
- package/payload/server/public/assets/graph-BCMscnCV.js.gz +0 -0
- package/payload/server/public/assets/{graph-labels-Dlcb6cW7.js → graph-labels-CgP17xHK.js} +1 -1
- package/payload/server/public/assets/graph-labels-CgP17xHK.js.br +0 -0
- package/payload/server/public/assets/graph-labels-CgP17xHK.js.gz +0 -0
- package/payload/server/public/assets/{maximize-2-BS689r4W.js → maximize-2-DkQzDv-g.js} +1 -1
- package/payload/server/public/assets/maximize-2-DkQzDv-g.js.br +0 -0
- package/payload/server/public/assets/maximize-2-DkQzDv-g.js.gz +0 -0
- package/payload/server/public/assets/{operator-CvapnpIW.js → operator-CLbCar9e.js} +1 -1
- package/payload/server/public/assets/operator-CLbCar9e.js.br +0 -0
- package/payload/server/public/assets/operator-CLbCar9e.js.gz +0 -0
- package/payload/server/public/assets/{page-DWkUH4Z_.js → page-CNJl3tWT.js} +1 -1
- package/payload/server/public/assets/page-CNJl3tWT.js.br +0 -0
- package/payload/server/public/assets/page-CNJl3tWT.js.gz +0 -0
- package/payload/server/public/assets/{page-987y4JbQ.js → page-CPVUAwb8.js} +1 -1
- package/payload/server/public/assets/page-CPVUAwb8.js.br +0 -0
- package/payload/server/public/assets/page-CPVUAwb8.js.gz +0 -0
- package/payload/server/public/assets/{public-D5pi-VFn.js → public-DQea3Ybz.js} +1 -1
- package/payload/server/public/assets/public-DQea3Ybz.js.br +0 -0
- package/payload/server/public/assets/public-DQea3Ybz.js.gz +0 -0
- package/payload/server/public/assets/{rotate-ccw-zNxnK36R.js → rotate-ccw-DPw0vXC0.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-DPw0vXC0.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-DPw0vXC0.js.gz +0 -0
- package/payload/server/public/assets/{routines-mZzrGA5y.js → routines-CwiiYpfK.js} +2 -2
- package/payload/server/public/assets/routines-CwiiYpfK.js.br +0 -0
- package/payload/server/public/assets/routines-CwiiYpfK.js.gz +0 -0
- package/payload/server/public/assets/{skills-5A8PockT.js → skills-0FOjKUM-.js} +1 -1
- package/payload/server/public/assets/skills-0FOjKUM-.js.br +0 -0
- package/payload/server/public/assets/skills-0FOjKUM-.js.gz +0 -0
- package/payload/server/public/assets/{tasks-B1_2wc6L.js → tasks-BUVsPEGm.js} +1 -1
- package/payload/server/public/assets/tasks-BUVsPEGm.js.br +0 -0
- package/payload/server/public/assets/tasks-BUVsPEGm.js.gz +0 -0
- package/payload/server/public/assets/{time-entry-format-CJ2FSSQt.js → time-entry-format-B6fX_19a.js} +1 -1
- package/payload/server/public/assets/time-entry-format-B6fX_19a.js.br +0 -0
- package/payload/server/public/assets/time-entry-format-B6fX_19a.js.gz +0 -0
- package/payload/server/public/assets/{triangle-alert-CedsrgME.js → triangle-alert-vAaSDhVq.js} +1 -1
- package/payload/server/public/assets/triangle-alert-vAaSDhVq.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-vAaSDhVq.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-zjZZUC2-.js → useCopyFeedback-BvIRgs7W.js} +1 -1
- package/payload/server/public/assets/useCopyFeedback-BvIRgs7W.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-BvIRgs7W.js.gz +0 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-72THldvm.css → useSubAccountSwitcher-DM5Y9eio.css} +1 -1
- package/payload/server/public/assets/useSubAccountSwitcher-DM5Y9eio.css.br +0 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-72THldvm.css.gz → useSubAccountSwitcher-DM5Y9eio.css.gz} +0 -0
- package/payload/server/public/assets/{useVoiceRecorder-CJecnefX.js → useVoiceRecorder-CiDOh8PG.js} +1 -1
- package/payload/server/public/assets/useVoiceRecorder-CiDOh8PG.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-CiDOh8PG.js.gz +0 -0
- package/payload/server/public/assets/{wrench-D8BH20W8.js → wrench-BNBtwT2p.js} +1 -1
- package/payload/server/public/assets/wrench-BNBtwT2p.js.br +0 -0
- package/payload/server/public/assets/wrench-BNBtwT2p.js.gz +0 -0
- package/payload/server/public/browser.html +5 -5
- package/payload/server/public/calendar.html +7 -7
- package/payload/server/public/chat.html +13 -13
- package/payload/server/public/data.html +12 -12
- package/payload/server/public/graph.html +9 -9
- package/payload/server/public/index.html +16 -16
- package/payload/server/public/operator.html +15 -15
- package/payload/server/public/public.html +13 -13
- package/payload/server/public/routines.html +7 -7
- package/payload/server/public/skills.html +5 -5
- package/payload/server/public/tasks.html +6 -6
- package/payload/server/server.js +10 -4
- package/payload/server/public/assets/AdminLoginScreens-zfexKfbT.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-zfexKfbT.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-Cbk0TL1B.js.br +0 -0
- package/payload/server/public/assets/AdminShell-Cbk0TL1B.js.gz +0 -0
- package/payload/server/public/assets/CdpScreencastSurface-CLSQHh4e.js.br +0 -0
- package/payload/server/public/assets/CdpScreencastSurface-CLSQHh4e.js.gz +0 -0
- package/payload/server/public/assets/activity-u275Oc-u.js.br +0 -0
- package/payload/server/public/assets/activity-u275Oc-u.js.gz +0 -0
- package/payload/server/public/assets/admin-Du1nR_hP.js.br +0 -0
- package/payload/server/public/assets/admin-Du1nR_hP.js.gz +0 -0
- package/payload/server/public/assets/agents-DJTxRLLU.js.br +0 -0
- package/payload/server/public/assets/agents-DJTxRLLU.js.gz +0 -0
- package/payload/server/public/assets/browser-Bft6zVkX.js.br +0 -0
- package/payload/server/public/assets/browser-Bft6zVkX.js.gz +0 -0
- package/payload/server/public/assets/calendar-Ct-DCCqY.js.br +0 -0
- package/payload/server/public/assets/calendar-Ct-DCCqY.js.gz +0 -0
- package/payload/server/public/assets/chat-pqasbAg8.js +0 -1
- package/payload/server/public/assets/chat-pqasbAg8.js.br +0 -0
- package/payload/server/public/assets/chat-pqasbAg8.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-C8LTc7lb.js +0 -1
- package/payload/server/public/assets/chevron-right-Lz9t7Hed.js +0 -1
- package/payload/server/public/assets/chevron-right-Lz9t7Hed.js.br +0 -0
- package/payload/server/public/assets/clock-D6QQFHwJ.js +0 -1
- package/payload/server/public/assets/clock-D6QQFHwJ.js.br +0 -0
- package/payload/server/public/assets/clock-D6QQFHwJ.js.gz +0 -0
- package/payload/server/public/assets/data-B1JJ3Y1T.js +0 -1
- package/payload/server/public/assets/data-B1JJ3Y1T.js.br +0 -0
- package/payload/server/public/assets/data-B1JJ3Y1T.js.gz +0 -0
- package/payload/server/public/assets/file-download-C_fSe4dm.js.br +0 -0
- package/payload/server/public/assets/file-download-C_fSe4dm.js.gz +0 -0
- package/payload/server/public/assets/file-text-D7GbEcqj.js.br +0 -0
- package/payload/server/public/assets/file-text-D7GbEcqj.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-Dlcb6cW7.js.br +0 -0
- package/payload/server/public/assets/graph-labels-Dlcb6cW7.js.gz +0 -0
- package/payload/server/public/assets/graph-yl5qU1kO.js.br +0 -0
- package/payload/server/public/assets/graph-yl5qU1kO.js.gz +0 -0
- package/payload/server/public/assets/maximize-2-BS689r4W.js.br +0 -0
- package/payload/server/public/assets/maximize-2-BS689r4W.js.gz +0 -0
- package/payload/server/public/assets/operator-CvapnpIW.js.br +0 -0
- package/payload/server/public/assets/operator-CvapnpIW.js.gz +0 -0
- package/payload/server/public/assets/page-987y4JbQ.js.br +0 -0
- package/payload/server/public/assets/page-987y4JbQ.js.gz +0 -0
- package/payload/server/public/assets/page-DWkUH4Z_.js.br +0 -0
- package/payload/server/public/assets/page-DWkUH4Z_.js.gz +0 -0
- package/payload/server/public/assets/public-D5pi-VFn.js.br +0 -0
- package/payload/server/public/assets/public-D5pi-VFn.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-zNxnK36R.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-zNxnK36R.js.gz +0 -0
- package/payload/server/public/assets/routines-mZzrGA5y.js.br +0 -0
- package/payload/server/public/assets/routines-mZzrGA5y.js.gz +0 -0
- package/payload/server/public/assets/skills-5A8PockT.js.br +0 -0
- package/payload/server/public/assets/skills-5A8PockT.js.gz +0 -0
- package/payload/server/public/assets/tasks-B1_2wc6L.js.br +0 -0
- package/payload/server/public/assets/tasks-B1_2wc6L.js.gz +0 -0
- package/payload/server/public/assets/time-entry-format-CJ2FSSQt.js.br +0 -0
- package/payload/server/public/assets/time-entry-format-CJ2FSSQt.js.gz +0 -0
- package/payload/server/public/assets/triangle-alert-CedsrgME.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-CedsrgME.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-zjZZUC2-.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-zjZZUC2-.js.gz +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-72THldvm.css.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-CJecnefX.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-CJecnefX.js.gz +0 -0
- package/payload/server/public/assets/wrench-D8BH20W8.js.br +0 -0
- package/payload/server/public/assets/wrench-D8BH20W8.js.gz +0 -0
- /package/payload/server/public/assets/{useSubAccountSwitcher-HjQZjJBr.js → useSubAccountSwitcher-BEwQMRMo.js} +0 -0
- /package/payload/server/public/assets/{useSubAccountSwitcher-HjQZjJBr.js.br → useSubAccountSwitcher-BEwQMRMo.js.br} +0 -0
- /package/payload/server/public/assets/{useSubAccountSwitcher-HjQZjJBr.js.gz → useSubAccountSwitcher-BEwQMRMo.js.gz} +0 -0
package/dist/index.js
CHANGED
|
@@ -3385,6 +3385,19 @@ function setupAccount() {
|
|
|
3385
3385
|
logFile(` [neo4j] passing NEO4J_URI=${neo4jUri} to seed`);
|
|
3386
3386
|
shell("bash", [seedScript], { cwd: INSTALL_DIR, env: neo4jEnv });
|
|
3387
3387
|
}
|
|
3388
|
+
// Task 2213 — converge :Event.startDate onto canonical UTC. The dispatcher
|
|
3389
|
+
// compares startDate to new Date().toISOString() LEXICALLY, so a row storing
|
|
3390
|
+
// a +01:00 offset fires 60 minutes late under BST. Runs after the seed so the
|
|
3391
|
+
// schema exists, with the same Neo4j env, and needs PLATFORM_ROOT to scope
|
|
3392
|
+
// itself to this install's accounts on a shared Neo4j. Idempotent: a converged
|
|
3393
|
+
// install rewrites nothing and prints op=done rewritten=0.
|
|
3394
|
+
const convergeStartDate = join(INSTALL_DIR, "platform/plugins/scheduling/mcp/dist/scripts/converge-startdate-utc.js");
|
|
3395
|
+
if (existsSync(convergeStartDate)) {
|
|
3396
|
+
shell("node", [convergeStartDate], {
|
|
3397
|
+
cwd: INSTALL_DIR,
|
|
3398
|
+
env: { ...neo4jEnv, PLATFORM_ROOT: join(INSTALL_DIR, "platform") },
|
|
3399
|
+
});
|
|
3400
|
+
}
|
|
3388
3401
|
// Task 165 — register every bundled specialist subagent at
|
|
3389
3402
|
// $CLAUDE_CONFIG_DIR/agents/<name>.md. Claude Code's `--agent <name>`
|
|
3390
3403
|
// discovery only resolves under this path; without these symlinks,
|
package/package.json
CHANGED
|
@@ -70,6 +70,14 @@ export interface RoutineVerifyCounts {
|
|
|
70
70
|
actual: number;
|
|
71
71
|
suspended: number;
|
|
72
72
|
nextRunNull: number;
|
|
73
|
+
/** Task 2214 — roster rows holding no description. Zero is the healthy value
|
|
74
|
+
* on every account, not only a fresh one: `VERIFY_CYPHER` matches
|
|
75
|
+
* `routineTemplate IS NOT NULL`, so operator-created routines are outside
|
|
76
|
+
* its scope and cannot contribute, and `ON MATCH` writes the description
|
|
77
|
+
* unconditionally, so an operator-edited row is covered too. Anything above
|
|
78
|
+
* zero while `expected === actual` is a MERGE that wrote no description —
|
|
79
|
+
* the one failure here that emits no error and does not reproduce. */
|
|
80
|
+
descNull: number;
|
|
73
81
|
}
|
|
74
82
|
export interface RoutineSeedReport {
|
|
75
83
|
accountId: string;
|
|
@@ -114,11 +122,19 @@ export declare function resolveOwnerTimezone(session: SeedSessionLike, accountId
|
|
|
114
122
|
* `agentChannel`, not `agentDestination`, not `recurrence`, not `timezone`. A
|
|
115
123
|
* re-seed on upgrade must not re-suspend an enabled routine, unbind a bound
|
|
116
124
|
* destination, or reset a retimed cron. Only the prompt, the name and the
|
|
117
|
-
* version move, and only when the row is behind and unedited.
|
|
118
|
-
|
|
125
|
+
* version move, and only when the row is behind and unedited.
|
|
126
|
+
*
|
|
127
|
+
* `routineDescription` (Task 2214) is the one property ON MATCH writes on
|
|
128
|
+
* every match rather than only on the refresh branch, and that is not an
|
|
129
|
+
* exception to the rule above. It is roster-owned: the routines route projects
|
|
130
|
+
* it but its PATCH field set refuses it, so no operator edit exists for this
|
|
131
|
+
* to overwrite. Gating it on `refreshing` would leave every operator-edited
|
|
132
|
+
* row description-less permanently, because `skip-operator-edited` takes
|
|
133
|
+
* neither branch, and that row's card would show a title and nothing else. */
|
|
134
|
+
export declare const MERGE_CYPHER = "\nUNWIND $rows AS row\nOPTIONAL MATCH (pre:Event {accountId: $accountId, routineTemplate: row.key})\nWITH row,\n pre IS NOT NULL AS existed,\n coalesce(pre.routineTemplateVersion, 0) AS priorVersion,\n pre.operatorEdited IS NOT NULL AS edited\nWITH row, existed, priorVersion, edited,\n (existed AND NOT edited AND priorVersion < $version) AS refreshing\nMERGE (e:Event {accountId: $accountId, routineTemplate: row.key})\n ON CREATE SET e.eventId = randomUUID(),\n e.name = row.name,\n e.routineDescription = row.description,\n e.agentPrompt = row.prompt,\n e.recurrence = row.recurrence,\n e.routineTemplateVersion = $version,\n e.eventStatus = 'suspended',\n e.nextRun = null,\n e.agentChannel = null,\n e.agentDestination = null,\n e.actionPlugin = null,\n e.actionTool = null,\n e.actionArgs = null,\n e.sourcePlugin = null,\n e.timezone = $timezone,\n e.createdBySource = 'installer',\n e.createdByAgent = 'system',\n e.createdByTool = 'routine-roster-seed',\n e.createdAt = $now,\n e.updatedAt = $now\n ON MATCH SET e.agentPrompt = CASE WHEN refreshing THEN row.prompt ELSE e.agentPrompt END,\n e.name = CASE WHEN refreshing THEN row.name ELSE e.name END,\n e.routineDescription = row.description,\n e.routineTemplateVersion = CASE WHEN refreshing THEN $version ELSE e.routineTemplateVersion END,\n e.updatedAt = CASE WHEN refreshing THEN $now ELSE e.updatedAt END\nRETURN row.key AS key,\n e.eventId AS eventId,\n CASE WHEN NOT existed THEN 'create'\n WHEN priorVersion >= $version THEN 'unchanged'\n WHEN edited THEN 'skip-operator-edited'\n ELSE 'refresh-version' END AS action";
|
|
119
135
|
/** The post-condition read. Counts every roster row the account actually holds,
|
|
120
136
|
* independently of what the MERGE above believes it wrote. */
|
|
121
|
-
export declare const VERIFY_CYPHER = "\nMATCH (e:Event {accountId: $accountId})\nWHERE e.routineTemplate IS NOT NULL\nRETURN count(e) AS actual,\n sum(CASE WHEN e.eventStatus = 'suspended' THEN 1 ELSE 0 END) AS suspended,\n sum(CASE WHEN e.nextRun IS NULL THEN 1 ELSE 0 END) AS nextRunNull";
|
|
137
|
+
export declare const VERIFY_CYPHER = "\nMATCH (e:Event {accountId: $accountId})\nWHERE e.routineTemplate IS NOT NULL\nRETURN count(e) AS actual,\n sum(CASE WHEN e.eventStatus = 'suspended' THEN 1 ELSE 0 END) AS suspended,\n sum(CASE WHEN e.nextRun IS NULL THEN 1 ELSE 0 END) AS nextRunNull,\n sum(CASE WHEN e.routineDescription IS NULL THEN 1 ELSE 0 END) AS descNull";
|
|
122
138
|
export interface SeedRoutineRosterArgs {
|
|
123
139
|
session: SeedSessionLike;
|
|
124
140
|
accountId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAA4C,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAE7F,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5F,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;2EAG2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,KAAK,CAAC;YAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CAClH;AAED;;;;;;;4EAO4E;AAC5E,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,iBAAiB,GAAG,sBAAsB,GAAG,WAAW,CAAC;AAErG,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED;;;;;;0EAM0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAA4C,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAE7F,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5F,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;2EAG2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,KAAK,CAAC;YAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CAClH;AAED;;;;;;;4EAO4E;AAC5E,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,iBAAiB,GAAG,sBAAsB,GAAG,WAAW,CAAC;AAErG,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED;;;;;;0EAM0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;2EAMuE;IACvE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,eAAe,GAAG,QAAQ,CAAC;IAC3C,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAYD;4DAC4D;AAC5D,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,eAAe,GAAG,QAAQ,CAAA;CAAE,CAAC,CAa1E;AAED;;;;;;;;;;;;;;;;;;;;+EAoB+E;AAC/E,eAAO,MAAM,YAAY,28DAwCwB,CAAC;AAElD;+DAC+D;AAC/D,eAAO,MAAM,aAAa,+VAMuD,CAAC;AAElF,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,MAAM,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACpC,+DAA+D;IAC/D,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B;sEACkE;IAClE,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgF/F"}
|
|
@@ -90,7 +90,15 @@ async function resolveOwnerTimezone(session, accountId) {
|
|
|
90
90
|
* `agentChannel`, not `agentDestination`, not `recurrence`, not `timezone`. A
|
|
91
91
|
* re-seed on upgrade must not re-suspend an enabled routine, unbind a bound
|
|
92
92
|
* destination, or reset a retimed cron. Only the prompt, the name and the
|
|
93
|
-
* version move, and only when the row is behind and unedited.
|
|
93
|
+
* version move, and only when the row is behind and unedited.
|
|
94
|
+
*
|
|
95
|
+
* `routineDescription` (Task 2214) is the one property ON MATCH writes on
|
|
96
|
+
* every match rather than only on the refresh branch, and that is not an
|
|
97
|
+
* exception to the rule above. It is roster-owned: the routines route projects
|
|
98
|
+
* it but its PATCH field set refuses it, so no operator edit exists for this
|
|
99
|
+
* to overwrite. Gating it on `refreshing` would leave every operator-edited
|
|
100
|
+
* row description-less permanently, because `skip-operator-edited` takes
|
|
101
|
+
* neither branch, and that row's card would show a title and nothing else. */
|
|
94
102
|
exports.MERGE_CYPHER = `
|
|
95
103
|
UNWIND $rows AS row
|
|
96
104
|
OPTIONAL MATCH (pre:Event {accountId: $accountId, routineTemplate: row.key})
|
|
@@ -103,6 +111,7 @@ WITH row, existed, priorVersion, edited,
|
|
|
103
111
|
MERGE (e:Event {accountId: $accountId, routineTemplate: row.key})
|
|
104
112
|
ON CREATE SET e.eventId = randomUUID(),
|
|
105
113
|
e.name = row.name,
|
|
114
|
+
e.routineDescription = row.description,
|
|
106
115
|
e.agentPrompt = row.prompt,
|
|
107
116
|
e.recurrence = row.recurrence,
|
|
108
117
|
e.routineTemplateVersion = $version,
|
|
@@ -122,6 +131,7 @@ MERGE (e:Event {accountId: $accountId, routineTemplate: row.key})
|
|
|
122
131
|
e.updatedAt = $now
|
|
123
132
|
ON MATCH SET e.agentPrompt = CASE WHEN refreshing THEN row.prompt ELSE e.agentPrompt END,
|
|
124
133
|
e.name = CASE WHEN refreshing THEN row.name ELSE e.name END,
|
|
134
|
+
e.routineDescription = row.description,
|
|
125
135
|
e.routineTemplateVersion = CASE WHEN refreshing THEN $version ELSE e.routineTemplateVersion END,
|
|
126
136
|
e.updatedAt = CASE WHEN refreshing THEN $now ELSE e.updatedAt END
|
|
127
137
|
RETURN row.key AS key,
|
|
@@ -137,7 +147,8 @@ MATCH (e:Event {accountId: $accountId})
|
|
|
137
147
|
WHERE e.routineTemplate IS NOT NULL
|
|
138
148
|
RETURN count(e) AS actual,
|
|
139
149
|
sum(CASE WHEN e.eventStatus = 'suspended' THEN 1 ELSE 0 END) AS suspended,
|
|
140
|
-
sum(CASE WHEN e.nextRun IS NULL THEN 1 ELSE 0 END) AS nextRunNull
|
|
150
|
+
sum(CASE WHEN e.nextRun IS NULL THEN 1 ELSE 0 END) AS nextRunNull,
|
|
151
|
+
sum(CASE WHEN e.routineDescription IS NULL THEN 1 ELSE 0 END) AS descNull`;
|
|
141
152
|
/**
|
|
142
153
|
* Seed (or re-seed) the roster for one account and report what happened.
|
|
143
154
|
*
|
|
@@ -163,7 +174,13 @@ async function seedRoutineRoster(args) {
|
|
|
163
174
|
version,
|
|
164
175
|
timezone,
|
|
165
176
|
now,
|
|
166
|
-
rows: roster.map((r) => ({
|
|
177
|
+
rows: roster.map((r) => ({
|
|
178
|
+
key: r.key,
|
|
179
|
+
name: r.name,
|
|
180
|
+
description: r.description,
|
|
181
|
+
prompt: r.prompt,
|
|
182
|
+
recurrence: r.recurrence,
|
|
183
|
+
})),
|
|
167
184
|
});
|
|
168
185
|
const merges = mergeRes.records.map((rec) => ({
|
|
169
186
|
key: String(rec.get("key")),
|
|
@@ -180,9 +197,10 @@ async function seedRoutineRoster(args) {
|
|
|
180
197
|
actual: toInt(verifyRec?.get("actual")),
|
|
181
198
|
suspended: toInt(verifyRec?.get("suspended")),
|
|
182
199
|
nextRunNull: toInt(verifyRec?.get("nextRunNull")),
|
|
200
|
+
descNull: toInt(verifyRec?.get("descNull")),
|
|
183
201
|
};
|
|
184
202
|
log(`[routine-seed] op=verify acct=${acct} expected=${verify.expected} actual=${verify.actual} ` +
|
|
185
|
-
`suspended=${verify.suspended} nextRunNull=${verify.nextRunNull}`);
|
|
203
|
+
`suspended=${verify.suspended} nextRunNull=${verify.nextRunNull} descNull=${verify.descNull}`);
|
|
186
204
|
const created = merges.filter((m) => m.action === "create").length;
|
|
187
205
|
const refreshed = merges.filter((m) => m.action === "refresh-version").length;
|
|
188
206
|
const skippedOperatorEdited = merges.filter((m) => m.action === "skip-operator-edited").length;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,15 +3,17 @@
|
|
|
3
3
|
*
|
|
4
4
|
* A fresh install used to ship zero routines, so the only working examples
|
|
5
5
|
* lived in one customer's graph and every operator wrote the prompts from
|
|
6
|
-
* scratch. These
|
|
6
|
+
* scratch. These thirteen are the catalogue that ships with the platform
|
|
7
|
+
* instead.
|
|
7
8
|
*
|
|
8
9
|
* Two properties make a routine shippable, and both are load-bearing:
|
|
9
10
|
*
|
|
10
11
|
* 1. It resolves its own surfaces at run time. Every prompt opens on
|
|
11
12
|
* `capabilities-here`, which reports the account's live install set, and
|
|
12
13
|
* ends the turn without replying when the surface it needs is absent. That
|
|
13
|
-
* is what makes the same
|
|
14
|
-
* and a field-service install rather than a template someone must
|
|
14
|
+
* is what makes the same thirteen rows correct on an estate agency, a web
|
|
15
|
+
* studio and a field-service install rather than a template someone must
|
|
16
|
+
* edit.
|
|
15
17
|
*
|
|
16
18
|
* 2. It names nobody. No prompt carries a person's name, an email address, a
|
|
17
19
|
* phone number, a hostname or a database name. `scripts/check-routine-
|
|
@@ -32,7 +34,7 @@
|
|
|
32
34
|
* routine's prompt only when the stored `routineTemplateVersion` is BELOW this
|
|
33
35
|
* and no operator has edited the row, so an unbumped edit ships to new installs
|
|
34
36
|
* and never reaches existing ones — bump it in the same commit as the edit. */
|
|
35
|
-
export declare const ROUTINE_TEMPLATE_VERSION =
|
|
37
|
+
export declare const ROUTINE_TEMPLATE_VERSION = 2;
|
|
36
38
|
export interface RoutineTemplate {
|
|
37
39
|
/** Stable identity. Half of the MERGE key `(accountId, routineTemplate)`, so
|
|
38
40
|
* it is never renamed: a renamed key seeds a duplicate row and orphans the
|
|
@@ -40,15 +42,26 @@ export interface RoutineTemplate {
|
|
|
40
42
|
readonly key: string;
|
|
41
43
|
/** The title shown on `/routines`. */
|
|
42
44
|
readonly name: string;
|
|
45
|
+
/** One sentence under the title on the card: what this does and what it will
|
|
46
|
+
* not do. Roster-owned and read-only — projected by the routines route but
|
|
47
|
+
* absent from its PATCH field set, so no operator edit exists for the seed to
|
|
48
|
+
* overwrite and the MERGE rewrites it on every match. */
|
|
49
|
+
readonly description: string;
|
|
43
50
|
/** The proposed cron. Written ON CREATE only, never refreshed, so an operator
|
|
44
51
|
* who retimes a routine keeps their expression across upgrades. */
|
|
45
52
|
readonly recurrence: string;
|
|
46
53
|
/** The injected turn. Refreshed on a version bump when the row is unedited. */
|
|
47
54
|
readonly prompt: string;
|
|
48
55
|
}
|
|
49
|
-
/** The
|
|
56
|
+
/** The thirteen. Order is the display order on `/routines` before the operator
|
|
50
57
|
* retimes anything: the daily rhythm first, then the reconciles, then the
|
|
51
|
-
* weekly, then the standing check.
|
|
58
|
+
* weekly, then the standing check, then the two health reports.
|
|
59
|
+
*
|
|
60
|
+
* `description` is what the card shows under the title. It says what the row
|
|
61
|
+
* does and, where the row is deliberately narrower than its name suggests,
|
|
62
|
+
* what it will not do — the send it never makes, the write it never performs,
|
|
63
|
+
* the file it never deletes. That second half is the part an operator cannot
|
|
64
|
+
* infer from a title, and it is why the sentence is not just the name again. */
|
|
52
65
|
export declare const ROUTINE_ROSTER: readonly RoutineTemplate[];
|
|
53
66
|
/** Every roster key, in roster order. The scheduling heartbeat's `op=roster`
|
|
54
67
|
* drift check reconciles this expected set against what is actually in the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roster.d.ts","sourceRoot":"","sources":["../src/roster.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"roster.d.ts","sourceRoot":"","sources":["../src/roster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH;;;gFAGgF;AAChF,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,MAAM,WAAW,eAAe;IAC9B;;mEAE+D;IAC/D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;8DAG0D;IAC1D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;wEACoE;IACpE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAgKD;;;;;;;;iFAQiF;AACjF,eAAO,MAAM,cAAc,EAAE,SAAS,eAAe,EAyGpD,CAAC;AAEF;;6DAE6D;AAC7D,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAAqC,CAAC"}
|
|
@@ -4,15 +4,17 @@
|
|
|
4
4
|
*
|
|
5
5
|
* A fresh install used to ship zero routines, so the only working examples
|
|
6
6
|
* lived in one customer's graph and every operator wrote the prompts from
|
|
7
|
-
* scratch. These
|
|
7
|
+
* scratch. These thirteen are the catalogue that ships with the platform
|
|
8
|
+
* instead.
|
|
8
9
|
*
|
|
9
10
|
* Two properties make a routine shippable, and both are load-bearing:
|
|
10
11
|
*
|
|
11
12
|
* 1. It resolves its own surfaces at run time. Every prompt opens on
|
|
12
13
|
* `capabilities-here`, which reports the account's live install set, and
|
|
13
14
|
* ends the turn without replying when the surface it needs is absent. That
|
|
14
|
-
* is what makes the same
|
|
15
|
-
* and a field-service install rather than a template someone must
|
|
15
|
+
* is what makes the same thirteen rows correct on an estate agency, a web
|
|
16
|
+
* studio and a field-service install rather than a template someone must
|
|
17
|
+
* edit.
|
|
16
18
|
*
|
|
17
19
|
* 2. It names nobody. No prompt carries a person's name, an email address, a
|
|
18
20
|
* phone number, a hostname or a database name. `scripts/check-routine-
|
|
@@ -35,7 +37,7 @@ exports.ROUTINE_ROSTER_KEYS = exports.ROUTINE_ROSTER = exports.ROUTINE_TEMPLATE_
|
|
|
35
37
|
* routine's prompt only when the stored `routineTemplateVersion` is BELOW this
|
|
36
38
|
* and no operator has edited the row, so an unbumped edit ships to new installs
|
|
37
39
|
* and never reaches existing ones — bump it in the same commit as the edit. */
|
|
38
|
-
exports.ROUTINE_TEMPLATE_VERSION =
|
|
40
|
+
exports.ROUTINE_TEMPLATE_VERSION = 2;
|
|
39
41
|
const START_OF_DAY = `Prepare the operator's morning briefing and reply with it as a single message.
|
|
40
42
|
|
|
41
43
|
Call capabilities-here first and work only with the plugins it reports as enabled. Nothing below is mandatory: each part is included when its surface is present and skipped in silence when it is not.
|
|
@@ -159,21 +161,129 @@ If every link is connected, end the turn without replying. A message on a health
|
|
|
159
161
|
When a link is down, reply with one message naming the number it is paired to, the exact error it last reported, and how long it has been down. Say plainly whether the platform is still retrying it or has stopped. A link that was logged out, or replaced by another device, will not come back on its own: re-pairing needs someone holding the phone, so say that rather than implying it will recover by itself.
|
|
160
162
|
|
|
161
163
|
Never disconnect a link and never begin a re-pair from here. This routine reports; the remedy is a person's decision.`;
|
|
162
|
-
|
|
164
|
+
const GRAPH_HEALTH = `Report on the state of this account's graph and on what its maintenance sweep last found. This routine reads. It performs no graph writes at all.
|
|
165
|
+
|
|
166
|
+
Call capabilities-here first. If the memory plugin is not enabled, end the turn without replying.
|
|
167
|
+
|
|
168
|
+
Read the most recent maintenance report with memory-report-read-latest: it carries the run's per-phase counts and the time it ran. Read the two review queues with memory-review-queue. Orphan candidates are nodes the sweep could not attach to anything; citation proposals are timeline claims still waiting for a source.
|
|
169
|
+
|
|
170
|
+
Report four things: when the sweep last ran, how many orphan candidates are waiting, how large the citation backlog is, and how much compiled truth the last run found stale. A queue that has grown since the previous run matters more than its absolute size, so say which direction it is moving.
|
|
171
|
+
|
|
172
|
+
Never call memory-dream-run from here. The sweep already runs on its own hourly cadence and decides for itself whether an account is due; a second writer started from a scheduled turn would race it, and the surviving report would be whichever run finished last. Reading the sweep's output is the whole of this routine's authority.
|
|
173
|
+
|
|
174
|
+
If both queues are empty and the sweep ran within the past day, end the turn without replying. Nothing is wrong and there is nothing to decide.`;
|
|
175
|
+
const FILESYSTEM_HEALTH = `Report what has accumulated under this account's own directory, so growth is visible before it becomes a problem. This routine deletes nothing.
|
|
176
|
+
|
|
177
|
+
Call capabilities-here first. If the filesystem plugin is not enabled, end the turn without replying.
|
|
178
|
+
|
|
179
|
+
Walk the account directory with file-list, starting at its root and descending only where something is already large. Use file-glob to count the things that accumulate rather than get cleaned up: uploaded files, session transcripts, generated documents, logs, and anything a plugin writes once per run.
|
|
180
|
+
|
|
181
|
+
Report the few paths worth a person's attention, each with what is in it and roughly how much. Name every path relative to the account directory, never as an absolute one. Judgement is the point: one directory holding thousands of files is worth naming, and a hundred small ones spread evenly are not.
|
|
182
|
+
|
|
183
|
+
There is no deletion tool on this surface and this routine must not ask for one. Report what grew and leave the decision with the operator: a routine that removed files on a schedule would eventually remove the one that mattered, and nothing would say which.
|
|
184
|
+
|
|
185
|
+
If nothing has grown materially since the last run, end the turn without replying.`;
|
|
186
|
+
/** The thirteen. Order is the display order on `/routines` before the operator
|
|
163
187
|
* retimes anything: the daily rhythm first, then the reconciles, then the
|
|
164
|
-
* weekly, then the standing check.
|
|
188
|
+
* weekly, then the standing check, then the two health reports.
|
|
189
|
+
*
|
|
190
|
+
* `description` is what the card shows under the title. It says what the row
|
|
191
|
+
* does and, where the row is deliberately narrower than its name suggests,
|
|
192
|
+
* what it will not do — the send it never makes, the write it never performs,
|
|
193
|
+
* the file it never deletes. That second half is the part an operator cannot
|
|
194
|
+
* infer from a title, and it is why the sentence is not just the name again. */
|
|
165
195
|
exports.ROUTINE_ROSTER = [
|
|
166
|
-
{
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
{
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
196
|
+
{
|
|
197
|
+
key: "start-of-day",
|
|
198
|
+
name: "Start of day briefing",
|
|
199
|
+
description: "Sends one morning message covering what needs a decision, what is time-bound and what changed overnight; stays silent when there is nothing worth saying.",
|
|
200
|
+
recurrence: "30 7 * * 1-5",
|
|
201
|
+
prompt: START_OF_DAY,
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
key: "inbound-check",
|
|
205
|
+
name: "Working-hours inbound check",
|
|
206
|
+
description: "Triages mail that arrived since the last check and writes replies for you to approve; it never sends anything itself.",
|
|
207
|
+
recurrence: "*/30 9-17 * * 1-5",
|
|
208
|
+
prompt: INBOUND_CHECK,
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
key: "end-of-day",
|
|
212
|
+
name: "End of day wrap-up",
|
|
213
|
+
description: "Closes the day with your unsent drafts, overdue work and tomorrow's diary; says nothing when all three are empty.",
|
|
214
|
+
recurrence: "0 18 * * 1-5",
|
|
215
|
+
prompt: END_OF_DAY,
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
key: "appointment-reminder",
|
|
219
|
+
name: "Appointment reminders",
|
|
220
|
+
description: "Reminds each attendee once before a booked appointment, on a route they already use; it never opens a conversation with a stranger.",
|
|
221
|
+
recurrence: "0 * * * *",
|
|
222
|
+
prompt: APPOINTMENT_REMINDER,
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
key: "commitment-chase",
|
|
226
|
+
name: "Commitment chase",
|
|
227
|
+
description: "Surfaces promises the business made and did not keep, and promises made to it that nobody kept; it reports them rather than chasing them.",
|
|
228
|
+
recurrence: "0 10 * * 2",
|
|
229
|
+
prompt: COMMITMENT_CHASE,
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
key: "calendar-reconcile",
|
|
233
|
+
name: "Calendar reconcile",
|
|
234
|
+
description: "Reconciles the provider calendar against the appointments held in the graph, writing what is missing and marking what was cancelled; a clean run says nothing.",
|
|
235
|
+
recurrence: "*/15 * * * *",
|
|
236
|
+
prompt: CALENDAR_RECONCILE,
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
key: "contact-reconcile",
|
|
240
|
+
name: "Contact reconcile",
|
|
241
|
+
description: "Reconciles the people you correspond with against the people on record, creating and updating contacts; it never merges two records that might be two people.",
|
|
242
|
+
recurrence: "45 6 * * 1-5",
|
|
243
|
+
prompt: CONTACT_RECONCILE,
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
key: "crm-reconcile",
|
|
247
|
+
name: "Operational system reconcile",
|
|
248
|
+
description: "Brings across what changed in whichever operational system this business runs; it reads only and never writes back to that system.",
|
|
249
|
+
recurrence: "0 3 * * *",
|
|
250
|
+
prompt: CRM_RECONCILE,
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
key: "finance-reconcile",
|
|
254
|
+
name: "Finance reconcile",
|
|
255
|
+
description: "Reconciles the accounting system against the internal ledger and reports what does not agree; it never adjusts an entry to make the two sides match.",
|
|
256
|
+
recurrence: "0 4 * * 1",
|
|
257
|
+
prompt: FINANCE_RECONCILE,
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
key: "weekly-digest",
|
|
261
|
+
name: "Weekly digest",
|
|
262
|
+
description: "Writes the week in three paragraphs at most: what changed, what is stuck, and what next week turns on.",
|
|
263
|
+
recurrence: "0 16 * * 5",
|
|
264
|
+
prompt: WEEKLY_DIGEST,
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
key: "channel-link-check",
|
|
268
|
+
name: "Channel link check",
|
|
269
|
+
description: "Reports a messaging link that has gone down and whether it can recover on its own; it never disconnects a link or starts a re-pair.",
|
|
270
|
+
recurrence: "*/15 * * * *",
|
|
271
|
+
prompt: CHANNEL_LINK_CHECK,
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
key: "graph-health",
|
|
275
|
+
name: "Graph health report",
|
|
276
|
+
description: "Reports what the hourly graph sweep last did and what is waiting for review; it reads only and never runs the sweep itself.",
|
|
277
|
+
recurrence: "0 9 * * 1",
|
|
278
|
+
prompt: GRAPH_HEALTH,
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
key: "filesystem-health",
|
|
282
|
+
name: "Filesystem health report",
|
|
283
|
+
description: "Reports what has grown under the account directory and which paths are worth attention; it deletes nothing.",
|
|
284
|
+
recurrence: "0 9 * * 1",
|
|
285
|
+
prompt: FILESYSTEM_HEALTH,
|
|
286
|
+
},
|
|
177
287
|
];
|
|
178
288
|
/** Every roster key, in roster order. The scheduling heartbeat's `op=roster`
|
|
179
289
|
* drift check reconciles this expected set against what is actually in the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roster.js","sourceRoot":"","sources":["../src/roster.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"roster.js","sourceRoot":"","sources":["../src/roster.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;;;AAEH;;;gFAGgF;AACnE,QAAA,wBAAwB,GAAG,CAAC,CAAC;AAqB1C,MAAM,YAAY,GAAG;;;;;;;;;;;4OAWuN,CAAC;AAE7O,MAAM,aAAa,GAAG;;;;;;;;;;2NAUqM,CAAC;AAE5N,MAAM,UAAU,GAAG;;;;;;;;;;gGAU6E,CAAC;AAEjG,MAAM,oBAAoB,GAAG;;;;;;;;;;gJAUmH,CAAC;AAEjJ,MAAM,gBAAgB,GAAG;;;;;;;;;;;4DAWmC,CAAC;AAE7D,MAAM,kBAAkB,GAAG;;;;;;;;;;8NAUmM,CAAC;AAE/N,MAAM,iBAAiB,GAAG;;;;;;;;;;4JAUkI,CAAC;AAE7J,MAAM,aAAa,GAAG;;;;;;;;2HAQqG,CAAC;AAE5H,MAAM,iBAAiB,GAAG;;;;;;;;;;gHAUsF,CAAC;AAEjH,MAAM,aAAa,GAAG;;;;;;;;;;;;gEAY0C,CAAC;AAEjE,MAAM,kBAAkB,GAAG;;;;;;;;;;sHAU2F,CAAC;AAEvH,MAAM,YAAY,GAAG;;;;;;;;;;gJAU2H,CAAC;AAEjJ,MAAM,iBAAiB,GAAG;;;;;;;;;;mFAUyD,CAAC;AAEpF;;;;;;;;iFAQiF;AACpE,QAAA,cAAc,GAA+B;IACxD;QACE,GAAG,EAAE,cAAc;QACnB,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EACT,2JAA2J;QAC7J,UAAU,EAAE,cAAc;QAC1B,MAAM,EAAE,YAAY;KACrB;IACD;QACE,GAAG,EAAE,eAAe;QACpB,IAAI,EAAE,6BAA6B;QACnC,WAAW,EACT,uHAAuH;QACzH,UAAU,EAAE,mBAAmB;QAC/B,MAAM,EAAE,aAAa;KACtB;IACD;QACE,GAAG,EAAE,YAAY;QACjB,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EACT,mHAAmH;QACrH,UAAU,EAAE,cAAc;QAC1B,MAAM,EAAE,UAAU;KACnB;IACD;QACE,GAAG,EAAE,sBAAsB;QAC3B,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EACT,qIAAqI;QACvI,UAAU,EAAE,WAAW;QACvB,MAAM,EAAE,oBAAoB;KAC7B;IACD;QACE,GAAG,EAAE,kBAAkB;QACvB,IAAI,EAAE,kBAAkB;QACxB,WAAW,EACT,2IAA2I;QAC7I,UAAU,EAAE,YAAY;QACxB,MAAM,EAAE,gBAAgB;KACzB;IACD;QACE,GAAG,EAAE,oBAAoB;QACzB,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EACT,gKAAgK;QAClK,UAAU,EAAE,cAAc;QAC1B,MAAM,EAAE,kBAAkB;KAC3B;IACD;QACE,GAAG,EAAE,mBAAmB;QACxB,IAAI,EAAE,mBAAmB;QACzB,WAAW,EACT,+JAA+J;QACjK,UAAU,EAAE,cAAc;QAC1B,MAAM,EAAE,iBAAiB;KAC1B;IACD;QACE,GAAG,EAAE,eAAe;QACpB,IAAI,EAAE,8BAA8B;QACpC,WAAW,EACT,oIAAoI;QACtI,UAAU,EAAE,WAAW;QACvB,MAAM,EAAE,aAAa;KACtB;IACD;QACE,GAAG,EAAE,mBAAmB;QACxB,IAAI,EAAE,mBAAmB;QACzB,WAAW,EACT,sJAAsJ;QACxJ,UAAU,EAAE,WAAW;QACvB,MAAM,EAAE,iBAAiB;KAC1B;IACD;QACE,GAAG,EAAE,eAAe;QACpB,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,wGAAwG;QAC1G,UAAU,EAAE,YAAY;QACxB,MAAM,EAAE,aAAa;KACtB;IACD;QACE,GAAG,EAAE,oBAAoB;QACzB,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EACT,qIAAqI;QACvI,UAAU,EAAE,cAAc;QAC1B,MAAM,EAAE,kBAAkB;KAC3B;IACD;QACE,GAAG,EAAE,cAAc;QACnB,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EACT,6HAA6H;QAC/H,UAAU,EAAE,WAAW;QACvB,MAAM,EAAE,YAAY;KACrB;IACD;QACE,GAAG,EAAE,mBAAmB;QACxB,IAAI,EAAE,0BAA0B;QAChC,WAAW,EACT,6GAA6G;QAC/G,UAAU,EAAE,WAAW;QACvB,MAAM,EAAE,iBAAiB;KAC1B;CACF,CAAC;AAEF;;6DAE6D;AAChD,QAAA,mBAAmB,GAAsB,sBAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC"}
|
|
@@ -37,6 +37,11 @@ const CANONICAL_TOOL_NAMES: ReadonlySet<string> = (() => {
|
|
|
37
37
|
function citedToolCandidates(prompt: string): string[] {
|
|
38
38
|
const prefixes = [
|
|
39
39
|
"email-",
|
|
40
|
+
// `file-` is here because the filesystem routine is the first row to cite
|
|
41
|
+
// the filesystem plugin. Without the prefix its two tools are collected by
|
|
42
|
+
// nothing, and the registry assertion below passes over that prompt without
|
|
43
|
+
// ever examining it — a check that reports clean while checking nothing.
|
|
44
|
+
"file-",
|
|
40
45
|
"outlook-",
|
|
41
46
|
"google-",
|
|
42
47
|
"schedule-",
|
|
@@ -60,11 +65,11 @@ function citedToolCandidates(prompt: string): string[] {
|
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
describe("routine roster shape", () => {
|
|
63
|
-
it("ships exactly
|
|
64
|
-
expect(ROUTINE_ROSTER).toHaveLength(
|
|
68
|
+
it("ships exactly thirteen routines", () => {
|
|
69
|
+
expect(ROUTINE_ROSTER).toHaveLength(13);
|
|
65
70
|
});
|
|
66
71
|
|
|
67
|
-
it("has the
|
|
72
|
+
it("has the thirteen keys the task and the drift check agree on", () => {
|
|
68
73
|
expect([...ROUTINE_ROSTER_KEYS].sort()).toEqual(
|
|
69
74
|
[
|
|
70
75
|
"appointment-reminder",
|
|
@@ -74,7 +79,9 @@ describe("routine roster shape", () => {
|
|
|
74
79
|
"contact-reconcile",
|
|
75
80
|
"crm-reconcile",
|
|
76
81
|
"end-of-day",
|
|
82
|
+
"filesystem-health",
|
|
77
83
|
"finance-reconcile",
|
|
84
|
+
"graph-health",
|
|
78
85
|
"inbound-check",
|
|
79
86
|
"start-of-day",
|
|
80
87
|
"weekly-digest",
|
|
@@ -104,6 +111,42 @@ describe("routine roster shape", () => {
|
|
|
104
111
|
});
|
|
105
112
|
});
|
|
106
113
|
|
|
114
|
+
describe("routine descriptions", () => {
|
|
115
|
+
// The card renders this and nothing else about what the routine does, so an
|
|
116
|
+
// empty one is a card that says only its title — the state Task 2214 exists
|
|
117
|
+
// to end. Uniqueness matters because two rows sharing a sentence means one of
|
|
118
|
+
// them was copied and never rewritten.
|
|
119
|
+
it("every routine carries a non-empty description", () => {
|
|
120
|
+
for (const r of ROUTINE_ROSTER) {
|
|
121
|
+
expect(r.description.trim(), `${r.key} description`).not.toBe("");
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("descriptions are unique", () => {
|
|
126
|
+
const descriptions = ROUTINE_ROSTER.map((r) => r.description);
|
|
127
|
+
expect(new Set(descriptions).size).toBe(descriptions.length);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("each description is one sentence under 200 characters", () => {
|
|
131
|
+
for (const r of ROUTINE_ROSTER) {
|
|
132
|
+
expect(r.description.length, `${r.key} description length`).toBeLessThan(200);
|
|
133
|
+
expect(r.description.endsWith("."), `${r.key} must end in a full stop`).toBe(true);
|
|
134
|
+
// A second sentence wraps to a second line on a card sized for one.
|
|
135
|
+
expect(r.description.slice(0, -1), `${r.key} must be one sentence`).not.toMatch(/\.\s/);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("no prompt cites the graph routine's key as though it were a tool", () => {
|
|
140
|
+
// citedToolCandidates collects `graph-`-prefixed tokens and checks them
|
|
141
|
+
// against the canonical registry. `graph-health` is a MERGE key, not a
|
|
142
|
+
// tool, so a prompt that names itself fails the registry assertion with a
|
|
143
|
+
// message pointing at the registry rather than at this mistake.
|
|
144
|
+
for (const r of ROUTINE_ROSTER) {
|
|
145
|
+
expect(r.prompt, `${r.key} must not name the graph routine's key`).not.toContain("graph-health");
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
107
150
|
describe("routine prompts resolve their own surfaces", () => {
|
|
108
151
|
it("every prompt opens on capabilities-here", () => {
|
|
109
152
|
for (const r of ROUTINE_ROSTER) {
|