@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,254 @@
|
|
|
1
|
+
// Task 2446 — standing census over printed client documents.
|
|
2
|
+
//
|
|
3
|
+
// The PostToolUse conformance gate fires on a print. Four of the six ways a
|
|
4
|
+
// client document goes out with broken page chrome never reach a print in this
|
|
5
|
+
// session, so they emit nothing and do not reproduce on demand: the gate passing
|
|
6
|
+
// a defective PDF, the gate never matching the path at all (account settings are
|
|
7
|
+
// written at provision time and never reconciled), a template drifting back to a
|
|
8
|
+
// full-resolution asset, and a stale document never re-rendered. A periodic audit
|
|
9
|
+
// is the only signal for those four.
|
|
10
|
+
//
|
|
11
|
+
// It does NOT re-implement either conformance rule. It invokes the hook itself
|
|
12
|
+
// once per PDF with the log-directory environment stripped, so the hook resolves
|
|
13
|
+
// no log directory, appends to no file, and returns its verdict lines on stderr.
|
|
14
|
+
// One implementation of the rules, no drift between gate and audit.
|
|
15
|
+
//
|
|
16
|
+
// Shape mirrors the sibling standing audits (rootless-client-audit.ts): pure
|
|
17
|
+
// formatter, impure collector, and a start/stop factory whose setInterval is
|
|
18
|
+
// unref'd so it never holds the process open.
|
|
19
|
+
import { execFile } from 'node:child_process';
|
|
20
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
21
|
+
import { join } from 'node:path';
|
|
22
|
+
import { promisify } from 'node:util';
|
|
23
|
+
const execFileAsync = promisify(execFile);
|
|
24
|
+
export const TAG = '[quote-print-census]';
|
|
25
|
+
/** A4 is 594.96pt and the gate's limit is a third of it, 198.32pt. A page-margin
|
|
26
|
+
* box image is painted at 96 px/in, so its rendered width in points is
|
|
27
|
+
* px * 72/96. The largest intrinsic width that still fits is therefore 264px.
|
|
28
|
+
*
|
|
29
|
+
* A4 is assumed here and only here. The gate reads the real page size from
|
|
30
|
+
* `pdfinfo`, but this half of the census inspects source HTML with no PDF to
|
|
31
|
+
* read it from, and the print contract lets an operator keep their own page size
|
|
32
|
+
* on `@page` because their stationery may not be A4. The consequence is
|
|
33
|
+
* directional: on stationery wider than A4 this counter is stricter than the
|
|
34
|
+
* gate and can over-report; on narrower stationery it under-reports. The gate,
|
|
35
|
+
* which is the blocking path, is unaffected either way. */
|
|
36
|
+
const MAX_MARGIN_BOX_PX = Math.floor(594.96 / 3 / (72 / 96));
|
|
37
|
+
/** The census line. Every field is always present, so `oversizedImages=0` is
|
|
38
|
+
* greppable evidence of a clean sweep rather than an absent counter. */
|
|
39
|
+
export function formatPrintCensus(c) {
|
|
40
|
+
return (`${TAG} scanned=${c.scanned} pdfs=${c.pdfs} sourceHtml=${c.sourceHtml} ` +
|
|
41
|
+
`headerMissingPages=${c.headerMissingPages} oversizedImages=${c.oversizedImages} ` +
|
|
42
|
+
`unreadable=${c.unreadable}`);
|
|
43
|
+
}
|
|
44
|
+
/** Intrinsic pixel widths of every `@page` top-margin-box image in this source
|
|
45
|
+
* document that is wider than the box can render. The box's declared width is
|
|
46
|
+
* deliberately not read: Chromium does not scale the image to it, which is the
|
|
47
|
+
* whole of the defect, so the declared value carries no information about what
|
|
48
|
+
* actually prints. This is the half of the census that sees a template drift
|
|
49
|
+
* back to a full-resolution asset before anything is printed from it. */
|
|
50
|
+
export function intrinsicOversizePx(html) {
|
|
51
|
+
const out = [];
|
|
52
|
+
const boxes = html.matchAll(/@top-(?:left|center|right)\s*\{[^}]*?content\s*:\s*url\(\s*["']?data:image\/png;base64,([A-Za-z0-9+/=]+)/gs);
|
|
53
|
+
for (const m of boxes) {
|
|
54
|
+
let px = 0;
|
|
55
|
+
try {
|
|
56
|
+
const buf = Buffer.from(m[1], 'base64');
|
|
57
|
+
const i = buf.indexOf('IHDR');
|
|
58
|
+
if (i > 0 && i + 8 <= buf.length)
|
|
59
|
+
px = buf.readUInt32BE(i + 4);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
continue; // undecodable payload — counted by the caller as unreadable
|
|
63
|
+
}
|
|
64
|
+
if (px > MAX_MARGIN_BOX_PX)
|
|
65
|
+
out.push(px);
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
/** Run the conformance hook over one PDF and hand back what it said.
|
|
70
|
+
* LOG_DIR / CLAUDE_SESSION_MANAGER_PERSIST_DIR / ACCOUNT_DIR are stripped so the
|
|
71
|
+
* hook resolves no log directory: the census reads the verdict off stderr rather
|
|
72
|
+
* than writing one line per PDF per tick into the operator's conformance log.
|
|
73
|
+
*
|
|
74
|
+
* Asynchronous on purpose. The manager is a live server and this runs poppler
|
|
75
|
+
* three times per PDF, so a synchronous spawn would stall the event loop for the
|
|
76
|
+
* whole sweep — including the SSE stream and every route — on an install with
|
|
77
|
+
* many printed quotes. */
|
|
78
|
+
function defaultRunHook(hookPath) {
|
|
79
|
+
return async (cwd, pdf) => {
|
|
80
|
+
const envelope = JSON.stringify({
|
|
81
|
+
hook_event_name: 'PostToolUse',
|
|
82
|
+
tool_name: 'mcp__plugin_browser_browser__browser-pdf-save',
|
|
83
|
+
tool_input: { path: pdf },
|
|
84
|
+
});
|
|
85
|
+
const env = { ...process.env };
|
|
86
|
+
delete env.LOG_DIR;
|
|
87
|
+
delete env.CLAUDE_SESSION_MANAGER_PERSIST_DIR;
|
|
88
|
+
delete env.ACCOUNT_DIR;
|
|
89
|
+
const child = execFileAsync('bash', [hookPath], {
|
|
90
|
+
cwd,
|
|
91
|
+
env,
|
|
92
|
+
encoding: 'utf-8',
|
|
93
|
+
timeout: 60_000,
|
|
94
|
+
});
|
|
95
|
+
child.child.stdin?.end(envelope);
|
|
96
|
+
try {
|
|
97
|
+
const { stdout, stderr } = await child;
|
|
98
|
+
return String(stderr ?? '') + String(stdout ?? '');
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
// Exit 2 is a block, which is the case worth counting; the verdict lines
|
|
102
|
+
// are on stderr either way.
|
|
103
|
+
const e = err;
|
|
104
|
+
return String(e.stderr ?? '') + String(e.stdout ?? '');
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function accountIds(accountsRoot) {
|
|
109
|
+
try {
|
|
110
|
+
return readdirSync(accountsRoot).filter((e) => existsSync(join(accountsRoot, e, 'account.json')));
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** Every file under `dir` matching `ext`, one level of subdirectories deep at
|
|
117
|
+
* most, which is the shape of both `memory/users/<phone>/documents` and
|
|
118
|
+
* `quoting/templates`. */
|
|
119
|
+
function filesUnder(dir, ext, depth) {
|
|
120
|
+
let entries;
|
|
121
|
+
try {
|
|
122
|
+
entries = readdirSync(dir);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
const out = [];
|
|
128
|
+
for (const e of entries) {
|
|
129
|
+
const p = join(dir, e);
|
|
130
|
+
let isDir = false;
|
|
131
|
+
try {
|
|
132
|
+
isDir = statSync(p).isDirectory();
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (isDir) {
|
|
138
|
+
if (depth > 0)
|
|
139
|
+
out.push(...filesUnder(p, ext, depth - 1));
|
|
140
|
+
}
|
|
141
|
+
else if (e.endsWith(ext)) {
|
|
142
|
+
out.push(p);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return out;
|
|
146
|
+
}
|
|
147
|
+
/** Read one PDF's verdict out of the hook's own output. A PDF that produced
|
|
148
|
+
* neither verdict line, or produced a `no-poppler` skip, counts as unreadable
|
|
149
|
+
* rather than clean: a document the audit could not inspect must never read as
|
|
150
|
+
* evidence that nothing is wrong. */
|
|
151
|
+
function countOnePdf(hookOutput, counts) {
|
|
152
|
+
const header = /op=pdf-header-conformance[^\n]*/.exec(hookOutput)?.[0] ?? '';
|
|
153
|
+
const geometry = /op=pdf-image-geometry[^\n]*/.exec(hookOutput)?.[0] ?? '';
|
|
154
|
+
if (!header && !geometry) {
|
|
155
|
+
counts.unreadable += 1;
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (/reason=no-poppler/.test(hookOutput)) {
|
|
159
|
+
counts.unreadable += 1;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const missing = /pagesHeaderless=(\d+)/.exec(header);
|
|
163
|
+
if (missing)
|
|
164
|
+
counts.headerMissingPages += Number(missing[1]);
|
|
165
|
+
const frac = /fracPage=([\d.]+)%/.exec(geometry);
|
|
166
|
+
const limit = /limitPt=([\d.]+)/.exec(geometry);
|
|
167
|
+
const widest = /widestPt=([\d.]+)/.exec(geometry);
|
|
168
|
+
if (frac && limit && widest && Number(widest[1]) > Number(limit[1])) {
|
|
169
|
+
counts.oversizedImages += 1;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/** One sweep: every client-quote PDF on disk through the hook, and every source
|
|
173
|
+
* document that declares an image margin box through the intrinsic-width check.
|
|
174
|
+
* Emits one census line and returns the counts. */
|
|
175
|
+
export async function collectPrintCensus(deps) {
|
|
176
|
+
const runHook = deps.runHook ?? defaultRunHook(deps.hookPath);
|
|
177
|
+
const counts = {
|
|
178
|
+
scanned: 0,
|
|
179
|
+
pdfs: 0,
|
|
180
|
+
sourceHtml: 0,
|
|
181
|
+
headerMissingPages: 0,
|
|
182
|
+
oversizedImages: 0,
|
|
183
|
+
unreadable: 0,
|
|
184
|
+
};
|
|
185
|
+
for (const id of accountIds(deps.accountsRoot)) {
|
|
186
|
+
counts.scanned += 1;
|
|
187
|
+
const acct = join(deps.accountsRoot, id);
|
|
188
|
+
for (const pdf of filesUnder(join(acct, 'memory', 'users'), '.pdf', 2)) {
|
|
189
|
+
counts.pdfs += 1;
|
|
190
|
+
let output = '';
|
|
191
|
+
try {
|
|
192
|
+
output = await runHook(acct, pdf);
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
counts.unreadable += 1;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
countOnePdf(output, counts);
|
|
199
|
+
}
|
|
200
|
+
const html = [
|
|
201
|
+
...filesUnder(join(acct, 'quoting', 'templates'), '.html', 1),
|
|
202
|
+
...filesUnder(join(acct, 'memory', 'users'), '.html', 2),
|
|
203
|
+
];
|
|
204
|
+
for (const f of html) {
|
|
205
|
+
let doc;
|
|
206
|
+
try {
|
|
207
|
+
doc = readFileSync(f, 'utf-8');
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
counts.unreadable += 1;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
counts.sourceHtml += 1;
|
|
214
|
+
counts.oversizedImages += intrinsicOversizePx(doc).length;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
deps.logger(formatPrintCensus(counts));
|
|
218
|
+
return counts;
|
|
219
|
+
}
|
|
220
|
+
/** Standing periodic audit. Unref'd interval so it never holds the process open;
|
|
221
|
+
* a sweep that throws logs and does not stop the timer. A tick that arrives
|
|
222
|
+
* while the previous sweep is still running is dropped rather than queued, so a
|
|
223
|
+
* slow poppler can never stack sweeps on top of each other. */
|
|
224
|
+
export function createPrintCensus(deps) {
|
|
225
|
+
let timer = null;
|
|
226
|
+
let running = false;
|
|
227
|
+
return {
|
|
228
|
+
start() {
|
|
229
|
+
if (timer)
|
|
230
|
+
return;
|
|
231
|
+
timer = setInterval(() => {
|
|
232
|
+
if (running)
|
|
233
|
+
return;
|
|
234
|
+
running = true;
|
|
235
|
+
void collectPrintCensus(deps)
|
|
236
|
+
.catch((err) => {
|
|
237
|
+
deps.logger(`${TAG} op=sweep-failed detail=${err instanceof Error ? err.message : String(err)}`);
|
|
238
|
+
})
|
|
239
|
+
.finally(() => {
|
|
240
|
+
running = false;
|
|
241
|
+
});
|
|
242
|
+
}, deps.intervalMs);
|
|
243
|
+
if (typeof timer.unref === 'function')
|
|
244
|
+
timer.unref();
|
|
245
|
+
},
|
|
246
|
+
stop() {
|
|
247
|
+
if (timer) {
|
|
248
|
+
clearInterval(timer);
|
|
249
|
+
timer = null;
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=quote-print-census.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quote-print-census.js","sourceRoot":"","sources":["../src/quote-print-census.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export declare const WINDOW_MS: number;
|
|
2
|
+
export type Logger = (line: string) => void;
|
|
3
|
+
export interface TranscriptEvent {
|
|
4
|
+
/** Epoch ms from the record's own `timestamp`, so the window is per-record
|
|
5
|
+
* rather than per-file. A transcript appended to over days holds events on
|
|
6
|
+
* both sides of the boundary. */
|
|
7
|
+
ts: number;
|
|
8
|
+
kind: 'dispatch' | 'bypass';
|
|
9
|
+
/** Dispatch: the `tool_use` id, resolved to an agent type later. Bypass: the
|
|
10
|
+
* tool name. */
|
|
11
|
+
key: string;
|
|
12
|
+
}
|
|
13
|
+
/** Dispatches and gated calls in one transcript.
|
|
14
|
+
*
|
|
15
|
+
* The input is the PARENT session transcript, which is the main conversation by
|
|
16
|
+
* construction: Task 2469 measured all 41,456 records of one parent as
|
|
17
|
+
* `isSidechain: false`, carrying none of a subagent's tool calls. So a
|
|
18
|
+
* specialist's own use of its own tool can never be counted as a bypass here.
|
|
19
|
+
*
|
|
20
|
+
* A line that will not parse yields nothing rather than throwing: the corpus
|
|
21
|
+
* carries partial trailing writes, and one bad line must not abort the
|
|
22
|
+
* transcript it sits in.
|
|
23
|
+
*
|
|
24
|
+
* A dispatch with no `tool_use` id is skipped rather than counted: it cannot be
|
|
25
|
+
* attributed to a specialist, and an unattributable dispatch counted as a
|
|
26
|
+
* success is exactly the false green this task exists to remove. */
|
|
27
|
+
export declare function scanTranscript(lines: Iterable<string>, gated: ReadonlySet<string>): TranscriptEvent[];
|
|
28
|
+
/** The two counts over one window.
|
|
29
|
+
*
|
|
30
|
+
* A dispatch counts only when its agent type names one of the account's own
|
|
31
|
+
* specialists. A dispatch to a shipped specialist is not evidence that the
|
|
32
|
+
* account's own clerks are being used, and an id that resolves to nothing is
|
|
33
|
+
* not counted either: "we could not tell who ran" is not "the account's
|
|
34
|
+
* specialist ran". */
|
|
35
|
+
export declare function countWindow(events: readonly TranscriptEvent[], agentTypeById: ReadonlyMap<string, string>, authoredNames: ReadonlySet<string>, sinceMs: number): {
|
|
36
|
+
dispatched: number;
|
|
37
|
+
bypassed: number;
|
|
38
|
+
};
|
|
39
|
+
/** The every-tick line. `declared>0 dispatched7d=0` is the alarm; `bypassed7d=0`
|
|
40
|
+
* with `dispatched7d>0` is the healthy state. Emitted including all-zero, so
|
|
41
|
+
* the line's presence proves the check ran. */
|
|
42
|
+
export declare function formatCensus(p: {
|
|
43
|
+
accountId8: string;
|
|
44
|
+
declared: number;
|
|
45
|
+
dispatched7d: number;
|
|
46
|
+
bypassed7d: number;
|
|
47
|
+
}): string;
|
|
48
|
+
/** The error path, deliberately carrying NO counts. Reporting `declared=0` when
|
|
49
|
+
* the card set could not be read would assert something never measured, and
|
|
50
|
+
* would be indistinguishable from an account that genuinely has none. Task 2469
|
|
51
|
+
* applied the same rule to `op=agent-registry-resolution`. */
|
|
52
|
+
export declare function formatCensusDegraded(p: {
|
|
53
|
+
accountId8: string;
|
|
54
|
+
reason: string;
|
|
55
|
+
}): string;
|
|
56
|
+
export interface CensusAccount {
|
|
57
|
+
accountId: string;
|
|
58
|
+
accountDir: string;
|
|
59
|
+
}
|
|
60
|
+
export interface CensusTranscript {
|
|
61
|
+
path: string;
|
|
62
|
+
sessionId: string;
|
|
63
|
+
mtimeMs: number;
|
|
64
|
+
}
|
|
65
|
+
export interface ResolvedGating {
|
|
66
|
+
declared: number;
|
|
67
|
+
authoredNames: ReadonlySet<string>;
|
|
68
|
+
gated: ReadonlySet<string>;
|
|
69
|
+
}
|
|
70
|
+
export interface SpecialistCensusDeps {
|
|
71
|
+
intervalMs: number;
|
|
72
|
+
logger: Logger;
|
|
73
|
+
now(): number;
|
|
74
|
+
listAccounts(): readonly CensusAccount[];
|
|
75
|
+
/** May throw; a throw is the degraded path for that ACCOUNT and never for the
|
|
76
|
+
* run, so one unreadable account does not cost every other account its line. */
|
|
77
|
+
resolveGated(accountDir: string): ResolvedGating;
|
|
78
|
+
/** May throw; same rule as `resolveGated`. */
|
|
79
|
+
listTranscripts(accountDir: string): readonly CensusTranscript[];
|
|
80
|
+
readLines(path: string): Iterable<string>;
|
|
81
|
+
/** `tool_use` id to the agent type it spawned, read from that session's
|
|
82
|
+
* `subagents/agent-<id>.meta.json` files. Task 2469 established that sibling
|
|
83
|
+
* meta as the only surface tying a subagent run to its type. */
|
|
84
|
+
readAgentTypes(accountDir: string, sessionId: string): ReadonlyMap<string, string>;
|
|
85
|
+
}
|
|
86
|
+
export interface SpecialistCensus {
|
|
87
|
+
start(): void;
|
|
88
|
+
stop(): void;
|
|
89
|
+
tickOnce(): void;
|
|
90
|
+
}
|
|
91
|
+
export declare function createSpecialistCensus(deps: SpecialistCensusDeps): SpecialistCensus;
|
|
92
|
+
//# sourceMappingURL=specialist-census.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specialist-census.d.ts","sourceRoot":"","sources":["../src/specialist-census.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,SAAS,QAA0B,CAAA;AAEhD,MAAM,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;AAS3C,MAAM,WAAW,eAAe;IAC9B;;sCAEkC;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,UAAU,GAAG,QAAQ,CAAA;IAC3B;qBACiB;IACjB,GAAG,EAAE,MAAM,CAAA;CACZ;AAED;;;;;;;;;;;;;qEAaqE;AACrE,wBAAgB,cAAc,CAC5B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EACvB,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GACzB,eAAe,EAAE,CA6BnB;AAED;;;;;;uBAMuB;AACvB,wBAAgB,WAAW,CACzB,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1C,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,EAClC,OAAO,EAAE,MAAM,GACd;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAa1C;AAED;;gDAEgD;AAChD,wBAAgB,YAAY,CAAC,CAAC,EAAE;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;CACnB,GAAG,MAAM,CAGT;AAED;;;+DAG+D;AAC/D,wBAAgB,oBAAoB,CAAC,CAAC,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEtF;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAClC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,IAAI,MAAM,CAAA;IACb,YAAY,IAAI,SAAS,aAAa,EAAE,CAAA;IACxC;qFACiF;IACjF,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAAA;IAChD,8CAA8C;IAC9C,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,gBAAgB,EAAE,CAAA;IAChE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;IACzC;;qEAEiE;IACjE,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACnF;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,IAAI,IAAI,CAAA;IACb,IAAI,IAAI,IAAI,CAAA;IACZ,QAAQ,IAAI,IAAI,CAAA;CACjB;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,GAAG,gBAAgB,CAoHnF"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// Task 2244 — an account's own specialists are present, and nothing dispatches
|
|
2
|
+
// them.
|
|
3
|
+
//
|
|
4
|
+
// Skipped delegation writes no record: the inline draft logs an ordinary
|
|
5
|
+
// success, so no log line carries the fault and no re-run reproduces it. On
|
|
6
|
+
// account 2078cb54 four authored clerks owned email, works orders, invoices and
|
|
7
|
+
// quotes while the admin produced all of them inline — zero dispatches against
|
|
8
|
+
// 472 direct `email-draft` calls, for three days, found by the operator rather
|
|
9
|
+
// than by the platform. Only a standing check that reports on a QUIET account
|
|
10
|
+
// can see that state, which is why the line is emitted including all-zero.
|
|
11
|
+
//
|
|
12
|
+
// This is a fourth signal beside three that cannot answer it. The registry
|
|
13
|
+
// reconcile (`account-agent-registry.ts`) says a specialist CAN be reached. The
|
|
14
|
+
// roster census says it is advertised and resolvable. The preference audit
|
|
15
|
+
// (`specialist-preference-audit.ts`) says the RIGHT specialist wrote an owned
|
|
16
|
+
// artefact. None of them counts a dispatch.
|
|
17
|
+
//
|
|
18
|
+
// Shape mirrors specialist-preference-audit.ts: pure scanners, selector and
|
|
19
|
+
// formatters, plus an impure factory whose setInterval is unref'd and whose
|
|
20
|
+
// readers are injected.
|
|
21
|
+
const TAG = '[specialist-census]';
|
|
22
|
+
export const WINDOW_MS = 7 * 24 * 60 * 60 * 1000;
|
|
23
|
+
/** The dispatch tool has carried two names across CLI versions, and both are
|
|
24
|
+
* present in the corpus on disk: the current CLI writes `"name":"Agent"`, and
|
|
25
|
+
* Task 2237 recorded `"name":"Task"` on the same install. Counting one is how a
|
|
26
|
+
* brittle grep reads as a real zero — the trap that task documented when it
|
|
27
|
+
* validated its own count against a tool it knew had run. */
|
|
28
|
+
const DISPATCH_TOOLS = new Set(['Agent', 'Task']);
|
|
29
|
+
/** Dispatches and gated calls in one transcript.
|
|
30
|
+
*
|
|
31
|
+
* The input is the PARENT session transcript, which is the main conversation by
|
|
32
|
+
* construction: Task 2469 measured all 41,456 records of one parent as
|
|
33
|
+
* `isSidechain: false`, carrying none of a subagent's tool calls. So a
|
|
34
|
+
* specialist's own use of its own tool can never be counted as a bypass here.
|
|
35
|
+
*
|
|
36
|
+
* A line that will not parse yields nothing rather than throwing: the corpus
|
|
37
|
+
* carries partial trailing writes, and one bad line must not abort the
|
|
38
|
+
* transcript it sits in.
|
|
39
|
+
*
|
|
40
|
+
* A dispatch with no `tool_use` id is skipped rather than counted: it cannot be
|
|
41
|
+
* attributed to a specialist, and an unattributable dispatch counted as a
|
|
42
|
+
* success is exactly the false green this task exists to remove. */
|
|
43
|
+
export function scanTranscript(lines, gated) {
|
|
44
|
+
const out = [];
|
|
45
|
+
for (const line of lines) {
|
|
46
|
+
let parsed;
|
|
47
|
+
try {
|
|
48
|
+
parsed = JSON.parse(line);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const record = parsed;
|
|
54
|
+
if (typeof record.timestamp !== 'string')
|
|
55
|
+
continue;
|
|
56
|
+
const ts = Date.parse(record.timestamp);
|
|
57
|
+
if (Number.isNaN(ts))
|
|
58
|
+
continue;
|
|
59
|
+
const content = record.message?.content;
|
|
60
|
+
if (!Array.isArray(content))
|
|
61
|
+
continue;
|
|
62
|
+
for (const block of content) {
|
|
63
|
+
if (!block || typeof block !== 'object')
|
|
64
|
+
continue;
|
|
65
|
+
const b = block;
|
|
66
|
+
if (b.type !== 'tool_use' || typeof b.name !== 'string')
|
|
67
|
+
continue;
|
|
68
|
+
if (DISPATCH_TOOLS.has(b.name)) {
|
|
69
|
+
if (typeof b.id === 'string' && b.id.length > 0) {
|
|
70
|
+
out.push({ ts, kind: 'dispatch', key: b.id });
|
|
71
|
+
}
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (gated.has(b.name))
|
|
75
|
+
out.push({ ts, kind: 'bypass', key: b.name });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
/** The two counts over one window.
|
|
81
|
+
*
|
|
82
|
+
* A dispatch counts only when its agent type names one of the account's own
|
|
83
|
+
* specialists. A dispatch to a shipped specialist is not evidence that the
|
|
84
|
+
* account's own clerks are being used, and an id that resolves to nothing is
|
|
85
|
+
* not counted either: "we could not tell who ran" is not "the account's
|
|
86
|
+
* specialist ran". */
|
|
87
|
+
export function countWindow(events, agentTypeById, authoredNames, sinceMs) {
|
|
88
|
+
let dispatched = 0;
|
|
89
|
+
let bypassed = 0;
|
|
90
|
+
for (const event of events) {
|
|
91
|
+
if (event.ts < sinceMs)
|
|
92
|
+
continue;
|
|
93
|
+
if (event.kind === 'bypass') {
|
|
94
|
+
bypassed++;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const agentType = agentTypeById.get(event.key);
|
|
98
|
+
if (agentType !== undefined && authoredNames.has(agentType))
|
|
99
|
+
dispatched++;
|
|
100
|
+
}
|
|
101
|
+
return { dispatched, bypassed };
|
|
102
|
+
}
|
|
103
|
+
/** The every-tick line. `declared>0 dispatched7d=0` is the alarm; `bypassed7d=0`
|
|
104
|
+
* with `dispatched7d>0` is the healthy state. Emitted including all-zero, so
|
|
105
|
+
* the line's presence proves the check ran. */
|
|
106
|
+
export function formatCensus(p) {
|
|
107
|
+
return `${TAG} account=${p.accountId8} declared=${p.declared}` +
|
|
108
|
+
` dispatched7d=${p.dispatched7d} bypassed7d=${p.bypassed7d}`;
|
|
109
|
+
}
|
|
110
|
+
/** The error path, deliberately carrying NO counts. Reporting `declared=0` when
|
|
111
|
+
* the card set could not be read would assert something never measured, and
|
|
112
|
+
* would be indistinguishable from an account that genuinely has none. Task 2469
|
|
113
|
+
* applied the same rule to `op=agent-registry-resolution`. */
|
|
114
|
+
export function formatCensusDegraded(p) {
|
|
115
|
+
return `${TAG} account=${p.accountId8} op=degraded reason=${p.reason}`;
|
|
116
|
+
}
|
|
117
|
+
export function createSpecialistCensus(deps) {
|
|
118
|
+
/** transcript path -> the events found in it, at that mtime and under that
|
|
119
|
+
* gated set.
|
|
120
|
+
*
|
|
121
|
+
* Events rather than counts, because the window moves every tick while the
|
|
122
|
+
* file does not: a cached count would freeze at the window in force when the
|
|
123
|
+
* file was last read, and an account that went quiet would keep reporting the
|
|
124
|
+
* activity it had a fortnight ago.
|
|
125
|
+
*
|
|
126
|
+
* Keyed on the gated set as well as the mtime, because the gated set is not a
|
|
127
|
+
* property of the transcript. Authoring a specialist widens it while every
|
|
128
|
+
* existing file keeps its mtime, so an mtime-only cache would keep reporting
|
|
129
|
+
* the counts of the narrower set and the new clerk's tools would read as
|
|
130
|
+
* never bypassed on the day it was created. A transcript is re-read only when
|
|
131
|
+
* one of the two moves, so a steady state still costs one stat per file. */
|
|
132
|
+
const seen = new Map();
|
|
133
|
+
let timer = null;
|
|
134
|
+
/** A stable identity for a gated set, so a cache hit can prove the events were
|
|
135
|
+
* scanned under the set in force now. */
|
|
136
|
+
function gatingKeyFor(gated) {
|
|
137
|
+
return Array.from(gated).sort().join(',');
|
|
138
|
+
}
|
|
139
|
+
function tickOnce() {
|
|
140
|
+
const sinceMs = deps.now() - WINDOW_MS;
|
|
141
|
+
const live = new Set();
|
|
142
|
+
for (const account of deps.listAccounts()) {
|
|
143
|
+
const accountId8 = account.accountId.slice(0, 8);
|
|
144
|
+
let gating;
|
|
145
|
+
let transcripts;
|
|
146
|
+
try {
|
|
147
|
+
gating = deps.resolveGated(account.accountDir);
|
|
148
|
+
transcripts = deps.listTranscripts(account.accountDir);
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
deps.logger(formatCensusDegraded({
|
|
152
|
+
accountId8,
|
|
153
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
154
|
+
}));
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const gatingKey = gatingKeyFor(gating.gated);
|
|
158
|
+
let dispatched7d = 0;
|
|
159
|
+
let bypassed7d = 0;
|
|
160
|
+
for (const transcript of transcripts) {
|
|
161
|
+
live.add(transcript.path);
|
|
162
|
+
const prior = seen.get(transcript.path);
|
|
163
|
+
let events;
|
|
164
|
+
if (prior && prior.mtimeMs === transcript.mtimeMs && prior.gatingKey === gatingKey) {
|
|
165
|
+
events = prior.events;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
try {
|
|
169
|
+
events = scanTranscript(deps.readLines(transcript.path), gating.gated);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// A transcript that cannot be read contributes nothing and is not
|
|
173
|
+
// cached, so the next tick retries it. It does not degrade the
|
|
174
|
+
// account: every other transcript still carries real counts.
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
seen.set(transcript.path, { mtimeMs: transcript.mtimeMs, gatingKey, events });
|
|
178
|
+
}
|
|
179
|
+
let agentTypes = new Map();
|
|
180
|
+
if (events.some((e) => e.kind === 'dispatch')) {
|
|
181
|
+
try {
|
|
182
|
+
agentTypes = deps.readAgentTypes(account.accountDir, transcript.sessionId);
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
// Unresolved dispatches are not counted, which countWindow already
|
|
186
|
+
// enforces. Never counted as a success.
|
|
187
|
+
agentTypes = new Map();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const counted = countWindow(events, agentTypes, gating.authoredNames, sinceMs);
|
|
191
|
+
dispatched7d += counted.dispatched;
|
|
192
|
+
bypassed7d += counted.bypassed;
|
|
193
|
+
}
|
|
194
|
+
deps.logger(formatCensus({ accountId8, declared: gating.declared, dispatched7d, bypassed7d }));
|
|
195
|
+
}
|
|
196
|
+
// Drop transcripts that have gone, so the cache describes what is on disk now
|
|
197
|
+
// rather than growing for the life of a process that runs for weeks.
|
|
198
|
+
for (const path of Array.from(seen.keys()))
|
|
199
|
+
if (!live.has(path))
|
|
200
|
+
seen.delete(path);
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
tickOnce,
|
|
204
|
+
start() {
|
|
205
|
+
if (timer)
|
|
206
|
+
return;
|
|
207
|
+
timer = setInterval(() => {
|
|
208
|
+
try {
|
|
209
|
+
tickOnce();
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
deps.logger(`${TAG} op=tick-failed message=${err instanceof Error ? err.message : String(err)}`);
|
|
213
|
+
}
|
|
214
|
+
}, deps.intervalMs);
|
|
215
|
+
if (typeof timer.unref === 'function')
|
|
216
|
+
timer.unref();
|
|
217
|
+
deps.logger(`${TAG} op=started intervalMs=${deps.intervalMs}`);
|
|
218
|
+
},
|
|
219
|
+
stop() {
|
|
220
|
+
if (timer) {
|
|
221
|
+
clearInterval(timer);
|
|
222
|
+
timer = null;
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=specialist-census.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specialist-census.js","sourceRoot":"","sources":["../src/specialist-census.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walk `${CLAUDE_CONFIG_DIR}/projects/<slug>/` for `${sessionId}.jsonl` (live
|
|
3
|
+
* and archived). Returns the first match or null. Inlined from
|
|
4
|
+
* whatsapp-channel/jsonl-watch.ts (itself inlined from
|
|
5
|
+
* claude-session-manager/src/jsonl-path.ts) to avoid a cross-package dep.
|
|
6
|
+
*/
|
|
7
|
+
export declare function findJsonlForSessionId(sessionId: string, env?: NodeJS.ProcessEnv): string | null;
|
|
8
|
+
//# sourceMappingURL=jsonl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl.d.ts","sourceRoot":"","sources":["../src/jsonl.ts"],"names":[],"mappings":"AAcA;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,GAAG,IAAI,CAmBf"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Task 2521 — extracted from turn-follow.ts, which is gone. The follower that
|
|
2
|
+
// module carried was one of three copies that each decided independently what an
|
|
3
|
+
// answer was; the ui-server emitter replaced all of them. This path lookup was
|
|
4
|
+
// the only part the inbound path still needs, so it lives on its own rather than
|
|
5
|
+
// keeping a 500-line module alive for one function.
|
|
6
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
7
|
+
import { homedir } from 'node:os';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
function claudeConfigRoot(env) {
|
|
10
|
+
return env.CLAUDE_CONFIG_DIR ?? join(homedir(), '.claude');
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Walk `${CLAUDE_CONFIG_DIR}/projects/<slug>/` for `${sessionId}.jsonl` (live
|
|
14
|
+
* and archived). Returns the first match or null. Inlined from
|
|
15
|
+
* whatsapp-channel/jsonl-watch.ts (itself inlined from
|
|
16
|
+
* claude-session-manager/src/jsonl-path.ts) to avoid a cross-package dep.
|
|
17
|
+
*/
|
|
18
|
+
export function findJsonlForSessionId(sessionId, env = process.env) {
|
|
19
|
+
const projectsRoot = join(claudeConfigRoot(env), 'projects');
|
|
20
|
+
if (!existsSync(projectsRoot))
|
|
21
|
+
return null;
|
|
22
|
+
let slugs;
|
|
23
|
+
try {
|
|
24
|
+
slugs = readdirSync(projectsRoot, { withFileTypes: true })
|
|
25
|
+
.filter((d) => d.isDirectory())
|
|
26
|
+
.map((d) => d.name);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const basename = `${sessionId}.jsonl`;
|
|
32
|
+
for (const slug of slugs) {
|
|
33
|
+
const live = join(projectsRoot, slug, basename);
|
|
34
|
+
if (existsSync(live))
|
|
35
|
+
return live;
|
|
36
|
+
const archived = join(projectsRoot, slug, 'archive', basename);
|
|
37
|
+
if (existsSync(archived))
|
|
38
|
+
return archived;
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=jsonl.js.map
|