@rubytech/create-realagent-code 0.1.581 → 0.1.583
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/platform/lib/routine-templates/dist/index.d.ts +1 -1
- package/payload/platform/lib/routine-templates/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/routine-templates/dist/index.js +5 -1
- package/payload/platform/lib/routine-templates/dist/index.js.map +1 -1
- package/payload/platform/lib/routine-templates/src/index.ts +4 -0
- package/payload/platform/lib/telegram-managed-bot/dist/index.d.ts +269 -0
- package/payload/platform/lib/telegram-managed-bot/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/telegram-managed-bot/dist/index.js +351 -0
- package/payload/platform/lib/telegram-managed-bot/dist/index.js.map +1 -0
- package/payload/platform/lib/telegram-managed-bot/src/__tests__/managed-bot.test.ts +251 -0
- package/payload/platform/lib/telegram-managed-bot/src/index.ts +529 -0
- package/payload/platform/lib/telegram-managed-bot/tsconfig.json +9 -0
- package/payload/platform/lib/telegram-managed-bot/vitest.config.ts +9 -0
- package/payload/platform/lib/telegram-reach/dist/index.d.ts +80 -0
- package/payload/platform/lib/telegram-reach/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/telegram-reach/dist/index.js +211 -0
- package/payload/platform/lib/telegram-reach/dist/index.js.map +1 -0
- package/payload/platform/lib/telegram-reach/src/__tests__/telegram-reach.test.ts +216 -0
- package/payload/platform/lib/telegram-reach/src/index.ts +262 -0
- package/payload/platform/lib/telegram-reach/tsconfig.json +9 -0
- package/payload/platform/lib/telegram-reach/vitest.config.ts +9 -0
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/admin/PLUGIN.md +1 -1
- package/payload/platform/plugins/admin/hooks/__tests__/fs-schema-guard.test.sh +9 -0
- package/payload/platform/plugins/admin/hooks/__tests__/preference-consult-directive.test.sh +26 -0
- package/payload/platform/plugins/admin/hooks/fs-schema-guard.sh +20 -3
- package/payload/platform/plugins/admin/hooks/preference-consult-directive.sh +50 -5
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +181 -9
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +17 -0
- package/payload/platform/plugins/contacts/mcp/dist/__tests__/telegram-user-id.test.d.ts +2 -0
- package/payload/platform/plugins/contacts/mcp/dist/__tests__/telegram-user-id.test.d.ts.map +1 -0
- package/payload/platform/plugins/contacts/mcp/dist/__tests__/telegram-user-id.test.js +100 -0
- package/payload/platform/plugins/contacts/mcp/dist/__tests__/telegram-user-id.test.js.map +1 -0
- package/payload/platform/plugins/contacts/mcp/dist/index.js +11 -5
- package/payload/platform/plugins/contacts/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.d.ts +5 -0
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.d.ts.map +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.js +21 -4
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.js.map +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.d.ts +5 -0
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.d.ts.map +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.js +29 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.js.map +1 -1
- package/payload/platform/plugins/contacts/mcp/vitest.config.ts +14 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +20 -4
- package/payload/platform/plugins/docs/references/calendar-booking.md +2 -0
- package/payload/platform/plugins/docs/references/channel-wake-and-prompt.md +15 -0
- package/payload/platform/plugins/docs/references/telegram-guide.md +143 -4
- package/payload/platform/plugins/filesystem/PLUGIN.md +2 -2
- package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/account-schema.test.d.ts +2 -0
- package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/account-schema.test.d.ts.map +1 -0
- package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/account-schema.test.js +108 -0
- package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/account-schema.test.js.map +1 -0
- package/payload/platform/plugins/filesystem/mcp/dist/lib/account-schema.d.ts +17 -0
- package/payload/platform/plugins/filesystem/mcp/dist/lib/account-schema.d.ts.map +1 -0
- package/payload/platform/plugins/filesystem/mcp/dist/lib/account-schema.js +162 -0
- package/payload/platform/plugins/filesystem/mcp/dist/lib/account-schema.js.map +1 -0
- package/payload/platform/plugins/filesystem/mcp/dist/tools/__tests__/schema-fence.test.d.ts +2 -0
- package/payload/platform/plugins/filesystem/mcp/dist/tools/__tests__/schema-fence.test.d.ts.map +1 -0
- package/payload/platform/plugins/filesystem/mcp/dist/tools/__tests__/schema-fence.test.js +116 -0
- package/payload/platform/plugins/filesystem/mcp/dist/tools/__tests__/schema-fence.test.js.map +1 -0
- package/payload/platform/plugins/filesystem/mcp/dist/tools/file-edit.d.ts.map +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/tools/file-edit.js +9 -0
- package/payload/platform/plugins/filesystem/mcp/dist/tools/file-edit.js.map +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/tools/file-write.d.ts.map +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/tools/file-write.js +10 -0
- package/payload/platform/plugins/filesystem/mcp/dist/tools/file-write.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/label-origin-gate.test.js +64 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/label-origin-gate.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/label-origin-gate.d.ts +5 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/label-origin-gate.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/label-origin-gate.js +28 -6
- package/payload/platform/plugins/memory/mcp/dist/lib/label-origin-gate.js.map +1 -1
- package/payload/platform/plugins/memory/references/schema-knowledge-work.md +1 -1
- package/payload/platform/plugins/scheduling/PLUGIN.md +19 -3
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +7 -2
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js +53 -6
- 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 +38 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-uid-stamp.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-uid-stamp.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-uid-stamp.test.js +102 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-uid-stamp.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-audit.test.js +43 -9
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-audit.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +50 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +47 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts +5 -3
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js +18 -3
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts +40 -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 +132 -41
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +14 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +61 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js +258 -8
- 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__/schedule-trash-filter.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-trash-filter.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-trash-filter.test.js +67 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-trash-filter.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js +206 -3
- 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-cancel.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js +8 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +29 -21
- 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 +94 -14
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.js +6 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.js +7 -2
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.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 +46 -3
- 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 +30 -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 +69 -6
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -1
- package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +12 -0
- package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts +36 -5
- package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js +103 -10
- package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +2 -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/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +42 -4
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -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 +19 -5
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +9 -0
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +5 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
- package/payload/platform/services/telegram-channel/dist/instructions.d.ts.map +1 -1
- package/payload/platform/services/telegram-channel/dist/instructions.js +13 -0
- package/payload/platform/services/telegram-channel/dist/instructions.js.map +1 -1
- package/payload/platform/services/telegram-channel/dist/notification.d.ts +40 -0
- package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/telegram-channel/dist/notification.js +41 -4
- package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +52 -0
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js +64 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/server.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/server.js +14 -2
- package/payload/platform/services/whatsapp-channel/dist/server.js.map +1 -1
- package/payload/platform/templates/account-schema/SCHEMA.md +17 -10
- package/payload/platform/templates/agents/admin/IDENTITY.md +5 -0
- package/payload/platform/templates/specialists/agents/data-manager.md +2 -2
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/server/{chunk-BFRB2U75.js → chunk-CV6AEMKH.js} +1 -0
- package/payload/server/{manager-CTVTF4YB.js → manager-FQSQSSJ3.js} +1 -1
- package/payload/server/public/activity.html +6 -6
- package/payload/server/public/agents.html +5 -5
- package/payload/server/public/assets/{AdminLoginScreens-B1lu4-_F.js → AdminLoginScreens-BLsDYWVi.js} +1 -1
- package/payload/server/public/assets/AdminLoginScreens-BLsDYWVi.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-BLsDYWVi.js.gz +0 -0
- package/payload/server/public/assets/{AdminShell-BMslfZxN.js → AdminShell-BZS8jzFA.js} +1 -1
- package/payload/server/public/assets/AdminShell-BZS8jzFA.js.br +0 -0
- package/payload/server/public/assets/AdminShell-BZS8jzFA.js.gz +0 -0
- package/payload/server/public/assets/{activity-kQ3w70LJ.js → activity-DOjvoLdd.js} +1 -1
- package/payload/server/public/assets/activity-DOjvoLdd.js.br +0 -0
- package/payload/server/public/assets/activity-DOjvoLdd.js.gz +0 -0
- package/payload/server/public/assets/{admin-CkASgYA7.js → admin-JrSNg29g.js} +1 -1
- package/payload/server/public/assets/admin-JrSNg29g.js.br +0 -0
- package/payload/server/public/assets/admin-JrSNg29g.js.gz +0 -0
- package/payload/server/public/assets/{agents-Cn_bZgnD.js → agents--9WMJVLC.js} +1 -1
- package/payload/server/public/assets/agents--9WMJVLC.js.br +0 -0
- package/payload/server/public/assets/agents--9WMJVLC.js.gz +0 -0
- package/payload/server/public/assets/{browser-BE-GDk5-.js → browser-DiiMmTrM.js} +1 -1
- package/payload/server/public/assets/browser-DiiMmTrM.js.br +0 -0
- package/payload/server/public/assets/browser-DiiMmTrM.js.gz +0 -0
- package/payload/server/public/assets/{calendar-Di7BEHHN.js → calendar-CazmCzgO.js} +1 -1
- package/payload/server/public/assets/calendar-CazmCzgO.js.br +0 -0
- package/payload/server/public/assets/calendar-CazmCzgO.js.gz +0 -0
- package/payload/server/public/assets/chat-CB0TcyXX.js +1 -0
- package/payload/server/public/assets/chat-CB0TcyXX.js.br +0 -0
- package/payload/server/public/assets/chat-CB0TcyXX.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-0tVo23Dh.js +1 -0
- package/payload/server/public/assets/chevron-left-0tVo23Dh.js.br +0 -0
- package/payload/server/public/assets/clock-D2cZ0sge.js +1 -0
- package/payload/server/public/assets/clock-D2cZ0sge.js.br +0 -0
- package/payload/server/public/assets/clock-D2cZ0sge.js.gz +0 -0
- package/payload/server/public/assets/{copy-nkxspu2J.js → copy-C87QIN_o.js} +1 -1
- package/payload/server/public/assets/copy-C87QIN_o.js.br +0 -0
- package/payload/server/public/assets/copy-C87QIN_o.js.gz +0 -0
- package/payload/server/public/assets/data-CK7AMxPt.js +1 -0
- package/payload/server/public/assets/data-CK7AMxPt.js.br +0 -0
- package/payload/server/public/assets/data-CK7AMxPt.js.gz +0 -0
- package/payload/server/public/assets/{field-2rIXxGMt.js → field-C3kQgGWE.js} +1 -1
- package/payload/server/public/assets/field-C3kQgGWE.js.br +0 -0
- package/payload/server/public/assets/field-C3kQgGWE.js.gz +0 -0
- package/payload/server/public/assets/{file-text-CdSqrscg.js → file-text-rWowl9RN.js} +1 -1
- package/payload/server/public/assets/file-text-rWowl9RN.js.br +0 -0
- package/payload/server/public/assets/file-text-rWowl9RN.js.gz +0 -0
- package/payload/server/public/assets/{graph-BfBHHXaC.js → graph-CVJKz1Uo.js} +1 -1
- package/payload/server/public/assets/graph-CVJKz1Uo.js.br +0 -0
- package/payload/server/public/assets/graph-CVJKz1Uo.js.gz +0 -0
- package/payload/server/public/assets/{graph-labels-CHW2aBke.js → graph-labels-kneGnsHB.js} +1 -1
- package/payload/server/public/assets/graph-labels-kneGnsHB.js.br +0 -0
- package/payload/server/public/assets/graph-labels-kneGnsHB.js.gz +0 -0
- package/payload/server/public/assets/{jsx-runtime-D43jgaWP.css → jsx-runtime-rMaiYjNu.css} +1 -1
- package/payload/server/public/assets/jsx-runtime-rMaiYjNu.css.br +0 -0
- package/payload/server/public/assets/{jsx-runtime-D43jgaWP.css.gz → jsx-runtime-rMaiYjNu.css.gz} +0 -0
- package/payload/server/public/assets/{operator-DRn9LITC.js → operator-BGvB4hu4.js} +1 -1
- package/payload/server/public/assets/operator-BGvB4hu4.js.br +0 -0
- package/payload/server/public/assets/operator-BGvB4hu4.js.gz +0 -0
- package/payload/server/public/assets/{page-D_9mPS6W.js → page-DBQLOasI.js} +1 -1
- package/payload/server/public/assets/page-DBQLOasI.js.br +0 -0
- package/payload/server/public/assets/page-DBQLOasI.js.gz +0 -0
- package/payload/server/public/assets/{page-BwqQsoU8.js → page-DyVAu7tm.js} +1 -1
- package/payload/server/public/assets/page-DyVAu7tm.js.br +0 -0
- package/payload/server/public/assets/page-DyVAu7tm.js.gz +0 -0
- package/payload/server/public/assets/play-DgP7vl0r.js +1 -0
- package/payload/server/public/assets/play-DgP7vl0r.js.br +0 -0
- package/payload/server/public/assets/play-DgP7vl0r.js.gz +0 -0
- package/payload/server/public/assets/{public-CrjZYpdW.js → public-BvUQR3hd.js} +1 -1
- package/payload/server/public/assets/public-BvUQR3hd.js.br +0 -0
- package/payload/server/public/assets/public-BvUQR3hd.js.gz +0 -0
- package/payload/server/public/assets/{rotate-ccw-J9f-GWjm.js → rotate-ccw-Dnn7gbPh.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-Dnn7gbPh.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-Dnn7gbPh.js.gz +0 -0
- package/payload/server/public/assets/{routines-C1AB-3FR.js → routines-N8NmxPOZ.js} +1 -1
- package/payload/server/public/assets/routines-N8NmxPOZ.js.br +0 -0
- package/payload/server/public/assets/routines-N8NmxPOZ.js.gz +0 -0
- package/payload/server/public/assets/{skills-C4EfNKEx.js → skills-B2CRgO-U.js} +1 -1
- package/payload/server/public/assets/skills-B2CRgO-U.js.br +0 -0
- package/payload/server/public/assets/skills-B2CRgO-U.js.gz +0 -0
- package/payload/server/public/assets/{tasks-DszD3aZl.js → tasks-8QLGtlSj.js} +1 -1
- package/payload/server/public/assets/tasks-8QLGtlSj.js.br +0 -0
- package/payload/server/public/assets/tasks-8QLGtlSj.js.gz +0 -0
- package/payload/server/public/assets/{triangle-alert-B5WAyAkC.js → triangle-alert-el772yUQ.js} +1 -1
- package/payload/server/public/assets/triangle-alert-el772yUQ.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-el772yUQ.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-B2nuNNJw.js → useCopyFeedback-DfNAu8hQ.js} +1 -1
- package/payload/server/public/assets/useCopyFeedback-DfNAu8hQ.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-DfNAu8hQ.js.gz +0 -0
- package/payload/server/public/assets/{useMediaQuery-DUPJPHQt.js → useMediaQuery-B469O83-.js} +1 -1
- package/payload/server/public/assets/useMediaQuery-B469O83-.js.br +0 -0
- package/payload/server/public/assets/useMediaQuery-B469O83-.js.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-Bb-51cJv.js +2 -0
- package/payload/server/public/assets/useVoiceRecorder-Bb-51cJv.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-Bb-51cJv.js.gz +0 -0
- package/payload/server/public/assets/{wrench-DZJZm17j.js → wrench-Ck4phkdB.js} +1 -1
- package/payload/server/public/assets/wrench-Ck4phkdB.js.br +0 -0
- package/payload/server/public/assets/wrench-Ck4phkdB.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 +3777 -1258
- package/payload/server/public/assets/AdminLoginScreens-B1lu4-_F.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-B1lu4-_F.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-BMslfZxN.js.br +0 -0
- package/payload/server/public/assets/AdminShell-BMslfZxN.js.gz +0 -0
- package/payload/server/public/assets/activity-kQ3w70LJ.js.br +0 -0
- package/payload/server/public/assets/activity-kQ3w70LJ.js.gz +0 -0
- package/payload/server/public/assets/admin-CkASgYA7.js.br +0 -0
- package/payload/server/public/assets/admin-CkASgYA7.js.gz +0 -0
- package/payload/server/public/assets/agents-Cn_bZgnD.js.br +0 -0
- package/payload/server/public/assets/agents-Cn_bZgnD.js.gz +0 -0
- package/payload/server/public/assets/browser-BE-GDk5-.js.br +0 -0
- package/payload/server/public/assets/browser-BE-GDk5-.js.gz +0 -0
- package/payload/server/public/assets/calendar-Di7BEHHN.js.br +0 -0
- package/payload/server/public/assets/calendar-Di7BEHHN.js.gz +0 -0
- package/payload/server/public/assets/chat-CKyMT5Ai.js +0 -1
- package/payload/server/public/assets/chat-CKyMT5Ai.js.br +0 -1
- package/payload/server/public/assets/chat-CKyMT5Ai.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-Id9VAZAz.js +0 -1
- package/payload/server/public/assets/chevron-left-Id9VAZAz.js.br +0 -0
- package/payload/server/public/assets/clock-DKpWWJbJ.js +0 -1
- package/payload/server/public/assets/clock-DKpWWJbJ.js.br +0 -0
- package/payload/server/public/assets/copy-nkxspu2J.js.br +0 -0
- package/payload/server/public/assets/copy-nkxspu2J.js.gz +0 -0
- package/payload/server/public/assets/data-1c33cAHp.js +0 -1
- package/payload/server/public/assets/data-1c33cAHp.js.br +0 -2
- package/payload/server/public/assets/data-1c33cAHp.js.gz +0 -0
- package/payload/server/public/assets/field-2rIXxGMt.js.br +0 -0
- package/payload/server/public/assets/field-2rIXxGMt.js.gz +0 -0
- package/payload/server/public/assets/file-text-CdSqrscg.js.br +0 -0
- package/payload/server/public/assets/file-text-CdSqrscg.js.gz +0 -0
- package/payload/server/public/assets/graph-BfBHHXaC.js.br +0 -0
- package/payload/server/public/assets/graph-BfBHHXaC.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-CHW2aBke.js.br +0 -0
- package/payload/server/public/assets/graph-labels-CHW2aBke.js.gz +0 -0
- package/payload/server/public/assets/jsx-runtime-D43jgaWP.css.br +0 -0
- package/payload/server/public/assets/operator-DRn9LITC.js.br +0 -0
- package/payload/server/public/assets/operator-DRn9LITC.js.gz +0 -0
- package/payload/server/public/assets/page-BwqQsoU8.js.br +0 -0
- package/payload/server/public/assets/page-BwqQsoU8.js.gz +0 -0
- package/payload/server/public/assets/page-D_9mPS6W.js.br +0 -0
- package/payload/server/public/assets/page-D_9mPS6W.js.gz +0 -0
- package/payload/server/public/assets/play-7LTxCuLX.js +0 -1
- package/payload/server/public/assets/play-7LTxCuLX.js.br +0 -0
- package/payload/server/public/assets/play-7LTxCuLX.js.gz +0 -0
- package/payload/server/public/assets/public-CrjZYpdW.js.br +0 -0
- package/payload/server/public/assets/public-CrjZYpdW.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-J9f-GWjm.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-J9f-GWjm.js.gz +0 -0
- package/payload/server/public/assets/routines-C1AB-3FR.js.br +0 -0
- package/payload/server/public/assets/routines-C1AB-3FR.js.gz +0 -0
- package/payload/server/public/assets/skills-C4EfNKEx.js.br +0 -0
- package/payload/server/public/assets/skills-C4EfNKEx.js.gz +0 -0
- package/payload/server/public/assets/tasks-DszD3aZl.js.br +0 -0
- package/payload/server/public/assets/tasks-DszD3aZl.js.gz +0 -0
- package/payload/server/public/assets/triangle-alert-B5WAyAkC.js.br +0 -4
- package/payload/server/public/assets/triangle-alert-B5WAyAkC.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-B2nuNNJw.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-B2nuNNJw.js.gz +0 -0
- package/payload/server/public/assets/useMediaQuery-DUPJPHQt.js.br +0 -0
- package/payload/server/public/assets/useMediaQuery-DUPJPHQt.js.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-CCK60d2i.js +0 -2
- package/payload/server/public/assets/useVoiceRecorder-CCK60d2i.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-CCK60d2i.js.gz +0 -0
- package/payload/server/public/assets/wrench-DZJZm17j.js.br +0 -0
- package/payload/server/public/assets/wrench-DZJZm17j.js.gz +0 -0
- /package/payload/server/public/assets/{jsx-runtime-Cjug_Cyb.js → jsx-runtime-BmNepPEn.js} +0 -0
- /package/payload/server/public/assets/{jsx-runtime-Cjug_Cyb.js.br → jsx-runtime-BmNepPEn.js.br} +0 -0
- /package/payload/server/public/assets/{jsx-runtime-Cjug_Cyb.js.gz → jsx-runtime-BmNepPEn.js.gz} +0 -0
|
@@ -21,7 +21,7 @@ async function computeEmbedding(text) {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
export async function contactCreate(params) {
|
|
24
|
-
const { givenName, familyName, email, telephone, jobTitle, source, status = "prospect", accountId, relationships, createdBy, } = params;
|
|
24
|
+
const { givenName, familyName, email, telephone, telegramUserId, jobTitle, source, status = "prospect", accountId, relationships, createdBy, } = params;
|
|
25
25
|
const normalizedEmail = email?.toLowerCase().trim();
|
|
26
26
|
const normalizedPhone = telephone?.trim();
|
|
27
27
|
const session = getSession();
|
|
@@ -40,6 +40,10 @@ export async function contactCreate(params) {
|
|
|
40
40
|
dedupConditions.push("p.telephone = $telephone");
|
|
41
41
|
dedupParams.telephone = normalizedPhone;
|
|
42
42
|
}
|
|
43
|
+
if (telegramUserId !== undefined) {
|
|
44
|
+
dedupConditions.push("p.telegramUserId = $telegramUserId");
|
|
45
|
+
dedupParams.telegramUserId = telegramUserId;
|
|
46
|
+
}
|
|
43
47
|
if (dedupConditions.length > 0) {
|
|
44
48
|
// Trashed persons already have null email/telephone
|
|
45
49
|
// (UNIQUE_KEYS_BY_LABEL snapshot), so OR-matching by those keys would
|
|
@@ -47,11 +51,19 @@ export async function contactCreate(params) {
|
|
|
47
51
|
// legacy deletedAt soft-delete state.
|
|
48
52
|
const existing = await session.run(`MATCH (p:Person {accountId: $accountId})
|
|
49
53
|
WHERE (${dedupConditions.join(" OR ")}) AND ${notTrashed("p")}
|
|
50
|
-
RETURN elementId(p) AS nodeId, p.email AS email, p.telephone AS telephone
|
|
54
|
+
RETURN elementId(p) AS nodeId, p.email AS email, p.telephone AS telephone,
|
|
55
|
+
p.telegramUserId AS telegramUserId`, dedupParams);
|
|
51
56
|
if (existing.records.length > 0) {
|
|
52
57
|
const matchedEmail = existing.records[0].get("email");
|
|
53
58
|
const matchedPhone = existing.records[0].get("telephone");
|
|
54
|
-
|
|
59
|
+
// A telegram-only match has neither of the other two, and reporting it
|
|
60
|
+
// as "unknown" would tell the caller nothing about who it just found.
|
|
61
|
+
const matchedTelegram = existing.records[0].get("telegramUserId");
|
|
62
|
+
const matchedIdentifier = matchedEmail ??
|
|
63
|
+
matchedPhone ??
|
|
64
|
+
(matchedTelegram === null || matchedTelegram === undefined
|
|
65
|
+
? "unknown"
|
|
66
|
+
: String(matchedTelegram));
|
|
55
67
|
return {
|
|
56
68
|
nodeId: existing.records[0].get("nodeId"),
|
|
57
69
|
identifier: matchedIdentifier,
|
|
@@ -72,6 +84,8 @@ export async function contactCreate(params) {
|
|
|
72
84
|
props.email = normalizedEmail;
|
|
73
85
|
if (normalizedPhone)
|
|
74
86
|
props.telephone = normalizedPhone;
|
|
87
|
+
if (telegramUserId !== undefined)
|
|
88
|
+
props.telegramUserId = telegramUserId;
|
|
75
89
|
if (familyName)
|
|
76
90
|
props.familyName = familyName;
|
|
77
91
|
if (jobTitle)
|
|
@@ -108,7 +122,10 @@ export async function contactCreate(params) {
|
|
|
108
122
|
createdBy,
|
|
109
123
|
});
|
|
110
124
|
const nameIdentifier = [givenName, familyName].filter(Boolean).join(" ");
|
|
111
|
-
const primaryIdentifier = normalizedEmail ??
|
|
125
|
+
const primaryIdentifier = normalizedEmail ??
|
|
126
|
+
normalizedPhone ??
|
|
127
|
+
(telegramUserId === undefined ? undefined : String(telegramUserId)) ??
|
|
128
|
+
(nameIdentifier || "unknown");
|
|
112
129
|
return {
|
|
113
130
|
nodeId: result.nodeId,
|
|
114
131
|
identifier: primaryIdentifier,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contact-create.js","sourceRoot":"","sources":["../../src/tools/contact-create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAC1E,OAAO,EACL,kBAAkB,EAClB,4BAA4B,GAG7B,MAAM,8CAA8C,CAAC;AAEtD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,wBAAwB,CAAC;AACtE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,kBAAkB,CAAC;AAElE,KAAK,UAAU,gBAAgB,CAAC,IAAY;IAC1C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,YAAY,EAAE;YACjD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;SAC1D,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA+B,CAAC;QAC9D,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;QACzE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;
|
|
1
|
+
{"version":3,"file":"contact-create.js","sourceRoot":"","sources":["../../src/tools/contact-create.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
interface ContactLookupParams {
|
|
2
2
|
email?: string;
|
|
3
3
|
telephone?: string;
|
|
4
|
+
/** Task 2625 — the person's numeric Telegram user id. Tried after email and
|
|
5
|
+
* telephone and before name, matching the identifier priority everywhere else
|
|
6
|
+
* in this plugin: an exact key beats a substring search. */
|
|
7
|
+
telegramUserId?: number;
|
|
4
8
|
name?: string;
|
|
5
9
|
accountId?: string;
|
|
6
10
|
limit?: number;
|
|
@@ -19,6 +23,7 @@ export interface ContactRecord {
|
|
|
19
23
|
familyName?: string;
|
|
20
24
|
email?: string;
|
|
21
25
|
telephone?: string;
|
|
26
|
+
telegramUserId?: number;
|
|
22
27
|
jobTitle?: string;
|
|
23
28
|
source: string;
|
|
24
29
|
status: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contact-lookup.d.ts","sourceRoot":"","sources":["../../src/tools/contact-lookup.ts"],"names":[],"mappings":"AAIA,UAAU,mBAAmB;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAOD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,WAAW,EAAE,gBAAgB,EAAE,CAAC;CACjC;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,aAAa,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"contact-lookup.d.ts","sourceRoot":"","sources":["../../src/tools/contact-lookup.ts"],"names":[],"mappings":"AAIA,UAAU,mBAAmB;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;iEAE6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAOD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,WAAW,EAAE,gBAAgB,EAAE,CAAC;CACjC;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,aAAa,EAAE,CAAC,CAoH1B;AAUD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,MAAM,CA0BrE"}
|
|
@@ -10,11 +10,16 @@ export function normalizeNameQuery(name) {
|
|
|
10
10
|
return name.trim().replace(/\s+/g, " ");
|
|
11
11
|
}
|
|
12
12
|
export async function contactLookup(params) {
|
|
13
|
-
const { email, telephone, name, accountId, limit = 10 } = params;
|
|
13
|
+
const { email, telephone, telegramUserId, name, accountId, limit = 10 } = params;
|
|
14
14
|
const session = getSession();
|
|
15
15
|
try {
|
|
16
16
|
let query;
|
|
17
17
|
let queryParams;
|
|
18
|
+
// Set ONLY by the branch below that actually matches on the id. A caller
|
|
19
|
+
// that passes both an email and a telegramUserId takes the email branch, and
|
|
20
|
+
// logging a hit for a key the query never touched would report the
|
|
21
|
+
// telegramUserId path as working on the day it stopped.
|
|
22
|
+
let matchedOnTelegramUserId = false;
|
|
18
23
|
const trashFilter = notTrashed("p");
|
|
19
24
|
const prefFilter = `${notTrashed("pref")} AND coalesce(pref.notApplicable, false) = false`;
|
|
20
25
|
if (email) {
|
|
@@ -41,6 +46,19 @@ export async function contactLookup(params) {
|
|
|
41
46
|
`;
|
|
42
47
|
queryParams = { telephone: telephone.trim(), accountId, limit: neo4j.int(limit) };
|
|
43
48
|
}
|
|
49
|
+
else if (telegramUserId !== undefined) {
|
|
50
|
+
query = `
|
|
51
|
+
MATCH (p:Person {accountId: $accountId})
|
|
52
|
+
WHERE p.telegramUserId = $telegramUserId AND ${trashFilter}
|
|
53
|
+
WITH p, elementId(p) AS nodeId
|
|
54
|
+
LIMIT $limit
|
|
55
|
+
OPTIONAL MATCH (p)-[:HAS_PREFERENCE]->(pref:Preference)
|
|
56
|
+
WHERE ${prefFilter}
|
|
57
|
+
RETURN p, nodeId, collect(pref) AS prefs
|
|
58
|
+
`;
|
|
59
|
+
queryParams = { telegramUserId, accountId, limit: neo4j.int(limit) };
|
|
60
|
+
matchedOnTelegramUserId = true;
|
|
61
|
+
}
|
|
44
62
|
else if (name) {
|
|
45
63
|
query = `
|
|
46
64
|
MATCH (p:Person {accountId: $accountId})
|
|
@@ -68,6 +86,15 @@ export async function contactLookup(params) {
|
|
|
68
86
|
queryParams = { accountId, limit: neo4j.int(limit) };
|
|
69
87
|
}
|
|
70
88
|
const result = await session.run(query, queryParams);
|
|
89
|
+
// Task 2625 — a write with no read is the failure this line catches: an id
|
|
90
|
+
// stored on every Telegram contact and never matched means the lookup branch
|
|
91
|
+
// is missing or the property name drifted, and neither of those throws.
|
|
92
|
+
// Emitted only when the query actually matched on the id, so neither a
|
|
93
|
+
// lookup by email nor one that merely carried the field can dilute the hit
|
|
94
|
+
// rate this is read as.
|
|
95
|
+
if (matchedOnTelegramUserId) {
|
|
96
|
+
console.error(`[contacts] op=lookup key=telegramUserId hit=${result.records.length > 0}`);
|
|
97
|
+
}
|
|
71
98
|
return result.records.map((record) => {
|
|
72
99
|
const p = record.get("p").properties;
|
|
73
100
|
const prefNodes = record.get("prefs") ?? [];
|
|
@@ -84,6 +111,7 @@ export async function contactLookup(params) {
|
|
|
84
111
|
familyName: p.familyName,
|
|
85
112
|
email: p.email,
|
|
86
113
|
telephone: p.telephone,
|
|
114
|
+
telegramUserId: p.telegramUserId,
|
|
87
115
|
jobTitle: p.jobTitle,
|
|
88
116
|
source: p.source,
|
|
89
117
|
status: p.status,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contact-lookup.js","sourceRoot":"","sources":["../../src/tools/contact-lookup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;
|
|
1
|
+
{"version":3,"file":"contact-lookup.js","sourceRoot":"","sources":["../../src/tools/contact-lookup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineConfig } from "vitest/config";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
environment: "node",
|
|
6
|
+
// Scoped to src, matching plugins/telegram/mcp: without it vitest also
|
|
7
|
+
// collects dist/__tests__/*.test.js, which `tsc -p` emits because this
|
|
8
|
+
// plugin's tsconfig includes src/__tests__. Every test would then run twice,
|
|
9
|
+
// and a stale compiled copy can pass while the source it was built from
|
|
10
|
+
// fails.
|
|
11
|
+
include: ["src/**/__tests__/**/*.test.ts"],
|
|
12
|
+
testTimeout: 10_000,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -85,7 +85,9 @@ either is a regression.
|
|
|
85
85
|
|
|
86
86
|
**WhatsApp reader is read/write (WhatsApp-Web surface).** A WhatsApp store conversation in the operator Conversations reader (`OperatorConversations`) and the admin root channel viewer (`app/page.tsx`) no longer opens the plain read-only DM chrome — it opens `app/whatsapp/WhatsappWebConversation.tsx`, a WhatsApp-Web-styled surface: a conversation header, the delivered-only store transcript reskinned green/white under a `.wa-web` root class, and a reply composer (`app/whatsapp/ReplyComposer.tsx`). The operator can type text, insert emoji (a codepoint-data picker — no OS input, so the `check-no-emoji-in-jsx` gate stays green), record a voice note (MediaRecorder → the existing audio send path), attach a file **from device storage** (a modal browsing the DATA_ROOT tree via `GET /api/admin/files`, sent by reference — the OS file dialog is no longer the reader's picker), reply to a specific message (a per-bubble affordance that quotes the original in the composer and threads natively on WhatsApp), and search the loaded transcript (a header control that filters to matching turns and highlights the match). The header carries only that Search control — the former Video / Phone / menu icons are gone, because no call or presence data exists behind them. Sent files honour the webchat allowlist (`SUPPORTED_MIME_SET` / 50 MB / 5 files); a device-file reference is authorised server-side (`authorizeReplyFileRef`) against the send's own account (the conversation owner) **or** the session's pinned account (`getAccountIdForSession` — the exact scope the DeviceFilePicker used to offer it), so a house/managing-admin session can attach a managed-client file the picker listed. Because a reply sends bytes OUT to an external WhatsApp recipient, any other account, a `public` partition, and any install-wide / non-account path are refused fail-closed; the cross-account admission's authority is the session's pinned account, never the caller-supplied body `accountId` (the own-account admission matches the body `accountId`, which the route already trusts via `isValidAccountId` and the existing-conversation guard). A scope refusal returns a distinct HTTP 403 reason (`file-ref-cross-account` / `file-ref-public` / `file-ref-foreign`) and copy, never "device file not found" (reserved for a genuine resolve/stat miss). Per-ref `[wa-manual-send] op=reply-file-ref … via=own|session|deny reason=<…> ok=<bool>` logs the decision before any send; `via=deny ok=true` is the exfiltration signature that must never appear. **Send is reply-only and DM-only:** `POST /api/whatsapp-reader/reply` (`requireAdminSession`) refuses any target with no existing stored conversation (`reason=no-existing-conversation`, HTTP 403) — a cold first-contact send bans the account, so the composer is never a cold-contact path, enforced server-side — and refuses `@g.us` groups (`reason=group-send-blocked`), matching the agent's observe-only group invariant; a group thread shows a read-only note in place of the composer. The endpoint is the sole store writer for a manual send: right after each send resolves it appends the record itself, stamped `origin:'operator-manual'` (attributed "You", distinct from an assistant reply), because the Baileys echo that normally persists the store is gated on message text (`manager.ts:906`) and would leave an uncaptioned media send delivered-but-invisible. The record's `messageId` matches the echo's derivation so the async text echo's own persist dedups to a no-op; the send is confirmed by re-read (`op=recorded present=<bool>`). A sent send does not spawn an assistant turn (echo dispatch stays suppressed). Attachments deliver as WhatsApp media/documents and render **inline** in the store reader (image thumbnail / pdf preview / audio player / download chip), because the manual-send path records the message with the servable `attachmentId`. The `.wa-web` skin is scoped to WhatsApp store threads only, so `/chat`, the admin agent session view, and the public visitor webchat are unchanged; the visitor webchat gains no send capability. The in-bubble delivered-tick is cosmetic (no read-receipt data is stored); inbound bubbles keep their sender name so group threads stay attributable, and both directions carry a WhatsApp callout tail (`.wa-web`-scoped only). Non-WhatsApp reader rows (Telegram/webchat session JSONLs) keep the plain read-only `Transcript`. Observability rides `[wa-manual-send]` lines correlated by a per-request `sendId`. **Composer sizing matches the webchat composer:** the reply textarea auto-grows to fit multi-line content (measured from `scrollHeight`, clamped to a one-row minimum and a `viewport/3` maximum, scrollable past the cap with the scrollbar hidden), and a top-border grab handle drags (pointer) or nudges (ArrowUp/ArrowDown, keyboard-focusable) to an explicit height in the same clamp; a manual drag pins the height and overrides auto-grow until the field is cleared, which releases it back to auto-grow. A completed manual resize logs `[operator-ui] op=wa-composer-resize mode=drag|key h=<px>`; a bare click on the handle (no drag) logs nothing.
|
|
87
87
|
|
|
88
|
-
**Shared locations show a map.** When someone shares a location on WhatsApp, the conversation shows a small map with a pin on the spot, above the coordinates themselves.
|
|
88
|
+
**Shared locations show a map.** When someone shares a location on WhatsApp, the conversation shows a small map with a pin on the spot, above the coordinates themselves. A location shared as a place name with no coordinates shows the name only, because there is no point to put a pin on. The map images are fetched by your browser from OpenStreetMap, so the shared coordinates reach that service when a location bubble is on screen.
|
|
89
|
+
|
|
90
|
+
**Selecting a map opens one you can move around.** The small map opens a larger one over the conversation: drag to move it, scroll or pinch to zoom in and out, double-click to zoom in, and press Escape or select the backdrop to close it. On a phone it fills the screen. A link at the bottom still opens the same spot on OpenStreetMap in a new tab if you want it there. Someone sharing their live location keeps arriving as they move, and the open map keeps centring on where they are now until you move it yourself; from then on your own view stays put while the trail keeps growing, and a **Follow** button brings it back to following them.
|
|
89
91
|
|
|
90
92
|
**`/chat` live activity line.** While a turn is in flight the transcript tail shows one ephemeral `ChatActivity` line (mounted only while `busy`, admin/operator only). It tracks real activity, not a timer: while a `Task` subagent runs it shows that subagent's headline (`agentType · description`, prefixed `N agents ·` when ≥2 are concurrent), sourced from `agent-<hex>.meta.json` via named `activity` SSE events the admin reader pushes from the session's `subagents/` dir; with no subagent active it shows a neutral word that advances only on a real turn arrival. The line carries a turn-elapsed clock and flips to a `stalled` state once nothing has been written for 5 minutes (`now − lastEmitAt`), so the operator can tell a wedge from progress without SSH. It is never added to the persisted timeline. Detail and the `[webchat-activity]` observability live in [`admin-webchat-native-channel.md`](../../../.docs/admin-webchat-native-channel.md).
|
|
91
93
|
|
|
@@ -803,17 +805,31 @@ another account's directory, for every session including a house-scoped one, and
|
|
|
803
805
|
the Bash snapshot pair watches the account's own layout. All of them live in the
|
|
804
806
|
account's `.claude/settings.json`, and a hook that is not registered there runs
|
|
805
807
|
never and emits nothing, so the silence reads identical to a clean account. The
|
|
806
|
-
same pass therefore checks the
|
|
808
|
+
same pass therefore checks the six registrations per account and reports any
|
|
807
809
|
absence as
|
|
808
810
|
`[fs-reconcile] op=hook-registration account=<id8> missing=<matcher>:<hook>,…`,
|
|
809
811
|
with `hooks-missing=0 hooks-unaudited=0` on the summary line as the per-cycle
|
|
810
812
|
proof the fence is wired everywhere. An account whose settings cannot be read
|
|
811
813
|
counts as unaudited rather than clean, so an install where none of them can be
|
|
812
|
-
read never reports itself as fenced. The
|
|
813
|
-
|
|
814
|
+
read never reports itself as fenced. The sixth row is the per-turn filing
|
|
815
|
+
directive, whose template entry carries no matcher at all, so that row is
|
|
816
|
+
reported by its event as `UserPromptSubmit:preference-consult-directive.sh`. The
|
|
817
|
+
refusal itself is agent-facing and lands in the session's own child log as
|
|
814
818
|
`[fs-guard] blocked path=<abs> reason=cross-account target=<id8>`, not in
|
|
815
819
|
`server.log`.
|
|
816
820
|
|
|
821
|
+
The same pass also emits
|
|
822
|
+
`[fs-reconcile] op=entity-subdirs account=<id8> entities=<n> archive=<m> stray=<s>`
|
|
823
|
+
for every account on every cycle, not only on drift: `archive/` is the one folder
|
|
824
|
+
permitted under an entity folder, a write that wrongly succeeds emits nothing,
|
|
825
|
+
and `stray` above zero is the only signature an over-wide rule leaves.
|
|
826
|
+
`entities` is on the same line because `stray=0` cannot otherwise be told from a
|
|
827
|
+
walker that read nothing. The `file-write` and `file-edit` tools carry the same
|
|
828
|
+
five-reason fence as the native route; their refusals log the same
|
|
829
|
+
`[fs-guard] blocked` line into `mcp-filesystem-<sessionId>.log`, the plugin
|
|
830
|
+
server's own tee sink, because `lib/mcp-spawn-tee` mirrors only its
|
|
831
|
+
`[mcp-helper]` lifecycle lines into `server.log`.
|
|
832
|
+
|
|
817
833
|
### Graph
|
|
818
834
|
|
|
819
835
|
| Mount | Purpose |
|
|
@@ -18,6 +18,8 @@ Click any entry to open its details, where you can also edit it: the full title,
|
|
|
18
18
|
|
|
19
19
|
Everything on the calendar comes from records the rest of Real Agent already uses, scoped to your account.
|
|
20
20
|
|
|
21
|
+
Two things about what Real Agent itself can see and change. A deleted entry no longer comes back when Real Agent lists your diary, so if you or Real Agent removed a duplicate, it stays removed. And every entry Real Agent can see, Real Agent can now also change or cancel. Before, some entries could be read and not touched, and Real Agent would say so rather than act. If you ask Real Agent to record something *about* a meeting rather than the meeting itself, it writes that as a note attached to the meeting.
|
|
22
|
+
|
|
21
23
|
## The public booking page
|
|
22
24
|
|
|
23
25
|
The booking page is a separate, public site on its own web address (for example `book.yourdomain.com`). A visitor sees only open time slots, never the titles or details of your existing meetings. They pick a slot, enter their name, email, and an optional note, and submit. That is the whole flow, like a simple Calendly.
|
|
@@ -111,6 +111,21 @@ for that door alone.
|
|
|
111
111
|
census prints every cycle, including when the counts agree: an absent line means
|
|
112
112
|
the census stopped, never that delivery is healthy.
|
|
113
113
|
|
|
114
|
+
## Which channels can start a conversation
|
|
115
|
+
|
|
116
|
+
Answering an inbound and starting a new conversation are different powers, and
|
|
117
|
+
only the first is available on every door.
|
|
118
|
+
|
|
119
|
+
| Channel | Can start a conversation with | Cannot |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| WhatsApp | a registered admin phone, a registered account manager, or a registered party, through `whatsapp-send-admin` | any other number. The cold-send tools were removed after one such send tripped WhatsApp's anti-automation enforcement and restricted the account, and no setting re-enables them. |
|
|
122
|
+
| Telegram | any chat that has already messaged the bot | a chat that has not. Telegram itself refuses it. |
|
|
123
|
+
| Email | any address, once a mailbox is attached | nothing, once a mailbox is attached |
|
|
124
|
+
| Admin webchat | nobody. It is a browser chat the operator opens | anything outbound |
|
|
125
|
+
|
|
126
|
+
The admin identity carries the same rule under its `## Channel reality` section,
|
|
127
|
+
so an agent that has loaded no plugin skill still knows it. The two must agree.
|
|
128
|
+
|
|
114
129
|
## Which door an answer reaches
|
|
115
130
|
|
|
116
131
|
The door the message arrived on, and no other. A question asked on WhatsApp is
|
|
@@ -10,6 +10,24 @@ The Telegram plugin connects {{productName}} to a Telegram bot. Once set up, you
|
|
|
10
10
|
|
|
11
11
|
## Setup
|
|
12
12
|
|
|
13
|
+
### Adding a second bot: no BotFather at all
|
|
14
|
+
|
|
15
|
+
Once you have one working admin bot, you never need BotFather again to add another. Tell
|
|
16
|
+
{{productName}}: "create a new Telegram bot." It sends you a single button. Tap it, give the bot a
|
|
17
|
+
name, and Telegram hands the bot straight to {{productName}} — it stores the credentials, locks the
|
|
18
|
+
bot so only you can reach it, and connects it. No token is shown to anyone and nothing is copied or
|
|
19
|
+
pasted.
|
|
20
|
+
|
|
21
|
+
One thing has to be switched on first, once per managing bot: open @BotFather, go to its Mini App,
|
|
22
|
+
select your admin bot and turn on management of other bots. {{productName}} checks this before
|
|
23
|
+
sending the button and tells you if it is missing, so you never end up with a button that does
|
|
24
|
+
nothing.
|
|
25
|
+
|
|
26
|
+
A bot made this way arrives switched off: it answers nobody until you tell {{productName}} which
|
|
27
|
+
assistant should run on it.
|
|
28
|
+
|
|
29
|
+
Your **first** bot still comes from BotFather, below, and so does any bot you already own.
|
|
30
|
+
|
|
13
31
|
### Step 1: Create a Telegram bot
|
|
14
32
|
|
|
15
33
|
1. Open Telegram and search for `@BotFather`
|
|
@@ -21,11 +39,59 @@ The Telegram plugin connects {{productName}} to a Telegram bot. Once set up, you
|
|
|
21
39
|
|
|
22
40
|
Tell {{productName}}: "Set up Telegram" or "Configure the Telegram bot." Setup runs entirely in the admin chat — there is no settings page.
|
|
23
41
|
|
|
24
|
-
{{productName}} asks for your bot token, then asks
|
|
42
|
+
{{productName}} asks for your bot token, then asks what kind of bot this is:
|
|
43
|
+
|
|
44
|
+
- an **admin bot** — only your numeric Telegram IDs may message it, and it answers as your admin agent;
|
|
45
|
+
- a **public bot** — customer-facing, with a DM policy, answering as one of your account's agents;
|
|
46
|
+
- a **specialist bot** — bound to one of your own specialists, so messaging it runs that specialist with its own instructions and its own tools rather than your admin agent. You name the specialist and the numeric IDs allowed to reach it. Both are required: there is no open setting for this kind, because the specialist has real tools rather than the reply-only surface a public bot gets.
|
|
47
|
+
|
|
48
|
+
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.
|
|
25
49
|
|
|
26
50
|
### Step 3: Start the bot
|
|
27
51
|
|
|
28
|
-
In Telegram, open your bot and send `/start`, then a message. {{productName}} receives it and replies in the same chat. Admin-bot messages from your registered IDs reach the admin agent; public-bot messages reach the public agent you selected.
|
|
52
|
+
In Telegram, open your bot and send `/start`, then a message. {{productName}} receives it and replies in the same chat. Admin-bot messages from your registered IDs reach the admin agent; public-bot messages reach the public agent you selected; specialist-bot messages reach that specialist, in a conversation that stays the same one from one day to the next.
|
|
53
|
+
|
|
54
|
+
### Step 4 (optional): Use the bot in a group
|
|
55
|
+
|
|
56
|
+
Only a **public** bot can work in a group. An admin bot added to a group answers nobody, on purpose: it runs your own agent, with your own standing rules and tools, and a group is a room other people read.
|
|
57
|
+
|
|
58
|
+
Three things have to be true:
|
|
59
|
+
|
|
60
|
+
1. **Group privacy is on.** In BotFather: `/mybots`, pick the bot, Bot Settings, Group Privacy, Turn on. With privacy on the bot sees only messages that name it — a command, an @mention, or a reply to something it said. It cannot read the rest of the conversation. {{productName}} refuses to connect a bot with privacy off and tells you this step.
|
|
61
|
+
2. **The bot is in the group.** A group admin adds it, the same way any member is added.
|
|
62
|
+
3. **You allowlist the group.** Tell {{productName}}: "Let the bot answer in this group," and give it the group's chat ID (see Getting a Chat ID below). Until you do, the bot stays silent there.
|
|
63
|
+
|
|
64
|
+
Once a group is allowlisted, **anyone in that group can talk to the bot** — not only the people on your DM allowlist. Allowlisting a room is a decision about the room, not about its members.
|
|
65
|
+
|
|
66
|
+
Everyone in the group shares one conversation, and each message tells {{productName}} who sent it. If the group uses topics, an answer comes back inside the topic the question was asked in.
|
|
67
|
+
|
|
68
|
+
### Step 5 (optional): Use the bot in a channel
|
|
69
|
+
|
|
70
|
+
A channel is a broadcast: a post goes to every subscriber, and it cannot be taken back. So this one
|
|
71
|
+
is worth reading twice before you set it up.
|
|
72
|
+
|
|
73
|
+
Only a **public** bot can work in a channel, for the same reason only a public bot can work in a
|
|
74
|
+
group.
|
|
75
|
+
|
|
76
|
+
Two things have to be true:
|
|
77
|
+
|
|
78
|
+
1. **The bot is a channel admin with permission to post.** A channel admin adds it and ticks "Post
|
|
79
|
+
Messages". Without that tick the bot can still read the channel but every attempt to post fails
|
|
80
|
+
quietly.
|
|
81
|
+
2. **You allowlist the channel.** Tell {{productName}}: "Let the bot use this channel," and give it
|
|
82
|
+
the channel's chat ID. Until you do, the bot neither reads that channel nor posts to it.
|
|
83
|
+
|
|
84
|
+
Unlike a group, allowlisting a channel decides **both directions at once**. Once a channel is on the
|
|
85
|
+
list, {{productName}} can post to it. A channel that is not on the list is refused before anything
|
|
86
|
+
is sent, and you are told which channel and why.
|
|
87
|
+
|
|
88
|
+
Posts in a channel have no author — Telegram does not say who wrote one — so {{productName}} sees
|
|
89
|
+
the post as coming from the channel itself, by name.
|
|
90
|
+
|
|
91
|
+
**Comments.** If your channel has a linked discussion group, people can comment under each post.
|
|
92
|
+
Allowlist that group too (Step 4) and {{productName}} can read the comments and answer them under
|
|
93
|
+
the right post. Somebody who comments anonymously shows up as the group rather than as a person,
|
|
94
|
+
because that is all Telegram sends.
|
|
29
95
|
|
|
30
96
|
## Sending Messages via {{productName}}
|
|
31
97
|
|
|
@@ -37,13 +103,28 @@ Once connected, tell {{productName}} to send messages on your behalf:
|
|
|
37
103
|
|
|
38
104
|
{{productName}} needs a chat ID or username to target a specific person or group. For groups, you'll need to add the bot to the group first.
|
|
39
105
|
|
|
106
|
+
## Who your bot can message
|
|
107
|
+
|
|
108
|
+
Telegram does not let a bot start a conversation. Anyone who has messaged one of your bots can be
|
|
109
|
+
messaged back at any time; anyone who never has must write to the bot first. That is Telegram's own
|
|
110
|
+
rule and nothing here can get around it.
|
|
111
|
+
|
|
112
|
+
Ask {{productName}}: "Who can you reach on Telegram?" It lists every bot you have registered, the
|
|
113
|
+
people who have messaged each one and when they last wrote, and anyone on a bot's admin list who has
|
|
114
|
+
never messaged. Being on the admin list is not the same as having opened the chat, so those people
|
|
115
|
+
are listed separately as not reachable yet.
|
|
116
|
+
|
|
117
|
+
If {{productName}} ever says a Telegram message cannot be sent, ask it to check that list first.
|
|
118
|
+
|
|
40
119
|
## Getting a Chat ID
|
|
41
120
|
|
|
42
121
|
To message a specific person or group, {{productName}} needs their chat ID. The easiest way:
|
|
43
122
|
|
|
44
123
|
1. Have the person (or yourself) send any message to your bot
|
|
45
|
-
2. Ask {{productName}}: "
|
|
46
|
-
3. {{productName}} will
|
|
124
|
+
2. Ask {{productName}}: "Who can you reach on Telegram?"
|
|
125
|
+
3. {{productName}} will show you every chat that has messaged, with its ID
|
|
126
|
+
|
|
127
|
+
A group's ID is a long negative number, like `-1001234567890`. To find it, @mention the bot once in the group and then ask {{productName}} the same question — the group will be in the list even though the bot is not yet allowed to answer there.
|
|
47
128
|
|
|
48
129
|
## Message History
|
|
49
130
|
|
|
@@ -55,6 +136,10 @@ Ask {{productName}}: "What messages has the bot received?" or "Show recent Teleg
|
|
|
55
136
|
|
|
56
137
|
**Can't send to a group:** The bot must be a member of the group. Add it via the group settings in Telegram, then try again.
|
|
57
138
|
|
|
139
|
+
**"That channel isn't on the allowlist":** {{productName}} refuses to post to a channel or group you haven't allowlisted, and it refuses before anything is sent. Give it the chat ID and say you want the bot to use it. This applies to public bots only — an admin bot cannot post to any channel or group at all.
|
|
140
|
+
|
|
141
|
+
**The bot reads a channel but can't post to it:** It is a channel admin without the "Post Messages" permission. Turn that on in the channel's admin settings.
|
|
142
|
+
|
|
58
143
|
**Messages not arriving:** Make sure the bot hasn't been blocked. Try sending `/start` to the bot directly.
|
|
59
144
|
|
|
60
145
|
## Sending from the dashboard
|
|
@@ -96,12 +181,66 @@ nobody, and a vote was dropped without a trace. A press on a job-sheet card is t
|
|
|
96
181
|
one exception: the dispatch plugin applies the change and tells the presser
|
|
97
182
|
itself, so {{productName}} does not answer a second time.
|
|
98
183
|
|
|
184
|
+
The same is now true of most of what Telegram sends. Reply to one of
|
|
185
|
+
{{productName}}'s messages and it sees the message you replied to, so "yes, do
|
|
186
|
+
that one" means something. React to a message with an emoji and it hears the
|
|
187
|
+
reaction and what it was on. When a poll closes, it hears the final counts. When
|
|
188
|
+
somebody blocks the bot, that appears in the logs instead of sends quietly
|
|
189
|
+
failing.
|
|
190
|
+
|
|
191
|
+
Two things worth knowing about reactions. Telegram sends them only to a bot that
|
|
192
|
+
is an administrator of the chat, and a one-to-one chat has no administrator, so a
|
|
193
|
+
reaction in a private chat may never arrive at all. And a reaction on a message
|
|
194
|
+
{{productName}} itself sent will say the original is not held: it knows the
|
|
195
|
+
reaction happened, not what it was on.
|
|
196
|
+
|
|
197
|
+
Payments now complete. Telegram gives a bot ten seconds to approve a checkout
|
|
198
|
+
before cancelling it, which is faster than anything that has to think, so
|
|
199
|
+
{{productName}} approves it automatically and then tells you the sale happened,
|
|
200
|
+
with your own reference on it. If you sell a subscription, a customer cancelling,
|
|
201
|
+
re-subscribing or failing to pay all reach {{productName}} as well.
|
|
202
|
+
|
|
99
203
|
One limit worth knowing, and it is Telegram's rather than ours. Telegram only
|
|
100
204
|
reports who voted in a poll that is **not** anonymous, and polls are anonymous
|
|
101
205
|
unless you say otherwise. Ask for a poll where you can see who chose what, and
|
|
102
206
|
{{productName}} will send it that way; ask for a plain poll and Telegram will tell
|
|
103
207
|
nobody how anyone voted, so no reply is possible.
|
|
104
208
|
|
|
209
|
+
## Checklists and Telegram Business
|
|
210
|
+
|
|
211
|
+
{{productName}} can send a Telegram checklist, the kind with tick-boxes that anyone in the chat can
|
|
212
|
+
mark off. Telegram only allows this on behalf of a **business account**, never from a bot on its own,
|
|
213
|
+
so there is one thing to do first: in Telegram, open Settings, then Business, then Chatbots, and
|
|
214
|
+
connect your bot there.
|
|
215
|
+
|
|
216
|
+
That is the whole setup. {{productName}} notices the connection the moment you make it and remembers
|
|
217
|
+
it, so from then on you can just ask for a checklist. Disconnect the bot and it stops, and
|
|
218
|
+
{{productName}} will tell you that is why rather than failing silently.
|
|
219
|
+
|
|
220
|
+
One limit, and it is Telegram's. A message sent on behalf of a business account cannot carry a button
|
|
221
|
+
that opens a small web page, so a checklist and a job-sheet button arrive as two messages rather than
|
|
222
|
+
one.
|
|
223
|
+
|
|
224
|
+
## Your customers' messages
|
|
225
|
+
|
|
226
|
+
Connecting the bot to your business account does more than unlock checklists. From that moment,
|
|
227
|
+
messages your customers send to the business account reach {{productName}} too, and it can answer
|
|
228
|
+
them in the customer's own chat.
|
|
229
|
+
|
|
230
|
+
Those conversations are kept entirely separate from your own. A customer talking to your business
|
|
231
|
+
account never lands in the chat you use with {{productName}}, even if it is somebody who also
|
|
232
|
+
messages you directly, and {{productName}} answers a customer as your public assistant rather than as
|
|
233
|
+
your personal one. Your own notes and standing instructions are never visible in a customer's
|
|
234
|
+
conversation.
|
|
235
|
+
|
|
236
|
+
When a customer edits a message, the message you are looking at changes to match. When they delete
|
|
237
|
+
one, it stays in view but crossed out and marked deleted, so you can still see what was withdrawn.
|
|
238
|
+
|
|
239
|
+
**The one thing worth knowing: Telegram gives you 24 hours.** You may reply to a customer only within
|
|
240
|
+
24 hours of their last message. After that Telegram closes the door and there is no way to reopen it
|
|
241
|
+
except for the customer to write again. {{productName}} will refuse a late reply and tell you the
|
|
242
|
+
window has closed, rather than letting it fail silently.
|
|
243
|
+
|
|
105
244
|
Five of the 185 are deliberately refused, because they would break your own
|
|
106
245
|
inbound messages: setting or deleting the webhook by hand, polling Telegram for
|
|
107
246
|
updates instead, and the two that move the bot off Telegram's cloud servers.
|
|
@@ -71,8 +71,8 @@ Every path is confined to the resolved account directory. A path that escapes it
|
|
|
71
71
|
## Tools
|
|
72
72
|
|
|
73
73
|
- `file-read` — Read a UTF-8 file. Args: `path`, optional `targetAccountId`.
|
|
74
|
-
- `file-write` — Create or overwrite a UTF-8 file, making parent directories. Args: `path`, `content`, optional `targetAccountId`.
|
|
75
|
-
- `file-edit` — Replace one unique occurrence of `oldString` with `newString`. Fails if `oldString` is missing or not unique. Args: `path`, `oldString`, `newString`, optional `targetAccountId`.
|
|
74
|
+
- `file-write` — Create or overwrite a UTF-8 file, making parent directories. Args: `path`, `content`, optional `targetAccountId`. Refused before anything is created when the path breaks the target account's own `SCHEMA.md`: an unlisted top-level entry, one of the account's machinery entries, a plugin-declared file, a path deeper than the bucket allows, or a name outside `[a-z0-9-]`. The five reasons are the ones the native write guard gives, and each refusal logs `[fs-guard] blocked path=<rel> reason=<r>` to this server's own `mcp-filesystem-<sessionId>.log`. An account with no `SCHEMA.md`, and the shared folder (which is not an account), are exempt.
|
|
75
|
+
- `file-edit` — Replace one unique occurrence of `oldString` with `newString`. Fails if `oldString` is missing or not unique. Args: `path`, `oldString`, `newString`, optional `targetAccountId`. Carries the same five schema refusals as `file-write`, so a file already sitting at a path the schema forbids is not editable here either.
|
|
76
76
|
- `file-list` — List a directory's entries with their type. Args: optional `path` (defaults to the account root), optional `targetAccountId`.
|
|
77
77
|
- `file-glob` — List files matching a glob (`**`, `*`, `?`). Args: `pattern`, optional `targetAccountId`.
|
|
78
78
|
- `file-grep` — Search file contents for a JavaScript regular expression, returning `file:line:preview`. Args: `pattern`, optional `path`, optional `targetAccountId`.
|
package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/account-schema.test.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-schema.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/account-schema.test.ts"],"names":[],"mappings":""}
|