@rubytech/create-sitedesk-code 0.1.522 → 0.1.523
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/package.json +1 -1
- package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-style/dist/index.js +28 -0
- package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-style/src/__tests__/caption-coverage.test.ts +7 -0
- package/payload/platform/lib/graph-style/src/index.ts +24 -0
- package/payload/platform/lib/graph-write/dist/__tests__/merge-on.test.d.ts.map +1 -0
- package/payload/platform/lib/graph-write/dist/__tests__/merge-on.test.js.map +1 -0
- package/payload/platform/lib/graph-write/dist/index.d.ts +16 -0
- package/payload/platform/lib/graph-write/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-write/dist/index.js +83 -6
- package/payload/platform/lib/graph-write/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-write/src/index.ts +117 -10
- package/payload/platform/lib/routine-templates/dist/index.d.ts +151 -0
- package/payload/platform/lib/routine-templates/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/routine-templates/dist/index.js +207 -0
- package/payload/platform/lib/routine-templates/dist/index.js.map +1 -0
- package/payload/platform/lib/routine-templates/dist/roster.d.ts +57 -0
- package/payload/platform/lib/routine-templates/dist/roster.d.ts.map +1 -0
- package/payload/platform/lib/routine-templates/dist/roster.js +182 -0
- package/payload/platform/lib/routine-templates/dist/roster.js.map +1 -0
- package/payload/platform/lib/routine-templates/dist/seed-cli.d.ts +2 -0
- package/payload/platform/lib/routine-templates/dist/seed-cli.d.ts.map +1 -0
- package/payload/platform/lib/routine-templates/dist/seed-cli.js +64 -0
- package/payload/platform/lib/routine-templates/dist/seed-cli.js.map +1 -0
- package/payload/platform/lib/routine-templates/package.json +6 -0
- package/payload/platform/lib/routine-templates/src/__tests__/roster.test.ts +170 -0
- package/payload/platform/lib/routine-templates/src/__tests__/seed.test.ts +298 -0
- package/payload/platform/lib/routine-templates/src/index.ts +299 -0
- package/payload/platform/lib/routine-templates/src/roster.ts +206 -0
- package/payload/platform/lib/routine-templates/src/seed-cli.ts +65 -0
- package/payload/platform/lib/routine-templates/tsconfig.json +9 -0
- package/payload/platform/lib/routine-templates/vitest.config.ts +9 -0
- package/payload/platform/neo4j/edge-annotations.json +2 -2
- package/payload/platform/neo4j/schema.cypher +25 -1
- package/payload/platform/package.json +3 -2
- package/payload/platform/plugins/admin/PLUGIN.md +2 -2
- package/payload/platform/plugins/admin/mcp/dist/index.js +39 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +277 -61
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +6 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +265 -59
- package/payload/platform/plugins/docs/references/memory-guide.md +11 -1
- package/payload/platform/plugins/graph/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/graph/PLUGIN.md +1 -1
- package/payload/platform/plugins/memory/PLUGIN.md +1 -1
- package/payload/platform/plugins/memory/mcp/dist/index.js +12 -5
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/phase-estate-census.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/phase-estate-census.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/phase-estate-census.test.js +197 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/phase-estate-census.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-loader.test.js +55 -9
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-loader.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-validator.test.js +96 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-validator.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/index.d.ts +7 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/index.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-estate-census.d.ts +29 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-estate-census.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-estate-census.js +126 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-estate-census.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js +7 -4
- package/payload/platform/plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-dream-run.d.ts +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-dream-run.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-dream-run.js +18 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-dream-run.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts +7 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +4 -3
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/vitest.config.ts +2 -0
- package/payload/platform/plugins/memory/references/schema-estate-agent.md +2 -2
- package/payload/platform/plugins/memory/skills/conversation-archive-enrich/SKILL.md +4 -4
- package/payload/platform/plugins/quickbooks/PLUGIN.md +10 -10
- package/payload/platform/plugins/scheduling/PLUGIN.md +49 -1
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +48 -0
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/notes-cap.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/notes-cap.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/notes-cap.test.js +78 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/notes-cap.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.js +457 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/notes-cap.d.ts +35 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/notes-cap.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/notes-cap.js +39 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/notes-cap.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts +175 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.js +533 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +123 -9
- 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__/routine-roster-audit.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js +189 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/suspension-census.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/suspension-census.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/suspension-census.test.js +95 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/suspension-census.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/sweep-excludes-suspended.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/sweep-excludes-suspended.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/sweep-excludes-suspended.test.js +114 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/sweep-excludes-suspended.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +109 -2
- 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 +340 -9
- 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.d.ts +9 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +210 -45
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +43 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-get-agent.test.js +55 -7
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-get-agent.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-list.test.js +45 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-list.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-runs.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-runs.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-runs.test.js +96 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-runs.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js +2 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.d.ts +5 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.js +13 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.d.ts +4 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.js +24 -3
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-runs.d.ts +33 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-runs.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-runs.js +51 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-runs.js.map +1 -0
- 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 +12 -2
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
- package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +30 -2
- package/payload/platform/plugins/whatsapp/skills/connect-whatsapp/SKILL.md +1 -1
- package/payload/platform/scripts/check-specialist-tool-surface.mjs +92 -16
- package/payload/platform/scripts/seed-neo4j.sh +41 -0
- package/payload/platform/scripts/verify-skill-tool-surface.sh +91 -2
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/templates/specialists/agents/librarian.md +1 -1
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/server/{chunk-K7CJGZPU.js → chunk-VUXKXOJU.js} +342 -152
- package/payload/server/{chunk-UX2FRNO7.js → chunk-WT2PFGY4.js} +37 -265
- package/payload/server/{chunk-PXNY2TAP.js → chunk-XCR5D2G3.js} +239 -10
- package/payload/server/{manager-RKL7JZ4Y.js → manager-4TJK3YOY.js} +2 -2
- package/payload/server/maxy-edge.js +2 -2
- package/payload/server/public/activity.html +5 -5
- package/payload/server/public/agents.html +4 -4
- package/payload/server/public/assets/{AdminLoginScreens-zc2_qqh-.js → AdminLoginScreens-uknqh2Pm.js} +1 -1
- package/payload/server/public/assets/AdminLoginScreens-uknqh2Pm.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-uknqh2Pm.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-GqtMImyQ.js +2 -0
- package/payload/server/public/assets/AdminShell-GqtMImyQ.js.br +0 -0
- package/payload/server/public/assets/AdminShell-GqtMImyQ.js.gz +0 -0
- package/payload/server/public/assets/{activity-DVgO8YuM.js → activity-B4KfMJqO.js} +1 -1
- package/payload/server/public/assets/activity-B4KfMJqO.js.br +0 -0
- package/payload/server/public/assets/activity-B4KfMJqO.js.gz +0 -0
- package/payload/server/public/assets/admin-DxCZeVw0.js +1 -0
- package/payload/server/public/assets/admin-DxCZeVw0.js.br +0 -0
- package/payload/server/public/assets/admin-DxCZeVw0.js.gz +0 -0
- package/payload/server/public/assets/agents-BtwBuO4G.js +1 -0
- package/payload/server/public/assets/agents-BtwBuO4G.js.br +0 -0
- package/payload/server/public/assets/agents-BtwBuO4G.js.gz +0 -0
- package/payload/server/public/assets/{browser-Mw7DY3ft.js → browser-B3hSzI3O.js} +1 -1
- package/payload/server/public/assets/browser-B3hSzI3O.js.br +0 -0
- package/payload/server/public/assets/browser-B3hSzI3O.js.gz +0 -0
- package/payload/server/public/assets/{calendar-B9gvL_1_.js → calendar-BggxXxhS.js} +1 -1
- package/payload/server/public/assets/calendar-BggxXxhS.js.br +0 -0
- package/payload/server/public/assets/calendar-BggxXxhS.js.gz +0 -0
- package/payload/server/public/assets/chat-flivHt0t.js +1 -0
- package/payload/server/public/assets/chat-flivHt0t.js.br +0 -0
- package/payload/server/public/assets/chat-flivHt0t.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-nVRThX7f.js +1 -0
- package/payload/server/public/assets/chevron-right-CLqfrkRA.js +1 -0
- package/payload/server/public/assets/chevron-right-CLqfrkRA.js.br +0 -0
- package/payload/server/public/assets/clock-Dj3SRZKo.js +1 -0
- package/payload/server/public/assets/clock-Dj3SRZKo.js.br +0 -0
- package/payload/server/public/assets/clock-Dj3SRZKo.js.gz +0 -0
- package/payload/server/public/assets/data-Ckjkne54.js +1 -0
- package/payload/server/public/assets/data-Ckjkne54.js.br +3 -0
- package/payload/server/public/assets/data-Ckjkne54.js.gz +0 -0
- package/payload/server/public/assets/{file-text-dYBnXNEX.js → file-text-BKs9eyiw.js} +1 -1
- package/payload/server/public/assets/file-text-BKs9eyiw.js.br +0 -0
- package/payload/server/public/assets/file-text-BKs9eyiw.js.gz +0 -0
- package/payload/server/public/assets/{graph-CDyzd1Et.js → graph-DTi71NaZ.js} +3 -3
- package/payload/server/public/assets/graph-DTi71NaZ.js.br +0 -0
- package/payload/server/public/assets/graph-DTi71NaZ.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-BT3S6e9H.js +1 -0
- package/payload/server/public/assets/graph-labels-BT3S6e9H.js.br +0 -0
- package/payload/server/public/assets/graph-labels-BT3S6e9H.js.gz +0 -0
- package/payload/server/public/assets/{maximize-2-M-iSaznd.js → maximize-2-zC94tsxY.js} +1 -1
- package/payload/server/public/assets/maximize-2-zC94tsxY.js.br +0 -0
- package/payload/server/public/assets/maximize-2-zC94tsxY.js.gz +0 -0
- package/payload/server/public/assets/operator-BtWNEMh-.js +1 -0
- package/payload/server/public/assets/operator-BtWNEMh-.js.br +0 -0
- package/payload/server/public/assets/operator-BtWNEMh-.js.gz +0 -0
- package/payload/server/public/assets/page-BFm91p0e.js +1 -0
- package/payload/server/public/assets/page-BFm91p0e.js.br +0 -0
- package/payload/server/public/assets/page-BFm91p0e.js.gz +0 -0
- package/payload/server/public/assets/{page-CZ-73FAk.js → page-Ccl0FazM.js} +3 -3
- package/payload/server/public/assets/page-Ccl0FazM.js.br +0 -0
- package/payload/server/public/assets/page-Ccl0FazM.js.gz +0 -0
- package/payload/server/public/assets/{public-CN-ltC8x.js → public-BpC6cn9S.js} +1 -1
- package/payload/server/public/assets/public-BpC6cn9S.js.br +0 -0
- package/payload/server/public/assets/public-BpC6cn9S.js.gz +0 -0
- package/payload/server/public/assets/{rotate-ccw-Buopsc22.js → rotate-ccw-BNcqbHkZ.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-BNcqbHkZ.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-BNcqbHkZ.js.gz +0 -0
- package/payload/server/public/assets/routines-D5iia-XG.js +1 -0
- package/payload/server/public/assets/routines-D5iia-XG.js.br +0 -0
- package/payload/server/public/assets/routines-D5iia-XG.js.gz +0 -0
- package/payload/server/public/assets/{skills-DiiuVzDK.js → skills-COLAw_jt.js} +1 -1
- package/payload/server/public/assets/skills-COLAw_jt.js.br +0 -0
- package/payload/server/public/assets/skills-COLAw_jt.js.gz +0 -0
- package/payload/server/public/assets/tasks-CZDQI4nB.js +1 -0
- package/payload/server/public/assets/tasks-CZDQI4nB.js.br +0 -0
- package/payload/server/public/assets/tasks-CZDQI4nB.js.gz +0 -0
- package/payload/server/public/assets/{time-entry-format-BBokCF-D.js → time-entry-format-laTFzawg.js} +1 -1
- package/payload/server/public/assets/time-entry-format-laTFzawg.js.br +0 -0
- package/payload/server/public/assets/time-entry-format-laTFzawg.js.gz +0 -0
- package/payload/server/public/assets/{triangle-alert-C_AcpTW5.js → triangle-alert-DrwqhEog.js} +1 -1
- package/payload/server/public/assets/triangle-alert-DrwqhEog.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-DrwqhEog.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-TdimmPVR.js → useCopyFeedback-Cxme5GK6.js} +1 -1
- package/payload/server/public/assets/useCopyFeedback-Cxme5GK6.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-Cxme5GK6.js.gz +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-B-K8y5a4.css +1 -0
- package/payload/server/public/assets/useSubAccountSwitcher-B-K8y5a4.css.br +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-B-K8y5a4.css.gz +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-C_1E11Dv.js +14 -0
- package/payload/server/public/assets/useSubAccountSwitcher-C_1E11Dv.js.br +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-C_1E11Dv.js.gz +0 -0
- package/payload/server/public/assets/{useVoiceRecorder-BT2738ZS.js → useVoiceRecorder-DUBpVa2T.js} +1 -1
- package/payload/server/public/assets/useVoiceRecorder-DUBpVa2T.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-DUBpVa2T.js.gz +0 -0
- package/payload/server/public/assets/{wrench-B51s5kGA.js → wrench-DWuxPnzF.js} +1 -1
- package/payload/server/public/assets/wrench-DWuxPnzF.js.br +0 -0
- package/payload/server/public/assets/wrench-DWuxPnzF.js.gz +0 -0
- package/payload/server/public/browser.html +4 -4
- package/payload/server/public/calendar.html +7 -7
- package/payload/server/public/chat.html +13 -13
- package/payload/server/public/data.html +11 -11
- package/payload/server/public/graph.html +9 -9
- package/payload/server/public/index.html +14 -14
- package/payload/server/public/operator.html +14 -14
- package/payload/server/public/public.html +13 -13
- package/payload/server/public/routines.html +6 -6
- package/payload/server/public/skills.html +5 -5
- package/payload/server/public/tasks.html +6 -6
- package/payload/server/server.js +5910 -5369
- package/payload/server/public/assets/AdminLoginScreens-zc2_qqh-.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-zc2_qqh-.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-IGUdTx5q.js +0 -2
- package/payload/server/public/assets/AdminShell-IGUdTx5q.js.br +0 -0
- package/payload/server/public/assets/AdminShell-IGUdTx5q.js.gz +0 -0
- package/payload/server/public/assets/activity-DVgO8YuM.js.br +0 -0
- package/payload/server/public/assets/activity-DVgO8YuM.js.gz +0 -0
- package/payload/server/public/assets/admin-xtpM7fgl.js +0 -1
- package/payload/server/public/assets/admin-xtpM7fgl.js.br +0 -0
- package/payload/server/public/assets/admin-xtpM7fgl.js.gz +0 -0
- package/payload/server/public/assets/agents-P0nTIxo-.js +0 -1
- package/payload/server/public/assets/agents-P0nTIxo-.js.br +0 -0
- package/payload/server/public/assets/agents-P0nTIxo-.js.gz +0 -0
- package/payload/server/public/assets/browser-Mw7DY3ft.js.br +0 -0
- package/payload/server/public/assets/browser-Mw7DY3ft.js.gz +0 -0
- package/payload/server/public/assets/calendar-B9gvL_1_.js.br +0 -0
- package/payload/server/public/assets/calendar-B9gvL_1_.js.gz +0 -0
- package/payload/server/public/assets/chat-DBGqh4wg.js +0 -1
- package/payload/server/public/assets/chat-DBGqh4wg.js.br +0 -2
- package/payload/server/public/assets/chat-DBGqh4wg.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-Bl4vpOM0.js +0 -1
- package/payload/server/public/assets/chevron-left-Bl4vpOM0.js.br +0 -0
- package/payload/server/public/assets/chevron-right-BExigCnp.js +0 -1
- package/payload/server/public/assets/chevron-right-BExigCnp.js.br +0 -0
- package/payload/server/public/assets/clock-D8TJvgJC.js +0 -1
- package/payload/server/public/assets/clock-D8TJvgJC.js.br +0 -0
- package/payload/server/public/assets/data-HfFSxaC2.js +0 -1
- package/payload/server/public/assets/data-HfFSxaC2.js.br +0 -0
- package/payload/server/public/assets/data-HfFSxaC2.js.gz +0 -0
- package/payload/server/public/assets/file-text-dYBnXNEX.js.br +0 -0
- package/payload/server/public/assets/file-text-dYBnXNEX.js.gz +0 -0
- package/payload/server/public/assets/graph-CDyzd1Et.js.br +0 -0
- package/payload/server/public/assets/graph-CDyzd1Et.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-D1LkKiJr.js +0 -1
- package/payload/server/public/assets/graph-labels-D1LkKiJr.js.br +0 -0
- package/payload/server/public/assets/graph-labels-D1LkKiJr.js.gz +0 -0
- package/payload/server/public/assets/maximize-2-M-iSaznd.js.br +0 -0
- package/payload/server/public/assets/maximize-2-M-iSaznd.js.gz +0 -0
- package/payload/server/public/assets/operator-9jfCv1Fg.js +0 -1
- package/payload/server/public/assets/operator-9jfCv1Fg.js.br +0 -0
- package/payload/server/public/assets/operator-9jfCv1Fg.js.gz +0 -0
- package/payload/server/public/assets/page-CZ-73FAk.js.br +0 -0
- package/payload/server/public/assets/page-CZ-73FAk.js.gz +0 -0
- package/payload/server/public/assets/page-CjwSt7kx.js +0 -1
- package/payload/server/public/assets/page-CjwSt7kx.js.br +0 -0
- package/payload/server/public/assets/page-CjwSt7kx.js.gz +0 -0
- package/payload/server/public/assets/public-CN-ltC8x.js.br +0 -0
- package/payload/server/public/assets/public-CN-ltC8x.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-Buopsc22.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-Buopsc22.js.gz +0 -0
- package/payload/server/public/assets/routines-C-yr8ddT.js +0 -1
- package/payload/server/public/assets/routines-C-yr8ddT.js.br +0 -0
- package/payload/server/public/assets/routines-C-yr8ddT.js.gz +0 -0
- package/payload/server/public/assets/skills-DiiuVzDK.js.br +0 -0
- package/payload/server/public/assets/skills-DiiuVzDK.js.gz +0 -0
- package/payload/server/public/assets/tasks-CnHIfn2_.js +0 -1
- package/payload/server/public/assets/tasks-CnHIfn2_.js.br +0 -0
- package/payload/server/public/assets/tasks-CnHIfn2_.js.gz +0 -0
- package/payload/server/public/assets/time-entry-format-BBokCF-D.js.br +0 -0
- package/payload/server/public/assets/time-entry-format-BBokCF-D.js.gz +0 -0
- package/payload/server/public/assets/triangle-alert-C_AcpTW5.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-C_AcpTW5.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-TdimmPVR.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-TdimmPVR.js.gz +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-BwHqV55p.js +0 -14
- package/payload/server/public/assets/useSubAccountSwitcher-BwHqV55p.js.br +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-BwHqV55p.js.gz +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-CsrPYqtm.css +0 -1
- package/payload/server/public/assets/useSubAccountSwitcher-CsrPYqtm.css.br +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-CsrPYqtm.css.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-BT2738ZS.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-BT2738ZS.js.gz +0 -0
- package/payload/server/public/assets/wrench-B51s5kGA.js.br +0 -0
- package/payload/server/public/assets/wrench-B51s5kGA.js.gz +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface RunRow {
|
|
2
|
+
runId: string;
|
|
3
|
+
eventId: string;
|
|
4
|
+
/** Which dispatch loop opened it: `recurring` or `one-time`. */
|
|
5
|
+
kind: string;
|
|
6
|
+
/** The resolved dispatch mode: `agent`, `action` or `none`. */
|
|
7
|
+
mode: string;
|
|
8
|
+
/** `open` | `accepted` | `started` | `finished` | `failed` | `no-destination`. */
|
|
9
|
+
status: string;
|
|
10
|
+
/** `<channel>:<destination>`, `<plugin>.<tool>`, or `-`. */
|
|
11
|
+
target: string;
|
|
12
|
+
scheduledFor: string;
|
|
13
|
+
startedAt: string;
|
|
14
|
+
endedAt: string | null;
|
|
15
|
+
finishedAt: string | null;
|
|
16
|
+
ranMs: number | null;
|
|
17
|
+
httpStatus: number | null;
|
|
18
|
+
dispatchResult: string | null;
|
|
19
|
+
sessionKey: string | null;
|
|
20
|
+
transcriptOffset: number | null;
|
|
21
|
+
/** False when the record cannot name where in the shared transcript its output starts. */
|
|
22
|
+
bounded: boolean;
|
|
23
|
+
error: string | null;
|
|
24
|
+
}
|
|
25
|
+
export interface ScheduleRunsParams {
|
|
26
|
+
accountId: string;
|
|
27
|
+
eventId: string;
|
|
28
|
+
limit?: number;
|
|
29
|
+
}
|
|
30
|
+
/** Project a `:RoutineRun` node's properties into a RunRow. */
|
|
31
|
+
export declare function mapRunRow(p: Record<string, unknown>): RunRow;
|
|
32
|
+
export declare function scheduleRuns(params: ScheduleRunsParams): Promise<RunRow[]>;
|
|
33
|
+
//# sourceMappingURL=schedule-runs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule-runs.d.ts","sourceRoot":"","sources":["../../src/tools/schedule-runs.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,0FAA0F;IAC1F,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,+DAA+D;AAC/D,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAsB5D;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgBhF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task 2136 — one routine's run history.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `workflow-runs` (workflows/mcp/src/tools/workflow-runs.ts) so the two
|
|
5
|
+
* histories read the same way. Account-scoped at both ends — on the run node's
|
|
6
|
+
* own `accountId` AND through the routine it hangs off — so a foreign eventId
|
|
7
|
+
* returns nothing rather than another account's runs.
|
|
8
|
+
*/
|
|
9
|
+
import { int } from "neo4j-driver";
|
|
10
|
+
import { getSession } from "../lib/neo4j.js";
|
|
11
|
+
import { toNumber } from "../lib/routine-run.js";
|
|
12
|
+
/** Project a `:RoutineRun` node's properties into a RunRow. */
|
|
13
|
+
export function mapRunRow(p) {
|
|
14
|
+
return {
|
|
15
|
+
runId: p.runId,
|
|
16
|
+
eventId: p.eventId,
|
|
17
|
+
kind: p.kind,
|
|
18
|
+
mode: p.mode,
|
|
19
|
+
status: p.status,
|
|
20
|
+
target: p.target ?? "-",
|
|
21
|
+
scheduledFor: p.scheduledFor,
|
|
22
|
+
startedAt: p.startedAt,
|
|
23
|
+
endedAt: p.endedAt ?? null,
|
|
24
|
+
finishedAt: p.finishedAt ?? null,
|
|
25
|
+
ranMs: toNumber(p.ranMs),
|
|
26
|
+
httpStatus: toNumber(p.httpStatus),
|
|
27
|
+
dispatchResult: p.dispatchResult ?? null,
|
|
28
|
+
sessionKey: p.sessionKey ?? null,
|
|
29
|
+
transcriptOffset: toNumber(p.transcriptOffset),
|
|
30
|
+
// Strict identity, not truthiness: an absent or null `bounded` means the
|
|
31
|
+
// boundary was never established, which is exactly the false case.
|
|
32
|
+
bounded: p.bounded === true,
|
|
33
|
+
error: p.error ?? null,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export async function scheduleRuns(params) {
|
|
37
|
+
const { accountId, eventId, limit = 20 } = params;
|
|
38
|
+
const session = getSession();
|
|
39
|
+
try {
|
|
40
|
+
const res = await session.run(`MATCH (r:RoutineRun)-[:RUN_OF]->(e:Event {eventId: $eventId, accountId: $accountId})
|
|
41
|
+
WHERE r.accountId = $accountId
|
|
42
|
+
RETURN r
|
|
43
|
+
ORDER BY r.startedAt DESC
|
|
44
|
+
LIMIT $limit`, { accountId, eventId, limit: int(limit) });
|
|
45
|
+
return res.records.map((rec) => mapRunRow(rec.get("r").properties));
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
await session.close();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=schedule-runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule-runs.js","sourceRoot":"","sources":["../../src/tools/schedule-runs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAiCjD,+DAA+D;AAC/D,MAAM,UAAU,SAAS,CAAC,CAA0B;IAClD,OAAO;QACL,KAAK,EAAE,CAAC,CAAC,KAAe;QACxB,OAAO,EAAE,CAAC,CAAC,OAAiB;QAC5B,IAAI,EAAE,CAAC,CAAC,IAAc;QACtB,IAAI,EAAE,CAAC,CAAC,IAAc;QACtB,MAAM,EAAE,CAAC,CAAC,MAAgB;QAC1B,MAAM,EAAG,CAAC,CAAC,MAAiB,IAAI,GAAG;QACnC,YAAY,EAAE,CAAC,CAAC,YAAsB;QACtC,SAAS,EAAE,CAAC,CAAC,SAAmB;QAChC,OAAO,EAAG,CAAC,CAAC,OAAyB,IAAI,IAAI;QAC7C,UAAU,EAAG,CAAC,CAAC,UAA4B,IAAI,IAAI;QACnD,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;QACxB,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;QAClC,cAAc,EAAG,CAAC,CAAC,cAAgC,IAAI,IAAI;QAC3D,UAAU,EAAG,CAAC,CAAC,UAA4B,IAAI,IAAI;QACnD,gBAAgB,EAAE,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAC9C,yEAAyE;QACzE,mEAAmE;QACnE,OAAO,EAAE,CAAC,CAAC,OAAO,KAAK,IAAI;QAC3B,KAAK,EAAG,CAAC,CAAC,KAAuB,IAAI,IAAI;KAC1C,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAA0B;IAC3D,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC;IAClD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAC3B;;;;oBAIc,EACd,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAC1C,CAAC;QACF,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IACtE,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule-update.d.ts","sourceRoot":"","sources":["../../src/tools/schedule-update.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schedule-update.d.ts","sourceRoot":"","sources":["../../src/tools/schedule-update.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGtE,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;CACtC;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyQhF"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { getSession } from "../lib/neo4j.js";
|
|
4
|
+
import { appendNotesCapped } from "../lib/notes-cap.js";
|
|
4
5
|
import { computeEmbedding } from "../lib/embedding.js";
|
|
5
6
|
import cronParser from "cron-parser";
|
|
6
7
|
const { parseExpression } = cronParser;
|
|
@@ -41,7 +42,7 @@ export async function scheduleUpdate(params) {
|
|
|
41
42
|
SET e.nextRun = $newNextRun,
|
|
42
43
|
e.skipNext = false,
|
|
43
44
|
e.updatedAt = $now,
|
|
44
|
-
|
|
45
|
+
${appendNotesCapped("e", "noteEntry")}`, {
|
|
45
46
|
eventId,
|
|
46
47
|
accountId,
|
|
47
48
|
newNextRun,
|
|
@@ -164,13 +165,22 @@ export async function scheduleUpdate(params) {
|
|
|
164
165
|
queryParams.agentChannel = agentDispatch.channel;
|
|
165
166
|
queryParams.agentDestination = agentDispatch.destination;
|
|
166
167
|
queryParams.agentPrompt = agentDispatch.prompt;
|
|
168
|
+
// Task 2130 — stamp the prompt as operator-owned. The shipped routine
|
|
169
|
+
// roster re-seeds on every upgrade and rewrites a template's prompt when
|
|
170
|
+
// its stored version is behind, UNLESS the row carries this. Without the
|
|
171
|
+
// stamp the guard reads a property nothing ever sets, so the first version
|
|
172
|
+
// bump would silently overwrite an operator's customised prompt and the
|
|
173
|
+
// only evidence would be the prompt itself changing. Only the prompt is
|
|
174
|
+
// stamped: the seed never rewrites recurrence, status, channel or
|
|
175
|
+
// destination, so an edit to those needs no protection.
|
|
176
|
+
setClauses.push("e.operatorEdited = $now");
|
|
167
177
|
// Invariant: setting an agent dispatch clears any action.
|
|
168
178
|
setClauses.push("e.actionPlugin = null");
|
|
169
179
|
setClauses.push("e.actionTool = null");
|
|
170
180
|
setClauses.push("e.actionArgs = null");
|
|
171
181
|
}
|
|
172
182
|
if (note) {
|
|
173
|
-
setClauses.push("e
|
|
183
|
+
setClauses.push(appendNotesCapped("e", "noteEntry"));
|
|
174
184
|
queryParams.noteEntry = `\n[${queryParams.now}] ${note}`;
|
|
175
185
|
}
|
|
176
186
|
// Recompute embedding if name or description changed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule-update.js","sourceRoot":"","sources":["../../src/tools/schedule-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,MAAM,EAAE,eAAe,EAAE,GAAG,UAAU,CAAC;AAGvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAmBjE,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAA4B;IAC/D,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC;IAEzF,+EAA+E;IAC/E,gFAAgF;IAChF,yEAAyE;IACzE,IAAI,MAAM,IAAI,IAAI,IAAI,aAAa,IAAI,IAAI,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,kFAAkF,CAAC,CAAC;IACtG,CAAC;IAED,sDAAsD;IACtD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,YAAY,GAAG,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,CAClC;yFACiF,EACjF,EAAE,OAAO,EAAE,SAAS,EAAE,CACvB,CAAC;YACF,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;YACjD,CAAC;YACD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC/C,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;YACnE,CAAC;YAED,yCAAyC;YACzC,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAW,CAAC;YACjE,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAkB,CAAC;YAC7D,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,EAAE;gBACpC,WAAW,EAAE,IAAI,IAAI,CAAC,cAAc,CAAC;gBACrC,EAAE,EAAE,EAAE,IAAI,SAAS;aACpB,CAAC,CAAC;YACH,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACjD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAErC,MAAM,WAAW,GAAG,UAAU,EAAE,CAAC;YACjC,IAAI,CAAC;gBACH,MAAM,WAAW,CAAC,GAAG,CACnB;;;;
|
|
1
|
+
{"version":3,"file":"schedule-update.js","sourceRoot":"","sources":["../../src/tools/schedule-update.ts"],"names":[],"mappings":"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"}
|
|
@@ -297,7 +297,7 @@ When a pairing attempt fails — the phone accepts the code and shows "Continue
|
|
|
297
297
|
grep -aE '\[whatsapp:(login|session|reconcile)\]' <server log> | grep 'cid=<id>'
|
|
298
298
|
```
|
|
299
299
|
|
|
300
|
-
The single decision point is whether an `op=pair-success` line appears between `op=code-issued` and `op=close`. Absent + `op=close … kind=qr-refs-ended-408` → the completion signal never returned (beyond the Pi). When no account signature is captured, the login
|
|
300
|
+
The single decision point is whether an `op=pair-success` line appears between `op=code-issued` and `op=close`. Absent + `op=close … kind=qr-refs-ended-408` → the completion signal never returned (beyond the Pi). When no account signature is captured, the login terminates rather than reconnecting a half-registered credential into a `401`, and which of three terminals fires is decided by `op=companion-reg cid=… stage=… parseable=…`, emitted once per `link_code_companion_reg` notification received. A notification with no `primary_identity_pub` gives `op=pairing-declined … reason=companion-reg-unparseable` within seconds instead of at the ~160s ref cap, and the operator is told the phone was asked to approve and the approval did not complete, so they should clear any warning prompt the phone shows and request a new code. No notification at all gives `op=pairing-incomplete … reason=code-not-submitted`, meaning the code was never entered. Only a notification that parsed and still produced no signature gives `op=pairing-incomplete … reason=no-account-signature`, the linked-device-limit or stale-companion case; that advice used to be given for all three and misdirected an investigation on a brand-new number with no linked devices. `op=terminal` carries `companionRegSeen`, and `outcome=connected companionRegSeen=false` means the observer never bound. A dirty `op=creds-pre registered=true hasAccount=false` → Pi-side. A half-registered credential folder (pairing requested, never completed) is reconciled on each `/status` pass: an in-flight or freshly-written one is preserved and logged `[whatsapp:reconcile] op=half-registered … inFlight=<bool>`, while an aged, abandoned one (no live login, creds untouched past the 5-minute pairing window) is deleted once, logged `op=discard-half-registered`, so the next pairing starts from an empty folder.
|
|
301
301
|
|
|
302
302
|
Full grammar, success/failure signatures, and the `kind` table: [`.docs/whatsapp-pairing-lifeline.md`](../../../../.docs/whatsapp-pairing-lifeline.md).
|
|
303
303
|
|
|
@@ -329,9 +329,37 @@ The dead state is reported at two surfaces so it is visible without a reply havi
|
|
|
329
329
|
|
|
330
330
|
What is NOT handled here: the end user who triggered the reply receives no delivery-failure notice over WhatsApp, and there is no outbound retry queue — a dropped reply on a dead link is lost (the agent is made aware of the failure, but the sender is not). That is a separate concern; file a task if it is wanted.
|
|
331
331
|
|
|
332
|
+
## Giving Up Is Temporary: the Re-arm
|
|
333
|
+
|
|
334
|
+
Ten consecutive cycles shorter than `STABLE_UPTIME_MS` (30s) make `computeReconnectNextState` return `abort`. That branch used to `return` out of the reconnect loop, and nothing called back in: on 2026-07-28 three co-resident installs made **zero** socket attempts across 8h22m and only a manual QR re-pair recovered them.
|
|
335
|
+
|
|
336
|
+
The abort now waits `REARM_INTERVAL_MS` (15 minutes, flat, uncapped) and continues the loop. `reconnectAttempts` is deliberately not written in that branch, so it stays at the value the abort fired on — one below `MAX_RECONNECT_ATTEMPTS`, since the decision aborts when `reconnectAttempts + 1 >= maxAttempts`. The next short-lived cycle therefore aborts again and lands back on the same wait: **exactly one socket attempt per fifteen minutes, for as long as the link stays down**. The storm the bound exists to stop ran ten attempts in thirteen minutes, so the re-armed rate is about a fortieth of it. There is no cap, because any cap reinstates the same permanently-dead state at a later hour.
|
|
337
|
+
|
|
338
|
+
Two rules bound the re-arm, and both matter:
|
|
339
|
+
|
|
340
|
+
- **A stuck link clears once the reconnect has HELD 30 seconds**, on a timer armed at connect — not when the recovered session later ends. Clearing at socket-open would be too early (a link that opens and dies in two seconds has proven nothing); clearing after the session ends would be far too late, and would report a link that came back and stayed up as stuck for its whole life. The attempt counter is untouched by that clear: the bound is enforced by `reconnectAttempts`, which the stable-reset decision still resets when the cycle ends.
|
|
341
|
+
- **A `terminalReason` link is never re-armed.** A 401 `loggedOut` or a 409 `conflict` returns before the abort branch is reached, so re-arming cannot apply. When a *re-armed* attempt comes back terminal the loop ends and writes `outcome=skipped-terminal`, which is what makes the exclusion observable rather than merely coded. Retrying a revoked credential risks the number; re-pairing is the only remedy.
|
|
342
|
+
|
|
343
|
+
## Standing Link Census
|
|
344
|
+
|
|
345
|
+
Every other WhatsApp log line is a transition, so a link that died at 22:00 and a link that stayed up all night leave identical logs. Two standing lines close that, both on a 15-minute `registerLoop` tick, both written on healthy ticks too:
|
|
346
|
+
|
|
347
|
+
```
|
|
348
|
+
[whatsapp-health] op=link-census account=<id> connected=<bool> stuck=<bool> downMs=<n|unknown> lastError=<msg|none>
|
|
349
|
+
[whatsapp-health] op=rearm account=<id> attempt=<n> sinceStuckMs=<n> outcome=<connected|failed|skipped-terminal>
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
- `op=link-census` prints when the link is up as well as down, and prints `accounts=0` on an install with no WhatsApp connections at all. A census that speaks only when something is wrong cannot be told apart from a census that has stopped running.
|
|
353
|
+
- `downMs` is milliseconds since the link last reported `connected`, and is `unknown` — never `0` — for a link that has never connected. It is the one field that makes an 8h22m outage legible rather than reconstructable from an absence of lines.
|
|
354
|
+
- `op=rearm` is written when an attempt **resolves**, carrying what it resolved to. "Scheduled a re-arm" is not evidence a socket was attempted.
|
|
355
|
+
|
|
356
|
+
Triage a suspected dead link with `grep '\[whatsapp-health\]' ~/.<brand>/logs/server.log | tail -20`.
|
|
357
|
+
|
|
358
|
+
`/api/health` still publishes `whatsapp.any_stuck` and `whatsapp.any_terminal`, and still has no UI consumer. That is deliberate: a banner needs an open browser tab, and the census and the re-arm do not.
|
|
359
|
+
|
|
332
360
|
## Reconnection: Setup Failures vs Runtime Disconnects
|
|
333
361
|
|
|
334
|
-
> **
|
|
362
|
+
> **Where the lifecycle lives:** reconnect bounding (`STABLE_UPTIME_MS`, `MAX_RECONNECT_ATTEMPTS`, `REARM_INTERVAL_MS`) and the platform-side init queries are in `platform/ui/app/lib/whatsapp/reconnect.ts` and `manager.ts`; the two sections above describe the current behaviour. The content below describes the historical disconnect-reason mapping, which still applies.
|
|
335
363
|
|
|
336
364
|
The reconnection loop in `monitorWebChannel` handles two distinct failure modes:
|
|
337
365
|
|
|
@@ -25,7 +25,7 @@ Call `whatsapp-status` first to check the current state. If already connected, t
|
|
|
25
25
|
|
|
26
26
|
2. **Initiate pairing** — call `whatsapp-login-start` with `phone` set to that number. If the account is already linked and the user didn't say "relink", inform them and skip to Phase 2.
|
|
27
27
|
|
|
28
|
-
3. **Give the operator the code** — the tool returns an 8-character pairing code. Show it and tell the user: "On the phone with that number, open WhatsApp → Settings → Linked Devices → Link a Device → tap 'Link with phone number instead', then enter this code: {code}."
|
|
28
|
+
3. **Give the operator the code** — the tool returns an 8-character pairing code. Show it and tell the user: "On the phone with that number, open WhatsApp → Settings → Linked Devices → Link a Device → tap 'Link with phone number instead', then enter this code: {code}. If the phone shows a warning asking whether someone else asked you to link a device, clear that prompt and approve the link, otherwise the link will not complete."
|
|
29
29
|
|
|
30
30
|
4. **Wait for the link** — call `whatsapp-login-wait`. It polls for up to 60 seconds. The code stays valid and the connection stays alive across polls, so if it returns still-waiting, call it again — do not generate a new code unless the operator asks. While waiting, tell the user you're watching for the link.
|
|
31
31
|
|
|
@@ -67,25 +67,39 @@ function qualifyShortToolName(plugin, tool) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
// Frontmatter walker for PLUGIN.md tools: + hidden: blocks. Returns
|
|
70
|
-
// {tools
|
|
71
|
-
//
|
|
72
|
-
//
|
|
70
|
+
// {tools, hidden, hasTools, specialistOnly}. The drift check needs names
|
|
71
|
+
// only — every declared tool contributes to the `all` surface regardless of
|
|
72
|
+
// allowlist. `specialistOnly` (Task 2132) additionally carries the names
|
|
73
|
+
// declared unreachable from both the admin and public surfaces, which the
|
|
74
|
+
// reachability check below resolves against the specialist grants.
|
|
73
75
|
function parsePluginManifest(rawManifest) {
|
|
74
76
|
const fmMatch = rawManifest.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
75
|
-
if (!fmMatch) return { tools: [], hidden: [], hasTools: false };
|
|
77
|
+
if (!fmMatch) return { tools: [], hidden: [], hasTools: false, specialistOnly: [], manifestName: null };
|
|
76
78
|
const lines = fmMatch[1].split(/\r?\n/);
|
|
79
|
+
// The MCP server namespace is the manifest's own `name:`, which for a nested
|
|
80
|
+
// premium sub-plugin differs from its directory: premium-plugins/real-agent/
|
|
81
|
+
// plugins/loop/PLUGIN.md declares `name: real-agent-loop`, and the agents
|
|
82
|
+
// that hold its tools name them `mcp__plugin_real-agent-loop_real-agent-loop__*`.
|
|
83
|
+
// Used for the reachability set only, so the drift classifier's directory-keyed
|
|
84
|
+
// `all` set keeps its existing behaviour (Task 2132).
|
|
85
|
+
const nameMatch = fmMatch[1].match(/^name:\s*(\S+)\s*$/m);
|
|
86
|
+
const manifestName = nameMatch ? nameMatch[1] : null;
|
|
77
87
|
const tools = [];
|
|
78
88
|
const hidden = [];
|
|
89
|
+
const flags = {};
|
|
79
90
|
let mode = null; // 'tools' | 'hidden' | null
|
|
91
|
+
let cur = null;
|
|
80
92
|
let hasTools = false;
|
|
81
93
|
for (const line of lines) {
|
|
82
|
-
if (/^tools:\s*\[\s*\]\s*$/.test(line)) { mode = null; continue; }
|
|
83
|
-
if (/^tools:\s*$/.test(line)) { mode = 'tools'; hasTools = true; continue; }
|
|
84
|
-
if (/^hidden:\s*$/.test(line)) { mode = 'hidden'; continue; }
|
|
85
|
-
if (/^[A-Za-z_]/.test(line)) { mode = null; continue; }
|
|
94
|
+
if (/^tools:\s*\[\s*\]\s*$/.test(line)) { mode = null; cur = null; continue; }
|
|
95
|
+
if (/^tools:\s*$/.test(line)) { mode = 'tools'; hasTools = true; cur = null; continue; }
|
|
96
|
+
if (/^hidden:\s*$/.test(line)) { mode = 'hidden'; cur = null; continue; }
|
|
97
|
+
if (/^[A-Za-z_]/.test(line)) { mode = null; cur = null; continue; }
|
|
86
98
|
if (mode === 'tools') {
|
|
87
99
|
const nameLine = line.match(/^\s+-\s+name:\s*(.+?)\s*$/);
|
|
88
|
-
if (nameLine) { tools.push(
|
|
100
|
+
if (nameLine) { cur = nameLine[1]; tools.push(cur); flags[cur] = {}; continue; }
|
|
101
|
+
const flagLine = line.match(/^\s+(adminAllowlist|publicAllowlist):\s*(true|false)\s*$/);
|
|
102
|
+
if (flagLine && cur) { flags[cur][flagLine[1]] = flagLine[2] === 'true'; continue; }
|
|
89
103
|
}
|
|
90
104
|
if (mode === 'hidden') {
|
|
91
105
|
// Task 1998 — hidden entries carry the same `- name:` + `riskClass:`
|
|
@@ -95,7 +109,10 @@ function parsePluginManifest(rawManifest) {
|
|
|
95
109
|
if (nameLine) hidden.push(nameLine[1]);
|
|
96
110
|
}
|
|
97
111
|
}
|
|
98
|
-
|
|
112
|
+
const specialistOnly = tools.filter(
|
|
113
|
+
(t) => flags[t]?.adminAllowlist === false && flags[t]?.publicAllowlist === false,
|
|
114
|
+
);
|
|
115
|
+
return { tools, hidden, hasTools, specialistOnly, manifestName };
|
|
99
116
|
}
|
|
100
117
|
|
|
101
118
|
// Per-brand tool surface: walk platform/plugins (minus excludedPlugins) +
|
|
@@ -109,15 +126,17 @@ export function loadBrandToolSurface(maxyCodeRoot, excludedPlugins, shippedPremi
|
|
|
109
126
|
const { PLATFORM_PLUGINS, PREMIUM_ROOT } = rootsFor(maxyCodeRoot);
|
|
110
127
|
const all = new Set();
|
|
111
128
|
const maxyPluginSet = new Set();
|
|
129
|
+
const specialistOnlyAll = new Set();
|
|
112
130
|
const visit = (root, name) => {
|
|
113
131
|
if (excludedPlugins.has(name)) return;
|
|
114
132
|
const manifestPath = join(root, name, 'PLUGIN.md');
|
|
115
133
|
if (!existsSync(manifestPath)) return;
|
|
116
|
-
const { tools, hidden, hasTools } = parsePluginManifest(readFileSync(manifestPath, 'utf-8'));
|
|
134
|
+
const { tools, hidden, hasTools, specialistOnly, manifestName } = parsePluginManifest(readFileSync(manifestPath, 'utf-8'));
|
|
117
135
|
if (!hasTools && hidden.length === 0) return;
|
|
118
136
|
maxyPluginSet.add(name);
|
|
119
137
|
for (const t of tools) all.add(canonicalToolName(name, t));
|
|
120
138
|
for (const h of hidden) all.add(canonicalToolName(name, h));
|
|
139
|
+
for (const s of specialistOnly) specialistOnlyAll.add(canonicalToolName(manifestName ?? name, s));
|
|
121
140
|
};
|
|
122
141
|
if (existsSync(PLATFORM_PLUGINS)) {
|
|
123
142
|
for (const name of readdirSync(PLATFORM_PLUGINS).sort()) {
|
|
@@ -138,7 +157,53 @@ export function loadBrandToolSurface(maxyCodeRoot, excludedPlugins, shippedPremi
|
|
|
138
157
|
}
|
|
139
158
|
}
|
|
140
159
|
}
|
|
141
|
-
return { all, maxyPluginSet };
|
|
160
|
+
return { all, maxyPluginSet, specialistOnlyAll };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Task 2132 — the inverse of the drift check. A tool declared
|
|
164
|
+
// `adminAllowlist: false` + `publicAllowlist: false` is reachable only
|
|
165
|
+
// through a specialist's frontmatter `tools:` list. When no agent names it,
|
|
166
|
+
// the tool can never be called: no error, no log line, no failed run. That is
|
|
167
|
+
// a no-event failure, so it needs a standing check rather than an event.
|
|
168
|
+
// `maxy-graph-write_neo4j_cypher` sat unreachable from Task 081 until 2132,
|
|
169
|
+
// taking conversation-archive-enrich's wire step down with it.
|
|
170
|
+
export function collectGrantedTools(agentDirs) {
|
|
171
|
+
const granted = new Set();
|
|
172
|
+
for (const dir of agentDirs) {
|
|
173
|
+
let entries;
|
|
174
|
+
try { entries = readdirSync(dir); } catch { continue; }
|
|
175
|
+
for (const entry of entries) {
|
|
176
|
+
if (!entry.endsWith('.md')) continue;
|
|
177
|
+
if (SKIP_AGENT_BASENAMES.has(basename(entry, '.md').toUpperCase())) continue;
|
|
178
|
+
const fm = readFileSync(join(dir, entry), 'utf-8').match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
179
|
+
if (!fm) continue;
|
|
180
|
+
const toolsLine = parseSpecialistToolsLine(fm[1]);
|
|
181
|
+
if (!toolsLine) continue;
|
|
182
|
+
for (const t of splitToolList(toolsLine)) granted.add(t);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return granted;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Tools deliberately reachable by no agent, each with the reason it is not a
|
|
189
|
+
// mistake. Empty by construction: every tool that would have sat here was
|
|
190
|
+
// fixed in Task 2132 — fourteen admin-called ones moved onto the admin
|
|
191
|
+
// surface, the graph write tool onto the librarian. An entry added later must
|
|
192
|
+
// name why the tool is deliberately callable by nobody, and an entry whose
|
|
193
|
+
// tool has since been granted is itself reported, because a suppression that
|
|
194
|
+
// outlives its cause re-creates the blind spot.
|
|
195
|
+
const REACHABILITY_EXCEPTIONS = new Map([]);
|
|
196
|
+
|
|
197
|
+
export function findUnreachableTools(specialistOnlyAll, granted) {
|
|
198
|
+
const unreachable = [];
|
|
199
|
+
const staleExceptions = [];
|
|
200
|
+
for (const tool of [...specialistOnlyAll].sort()) {
|
|
201
|
+
const isGranted = granted.has(tool);
|
|
202
|
+
const excepted = REACHABILITY_EXCEPTIONS.has(tool);
|
|
203
|
+
if (!isGranted && !excepted) unreachable.push(tool);
|
|
204
|
+
if (isGranted && excepted) staleExceptions.push(tool);
|
|
205
|
+
}
|
|
206
|
+
return { unreachable, staleExceptions };
|
|
142
207
|
}
|
|
143
208
|
|
|
144
209
|
// Per-brand specialist-agent dirs: platform templates ship with every brand;
|
|
@@ -277,12 +342,16 @@ export function runForBrand(maxyCodeRoot, brandName) {
|
|
|
277
342
|
throw err;
|
|
278
343
|
}
|
|
279
344
|
const shippedSet = new Set(shipped);
|
|
280
|
-
const { all, maxyPluginSet } = loadBrandToolSurface(maxyCodeRoot, excludedPlugins, shippedSet);
|
|
345
|
+
const { all, maxyPluginSet, specialistOnlyAll } = loadBrandToolSurface(maxyCodeRoot, excludedPlugins, shippedSet);
|
|
281
346
|
const agentDirs = collectSpecialistDirs(maxyCodeRoot, shippedSet);
|
|
282
347
|
const { defects, inspected } = assertSpecialistDrift(agentDirs, all, maxyPluginSet, excludedPlugins);
|
|
283
348
|
const blocking = defects.filter(d => d.reason !== 'brand-excluded-plugin');
|
|
284
349
|
const stripList = defects.filter(d => d.reason === 'brand-excluded-plugin');
|
|
285
|
-
|
|
350
|
+
const { unreachable, staleExceptions } = findUnreachableTools(
|
|
351
|
+
specialistOnlyAll,
|
|
352
|
+
collectGrantedTools(agentDirs),
|
|
353
|
+
);
|
|
354
|
+
return { blocking, stripList, inspected, unreachable, staleExceptions };
|
|
286
355
|
}
|
|
287
356
|
|
|
288
357
|
function main(maxyCodeRoot) {
|
|
@@ -306,14 +375,21 @@ function main(maxyCodeRoot) {
|
|
|
306
375
|
: d.specialistPath;
|
|
307
376
|
console.error(`[specialist-tool-surface] specialist=${rel} tool=${d.tool} reason=${d.reason} brand=${brandName}`);
|
|
308
377
|
}
|
|
309
|
-
|
|
310
|
-
|
|
378
|
+
for (const tool of result.unreachable) {
|
|
379
|
+
console.error(`[specialist-tool-surface] unreachable-tool=${tool} reason=granted-by-no-agent brand=${brandName}`);
|
|
380
|
+
}
|
|
381
|
+
for (const tool of result.staleExceptions) {
|
|
382
|
+
console.error(`[specialist-tool-surface] stale-reachability-exception=${tool} reason=now-granted brand=${brandName}`);
|
|
383
|
+
}
|
|
384
|
+
totalBlocking += result.blocking.length + result.unreachable.length + result.staleExceptions.length;
|
|
385
|
+
if (result.blocking.length === 0 && result.unreachable.length === 0 && result.staleExceptions.length === 0) {
|
|
311
386
|
console.log(`[specialist-tool-surface] ok brand=${brandName} inspected=${result.inspected}`);
|
|
312
387
|
}
|
|
313
388
|
}
|
|
314
389
|
if (totalBlocking > 0) {
|
|
315
390
|
console.error(`[specialist-tool-surface] FAIL: ${totalBlocking} defect(s) across ${brands.length} brand(s).`);
|
|
316
391
|
console.error(` Rename the tool in the listed file to a registered namespace, or move the plugin off the brand's plugins.excluded list.`);
|
|
392
|
+
console.error(` An unreachable-tool is declared adminAllowlist:false + publicAllowlist:false and named by no agent: grant it to the specialist that needs it, put it on the admin surface, or remove the declaration.`);
|
|
317
393
|
process.exit(1);
|
|
318
394
|
}
|
|
319
395
|
}
|
|
@@ -369,4 +369,45 @@ IDENT_DROPPED=$("$CYPHER_SHELL" -u "$NEO4J_USER" -p "$NEO4J_PASSWORD" -a "$NEO4J
|
|
|
369
369
|
"MATCH (au:AdminUser) WHERE au.name IS NOT NULL REMOVE au.name RETURN count(au)" 2>/dev/null | tail -1 | tr -d ' \r')
|
|
370
370
|
echo " [identity-reconcile] namedExisting=${IDENT_NAMED:-0} createdOwned=${IDENT_CREATED:-0} droppedAuName=${IDENT_DROPPED:-0}"
|
|
371
371
|
|
|
372
|
+
# ------------------------------------------------------------------
|
|
373
|
+
# 8. Routine roster (Task 2130)
|
|
374
|
+
# ------------------------------------------------------------------
|
|
375
|
+
# Ten generic routines, seeded eventStatus='suspended' with nextRun NULL and no
|
|
376
|
+
# channel or destination, so a fresh install has a catalogue to enable instead
|
|
377
|
+
# of a blank /routines page. Running here rather than only at account creation
|
|
378
|
+
# is what carries the roster to the EXISTING fleet: this script runs on every
|
|
379
|
+
# upgrade, not just the first install.
|
|
380
|
+
#
|
|
381
|
+
# The roster, the MERGE and the whole [routine-seed] lifecycle live in
|
|
382
|
+
# platform/lib/routine-templates so the sub-account path in the admin plugin
|
|
383
|
+
# shares them verbatim. This script only supplies the process boundary; it logs
|
|
384
|
+
# nothing itself.
|
|
385
|
+
#
|
|
386
|
+
# Never install-blocking, matching sections 5-7 above. An account with no
|
|
387
|
+
# routines is degraded, not broken: the graph, the agent and every channel work,
|
|
388
|
+
# and only /routines is empty. Aborting here would take down an install or a
|
|
389
|
+
# whole-fleet upgrade over a transient Neo4j hiccup, after the schema, the root
|
|
390
|
+
# :LocalBusiness and the owner :AdminUser had all already succeeded — and the
|
|
391
|
+
# installer's shell() throws on any non-zero exit, so a failure here is not
|
|
392
|
+
# recoverable further up.
|
|
393
|
+
#
|
|
394
|
+
# What makes that safe is that this change also ships the control: the
|
|
395
|
+
# heartbeat's [schedule-audit] op=roster reconciles the expected roster against
|
|
396
|
+
# what each account actually holds, every tick, naming the missing keys. A short
|
|
397
|
+
# seed is loud whether or not it aborts the install, so blocking buys nothing
|
|
398
|
+
# and costs a bricked upgrade.
|
|
399
|
+
ROUTINE_SEED_CLI="$PROJECT_DIR/lib/routine-templates/dist/seed-cli.js"
|
|
400
|
+
if [ ! -f "$ROUTINE_SEED_CLI" ]; then
|
|
401
|
+
echo " [routine-seed] op=skipped reason=cli-missing path=$ROUTINE_SEED_CLI — platform/lib/routine-templates was not built before the payload was bundled; run 'npm run build:lib' in platform/ and re-bundle. /routines will be empty and [schedule-audit] op=roster will report every key missing." >&2
|
|
402
|
+
elif ! command -v node &> /dev/null; then
|
|
403
|
+
echo " [routine-seed] op=skipped reason=no-node — node is required by the routine-roster seed. /routines will be empty and [schedule-audit] op=roster will report every key missing." >&2
|
|
404
|
+
else
|
|
405
|
+
NEO4J_URI="$NEO4J_URI" \
|
|
406
|
+
NEO4J_USER="$NEO4J_USER" \
|
|
407
|
+
NEO4J_PASSWORD="$NEO4J_PASSWORD" \
|
|
408
|
+
ROUTINE_SEED_ACCOUNT_ID="$ACCOUNT_ID" \
|
|
409
|
+
node "$ROUTINE_SEED_CLI" \
|
|
410
|
+
|| echo " [routine-seed] op=skipped reason=seed-failed — the routine roster did not seed; the account is otherwise fully provisioned. [schedule-audit] op=roster names the missing keys every tick, and the next upgrade re-seeds." >&2
|
|
411
|
+
fi
|
|
412
|
+
|
|
372
413
|
echo " Done."
|
|
@@ -58,6 +58,20 @@ EXPLICIT_OWNERSHIP = {
|
|
|
58
58
|
"memory/document-ingest": "librarian",
|
|
59
59
|
"memory/conversation-archive": "librarian",
|
|
60
60
|
"memory/conversation-archive-enrich": "librarian",
|
|
61
|
+
# publish-site/SKILL.md:10 — "Invoked from `specialists:content-producer`".
|
|
62
|
+
# The admin plugin declares no `specialist:` field, so without this entry
|
|
63
|
+
# the skill defaults to admin-owned and its two tools resolve against the
|
|
64
|
+
# wrong surface (Task 2132).
|
|
65
|
+
"admin/publish-site": "content-producer",
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
# Generated catalogue skills. platform-architecture is assembled from the docs
|
|
69
|
+
# mirror by scripts/assemble-architecture-skill.mjs and describes the whole
|
|
70
|
+
# platform, so it names tools it never calls — a token there is documentation,
|
|
71
|
+
# not a prescription. Token resolution does not apply; the forbidden-token rule
|
|
72
|
+
# still does (Task 2132).
|
|
73
|
+
CATALOGUE_SKILLS = {
|
|
74
|
+
"admin/platform-architecture",
|
|
61
75
|
}
|
|
62
76
|
|
|
63
77
|
# Skills that are explicitly admin-owned (loaded via plugin-read by the admin
|
|
@@ -138,6 +152,49 @@ def specialist_tools(specialist: str) -> set[str] | None:
|
|
|
138
152
|
return {t for t in items if t}
|
|
139
153
|
|
|
140
154
|
|
|
155
|
+
def scan_manifest_allowlists() -> tuple[set[str], set[str]]:
|
|
156
|
+
"""Long-prefix names of (every declared tool, those declared
|
|
157
|
+
`adminAllowlist: true`).
|
|
158
|
+
|
|
159
|
+
The admin agent's surface is NOT the union of all enabled plugins: a tool
|
|
160
|
+
declared `adminAllowlist: false` is excluded from the admin spawn by
|
|
161
|
+
tool-surface.ts, so an admin-owned skill naming one prescribes a call its
|
|
162
|
+
own agent cannot make. That premise left fourteen tools unreachable and
|
|
163
|
+
invisible to this gate until Task 2132 — capabilities-here/SKILL.md names
|
|
164
|
+
its tool in the required backtick form and still passed.
|
|
165
|
+
"""
|
|
166
|
+
declared: set[str] = set()
|
|
167
|
+
admin: set[str] = set()
|
|
168
|
+
for plugin in sorted(os.listdir(PLUGINS_DIR)):
|
|
169
|
+
manifest = os.path.join(PLUGINS_DIR, plugin, "PLUGIN.md")
|
|
170
|
+
if not os.path.exists(manifest):
|
|
171
|
+
continue
|
|
172
|
+
m = re.match(r"^---\n(.*?)\n---", open(manifest, encoding="utf-8").read(), re.S)
|
|
173
|
+
if not m:
|
|
174
|
+
continue
|
|
175
|
+
cur = None
|
|
176
|
+
in_tools = False
|
|
177
|
+
for line in m.group(1).split("\n"):
|
|
178
|
+
if re.match(r"^tools:\s*$", line):
|
|
179
|
+
in_tools = True
|
|
180
|
+
continue
|
|
181
|
+
if re.match(r"^[A-Za-z_]", line):
|
|
182
|
+
in_tools = False
|
|
183
|
+
cur = None
|
|
184
|
+
continue
|
|
185
|
+
if not in_tools:
|
|
186
|
+
continue
|
|
187
|
+
nm = re.match(r"^\s+-\s+name:\s*(.+?)\s*$", line)
|
|
188
|
+
if nm:
|
|
189
|
+
cur = nm.group(1)
|
|
190
|
+
declared.add(f"mcp__plugin_{plugin}_{plugin}__{cur}")
|
|
191
|
+
continue
|
|
192
|
+
aa = re.match(r"^\s+adminAllowlist:\s*(true|false)\s*$", line)
|
|
193
|
+
if aa and cur and aa.group(1) == "true":
|
|
194
|
+
admin.add(f"mcp__plugin_{plugin}_{plugin}__{cur}")
|
|
195
|
+
return declared, admin
|
|
196
|
+
|
|
197
|
+
|
|
141
198
|
def extract_prescribed_tokens(text: str) -> set[str]:
|
|
142
199
|
return set(TOKEN_RE.findall(text))
|
|
143
200
|
|
|
@@ -255,6 +312,7 @@ def main() -> int:
|
|
|
255
312
|
summary: list[str] = []
|
|
256
313
|
errors: list[str] = []
|
|
257
314
|
pairs_checked = 0
|
|
315
|
+
all_declared_tools, admin_surface = scan_manifest_allowlists()
|
|
258
316
|
|
|
259
317
|
for plugin in sorted(os.listdir(PLUGINS_DIR)):
|
|
260
318
|
pdir = os.path.join(PLUGINS_DIR, plugin)
|
|
@@ -288,7 +346,24 @@ def main() -> int:
|
|
|
288
346
|
)
|
|
289
347
|
|
|
290
348
|
if specialist is None:
|
|
291
|
-
# Admin-owned:
|
|
349
|
+
# Admin-owned: forbidden-token rule, plus the admin surface.
|
|
350
|
+
# A prescribed tool that some manifest declares must also be
|
|
351
|
+
# `adminAllowlist: true`, or the admin cannot call it. Tokens
|
|
352
|
+
# no manifest declares are upstream bridges (Playwright and
|
|
353
|
+
# friends) and are left to the drift gate (Task 2132).
|
|
354
|
+
unresolved_admin = (
|
|
355
|
+
[]
|
|
356
|
+
if ownership_key in CATALOGUE_SKILLS
|
|
357
|
+
else sorted(
|
|
358
|
+
t for t in prescribed
|
|
359
|
+
if t in all_declared_tools and t not in admin_surface
|
|
360
|
+
)
|
|
361
|
+
)
|
|
362
|
+
for tok in unresolved_admin:
|
|
363
|
+
errors.append(
|
|
364
|
+
f"[verify] skill={ownership_key} specialist=admin "
|
|
365
|
+
f"unresolved={tok} reason=not-admin-allowlisted"
|
|
366
|
+
)
|
|
292
367
|
for tok, ctx in forbidden:
|
|
293
368
|
errors.append(
|
|
294
369
|
f"[verify] skill={ownership_key} specialist=admin "
|
|
@@ -296,7 +371,8 @@ def main() -> int:
|
|
|
296
371
|
)
|
|
297
372
|
summary.append(
|
|
298
373
|
f"[verify] skill={ownership_key} specialist=admin (admin-owned) "
|
|
299
|
-
f"tokens={len(prescribed)}
|
|
374
|
+
f"tokens={len(prescribed)} unresolved={len(unresolved_admin)} "
|
|
375
|
+
f"forbidden={len(forbidden)}"
|
|
300
376
|
)
|
|
301
377
|
continue
|
|
302
378
|
|
|
@@ -314,6 +390,19 @@ def main() -> int:
|
|
|
314
390
|
f"[verify] skill={ownership_key} specialist={specialist} "
|
|
315
391
|
f"unresolved={tok}"
|
|
316
392
|
)
|
|
393
|
+
# A skill that instructs execution of a tool-emitted `mergeCypher`
|
|
394
|
+
# must name the tool that executes it. The token rule above is
|
|
395
|
+
# name-based, so prose like "Run the `mergeCypher`" resolves
|
|
396
|
+
# nothing and passes — the blind spot that left
|
|
397
|
+
# conversation-archive-enrich's wire step unexecutable while this
|
|
398
|
+
# gate reported resolved=5/5 (Task 2132).
|
|
399
|
+
if "mergeCypher" in text and not any(
|
|
400
|
+
tok.endswith("write_neo4j_cypher") for tok in prescribed
|
|
401
|
+
):
|
|
402
|
+
errors.append(
|
|
403
|
+
f"[verify] skill={ownership_key} specialist={specialist} "
|
|
404
|
+
f"mergecypher-unexecutable=no-write-cypher-tool-prescribed"
|
|
405
|
+
)
|
|
317
406
|
for tok, ctx in forbidden:
|
|
318
407
|
errors.append(
|
|
319
408
|
f"[verify] skill={ownership_key} specialist={specialist} "
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAyB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,
|
|
1
|
+
{"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAyB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAoUtD,CAAA"}
|
package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js
CHANGED
|
@@ -298,6 +298,7 @@ export const CANONICAL_MAXY_TOOL_NAMES = [
|
|
|
298
298
|
"mcp__plugin_scheduling_scheduling__schedule-get",
|
|
299
299
|
"mcp__plugin_scheduling_scheduling__schedule-import-ics",
|
|
300
300
|
"mcp__plugin_scheduling_scheduling__schedule-list",
|
|
301
|
+
"mcp__plugin_scheduling_scheduling__schedule-runs",
|
|
301
302
|
"mcp__plugin_scheduling_scheduling__schedule-update",
|
|
302
303
|
"mcp__plugin_scheduling_scheduling__time-resolve",
|
|
303
304
|
"mcp__plugin_storage-broker_storage-broker__storage-d1-create",
|