@rubytech/create-maxy-code 0.1.579 → 0.1.581
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/telegram-media/dist/index.d.ts +45 -0
- package/payload/platform/lib/telegram-media/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/telegram-media/dist/index.js +89 -0
- package/payload/platform/lib/telegram-media/dist/index.js.map +1 -0
- package/payload/platform/lib/telegram-media/src/__tests__/telegram-media.test.ts +104 -0
- package/payload/platform/lib/telegram-media/src/index.ts +102 -0
- package/payload/platform/lib/telegram-media/tsconfig.json +9 -0
- package/payload/platform/lib/telegram-media/vitest.config.ts +9 -0
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/admin/PLUGIN.md +2 -2
- package/payload/platform/plugins/admin/hooks/__tests__/archive-ingest-surface-gate.test.sh +22 -0
- package/payload/platform/plugins/admin/hooks/__tests__/fs-schema-guard.test.sh +34 -0
- package/payload/platform/plugins/admin/hooks/__tests__/quote-path-write-gate.test.sh +25 -0
- package/payload/platform/plugins/admin/hooks/archive-ingest-surface-gate.sh +11 -4
- package/payload/platform/plugins/admin/hooks/fs-schema-guard.sh +2 -2
- package/payload/platform/plugins/admin/hooks/quote-path-write-gate.sh +6 -3
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +13 -1
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +16 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-schema-shape.test.ts +23 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-visit-status-write.test.ts +175 -3
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-visits-scope.test.ts +101 -0
- package/payload/platform/plugins/cloudflare/skills/data-portal/schema.sql +35 -1
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/visit-status.ts +73 -8
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/visits.ts +59 -8
- package/payload/platform/plugins/docs/references/telegram-guide.md +12 -0
- package/payload/platform/plugins/telegram/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/telegram/PLUGIN.md +27 -3
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-census.test.js +99 -1
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-census.test.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/ask-tool.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/ask-tool.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/ask-tool.test.js +226 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/ask-tool.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-ratio.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-ratio.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-ratio.test.js +75 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-ratio.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-store.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-store.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-store.test.js +152 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-store.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-tool.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-tool.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-tool.test.js +231 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-tool.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/invoice-tool.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/invoice-tool.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/invoice-tool.test.js +196 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/invoice-tool.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/live-location-store.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/live-location-store.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/live-location-store.test.js +93 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/live-location-store.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/live-location-tool.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/live-location-tool.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/live-location-tool.test.js +76 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/live-location-tool.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/media-fetch-tool.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/media-fetch-tool.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/media-fetch-tool.test.js +95 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/media-fetch-tool.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/media-send-tool.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/media-send-tool.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/media-send-tool.test.js +293 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/media-send-tool.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/schemas.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/schemas.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/schemas.test.js +130 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/schemas.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/thread-tool.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/thread-tool.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/thread-tool.test.js +119 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/thread-tool.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/index.js +89 -66
- package/payload/platform/plugins/telegram/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.d.ts +15 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.js +27 -10
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-census.d.ts +38 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-census.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-census.js +106 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/api-census.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/card-ratio.d.ts +15 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/card-ratio.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/card-ratio.js +78 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/card-ratio.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/card-store.d.ts +60 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/card-store.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/card-store.js +141 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/card-store.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/live-location-store.d.ts +44 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/live-location-store.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/live-location-store.js +88 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/live-location-store.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/ask.d.ts +73 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/ask.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/ask.js +270 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/ask.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/card.d.ts +34 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/card.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/card.js +140 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/card.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/invoice.d.ts +70 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/invoice.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/invoice.js +232 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/invoice.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/live-location.d.ts +23 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/live-location.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/live-location.js +43 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/live-location.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/media-fetch.d.ts +42 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/media-fetch.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/media-fetch.js +92 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/media-fetch.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/media-send.d.ts +76 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/media-send.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/media-send.js +288 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/media-send.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/schemas.d.ts +250 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/schemas.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/schemas.js +400 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/schemas.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/thread.d.ts +38 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/thread.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/thread.js +120 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/thread.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/vitest.config.ts +14 -0
- package/payload/platform/plugins/telegram/skills/build/SKILL.md +171 -21
- package/payload/platform/scripts/__tests__/hook-matcher-dispatch.test.sh +163 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +7 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.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 +15 -1
- package/payload/platform/services/telegram-channel/dist/instructions.js.map +1 -1
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/server/{adminuser-self-heal-Y4U3UNKF.js → adminuser-self-heal-ZHFNDKJK.js} +2 -10
- package/payload/server/{chunk-637C2FGE.js → chunk-BFRB2U75.js} +3278 -3381
- package/payload/server/{chunk-6DQCFP2E.js → chunk-BTXRBXMU.js} +3785 -4090
- package/payload/server/{chunk-KVR2FT6O.js → chunk-HYQNUVGO.js} +1 -12
- package/payload/server/{chunk-PGGGWUBM.js → chunk-SKYZG6OT.js} +224 -372
- package/payload/server/{manager-R3XH3BNM.js → manager-CTVTF4YB.js} +3 -3
- package/payload/server/maxy-edge.js +4 -27
- package/payload/server/public/activity.html +6 -6
- package/payload/server/public/agents.html +5 -5
- package/payload/server/public/assets/{AdminLoginScreens-Bus-Y-rG.js → AdminLoginScreens-B1lu4-_F.js} +1 -1
- 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-Bsm7q3CW.js → AdminShell-BMslfZxN.js} +1 -1
- 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-BWqrCyYM.js → activity-kQ3w70LJ.js} +1 -1
- 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-zly7Y6EZ.js → admin-CkASgYA7.js} +1 -1
- 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-BsxGD1V1.js → agents-Cn_bZgnD.js} +1 -1
- 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-CRLxTaw2.js → browser-BE-GDk5-.js} +1 -1
- 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-Bmp6qI_P.js → calendar-Di7BEHHN.js} +1 -1
- 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 +1 -0
- package/payload/server/public/assets/chat-CKyMT5Ai.js.br +1 -0
- package/payload/server/public/assets/chat-CKyMT5Ai.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-Id9VAZAz.js +1 -0
- package/payload/server/public/assets/chevron-left-Id9VAZAz.js.br +0 -0
- package/payload/server/public/assets/clock-DKpWWJbJ.js +1 -0
- package/payload/server/public/assets/clock-DKpWWJbJ.js.br +0 -0
- package/payload/server/public/assets/{copy-Bcjpxqzn.js → copy-nkxspu2J.js} +1 -1
- 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 +1 -0
- package/payload/server/public/assets/data-1c33cAHp.js.br +2 -0
- package/payload/server/public/assets/data-1c33cAHp.js.gz +0 -0
- package/payload/server/public/assets/{field-ChKB2l_d.js → field-2rIXxGMt.js} +1 -1
- 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-COZcf7mU.js → file-text-CdSqrscg.js} +1 -1
- 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-nnV47iqM.js → graph-BfBHHXaC.js} +1 -1
- 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-x-1MT-3c.js → graph-labels-CHW2aBke.js} +1 -1
- 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 +1 -0
- package/payload/server/public/assets/jsx-runtime-D43jgaWP.css.br +0 -0
- package/payload/server/public/assets/jsx-runtime-D43jgaWP.css.gz +0 -0
- package/payload/server/public/assets/{operator-BAO0-mjU.js → operator-DRn9LITC.js} +1 -1
- 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 +1 -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-B-F08pod.js → page-D_9mPS6W.js} +1 -1
- 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 +1 -0
- 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-_HJsUohA.js → public-CrjZYpdW.js} +1 -1
- 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-DJeAnYLQ.js → rotate-ccw-J9f-GWjm.js} +1 -1
- 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-CoIVXRCB.js → routines-C1AB-3FR.js} +1 -1
- 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-BjHt5lDG.js → skills-C4EfNKEx.js} +1 -1
- 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-iUFfeA9_.js → tasks-DszD3aZl.js} +1 -1
- 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-Dwa986Gg.js → triangle-alert-B5WAyAkC.js} +1 -1
- package/payload/server/public/assets/triangle-alert-B5WAyAkC.js.br +4 -0
- package/payload/server/public/assets/triangle-alert-B5WAyAkC.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-B1Jp6CsE.js → useCopyFeedback-B2nuNNJw.js} +1 -1
- 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-CVZYjRf6.js → useMediaQuery-DUPJPHQt.js} +1 -1
- 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 +2 -0
- 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-BD7xwbV1.js → wrench-DZJZm17j.js} +1 -1
- 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/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 +10561 -10491
- package/payload/server/{src-IJCLNFYU.js → src-MM64CYYZ.js} +1 -1
- package/payload/server/{userprofile-reconcile-PUA657YX.js → userprofile-reconcile-TL4JKBPG.js} +1 -8
- package/payload/server/public/assets/AdminLoginScreens-Bus-Y-rG.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-Bus-Y-rG.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-Bsm7q3CW.js.br +0 -0
- package/payload/server/public/assets/AdminShell-Bsm7q3CW.js.gz +0 -0
- package/payload/server/public/assets/activity-BWqrCyYM.js.br +0 -0
- package/payload/server/public/assets/activity-BWqrCyYM.js.gz +0 -0
- package/payload/server/public/assets/admin-zly7Y6EZ.js.br +0 -0
- package/payload/server/public/assets/admin-zly7Y6EZ.js.gz +0 -0
- package/payload/server/public/assets/agents-BsxGD1V1.js.br +0 -0
- package/payload/server/public/assets/agents-BsxGD1V1.js.gz +0 -0
- package/payload/server/public/assets/browser-CRLxTaw2.js.br +0 -0
- package/payload/server/public/assets/browser-CRLxTaw2.js.gz +0 -0
- package/payload/server/public/assets/calendar-Bmp6qI_P.js.br +0 -0
- package/payload/server/public/assets/calendar-Bmp6qI_P.js.gz +0 -0
- package/payload/server/public/assets/chat-ChObDKHy.js +0 -1
- package/payload/server/public/assets/chat-ChObDKHy.js.br +0 -0
- package/payload/server/public/assets/chat-ChObDKHy.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-D2l4jMcd.js +0 -1
- package/payload/server/public/assets/chevron-left-D2l4jMcd.js.br +0 -0
- package/payload/server/public/assets/clock-CMdfsroW.js +0 -1
- package/payload/server/public/assets/clock-CMdfsroW.js.br +0 -0
- package/payload/server/public/assets/clock-CMdfsroW.js.gz +0 -0
- package/payload/server/public/assets/copy-Bcjpxqzn.js.br +0 -0
- package/payload/server/public/assets/copy-Bcjpxqzn.js.gz +0 -0
- package/payload/server/public/assets/data-CFB5Lgw-.js +0 -1
- package/payload/server/public/assets/data-CFB5Lgw-.js.br +0 -0
- package/payload/server/public/assets/data-CFB5Lgw-.js.gz +0 -0
- package/payload/server/public/assets/field-ChKB2l_d.js.br +0 -0
- package/payload/server/public/assets/field-ChKB2l_d.js.gz +0 -0
- package/payload/server/public/assets/file-text-COZcf7mU.js.br +0 -0
- package/payload/server/public/assets/file-text-COZcf7mU.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-x-1MT-3c.js.br +0 -0
- package/payload/server/public/assets/graph-labels-x-1MT-3c.js.gz +0 -0
- package/payload/server/public/assets/graph-nnV47iqM.js.br +0 -0
- package/payload/server/public/assets/graph-nnV47iqM.js.gz +0 -0
- package/payload/server/public/assets/jsx-runtime-CeNZasfC.css +0 -1
- package/payload/server/public/assets/jsx-runtime-CeNZasfC.css.br +0 -0
- package/payload/server/public/assets/jsx-runtime-CeNZasfC.css.gz +0 -0
- package/payload/server/public/assets/operator-BAO0-mjU.js.br +0 -0
- package/payload/server/public/assets/operator-BAO0-mjU.js.gz +0 -0
- package/payload/server/public/assets/page-B-F08pod.js.br +0 -0
- package/payload/server/public/assets/page-B-F08pod.js.gz +0 -0
- package/payload/server/public/assets/page-BMOCy2aD.js +0 -1
- package/payload/server/public/assets/page-BMOCy2aD.js.br +0 -0
- package/payload/server/public/assets/page-BMOCy2aD.js.gz +0 -0
- package/payload/server/public/assets/play-DFtlk8Zs.js +0 -1
- package/payload/server/public/assets/play-DFtlk8Zs.js.br +0 -0
- package/payload/server/public/assets/play-DFtlk8Zs.js.gz +0 -0
- package/payload/server/public/assets/public-_HJsUohA.js.br +0 -0
- package/payload/server/public/assets/public-_HJsUohA.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-DJeAnYLQ.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-DJeAnYLQ.js.gz +0 -0
- package/payload/server/public/assets/routines-CoIVXRCB.js.br +0 -0
- package/payload/server/public/assets/routines-CoIVXRCB.js.gz +0 -0
- package/payload/server/public/assets/skills-BjHt5lDG.js.br +0 -0
- package/payload/server/public/assets/skills-BjHt5lDG.js.gz +0 -0
- package/payload/server/public/assets/tasks-iUFfeA9_.js.br +0 -0
- package/payload/server/public/assets/tasks-iUFfeA9_.js.gz +0 -0
- package/payload/server/public/assets/triangle-alert-Dwa986Gg.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-Dwa986Gg.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-B1Jp6CsE.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-B1Jp6CsE.js.gz +0 -0
- package/payload/server/public/assets/useMediaQuery-CVZYjRf6.js.br +0 -0
- package/payload/server/public/assets/useMediaQuery-CVZYjRf6.js.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-D5b4r4z0.js +0 -2
- package/payload/server/public/assets/useVoiceRecorder-D5b4r4z0.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-D5b4r4z0.js.gz +0 -0
- package/payload/server/public/assets/wrench-BD7xwbV1.js.br +0 -0
- package/payload/server/public/assets/wrench-BD7xwbV1.js.gz +0 -0
- /package/payload/server/public/assets/{jsx-runtime-CjJ246F7.js → jsx-runtime-Cjug_Cyb.js} +0 -0
- /package/payload/server/public/assets/{jsx-runtime-CjJ246F7.js.br → jsx-runtime-Cjug_Cyb.js.br} +0 -0
- /package/payload/server/public/assets/{jsx-runtime-CjJ246F7.js.gz → jsx-runtime-Cjug_Cyb.js.gz} +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { MAX_BYTES_PER_FILE } from "./api-census.js";
|
|
4
|
+
/** The numerator: one card that carried at least one button. Task 2604 added the
|
|
5
|
+
* `buttons=` field; a line from an older build has none, matches nothing here and
|
|
6
|
+
* is counted as neither, which is right — it cannot say whether it had buttons.
|
|
7
|
+
*
|
|
8
|
+
* EVERY outcome counts, `none` included. card.ts logs `op=card` unconditionally
|
|
9
|
+
* after its outcome branch, so a card Telegram refused is in this count. That is
|
|
10
|
+
* deliberate: this census measures whether the AGENT reached for the affordance,
|
|
11
|
+
* which is what the instruction clause governs, and a 400 from Telegram is not
|
|
12
|
+
* the agent declining to offer buttons. It does mean the numerator is offers
|
|
13
|
+
* made, not keyboards seen — read `[telegram-tools] op=result … ok=false` beside
|
|
14
|
+
* it if that distinction matters for a given question. */
|
|
15
|
+
const CARD_LINE = /^\[telegram-tools\] op=card .*\bbuttons=(\d+)/;
|
|
16
|
+
/** The denominator: one composed turn on the ADMIN Telegram door. The channel
|
|
17
|
+
* service writes this per turn (telegram-channel/src/server.ts), to its own
|
|
18
|
+
* stderr, which lands in mcp-telegram-channel-<sessionId>.log — an mcp-*.log, so
|
|
19
|
+
* the same walk finds it. `[telegram:reframe] op=compose` is per-turn too but is
|
|
20
|
+
* emitted by the GATEWAY into server.log, which rotates on size and is skipped by
|
|
21
|
+
* MAX_BYTES_PER_FILE, so it would report a permanent zero denominator.
|
|
22
|
+
*
|
|
23
|
+
* role=admin only: the clause this census measures lives in
|
|
24
|
+
* ADMIN_REFRAME_INSTRUCTION and a public visitor's turn never carries it. */
|
|
25
|
+
const TURN_LINE = /^\[telegram:inbound\] op=delivered .*\brole=admin\b/;
|
|
26
|
+
/** Pure, so the arithmetic is testable without a log directory. */
|
|
27
|
+
export function tallyCardRatio(lines) {
|
|
28
|
+
let cardsWithButtons = 0;
|
|
29
|
+
let turns = 0;
|
|
30
|
+
for (const line of lines) {
|
|
31
|
+
const card = CARD_LINE.exec(line);
|
|
32
|
+
if (card) {
|
|
33
|
+
if (Number(card[1]) > 0)
|
|
34
|
+
cardsWithButtons += 1;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (TURN_LINE.test(line))
|
|
38
|
+
turns += 1;
|
|
39
|
+
}
|
|
40
|
+
return { cardsWithButtons, turns };
|
|
41
|
+
}
|
|
42
|
+
/** Both counts from one walk of LOG_DIR over mcp-*.log — the filter and size
|
|
43
|
+
* guard passthroughCensusLine already uses. Rotated `.gz` files are skipped:
|
|
44
|
+
* read as text they yield binary noise, not lines.
|
|
45
|
+
*
|
|
46
|
+
* Never throws. A boot throw empties the plugin registry (CLAUDE.md), so any
|
|
47
|
+
* failure reports zeros, and `turns` on the census line is what lets the
|
|
48
|
+
* operator tell those zeros from a healthy quiet window. */
|
|
49
|
+
export function cardRatioFromLogs(logDir) {
|
|
50
|
+
let cardsWithButtons = 0;
|
|
51
|
+
let turns = 0;
|
|
52
|
+
try {
|
|
53
|
+
if (logDir) {
|
|
54
|
+
for (const name of readdirSync(logDir)) {
|
|
55
|
+
if (!name.startsWith("mcp-") || !name.endsWith(".log"))
|
|
56
|
+
continue;
|
|
57
|
+
const path = join(logDir, name);
|
|
58
|
+
let text;
|
|
59
|
+
try {
|
|
60
|
+
if (statSync(path).size > MAX_BYTES_PER_FILE)
|
|
61
|
+
continue;
|
|
62
|
+
text = readFileSync(path, "utf-8");
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const t = tallyCardRatio(text.split("\n"));
|
|
68
|
+
cardsWithButtons += t.cardsWithButtons;
|
|
69
|
+
turns += t.turns;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Zeros, deliberately. See the doc comment.
|
|
75
|
+
}
|
|
76
|
+
return { cardsWithButtons, turns };
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=card-ratio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card-ratio.js","sourceRoot":"","sources":["../../src/lib/card-ratio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;;;;;;;;2DAU2D;AAC3D,MAAM,SAAS,GAAG,+CAA+C,CAAC;AAElE;;;;;;;;8EAQ8E;AAC9E,MAAM,SAAS,GAAG,qDAAqD,CAAC;AAOxE,mEAAmE;AACnE,MAAM,UAAU,cAAc,CAAC,KAAuB;IACpD,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;gBAAE,gBAAgB,IAAI,CAAC,CAAC;YAC/C,SAAS;QACX,CAAC;QACD,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,KAAK,IAAI,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;AACrC,CAAC;AAED;;;;;;6DAM6D;AAC7D,MAAM,UAAU,iBAAiB,CAAC,MAA0B;IAC1D,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,CAAC;QACH,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;oBAAE,SAAS;gBACjE,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBAChC,IAAI,IAAY,CAAC;gBACjB,IAAI,CAAC;oBACH,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,kBAAkB;wBAAE,SAAS;oBACvD,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBACrC,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;gBACD,MAAM,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC3C,gBAAgB,IAAI,CAAC,CAAC,gBAAgB,CAAC;gBACvC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4CAA4C;IAC9C,CAAC;IACD,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Scoped by bot AND chat, not by the caller's key alone: the same "job-4102"
|
|
2
|
+
* key in two chats is two cards, and collapsing them would edit a stranger's
|
|
3
|
+
* message. */
|
|
4
|
+
export declare function cardKey(botId: string, chatId: string | number, key: string): string;
|
|
5
|
+
/** A card untouched for this long stops being edited in place: the next keyed
|
|
6
|
+
* call posts fresh. Operator decision 2026-08-08 (Task 2595). No Telegram-imposed
|
|
7
|
+
* edit window is claimed here — none was confirmed. This is our own ceiling, and
|
|
8
|
+
* it is what bounds the file: without it every key ever used is kept for ever. */
|
|
9
|
+
export declare const CARD_TTL_MS: number;
|
|
10
|
+
/** The stored message id for this key, or null. Null once the entry has gone
|
|
11
|
+
* CARD_TTL_MS untouched: the caller then posts fresh, which is how a key whose
|
|
12
|
+
* message is gone recovers without matching on Telegram's error prose. */
|
|
13
|
+
export declare function readCardId(platformRoot: string, accountId: string, k: string, now?: number): number | null;
|
|
14
|
+
/** Record the message id this key now names, and drop every entry that has gone
|
|
15
|
+
* CARD_TTL_MS untouched. Compaction rides the write because the write already
|
|
16
|
+
* rewrites the whole file; a separate prune pass would be a second thing to
|
|
17
|
+
* schedule. Every surviving key keeps its own id and timestamp, the same promise
|
|
18
|
+
* persistTelegramBot makes for bot entries. */
|
|
19
|
+
export declare function writeCardId(platformRoot: string, accountId: string, k: string, messageId: number, now?: number): void;
|
|
20
|
+
export declare const CARD_CENSUS_TAG = "[telegram-card-census]";
|
|
21
|
+
/** The standing check for this store, emitted once at MCP boot.
|
|
22
|
+
*
|
|
23
|
+
* It answers what nothing else can: is telegram-cards.json growing? Every entry
|
|
24
|
+
* is one key that was used and kept, and until this line existed that growth was
|
|
25
|
+
* invisible — Task 2588 gave the media store a census and gave this one none.
|
|
26
|
+
*
|
|
27
|
+
* It reports the count it read back from disk, never that a prune ran. A prune
|
|
28
|
+
* that pruned nothing and a prune that worked print the same thing if the line
|
|
29
|
+
* reports the prune rather than the state.
|
|
30
|
+
*
|
|
31
|
+
* `keys` is every entry ON DISK, expired ones included. Compaction only rides a
|
|
32
|
+
* write, so an account that stops posting cards keeps its file at whatever size
|
|
33
|
+
* it reached while every entry in it reads as absent through readCardId. That is
|
|
34
|
+
* the right number for the question this line asks — is the file growing — but
|
|
35
|
+
* it is not a count of live cards. `keys=0` with `bytes>0` is the third state: a
|
|
36
|
+
* file that exists and parsed to nothing.
|
|
37
|
+
*
|
|
38
|
+
* `keys` rising across boots while jobs close is the leak. Never throws: a boot
|
|
39
|
+
* throw empties the plugin registry (CLAUDE.md), so any failure reports zeros.
|
|
40
|
+
*
|
|
41
|
+
* Task 2604 added `cardsWithButtons` and `turns`, which come from LOG_DIR rather
|
|
42
|
+
* than from this store: buttons are not stored here and an unkeyed one-off card
|
|
43
|
+
* has no entry at all, so neither is answerable from telegram-cards.json. The
|
|
44
|
+
* pair is the signal for the affordances clause in the Telegram turn
|
|
45
|
+
* instruction — not offering a button is a non-event and logs nothing of its
|
|
46
|
+
* own, so only a ratio can show the clause taking or over-firing. `turns` is on
|
|
47
|
+
* the line because `cardsWithButtons=0` alone cannot be told from a counter that
|
|
48
|
+
* is not running. No threshold is asserted here; the numbers are what the
|
|
49
|
+
* operator judges the wording against.
|
|
50
|
+
*
|
|
51
|
+
* THE TWO HALVES OF THIS LINE ARE SCOPED DIFFERENTLY, and reading them as one
|
|
52
|
+
* scope is the mistake to avoid. `keys` and `bytes` are ONE ACCOUNT's: they read
|
|
53
|
+
* telegram-cards.json under that account's own directory. `cardsWithButtons` and
|
|
54
|
+
* `turns` are INSTALL-WIDE: LOG_DIR is `~/.<brand>/logs/`, which every account in
|
|
55
|
+
* the brand shares, and no line in it carries an accountId to filter on. So on a
|
|
56
|
+
* multi-account install the ratio is the whole brand's and the store counts are
|
|
57
|
+
* one account's. Per-account attribution would need an accountId on the
|
|
58
|
+
* `op=card` and `op=delivered` lines, which neither carries today. */
|
|
59
|
+
export declare function cardCensusLine(platformRoot: string, accountId: string | undefined, logDir?: string): string;
|
|
60
|
+
//# sourceMappingURL=card-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card-store.d.ts","sourceRoot":"","sources":["../../src/lib/card-store.ts"],"names":[],"mappings":"AASA;;eAEe;AACf,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEnF;AAOD;;;mFAGmF;AACnF,eAAO,MAAM,WAAW,QAA0B,CAAC;AAwCnD;;2EAE2E;AAC3E,wBAAgB,UAAU,CACxB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,CAAC,EAAE,MAAM,EACT,GAAG,GAAE,MAAmB,GACvB,MAAM,GAAG,IAAI,CAMf;AAED;;;;gDAIgD;AAChD,wBAAgB,WAAW,CACzB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,CAAC,EAAE,MAAM,EACT,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAmB,GACvB,IAAI,CASN;AAED,eAAO,MAAM,eAAe,2BAA2B,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uEAqCuE;AACvE,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAgBR"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { existsSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { resolveAccountDir } from "./account-write.js";
|
|
4
|
+
import { cardRatioFromLogs } from "./card-ratio.js";
|
|
5
|
+
/** Runtime state, so a file of its own rather than a key inside account.json,
|
|
6
|
+
* which holds configuration. Same directory, same brand containment. */
|
|
7
|
+
const FILE = "telegram-cards.json";
|
|
8
|
+
/** Scoped by bot AND chat, not by the caller's key alone: the same "job-4102"
|
|
9
|
+
* key in two chats is two cards, and collapsing them would edit a stranger's
|
|
10
|
+
* message. */
|
|
11
|
+
export function cardKey(botId, chatId, key) {
|
|
12
|
+
return `${botId}:${chatId}:${key}`;
|
|
13
|
+
}
|
|
14
|
+
function storePath(platformRoot, accountId) {
|
|
15
|
+
const resolved = resolveAccountDir(platformRoot, accountId);
|
|
16
|
+
return resolved.ok ? join(resolved.dir, FILE) : null;
|
|
17
|
+
}
|
|
18
|
+
/** A card untouched for this long stops being edited in place: the next keyed
|
|
19
|
+
* call posts fresh. Operator decision 2026-08-08 (Task 2595). No Telegram-imposed
|
|
20
|
+
* edit window is claimed here — none was confirmed. This is our own ceiling, and
|
|
21
|
+
* it is what bounds the file: without it every key ever used is kept for ever. */
|
|
22
|
+
export const CARD_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
23
|
+
function isEntry(v) {
|
|
24
|
+
if (!v || typeof v !== "object" || Array.isArray(v))
|
|
25
|
+
return false;
|
|
26
|
+
const e = v;
|
|
27
|
+
return (typeof e.id === "number" &&
|
|
28
|
+
Number.isFinite(e.id) &&
|
|
29
|
+
typeof e.at === "number" &&
|
|
30
|
+
Number.isFinite(e.at));
|
|
31
|
+
}
|
|
32
|
+
function readAll(path) {
|
|
33
|
+
if (!existsSync(path))
|
|
34
|
+
return {};
|
|
35
|
+
try {
|
|
36
|
+
const parsed = JSON.parse(readFileSync(path, "utf-8"));
|
|
37
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
38
|
+
return {};
|
|
39
|
+
const out = {};
|
|
40
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
41
|
+
if (isEntry(v))
|
|
42
|
+
out[k] = v;
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Unparseable state reads as "no card stored", which makes the next call
|
|
48
|
+
// post a fresh one. Throwing here would take the tool down over a file the
|
|
49
|
+
// caller never sees. A pre-2588-shape bare number fails isEntry and reads as
|
|
50
|
+
// absent for the same reason: it carries no timestamp, so its age is
|
|
51
|
+
// unknowable and it can never be aged out.
|
|
52
|
+
return {};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** The stored message id for this key, or null. Null once the entry has gone
|
|
56
|
+
* CARD_TTL_MS untouched: the caller then posts fresh, which is how a key whose
|
|
57
|
+
* message is gone recovers without matching on Telegram's error prose. */
|
|
58
|
+
export function readCardId(platformRoot, accountId, k, now = Date.now()) {
|
|
59
|
+
const path = storePath(platformRoot, accountId);
|
|
60
|
+
if (!path)
|
|
61
|
+
return null;
|
|
62
|
+
const entry = readAll(path)[k];
|
|
63
|
+
if (!entry)
|
|
64
|
+
return null;
|
|
65
|
+
return now - entry.at >= CARD_TTL_MS ? null : entry.id;
|
|
66
|
+
}
|
|
67
|
+
/** Record the message id this key now names, and drop every entry that has gone
|
|
68
|
+
* CARD_TTL_MS untouched. Compaction rides the write because the write already
|
|
69
|
+
* rewrites the whole file; a separate prune pass would be a second thing to
|
|
70
|
+
* schedule. Every surviving key keeps its own id and timestamp, the same promise
|
|
71
|
+
* persistTelegramBot makes for bot entries. */
|
|
72
|
+
export function writeCardId(platformRoot, accountId, k, messageId, now = Date.now()) {
|
|
73
|
+
const path = storePath(platformRoot, accountId);
|
|
74
|
+
if (!path)
|
|
75
|
+
return;
|
|
76
|
+
const kept = {};
|
|
77
|
+
for (const [key, entry] of Object.entries(readAll(path))) {
|
|
78
|
+
if (now - entry.at < CARD_TTL_MS)
|
|
79
|
+
kept[key] = entry;
|
|
80
|
+
}
|
|
81
|
+
kept[k] = { id: messageId, at: now };
|
|
82
|
+
writeFileSync(path, JSON.stringify(kept, null, 2) + "\n", "utf-8");
|
|
83
|
+
}
|
|
84
|
+
export const CARD_CENSUS_TAG = "[telegram-card-census]";
|
|
85
|
+
/** The standing check for this store, emitted once at MCP boot.
|
|
86
|
+
*
|
|
87
|
+
* It answers what nothing else can: is telegram-cards.json growing? Every entry
|
|
88
|
+
* is one key that was used and kept, and until this line existed that growth was
|
|
89
|
+
* invisible — Task 2588 gave the media store a census and gave this one none.
|
|
90
|
+
*
|
|
91
|
+
* It reports the count it read back from disk, never that a prune ran. A prune
|
|
92
|
+
* that pruned nothing and a prune that worked print the same thing if the line
|
|
93
|
+
* reports the prune rather than the state.
|
|
94
|
+
*
|
|
95
|
+
* `keys` is every entry ON DISK, expired ones included. Compaction only rides a
|
|
96
|
+
* write, so an account that stops posting cards keeps its file at whatever size
|
|
97
|
+
* it reached while every entry in it reads as absent through readCardId. That is
|
|
98
|
+
* the right number for the question this line asks — is the file growing — but
|
|
99
|
+
* it is not a count of live cards. `keys=0` with `bytes>0` is the third state: a
|
|
100
|
+
* file that exists and parsed to nothing.
|
|
101
|
+
*
|
|
102
|
+
* `keys` rising across boots while jobs close is the leak. Never throws: a boot
|
|
103
|
+
* throw empties the plugin registry (CLAUDE.md), so any failure reports zeros.
|
|
104
|
+
*
|
|
105
|
+
* Task 2604 added `cardsWithButtons` and `turns`, which come from LOG_DIR rather
|
|
106
|
+
* than from this store: buttons are not stored here and an unkeyed one-off card
|
|
107
|
+
* has no entry at all, so neither is answerable from telegram-cards.json. The
|
|
108
|
+
* pair is the signal for the affordances clause in the Telegram turn
|
|
109
|
+
* instruction — not offering a button is a non-event and logs nothing of its
|
|
110
|
+
* own, so only a ratio can show the clause taking or over-firing. `turns` is on
|
|
111
|
+
* the line because `cardsWithButtons=0` alone cannot be told from a counter that
|
|
112
|
+
* is not running. No threshold is asserted here; the numbers are what the
|
|
113
|
+
* operator judges the wording against.
|
|
114
|
+
*
|
|
115
|
+
* THE TWO HALVES OF THIS LINE ARE SCOPED DIFFERENTLY, and reading them as one
|
|
116
|
+
* scope is the mistake to avoid. `keys` and `bytes` are ONE ACCOUNT's: they read
|
|
117
|
+
* telegram-cards.json under that account's own directory. `cardsWithButtons` and
|
|
118
|
+
* `turns` are INSTALL-WIDE: LOG_DIR is `~/.<brand>/logs/`, which every account in
|
|
119
|
+
* the brand shares, and no line in it carries an accountId to filter on. So on a
|
|
120
|
+
* multi-account install the ratio is the whole brand's and the store counts are
|
|
121
|
+
* one account's. Per-account attribution would need an accountId on the
|
|
122
|
+
* `op=card` and `op=delivered` lines, which neither carries today. */
|
|
123
|
+
export function cardCensusLine(platformRoot, accountId, logDir) {
|
|
124
|
+
let keys = 0;
|
|
125
|
+
let bytes = 0;
|
|
126
|
+
try {
|
|
127
|
+
if (accountId) {
|
|
128
|
+
const path = storePath(platformRoot, accountId);
|
|
129
|
+
if (path && existsSync(path)) {
|
|
130
|
+
keys = Object.keys(readAll(path)).length;
|
|
131
|
+
bytes = statSync(path).size;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// Zeros, deliberately. See the doc comment.
|
|
137
|
+
}
|
|
138
|
+
const ratio = cardRatioFromLogs(logDir);
|
|
139
|
+
return `${CARD_CENSUS_TAG} keys=${keys} bytes=${bytes} cardsWithButtons=${ratio.cardsWithButtons} turns=${ratio.turns}`;
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=card-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card-store.js","sourceRoot":"","sources":["../../src/lib/card-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Task 2602 — the read side of the live-location record.
|
|
2
|
+
*
|
|
3
|
+
* The platform writes it (`platform/ui/app/lib/telegram/live-location.ts`) on
|
|
4
|
+
* every location-carrying inbound; this reads it back for the agent. The shape,
|
|
5
|
+
* the file name and the expiry rule are duplicated across the boundary on
|
|
6
|
+
* purpose — the plugin cannot import from `platform/ui/app`, the same boundary
|
|
7
|
+
* that already duplicates the webhook secret path and the card store — and
|
|
8
|
+
* `ui/app/lib/telegram/__tests__/live-location-boundary.test.ts` asserts the two
|
|
9
|
+
* derivations agree.
|
|
10
|
+
*
|
|
11
|
+
* Runtime state, so its own file beside `telegram-cards.json` rather than a key
|
|
12
|
+
* in `account.json`, which holds configuration. Same brand containment: the
|
|
13
|
+
* path resolves through `resolveAccountDir`, so a traversal in the account id
|
|
14
|
+
* reads as no share rather than reaching outside the install.
|
|
15
|
+
*/
|
|
16
|
+
export declare const LIVE_LOCATION_FILE = "telegram-live-location.json";
|
|
17
|
+
export interface LiveLocationRecord {
|
|
18
|
+
lat: number;
|
|
19
|
+
lon: number;
|
|
20
|
+
/** Telegram's own measurement time, in ms. Not when we heard about it. */
|
|
21
|
+
at: number;
|
|
22
|
+
botId: string;
|
|
23
|
+
/** The share's own `live_period`, in seconds. */
|
|
24
|
+
livePeriodS: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function liveLocationKey(botId: string, senderId: string): string;
|
|
27
|
+
/** Item 5's rule: a record older than the share's own `live_period` reads as
|
|
28
|
+
* absent, so a stale fix is never answered as current. */
|
|
29
|
+
export declare function isExpired(rec: LiveLocationRecord, now: number): boolean;
|
|
30
|
+
/** The current position for one sender on one bot, or a named refusal.
|
|
31
|
+
*
|
|
32
|
+
* An expired record comes back as no record at all. Returning it and trusting
|
|
33
|
+
* every caller to check the outcome is exactly how a stale fix gets reported as
|
|
34
|
+
* where somebody is now. */
|
|
35
|
+
export declare function readLiveLocation(platformRoot: string, accountId: string, botId: string, senderId: string, now?: number): {
|
|
36
|
+
outcome: "current" | "expired" | "absent";
|
|
37
|
+
record: LiveLocationRecord | null;
|
|
38
|
+
ageMs: number | null;
|
|
39
|
+
};
|
|
40
|
+
/** Every `<botId>:<senderId>` still inside its period. The refusal lists these
|
|
41
|
+
* so a caller who guessed the wrong id can correct it without guessing again.
|
|
42
|
+
* Keys only: a refusal is not a place to hand back positions nobody asked for. */
|
|
43
|
+
export declare function currentLiveLocationKeys(platformRoot: string, accountId: string, now?: number): string[];
|
|
44
|
+
//# sourceMappingURL=live-location-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-location-store.d.ts","sourceRoot":"","sources":["../../src/lib/live-location-store.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,kBAAkB,gCAAgC,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEvE;AAkBD;2DAC2D;AAC3D,wBAAgB,SAAS,CAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAEvE;AAsBD;;;;6BAI6B;AAC7B,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAmB,GACvB;IACD,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC1C,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAClC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAMA;AAED;;mFAEmF;AACnF,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAmB,GACvB,MAAM,EAAE,CAIV"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { resolveAccountDir } from "./account-write.js";
|
|
4
|
+
/** Task 2602 — the read side of the live-location record.
|
|
5
|
+
*
|
|
6
|
+
* The platform writes it (`platform/ui/app/lib/telegram/live-location.ts`) on
|
|
7
|
+
* every location-carrying inbound; this reads it back for the agent. The shape,
|
|
8
|
+
* the file name and the expiry rule are duplicated across the boundary on
|
|
9
|
+
* purpose — the plugin cannot import from `platform/ui/app`, the same boundary
|
|
10
|
+
* that already duplicates the webhook secret path and the card store — and
|
|
11
|
+
* `ui/app/lib/telegram/__tests__/live-location-boundary.test.ts` asserts the two
|
|
12
|
+
* derivations agree.
|
|
13
|
+
*
|
|
14
|
+
* Runtime state, so its own file beside `telegram-cards.json` rather than a key
|
|
15
|
+
* in `account.json`, which holds configuration. Same brand containment: the
|
|
16
|
+
* path resolves through `resolveAccountDir`, so a traversal in the account id
|
|
17
|
+
* reads as no share rather than reaching outside the install.
|
|
18
|
+
*/
|
|
19
|
+
export const LIVE_LOCATION_FILE = "telegram-live-location.json";
|
|
20
|
+
export function liveLocationKey(botId, senderId) {
|
|
21
|
+
return `${botId}:${senderId}`;
|
|
22
|
+
}
|
|
23
|
+
function isRecord(v) {
|
|
24
|
+
if (!v || typeof v !== "object" || Array.isArray(v))
|
|
25
|
+
return false;
|
|
26
|
+
const r = v;
|
|
27
|
+
return (typeof r.lat === "number" &&
|
|
28
|
+
Number.isFinite(r.lat) &&
|
|
29
|
+
typeof r.lon === "number" &&
|
|
30
|
+
Number.isFinite(r.lon) &&
|
|
31
|
+
typeof r.at === "number" &&
|
|
32
|
+
Number.isFinite(r.at) &&
|
|
33
|
+
typeof r.botId === "string" &&
|
|
34
|
+
typeof r.livePeriodS === "number" &&
|
|
35
|
+
Number.isFinite(r.livePeriodS));
|
|
36
|
+
}
|
|
37
|
+
/** Item 5's rule: a record older than the share's own `live_period` reads as
|
|
38
|
+
* absent, so a stale fix is never answered as current. */
|
|
39
|
+
export function isExpired(rec, now) {
|
|
40
|
+
return now - rec.at >= rec.livePeriodS * 1000;
|
|
41
|
+
}
|
|
42
|
+
function readAll(platformRoot, accountId) {
|
|
43
|
+
const resolved = resolveAccountDir(platformRoot, accountId);
|
|
44
|
+
if (!resolved.ok)
|
|
45
|
+
return {};
|
|
46
|
+
const path = join(resolved.dir, LIVE_LOCATION_FILE);
|
|
47
|
+
if (!existsSync(path))
|
|
48
|
+
return {};
|
|
49
|
+
try {
|
|
50
|
+
const parsed = JSON.parse(readFileSync(path, "utf-8"));
|
|
51
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
52
|
+
return {};
|
|
53
|
+
const out = {};
|
|
54
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
55
|
+
if (isRecord(v))
|
|
56
|
+
out[k] = v;
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Unparseable state reads as "no share stored", so the tool refuses by name.
|
|
62
|
+
// Throwing here would take the tool down over a file the caller never sees.
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** The current position for one sender on one bot, or a named refusal.
|
|
67
|
+
*
|
|
68
|
+
* An expired record comes back as no record at all. Returning it and trusting
|
|
69
|
+
* every caller to check the outcome is exactly how a stale fix gets reported as
|
|
70
|
+
* where somebody is now. */
|
|
71
|
+
export function readLiveLocation(platformRoot, accountId, botId, senderId, now = Date.now()) {
|
|
72
|
+
const rec = readAll(platformRoot, accountId)[liveLocationKey(botId, senderId)];
|
|
73
|
+
if (!rec)
|
|
74
|
+
return { outcome: "absent", record: null, ageMs: null };
|
|
75
|
+
const ageMs = now - rec.at;
|
|
76
|
+
if (isExpired(rec, now))
|
|
77
|
+
return { outcome: "expired", record: null, ageMs };
|
|
78
|
+
return { outcome: "current", record: rec, ageMs };
|
|
79
|
+
}
|
|
80
|
+
/** Every `<botId>:<senderId>` still inside its period. The refusal lists these
|
|
81
|
+
* so a caller who guessed the wrong id can correct it without guessing again.
|
|
82
|
+
* Keys only: a refusal is not a place to hand back positions nobody asked for. */
|
|
83
|
+
export function currentLiveLocationKeys(platformRoot, accountId, now = Date.now()) {
|
|
84
|
+
return Object.entries(readAll(platformRoot, accountId))
|
|
85
|
+
.filter(([, rec]) => !isExpired(rec, now))
|
|
86
|
+
.map(([k]) => k);
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=live-location-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-location-store.js","sourceRoot":"","sources":["../../src/lib/live-location-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { type InlineKeyboardButtonInput } from "../lib/telegram.js";
|
|
2
|
+
export type AskKind = "poll" | "checklist" | "location" | "venue" | "contact" | "dice" | "stopPoll" | "editChecklist" | "editLiveLocation" | "stopLiveLocation";
|
|
3
|
+
/** Kind to Bot API method. Verified against the live parameter tables on
|
|
4
|
+
* 2026-08-08. Exported so the census's owned-method map and this tool cannot
|
|
5
|
+
* disagree about which methods the tool owns. */
|
|
6
|
+
export declare const ASK_METHOD: Readonly<Record<AskKind, string>>;
|
|
7
|
+
export interface ChecklistInput {
|
|
8
|
+
title: string;
|
|
9
|
+
tasks: Array<{
|
|
10
|
+
id: number;
|
|
11
|
+
text: string;
|
|
12
|
+
}>;
|
|
13
|
+
othersCanAddTasks?: boolean;
|
|
14
|
+
othersCanMarkTasksAsDone?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface AskParams {
|
|
17
|
+
botId: string;
|
|
18
|
+
chatId: string | number;
|
|
19
|
+
kind: AskKind;
|
|
20
|
+
question?: string;
|
|
21
|
+
options?: string[];
|
|
22
|
+
pollType?: "regular" | "quiz";
|
|
23
|
+
isAnonymous?: boolean;
|
|
24
|
+
allowsMultipleAnswers?: boolean;
|
|
25
|
+
correctOptionIds?: number[];
|
|
26
|
+
explanation?: string;
|
|
27
|
+
openPeriod?: number;
|
|
28
|
+
businessConnectionId?: string;
|
|
29
|
+
checklist?: ChecklistInput;
|
|
30
|
+
latitude?: number;
|
|
31
|
+
longitude?: number;
|
|
32
|
+
horizontalAccuracy?: number;
|
|
33
|
+
livePeriod?: number;
|
|
34
|
+
heading?: number;
|
|
35
|
+
proximityAlertRadius?: number;
|
|
36
|
+
title?: string;
|
|
37
|
+
address?: string;
|
|
38
|
+
phoneNumber?: string;
|
|
39
|
+
firstName?: string;
|
|
40
|
+
lastName?: string;
|
|
41
|
+
emoji?: string;
|
|
42
|
+
messageId?: number;
|
|
43
|
+
buttons?: InlineKeyboardButtonInput[][];
|
|
44
|
+
replyToMessageId?: number;
|
|
45
|
+
messageThreadId?: number;
|
|
46
|
+
disableNotification?: boolean;
|
|
47
|
+
protectContent?: boolean;
|
|
48
|
+
}
|
|
49
|
+
export interface AskDeps {
|
|
50
|
+
platformRoot: string;
|
|
51
|
+
accountId: string | undefined;
|
|
52
|
+
/** Per-invocation id threading one call's lines together. */
|
|
53
|
+
callId: string;
|
|
54
|
+
log: (line: string) => void;
|
|
55
|
+
fetchImpl?: typeof fetch;
|
|
56
|
+
}
|
|
57
|
+
export interface AskResult {
|
|
58
|
+
ok: boolean;
|
|
59
|
+
text: string;
|
|
60
|
+
isError: boolean;
|
|
61
|
+
}
|
|
62
|
+
/** Polls, checklists, locations, venues, contacts and dice, plus stopping a
|
|
63
|
+
* poll and editing or stopping a live location.
|
|
64
|
+
*
|
|
65
|
+
* Task 2594: these ten methods were reachable only through telegram-api, whose
|
|
66
|
+
* untyped params object gave the model no field names for any of them, so a
|
|
67
|
+
* malformed call was caught by Telegram's 400 and nothing earlier.
|
|
68
|
+
*
|
|
69
|
+
* Inline messages are not addressed. Telegram lets editMessageLiveLocation and
|
|
70
|
+
* stopMessageLiveLocation target an inline_message_id instead of a chat, but
|
|
71
|
+
* nothing on this install sends inline messages, so chatId stays required. */
|
|
72
|
+
export declare function telegramAsk(p: AskParams, deps: AskDeps): Promise<AskResult>;
|
|
73
|
+
//# sourceMappingURL=ask.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/tools/ask.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAKzF,MAAM,MAAM,OAAO,GACf,MAAM,GACN,WAAW,GACX,UAAU,GACV,OAAO,GACP,SAAS,GACT,MAAM,GACN,UAAU,GACV,eAAe,GACf,kBAAkB,GAClB,kBAAkB,CAAC;AAEvB;;kDAEkD;AAClD,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAWvD,CAAC;AAEH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,yBAAyB,EAAE,EAAE,CAAC;IACxC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,OAAO;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAwLD;;;;;;;;;+EAS+E;AAC/E,wBAAsB,WAAW,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAiEjF"}
|