@rubytech/create-realagent-code 0.1.590 → 0.1.592
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/routine-templates/dist/index.d.ts +2 -2
- package/payload/platform/lib/routine-templates/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/routine-templates/dist/index.js +2 -9
- package/payload/platform/lib/routine-templates/dist/index.js.map +1 -1
- package/payload/platform/lib/routine-templates/dist/roster.d.ts +1 -11
- package/payload/platform/lib/routine-templates/dist/roster.d.ts.map +1 -1
- package/payload/platform/lib/routine-templates/dist/roster.js +11 -15
- package/payload/platform/lib/routine-templates/dist/roster.js.map +1 -1
- package/payload/platform/lib/routine-templates/src/__tests__/roster.test.ts +0 -0
- package/payload/platform/lib/routine-templates/src/__tests__/seed.test.ts +8 -3
- package/payload/platform/lib/routine-templates/src/index.ts +1 -8
- package/payload/platform/lib/routine-templates/src/roster.ts +10 -14
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +13 -0
- package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/outlook/PLUGIN.md +6 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-gate-probe.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-gate-probe.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-gate-probe.test.js +75 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-gate-probe.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/index.js +14 -0
- package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-gate-probe.d.ts +33 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-gate-probe.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-gate-probe.js +32 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-gate-probe.js.map +1 -0
- package/payload/platform/plugins/scheduling/PLUGIN.md +11 -5
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +4 -12
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js +85 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js +55 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts +10 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js +42 -6
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts +22 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js +73 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +79 -0
- 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/agent-turn-dispatch.d.ts +2 -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 +40 -1
- 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 +19 -2
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js +339 -275
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js +510 -96
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +62 -31
- 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 +153 -93
- 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 +8 -36
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts +234 -30
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js +349 -38
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -1
- package/payload/platform/scripts/check-specialist-tool-surface.mjs +15 -1
- 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/server/public/activity.html +6 -6
- package/payload/server/public/agents.html +5 -5
- package/payload/server/public/assets/{AdminLoginScreens-CemYu7ho.js → AdminLoginScreens-dBZJlMbp.js} +1 -1
- package/payload/server/public/assets/AdminLoginScreens-dBZJlMbp.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-dBZJlMbp.js.gz +0 -0
- package/payload/server/public/assets/{AdminShell-B5vEeSLw.js → AdminShell-D94sgtsb.js} +1 -1
- package/payload/server/public/assets/AdminShell-D94sgtsb.js.br +0 -0
- package/payload/server/public/assets/AdminShell-D94sgtsb.js.gz +0 -0
- package/payload/server/public/assets/{activity-BHSuZrqG.js → activity-D6NEUvT7.js} +1 -1
- package/payload/server/public/assets/activity-D6NEUvT7.js.br +0 -0
- package/payload/server/public/assets/activity-D6NEUvT7.js.gz +0 -0
- package/payload/server/public/assets/{admin-DnvauP59.js → admin-BluqXSKn.js} +1 -1
- package/payload/server/public/assets/admin-BluqXSKn.js.br +0 -0
- package/payload/server/public/assets/admin-BluqXSKn.js.gz +0 -0
- package/payload/server/public/assets/{agents-CwTJjfyV.js → agents-D_6V66dr.js} +1 -1
- package/payload/server/public/assets/agents-D_6V66dr.js.br +0 -0
- package/payload/server/public/assets/agents-D_6V66dr.js.gz +0 -0
- package/payload/server/public/assets/{browser-D4yjnKEH.js → browser-Bz9s6ztS.js} +1 -1
- package/payload/server/public/assets/browser-Bz9s6ztS.js.br +0 -0
- package/payload/server/public/assets/browser-Bz9s6ztS.js.gz +0 -0
- package/payload/server/public/assets/{calendar-DUi1XFyY.js → calendar-D5OCrmwA.js} +1 -1
- package/payload/server/public/assets/calendar-D5OCrmwA.js.br +0 -0
- package/payload/server/public/assets/calendar-D5OCrmwA.js.gz +0 -0
- package/payload/server/public/assets/chat-CjlbEzZ-.js +1 -0
- package/payload/server/public/assets/chat-CjlbEzZ-.js.br +1 -0
- package/payload/server/public/assets/chat-CjlbEzZ-.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-b_r2jNvg.js +1 -0
- package/payload/server/public/assets/chevron-left-b_r2jNvg.js.br +0 -0
- package/payload/server/public/assets/clock-D8tMbEZD.js +1 -0
- package/payload/server/public/assets/clock-D8tMbEZD.js.br +0 -0
- package/payload/server/public/assets/clock-D8tMbEZD.js.gz +0 -0
- package/payload/server/public/assets/{copy-Bw2h4ofb.js → copy-CXBu2lHL.js} +1 -1
- package/payload/server/public/assets/copy-CXBu2lHL.js.br +0 -0
- package/payload/server/public/assets/copy-CXBu2lHL.js.gz +0 -0
- package/payload/server/public/assets/data-ChHg_Lq9.js +1 -0
- package/payload/server/public/assets/data-ChHg_Lq9.js.br +0 -0
- package/payload/server/public/assets/data-ChHg_Lq9.js.gz +0 -0
- package/payload/server/public/assets/{field-BS-mu5Jx.js → field-D4fXu_SP.js} +1 -1
- package/payload/server/public/assets/field-D4fXu_SP.js.br +0 -0
- package/payload/server/public/assets/field-D4fXu_SP.js.gz +0 -0
- package/payload/server/public/assets/{file-text-xUlDn7ui.js → file-text-BxZ1UMcQ.js} +1 -1
- package/payload/server/public/assets/file-text-BxZ1UMcQ.js.br +0 -0
- package/payload/server/public/assets/file-text-BxZ1UMcQ.js.gz +0 -0
- package/payload/server/public/assets/{graph-DEEXiQLx.js → graph-DMleOCBZ.js} +1 -1
- package/payload/server/public/assets/graph-DMleOCBZ.js.br +0 -0
- package/payload/server/public/assets/graph-DMleOCBZ.js.gz +0 -0
- package/payload/server/public/assets/{graph-labels-F6hQJKCn.js → graph-labels-BHapdrTm.js} +1 -1
- package/payload/server/public/assets/graph-labels-BHapdrTm.js.br +0 -0
- package/payload/server/public/assets/graph-labels-BHapdrTm.js.gz +0 -0
- package/payload/server/public/assets/{jsx-runtime-DDrveXI8.css → jsx-runtime-gqFnq1MC.css} +1 -1
- package/payload/server/public/assets/jsx-runtime-gqFnq1MC.css.br +0 -0
- package/payload/server/public/assets/{jsx-runtime-DDrveXI8.css.gz → jsx-runtime-gqFnq1MC.css.gz} +0 -0
- package/payload/server/public/assets/{operator-CkWK9uRB.js → operator-BpZTRiga.js} +1 -1
- package/payload/server/public/assets/operator-BpZTRiga.js.br +0 -0
- package/payload/server/public/assets/operator-BpZTRiga.js.gz +0 -0
- package/payload/server/public/assets/{page-Dh6fCuUi.js → page-CsHWZZ0U.js} +1 -1
- package/payload/server/public/assets/page-CsHWZZ0U.js.br +0 -0
- package/payload/server/public/assets/page-CsHWZZ0U.js.gz +0 -0
- package/payload/server/public/assets/{page-DbWIOK60.js → page-Dczx6CPP.js} +1 -1
- package/payload/server/public/assets/page-Dczx6CPP.js.br +0 -0
- package/payload/server/public/assets/page-Dczx6CPP.js.gz +0 -0
- package/payload/server/public/assets/play-D_xdb6gy.js +1 -0
- package/payload/server/public/assets/play-D_xdb6gy.js.br +0 -0
- package/payload/server/public/assets/play-D_xdb6gy.js.gz +0 -0
- package/payload/server/public/assets/{public-DmD6vvFM.js → public-BzpELWaZ.js} +1 -1
- package/payload/server/public/assets/public-BzpELWaZ.js.br +0 -0
- package/payload/server/public/assets/public-BzpELWaZ.js.gz +0 -0
- package/payload/server/public/assets/{rotate-ccw-BDdOWTDl.js → rotate-ccw-Bkpst1na.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-Bkpst1na.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-Bkpst1na.js.gz +0 -0
- package/payload/server/public/assets/{routines-CZoKUK0p.js → routines-Cmuf8pPP.js} +2 -2
- package/payload/server/public/assets/routines-Cmuf8pPP.js.br +0 -0
- package/payload/server/public/assets/routines-Cmuf8pPP.js.gz +0 -0
- package/payload/server/public/assets/{skills-D0yS0qLX.js → skills-Bfq3Pbw-.js} +1 -1
- package/payload/server/public/assets/skills-Bfq3Pbw-.js.br +0 -0
- package/payload/server/public/assets/skills-Bfq3Pbw-.js.gz +0 -0
- package/payload/server/public/assets/{tasks-Dtn1uDRY.js → tasks-nyWLrolq.js} +1 -1
- package/payload/server/public/assets/tasks-nyWLrolq.js.br +0 -0
- package/payload/server/public/assets/tasks-nyWLrolq.js.gz +0 -0
- package/payload/server/public/assets/{triangle-alert-DN-Eswuf.js → triangle-alert-DkENIQJ6.js} +1 -1
- package/payload/server/public/assets/triangle-alert-DkENIQJ6.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-DkENIQJ6.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-BmOZr_Mw.js → useCopyFeedback-DmNjbXe9.js} +1 -1
- package/payload/server/public/assets/useCopyFeedback-DmNjbXe9.js.br +1 -0
- package/payload/server/public/assets/useCopyFeedback-DmNjbXe9.js.gz +0 -0
- package/payload/server/public/assets/{useMediaQuery-fFM7rxUD.js → useMediaQuery-DL-C1y_F.js} +1 -1
- package/payload/server/public/assets/useMediaQuery-DL-C1y_F.js.br +0 -0
- package/payload/server/public/assets/useMediaQuery-DL-C1y_F.js.gz +0 -0
- package/payload/server/public/assets/{useVoiceRecorder-D0MWFIde.js → useVoiceRecorder-DseLVULD.js} +1 -1
- package/payload/server/public/assets/useVoiceRecorder-DseLVULD.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-DseLVULD.js.gz +0 -0
- package/payload/server/public/assets/{wrench-C-yn7q1Q.js → wrench-C7tdp6z9.js} +1 -1
- package/payload/server/public/assets/wrench-C7tdp6z9.js.br +0 -0
- package/payload/server/public/assets/wrench-C7tdp6z9.js.gz +0 -0
- package/payload/server/public/browser.html +5 -5
- package/payload/server/public/calendar.html +8 -8
- package/payload/server/public/chat.html +14 -14
- package/payload/server/public/data.html +12 -12
- package/payload/server/public/field.html +3 -3
- package/payload/server/public/graph.html +10 -10
- package/payload/server/public/index.html +14 -14
- package/payload/server/public/operator.html +15 -15
- package/payload/server/public/public.html +14 -14
- package/payload/server/public/routines.html +8 -8
- package/payload/server/public/skills.html +6 -6
- package/payload/server/public/tasks.html +7 -7
- package/payload/server/server.js +41 -2
- package/payload/server/public/assets/AdminLoginScreens-CemYu7ho.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-CemYu7ho.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-B5vEeSLw.js.br +0 -0
- package/payload/server/public/assets/AdminShell-B5vEeSLw.js.gz +0 -0
- package/payload/server/public/assets/activity-BHSuZrqG.js.br +0 -0
- package/payload/server/public/assets/activity-BHSuZrqG.js.gz +0 -0
- package/payload/server/public/assets/admin-DnvauP59.js.br +0 -0
- package/payload/server/public/assets/admin-DnvauP59.js.gz +0 -0
- package/payload/server/public/assets/agents-CwTJjfyV.js.br +0 -0
- package/payload/server/public/assets/agents-CwTJjfyV.js.gz +0 -0
- package/payload/server/public/assets/browser-D4yjnKEH.js.br +0 -0
- package/payload/server/public/assets/browser-D4yjnKEH.js.gz +0 -0
- package/payload/server/public/assets/calendar-DUi1XFyY.js.br +0 -0
- package/payload/server/public/assets/calendar-DUi1XFyY.js.gz +0 -0
- package/payload/server/public/assets/chat-BJ1p4kuh.js +0 -1
- package/payload/server/public/assets/chat-BJ1p4kuh.js.br +0 -1
- package/payload/server/public/assets/chat-BJ1p4kuh.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-Ctw-3JsV.js +0 -1
- package/payload/server/public/assets/chevron-left-Ctw-3JsV.js.br +0 -0
- package/payload/server/public/assets/clock-BLOp42yY.js +0 -1
- package/payload/server/public/assets/clock-BLOp42yY.js.br +0 -0
- package/payload/server/public/assets/clock-BLOp42yY.js.gz +0 -0
- package/payload/server/public/assets/copy-Bw2h4ofb.js.br +0 -0
- package/payload/server/public/assets/copy-Bw2h4ofb.js.gz +0 -0
- package/payload/server/public/assets/data-uR7BZKVU.js +0 -1
- package/payload/server/public/assets/data-uR7BZKVU.js.br +0 -0
- package/payload/server/public/assets/data-uR7BZKVU.js.gz +0 -0
- package/payload/server/public/assets/field-BS-mu5Jx.js.br +0 -0
- package/payload/server/public/assets/field-BS-mu5Jx.js.gz +0 -0
- package/payload/server/public/assets/file-text-xUlDn7ui.js.br +0 -0
- package/payload/server/public/assets/file-text-xUlDn7ui.js.gz +0 -0
- package/payload/server/public/assets/graph-DEEXiQLx.js.br +0 -0
- package/payload/server/public/assets/graph-DEEXiQLx.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-F6hQJKCn.js.br +0 -0
- package/payload/server/public/assets/graph-labels-F6hQJKCn.js.gz +0 -0
- package/payload/server/public/assets/jsx-runtime-DDrveXI8.css.br +0 -0
- package/payload/server/public/assets/operator-CkWK9uRB.js.br +0 -0
- package/payload/server/public/assets/operator-CkWK9uRB.js.gz +0 -0
- package/payload/server/public/assets/page-DbWIOK60.js.br +0 -0
- package/payload/server/public/assets/page-DbWIOK60.js.gz +0 -0
- package/payload/server/public/assets/page-Dh6fCuUi.js.br +0 -0
- package/payload/server/public/assets/page-Dh6fCuUi.js.gz +0 -0
- package/payload/server/public/assets/play-fy3tdi7M.js +0 -1
- package/payload/server/public/assets/play-fy3tdi7M.js.br +0 -0
- package/payload/server/public/assets/play-fy3tdi7M.js.gz +0 -0
- package/payload/server/public/assets/public-DmD6vvFM.js.br +0 -0
- package/payload/server/public/assets/public-DmD6vvFM.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-BDdOWTDl.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-BDdOWTDl.js.gz +0 -0
- package/payload/server/public/assets/routines-CZoKUK0p.js.br +0 -0
- package/payload/server/public/assets/routines-CZoKUK0p.js.gz +0 -0
- package/payload/server/public/assets/skills-D0yS0qLX.js.br +0 -0
- package/payload/server/public/assets/skills-D0yS0qLX.js.gz +0 -0
- package/payload/server/public/assets/tasks-Dtn1uDRY.js.br +0 -0
- package/payload/server/public/assets/tasks-Dtn1uDRY.js.gz +0 -0
- package/payload/server/public/assets/triangle-alert-DN-Eswuf.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-DN-Eswuf.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-BmOZr_Mw.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-BmOZr_Mw.js.gz +0 -0
- package/payload/server/public/assets/useMediaQuery-fFM7rxUD.js.br +0 -0
- package/payload/server/public/assets/useMediaQuery-fFM7rxUD.js.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-D0MWFIde.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-D0MWFIde.js.gz +0 -0
- package/payload/server/public/assets/wrench-C-yn7q1Q.js.br +0 -0
- package/payload/server/public/assets/wrench-C-yn7q1Q.js.gz +0 -0
- /package/payload/server/public/assets/{jsx-runtime-DXWyHqht.js → jsx-runtime-BcrVQeV-.js} +0 -0
- /package/payload/server/public/assets/{jsx-runtime-DXWyHqht.js.br → jsx-runtime-BcrVQeV-.js.br} +0 -0
- /package/payload/server/public/assets/{jsx-runtime-DXWyHqht.js.gz → jsx-runtime-BcrVQeV-.js.gz} +0 -0
package/package.json
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* unrelated, which is worse than no citation.
|
|
32
32
|
*/
|
|
33
33
|
import { type RoutineTemplate } from "./roster.js";
|
|
34
|
-
export { ROUTINE_ROSTER, ROUTINE_ROSTER_KEYS, ROUTINE_TEMPLATE_VERSION, isWatermarkedCheck, gateNeedsCommit,
|
|
34
|
+
export { ROUTINE_ROSTER, ROUTINE_ROSTER_KEYS, ROUTINE_TEMPLATE_VERSION, isWatermarkedCheck, gateNeedsCommit, } from "./roster.js";
|
|
35
35
|
export type { RoutineTemplate, RoutineGate, RoutineGateCheck } from "./roster.js";
|
|
36
36
|
/** The minimal Neo4j session surface the seed needs. Both the admin plugin's
|
|
37
37
|
* `getSession()` and a driver session from `seed-cli` satisfy it; the tests
|
|
@@ -150,7 +150,7 @@ export declare function resolveOwnerTimezone(session: SeedSessionLike, accountId
|
|
|
150
150
|
* the commit token is substituted from the same `row.gateChecks` the gate is
|
|
151
151
|
* built from, so the precondition and the turn's own commit call cannot
|
|
152
152
|
* disagree about what this routine checks. */
|
|
153
|
-
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.description = 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.description = CASE WHEN refreshing THEN row.description ELSE e.description END,\n e.routineTemplateVersion = CASE WHEN refreshing THEN $version ELSE e.routineTemplateVersion END,\n e.updatedAt = CASE WHEN refreshing THEN $now ELSE e.updatedAt END\nWITH row, e, existed, priorVersion, edited, (NOT existed OR refreshing) AS writing\nSET e.gatePlugin = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE 'scheduling' END) ELSE e.gatePlugin END,\n e.gateTool = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE 'scheduling-gate' END) ELSE e.gateTool END,\n e.gateArgs = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE '{\"eventId\":\"' + e.eventId + '\",\"checks\":' + row.gateChecks + '}' END) ELSE e.gateArgs END
|
|
153
|
+
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.description = 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.description = CASE WHEN refreshing THEN row.description ELSE e.description END,\n e.routineTemplateVersion = CASE WHEN refreshing THEN $version ELSE e.routineTemplateVersion END,\n e.updatedAt = CASE WHEN refreshing THEN $now ELSE e.updatedAt END\nWITH row, e, existed, priorVersion, edited, (NOT existed OR refreshing) AS writing\nSET e.gatePlugin = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE 'scheduling' END) ELSE e.gatePlugin END,\n e.gateTool = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE 'scheduling-gate' END) ELSE e.gateTool END,\n e.gateArgs = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE '{\"eventId\":\"' + e.eventId + '\",\"checks\":' + row.gateChecks + '}' END) ELSE e.gateArgs 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";
|
|
154
154
|
/** The post-condition read. Counts every roster row the account actually holds,
|
|
155
155
|
* independently of what the MERGE above believes it wrote. */
|
|
156
156
|
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.description IS NULL THEN 1 ELSE 0 END) AS descNull";
|
|
@@ -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;AAQ7F,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.VERIFY_CYPHER = exports.MERGE_CYPHER = exports.
|
|
3
|
+
exports.VERIFY_CYPHER = exports.MERGE_CYPHER = exports.gateNeedsCommit = exports.isWatermarkedCheck = exports.ROUTINE_TEMPLATE_VERSION = exports.ROUTINE_ROSTER_KEYS = exports.ROUTINE_ROSTER = void 0;
|
|
4
4
|
exports.acctTag = acctTag;
|
|
5
5
|
exports.resolveOwnerTimezone = resolveOwnerTimezone;
|
|
6
6
|
exports.seedRoutineRoster = seedRoutineRoster;
|
|
@@ -49,10 +49,6 @@ Object.defineProperty(exports, "ROUTINE_ROSTER_KEYS", { enumerable: true, get: f
|
|
|
49
49
|
Object.defineProperty(exports, "ROUTINE_TEMPLATE_VERSION", { enumerable: true, get: function () { return roster_js_2.ROUTINE_TEMPLATE_VERSION; } });
|
|
50
50
|
Object.defineProperty(exports, "isWatermarkedCheck", { enumerable: true, get: function () { return roster_js_2.isWatermarkedCheck; } });
|
|
51
51
|
Object.defineProperty(exports, "gateNeedsCommit", { enumerable: true, get: function () { return roster_js_2.gateNeedsCommit; } });
|
|
52
|
-
// Task 2634 — the scheduling plugin's write-time guard accepts a prompt that
|
|
53
|
-
// carries this token, so the token has to be reachable from the package's own
|
|
54
|
-
// entry point rather than only from the roster the seed reads.
|
|
55
|
-
Object.defineProperty(exports, "GATE_COMMIT_TOKEN", { enumerable: true, get: function () { return roster_js_2.GATE_COMMIT_TOKEN; } });
|
|
56
52
|
/** Neo4j returns integers as its own `Integer` type over bolt and as plain
|
|
57
53
|
* numbers through a test fake. Normalise both without importing the driver. */
|
|
58
54
|
function toInt(raw) {
|
|
@@ -167,10 +163,7 @@ MERGE (e:Event {accountId: $accountId, routineTemplate: row.key})
|
|
|
167
163
|
WITH row, e, existed, priorVersion, edited, (NOT existed OR refreshing) AS writing
|
|
168
164
|
SET e.gatePlugin = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE 'scheduling' END) ELSE e.gatePlugin END,
|
|
169
165
|
e.gateTool = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE 'scheduling-gate' END) ELSE e.gateTool END,
|
|
170
|
-
e.gateArgs = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE '{"eventId":"' + e.eventId + '","checks":' + row.gateChecks + '}' END) ELSE e.gateArgs END
|
|
171
|
-
e.agentPrompt = CASE WHEN writing AND row.gateChecks IS NOT NULL
|
|
172
|
-
THEN replace(e.agentPrompt, '<<gateCommit>>', '{"eventId":"' + e.eventId + '","checks":' + row.gateChecks + ',"commit":true}')
|
|
173
|
-
ELSE e.agentPrompt END
|
|
166
|
+
e.gateArgs = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE '{"eventId":"' + e.eventId + '","checks":' + row.gateChecks + '}' END) ELSE e.gateArgs END
|
|
174
167
|
RETURN row.key AS key,
|
|
175
168
|
e.eventId AS eventId,
|
|
176
169
|
CASE WHEN NOT existed THEN 'create'
|
|
@@ -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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"}
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* routine's prompt only when the stored `routineTemplateVersion` is BELOW this
|
|
35
35
|
* and no operator has edited the row, so an unbumped edit ships to new installs
|
|
36
36
|
* and never reaches existing ones — bump it in the same commit as the edit. */
|
|
37
|
-
export declare const ROUTINE_TEMPLATE_VERSION =
|
|
37
|
+
export declare const ROUTINE_TEMPLATE_VERSION = 4;
|
|
38
38
|
/**
|
|
39
39
|
* Task 2379 — the check shapes a shipped template may name.
|
|
40
40
|
*
|
|
@@ -76,16 +76,6 @@ export type RoutineGateCheck = RoutineMailCheck | RoutineD1Check | RoutineWhatsa
|
|
|
76
76
|
export interface RoutineGate {
|
|
77
77
|
readonly checks: readonly RoutineGateCheck[];
|
|
78
78
|
}
|
|
79
|
-
/** Substituted by the seed with the full `scheduling-gate` argument object,
|
|
80
|
-
* including the row's own event id.
|
|
81
|
-
*
|
|
82
|
-
* A template cannot write that id: it is minted by the MERGE. Nor can the turn
|
|
83
|
-
* supply it, because the only place a scheduled turn sees its own event is the
|
|
84
|
-
* provenance preamble, which carries the first eight characters. The watermark
|
|
85
|
-
* file is named from the whole id, so a turn committing against the prefix
|
|
86
|
-
* would write a file the next gate never reads and the routine would report
|
|
87
|
-
* work for ever. */
|
|
88
|
-
export declare const GATE_COMMIT_TOKEN = "<<gateCommit>>";
|
|
89
79
|
/** True when the check compares against a stored position rather than reading a
|
|
90
80
|
* current one.
|
|
91
81
|
*
|
|
@@ -1 +1 @@
|
|
|
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;;;;;;;;;GASG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C;AACD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AACD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,QAAQ,CAAC;CACtC;AACD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AACD;iDACiD;AACjD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B;AACD,MAAM,MAAM,gBAAgB,GACxB,gBAAgB,GAChB,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,oBAAoB,CAAC;AAEzB;iEACiE;AACjE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC9C;
|
|
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;;;;;;;;;GASG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C;AACD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AACD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,QAAQ,CAAC;CACtC;AACD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AACD;iDACiD;AACjD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B;AACD,MAAM,MAAM,gBAAgB,GACxB,gBAAgB,GAChB,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,oBAAoB,CAAC;AAEzB;iEACiE;AACjE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC9C;AAWD;;;;;;;;;;;4DAW4D;AAC5D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAGnE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAE1D;AAED,MAAM,WAAW,eAAe;IAC9B;;mEAE+D;IAC/D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;6EAGyE;IACzE,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;IACxB;;;;2CAIuC;IACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IAC5B;;;+DAG2D;IAC3D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;2BAO2B;AAC3B,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAI/D;AAgKD;;;;;;;;iFAQiF;AACjF,eAAO,MAAM,cAAc,EAAE,SAAS,eAAe,EAsHpD,CAAC;AAEF;;6DAE6D;AAC7D,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAAqC,CAAC"}
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
* shipping a prompt that reaches for a tool no install serves.
|
|
33
33
|
*/
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
-
exports.ROUTINE_ROSTER_KEYS = exports.ROUTINE_ROSTER = exports.
|
|
35
|
+
exports.ROUTINE_ROSTER_KEYS = exports.ROUTINE_ROSTER = exports.ROUTINE_TEMPLATE_VERSION = void 0;
|
|
36
36
|
exports.isWatermarkedCheck = isWatermarkedCheck;
|
|
37
37
|
exports.gateNeedsCommit = gateNeedsCommit;
|
|
38
38
|
exports.isClassified = isClassified;
|
|
@@ -40,17 +40,15 @@ exports.isClassified = isClassified;
|
|
|
40
40
|
* routine's prompt only when the stored `routineTemplateVersion` is BELOW this
|
|
41
41
|
* and no operator has edited the row, so an unbumped edit ships to new installs
|
|
42
42
|
* and never reaches existing ones — bump it in the same commit as the edit. */
|
|
43
|
-
exports.ROUTINE_TEMPLATE_VERSION =
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
* work for ever. */
|
|
53
|
-
exports.GATE_COMMIT_TOKEN = "<<gateCommit>>";
|
|
43
|
+
exports.ROUTINE_TEMPLATE_VERSION = 4;
|
|
44
|
+
// Task 2663 — `GATE_COMMIT_TOKEN` is deleted. It stood in for a
|
|
45
|
+
// `scheduling-gate` call the routine's own turn made to advance its watermark,
|
|
46
|
+
// and the whole reason it had to be a token was that a template cannot write the
|
|
47
|
+
// event id the MERGE mints, while a turn only ever sees the first eight
|
|
48
|
+
// characters of it. That hazard is gone with the commit: the platform advances
|
|
49
|
+
// the mark itself, from the dispatcher, which holds the whole id by
|
|
50
|
+
// construction. A prompt that still contains the literal token is harmless prose
|
|
51
|
+
// naming a tool argument that no longer exists.
|
|
54
52
|
/** True when the check compares against a stored position rather than reading a
|
|
55
53
|
* current one.
|
|
56
54
|
*
|
|
@@ -151,9 +149,7 @@ An appointment on the provider calendar with no counterpart in the graph is invi
|
|
|
151
149
|
|
|
152
150
|
If the account has a busy-time sync configured, run schedule-connector-busy-sync so availability reflects what was just reconciled.
|
|
153
151
|
|
|
154
|
-
Reply only when something was actually changed, naming what and why. A clean reconcile ends the turn without replying, every time. This routine runs often, so a message on every clean run trains the operator to ignore it
|
|
155
|
-
|
|
156
|
-
When the run has finished and nothing failed, call scheduling-gate with <<gateCommit>> so the next run does not re-examine what you have just reconciled. Do not call it after a run that failed or that you stopped early: the work would be marked as handled without anyone having seen it.`;
|
|
152
|
+
Reply only when something was actually changed, naming what and why. A clean reconcile ends the turn without replying, every time. This routine runs often, so a message on every clean run trains the operator to ignore it.`;
|
|
157
153
|
const CONTACT_RECONCILE = `Reconcile the people the business actually deals with against the people it has recorded.
|
|
158
154
|
|
|
159
155
|
Call capabilities-here first. If neither a mail plugin nor the contacts plugin is enabled, end the turn without replying.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roster.js","sourceRoot":"","sources":["../src/roster.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;;;
|
|
1
|
+
{"version":3,"file":"roster.js","sourceRoot":"","sources":["../src/roster.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
@@ -384,9 +384,14 @@ describe("gate seeding", () => {
|
|
|
384
384
|
}
|
|
385
385
|
});
|
|
386
386
|
|
|
387
|
-
it("
|
|
388
|
-
|
|
389
|
-
|
|
387
|
+
it("writes no commit into any prompt (Task 2663)", () => {
|
|
388
|
+
// The seed used to expand `<<gateCommit>>` into a full argument object so the
|
|
389
|
+
// turn could advance its own watermark. The platform does that now, from the
|
|
390
|
+
// dispatcher, so the seed touching `agentPrompt` at all would only reinstate
|
|
391
|
+
// the writer this task removed.
|
|
392
|
+
expect(gateBlock()).not.toContain("gateCommit");
|
|
393
|
+
expect(gateBlock()).not.toContain('"commit":true');
|
|
394
|
+
expect(gateBlock()).not.toContain("e.agentPrompt");
|
|
390
395
|
});
|
|
391
396
|
|
|
392
397
|
it("passes serialised checks for a gated row and null for a gateless one", async () => {
|
|
@@ -44,10 +44,6 @@ export {
|
|
|
44
44
|
ROUTINE_TEMPLATE_VERSION,
|
|
45
45
|
isWatermarkedCheck,
|
|
46
46
|
gateNeedsCommit,
|
|
47
|
-
// Task 2634 — the scheduling plugin's write-time guard accepts a prompt that
|
|
48
|
-
// carries this token, so the token has to be reachable from the package's own
|
|
49
|
-
// entry point rather than only from the roster the seed reads.
|
|
50
|
-
GATE_COMMIT_TOKEN,
|
|
51
47
|
} from "./roster.js";
|
|
52
48
|
export type { RoutineTemplate, RoutineGate, RoutineGateCheck } from "./roster.js";
|
|
53
49
|
|
|
@@ -234,10 +230,7 @@ MERGE (e:Event {accountId: $accountId, routineTemplate: row.key})
|
|
|
234
230
|
WITH row, e, existed, priorVersion, edited, (NOT existed OR refreshing) AS writing
|
|
235
231
|
SET e.gatePlugin = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE 'scheduling' END) ELSE e.gatePlugin END,
|
|
236
232
|
e.gateTool = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE 'scheduling-gate' END) ELSE e.gateTool END,
|
|
237
|
-
e.gateArgs = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE '{"eventId":"' + e.eventId + '","checks":' + row.gateChecks + '}' END) ELSE e.gateArgs END
|
|
238
|
-
e.agentPrompt = CASE WHEN writing AND row.gateChecks IS NOT NULL
|
|
239
|
-
THEN replace(e.agentPrompt, '<<gateCommit>>', '{"eventId":"' + e.eventId + '","checks":' + row.gateChecks + ',"commit":true}')
|
|
240
|
-
ELSE e.agentPrompt END
|
|
233
|
+
e.gateArgs = CASE WHEN writing THEN (CASE WHEN row.gateChecks IS NULL THEN null ELSE '{"eventId":"' + e.eventId + '","checks":' + row.gateChecks + '}' END) ELSE e.gateArgs END
|
|
241
234
|
RETURN row.key AS key,
|
|
242
235
|
e.eventId AS eventId,
|
|
243
236
|
CASE WHEN NOT existed THEN 'create'
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* routine's prompt only when the stored `routineTemplateVersion` is BELOW this
|
|
36
36
|
* and no operator has edited the row, so an unbumped edit ships to new installs
|
|
37
37
|
* and never reaches existing ones — bump it in the same commit as the edit. */
|
|
38
|
-
export const ROUTINE_TEMPLATE_VERSION =
|
|
38
|
+
export const ROUTINE_TEMPLATE_VERSION = 4;
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* Task 2379 — the check shapes a shipped template may name.
|
|
@@ -85,16 +85,14 @@ export interface RoutineGate {
|
|
|
85
85
|
readonly checks: readonly RoutineGateCheck[];
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
* work for ever. */
|
|
97
|
-
export const GATE_COMMIT_TOKEN = "<<gateCommit>>";
|
|
88
|
+
// Task 2663 — `GATE_COMMIT_TOKEN` is deleted. It stood in for a
|
|
89
|
+
// `scheduling-gate` call the routine's own turn made to advance its watermark,
|
|
90
|
+
// and the whole reason it had to be a token was that a template cannot write the
|
|
91
|
+
// event id the MERGE mints, while a turn only ever sees the first eight
|
|
92
|
+
// characters of it. That hazard is gone with the commit: the platform advances
|
|
93
|
+
// the mark itself, from the dispatcher, which holds the whole id by
|
|
94
|
+
// construction. A prompt that still contains the literal token is harmless prose
|
|
95
|
+
// naming a tool argument that no longer exists.
|
|
98
96
|
|
|
99
97
|
/** True when the check compares against a stored position rather than reading a
|
|
100
98
|
* current one.
|
|
@@ -233,9 +231,7 @@ An appointment on the provider calendar with no counterpart in the graph is invi
|
|
|
233
231
|
|
|
234
232
|
If the account has a busy-time sync configured, run schedule-connector-busy-sync so availability reflects what was just reconciled.
|
|
235
233
|
|
|
236
|
-
Reply only when something was actually changed, naming what and why. A clean reconcile ends the turn without replying, every time. This routine runs often, so a message on every clean run trains the operator to ignore it
|
|
237
|
-
|
|
238
|
-
When the run has finished and nothing failed, call scheduling-gate with <<gateCommit>> so the next run does not re-examine what you have just reconciled. Do not call it after a run that failed or that you stopped early: the work would be marked as handled without anyone having seen it.`;
|
|
234
|
+
Reply only when something was actually changed, naming what and why. A clean reconcile ends the turn without replying, every time. This routine runs often, so a message on every clean run trains the operator to ignore it.`;
|
|
239
235
|
|
|
240
236
|
const CONTACT_RECONCILE = `Reconcile the people the business actually deals with against the people it has recorded.
|
|
241
237
|
|
|
@@ -9,6 +9,19 @@ Invoked by the admin agent directly.
|
|
|
9
9
|
|
|
10
10
|
This is the platform's release timeline, newest first. Each entry shows the date it shipped and the version it shipped in, so you can tell the operator how current their install is. To compare, read the installed version from `capabilities-here` and match it against the versions below. Keep answers high level and in plain English; this is a summary, not a full commit log.
|
|
11
11
|
|
|
12
|
+
## 2026-08-10 (0.1.592)
|
|
13
|
+
|
|
14
|
+
- A routine that has nothing to do now stops waking the assistant. The record of how far a check had already read was written by the assistant itself, so if it finished a turn without noting that it had looked, the routine woke again on the next tick and kept doing so. The platform now moves that marker itself once a wake is accepted, and a standing check reports a marker that has stopped moving.
|
|
15
|
+
|
|
16
|
+
## 2026-08-10 (0.1.591)
|
|
17
|
+
|
|
18
|
+
- A routine that watches Telegram can now be pointed at one bot. Before, it watched every bot on the account, so a routine watching your booking bot also woke up for every message to any other bot beside it, did the work, and threw it away. Naming a bot that does not exist is now reported as a fault rather than quietly treated as "nothing to do".
|
|
19
|
+
- Setting up a routine with a setting the system does not actually use is refused when you save it, and told you which settings that check does accept. Those settings used to be accepted and thrown away, so a routine could look like it was watching one thing while it watched everything.
|
|
20
|
+
- A message that arrived while a routine was still working is no longer treated as already handled. It used to be marked done at the end of the run whether or not anyone had seen it, so it was never mentioned again.
|
|
21
|
+
- Routines that check email now work with Microsoft 365 mailboxes, which were invisible to the check before.
|
|
22
|
+
- A routine is now tested against its own sources at the moment you set it up, so one pointed at something it cannot reach is caught then rather than running every time and quietly costing you.
|
|
23
|
+
- The routines page now marks a routine that keeps running without ever finding work, and one that is failing every time. Both used to look completely healthy.
|
|
24
|
+
|
|
12
25
|
## 2026-08-10 (0.1.590)
|
|
13
26
|
|
|
14
27
|
- A scheduled routine can now check for new Telegram messages without waking the assistant. Before, the only way to find out whether anything had come in was to run a full turn and pay for it, so a routine set to look every hour cost an hour's worth of thinking whether or not a single message had arrived. It now looks first and only runs the turn when there is something to answer.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "outlook",
|
|
3
|
-
"description": "Microsoft 365 / Outlook.com via Microsoft Graph. Mail is read (list, search, full-body), reply, delete, and compose (draft, draft-edit, send); contacts are read-only; calendar is read + control. Per-account OAuth device-code flow; no client secret. One account can hold several mailboxes at once; every operational tool takes an optional mailbox selector (email or graphUserId) and refuses ambiguously when two or more are attached and none is named. Tools — outlook-account-register / outlook-account-register-poll: device-code register (start + poll); outlook-mail-list / outlook-mail-search: inbox triage (~255-char preview) with a date window (list) or KQL from:/subject: filters (search) and a nextCursor for paging beyond the newest page; outlook-mail-fetch-body: full body of one message by id; outlook-mail-attachment: list any message's attachments (received or draft), or download one file attachment's bytes to the account uploads folder; outlook-mail-reply: in-thread reply (replyAll, cc/bcc, attachments); outlook-mail-delete: move to Deleted Items (recoverable); outlook-mail-ingest: write operator-reviewed messages into the business graph as :ConversationArchive threads (per-message ingest/discard, conversationId threading, closed-set participant resolution); outlook-mail-otp-extract: poll for a one-time code; outlook-mail-send / outlook-draft / outlook-draft-edit / outlook-draft-send: compose, edit, and send, all with attachments — outlook-draft takes an optional replyToMessageId to draft a threaded reply, unsent, under the original conversation; outlook-calendar-list / outlook-calendar-event: read calendar; outlook-calendar-create / outlook-calendar-update / outlook-calendar-cancel / outlook-calendar-respond / outlook-calendar-freebusy: control calendar; outlook-contacts-list: contacts; outlook-mailbox-info: auth state + folder count for one mailbox; outlook-mailbox-list: every connected mailbox, signed-in and shared, with an opt-in reachability probe; outlook-shared-mailbox-add / outlook-shared-mailbox-remove: attach or detach a shared mailbox (no licence, no sign-in of its own) through the signed-in mailbox's Full Access, access proved before anything is stored.",
|
|
3
|
+
"description": "Microsoft 365 / Outlook.com via Microsoft Graph. Mail is read (list, search, full-body), reply, delete, and compose (draft, draft-edit, send); contacts are read-only; calendar is read + control. Per-account OAuth device-code flow; no client secret. One account can hold several mailboxes at once; every operational tool takes an optional mailbox selector (email or graphUserId) and refuses ambiguously when two or more are attached and none is named. Tools — outlook-account-register / outlook-account-register-poll: device-code register (start + poll); outlook-mail-list / outlook-mail-search: inbox triage (~255-char preview) with a date window (list) or KQL from:/subject: filters (search) and a nextCursor for paging beyond the newest page; outlook-mail-fetch-body: full body of one message by id; outlook-mail-probe: the newest receivedDateTime in one folder and nothing else, for the scheduling gate's mail precondition; outlook-mail-attachment: list any message's attachments (received or draft), or download one file attachment's bytes to the account uploads folder; outlook-mail-reply: in-thread reply (replyAll, cc/bcc, attachments); outlook-mail-delete: move to Deleted Items (recoverable); outlook-mail-ingest: write operator-reviewed messages into the business graph as :ConversationArchive threads (per-message ingest/discard, conversationId threading, closed-set participant resolution); outlook-mail-otp-extract: poll for a one-time code; outlook-mail-send / outlook-draft / outlook-draft-edit / outlook-draft-send: compose, edit, and send, all with attachments — outlook-draft takes an optional replyToMessageId to draft a threaded reply, unsent, under the original conversation; outlook-calendar-list / outlook-calendar-event: read calendar; outlook-calendar-create / outlook-calendar-update / outlook-calendar-cancel / outlook-calendar-respond / outlook-calendar-freebusy: control calendar; outlook-contacts-list: contacts; outlook-mailbox-info: auth state + folder count for one mailbox; outlook-mailbox-list: every connected mailbox, signed-in and shared, with an opt-in reachability probe; outlook-shared-mailbox-add / outlook-shared-mailbox-remove: attach or detach a shared mailbox (no licence, no sign-in of its own) through the signed-in mailbox's Full Access, access proved before anything is stored.",
|
|
4
4
|
"version": "0.1.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Rubytech LLC"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: outlook
|
|
3
|
-
description: Microsoft 365 / Outlook.com via Microsoft Graph. Mail is read (list, search, full-body), reply, delete, and compose (draft, draft-edit, send); contacts are read-only; calendar is read + control. Per-account OAuth device-code flow; no client secret. One account can hold several mailboxes at once; every operational tool takes an optional mailbox selector (email or graphUserId) and refuses ambiguously when two or more are attached and none is named. Tools — outlook-account-register / outlook-account-register-poll: device-code register (start + poll); outlook-mail-list / outlook-mail-search: inbox triage (~255-char preview) with a date window (list) or KQL from:/subject: filters (search) and a nextCursor for paging beyond the newest page; outlook-mail-fetch-body: full body of one message by id; outlook-mail-attachment: list any message's attachments (received or draft), or download one file attachment's bytes to the account uploads folder; outlook-mail-reply: in-thread reply (replyAll, cc/bcc, attachments); outlook-mail-delete: move to Deleted Items (recoverable); outlook-mail-ingest: write operator-reviewed messages into the business graph as :ConversationArchive threads (per-message ingest/discard, conversationId threading, closed-set participant resolution); outlook-mail-otp-extract: poll for a one-time code; outlook-mail-send / outlook-draft / outlook-draft-edit / outlook-draft-send: compose, edit, and send, all with attachments — outlook-draft takes an optional replyToMessageId to draft a threaded reply, unsent, under the original conversation; outlook-calendar-list / outlook-calendar-event: read calendar; outlook-calendar-create / outlook-calendar-update / outlook-calendar-cancel / outlook-calendar-respond / outlook-calendar-freebusy: control calendar; outlook-contacts-list: contacts; outlook-mailbox-info: auth state + folder count for one mailbox; outlook-mailbox-list: every connected mailbox, signed-in and shared, with an opt-in reachability probe; outlook-shared-mailbox-add / outlook-shared-mailbox-remove: attach or detach a shared mailbox (no licence, no sign-in of its own) through the signed-in mailbox's Full Access, access proved before anything is stored.
|
|
3
|
+
description: Microsoft 365 / Outlook.com via Microsoft Graph. Mail is read (list, search, full-body), reply, delete, and compose (draft, draft-edit, send); contacts are read-only; calendar is read + control. Per-account OAuth device-code flow; no client secret. One account can hold several mailboxes at once; every operational tool takes an optional mailbox selector (email or graphUserId) and refuses ambiguously when two or more are attached and none is named. Tools — outlook-account-register / outlook-account-register-poll: device-code register (start + poll); outlook-mail-list / outlook-mail-search: inbox triage (~255-char preview) with a date window (list) or KQL from:/subject: filters (search) and a nextCursor for paging beyond the newest page; outlook-mail-fetch-body: full body of one message by id; outlook-mail-probe: the newest receivedDateTime in one folder and nothing else, for the scheduling gate's mail precondition; outlook-mail-attachment: list any message's attachments (received or draft), or download one file attachment's bytes to the account uploads folder; outlook-mail-reply: in-thread reply (replyAll, cc/bcc, attachments); outlook-mail-delete: move to Deleted Items (recoverable); outlook-mail-ingest: write operator-reviewed messages into the business graph as :ConversationArchive threads (per-message ingest/discard, conversationId threading, closed-set participant resolution); outlook-mail-otp-extract: poll for a one-time code; outlook-mail-send / outlook-draft / outlook-draft-edit / outlook-draft-send: compose, edit, and send, all with attachments — outlook-draft takes an optional replyToMessageId to draft a threaded reply, unsent, under the original conversation; outlook-calendar-list / outlook-calendar-event: read calendar; outlook-calendar-create / outlook-calendar-update / outlook-calendar-cancel / outlook-calendar-respond / outlook-calendar-freebusy: control calendar; outlook-contacts-list: contacts; outlook-mailbox-info: auth state + folder count for one mailbox; outlook-mailbox-list: every connected mailbox, signed-in and shared, with an opt-in reachability probe; outlook-shared-mailbox-add / outlook-shared-mailbox-remove: attach or detach a shared mailbox (no licence, no sign-in of its own) through the signed-in mailbox's Full Access, access proved before anything is stored.
|
|
4
4
|
tools:
|
|
5
5
|
- name: outlook-account-register
|
|
6
6
|
publicAllowlist: false
|
|
@@ -18,6 +18,10 @@ tools:
|
|
|
18
18
|
publicAllowlist: false
|
|
19
19
|
adminAllowlist: false
|
|
20
20
|
riskClass: read
|
|
21
|
+
- name: outlook-mail-probe
|
|
22
|
+
publicAllowlist: false
|
|
23
|
+
adminAllowlist: false
|
|
24
|
+
riskClass: read
|
|
21
25
|
- name: outlook-mail-fetch-body
|
|
22
26
|
publicAllowlist: false
|
|
23
27
|
adminAllowlist: false
|
|
@@ -132,6 +136,7 @@ Microsoft Graph access for Outlook.com / Microsoft 365 mailboxes. Mail is read (
|
|
|
132
136
|
- **Register:** `outlook-account-register` — starts the OAuth device-code flow against the brand's Entra app and returns a user code + verification URL immediately. The operator opens `microsoft.com/devicelogin` on any device, enters the code, and consents. The always-running server then completes registration on its own: a self-contained dispatcher (`dist/scripts/complete-registration.js`), armed on a 30 s interval, polls every live pending code to a terminal outcome, so a mailbox connects once the operator consents with no agent action. `outlook-account-register-poll` remains the manual path and the fallback, one check per call. Registering a second mailbox on the same account adds it alongside the first rather than replacing it; each mailbox holds its own encrypted tokens (AES-256-CBC) under a shared account key. One device-code flow runs at a time per account; starting another while one is live returns an `in-progress` signal. Observability: `devicecode-autopoll` per poll cycle and an independent `devicecode-stranded` audit for any pending code left un-harvested past its lifetime.
|
|
133
137
|
- **Multiple mailboxes:** one account can hold several mailboxes. Every operational tool takes an optional `mailbox` argument (email or graphUserId). With one mailbox, omit it. With two or more, name it — omitting it returns a refusal listing the connected mailboxes. `outlook-mailbox-list` shows them all.
|
|
134
138
|
- **Mail (read):** `outlook-mail-list` returns messages newest-first with an optional `since`/`before` date window, and `outlook-mail-search` runs a Graph `$search` (KQL) query where `from:`/`to:`/`subject:`/`received>=` filters live — both return Microsoft's short `bodyPreview` (~255 chars) for cheap triage and a `nextCursor` for paging beyond the 250-per-page window (the cursor is an opaque `@odata.nextLink`; pass it back as `cursor`). Graph forbids `$search`+`$filter`, so the strict date window is on the list tool and sender/subject filtering is on the search tool. `outlook-mail-fetch-body` reads the COMPLETE body of one message by id (HTML decoded to text, no preview cap) — the full-read path. All three read tools report `hasAttachments` per message, so the agent knows to reach for the attachment tool.
|
|
139
|
+
- **Mail (gate probe):** `outlook-mail-probe` returns the newest `receivedDateTime` in one folder and nothing else — no ids, subjects, senders or previews. It exists for the scheduling plugin's `mail` gate check on a Microsoft 365 mailbox, which the IMAP arm cannot see because a Graph mailbox has no `:EmailAccount` node; the gate reaches it by spawning this plugin's own MCP server, since the provider owns the decryption of its own tokens. Graph returns the newest message whether or not anything arrived, so a non-null answer is **not** evidence of work — the arrival test is the caller's comparison against its own stored watermark. Requires `Mail.Read`.
|
|
135
140
|
- **Mail (attachments):** `outlook-mail-attachment` lists or downloads any message's attachments — received or draft. Called with `messageId` alone it LISTS them (`id`, `name`, `contentType`, `size`, `isInline`, and a `kind` of `file`/`item`/`reference`) via `GET /me/messages/{id}/attachments` with `$select` (no bytes); a draft is a message in the same collection, so passing a draftId lists what that draft carries, and the returned `name`/`id` is the handle `outlook-draft-edit`'s `removeAttachments` takes. Called with `messageId`+`attachmentId` it DOWNLOADS one file attachment: the bytes are written to `{accountDir}/uploads/outlook/<messageHash>/<bytesHash>-<name>` at `0o600` and the saved absolute path is returned, ready for the Read tool, `SendUserFile`, or an `outlook-mail-reply` attachment. Only file attachments download — `item` (embedded message/event) and `reference` (cloud-drive link) kinds are refused, as are empty payloads and anything over the 25 MB cap; in each case nothing is written. Requires `Mail.Read`.
|
|
136
141
|
- **Mail (reply / delete):** `outlook-mail-reply` replies in-thread (native `conversationId` threading) with `replyAll`, added cc/bcc, and account-scoped file attachments (up to 25 MB per file — files over Graph's ~3 MB inline limit stream through a chunked upload session); the body is prepended above the quoted original. A reply whose recipients resolve **only** to the sending mailbox is refused before the send and its draft deleted: Graph addresses a reply to the original message's sender, so replying to your own sent message addresses it to yourself. An explicit `cc` does not exempt it — use `outlook-mail-send` with an explicit `to` instead. Both `outlook-mail-reply` and `outlook-draft` log the resolved recipients as `to=`. `outlook-mail-delete` moves messages to Deleted Items (recoverable — never hard-deletes). Both require `Mail.ReadWrite` (reply also needs `Mail.Send`).
|
|
137
142
|
- **Mail (ingest to graph):** `outlook-mail-ingest` writes operator-reviewed messages into the business graph as `:ConversationArchive {source:'email'}` threads, the analogue of the IMAP `email-ingest`. Input is `decisions`: one `{messageId, disposition:'ingest'|'discard'}` per listed message. Each `ingest` message's full body + envelope is fetched via `runMailFetchBody`, threads are grouped by Graph `conversationId`, and participant resolution is closed-set — every From/To/Cc address must already resolve to a `:Person.email` or `:AdminUser.email` for the `accountId`, or its thread is skipped and the address is returned to the operator (no `:Person` auto-create). Resolvable threads dispatch one at a time through the shared `plugins/memory/bin/conversation-archive-ingest.sh --source email` (same RFC822 thread-JSON shape the `email` normaliser consumes). This is the plugin's only Neo4j coupling (`neo4j-driver`). Human-in-the-loop: nothing enters the graph without an explicit per-message decision; the `outlook-mail-ingest` skill drives the list → summarise → ask → ingest loop. Requires `Mail.Read`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mail-gate-probe.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mail-gate-probe.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { mkdtempSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { TokenStore } from "../auth/token-store.js";
|
|
7
|
+
import { runMailGateProbe } from "../tools/mail-gate-probe.js";
|
|
8
|
+
function configWithToken(accountId) {
|
|
9
|
+
const dir = mkdtempSync(join(tmpdir(), "outlook-probe-"));
|
|
10
|
+
const tokenStore = new TokenStore(accountId, dir);
|
|
11
|
+
tokenStore.store("access-token", "refresh-token", 3600, { scopes: ["Mail.Read"] });
|
|
12
|
+
return { clientId: "test-client", tenantId: "common", accountId, tokenStore, mailboxAddress: null };
|
|
13
|
+
}
|
|
14
|
+
function mockGraph(status, bodyObj) {
|
|
15
|
+
const calls = [];
|
|
16
|
+
const original = globalThis.fetch;
|
|
17
|
+
globalThis.fetch = (async (input, init) => {
|
|
18
|
+
const req = input instanceof Request ? input : null;
|
|
19
|
+
const url = req ? req.url : typeof input === "string" ? input : input.toString();
|
|
20
|
+
if (!url.includes("graph.microsoft.com"))
|
|
21
|
+
return original(input, init);
|
|
22
|
+
calls.push(url);
|
|
23
|
+
const payload = bodyObj === null ? null : JSON.stringify(bodyObj);
|
|
24
|
+
const headers = bodyObj === null ? undefined : { "content-type": "application/json" };
|
|
25
|
+
return new Response(payload, { status, headers });
|
|
26
|
+
});
|
|
27
|
+
return { restore: () => { globalThis.fetch = original; }, calls };
|
|
28
|
+
}
|
|
29
|
+
test("outlook-mail-probe: returns the newest receivedDateTime and nothing else", async () => {
|
|
30
|
+
const mock = mockGraph(200, { value: [{ receivedDateTime: "2026-08-10T09:05:00Z" }] });
|
|
31
|
+
try {
|
|
32
|
+
const r = await runMailGateProbe(configWithToken("acct-probe-1"), {});
|
|
33
|
+
assert.deepEqual(r, { newestReceivedAt: "2026-08-10T09:05:00Z" });
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
mock.restore();
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
test("outlook-mail-probe: asks for one message, newest first, selecting only the timestamp", async () => {
|
|
40
|
+
const mock = mockGraph(200, { value: [{ receivedDateTime: "2026-08-10T09:05:00Z" }] });
|
|
41
|
+
try {
|
|
42
|
+
await runMailGateProbe(configWithToken("acct-probe-2"), {});
|
|
43
|
+
const url = decodeURIComponent(mock.calls[0]);
|
|
44
|
+
assert.match(url, /\/mailFolders\/Inbox\/messages/);
|
|
45
|
+
assert.match(url, /\$top=1/);
|
|
46
|
+
assert.match(url, /\$orderby=receivedDateTime DESC/);
|
|
47
|
+
assert.match(url, /\$select=receivedDateTime/);
|
|
48
|
+
// No message content is requested: no ids, subjects, senders or previews.
|
|
49
|
+
assert.doesNotMatch(url, /bodyPreview|subject|from/);
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
mock.restore();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
test("outlook-mail-probe: an empty folder is null, not an error", async () => {
|
|
56
|
+
const mock = mockGraph(200, { value: [] });
|
|
57
|
+
try {
|
|
58
|
+
const r = await runMailGateProbe(configWithToken("acct-probe-3"), {});
|
|
59
|
+
assert.deepEqual(r, { newestReceivedAt: null });
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
mock.restore();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
test("outlook-mail-probe: resolves a folder alias to its Graph well-known token", async () => {
|
|
66
|
+
const mock = mockGraph(200, { value: [] });
|
|
67
|
+
try {
|
|
68
|
+
await runMailGateProbe(configWithToken("acct-probe-4"), { folder: "Sent Items" });
|
|
69
|
+
assert.match(decodeURIComponent(mock.calls[0]), /\/mailFolders\/sentitems\/messages/);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
mock.restore();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=mail-gate-probe.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mail-gate-probe.test.js","sourceRoot":"","sources":["../../src/__tests__/mail-gate-probe.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,6 +26,7 @@ import { graphInboxProbe, runSharedMailboxAdd } from "./tools/shared-mailbox-add
|
|
|
26
26
|
import { runSharedMailboxRemove } from "./tools/shared-mailbox-remove.js";
|
|
27
27
|
import { runAccountRegisterStart, runAccountRegisterPoll } from "./tools/account-register.js";
|
|
28
28
|
import { runMailList } from "./tools/mail-list.js";
|
|
29
|
+
import { runMailGateProbe } from "./tools/mail-gate-probe.js";
|
|
29
30
|
import { runMailSearch } from "./tools/mail-search.js";
|
|
30
31
|
import { runMailFetchBody } from "./tools/mail-fetch-body.js";
|
|
31
32
|
import { runMailAttachmentList, runMailAttachmentDownload } from "./tools/mail-attachment.js";
|
|
@@ -261,6 +262,19 @@ lifelineTool(server, "outlook-mail-list", "List messages in a mailbox folder, ne
|
|
|
261
262
|
return fail(`outlook-mail-list failed: ${err.message}`);
|
|
262
263
|
}
|
|
263
264
|
});
|
|
265
|
+
lifelineTool(server, "outlook-mail-probe", "Return the newest message's receivedDateTime in one mailbox folder, and nothing else — no ids, subjects, senders or previews. This is the scheduling gate's mail precondition: it answers 'has anything arrived here' for a routine deciding whether to spend a model turn. Folder: a well-known name or alias, Inbox when omitted. Returns { newestReceivedAt: ISO 8601 string | null }; null means the folder holds no message at all. A non-null value is NOT on its own evidence that anything arrived — the newest message comes back whether or not it is new — so the caller compares it against its own stored position. To read mail, use outlook-mail-list.", {
|
|
266
|
+
folder: z.string().optional(),
|
|
267
|
+
mailbox: mailboxArg,
|
|
268
|
+
}, async ({ folder, mailbox }) => {
|
|
269
|
+
if (!ACCOUNT_ID)
|
|
270
|
+
return refuseNoAccount("outlook-mail-probe");
|
|
271
|
+
try {
|
|
272
|
+
return ok(await runMailGateProbe(getConfig(mailbox), { folder }));
|
|
273
|
+
}
|
|
274
|
+
catch (err) {
|
|
275
|
+
return fail(`outlook-mail-probe failed: ${err.message}`);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
264
278
|
lifelineTool(server, "outlook-mail-search", "Search mail with Microsoft Graph $search (KQL), applied with ConsistencyLevel=eventual. Put filters in the query: free text, from:addr, to:addr, subject:text, received>=2024-01-01. Graph forbids combining $search with a date $filter, so date-narrow here via the received: KQL term (use outlook-mail-list for a strict receivedDateTime window). Pagination: the response carries nextCursor when more results remain — pass it back as cursor for the next page (cursor supersedes query). Returns { items (same shape as outlook-mail-list), nextCursor, dropped }. On a SHARED mailbox a hit whose id cannot be re-resolved into a durable handle is omitted from items and counted in dropped, so dropped > 0 means the mailbox matched more than you are seeing — say so rather than reporting items as the complete answer.", {
|
|
265
279
|
query: z.string().min(1).describe("KQL search query. Ignored when cursor is set (the cursor's nextLink re-issues the original search) — pass the same query you used for the first page."),
|
|
266
280
|
top: z.number().int().min(1).max(250).optional(),
|