@rubytech/create-maxy-code 0.1.601 → 0.1.603
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/neo4j/schema.cypher +7 -0
- package/payload/platform/plugins/admin/hooks/video-frames-inject.sh +141 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +19 -1
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +12 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +2 -0
- package/payload/platform/plugins/docs/references/telegram-guide.md +16 -0
- package/payload/platform/plugins/scheduling/PLUGIN.md +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js +67 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js +89 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/outage-marker.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/outage-marker.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/outage-marker.test.js +160 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/outage-marker.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.js +16 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts +31 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js +42 -4
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/outage-marker.d.ts +101 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/outage-marker.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/outage-marker.js +130 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/outage-marker.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts +10 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts +24 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js +89 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +67 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js +31 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +10 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +46 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +72 -4
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js +81 -4
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts +50 -0
- 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 +48 -7
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -1
- package/payload/platform/plugins/telegram/PLUGIN.md +4 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin-registry.test.js +33 -1
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin-registry.test.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin.test.js +166 -1
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin.test.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/index.js +39 -14
- package/payload/platform/plugins/telegram/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.d.ts +95 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.js +125 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.js.map +1 -1
- package/payload/platform/plugins/telegram/skills/configure/SKILL.md +15 -1
- package/payload/platform/services/telegram-channel/dist/notification.d.ts +6 -0
- package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/telegram-channel/dist/notification.js +12 -5
- package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +5 -0
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js +9 -3
- package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
- package/payload/platform/templates/account-settings.json +6 -0
- package/payload/server/chunk-CYU75QAV.js +377 -0
- package/payload/server/{chunk-34FPJYHN.js → chunk-GI5AVCRG.js} +87 -146
- package/payload/server/chunk-KUVNCAE4.js +77 -0
- package/payload/server/{manager-7BXVB76I.js → manager-VDHT3YYI.js} +2 -1
- package/payload/server/maxy-edge.js +33 -1
- package/payload/server/public/activity.html +6 -6
- package/payload/server/public/agents.html +5 -5
- package/payload/server/public/assets/{AdminLoginScreens-B3W6J6Bl.js → AdminLoginScreens-DI5bNlX8.js} +1 -1
- package/payload/server/public/assets/AdminLoginScreens-DI5bNlX8.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-DI5bNlX8.js.gz +0 -0
- package/payload/server/public/assets/{AdminShell-C3R-vMZ5.js → AdminShell-B-iX9ahJ.js} +1 -1
- package/payload/server/public/assets/AdminShell-B-iX9ahJ.js.br +0 -0
- package/payload/server/public/assets/AdminShell-B-iX9ahJ.js.gz +0 -0
- package/payload/server/public/assets/{activity-tzv68iBs.js → activity-CqgFwANo.js} +1 -1
- package/payload/server/public/assets/activity-CqgFwANo.js.br +0 -0
- package/payload/server/public/assets/activity-CqgFwANo.js.gz +0 -0
- package/payload/server/public/assets/admin-K63n6ybW.js +1 -0
- package/payload/server/public/assets/admin-K63n6ybW.js.br +0 -0
- package/payload/server/public/assets/admin-K63n6ybW.js.gz +0 -0
- package/payload/server/public/assets/{agents-DUZfeY3X.js → agents-cue5Zf8X.js} +1 -1
- package/payload/server/public/assets/agents-cue5Zf8X.js.br +0 -0
- package/payload/server/public/assets/agents-cue5Zf8X.js.gz +0 -0
- package/payload/server/public/assets/{browser-DwLaXqjO.js → browser-CqDBcKwU.js} +1 -1
- package/payload/server/public/assets/browser-CqDBcKwU.js.br +0 -0
- package/payload/server/public/assets/browser-CqDBcKwU.js.gz +0 -0
- package/payload/server/public/assets/{calendar-Cli8Qjl9.js → calendar-BgzuW5Rt.js} +1 -1
- package/payload/server/public/assets/calendar-BgzuW5Rt.js.br +0 -0
- package/payload/server/public/assets/calendar-BgzuW5Rt.js.gz +0 -0
- package/payload/server/public/assets/chat-HYZViu2u.js +1 -0
- package/payload/server/public/assets/chat-HYZViu2u.js.br +3 -0
- package/payload/server/public/assets/chat-HYZViu2u.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-C5FXH9r_.js +1 -0
- package/payload/server/public/assets/chevron-left-C5FXH9r_.js.br +0 -0
- package/payload/server/public/assets/clock-DxPtyejC.js +1 -0
- package/payload/server/public/assets/clock-DxPtyejC.js.br +0 -0
- package/payload/server/public/assets/clock-DxPtyejC.js.gz +0 -0
- package/payload/server/public/assets/{copy-yhhwfEbQ.js → copy-BNhZ0flH.js} +1 -1
- package/payload/server/public/assets/copy-BNhZ0flH.js.br +0 -0
- package/payload/server/public/assets/copy-BNhZ0flH.js.gz +0 -0
- package/payload/server/public/assets/data-kCBB8Z4Z.js +1 -0
- package/payload/server/public/assets/data-kCBB8Z4Z.js.br +0 -0
- package/payload/server/public/assets/data-kCBB8Z4Z.js.gz +0 -0
- package/payload/server/public/assets/{field-jg0YQNDy.js → field-X4OVA3vx.js} +1 -1
- package/payload/server/public/assets/field-X4OVA3vx.js.br +0 -0
- package/payload/server/public/assets/field-X4OVA3vx.js.gz +0 -0
- package/payload/server/public/assets/{file-text-D0EdW7h4.js → file-text-BddO_2EI.js} +1 -1
- package/payload/server/public/assets/file-text-BddO_2EI.js.br +0 -0
- package/payload/server/public/assets/file-text-BddO_2EI.js.gz +0 -0
- package/payload/server/public/assets/{graph--AUr4uBc.js → graph-l7tzHqvm.js} +1 -1
- package/payload/server/public/assets/graph-l7tzHqvm.js.br +0 -0
- package/payload/server/public/assets/graph-l7tzHqvm.js.gz +0 -0
- package/payload/server/public/assets/{graph-labels-DM0CiAX1.js → graph-labels-CtFFq5W2.js} +1 -1
- package/payload/server/public/assets/graph-labels-CtFFq5W2.js.br +0 -0
- package/payload/server/public/assets/graph-labels-CtFFq5W2.js.gz +0 -0
- package/payload/server/public/assets/jsx-runtime-bq0g4NlA.css +1 -0
- package/payload/server/public/assets/jsx-runtime-bq0g4NlA.css.br +0 -0
- package/payload/server/public/assets/jsx-runtime-bq0g4NlA.css.gz +0 -0
- package/payload/server/public/assets/{operator-CNYKStFX.js → operator-Dg-dwf7a.js} +1 -1
- package/payload/server/public/assets/operator-Dg-dwf7a.js.br +7 -0
- package/payload/server/public/assets/operator-Dg-dwf7a.js.gz +0 -0
- package/payload/server/public/assets/page-Ci1bfIbs.js +1 -0
- package/payload/server/public/assets/page-Ci1bfIbs.js.br +0 -0
- package/payload/server/public/assets/page-Ci1bfIbs.js.gz +0 -0
- package/payload/server/public/assets/page-Y9JmFq0Q.js +32 -0
- package/payload/server/public/assets/page-Y9JmFq0Q.js.br +0 -0
- package/payload/server/public/assets/page-Y9JmFq0Q.js.gz +0 -0
- package/payload/server/public/assets/play-BSZVGpQT.js +1 -0
- package/payload/server/public/assets/play-BSZVGpQT.js.br +0 -0
- package/payload/server/public/assets/play-BSZVGpQT.js.gz +0 -0
- package/payload/server/public/assets/{public-7gXDqCog.js → public-m66FAza_.js} +1 -1
- package/payload/server/public/assets/public-m66FAza_.js.br +0 -0
- package/payload/server/public/assets/public-m66FAza_.js.gz +0 -0
- package/payload/server/public/assets/{rotate-ccw-DhqNTPpo.js → rotate-ccw-DTOJmOxB.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-DTOJmOxB.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-DTOJmOxB.js.gz +0 -0
- package/payload/server/public/assets/{routines-DN_yDtEj.js → routines-6fxZNacQ.js} +1 -1
- package/payload/server/public/assets/routines-6fxZNacQ.js.br +0 -0
- package/payload/server/public/assets/routines-6fxZNacQ.js.gz +0 -0
- package/payload/server/public/assets/{skills-pb_3BdOl.js → skills-51mqx-s5.js} +1 -1
- package/payload/server/public/assets/skills-51mqx-s5.js.br +0 -0
- package/payload/server/public/assets/skills-51mqx-s5.js.gz +0 -0
- package/payload/server/public/assets/{tasks-BQm4boat.js → tasks-D4y-Cwa3.js} +1 -1
- package/payload/server/public/assets/tasks-D4y-Cwa3.js.br +0 -0
- package/payload/server/public/assets/tasks-D4y-Cwa3.js.gz +0 -0
- package/payload/server/public/assets/{triangle-alert-d7yjaIqv.js → triangle-alert-BzCjDFts.js} +1 -1
- package/payload/server/public/assets/triangle-alert-BzCjDFts.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-BzCjDFts.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-CZ6Qhfkj.js → useCopyFeedback-BG7h37Rx.js} +1 -1
- package/payload/server/public/assets/useCopyFeedback-BG7h37Rx.js.br +2 -0
- package/payload/server/public/assets/useCopyFeedback-BG7h37Rx.js.gz +0 -0
- package/payload/server/public/assets/{useMediaQuery-R1smYLx4.js → useMediaQuery-CqwktQr_.js} +1 -1
- package/payload/server/public/assets/useMediaQuery-CqwktQr_.js.br +0 -0
- package/payload/server/public/assets/useMediaQuery-CqwktQr_.js.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-CAZcUc1s.js +2 -0
- package/payload/server/public/assets/useVoiceRecorder-CAZcUc1s.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-CAZcUc1s.js.gz +0 -0
- package/payload/server/public/assets/{wrench-DL1pbaCs.js → wrench-B2WKLLQG.js} +1 -1
- package/payload/server/public/assets/wrench-B2WKLLQG.js.br +0 -0
- package/payload/server/public/assets/wrench-B2WKLLQG.js.gz +0 -0
- package/payload/server/public/browser.html +5 -5
- package/payload/server/public/calendar.html +8 -8
- package/payload/server/public/chat.html +14 -14
- package/payload/server/public/data.html +12 -12
- package/payload/server/public/field.html +3 -3
- package/payload/server/public/graph.html +10 -10
- package/payload/server/public/index.html +14 -14
- package/payload/server/public/operator.html +15 -15
- package/payload/server/public/public.html +14 -14
- package/payload/server/public/routines.html +8 -8
- package/payload/server/public/skills.html +6 -6
- package/payload/server/public/tasks.html +7 -7
- package/payload/server/server.js +1067 -783
- package/payload/server/video-extract.js +36 -0
- package/payload/server/public/assets/AdminLoginScreens-B3W6J6Bl.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-B3W6J6Bl.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-C3R-vMZ5.js.br +0 -0
- package/payload/server/public/assets/AdminShell-C3R-vMZ5.js.gz +0 -0
- package/payload/server/public/assets/activity-tzv68iBs.js.br +0 -0
- package/payload/server/public/assets/activity-tzv68iBs.js.gz +0 -0
- package/payload/server/public/assets/admin-CzW_9jm3.js +0 -1
- package/payload/server/public/assets/admin-CzW_9jm3.js.br +0 -0
- package/payload/server/public/assets/admin-CzW_9jm3.js.gz +0 -0
- package/payload/server/public/assets/agents-DUZfeY3X.js.br +0 -0
- package/payload/server/public/assets/agents-DUZfeY3X.js.gz +0 -0
- package/payload/server/public/assets/browser-DwLaXqjO.js.br +0 -0
- package/payload/server/public/assets/browser-DwLaXqjO.js.gz +0 -0
- package/payload/server/public/assets/calendar-Cli8Qjl9.js.br +0 -0
- package/payload/server/public/assets/calendar-Cli8Qjl9.js.gz +0 -0
- package/payload/server/public/assets/chat-ByAgBgm1.js +0 -1
- package/payload/server/public/assets/chat-ByAgBgm1.js.br +0 -1
- package/payload/server/public/assets/chat-ByAgBgm1.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-BIYVnwvk.js +0 -1
- package/payload/server/public/assets/chevron-left-BIYVnwvk.js.br +0 -0
- package/payload/server/public/assets/clock-Dzy79hq3.js +0 -1
- package/payload/server/public/assets/clock-Dzy79hq3.js.br +0 -0
- package/payload/server/public/assets/clock-Dzy79hq3.js.gz +0 -0
- package/payload/server/public/assets/copy-yhhwfEbQ.js.br +0 -0
- package/payload/server/public/assets/copy-yhhwfEbQ.js.gz +0 -0
- package/payload/server/public/assets/data-CsMMki2A.js +0 -1
- package/payload/server/public/assets/data-CsMMki2A.js.br +0 -0
- package/payload/server/public/assets/data-CsMMki2A.js.gz +0 -0
- package/payload/server/public/assets/field-jg0YQNDy.js.br +0 -0
- package/payload/server/public/assets/field-jg0YQNDy.js.gz +0 -0
- package/payload/server/public/assets/file-text-D0EdW7h4.js.br +0 -0
- package/payload/server/public/assets/file-text-D0EdW7h4.js.gz +0 -0
- package/payload/server/public/assets/graph--AUr4uBc.js.br +0 -0
- package/payload/server/public/assets/graph--AUr4uBc.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-DM0CiAX1.js.br +0 -0
- package/payload/server/public/assets/graph-labels-DM0CiAX1.js.gz +0 -0
- package/payload/server/public/assets/jsx-runtime-lfcjzaWi.css +0 -1
- package/payload/server/public/assets/jsx-runtime-lfcjzaWi.css.br +0 -0
- package/payload/server/public/assets/jsx-runtime-lfcjzaWi.css.gz +0 -0
- package/payload/server/public/assets/operator-CNYKStFX.js.br +0 -0
- package/payload/server/public/assets/operator-CNYKStFX.js.gz +0 -0
- package/payload/server/public/assets/page-DSsEpl8J.js +0 -32
- package/payload/server/public/assets/page-DSsEpl8J.js.br +0 -0
- package/payload/server/public/assets/page-DSsEpl8J.js.gz +0 -0
- package/payload/server/public/assets/page-DjhmwxnY.js +0 -1
- package/payload/server/public/assets/page-DjhmwxnY.js.br +0 -0
- package/payload/server/public/assets/page-DjhmwxnY.js.gz +0 -0
- package/payload/server/public/assets/play-DhZlml5b.js +0 -1
- package/payload/server/public/assets/play-DhZlml5b.js.br +0 -0
- package/payload/server/public/assets/play-DhZlml5b.js.gz +0 -0
- package/payload/server/public/assets/public-7gXDqCog.js.br +0 -0
- package/payload/server/public/assets/public-7gXDqCog.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-DhqNTPpo.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-DhqNTPpo.js.gz +0 -0
- package/payload/server/public/assets/routines-DN_yDtEj.js.br +0 -0
- package/payload/server/public/assets/routines-DN_yDtEj.js.gz +0 -0
- package/payload/server/public/assets/skills-pb_3BdOl.js.br +0 -0
- package/payload/server/public/assets/skills-pb_3BdOl.js.gz +0 -0
- package/payload/server/public/assets/tasks-BQm4boat.js.br +0 -0
- package/payload/server/public/assets/tasks-BQm4boat.js.gz +0 -0
- package/payload/server/public/assets/triangle-alert-d7yjaIqv.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-d7yjaIqv.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-CZ6Qhfkj.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-CZ6Qhfkj.js.gz +0 -0
- package/payload/server/public/assets/useMediaQuery-R1smYLx4.js.br +0 -0
- package/payload/server/public/assets/useMediaQuery-R1smYLx4.js.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-DM1v6sRa.js +0 -2
- package/payload/server/public/assets/useVoiceRecorder-DM1v6sRa.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-DM1v6sRa.js.gz +0 -0
- package/payload/server/public/assets/wrench-DL1pbaCs.js.br +0 -0
- package/payload/server/public/assets/wrench-DL1pbaCs.js.gz +0 -0
- /package/payload/server/public/assets/{jsx-runtime-BtDK2X5t.js → jsx-runtime-UK6hgBWO.js} +0 -0
- /package/payload/server/public/assets/{jsx-runtime-BtDK2X5t.js.br → jsx-runtime-UK6hgBWO.js.br} +0 -0
- /package/payload/server/public/assets/{jsx-runtime-BtDK2X5t.js.gz → jsx-runtime-UK6hgBWO.js.gz} +0 -0
package/package.json
CHANGED
|
@@ -72,6 +72,13 @@ FOR (d:DefinedTerm) ON (d.category);
|
|
|
72
72
|
CREATE INDEX person_status IF NOT EXISTS
|
|
73
73
|
FOR (p:Person) ON (p.status);
|
|
74
74
|
|
|
75
|
+
// Person.telegramUserId — the key an inbound Telegram turn resolves the
|
|
76
|
+
// speaker's name by (Task 2705). Composite with accountId because the lookup is
|
|
77
|
+
// always account-scoped and neither property is indexed alone: without this the
|
|
78
|
+
// read is a label scan over every Person in the database, on a message path.
|
|
79
|
+
CREATE INDEX person_account_telegram_user_id IF NOT EXISTS
|
|
80
|
+
FOR (p:Person) ON (p.accountId, p.telegramUserId);
|
|
81
|
+
|
|
75
82
|
// Review (schema:Review) — competitor comparison assessments
|
|
76
83
|
CREATE INDEX review_item_reviewed IF NOT EXISTS
|
|
77
84
|
FOR (r:Review) ON (r.itemReviewed);
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# video-frames-inject — PreToolUse gate on Read of a video file (Task 2696).
|
|
3
|
+
#
|
|
4
|
+
# Read cannot decode a video at all: it refuses with "This tool cannot read
|
|
5
|
+
# binary files", so an agent handed a video path either gives up or improvises
|
|
6
|
+
# its own ffmpeg frame grab with no relation to the audio. This hook runs the
|
|
7
|
+
# same deterministic extraction the three channels use and hands back the frame
|
|
8
|
+
# and speech timeline, so the filesystem route stops being the one door where
|
|
9
|
+
# seeing a video depends on the model deciding to.
|
|
10
|
+
#
|
|
11
|
+
# PreToolUse, NOT PostToolUse — the opposite of pdf-text-layer-inject.sh, and
|
|
12
|
+
# for a measured reason. Read SUCCEEDS on a PDF (returning page images), so the
|
|
13
|
+
# PDF hook injects its text layer afterwards. Read FAILS on a video, so there is
|
|
14
|
+
# no successful call to attach to; blocking the doomed Read and returning the
|
|
15
|
+
# timeline as the reason is the only way the content reaches the turn.
|
|
16
|
+
#
|
|
17
|
+
# Exit codes: 2 = the Read is blocked and the timeline on stderr reaches the
|
|
18
|
+
# model (the same feedback mechanism pdf-text-layer-inject.sh and
|
|
19
|
+
# task-authoring-gate.sh rely on); 0 = not a video, or extraction had nothing to
|
|
20
|
+
# say, and the Read proceeds untouched. Fail OPEN on every uninspectable path —
|
|
21
|
+
# a hook that cannot extract must never block a Read it has no opinion on.
|
|
22
|
+
#
|
|
23
|
+
# One line per video Read to <logDir>/video-frames.log, including the reads that
|
|
24
|
+
# inject nothing: a clip past the duration ceiling and a hook that never fired
|
|
25
|
+
# are different states and only the log tells them apart.
|
|
26
|
+
|
|
27
|
+
set -uo pipefail
|
|
28
|
+
|
|
29
|
+
if [ -t 0 ]; then exit 0; fi
|
|
30
|
+
INPUT=$(cat)
|
|
31
|
+
[ -z "$INPUT" ] && exit 0
|
|
32
|
+
|
|
33
|
+
# --- log sink ---------------------------------------------------------------
|
|
34
|
+
# Same ladder as pdf-text-layer-inject.sh: a hook's stderr on exit 0 reaches no
|
|
35
|
+
# file on this platform. LOG_DIR is stamped only on the rc-spawn path,
|
|
36
|
+
# CLAUDE_SESSION_MANAGER_PERSIST_DIR is on the systemd unit and resolves to the
|
|
37
|
+
# same directory, ACCOUNT_DIR/logs is the last resort.
|
|
38
|
+
LOGD=""
|
|
39
|
+
if [ -n "${LOG_DIR:-}" ] && [ -d "${LOG_DIR}" ]; then
|
|
40
|
+
LOGD="$LOG_DIR"
|
|
41
|
+
elif [ -n "${CLAUDE_SESSION_MANAGER_PERSIST_DIR:-}" ] && [ -d "${CLAUDE_SESSION_MANAGER_PERSIST_DIR}/logs" ]; then
|
|
42
|
+
LOGD="$CLAUDE_SESSION_MANAGER_PERSIST_DIR/logs"
|
|
43
|
+
elif [ -n "${ACCOUNT_DIR:-}" ] && [ -d "${ACCOUNT_DIR}/logs" ]; then
|
|
44
|
+
LOGD="$ACCOUNT_DIR/logs"
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
INPUT="$INPUT" LOGD="$LOGD" \
|
|
48
|
+
NOW_ISO="$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || echo '?')" \
|
|
49
|
+
PLATFORM_ROOT="${PLATFORM_ROOT:-}" \
|
|
50
|
+
python3 - <<'PY'
|
|
51
|
+
import json, os, subprocess, sys
|
|
52
|
+
|
|
53
|
+
VIDEO_EXTS = (".mp4", ".mov", ".webm", ".mkv", ".3gp")
|
|
54
|
+
|
|
55
|
+
logd = os.environ.get("LOGD", "")
|
|
56
|
+
now = os.environ.get("NOW_ISO", "?")
|
|
57
|
+
|
|
58
|
+
account = os.environ.get("ACCOUNT_ID") or ""
|
|
59
|
+
if not account:
|
|
60
|
+
acct_dir = os.environ.get("ACCOUNT_DIR") or ""
|
|
61
|
+
account = os.path.basename(acct_dir.rstrip("/")) if acct_dir else ""
|
|
62
|
+
account = account or "?"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def emit_log(base, chars, injected, reason, sid):
|
|
66
|
+
if not logd:
|
|
67
|
+
return
|
|
68
|
+
line = ("%s [video-frames] op=video-frames file=%s chars=%d "
|
|
69
|
+
"injected=%s reason=%s account=%s session=%s"
|
|
70
|
+
% (now, base, chars, injected, reason, account, sid))
|
|
71
|
+
try:
|
|
72
|
+
with open(os.path.join(logd, "video-frames.log"), "a") as fh:
|
|
73
|
+
fh.write(line + "\n")
|
|
74
|
+
except Exception:
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
d = json.loads(os.environ["INPUT"])
|
|
80
|
+
except Exception:
|
|
81
|
+
sys.exit(0)
|
|
82
|
+
|
|
83
|
+
if (d.get("hook_event_name") or "") != "PreToolUse":
|
|
84
|
+
sys.exit(0)
|
|
85
|
+
if (d.get("tool_name") or "") != "Read":
|
|
86
|
+
sys.exit(0)
|
|
87
|
+
path = (d.get("tool_input") or {}).get("file_path") or ""
|
|
88
|
+
if not path.lower().endswith(VIDEO_EXTS):
|
|
89
|
+
sys.exit(0)
|
|
90
|
+
|
|
91
|
+
sid = d.get("session_id") or "?"
|
|
92
|
+
base = os.path.basename(path)
|
|
93
|
+
|
|
94
|
+
# The extraction CLI is built beside the server (tsup entry `video-extract`), so
|
|
95
|
+
# the pipeline here is the same code the WhatsApp, Telegram and admin webchat
|
|
96
|
+
# doors run. Re-implementing ffmpeg and whisper in this hook would be a second
|
|
97
|
+
# authority for the same fact.
|
|
98
|
+
root = os.environ.get("PLATFORM_ROOT") or ""
|
|
99
|
+
cli = os.path.join(root, "ui", "dist", "video-extract.js") if root else ""
|
|
100
|
+
if not cli or not os.path.exists(cli):
|
|
101
|
+
emit_log(base, 0, "no", "no-cli", sid)
|
|
102
|
+
sys.exit(0)
|
|
103
|
+
|
|
104
|
+
# 25 minutes, and it must stay above the extraction's own budget or this door
|
|
105
|
+
# caps lower than the channels and MAX_DURATION_S means two different things.
|
|
106
|
+
# A 300s clip (the ceiling) costs ~1200s of whisper at 0.25x real time, which
|
|
107
|
+
# is WHISPER_TIMEOUT_MS; frame extraction is on top. Cutting in below that would
|
|
108
|
+
# kill work the channel doors would have completed.
|
|
109
|
+
try:
|
|
110
|
+
proc = subprocess.run(["node", cli, path], capture_output=True, timeout=1500)
|
|
111
|
+
except FileNotFoundError:
|
|
112
|
+
emit_log(base, 0, "no", "no-node", sid)
|
|
113
|
+
sys.exit(0)
|
|
114
|
+
except Exception:
|
|
115
|
+
emit_log(base, 0, "no", "unreadable", sid)
|
|
116
|
+
sys.exit(0)
|
|
117
|
+
|
|
118
|
+
# Exit 1 is the CLI's "nothing useful to say": not a video, past the duration
|
|
119
|
+
# ceiling, no video stream, or no frame extracted. The [video] line written by
|
|
120
|
+
# the extraction itself carries which one.
|
|
121
|
+
if proc.returncode != 0:
|
|
122
|
+
emit_log(base, 0, "no", "no-timeline", sid)
|
|
123
|
+
sys.exit(0)
|
|
124
|
+
|
|
125
|
+
timeline = proc.stdout.decode("utf-8", "replace").strip()
|
|
126
|
+
if not timeline:
|
|
127
|
+
emit_log(base, 0, "no", "empty-timeline", sid)
|
|
128
|
+
sys.exit(0)
|
|
129
|
+
|
|
130
|
+
# Log before writing the payload, so a failure mid-write still leaves the record.
|
|
131
|
+
emit_log(base, len(timeline), "yes", "timeline", sid)
|
|
132
|
+
|
|
133
|
+
sys.stderr.write(
|
|
134
|
+
"Read cannot decode %s, so it was not opened. Below is that video as "
|
|
135
|
+
"sampled frames and its spoken transcript, on the video's own clock. Read "
|
|
136
|
+
"the frame paths to see those moments.\n\n%s\n" % (base, timeline))
|
|
137
|
+
sys.exit(2)
|
|
138
|
+
PY
|
|
139
|
+
rc=$?
|
|
140
|
+
[ "$rc" -eq 2 ] && exit 2
|
|
141
|
+
exit 0
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: platform-architecture
|
|
3
3
|
description: Use when grounding any documented-surface claim about what Maxy ships — plugins, skills, specialists, install/deploy flows, internals. This is the install catalogue, not evidence of what is enabled on the current account. For install state on this account, call `capabilities-here`; for documented surface, cite the `Source:` URL inline.
|
|
4
|
-
content-hash: sha256:
|
|
4
|
+
content-hash: sha256:2a7e28897d543df02b543552d72a457eca3956ab090a4bc5b886b487eb950d3e
|
|
5
5
|
brand: maxy-code
|
|
6
6
|
product-name: Maxy
|
|
7
7
|
---
|
|
@@ -2868,6 +2868,8 @@ Maxy asks for your bot token, then asks what kind of bot this is:
|
|
|
2868
2868
|
|
|
2869
2869
|
A public Telegram bot holds five things and nothing else: the reply that carries its answer, cards with tappable buttons, polls and quizzes and map pins, outgoing photos and documents and voice notes, and the ability to open a file a visitor sent it. That set is fixed by the platform for every public agent on every account, so there is no tools setting on an agent to turn any of it on or off. A public bot on webchat or WhatsApp still has the reply alone, because those channels ship no equivalent set.
|
|
2870
2870
|
|
|
2871
|
+
Everything outside that set is not offered to a public bot at all, rather than offered and then refused. The difference matters to a visitor: an agent shown a tool it cannot use will sometimes try it, and the refusal it gets back reads to the person waiting as the assistant talking to itself. A public spawn states its surface when it starts — `[telegram-tools] op=public-surface registered=4` in the server log — and a count above four is a fault worth reporting.
|
|
2872
|
+
|
|
2871
2873
|
It verifies the token, registers the bot's webhook on your brand's edge, stores the token under your brand's config (never in a shared system directory), and sets whichever agent or specialist will answer. The bot is now connected.
|
|
2872
2874
|
|
|
2873
2875
|
### Step 3: Start the bot
|
|
@@ -2943,6 +2945,20 @@ store, so what Maxy tells you and what actually arrived cannot drift apart.
|
|
|
2943
2945
|
|
|
2944
2946
|
If Maxy ever says a Telegram message cannot be sent, ask it to check that list first.
|
|
2945
2947
|
|
|
2948
|
+
### How your bot knows who is talking to it
|
|
2949
|
+
|
|
2950
|
+
Allowing someone's Telegram ID lets them message the bot. It does not tell the bot who they are: an
|
|
2951
|
+
ID is a number, and the only other name available is whatever that person's own Telegram profile is
|
|
2952
|
+
called, which is often a device or account label rather than a person.
|
|
2953
|
+
|
|
2954
|
+
Maxy reads the name from your contacts. When a Telegram ID is saved on someone's contact
|
|
2955
|
+
record, every message from that ID arrives with their name attached, so you get a proper greeting and
|
|
2956
|
+
Maxy knows whose request it is handling. When it is not saved, it falls back to the
|
|
2957
|
+
Telegram profile name and will tell you plainly that it cannot put a name to the sender.
|
|
2958
|
+
|
|
2959
|
+
Ask Maxy to save the Telegram ID against the contact. It is one change to one contact, and
|
|
2960
|
+
it takes effect on the very next message.
|
|
2961
|
+
|
|
2946
2962
|
## Getting a Chat ID
|
|
2947
2963
|
|
|
2948
2964
|
To message a specific person or group, Maxy needs their chat ID. The easiest way:
|
|
@@ -4082,6 +4098,8 @@ either is a regression.
|
|
|
4082
4098
|
|
|
4083
4099
|
**`/chat` composer transport button.** The button at the end of the input shows a **microphone** while the box is empty — tap it to record a voice note. Type a character, or attach a file, and the same button becomes the **send** arrow; while the agent is replying it becomes a **stop** square. So an empty composer offers voice, a composer with something to send offers send, and a running turn offers stop — one button, three states. The microphone-device chooser (which input to record from) stays in the row of icons below the box. This is the same on the admin `/chat`, the public chat, and the maxy-lite webchat.
|
|
4084
4100
|
|
|
4101
|
+
**`/chat` a voice note or video clears the composer as soon as it uploads.** Sending audio or video used to hold the request open for the whole of transcription — a ~25 MB clip measures around three minutes — and the tunnel cancels anything past 125 seconds. The reply still arrived, but the browser had already given up, so the operator read an answer sitting above a composer that still held their text and the audio chip, and sent again. The send now answers as soon as the upload is stored: the composer clears in a couple of seconds, and "Transcribing audio…" stays up for the whole of the real transcription because the server reports that state on the session pointer rather than the browser guessing it from its own request. The bare microphone path behaves the same way and gains the same line, where before it re-staged the recording and said "Voice note failed to send" while the turn was landing. Every refusal an operator can trigger — too many files, an unsupported file, an oversize recording, a storage failure — is still answered on the request itself, so a rejected send is still rejected on screen. A send that genuinely never reaches the server now says "Couldn't be sent — press send to retry." and writes a `webchat-send-failed` line to `client-errors.log`; that is a different statement from the existing "Message not delivered" banner, which means an accepted send that produced no turn. Operators triaging this have three server-side lines: `op=send-staged` when the upload was taken, `op=send-continuation-failed` if transcription died, and a 15-minute `op=send-response-lost-census` in the edge log that reports `aborted=0` too, so a quiet census is distinguishable from a stopped one. Detail lives in `.docs/admin-webchat-native-channel.md` ("A voice or video send accepts on upload").
|
|
4102
|
+
|
|
4085
4103
|
**`/chat` Conversations flyout + zero-sessions splash.** The admin `/chat` `HeaderMenu` carries a **Conversations** item (rendered only when `onOpenConversations` is wired, which scopes it to `/chat`) that opens an in-chat session-management pane (`app/chat/SessionList.tsx`) hosted by `chat/page.tsx` — distinct from, and sharing endpoints with, the `Sidebar` Sessions list (which stays hidden on narrow viewports). It enumerates the admin's own webchat sessions via `GET /api/admin/sidebar-sessions` (carries the per-row `live` marker and `archived` flag, install-wide), **filtering out `channel:'whatsapp'`/`'telegram'` rows** (those are channel-bound, cannot be chatted in webchat, and live in the WhatsApp/Telegram reader panels; the same endpoint now also feeds the sidebar Sessions list, which does show them), lists the remainder newest-first with the live one marked and archived rows folded under a collapsible subsection, and offers per-row resume (`/chat?session=<id>`), rename, archive/unarchive, two-tap delete, an **End** control on the live row (`session-stop`), plus a New-session control (`session-rc-spawn`) and a copyable full id. The pane header carries the title and a top-right close (X) control that dismisses the flyout (no back-chevron/"Chat" label); the New-session control floats at the pane's bottom-left. When the canonical pointer is `known:false` (`canonical-empty`) and enumeration returns zero rows, the surface renders a splash (brand logo + New session) instead of a dead bootstrap thread; a freshly-spawned New session is `known:true`, so its greeting is preserved. Client breadcrumbs: `[chat-conversations] op=enumerate owned=<n>` and `op=action name=<open|rename|archive|delete|stop> sessionId=<id8>` (`op=action-failed … status=…` on a non-2xx). Detail lives in `.docs/admin-webchat-native-channel.md` ("Conversations flyout + zero-sessions splash").
|
|
4086
4104
|
|
|
4087
4105
|
**`/chat` header always shows the account name.** The admin/operator `HeaderMenu` centre always renders the active account's name alongside the brand logo, on every chat surface, regardless of the active conversation — `headerTitle = businessName || brand.productName`. There is no per-conversation header title: the active conversation's label stays in the sidebar and the Conversations flyout (each resolves its own per-session title independently), never in the header. The account name is `LocalBusiness.name`, resolved by `fetchAccountName(accountId)` in `neo4j-store.ts` with **no theme gate** — unlike `fetchBranding` (which returns null unless a colour/logo property is also set, and stays the source for actual theming). The house account is seeded with `LocalBusiness.name = <brand productName>` (`seed-neo4j.sh`, coalesced ON MATCH so a re-seed backfills a name-less node and never clobbers a name the business-profile recorder set later), so the sub-account picker's house row shows the product name (e.g. "SiteDesk"), not the raw accountId UUID. When a name is absent the resolver emits `[branding] account-name-fallback accountId=<id8>… reason=no-name`, and the picker falls back to the accountId; the seed + backfill is the name source. The lite variant header is unchanged.
|
|
@@ -9,6 +9,18 @@ Invoked by the admin agent directly.
|
|
|
9
9
|
|
|
10
10
|
This is the platform's release timeline, newest first. Each entry shows the date it shipped and the version it shipped in, so you can tell the operator how current their install is. To compare, read the installed version from `capabilities-here` and match it against the versions below. Keep answers high level and in plain English; this is a summary, not a full commit log.
|
|
11
11
|
|
|
12
|
+
## 2026-08-13 (0.1.603)
|
|
13
|
+
|
|
14
|
+
- Your Telegram assistant now knows who it is talking to. When someone's Telegram ID is saved on their contact record, every message from them arrives with their name attached, instead of the assistant seeing only a number or whatever that person's Telegram profile happens to be called.
|
|
15
|
+
- Setting up an admin bot now asks who each allowed ID belongs to, and saves the answer against the contact, so the names you give are kept rather than lost.
|
|
16
|
+
- An hourly check reports any allowed Telegram ID that is not yet matched to a contact, so a missed one is noticed without anyone having to message the bot.
|
|
17
|
+
|
|
18
|
+
## 2026-08-13 (0.1.602)
|
|
19
|
+
|
|
20
|
+
- Voice and video sends from the webchat composer are now accepted the moment the upload lands, instead of holding the confirmation until transcription completes.
|
|
21
|
+
- A new 15-minute census on the edge counts aborted webchat send responses, and a `webchat-send-failed` client-error kind lets a failed send surface honestly.
|
|
22
|
+
- Read a failed transcription state from the pointer instead of the request path, and count staged sends per key rather than in aggregate.
|
|
23
|
+
|
|
12
24
|
## 2026-08-13 (0.1.601)
|
|
13
25
|
|
|
14
26
|
- Your incoming email is now recorded automatically. A background service checks each connected mailbox on its own and saves every new message so the assistant can recall it later, without you having to say "check my email" first.
|
|
@@ -73,6 +73,8 @@ either is a regression.
|
|
|
73
73
|
|
|
74
74
|
**`/chat` composer transport button.** The button at the end of the input shows a **microphone** while the box is empty — tap it to record a voice note. Type a character, or attach a file, and the same button becomes the **send** arrow; while the agent is replying it becomes a **stop** square. So an empty composer offers voice, a composer with something to send offers send, and a running turn offers stop — one button, three states. The microphone-device chooser (which input to record from) stays in the row of icons below the box. This is the same on the admin `/chat`, the public chat, and the maxy-lite webchat.
|
|
75
75
|
|
|
76
|
+
**`/chat` a voice note or video clears the composer as soon as it uploads.** Sending audio or video used to hold the request open for the whole of transcription — a ~25 MB clip measures around three minutes — and the tunnel cancels anything past 125 seconds. The reply still arrived, but the browser had already given up, so the operator read an answer sitting above a composer that still held their text and the audio chip, and sent again. The send now answers as soon as the upload is stored: the composer clears in a couple of seconds, and "Transcribing audio…" stays up for the whole of the real transcription because the server reports that state on the session pointer rather than the browser guessing it from its own request. The bare microphone path behaves the same way and gains the same line, where before it re-staged the recording and said "Voice note failed to send" while the turn was landing. Every refusal an operator can trigger — too many files, an unsupported file, an oversize recording, a storage failure — is still answered on the request itself, so a rejected send is still rejected on screen. A send that genuinely never reaches the server now says "Couldn't be sent — press send to retry." and writes a `webchat-send-failed` line to `client-errors.log`; that is a different statement from the existing "Message not delivered" banner, which means an accepted send that produced no turn. Operators triaging this have three server-side lines: `op=send-staged` when the upload was taken, `op=send-continuation-failed` if transcription died, and a 15-minute `op=send-response-lost-census` in the edge log that reports `aborted=0` too, so a quiet census is distinguishable from a stopped one. Detail lives in `.docs/admin-webchat-native-channel.md` ("A voice or video send accepts on upload").
|
|
77
|
+
|
|
76
78
|
**`/chat` Conversations flyout + zero-sessions splash.** The admin `/chat` `HeaderMenu` carries a **Conversations** item (rendered only when `onOpenConversations` is wired, which scopes it to `/chat`) that opens an in-chat session-management pane (`app/chat/SessionList.tsx`) hosted by `chat/page.tsx` — distinct from, and sharing endpoints with, the `Sidebar` Sessions list (which stays hidden on narrow viewports). It enumerates the admin's own webchat sessions via `GET /api/admin/sidebar-sessions` (carries the per-row `live` marker and `archived` flag, install-wide), **filtering out `channel:'whatsapp'`/`'telegram'` rows** (those are channel-bound, cannot be chatted in webchat, and live in the WhatsApp/Telegram reader panels; the same endpoint now also feeds the sidebar Sessions list, which does show them), lists the remainder newest-first with the live one marked and archived rows folded under a collapsible subsection, and offers per-row resume (`/chat?session=<id>`), rename, archive/unarchive, two-tap delete, an **End** control on the live row (`session-stop`), plus a New-session control (`session-rc-spawn`) and a copyable full id. The pane header carries the title and a top-right close (X) control that dismisses the flyout (no back-chevron/"Chat" label); the New-session control floats at the pane's bottom-left. When the canonical pointer is `known:false` (`canonical-empty`) and enumeration returns zero rows, the surface renders a splash (brand logo + New session) instead of a dead bootstrap thread; a freshly-spawned New session is `known:true`, so its greeting is preserved. Client breadcrumbs: `[chat-conversations] op=enumerate owned=<n>` and `op=action name=<open|rename|archive|delete|stop> sessionId=<id8>` (`op=action-failed … status=…` on a non-2xx). Detail lives in `.docs/admin-webchat-native-channel.md` ("Conversations flyout + zero-sessions splash").
|
|
77
79
|
|
|
78
80
|
**`/chat` header always shows the account name.** The admin/operator `HeaderMenu` centre always renders the active account's name alongside the brand logo, on every chat surface, regardless of the active conversation — `headerTitle = businessName || brand.productName`. There is no per-conversation header title: the active conversation's label stays in the sidebar and the Conversations flyout (each resolves its own per-session title independently), never in the header. The account name is `LocalBusiness.name`, resolved by `fetchAccountName(accountId)` in `neo4j-store.ts` with **no theme gate** — unlike `fetchBranding` (which returns null unless a colour/logo property is also set, and stays the source for actual theming). The house account is seeded with `LocalBusiness.name = <brand productName>` (`seed-neo4j.sh`, coalesced ON MATCH so a re-seed backfills a name-less node and never clobbers a name the business-profile recorder set later), so the sub-account picker's house row shows the product name (e.g. "SiteDesk"), not the raw accountId UUID. When a name is absent the resolver emits `[branding] account-name-fallback accountId=<id8>… reason=no-name`, and the picker falls back to the accountId; the seed + backfill is the name source. The lite variant header is unchanged.
|
|
@@ -47,6 +47,8 @@ Tell {{productName}}: "Set up Telegram" or "Configure the Telegram bot." Setup r
|
|
|
47
47
|
|
|
48
48
|
A public Telegram bot holds five things and nothing else: the reply that carries its answer, cards with tappable buttons, polls and quizzes and map pins, outgoing photos and documents and voice notes, and the ability to open a file a visitor sent it. That set is fixed by the platform for every public agent on every account, so there is no tools setting on an agent to turn any of it on or off. A public bot on webchat or WhatsApp still has the reply alone, because those channels ship no equivalent set.
|
|
49
49
|
|
|
50
|
+
Everything outside that set is not offered to a public bot at all, rather than offered and then refused. The difference matters to a visitor: an agent shown a tool it cannot use will sometimes try it, and the refusal it gets back reads to the person waiting as the assistant talking to itself. A public spawn states its surface when it starts — `[telegram-tools] op=public-surface registered=4` in the server log — and a count above four is a fault worth reporting.
|
|
51
|
+
|
|
50
52
|
It verifies the token, registers the bot's webhook on your brand's edge, stores the token under your brand's config (never in a shared system directory), and sets whichever agent or specialist will answer. The bot is now connected.
|
|
51
53
|
|
|
52
54
|
### Step 3: Start the bot
|
|
@@ -122,6 +124,20 @@ store, so what {{productName}} tells you and what actually arrived cannot drift
|
|
|
122
124
|
|
|
123
125
|
If {{productName}} ever says a Telegram message cannot be sent, ask it to check that list first.
|
|
124
126
|
|
|
127
|
+
### How your bot knows who is talking to it
|
|
128
|
+
|
|
129
|
+
Allowing someone's Telegram ID lets them message the bot. It does not tell the bot who they are: an
|
|
130
|
+
ID is a number, and the only other name available is whatever that person's own Telegram profile is
|
|
131
|
+
called, which is often a device or account label rather than a person.
|
|
132
|
+
|
|
133
|
+
{{productName}} reads the name from your contacts. When a Telegram ID is saved on someone's contact
|
|
134
|
+
record, every message from that ID arrives with their name attached, so you get a proper greeting and
|
|
135
|
+
{{productName}} knows whose request it is handling. When it is not saved, it falls back to the
|
|
136
|
+
Telegram profile name and will tell you plainly that it cannot put a name to the sender.
|
|
137
|
+
|
|
138
|
+
Ask {{productName}} to save the Telegram ID against the contact. It is one change to one contact, and
|
|
139
|
+
it takes effect on the very next message.
|
|
140
|
+
|
|
125
141
|
## Getting a Chat ID
|
|
126
142
|
|
|
127
143
|
To message a specific person or group, {{productName}} needs their chat ID. The easiest way:
|
|
@@ -348,6 +348,8 @@ The position written is the one the GATE read, carried back in the result rather
|
|
|
348
348
|
|
|
349
349
|
Three lines record it. `[schedule-gate] op=mark-advanced eventId=… advanced=… positions=…` per accepted wake, `op=mark-not-advanced eventId=… reason=no-observation|watermark-unreadable|write-failed` when nothing moved, and the standing `[schedule-audit] op=gate-mark-stalled acct=… count=… eventIds=[…]`, which names any gated event with three or more accepted wakes since its mark last moved. That last one is the check for the failure that emits nothing at all: a promote that runs, writes nothing, and leaves every surface reading normally. `op=gate-watermark-age` measures the same mark against the clock and so reads a weekly routine as stale; this one measures it against the routine's own wakes. A watermark file that exists and is not a watermark object is named by `[scheduling-gate] op=watermark-unreadable eventId=… reason=…` on every read of it, and is never overwritten, so its positions survive for an operator to look at; a missing file stays silent, because that is a first fire. `reason=` names the shape found: a body holding a JSON array reads `an array, not a watermark object`, because an array is an object to `typeof` and so passed the guard, was promoted into, and was then written back by `JSON.stringify` with every promoted position dropped.
|
|
350
350
|
|
|
351
|
+
**An unreachable source is reported once per outage, not once per fire.** A check that cannot reach its source still counts as work and still fires — that is what fail-open means — but the REPEAT is deduplicated. The result carries `genuineWork`, set only by a check that answered, and a `source` on every `errored[]` entry (the mailbox, the connector, the database, the bot, or the channel). When nothing answered with work and one or more checks errored, the sorted set of those sources is compared with the set last reported, held as `outageReported {sources, at}` inside the event's own watermark file. An unchanged set skips the fire: no turn, no message, no watermark advance, and a run recorded `gated` with `dispatchResult = 'outage-suppressed'`. A new or changed set dispatches, and the set is stored only once the inject route accepts the wake, because a refused dispatch told nobody anything. A fire with genuine work dispatches regardless and records whatever is unreachable at that fire: real work on one check is no evidence about another check's source, so a delivery on a healthy mailbox leaves a sick mailbox's marker exactly where it was, and clearing there would re-report the same outage on the next quiet fire. The marker clears when a dispatching fire has nothing unreachable, and when the gate answers quiet, so the next outage reports afresh; recovery rides the routine's next real wake rather than a message of its own. Re-recording a set already held rewrites nothing, so its age stays measurable. Four lines record it: the per-fire `[schedule-gate] op=evaluated … genuineWork=… errored=[…] class=has-work|outage-report|outage-suppressed|no-work`, then `op=outage-reported eventId=… sources=[…]`, `op=outage-suppressed eventId=… sources=[…] promoted=0`, and `op=outage-cleared eventId=… priorSources=[…] reason=…`. A marker that stops clearing would mute that routine's outage reporting permanently with no other symptom, so the standing `[schedule-audit] op=outage-marker-census acct=… held=… stale=… ok=…` prints per account on every reconcile tick and `op=stale-outage-marker eventId=… sources=[…] agedCycles=… agedHours=…` names any marker older than a day. A gate server built before this contract returns neither field, reads as genuine work, and is never suppressed.
|
|
352
|
+
|
|
351
353
|
**Recurring only.** A one-time agent event is never gated — its row is already `due` by the time the dispatcher sees it, so a skip there would drop the routine for good — and it is therefore outside the refusal. `schedule-update` takes no waiver either: an existing routine keeps what it has until it is edited.
|
|
352
354
|
|
|
353
355
|
An event carries **either** an `action` **or** an `agentDispatch`, never both — setting one clears the other. Agent dispatch is stored as `agentChannel`, `agentDestination`, `agentPrompt`; the gate as `gatePlugin`, `gateTool`, `gateArgs`; the waiver as `gateWaived`. Use `schedule-update` with `agentDispatch` to modify or `agentDispatch: null` to clear. On WhatsApp, a destination bound as an account-manager scopes the spawned session to its sub-account — unless that same phone is also on the house `adminPhones` list, in which case it scopes to the channel account, because the dispatch rides the house socket and so arrives from the house number. On Telegram the session runs on the house account.
|
|
@@ -9,7 +9,7 @@ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
|
9
9
|
import { mkdtempSync, mkdirSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { tmpdir } from "node:os";
|
|
11
11
|
import { join } from "node:path";
|
|
12
|
-
import { auditGateAlwaysSkipping, auditGateNeverGates, auditGateWatermarkAge, auditGateMarkStalled, } from "../schedule-audit.js";
|
|
12
|
+
import { auditGateAlwaysSkipping, auditGateNeverGates, auditGateWatermarkAge, auditGateMarkStalled, auditStaleOutageMarker, } from "../schedule-audit.js";
|
|
13
13
|
import { watermarkPath } from "../../tools/scheduling-gate.js";
|
|
14
14
|
const ACCT = "20028fb5-0000-4000-8000-000000000000";
|
|
15
15
|
const NOW = Date.parse("2026-08-02T20:00:00.000Z");
|
|
@@ -256,4 +256,70 @@ describe("auditGateMarkStalled", () => {
|
|
|
256
256
|
expect(lines.join("\n")).toContain("op=gate-mark-stalled-error");
|
|
257
257
|
});
|
|
258
258
|
});
|
|
259
|
+
// Task 2699 — the outage marker that stopped clearing. While one is held every
|
|
260
|
+
// errors-only fire is suppressed, and a marker that outlives its outage mutes
|
|
261
|
+
// the routine's outage reporting for good with no other symptom.
|
|
262
|
+
describe("auditStaleOutageMarker", () => {
|
|
263
|
+
const rowDriver = (rows) => ({
|
|
264
|
+
session: () => ({
|
|
265
|
+
run: async () => ({ records: rows.map((r) => ({ get: (k) => r[k] })) }),
|
|
266
|
+
close: async () => { },
|
|
267
|
+
}),
|
|
268
|
+
});
|
|
269
|
+
const gatedRow = (eventId, suppressedAt = []) => ({
|
|
270
|
+
eventId,
|
|
271
|
+
accountId: ACCT,
|
|
272
|
+
suppressedAt,
|
|
273
|
+
});
|
|
274
|
+
it("prints a census line per account even when no marker is held", async () => {
|
|
275
|
+
await auditStaleOutageMarker(rowDriver([gatedRow("e-1")]), [ACCT], platformRoot, NOW);
|
|
276
|
+
expect(lines).toEqual([
|
|
277
|
+
"[schedule-audit] op=outage-marker-census acct=20028fb5 held=0 stale=0 ok=true",
|
|
278
|
+
]);
|
|
279
|
+
});
|
|
280
|
+
it("counts a fresh marker as held and not stale", async () => {
|
|
281
|
+
seedMarks("e-1", {
|
|
282
|
+
outageReported: { sources: ["a@x"], at: "2026-08-02T18:00:00.000Z" },
|
|
283
|
+
});
|
|
284
|
+
await auditStaleOutageMarker(rowDriver([gatedRow("e-1")]), [ACCT], platformRoot, NOW);
|
|
285
|
+
expect(lines).toEqual([
|
|
286
|
+
"[schedule-audit] op=outage-marker-census acct=20028fb5 held=1 stale=0 ok=true",
|
|
287
|
+
]);
|
|
288
|
+
});
|
|
289
|
+
it("names a marker older than a day, with the fires it has suppressed", async () => {
|
|
290
|
+
seedMarks("e-1", {
|
|
291
|
+
outageReported: { sources: ["a@x", "b@x"], at: "2026-08-01T18:00:00.000Z" },
|
|
292
|
+
});
|
|
293
|
+
await auditStaleOutageMarker(rowDriver([
|
|
294
|
+
gatedRow("e-1", [
|
|
295
|
+
// Before the marker: a different episode, not this marker's cost.
|
|
296
|
+
"2026-08-01T17:00:00.000Z",
|
|
297
|
+
"2026-08-01T19:00:00.000Z",
|
|
298
|
+
"2026-08-02T19:00:00.000Z",
|
|
299
|
+
]),
|
|
300
|
+
]), [ACCT], platformRoot, NOW);
|
|
301
|
+
expect(lines[0]).toBe("[schedule-audit] op=stale-outage-marker eventId=e-1 sources=[a@x,b@x] agedCycles=2 agedHours=26");
|
|
302
|
+
expect(lines[1]).toBe("[schedule-audit] op=outage-marker-census acct=20028fb5 held=1 stale=1 ok=false");
|
|
303
|
+
});
|
|
304
|
+
it("treats an unparsable stamp as stale — nothing could ever measure it", async () => {
|
|
305
|
+
seedMarks("e-1", { outageReported: { sources: ["a@x"], at: "not a date" } });
|
|
306
|
+
await auditStaleOutageMarker(rowDriver([gatedRow("e-1")]), [ACCT], platformRoot, NOW);
|
|
307
|
+
expect(lines[0]).toContain("op=stale-outage-marker eventId=e-1 sources=[a@x]");
|
|
308
|
+
expect(lines[0]).toContain("agedHours=-1");
|
|
309
|
+
});
|
|
310
|
+
it("names its own failure rather than going quiet when neo4j is down", async () => {
|
|
311
|
+
const throwing = {
|
|
312
|
+
session: () => ({
|
|
313
|
+
run: async () => {
|
|
314
|
+
throw new Error("neo4j down");
|
|
315
|
+
},
|
|
316
|
+
close: async () => { },
|
|
317
|
+
}),
|
|
318
|
+
};
|
|
319
|
+
await auditStaleOutageMarker(throwing, [ACCT], platformRoot, NOW);
|
|
320
|
+
expect(lines).toEqual([
|
|
321
|
+
"[schedule-audit] op=outage-marker-census-error detail=neo4j down",
|
|
322
|
+
]);
|
|
323
|
+
});
|
|
324
|
+
});
|
|
259
325
|
//# sourceMappingURL=gate-audits.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate-audits.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/gate-audits.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gate-audits.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/gate-audits.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -49,7 +49,14 @@ describe("chooseGate", () => {
|
|
|
49
49
|
describe("evaluateGate", () => {
|
|
50
50
|
it("hasWork true dispatches and logs op=evaluated", async () => {
|
|
51
51
|
const call = async () => ok({ hasWork: true, reasons: ["d1"] });
|
|
52
|
-
expect(await evaluateGate(GATE, EVENT, ACCOUNT, call)).toEqual({
|
|
52
|
+
expect(await evaluateGate(GATE, EVENT, ACCOUNT, call)).toEqual({
|
|
53
|
+
kind: "has-work",
|
|
54
|
+
observed: {},
|
|
55
|
+
// Task 2699 — a gate server predating `genuineWork` reads as genuine work
|
|
56
|
+
// with no named source, so an install mid-upgrade is never suppressed and
|
|
57
|
+
// records no outage.
|
|
58
|
+
outage: [],
|
|
59
|
+
});
|
|
53
60
|
expect(lines.join("\n")).toContain("[schedule-gate] op=evaluated");
|
|
54
61
|
expect(lines.join("\n")).toContain("hasWork=true");
|
|
55
62
|
});
|
|
@@ -211,6 +218,7 @@ describe("evaluateGate", () => {
|
|
|
211
218
|
expect(await evaluateGate(GATE, EVENT, ACCOUNT, async () => ok({ hasWork: true }))).toEqual({
|
|
212
219
|
kind: "has-work",
|
|
213
220
|
observed: {},
|
|
221
|
+
outage: [],
|
|
214
222
|
});
|
|
215
223
|
expect(lines).toHaveLength(1);
|
|
216
224
|
expect(lines[0]).toContain("op=evaluated");
|
|
@@ -224,4 +232,84 @@ describe("evaluateGate", () => {
|
|
|
224
232
|
expect(lines).toHaveLength(1);
|
|
225
233
|
});
|
|
226
234
|
});
|
|
235
|
+
// Task 2699 — the classification an errors-only wake gets, against the set last
|
|
236
|
+
// reported. Each case is separate because the two directions fail differently:
|
|
237
|
+
// suppressing a fire that had real work mutes the routine, and failing to
|
|
238
|
+
// suppress a repeat re-notifies the operator every fire for the whole outage.
|
|
239
|
+
describe("evaluateGate — outage dedup (Task 2699)", () => {
|
|
240
|
+
const errored = (...sources) => sources.map((source) => ({ kind: "mail", detail: "ETIMEDOUT", source }));
|
|
241
|
+
/** A gate result in the post-2699 shape. */
|
|
242
|
+
const gateResult = (over) => ok({ hasWork: true, reasons: ["mail"], genuineWork: false, errored: [], ...over });
|
|
243
|
+
const evaluate = (structured, stored) => evaluateGate(GATE, EVENT, ACCOUNT, async () => ok(structured), () => stored);
|
|
244
|
+
it("errors-only with no marker held dispatches and carries the set to report", async () => {
|
|
245
|
+
expect(await evaluate({ hasWork: true, genuineWork: false, errored: errored("a@x") }, null)).toEqual({ kind: "has-work", observed: {}, outage: ["a@x"] });
|
|
246
|
+
});
|
|
247
|
+
it("errors-only whose set is already reported is suppressed", async () => {
|
|
248
|
+
expect(await evaluate({ hasWork: true, genuineWork: false, errored: errored("a@x", "b@x") }, [
|
|
249
|
+
"a@x",
|
|
250
|
+
"b@x",
|
|
251
|
+
])).toEqual({ kind: "outage-suppressed", sources: ["a@x", "b@x"] });
|
|
252
|
+
});
|
|
253
|
+
it("errors-only whose set changed dispatches again with the new set", async () => {
|
|
254
|
+
expect(await evaluate({ hasWork: true, genuineWork: false, errored: errored("a@x", "b@x") }, ["a@x"])).toEqual({ kind: "has-work", observed: {}, outage: ["a@x", "b@x"] });
|
|
255
|
+
});
|
|
256
|
+
it("genuine work beside a still-down source dispatches and clears the marker", async () => {
|
|
257
|
+
expect(await evaluate({ hasWork: true, genuineWork: true, errored: errored("a@x") }, ["a@x"])).toEqual({ kind: "has-work", observed: {}, outage: ["a@x"] });
|
|
258
|
+
});
|
|
259
|
+
it("genuine work with nothing down carries an empty set, which clears the marker", async () => {
|
|
260
|
+
expect(await evaluate({ hasWork: true, genuineWork: true, errored: [] }, ["a@x"])).toEqual({
|
|
261
|
+
kind: "has-work",
|
|
262
|
+
observed: {},
|
|
263
|
+
outage: [],
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
it("a quiet gate is no-work, whatever marker is held", async () => {
|
|
267
|
+
expect(await evaluate({ hasWork: false, genuineWork: false, errored: [] }, ["a@x"])).toEqual({
|
|
268
|
+
kind: "no-work",
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
it("an unreadable gate still fails open, and reads no marker at all", async () => {
|
|
272
|
+
const reads = [];
|
|
273
|
+
const verdict = await evaluateGate(GATE, EVENT, ACCOUNT, async () => {
|
|
274
|
+
throw new PluginToolError("boom", "error", "");
|
|
275
|
+
}, (id) => {
|
|
276
|
+
reads.push(id);
|
|
277
|
+
return ["a@x"];
|
|
278
|
+
});
|
|
279
|
+
expect(verdict).toMatchObject({ kind: "fail-open" });
|
|
280
|
+
expect(reads).toEqual([]);
|
|
281
|
+
});
|
|
282
|
+
it("a gate server predating genuineWork is never suppressed", async () => {
|
|
283
|
+
// The upgrade window: `errored[]` without `source`, and no `genuineWork`.
|
|
284
|
+
expect(await evaluate({ hasWork: true, errored: [{ kind: "mail", detail: "ETIMEDOUT" }] }, ["a@x"])).toEqual({ kind: "has-work", observed: {}, outage: [] });
|
|
285
|
+
});
|
|
286
|
+
it("names the report class on the fire that starts an outage episode", async () => {
|
|
287
|
+
await evaluate({ hasWork: true, genuineWork: false, errored: errored("a@x") }, null);
|
|
288
|
+
expect(lines.join("\n")).toContain("errored=[a@x] class=outage-report");
|
|
289
|
+
});
|
|
290
|
+
it("names the class on every readable fire", async () => {
|
|
291
|
+
await evaluate({ hasWork: true, genuineWork: false, errored: errored("a@x") }, ["a@x"]);
|
|
292
|
+
expect(lines.join("\n")).toContain("op=evaluated eventId=65ef758c plugin=scheduling tool=scheduling-gate " +
|
|
293
|
+
"hasWork=true genuineWork=false errored=[a@x] class=outage-suppressed");
|
|
294
|
+
});
|
|
295
|
+
it("never reports a suppressed class beside genuine work", async () => {
|
|
296
|
+
// Signature (a) of the task's observability section: the fail-loud
|
|
297
|
+
// regression. `class=outage-suppressed genuineWork=true` must not exist.
|
|
298
|
+
await evaluate({ hasWork: true, genuineWork: true, errored: errored("a@x") }, ["a@x"]);
|
|
299
|
+
await evaluate({ hasWork: true, genuineWork: false, errored: errored("a@x") }, ["a@x"]);
|
|
300
|
+
await evaluate({ hasWork: false, genuineWork: false, errored: [] }, null);
|
|
301
|
+
const classes = lines.filter((l) => l.includes("op=evaluated"));
|
|
302
|
+
expect(classes).toHaveLength(3);
|
|
303
|
+
expect(classes.some((l) => l.includes("class=outage-suppressed") && l.includes("genuineWork=true"))).toBe(false);
|
|
304
|
+
});
|
|
305
|
+
it("gateResult keeps the tool's own shape honest", () => {
|
|
306
|
+
// Guards the fixture above: if the real result stops carrying these fields,
|
|
307
|
+
// every case here would pass against a shape the gate no longer returns.
|
|
308
|
+
expect(gateResult({}).result.structuredContent).toMatchObject({
|
|
309
|
+
hasWork: true,
|
|
310
|
+
genuineWork: false,
|
|
311
|
+
errored: [],
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
});
|
|
227
315
|
//# sourceMappingURL=gate.test.js.map
|