@rubytech/create-maxy-code 0.1.572 → 0.1.574
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/config/brand.json +2 -2
- package/payload/platform/lib/admins-write/__tests__/index.test.ts +97 -0
- package/payload/platform/lib/admins-write/dist/index.d.ts +12 -0
- package/payload/platform/lib/admins-write/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/admins-write/dist/index.js +27 -5
- package/payload/platform/lib/admins-write/dist/index.js.map +1 -1
- package/payload/platform/lib/admins-write/src/index.ts +35 -5
- package/payload/platform/lib/admins-write/vitest.config.ts +14 -0
- package/payload/platform/lib/dispatch-read/dist/session.d.ts.map +1 -1
- package/payload/platform/lib/dispatch-read/dist/session.js +19 -4
- package/payload/platform/lib/dispatch-read/dist/session.js.map +1 -1
- package/payload/platform/lib/dispatch-read/src/__tests__/session.test.ts +91 -0
- package/payload/platform/lib/dispatch-read/src/session.ts +25 -6
- 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 +9 -1
- package/payload/platform/lib/routine-templates/dist/index.js.map +1 -1
- package/payload/platform/lib/routine-templates/src/index.ts +14 -2
- package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +8 -3
- package/payload/platform/plugins/admin/hooks/__tests__/html-structure-gate.test.sh +264 -0
- package/payload/platform/plugins/admin/hooks/__tests__/quote-render-pdf-conformance.test.sh +122 -24
- package/payload/platform/plugins/admin/hooks/__tests__/specialist-dispatch-gate.test.sh +158 -0
- package/payload/platform/plugins/admin/hooks/html-structure-gate.sh +165 -0
- package/payload/platform/plugins/admin/hooks/quote-render-pdf-conformance.sh +111 -19
- package/payload/platform/plugins/admin/hooks/specialist-dispatch-gate.sh +159 -0
- package/payload/platform/plugins/admin/mcp/dist/admin-bind-classify.d.ts +27 -0
- package/payload/platform/plugins/admin/mcp/dist/admin-bind-classify.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/admin-bind-classify.js +29 -0
- package/payload/platform/plugins/admin/mcp/dist/admin-bind-classify.js.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/binding-validate.d.ts +11 -0
- package/payload/platform/plugins/admin/mcp/dist/binding-validate.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/binding-validate.js +20 -0
- package/payload/platform/plugins/admin/mcp/dist/binding-validate.js.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js +137 -2
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/skills/admin-user-management/SKILL.md +32 -2
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +192 -90
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +18 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +71 -31
- package/payload/platform/plugins/docs/references/channel-wake-and-prompt.md +50 -57
- package/payload/platform/plugins/docs/references/internals.md +6 -0
- package/payload/platform/plugins/docs/references/outlook-guide.md +31 -1
- package/payload/platform/plugins/docs/references/telegram-guide.md +23 -0
- package/payload/platform/plugins/docs/references/troubleshooting.md +10 -0
- package/payload/platform/plugins/email/PLUGIN.md +1 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.js +36 -5
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js +10 -5
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +12 -6
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js +18 -8
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.js +41 -10
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.js.map +1 -1
- package/payload/platform/plugins/email/references/email-reference.md +12 -0
- package/payload/platform/plugins/outlook/PLUGIN.md +3 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger-write-sites.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger-write-sites.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger-write-sites.test.js +177 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger-write-sites.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger.test.js +130 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-reconcile.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-reconcile.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-reconcile.test.js +162 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-reconcile.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-state-fields.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-state-fields.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-state-fields.test.js +168 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-state-fields.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/draft-ledger.d.ts +64 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/draft-ledger.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/draft-ledger.js +110 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/draft-ledger.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/draft-reconcile.d.ts +119 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/draft-reconcile.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/draft-reconcile.js +0 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/draft-reconcile.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/scripts/draft-reconcile.d.ts +8 -0
- package/payload/platform/plugins/outlook/mcp/dist/scripts/draft-reconcile.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/scripts/draft-reconcile.js +247 -0
- package/payload/platform/plugins/outlook/mcp/dist/scripts/draft-reconcile.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.js +10 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js +21 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts +16 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js +5 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.d.ts +4 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.js +2 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js +24 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.js +2 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js +29 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js.map +1 -1
- package/payload/platform/plugins/scheduling/PLUGIN.md +4 -0
- package/payload/platform/plugins/scheduling/mcp/dist/__tests__/draft-reconcile-throttle.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/__tests__/draft-reconcile-throttle.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/__tests__/draft-reconcile-throttle.test.js +21 -0
- package/payload/platform/plugins/scheduling/mcp/dist/__tests__/draft-reconcile-throttle.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/draft-reconcile-throttle.d.ts +13 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/draft-reconcile-throttle.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/draft-reconcile-throttle.js +10 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/draft-reconcile-throttle.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +54 -0
- 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 +78 -5
- 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 +133 -2
- 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 +11 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +30 -1
- 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 -0
- 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.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js +37 -6
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -1
- package/payload/platform/plugins/telegram/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/telegram/PLUGIN.md +14 -2
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-census.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-census.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-census.test.js +77 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-census.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-guard.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-guard.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-guard.test.js +49 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-guard.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-methods.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-methods.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-methods.test.js +25 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-methods.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-tool.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-tool.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-tool.test.js +115 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-tool.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/bot-api.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/bot-api.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/bot-api.test.js +83 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/bot-api.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/index.js +42 -0
- package/payload/platform/plugins/telegram/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-census.d.ts +32 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-census.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-census.js +59 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-census.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-guard.d.ts +18 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-guard.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-guard.js +35 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-guard.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-methods.d.ts +38 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-methods.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-methods.js +21 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-methods.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/bot-api.d.ts +24 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/bot-api.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/bot-api.js +57 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/bot-api.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/api-census.d.ts +16 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/api-census.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/api-census.js +34 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/api-census.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/api.d.ts +26 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/api.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/api.js +80 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/api.js.map +1 -0
- package/payload/platform/plugins/telegram/skills/build/SKILL.md +110 -0
- package/payload/platform/plugins/telegram/skills/build/references/methods.md +219 -0
- package/payload/platform/scripts/check-no-esm-require.mjs +4 -0
- package/payload/platform/services/claude-session-manager/dist/authored-specialist-tools.d.ts +32 -0
- package/payload/platform/services/claude-session-manager/dist/authored-specialist-tools.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/authored-specialist-tools.js +144 -0
- package/payload/platform/services/claude-session-manager/dist/authored-specialist-tools.js.map +1 -0
- 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 +3 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/html-structure-census.d.ts +44 -0
- package/payload/platform/services/claude-session-manager/dist/html-structure-census.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/html-structure-census.js +185 -0
- package/payload/platform/services/claude-session-manager/dist/html-structure-census.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +32 -5
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +125 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +12 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +13 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/quote-delivery-reconcile.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/quote-delivery-reconcile.js +7 -0
- package/payload/platform/services/claude-session-manager/dist/quote-delivery-reconcile.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/quote-print-census.d.ts +42 -0
- package/payload/platform/services/claude-session-manager/dist/quote-print-census.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/quote-print-census.js +254 -0
- package/payload/platform/services/claude-session-manager/dist/quote-print-census.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/specialist-census.d.ts +92 -0
- package/payload/platform/services/claude-session-manager/dist/specialist-census.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/specialist-census.js +227 -0
- package/payload/platform/services/claude-session-manager/dist/specialist-census.js.map +1 -0
- package/payload/platform/services/telegram-channel/dist/jsonl.d.ts +8 -0
- package/payload/platform/services/telegram-channel/dist/jsonl.d.ts.map +1 -0
- package/payload/platform/services/telegram-channel/dist/jsonl.js +42 -0
- package/payload/platform/services/telegram-channel/dist/jsonl.js.map +1 -0
- package/payload/platform/services/telegram-channel/dist/notification.d.ts +0 -31
- package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/telegram-channel/dist/notification.js +4 -33
- package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/telegram-channel/dist/server.d.ts +0 -5
- package/payload/platform/services/telegram-channel/dist/server.d.ts.map +1 -1
- package/payload/platform/services/telegram-channel/dist/server.js +7 -101
- package/payload/platform/services/telegram-channel/dist/server.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +0 -66
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js +2 -64
- package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/server.d.ts +0 -12
- package/payload/platform/services/whatsapp-channel/dist/server.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/server.js +15 -268
- package/payload/platform/services/whatsapp-channel/dist/server.js.map +1 -1
- package/payload/platform/templates/account-settings.json +8 -4
- package/payload/server/public/activity.html +6 -6
- package/payload/server/public/agents.html +5 -5
- package/payload/server/public/assets/{AdminLoginScreens-CMdj1W5p.js → AdminLoginScreens-Dp6k1XgD.js} +1 -1
- package/payload/server/public/assets/AdminLoginScreens-Dp6k1XgD.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-Dp6k1XgD.js.gz +0 -0
- package/payload/server/public/assets/{AdminShell-CZcaW3BQ.js → AdminShell-D-wB90c3.js} +1 -1
- package/payload/server/public/assets/AdminShell-D-wB90c3.js.br +0 -0
- package/payload/server/public/assets/AdminShell-D-wB90c3.js.gz +0 -0
- package/payload/server/public/assets/{activity-CAhibgb-.js → activity-BJxhblz-.js} +1 -1
- package/payload/server/public/assets/activity-BJxhblz-.js.br +0 -0
- package/payload/server/public/assets/activity-BJxhblz-.js.gz +0 -0
- package/payload/server/public/assets/{admin-xEXv3w9e.js → admin-DzEi8shs.js} +1 -1
- package/payload/server/public/assets/admin-DzEi8shs.js.br +0 -0
- package/payload/server/public/assets/admin-DzEi8shs.js.gz +0 -0
- package/payload/server/public/assets/{agents-CiAmzTaT.js → agents-DTL8kjfD.js} +1 -1
- package/payload/server/public/assets/agents-DTL8kjfD.js.br +0 -0
- package/payload/server/public/assets/agents-DTL8kjfD.js.gz +0 -0
- package/payload/server/public/assets/{browser-D36BiYhS.js → browser-UZp75zhx.js} +1 -1
- package/payload/server/public/assets/browser-UZp75zhx.js.br +0 -0
- package/payload/server/public/assets/browser-UZp75zhx.js.gz +0 -0
- package/payload/server/public/assets/{calendar-CJAM-iXn.js → calendar-Dfo0O2K_.js} +1 -1
- package/payload/server/public/assets/calendar-Dfo0O2K_.js.br +0 -0
- package/payload/server/public/assets/calendar-Dfo0O2K_.js.gz +0 -0
- package/payload/server/public/assets/chat-ByJAvEWZ.js +1 -0
- package/payload/server/public/assets/chat-ByJAvEWZ.js.br +0 -0
- package/payload/server/public/assets/chat-ByJAvEWZ.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-iG7sYNm7.js +1 -0
- package/payload/server/public/assets/chevron-left-iG7sYNm7.js.br +0 -0
- package/payload/server/public/assets/clock-xSs0UF10.js +1 -0
- package/payload/server/public/assets/clock-xSs0UF10.js.br +0 -0
- package/payload/server/public/assets/clock-xSs0UF10.js.gz +0 -0
- package/payload/server/public/assets/{copy-axBe92iY.js → copy-CGI2jioK.js} +1 -1
- package/payload/server/public/assets/copy-CGI2jioK.js.br +0 -0
- package/payload/server/public/assets/copy-CGI2jioK.js.gz +0 -0
- package/payload/server/public/assets/data-dvwK4BcP.js +1 -0
- package/payload/server/public/assets/data-dvwK4BcP.js.br +0 -0
- package/payload/server/public/assets/data-dvwK4BcP.js.gz +0 -0
- package/payload/server/public/assets/{dispatch-D_i2ko7K.js → dispatch-Dx9-ty1K.js} +1 -1
- package/payload/server/public/assets/dispatch-Dx9-ty1K.js.br +0 -0
- package/payload/server/public/assets/dispatch-Dx9-ty1K.js.gz +0 -0
- package/payload/server/public/assets/{field-DFgkqq1P.js → field-D-P6CsWA.js} +1 -1
- package/payload/server/public/assets/field-D-P6CsWA.js.br +0 -0
- package/payload/server/public/assets/field-D-P6CsWA.js.gz +0 -0
- package/payload/server/public/assets/{file-text-CEFoq0Je.js → file-text-RWintp9q.js} +1 -1
- package/payload/server/public/assets/file-text-RWintp9q.js.br +0 -0
- package/payload/server/public/assets/file-text-RWintp9q.js.gz +0 -0
- package/payload/server/public/assets/{graph-BrpbilNr.js → graph-CpBlfYrJ.js} +1 -1
- package/payload/server/public/assets/graph-CpBlfYrJ.js.br +0 -0
- package/payload/server/public/assets/graph-CpBlfYrJ.js.gz +0 -0
- package/payload/server/public/assets/{graph-labels-BtmcWzo7.js → graph-labels-BOMyPppX.js} +1 -1
- package/payload/server/public/assets/graph-labels-BOMyPppX.js.br +0 -0
- package/payload/server/public/assets/graph-labels-BOMyPppX.js.gz +0 -0
- package/payload/server/public/assets/jsx-runtime-DxsQ5Y-z.css +1 -0
- package/payload/server/public/assets/jsx-runtime-DxsQ5Y-z.css.br +0 -0
- package/payload/server/public/assets/jsx-runtime-DxsQ5Y-z.css.gz +0 -0
- package/payload/server/public/assets/{operator-Dl7dJt1G.js → operator-DFgW6GiH.js} +1 -1
- package/payload/server/public/assets/operator-DFgW6GiH.js.br +0 -0
- package/payload/server/public/assets/operator-DFgW6GiH.js.gz +0 -0
- package/payload/server/public/assets/{page-nx31Ij0T.js → page-BRShHSH0.js} +1 -1
- package/payload/server/public/assets/page-BRShHSH0.js.br +0 -0
- package/payload/server/public/assets/page-BRShHSH0.js.gz +0 -0
- package/payload/server/public/assets/{page-zC66xzNT.js → page-BbBCu9iP.js} +5 -5
- package/payload/server/public/assets/page-BbBCu9iP.js.br +0 -0
- package/payload/server/public/assets/page-BbBCu9iP.js.gz +0 -0
- package/payload/server/public/assets/play-BJxUaf6-.js +1 -0
- package/payload/server/public/assets/play-BJxUaf6-.js.br +0 -0
- package/payload/server/public/assets/play-BJxUaf6-.js.gz +0 -0
- package/payload/server/public/assets/{public-DEKnH5Q0.js → public-DkObqkzL.js} +1 -1
- package/payload/server/public/assets/public-DkObqkzL.js.br +0 -0
- package/payload/server/public/assets/public-DkObqkzL.js.gz +0 -0
- package/payload/server/public/assets/{rotate-ccw-CBex8gon.js → rotate-ccw-DgMO69nh.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-DgMO69nh.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-DgMO69nh.js.gz +0 -0
- package/payload/server/public/assets/routines-D9kvg_Xu.js +2 -0
- package/payload/server/public/assets/routines-D9kvg_Xu.js.br +0 -0
- package/payload/server/public/assets/routines-D9kvg_Xu.js.gz +0 -0
- package/payload/server/public/assets/{skills-BmxjPOmq.js → skills-l5I9HZ3D.js} +1 -1
- package/payload/server/public/assets/skills-l5I9HZ3D.js.br +0 -0
- package/payload/server/public/assets/skills-l5I9HZ3D.js.gz +0 -0
- package/payload/server/public/assets/{tasks-BTFYO9vT.js → tasks-C2qJMv6i.js} +1 -1
- package/payload/server/public/assets/tasks-C2qJMv6i.js.br +0 -0
- package/payload/server/public/assets/tasks-C2qJMv6i.js.gz +0 -0
- package/payload/server/public/assets/{triangle-alert-px1YRJJ7.js → triangle-alert-BnC67uSs.js} +1 -1
- package/payload/server/public/assets/triangle-alert-BnC67uSs.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-BnC67uSs.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-nMXwRcDX.js → useCopyFeedback-1RmgkTFh.js} +1 -1
- package/payload/server/public/assets/useCopyFeedback-1RmgkTFh.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-1RmgkTFh.js.gz +0 -0
- package/payload/server/public/assets/{useMediaQuery-DjbOTk2X.js → useMediaQuery-BQslddHQ.js} +1 -1
- package/payload/server/public/assets/useMediaQuery-BQslddHQ.js.br +0 -0
- package/payload/server/public/assets/useMediaQuery-BQslddHQ.js.gz +0 -0
- package/payload/server/public/assets/{useVoiceRecorder-Cx7AOmib.js → useVoiceRecorder-BeZNQEC4.js} +1 -1
- package/payload/server/public/assets/useVoiceRecorder-BeZNQEC4.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-BeZNQEC4.js.gz +0 -0
- package/payload/server/public/assets/{wrench-Cexvlx6J.js → wrench-D4ufQG6C.js} +1 -1
- package/payload/server/public/assets/wrench-D4ufQG6C.js.br +0 -0
- package/payload/server/public/assets/wrench-D4ufQG6C.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/dispatch.html +5 -5
- 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 +16 -16
- 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 +1088 -694
- package/payload/server/public/assets/AdminLoginScreens-CMdj1W5p.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-CMdj1W5p.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-CZcaW3BQ.js.br +0 -0
- package/payload/server/public/assets/AdminShell-CZcaW3BQ.js.gz +0 -0
- package/payload/server/public/assets/activity-CAhibgb-.js.br +0 -0
- package/payload/server/public/assets/activity-CAhibgb-.js.gz +0 -0
- package/payload/server/public/assets/admin-xEXv3w9e.js.br +0 -0
- package/payload/server/public/assets/admin-xEXv3w9e.js.gz +0 -0
- package/payload/server/public/assets/agents-CiAmzTaT.js.br +0 -0
- package/payload/server/public/assets/agents-CiAmzTaT.js.gz +0 -0
- package/payload/server/public/assets/browser-D36BiYhS.js.br +0 -0
- package/payload/server/public/assets/browser-D36BiYhS.js.gz +0 -0
- package/payload/server/public/assets/calendar-CJAM-iXn.js.br +0 -0
- package/payload/server/public/assets/calendar-CJAM-iXn.js.gz +0 -0
- package/payload/server/public/assets/chat-DhZSvtZK.js +0 -1
- package/payload/server/public/assets/chat-DhZSvtZK.js.br +0 -0
- package/payload/server/public/assets/chat-DhZSvtZK.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-CXEcNlc3.js +0 -1
- package/payload/server/public/assets/chevron-left-CXEcNlc3.js.br +0 -0
- package/payload/server/public/assets/clock-DdxIJwTr.js +0 -1
- package/payload/server/public/assets/clock-DdxIJwTr.js.br +0 -0
- package/payload/server/public/assets/clock-DdxIJwTr.js.gz +0 -0
- package/payload/server/public/assets/copy-axBe92iY.js.br +0 -0
- package/payload/server/public/assets/copy-axBe92iY.js.gz +0 -0
- package/payload/server/public/assets/data-DUvkI-zq.js +0 -1
- package/payload/server/public/assets/data-DUvkI-zq.js.br +0 -0
- package/payload/server/public/assets/data-DUvkI-zq.js.gz +0 -0
- package/payload/server/public/assets/dispatch-D_i2ko7K.js.br +0 -0
- package/payload/server/public/assets/dispatch-D_i2ko7K.js.gz +0 -0
- package/payload/server/public/assets/field-DFgkqq1P.js.br +0 -0
- package/payload/server/public/assets/field-DFgkqq1P.js.gz +0 -0
- package/payload/server/public/assets/file-text-CEFoq0Je.js.br +0 -0
- package/payload/server/public/assets/file-text-CEFoq0Je.js.gz +0 -0
- package/payload/server/public/assets/graph-BrpbilNr.js.br +0 -0
- package/payload/server/public/assets/graph-BrpbilNr.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-BtmcWzo7.js.br +0 -0
- package/payload/server/public/assets/graph-labels-BtmcWzo7.js.gz +0 -0
- package/payload/server/public/assets/jsx-runtime-XuYKjgVb.css +0 -1
- package/payload/server/public/assets/jsx-runtime-XuYKjgVb.css.br +0 -0
- package/payload/server/public/assets/jsx-runtime-XuYKjgVb.css.gz +0 -0
- package/payload/server/public/assets/operator-Dl7dJt1G.js.br +0 -3
- package/payload/server/public/assets/operator-Dl7dJt1G.js.gz +0 -0
- package/payload/server/public/assets/page-nx31Ij0T.js.br +0 -0
- package/payload/server/public/assets/page-nx31Ij0T.js.gz +0 -0
- package/payload/server/public/assets/page-zC66xzNT.js.br +0 -0
- package/payload/server/public/assets/page-zC66xzNT.js.gz +0 -0
- package/payload/server/public/assets/play-MbU8O2iC.js +0 -1
- package/payload/server/public/assets/play-MbU8O2iC.js.br +0 -0
- package/payload/server/public/assets/play-MbU8O2iC.js.gz +0 -0
- package/payload/server/public/assets/public-DEKnH5Q0.js.br +0 -0
- package/payload/server/public/assets/public-DEKnH5Q0.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-CBex8gon.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-CBex8gon.js.gz +0 -0
- package/payload/server/public/assets/routines-BqCmbvFJ.js +0 -2
- package/payload/server/public/assets/routines-BqCmbvFJ.js.br +0 -0
- package/payload/server/public/assets/routines-BqCmbvFJ.js.gz +0 -0
- package/payload/server/public/assets/skills-BmxjPOmq.js.br +0 -0
- package/payload/server/public/assets/skills-BmxjPOmq.js.gz +0 -0
- package/payload/server/public/assets/tasks-BTFYO9vT.js.br +0 -0
- package/payload/server/public/assets/tasks-BTFYO9vT.js.gz +0 -0
- package/payload/server/public/assets/triangle-alert-px1YRJJ7.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-px1YRJJ7.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-nMXwRcDX.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-nMXwRcDX.js.gz +0 -0
- package/payload/server/public/assets/useMediaQuery-DjbOTk2X.js.br +0 -0
- package/payload/server/public/assets/useMediaQuery-DjbOTk2X.js.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-Cx7AOmib.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-Cx7AOmib.js.gz +0 -0
- package/payload/server/public/assets/wrench-Cexvlx6J.js.br +0 -0
- package/payload/server/public/assets/wrench-Cexvlx6J.js.gz +0 -0
- /package/payload/server/public/assets/{jsx-runtime-C5Hcfj84.js → jsx-runtime-5lmxFBIw.js} +0 -0
- /package/payload/server/public/assets/{jsx-runtime-C5Hcfj84.js.br → jsx-runtime-5lmxFBIw.js.br} +0 -0
- /package/payload/server/public/assets/{jsx-runtime-C5Hcfj84.js.gz → jsx-runtime-5lmxFBIw.js.gz} +0 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { DraftLedgerEntry } from "./draft-ledger.js";
|
|
2
|
+
/**
|
|
3
|
+
* Classification for one ledger draft, and the pruning rule for the file.
|
|
4
|
+
*
|
|
5
|
+
* Pure and injectable: the Graph read happens in scripts/draft-reconcile.ts and
|
|
6
|
+
* arrives here as a `DraftState`, so every verdict is testable without a live
|
|
7
|
+
* mailbox (Task 2530).
|
|
8
|
+
*/
|
|
9
|
+
export type DraftVerdict = "still-draft" | "sent-by-maxy" | "sent-not-by-maxy" | "deleted" | "unreadable";
|
|
10
|
+
export type DraftState = {
|
|
11
|
+
kind: "read";
|
|
12
|
+
isDraft: boolean;
|
|
13
|
+
parentFolderId: string | null;
|
|
14
|
+
sentDateTime: string | null;
|
|
15
|
+
} | {
|
|
16
|
+
kind: "not-found";
|
|
17
|
+
} | {
|
|
18
|
+
kind: "error";
|
|
19
|
+
statusCode: number;
|
|
20
|
+
code: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Hard age cap. Terminal rows are pruned as soon as they are classified; this
|
|
24
|
+
* bounds the file even if a draft never reaches a terminal verdict.
|
|
25
|
+
*
|
|
26
|
+
* 90 days, not the email ledger's 48 hours (`sent-ledger.ts:28`). That file's
|
|
27
|
+
* window is a 24h sweep, so 48h leaves margin. A draft awaiting the operator's
|
|
28
|
+
* review legitimately sits for days, and a short prune would drop exactly the
|
|
29
|
+
* rows that carry the point.
|
|
30
|
+
*/
|
|
31
|
+
export declare const RETENTION_CAP_MS: number;
|
|
32
|
+
/**
|
|
33
|
+
* The ids this plugin actually sent.
|
|
34
|
+
*
|
|
35
|
+
* An empty id is excluded. mail-send's `sendMail` route has no draft id when
|
|
36
|
+
* Graph returns none and writes "", and a created row's id is never "" — but
|
|
37
|
+
* letting "" into the set would make a naive membership test match nothing
|
|
38
|
+
* useful while looking like it worked.
|
|
39
|
+
*/
|
|
40
|
+
export declare function sentDraftIds(rows: DraftLedgerEntry[]): Set<string>;
|
|
41
|
+
/**
|
|
42
|
+
* Created rows with no matching sent row.
|
|
43
|
+
*
|
|
44
|
+
* A sent row with no created row is normal, not an error: mail-send's
|
|
45
|
+
* attachment route and mail-reply both mint their own draft and send it in one
|
|
46
|
+
* call, so they never write a `created` row.
|
|
47
|
+
*/
|
|
48
|
+
export declare function openDrafts(rows: DraftLedgerEntry[]): DraftLedgerEntry[];
|
|
49
|
+
/**
|
|
50
|
+
* `parentFolderId` is the discriminator, not `isDraft`.
|
|
51
|
+
*
|
|
52
|
+
* Two states both mean the draft is no longer an open draft in that folder, and
|
|
53
|
+
* only one of them sets `isDraft: false`. On 2026-08-07 the Ecolec Drafts
|
|
54
|
+
* listing returned zero items while the same draft id still fetched and still
|
|
55
|
+
* returned `from: null` eleven seconds later — a draft object outside the
|
|
56
|
+
* Drafts folder. Keying on `isDraft` alone calls that healthy.
|
|
57
|
+
*
|
|
58
|
+
* A null `draftsFolderId` is `unreadable`, never a verdict: with nothing to
|
|
59
|
+
* compare against, reporting a healthy draft as sent by someone else is the one
|
|
60
|
+
* mistake this check must not make.
|
|
61
|
+
*/
|
|
62
|
+
export declare function classifyDraft(state: DraftState, draftsFolderId: string | null): DraftVerdict;
|
|
63
|
+
/**
|
|
64
|
+
* A verdict that will not change, so its rows can be dropped.
|
|
65
|
+
*
|
|
66
|
+
* `unreadable` is deliberately not terminal — a transient 503 must not retire a
|
|
67
|
+
* draft — and neither is `still-draft`, which is the state the reconcile exists
|
|
68
|
+
* to keep watching.
|
|
69
|
+
*/
|
|
70
|
+
export declare function isTerminal(verdict: DraftVerdict): boolean;
|
|
71
|
+
/** One Sent Items row, as much of it as the match needs. */
|
|
72
|
+
export interface SentItemsRow {
|
|
73
|
+
id?: unknown;
|
|
74
|
+
subject?: unknown;
|
|
75
|
+
conversationId?: unknown;
|
|
76
|
+
toRecipients?: Array<{
|
|
77
|
+
emailAddress?: {
|
|
78
|
+
address?: string;
|
|
79
|
+
};
|
|
80
|
+
}>;
|
|
81
|
+
sentDateTime?: unknown;
|
|
82
|
+
}
|
|
83
|
+
export interface SentCopy {
|
|
84
|
+
id: string;
|
|
85
|
+
to: string;
|
|
86
|
+
at: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Find the copy that actually went out, among a page of Sent Items.
|
|
90
|
+
*
|
|
91
|
+
* Matched by conversationId when the draft carries one, else by subject. The
|
|
92
|
+
* 2026-08-07 Leaders draft was standalone with `conversationId: null`, so a
|
|
93
|
+
* conversationId-only match would have found nothing and the operator would
|
|
94
|
+
* still not know who received it.
|
|
95
|
+
*
|
|
96
|
+
* A row with neither key matches nothing rather than matching the newest item:
|
|
97
|
+
* naming the wrong recipient is worse than naming none.
|
|
98
|
+
*/
|
|
99
|
+
export declare function matchSentCopy(rows: SentItemsRow[], draft: DraftLedgerEntry): SentCopy | null;
|
|
100
|
+
/** Graph's message projection, narrowed to the three fields a verdict needs. */
|
|
101
|
+
export declare function mapDraftState(json: {
|
|
102
|
+
isDraft?: boolean;
|
|
103
|
+
parentFolderId?: string | null;
|
|
104
|
+
sentDateTime?: string | null;
|
|
105
|
+
} | null): DraftState;
|
|
106
|
+
/**
|
|
107
|
+
* The prune key: account AND draft, never the draft id alone.
|
|
108
|
+
*
|
|
109
|
+
* Graph ids are long enough that a collision across two accounts is unlikely,
|
|
110
|
+
* but account scope is a property that has to hold exactly — a shared key would
|
|
111
|
+
* let one account's terminal verdict delete another account's open row.
|
|
112
|
+
*/
|
|
113
|
+
export declare function ledgerKey(accountId: string, draftId: string): string;
|
|
114
|
+
/**
|
|
115
|
+
* Drop every row for a draft that reached a terminal verdict, and every row past
|
|
116
|
+
* the hard cap. Called once per run from the reconcile's single process.
|
|
117
|
+
*/
|
|
118
|
+
export declare function pruneRows(rows: DraftLedgerEntry[], terminalKeys: Set<string>, nowMs: number): DraftLedgerEntry[];
|
|
119
|
+
//# sourceMappingURL=draft-reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft-reconcile.d.ts","sourceRoot":"","sources":["../../src/lib/draft-reconcile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GACpB,aAAa,GACb,cAAc,GACd,kBAAkB,GAClB,SAAS,GACT,YAAY,CAAC;AAEjB,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC9F;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,QAA2B,CAAC;AAEzD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAIlE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAGvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,YAAY,CAM5F;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAEzD;AAED,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,YAAY,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;IAC9D,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,gBAAgB,GAAG,QAAQ,GAAG,IAAI,CAgB5F;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,IAAI,GAAG,UAAU,CAOpB;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,gBAAgB,EAAE,EACxB,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,EACzB,KAAK,EAAE,MAAM,GACZ,gBAAgB,EAAE,CASpB"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft-reconcile.js","sourceRoot":"","sources":["../../src/lib/draft-reconcile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface VendorApp {
|
|
2
|
+
clientId: string;
|
|
3
|
+
tenantId: string;
|
|
4
|
+
}
|
|
5
|
+
/** The brand's Outlook app, read from disk because the heartbeat's env has none. */
|
|
6
|
+
export declare function readVendorApp(platformRoot: string): VendorApp | null;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=draft-reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft-reconcile.d.ts","sourceRoot":"","sources":["../../src/scripts/draft-reconcile.ts"],"names":[],"mappings":"AA+CA,UAAU,SAAS;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAcpE"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standing reconciliation of every draft this plugin created, one pass over
|
|
3
|
+
* every local account.
|
|
4
|
+
*
|
|
5
|
+
* Spawned by the scheduling heartbeat on an hourly throttle rather than
|
|
6
|
+
* imported by it: the scheduling plugin builds with its own rootDir and does
|
|
7
|
+
* not carry the Graph client, so the Graph work stays on this side of the
|
|
8
|
+
* boundary — the rule Task 1822 set for the email sent-copy sweep.
|
|
9
|
+
*
|
|
10
|
+
* It has to be a standing check rather than another action log. The failure it
|
|
11
|
+
* exists for emits no event: nobody calls a tool when an external mail client
|
|
12
|
+
* sends a draft, so there is nothing to hang a log line on, and re-running the
|
|
13
|
+
* code will not surface it. On 2026-08-07 a Maxy-created draft left the Drafts
|
|
14
|
+
* folder at 12:26:47Z and the platform recorded nothing at all.
|
|
15
|
+
*
|
|
16
|
+
* The heartbeat's cron line carries only PLATFORM_ROOT, NEO4J_URI and
|
|
17
|
+
* MAXY_UI_INTERNAL_PORT — no OUTLOOK_CLIENT_ID — so the vendor app is read from
|
|
18
|
+
* platform/config/brand.json here, the same source and the same reason as
|
|
19
|
+
* scheduling's connector-freebusy.ts:83.
|
|
20
|
+
*
|
|
21
|
+
* Exit code is 0 whenever the reconcile ran, including when it found a
|
|
22
|
+
* sent-not-by-maxy: a finding is a result, not a failure of the check. Non-zero
|
|
23
|
+
* means it could not run, which is what keeps "failing" and "did not run"
|
|
24
|
+
* distinguishable.
|
|
25
|
+
*/
|
|
26
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
27
|
+
import { resolve } from "node:path";
|
|
28
|
+
import { enumerateValidAccountIds } from "../../../../../lib/account-enumeration/dist/index.js";
|
|
29
|
+
import { MailboxRegistry } from "../auth/mailbox-registry.js";
|
|
30
|
+
import { callGraph, classifyGraphError } from "../lib/graph-client.js";
|
|
31
|
+
import { log } from "../lib/log.js";
|
|
32
|
+
import { readDraftLedger, writeDraftLedger } from "../lib/draft-ledger.js";
|
|
33
|
+
import { openDrafts, sentDraftIds, classifyDraft, pruneRows, isTerminal, ledgerKey, mapDraftState, matchSentCopy, } from "../lib/draft-reconcile.js";
|
|
34
|
+
/** The brand's Outlook app, read from disk because the heartbeat's env has none. */
|
|
35
|
+
export function readVendorApp(platformRoot) {
|
|
36
|
+
const path = resolve(platformRoot, "config", "brand.json");
|
|
37
|
+
try {
|
|
38
|
+
const brand = JSON.parse(readFileSync(path, "utf-8"));
|
|
39
|
+
const clientId = typeof brand.outlookClientId === "string" ? brand.outlookClientId : "";
|
|
40
|
+
if (!clientId)
|
|
41
|
+
return null;
|
|
42
|
+
const tenantId = typeof brand.outlookTenantId === "string" && brand.outlookTenantId
|
|
43
|
+
? brand.outlookTenantId
|
|
44
|
+
: "common";
|
|
45
|
+
return { clientId, tenantId };
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The Drafts folder's opaque id.
|
|
53
|
+
*
|
|
54
|
+
* `parentFolderId` on a message is an opaque id, never the well-known `drafts`
|
|
55
|
+
* token, so it can only be compared against a resolved one. Null on failure,
|
|
56
|
+
* which classifyDraft turns into `unreadable` rather than a verdict.
|
|
57
|
+
*/
|
|
58
|
+
async function resolveDraftsFolderId(config) {
|
|
59
|
+
try {
|
|
60
|
+
const json = await callGraph(config, (client) => client.api("/me/mailFolders/drafts").select("id").get(), { tool: "draft-reconcile" });
|
|
61
|
+
return json?.id ?? null;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async function readDraftState(config, draftId) {
|
|
68
|
+
try {
|
|
69
|
+
const json = await callGraph(config, (client) => client
|
|
70
|
+
.api(`/me/messages/${encodeURIComponent(draftId)}`)
|
|
71
|
+
.select("isDraft,parentFolderId,sentDateTime,lastModifiedDateTime")
|
|
72
|
+
.get(), { tool: "draft-reconcile", target: draftId });
|
|
73
|
+
return mapDraftState(json);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
const cls = classifyGraphError(err);
|
|
77
|
+
if (cls.statusCode === 404)
|
|
78
|
+
return { kind: "not-found" };
|
|
79
|
+
// Two of the rate-limit classes carry no `code` field at all, so it is read
|
|
80
|
+
// off the union rather than assumed present.
|
|
81
|
+
const code = "code" in cls ? cls.code : cls.kind;
|
|
82
|
+
return { kind: "error", statusCode: cls.statusCode, code };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The newest Sent Items, fetched at most once per mailbox per run.
|
|
87
|
+
*
|
|
88
|
+
* Several drafts in one mailbox can come back sent-not-by-maxy together, and
|
|
89
|
+
* they all match against the same page — refetching it per draft would be N
|
|
90
|
+
* identical Graph calls. A failed fetch caches the empty page too, so one
|
|
91
|
+
* outage does not become N retries inside a single run.
|
|
92
|
+
*/
|
|
93
|
+
async function sentItemsPage(config) {
|
|
94
|
+
try {
|
|
95
|
+
const page = await callGraph(config, (client) => client
|
|
96
|
+
.api("/me/mailFolders/sentitems/messages")
|
|
97
|
+
.select("id,subject,conversationId,toRecipients,sentDateTime")
|
|
98
|
+
.top(25)
|
|
99
|
+
.orderby("sentDateTime desc")
|
|
100
|
+
.get(), { tool: "draft-reconcile" });
|
|
101
|
+
return page?.value ?? [];
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function emptyCounts() {
|
|
108
|
+
return {
|
|
109
|
+
"still-draft": 0,
|
|
110
|
+
"sent-by-maxy": 0,
|
|
111
|
+
"sent-not-by-maxy": 0,
|
|
112
|
+
deleted: 0,
|
|
113
|
+
unreadable: 0,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
async function reconcileAccount(accountId, accountsDir, vendor, rows, nowMs, terminal) {
|
|
117
|
+
const mine = rows.filter((r) => r.accountId === accountId);
|
|
118
|
+
if (mine.length === 0)
|
|
119
|
+
return;
|
|
120
|
+
const counts = emptyCounts();
|
|
121
|
+
const alreadySent = sentDraftIds(mine);
|
|
122
|
+
// A created row whose id also carries a sent row is answered by the ledger
|
|
123
|
+
// alone. No Graph call: the ledger already knows, and asking would spend a
|
|
124
|
+
// request to learn nothing.
|
|
125
|
+
for (const r of mine) {
|
|
126
|
+
if (r.event === "created" && alreadySent.has(r.draftId)) {
|
|
127
|
+
counts["sent-by-maxy"]++;
|
|
128
|
+
terminal.add(ledgerKey(accountId, r.draftId));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const registry = new MailboxRegistry(accountId, accountsDir);
|
|
132
|
+
const byMailbox = new Map();
|
|
133
|
+
for (const r of openDrafts(mine)) {
|
|
134
|
+
const list = byMailbox.get(r.mailbox) ?? [];
|
|
135
|
+
list.push(r);
|
|
136
|
+
byMailbox.set(r.mailbox, list);
|
|
137
|
+
}
|
|
138
|
+
for (const [mailbox, drafts] of byMailbox) {
|
|
139
|
+
const resolved = registry.resolve(mailbox || undefined);
|
|
140
|
+
if (resolved.kind !== "ok") {
|
|
141
|
+
// Not terminal: a mailbox that is momentarily unresolvable must not
|
|
142
|
+
// retire a draft that is still sitting there.
|
|
143
|
+
for (const r of drafts) {
|
|
144
|
+
counts.unreadable++;
|
|
145
|
+
log({
|
|
146
|
+
event: "draft-reconcile",
|
|
147
|
+
account: accountId,
|
|
148
|
+
mailbox,
|
|
149
|
+
draftId: r.draftId,
|
|
150
|
+
outcome: "unreadable",
|
|
151
|
+
createdTs: r.at,
|
|
152
|
+
reason: `mailbox-${resolved.kind}`,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const config = {
|
|
158
|
+
clientId: vendor.clientId,
|
|
159
|
+
tenantId: vendor.tenantId,
|
|
160
|
+
accountId,
|
|
161
|
+
tokenStore: resolved.store,
|
|
162
|
+
mailboxPathPrefix: resolved.pathPrefix,
|
|
163
|
+
mailboxAddress: resolved.delegatedAddress ?? resolved.descriptor.mail ?? null,
|
|
164
|
+
};
|
|
165
|
+
const draftsFolderId = await resolveDraftsFolderId(config);
|
|
166
|
+
let sentPage = null;
|
|
167
|
+
for (const r of drafts) {
|
|
168
|
+
const state = await readDraftState(config, r.draftId);
|
|
169
|
+
const outcome = classifyDraft(state, draftsFolderId);
|
|
170
|
+
counts[outcome]++;
|
|
171
|
+
if (isTerminal(outcome))
|
|
172
|
+
terminal.add(ledgerKey(accountId, r.draftId));
|
|
173
|
+
const createdMs = Date.parse(r.at);
|
|
174
|
+
const fields = {
|
|
175
|
+
event: "draft-reconcile",
|
|
176
|
+
account: accountId,
|
|
177
|
+
mailbox,
|
|
178
|
+
draftId: r.draftId,
|
|
179
|
+
outcome,
|
|
180
|
+
createdTs: r.at,
|
|
181
|
+
sentDateTime: state.kind === "read" ? state.sentDateTime : null,
|
|
182
|
+
parentFolderId: state.kind === "read" ? state.parentFolderId : null,
|
|
183
|
+
ageMs: Number.isFinite(createdMs) ? nowMs - createdMs : null,
|
|
184
|
+
};
|
|
185
|
+
if (state.kind === "error") {
|
|
186
|
+
fields.status = state.statusCode;
|
|
187
|
+
fields.code = state.code;
|
|
188
|
+
}
|
|
189
|
+
if (outcome === "sent-not-by-maxy") {
|
|
190
|
+
if (sentPage === null)
|
|
191
|
+
sentPage = await sentItemsPage(config);
|
|
192
|
+
const copy = matchSentCopy(sentPage, r);
|
|
193
|
+
fields.sentCopyId = copy?.id ?? "none";
|
|
194
|
+
fields.sentCopyTo = copy?.to ?? "none";
|
|
195
|
+
fields.sentCopyAt = copy?.at ?? "none";
|
|
196
|
+
}
|
|
197
|
+
log(fields);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Emitted on every pass including an all-zero one: an absent census line is
|
|
201
|
+
// the signal that the reconcile stopped running, and that only works if a
|
|
202
|
+
// quiet pass still speaks.
|
|
203
|
+
log({
|
|
204
|
+
event: "draft-reconcile-census",
|
|
205
|
+
account: accountId,
|
|
206
|
+
total: mine.filter((r) => r.event === "created").length,
|
|
207
|
+
stillDraft: counts["still-draft"],
|
|
208
|
+
sentByMaxy: counts["sent-by-maxy"],
|
|
209
|
+
sentNotByMaxy: counts["sent-not-by-maxy"],
|
|
210
|
+
deleted: counts.deleted,
|
|
211
|
+
unreadable: counts.unreadable,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
async function main() {
|
|
215
|
+
const platformRoot = process.env.PLATFORM_ROOT;
|
|
216
|
+
if (!platformRoot)
|
|
217
|
+
throw new Error("PLATFORM_ROOT is not set");
|
|
218
|
+
const vendor = readVendorApp(platformRoot);
|
|
219
|
+
if (!vendor) {
|
|
220
|
+
// A brand that ships no Outlook vendor app has nothing to reconcile. A
|
|
221
|
+
// distinct outcome from "did not run", and it has to say so.
|
|
222
|
+
log({ event: "draft-reconcile-skipped", reason: "no-vendor-app" });
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const accountsDir = resolve(platformRoot, "..", "data/accounts");
|
|
226
|
+
const accountIds = existsSync(accountsDir) ? enumerateValidAccountIds(accountsDir) : [];
|
|
227
|
+
const rows = readDraftLedger();
|
|
228
|
+
const terminal = new Set();
|
|
229
|
+
const nowMs = Date.now();
|
|
230
|
+
for (const accountId of accountIds) {
|
|
231
|
+
await reconcileAccount(accountId, accountsDir, vendor, rows, nowMs, terminal);
|
|
232
|
+
}
|
|
233
|
+
const kept = pruneRows(rows, terminal, nowMs);
|
|
234
|
+
if (kept.length !== rows.length)
|
|
235
|
+
writeDraftLedger(kept);
|
|
236
|
+
log({
|
|
237
|
+
event: "draft-reconcile-pruned",
|
|
238
|
+
accounts: accountIds.length,
|
|
239
|
+
removed: rows.length - kept.length,
|
|
240
|
+
kept: kept.length,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
main().catch((err) => {
|
|
244
|
+
log({ event: "draft-reconcile-failed", error: err.message });
|
|
245
|
+
process.exit(1);
|
|
246
|
+
});
|
|
247
|
+
//# sourceMappingURL=draft-reconcile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft-reconcile.js","sourceRoot":"","sources":["../../src/scripts/draft-reconcile.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"draft-send.d.ts","sourceRoot":"","sources":["../../src/tools/draft-send.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"draft-send.d.ts","sourceRoot":"","sources":["../../src/tools/draft-send.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAKhE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,eAAe,CAAC,CA6B1B"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { postGraph } from "../lib/graph-client.js";
|
|
2
2
|
import { log } from "../lib/log.js";
|
|
3
|
+
import { appendDraftLedger } from "../lib/draft-ledger.js";
|
|
3
4
|
/**
|
|
4
5
|
* Send an existing draft via Graph `POST /me/messages/{id}/send` (empty body).
|
|
5
6
|
* Graph consumes the draft and returns 202. Success is asserted on the 202
|
|
@@ -16,6 +17,15 @@ export async function runDraftSend(config, args) {
|
|
|
16
17
|
try {
|
|
17
18
|
const { status } = await postGraph(config, `/me/messages/${encodeURIComponent(draftId)}/send`, undefined, { tool: "draft-send" });
|
|
18
19
|
log({ event: "draft-sent", account, id: draftId, status });
|
|
20
|
+
appendDraftLedger({
|
|
21
|
+
at: new Date().toISOString(),
|
|
22
|
+
accountId: account,
|
|
23
|
+
mailbox: config.mailboxAddress ?? "",
|
|
24
|
+
draftId,
|
|
25
|
+
event: "sent",
|
|
26
|
+
tool: "draft-send",
|
|
27
|
+
route: "draft-send",
|
|
28
|
+
});
|
|
19
29
|
return { status: "sent", draftId, httpStatus: status };
|
|
20
30
|
}
|
|
21
31
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"draft-send.js","sourceRoot":"","sources":["../../src/tools/draft-send.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"draft-send.js","sourceRoot":"","sources":["../../src/tools/draft-send.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAY3D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAyB,EACzB,IAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC;IACjC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IACD,GAAG,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAChC,MAAM,EACN,gBAAgB,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAClD,SAAS,EACT,EAAE,IAAI,EAAE,YAAY,EAAE,CACvB,CAAC;QACF,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3D,iBAAiB,CAAC;YAChB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,SAAS,EAAE,OAAO;YAClB,OAAO,EAAE,MAAM,CAAC,cAAc,IAAI,EAAE;YACpC,OAAO;YACP,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,YAAY;SACpB,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IACzD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACzF,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"draft.d.ts","sourceRoot":"","sources":["../../src/tools/draft.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"draft.d.ts","sourceRoot":"","sources":["../../src/tools/draft.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAMpE;;;;;;GAMG;AACH,MAAM,WAAW,UAAW,SAAQ,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,SAAS,CAAC;IACtE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;qFACiF;IACjF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB;;;yDAGqD;IACrD,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;;4DAKwD;IACxD,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAmDjG"}
|
|
@@ -2,6 +2,7 @@ import { postGraph } from "../lib/graph-client.js";
|
|
|
2
2
|
import { buildMessage } from "../lib/message.js";
|
|
3
3
|
import { attachFilesToDraft, resolveAttachmentsOrRefuse } from "../lib/attach.js";
|
|
4
4
|
import { log } from "../lib/log.js";
|
|
5
|
+
import { appendDraftLedger } from "../lib/draft-ledger.js";
|
|
5
6
|
import { addrs, applyCcBccToDraft } from "../lib/recipients.js";
|
|
6
7
|
/**
|
|
7
8
|
* Create a draft via Graph, attach any files to it, and return an id naming a
|
|
@@ -54,6 +55,26 @@ export async function runDraft(config, input) {
|
|
|
54
55
|
const { draftId, conversationId, to } = threaded
|
|
55
56
|
? await createThreadedDraft(config, input)
|
|
56
57
|
: await createStandaloneDraft(config, input);
|
|
58
|
+
// Written the moment the draft exists, BEFORE the attach. An attach that
|
|
59
|
+
// fails Graph-side rethrows but leaves the draft in Drafts (see the orphan
|
|
60
|
+
// note above), and a row written after the attach would miss exactly that
|
|
61
|
+
// draft — the reconcile would never watch the one case that already goes
|
|
62
|
+
// wrong (Task 2530).
|
|
63
|
+
//
|
|
64
|
+
// `subject` is undefined on the threaded path — Graph sets it there — and
|
|
65
|
+
// that is correct: a threaded draft carries a conversationId, which is the
|
|
66
|
+
// stronger Sent Items match key. A standalone draft has no conversationId
|
|
67
|
+
// and always has a subject.
|
|
68
|
+
appendDraftLedger({
|
|
69
|
+
at: new Date().toISOString(),
|
|
70
|
+
accountId: account,
|
|
71
|
+
mailbox: config.mailboxAddress ?? "",
|
|
72
|
+
draftId,
|
|
73
|
+
event: "created",
|
|
74
|
+
tool: "draft",
|
|
75
|
+
subject: input.subject,
|
|
76
|
+
conversationId,
|
|
77
|
+
});
|
|
57
78
|
await attachFilesToDraft(config, draftId, files, "draft");
|
|
58
79
|
log({
|
|
59
80
|
event: "draft-created",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"draft.js","sourceRoot":"","sources":["../../src/tools/draft.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"draft.js","sourceRoot":"","sources":["../../src/tools/draft.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,22 @@ export interface FetchBodyResult {
|
|
|
10
10
|
conversationId: string | null;
|
|
11
11
|
isRead: boolean;
|
|
12
12
|
hasAttachments: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Graph's own view of whether this is still an unsent draft, and which folder
|
|
15
|
+
* it is actually in. Both are needed to answer "is my draft still a draft":
|
|
16
|
+
* an item can be `isDraft: true` and no longer sit in the Drafts folder, and a
|
|
17
|
+
* fetch by id still succeeds in that state — on 2026-08-07 the Ecolec Drafts
|
|
18
|
+
* listing returned zero items while this same call returned `from: null`
|
|
19
|
+
* eleven seconds later (Task 2530). `parentFolderId` is the discriminator;
|
|
20
|
+
* `isDraft` alone calls that healthy.
|
|
21
|
+
*
|
|
22
|
+
* `sentDateTime` is `0001-01-01T00:00:00Z` on anything never sent, and null
|
|
23
|
+
* only when Graph omitted the field.
|
|
24
|
+
*/
|
|
25
|
+
isDraft: boolean;
|
|
26
|
+
parentFolderId: string | null;
|
|
27
|
+
sentDateTime: string | null;
|
|
28
|
+
lastModifiedDateTime: string | null;
|
|
13
29
|
contentType: "html" | "text";
|
|
14
30
|
body: string;
|
|
15
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mail-fetch-body.d.ts","sourceRoot":"","sources":["../../src/tools/mail-fetch-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAMhE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;
|
|
1
|
+
{"version":3,"file":"mail-fetch-body.d.ts","sourceRoot":"","sources":["../../src/tools/mail-fetch-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAMhE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;IACxB;;;;;;;;;;;OAWG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAsBD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,IAAI,GACnE;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAKlD;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAC1B,OAAO,CAAC,eAAe,CAAC,CAyC1B"}
|
|
@@ -2,7 +2,7 @@ import { callGraph } from "../lib/graph-client.js";
|
|
|
2
2
|
import { htmlToText } from "../lib/html-to-text.js";
|
|
3
3
|
import { log } from "../lib/log.js";
|
|
4
4
|
import { addrs } from "../lib/recipients.js";
|
|
5
|
-
const SELECT = "id,subject,from,toRecipients,ccRecipients,receivedDateTime,conversationId,isRead,hasAttachments,body";
|
|
5
|
+
const SELECT = "id,subject,from,toRecipients,ccRecipients,receivedDateTime,conversationId,isRead,hasAttachments,isDraft,parentFolderId,sentDateTime,lastModifiedDateTime,body";
|
|
6
6
|
/**
|
|
7
7
|
* Map Graph's `from.emailAddress` to the archive's { from, fromName } pair.
|
|
8
8
|
* Exported so the mapping is unit-testable without a live Graph call.
|
|
@@ -46,6 +46,10 @@ export async function runMailFetchBody(config, args) {
|
|
|
46
46
|
conversationId: msg.conversationId ?? null,
|
|
47
47
|
isRead: msg.isRead ?? false,
|
|
48
48
|
hasAttachments: msg.hasAttachments ?? false,
|
|
49
|
+
isDraft: msg.isDraft ?? false,
|
|
50
|
+
parentFolderId: msg.parentFolderId ?? null,
|
|
51
|
+
sentDateTime: msg.sentDateTime ?? null,
|
|
52
|
+
lastModifiedDateTime: msg.lastModifiedDateTime ?? null,
|
|
49
53
|
contentType,
|
|
50
54
|
body,
|
|
51
55
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mail-fetch-body.js","sourceRoot":"","sources":["../../src/tools/mail-fetch-body.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,KAAK,EAAqB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"mail-fetch-body.js","sourceRoot":"","sources":["../../src/tools/mail-fetch-body.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,KAAK,EAAqB,MAAM,sBAAsB,CAAC;AAkDhE,MAAM,MAAM,GACV,+JAA+J,CAAC;AAElK;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,IAAoE;IAEpE,OAAO;QACL,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,IAAI,IAAI;QACzC,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,IAAI,IAAI;KAC3C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAyB,EACzB,IAA2B;IAE3B,MAAM,IAAI,GAAG,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;IAClE,MAAM,GAAG,GAAG,MAAM,SAAS,CACzB,MAAM,EACN,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAe,EAC7E,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,CAC1C,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IAChE,MAAM,WAAW,GAAoB,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAC1E,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAE5D,GAAG,CAAC;QACF,KAAK,EAAE,iBAAiB;QACxB,EAAE,EAAE,YAAY;QAChB,OAAO,EAAE,MAAM,CAAC,SAAS;QACzB,EAAE,EAAE,IAAI,CAAC,SAAS;QAClB,KAAK,EAAE,IAAI,CAAC,MAAM;QAClB,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,IAAI;QAC5B,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,QAAQ,EAAE,UAAU,CAAC,QAAQ;QAC7B,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC;QAC3B,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC;QAC3B,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;QACtC,cAAc,EAAE,GAAG,CAAC,cAAc,IAAI,IAAI;QAC1C,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,KAAK;QAC3B,cAAc,EAAE,GAAG,CAAC,cAAc,IAAI,KAAK;QAC3C,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,KAAK;QAC7B,cAAc,EAAE,GAAG,CAAC,cAAc,IAAI,IAAI;QAC1C,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,IAAI;QACtC,oBAAoB,EAAE,GAAG,CAAC,oBAAoB,IAAI,IAAI;QACtD,WAAW;QACX,IAAI;KACL,CAAC;AACJ,CAAC"}
|
|
@@ -41,6 +41,10 @@ export interface MailListItem {
|
|
|
41
41
|
* outlook-mail-attachment to list/download them. Inline-only images can read
|
|
42
42
|
* false, matching Graph. */
|
|
43
43
|
hasAttachments: boolean;
|
|
44
|
+
/** Graph `isDraft`. Carried on every folder's listing, not just Drafts, so a
|
|
45
|
+
* caller comparing a Drafts listing against a message it fetched by id is
|
|
46
|
+
* reading the same field on both sides (Task 2530). */
|
|
47
|
+
isDraft: boolean;
|
|
44
48
|
}
|
|
45
49
|
export interface MailListResult {
|
|
46
50
|
items: MailListItem[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mail-list.d.ts","sourceRoot":"","sources":["../../src/tools/mail-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IAMb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAUjF;AAsBD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB;;iCAE6B;IAC7B,cAAc,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"mail-list.d.ts","sourceRoot":"","sources":["../../src/tools/mail-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IAMb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAUjF;AAsBD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB;;iCAE6B;IAC7B,cAAc,EAAE,OAAO,CAAC;IACxB;;4DAEwD;IACxD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,kFAAkF;IAClF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AA8BD,wBAAsB,WAAW,CAC/B,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,cAAc,CAAC,CA+DzB"}
|
|
@@ -43,7 +43,7 @@ const WELL_KNOWN_ALIASES = {
|
|
|
43
43
|
archive: "archive",
|
|
44
44
|
outbox: "outbox",
|
|
45
45
|
};
|
|
46
|
-
const FIELDS = "id,subject,from,receivedDateTime,bodyPreview,isRead,hasAttachments";
|
|
46
|
+
const FIELDS = "id,subject,from,receivedDateTime,bodyPreview,isRead,hasAttachments,isDraft";
|
|
47
47
|
function toGraphDate(input, field) {
|
|
48
48
|
const d = new Date(input);
|
|
49
49
|
if (!Number.isFinite(d.getTime())) {
|
|
@@ -128,6 +128,7 @@ function shapeMessage(msg) {
|
|
|
128
128
|
bodyPreview: (msg.bodyPreview ?? "").slice(0, 1024),
|
|
129
129
|
isRead: msg.isRead ?? false,
|
|
130
130
|
hasAttachments: msg.hasAttachments ?? false,
|
|
131
|
+
isDraft: msg.isDraft ?? false,
|
|
131
132
|
};
|
|
132
133
|
}
|
|
133
134
|
function clampTop(input, fallback) {
|