@rubytech/create-maxy-code 0.1.582 → 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.
Files changed (409) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/routine-templates/dist/index.d.ts +1 -1
  3. package/payload/platform/lib/routine-templates/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/routine-templates/dist/index.js +5 -1
  5. package/payload/platform/lib/routine-templates/dist/index.js.map +1 -1
  6. package/payload/platform/lib/routine-templates/src/index.ts +4 -0
  7. package/payload/platform/lib/telegram-managed-bot/dist/index.d.ts +269 -0
  8. package/payload/platform/lib/telegram-managed-bot/dist/index.d.ts.map +1 -0
  9. package/payload/platform/lib/telegram-managed-bot/dist/index.js +351 -0
  10. package/payload/platform/lib/telegram-managed-bot/dist/index.js.map +1 -0
  11. package/payload/platform/lib/telegram-managed-bot/src/__tests__/managed-bot.test.ts +251 -0
  12. package/payload/platform/lib/telegram-managed-bot/src/index.ts +529 -0
  13. package/payload/platform/lib/telegram-managed-bot/tsconfig.json +9 -0
  14. package/payload/platform/lib/telegram-managed-bot/vitest.config.ts +9 -0
  15. package/payload/platform/lib/telegram-reach/dist/index.d.ts +80 -0
  16. package/payload/platform/lib/telegram-reach/dist/index.d.ts.map +1 -0
  17. package/payload/platform/lib/telegram-reach/dist/index.js +211 -0
  18. package/payload/platform/lib/telegram-reach/dist/index.js.map +1 -0
  19. package/payload/platform/lib/telegram-reach/src/__tests__/telegram-reach.test.ts +216 -0
  20. package/payload/platform/lib/telegram-reach/src/index.ts +262 -0
  21. package/payload/platform/lib/telegram-reach/tsconfig.json +9 -0
  22. package/payload/platform/lib/telegram-reach/vitest.config.ts +9 -0
  23. package/payload/platform/package.json +2 -2
  24. package/payload/platform/plugins/admin/PLUGIN.md +1 -1
  25. package/payload/platform/plugins/admin/hooks/__tests__/fs-schema-guard.test.sh +9 -0
  26. package/payload/platform/plugins/admin/hooks/__tests__/preference-consult-directive.test.sh +26 -0
  27. package/payload/platform/plugins/admin/hooks/fs-schema-guard.sh +20 -3
  28. package/payload/platform/plugins/admin/hooks/preference-consult-directive.sh +50 -5
  29. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +142 -8
  30. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +10 -0
  31. package/payload/platform/plugins/contacts/mcp/dist/__tests__/telegram-user-id.test.d.ts +2 -0
  32. package/payload/platform/plugins/contacts/mcp/dist/__tests__/telegram-user-id.test.d.ts.map +1 -0
  33. package/payload/platform/plugins/contacts/mcp/dist/__tests__/telegram-user-id.test.js +100 -0
  34. package/payload/platform/plugins/contacts/mcp/dist/__tests__/telegram-user-id.test.js.map +1 -0
  35. package/payload/platform/plugins/contacts/mcp/dist/index.js +11 -5
  36. package/payload/platform/plugins/contacts/mcp/dist/index.js.map +1 -1
  37. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.d.ts +5 -0
  38. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.d.ts.map +1 -1
  39. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.js +21 -4
  40. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.js.map +1 -1
  41. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.d.ts +5 -0
  42. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.d.ts.map +1 -1
  43. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.js +29 -1
  44. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.js.map +1 -1
  45. package/payload/platform/plugins/contacts/mcp/vitest.config.ts +14 -0
  46. package/payload/platform/plugins/docs/references/admin-ui.md +17 -3
  47. package/payload/platform/plugins/docs/references/channel-wake-and-prompt.md +15 -0
  48. package/payload/platform/plugins/docs/references/telegram-guide.md +109 -4
  49. package/payload/platform/plugins/filesystem/PLUGIN.md +2 -2
  50. package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/account-schema.test.d.ts +2 -0
  51. package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/account-schema.test.d.ts.map +1 -0
  52. package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/account-schema.test.js +108 -0
  53. package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/account-schema.test.js.map +1 -0
  54. package/payload/platform/plugins/filesystem/mcp/dist/lib/account-schema.d.ts +17 -0
  55. package/payload/platform/plugins/filesystem/mcp/dist/lib/account-schema.d.ts.map +1 -0
  56. package/payload/platform/plugins/filesystem/mcp/dist/lib/account-schema.js +162 -0
  57. package/payload/platform/plugins/filesystem/mcp/dist/lib/account-schema.js.map +1 -0
  58. package/payload/platform/plugins/filesystem/mcp/dist/tools/__tests__/schema-fence.test.d.ts +2 -0
  59. package/payload/platform/plugins/filesystem/mcp/dist/tools/__tests__/schema-fence.test.d.ts.map +1 -0
  60. package/payload/platform/plugins/filesystem/mcp/dist/tools/__tests__/schema-fence.test.js +116 -0
  61. package/payload/platform/plugins/filesystem/mcp/dist/tools/__tests__/schema-fence.test.js.map +1 -0
  62. package/payload/platform/plugins/filesystem/mcp/dist/tools/file-edit.d.ts.map +1 -1
  63. package/payload/platform/plugins/filesystem/mcp/dist/tools/file-edit.js +9 -0
  64. package/payload/platform/plugins/filesystem/mcp/dist/tools/file-edit.js.map +1 -1
  65. package/payload/platform/plugins/filesystem/mcp/dist/tools/file-write.d.ts.map +1 -1
  66. package/payload/platform/plugins/filesystem/mcp/dist/tools/file-write.js +10 -0
  67. package/payload/platform/plugins/filesystem/mcp/dist/tools/file-write.js.map +1 -1
  68. package/payload/platform/plugins/scheduling/PLUGIN.md +8 -2
  69. package/payload/platform/plugins/scheduling/mcp/dist/index.js +7 -2
  70. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  71. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js +53 -6
  72. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js.map +1 -1
  73. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js +38 -0
  74. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js.map +1 -1
  75. package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts +5 -3
  76. package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts.map +1 -1
  77. package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js +18 -3
  78. package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js.map +1 -1
  79. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts +30 -0
  80. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts.map +1 -1
  81. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js +112 -39
  82. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js.map +1 -1
  83. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +14 -1
  84. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
  85. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js +258 -8
  86. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js.map +1 -1
  87. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js +206 -3
  88. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js.map +1 -1
  89. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +29 -21
  90. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
  91. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +94 -14
  92. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
  93. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts.map +1 -1
  94. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js +29 -1
  95. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
  96. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts +30 -0
  97. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts.map +1 -1
  98. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js +69 -6
  99. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -1
  100. package/payload/platform/plugins/telegram/PLUGIN.md +44 -3
  101. package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-census.test.js +3 -3
  102. package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-guard.test.js +28 -2
  103. package/payload/platform/plugins/telegram/mcp/dist/__tests__/api-guard.test.js.map +1 -1
  104. package/payload/platform/plugins/telegram/mcp/dist/__tests__/ask-tool.test.js +87 -3
  105. package/payload/platform/plugins/telegram/mcp/dist/__tests__/ask-tool.test.js.map +1 -1
  106. package/payload/platform/plugins/telegram/mcp/dist/__tests__/bot-provision-tool.test.d.ts +2 -0
  107. package/payload/platform/plugins/telegram/mcp/dist/__tests__/bot-provision-tool.test.d.ts.map +1 -0
  108. package/payload/platform/plugins/telegram/mcp/dist/__tests__/bot-provision-tool.test.js +326 -0
  109. package/payload/platform/plugins/telegram/mcp/dist/__tests__/bot-provision-tool.test.js.map +1 -0
  110. package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-business.test.d.ts +2 -0
  111. package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-business.test.d.ts.map +1 -0
  112. package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-business.test.js +173 -0
  113. package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-business.test.js.map +1 -0
  114. package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-tool.test.js +79 -0
  115. package/payload/platform/plugins/telegram/mcp/dist/__tests__/card-tool.test.js.map +1 -1
  116. package/payload/platform/plugins/telegram/mcp/dist/__tests__/chat-send-policy.test.d.ts +2 -0
  117. package/payload/platform/plugins/telegram/mcp/dist/__tests__/chat-send-policy.test.d.ts.map +1 -0
  118. package/payload/platform/plugins/telegram/mcp/dist/__tests__/chat-send-policy.test.js +34 -0
  119. package/payload/platform/plugins/telegram/mcp/dist/__tests__/chat-send-policy.test.js.map +1 -0
  120. package/payload/platform/plugins/telegram/mcp/dist/__tests__/reach-tool.test.d.ts +2 -0
  121. package/payload/platform/plugins/telegram/mcp/dist/__tests__/reach-tool.test.d.ts.map +1 -0
  122. package/payload/platform/plugins/telegram/mcp/dist/__tests__/reach-tool.test.js +93 -0
  123. package/payload/platform/plugins/telegram/mcp/dist/__tests__/reach-tool.test.js.map +1 -0
  124. package/payload/platform/plugins/telegram/mcp/dist/__tests__/thread-tool.test.js +15 -1
  125. package/payload/platform/plugins/telegram/mcp/dist/__tests__/thread-tool.test.js.map +1 -1
  126. package/payload/platform/plugins/telegram/mcp/dist/__tests__/webhook-register.test.js +178 -2
  127. package/payload/platform/plugins/telegram/mcp/dist/__tests__/webhook-register.test.js.map +1 -1
  128. package/payload/platform/plugins/telegram/mcp/dist/index.js +26 -4
  129. package/payload/platform/plugins/telegram/mcp/dist/index.js.map +1 -1
  130. package/payload/platform/plugins/telegram/mcp/dist/lib/account-token.d.ts +19 -0
  131. package/payload/platform/plugins/telegram/mcp/dist/lib/account-token.d.ts.map +1 -1
  132. package/payload/platform/plugins/telegram/mcp/dist/lib/account-token.js +41 -1
  133. package/payload/platform/plugins/telegram/mcp/dist/lib/account-token.js.map +1 -1
  134. package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.d.ts +15 -20
  135. package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.d.ts.map +1 -1
  136. package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.js +27 -32
  137. package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.js.map +1 -1
  138. package/payload/platform/plugins/telegram/mcp/dist/lib/agent-active.d.ts +13 -0
  139. package/payload/platform/plugins/telegram/mcp/dist/lib/agent-active.d.ts.map +1 -1
  140. package/payload/platform/plugins/telegram/mcp/dist/lib/agent-active.js +22 -1
  141. package/payload/platform/plugins/telegram/mcp/dist/lib/agent-active.js.map +1 -1
  142. package/payload/platform/plugins/telegram/mcp/dist/lib/api-census.d.ts.map +1 -1
  143. package/payload/platform/plugins/telegram/mcp/dist/lib/api-census.js +6 -0
  144. package/payload/platform/plugins/telegram/mcp/dist/lib/api-census.js.map +1 -1
  145. package/payload/platform/plugins/telegram/mcp/dist/lib/api-guard.d.ts +1 -1
  146. package/payload/platform/plugins/telegram/mcp/dist/lib/api-guard.d.ts.map +1 -1
  147. package/payload/platform/plugins/telegram/mcp/dist/lib/api-guard.js +22 -2
  148. package/payload/platform/plugins/telegram/mcp/dist/lib/api-guard.js.map +1 -1
  149. package/payload/platform/plugins/telegram/mcp/dist/lib/business-window-store.d.ts +55 -0
  150. package/payload/platform/plugins/telegram/mcp/dist/lib/business-window-store.d.ts.map +1 -0
  151. package/payload/platform/plugins/telegram/mcp/dist/lib/business-window-store.js +116 -0
  152. package/payload/platform/plugins/telegram/mcp/dist/lib/business-window-store.js.map +1 -0
  153. package/payload/platform/plugins/telegram/mcp/dist/lib/chat-send-policy.d.ts +54 -0
  154. package/payload/platform/plugins/telegram/mcp/dist/lib/chat-send-policy.d.ts.map +1 -0
  155. package/payload/platform/plugins/telegram/mcp/dist/lib/chat-send-policy.js +90 -0
  156. package/payload/platform/plugins/telegram/mcp/dist/lib/chat-send-policy.js.map +1 -0
  157. package/payload/platform/plugins/telegram/mcp/dist/lib/telegram.d.ts +2 -53
  158. package/payload/platform/plugins/telegram/mcp/dist/lib/telegram.d.ts.map +1 -1
  159. package/payload/platform/plugins/telegram/mcp/dist/lib/telegram.js +8 -94
  160. package/payload/platform/plugins/telegram/mcp/dist/lib/telegram.js.map +1 -1
  161. package/payload/platform/plugins/telegram/mcp/dist/tools/api.d.ts.map +1 -1
  162. package/payload/platform/plugins/telegram/mcp/dist/tools/api.js +19 -0
  163. package/payload/platform/plugins/telegram/mcp/dist/tools/api.js.map +1 -1
  164. package/payload/platform/plugins/telegram/mcp/dist/tools/ask.d.ts.map +1 -1
  165. package/payload/platform/plugins/telegram/mcp/dist/tools/ask.js +31 -1
  166. package/payload/platform/plugins/telegram/mcp/dist/tools/ask.js.map +1 -1
  167. package/payload/platform/plugins/telegram/mcp/dist/tools/bot-provision.d.ts +64 -0
  168. package/payload/platform/plugins/telegram/mcp/dist/tools/bot-provision.d.ts.map +1 -0
  169. package/payload/platform/plugins/telegram/mcp/dist/tools/bot-provision.js +217 -0
  170. package/payload/platform/plugins/telegram/mcp/dist/tools/bot-provision.js.map +1 -0
  171. package/payload/platform/plugins/telegram/mcp/dist/tools/card.d.ts +7 -0
  172. package/payload/platform/plugins/telegram/mcp/dist/tools/card.d.ts.map +1 -1
  173. package/payload/platform/plugins/telegram/mcp/dist/tools/card.js +56 -0
  174. package/payload/platform/plugins/telegram/mcp/dist/tools/card.js.map +1 -1
  175. package/payload/platform/plugins/telegram/mcp/dist/tools/invoice.d.ts.map +1 -1
  176. package/payload/platform/plugins/telegram/mcp/dist/tools/invoice.js +15 -0
  177. package/payload/platform/plugins/telegram/mcp/dist/tools/invoice.js.map +1 -1
  178. package/payload/platform/plugins/telegram/mcp/dist/tools/media-send.d.ts.map +1 -1
  179. package/payload/platform/plugins/telegram/mcp/dist/tools/media-send.js +12 -0
  180. package/payload/platform/plugins/telegram/mcp/dist/tools/media-send.js.map +1 -1
  181. package/payload/platform/plugins/telegram/mcp/dist/tools/reach.d.ts +22 -0
  182. package/payload/platform/plugins/telegram/mcp/dist/tools/reach.d.ts.map +1 -0
  183. package/payload/platform/plugins/telegram/mcp/dist/tools/reach.js +67 -0
  184. package/payload/platform/plugins/telegram/mcp/dist/tools/reach.js.map +1 -0
  185. package/payload/platform/plugins/telegram/mcp/dist/tools/schemas.d.ts +19 -0
  186. package/payload/platform/plugins/telegram/mcp/dist/tools/schemas.d.ts.map +1 -1
  187. package/payload/platform/plugins/telegram/mcp/dist/tools/schemas.js +45 -0
  188. package/payload/platform/plugins/telegram/mcp/dist/tools/schemas.js.map +1 -1
  189. package/payload/platform/plugins/telegram/mcp/dist/tools/thread.d.ts.map +1 -1
  190. package/payload/platform/plugins/telegram/mcp/dist/tools/thread.js +12 -0
  191. package/payload/platform/plugins/telegram/mcp/dist/tools/thread.js.map +1 -1
  192. package/payload/platform/plugins/telegram/mcp/dist/tools/webhook-register.d.ts +4 -1
  193. package/payload/platform/plugins/telegram/mcp/dist/tools/webhook-register.d.ts.map +1 -1
  194. package/payload/platform/plugins/telegram/mcp/dist/tools/webhook-register.js +59 -4
  195. package/payload/platform/plugins/telegram/mcp/dist/tools/webhook-register.js.map +1 -1
  196. package/payload/platform/plugins/telegram/skills/build/SKILL.md +143 -5
  197. package/payload/platform/plugins/telegram/skills/configure/SKILL.md +87 -6
  198. package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +12 -0
  199. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts +36 -5
  200. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts.map +1 -1
  201. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js +103 -10
  202. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js.map +1 -1
  203. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  204. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +2 -0
  205. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  206. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  207. package/payload/platform/services/claude-session-manager/dist/http-server.js +42 -4
  208. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  209. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  210. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +19 -5
  211. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  212. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +9 -0
  213. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
  214. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +5 -1
  215. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
  216. package/payload/platform/services/telegram-channel/dist/instructions.d.ts.map +1 -1
  217. package/payload/platform/services/telegram-channel/dist/instructions.js +13 -0
  218. package/payload/platform/services/telegram-channel/dist/instructions.js.map +1 -1
  219. package/payload/platform/services/telegram-channel/dist/notification.d.ts +13 -0
  220. package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -1
  221. package/payload/platform/services/telegram-channel/dist/notification.js +13 -2
  222. package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -1
  223. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +52 -0
  224. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
  225. package/payload/platform/services/whatsapp-channel/dist/notification.js +64 -1
  226. package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
  227. package/payload/platform/services/whatsapp-channel/dist/server.d.ts.map +1 -1
  228. package/payload/platform/services/whatsapp-channel/dist/server.js +14 -2
  229. package/payload/platform/services/whatsapp-channel/dist/server.js.map +1 -1
  230. package/payload/platform/templates/account-schema/SCHEMA.md +17 -10
  231. package/payload/platform/templates/agents/admin/IDENTITY.md +5 -0
  232. package/payload/platform/templates/specialists/agents/data-manager.md +2 -2
  233. package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
  234. package/payload/server/{chunk-BFRB2U75.js → chunk-CV6AEMKH.js} +1 -0
  235. package/payload/server/{manager-CTVTF4YB.js → manager-FQSQSSJ3.js} +1 -1
  236. package/payload/server/public/activity.html +6 -6
  237. package/payload/server/public/agents.html +5 -5
  238. package/payload/server/public/assets/{AdminLoginScreens-AnJZfgFz.js → AdminLoginScreens-BLsDYWVi.js} +1 -1
  239. package/payload/server/public/assets/AdminLoginScreens-BLsDYWVi.js.br +0 -0
  240. package/payload/server/public/assets/AdminLoginScreens-BLsDYWVi.js.gz +0 -0
  241. package/payload/server/public/assets/{AdminShell-CEVqyQqg.js → AdminShell-BZS8jzFA.js} +1 -1
  242. package/payload/server/public/assets/AdminShell-BZS8jzFA.js.br +0 -0
  243. package/payload/server/public/assets/AdminShell-BZS8jzFA.js.gz +0 -0
  244. package/payload/server/public/assets/{activity-czUaUl8I.js → activity-DOjvoLdd.js} +1 -1
  245. package/payload/server/public/assets/activity-DOjvoLdd.js.br +0 -0
  246. package/payload/server/public/assets/activity-DOjvoLdd.js.gz +0 -0
  247. package/payload/server/public/assets/{admin-B0iRcfuk.js → admin-JrSNg29g.js} +1 -1
  248. package/payload/server/public/assets/admin-JrSNg29g.js.br +0 -0
  249. package/payload/server/public/assets/admin-JrSNg29g.js.gz +0 -0
  250. package/payload/server/public/assets/{agents-BocONCeQ.js → agents--9WMJVLC.js} +1 -1
  251. package/payload/server/public/assets/agents--9WMJVLC.js.br +0 -0
  252. package/payload/server/public/assets/agents--9WMJVLC.js.gz +0 -0
  253. package/payload/server/public/assets/{browser-Cy-rJm3t.js → browser-DiiMmTrM.js} +1 -1
  254. package/payload/server/public/assets/browser-DiiMmTrM.js.br +0 -0
  255. package/payload/server/public/assets/browser-DiiMmTrM.js.gz +0 -0
  256. package/payload/server/public/assets/{calendar-DUTKxWtd.js → calendar-CazmCzgO.js} +1 -1
  257. package/payload/server/public/assets/calendar-CazmCzgO.js.br +0 -0
  258. package/payload/server/public/assets/calendar-CazmCzgO.js.gz +0 -0
  259. package/payload/server/public/assets/chat-CB0TcyXX.js +1 -0
  260. package/payload/server/public/assets/chat-CB0TcyXX.js.br +0 -0
  261. package/payload/server/public/assets/chat-CB0TcyXX.js.gz +0 -0
  262. package/payload/server/public/assets/chevron-left-0tVo23Dh.js +1 -0
  263. package/payload/server/public/assets/chevron-left-0tVo23Dh.js.br +0 -0
  264. package/payload/server/public/assets/clock-D2cZ0sge.js +1 -0
  265. package/payload/server/public/assets/clock-D2cZ0sge.js.br +0 -0
  266. package/payload/server/public/assets/clock-D2cZ0sge.js.gz +0 -0
  267. package/payload/server/public/assets/{copy-DE9qmAs5.js → copy-C87QIN_o.js} +1 -1
  268. package/payload/server/public/assets/copy-C87QIN_o.js.br +0 -0
  269. package/payload/server/public/assets/copy-C87QIN_o.js.gz +0 -0
  270. package/payload/server/public/assets/data-CK7AMxPt.js +1 -0
  271. package/payload/server/public/assets/data-CK7AMxPt.js.br +0 -0
  272. package/payload/server/public/assets/data-CK7AMxPt.js.gz +0 -0
  273. package/payload/server/public/assets/{field-DE2tEfTo.js → field-C3kQgGWE.js} +1 -1
  274. package/payload/server/public/assets/field-C3kQgGWE.js.br +0 -0
  275. package/payload/server/public/assets/field-C3kQgGWE.js.gz +0 -0
  276. package/payload/server/public/assets/{file-text-BHfL2gqo.js → file-text-rWowl9RN.js} +1 -1
  277. package/payload/server/public/assets/file-text-rWowl9RN.js.br +0 -0
  278. package/payload/server/public/assets/file-text-rWowl9RN.js.gz +0 -0
  279. package/payload/server/public/assets/{graph-08S_BofN.js → graph-CVJKz1Uo.js} +1 -1
  280. package/payload/server/public/assets/graph-CVJKz1Uo.js.br +0 -0
  281. package/payload/server/public/assets/graph-CVJKz1Uo.js.gz +0 -0
  282. package/payload/server/public/assets/{graph-labels-C640Er5R.js → graph-labels-kneGnsHB.js} +1 -1
  283. package/payload/server/public/assets/graph-labels-kneGnsHB.js.br +0 -0
  284. package/payload/server/public/assets/graph-labels-kneGnsHB.js.gz +0 -0
  285. package/payload/server/public/assets/{jsx-runtime-FxjwOUbA.css → jsx-runtime-rMaiYjNu.css} +1 -1
  286. package/payload/server/public/assets/jsx-runtime-rMaiYjNu.css.br +0 -0
  287. package/payload/server/public/assets/{jsx-runtime-FxjwOUbA.css.gz → jsx-runtime-rMaiYjNu.css.gz} +0 -0
  288. package/payload/server/public/assets/{operator-DH5Kw3fL.js → operator-BGvB4hu4.js} +1 -1
  289. package/payload/server/public/assets/operator-BGvB4hu4.js.br +0 -0
  290. package/payload/server/public/assets/operator-BGvB4hu4.js.gz +0 -0
  291. package/payload/server/public/assets/{page-BDpa4HWT.js → page-DBQLOasI.js} +1 -1
  292. package/payload/server/public/assets/page-DBQLOasI.js.br +0 -0
  293. package/payload/server/public/assets/page-DBQLOasI.js.gz +0 -0
  294. package/payload/server/public/assets/{page-yn7ivq8O.js → page-DyVAu7tm.js} +1 -1
  295. package/payload/server/public/assets/page-DyVAu7tm.js.br +0 -0
  296. package/payload/server/public/assets/page-DyVAu7tm.js.gz +0 -0
  297. package/payload/server/public/assets/play-DgP7vl0r.js +1 -0
  298. package/payload/server/public/assets/play-DgP7vl0r.js.br +0 -0
  299. package/payload/server/public/assets/play-DgP7vl0r.js.gz +0 -0
  300. package/payload/server/public/assets/{public-D_qjqet7.js → public-BvUQR3hd.js} +1 -1
  301. package/payload/server/public/assets/public-BvUQR3hd.js.br +0 -0
  302. package/payload/server/public/assets/public-BvUQR3hd.js.gz +0 -0
  303. package/payload/server/public/assets/{rotate-ccw-Ixkq1iUA.js → rotate-ccw-Dnn7gbPh.js} +1 -1
  304. package/payload/server/public/assets/rotate-ccw-Dnn7gbPh.js.br +0 -0
  305. package/payload/server/public/assets/rotate-ccw-Dnn7gbPh.js.gz +0 -0
  306. package/payload/server/public/assets/{routines-Cxjlmcp7.js → routines-N8NmxPOZ.js} +1 -1
  307. package/payload/server/public/assets/routines-N8NmxPOZ.js.br +0 -0
  308. package/payload/server/public/assets/routines-N8NmxPOZ.js.gz +0 -0
  309. package/payload/server/public/assets/{skills-DEo9hSVX.js → skills-B2CRgO-U.js} +1 -1
  310. package/payload/server/public/assets/skills-B2CRgO-U.js.br +0 -0
  311. package/payload/server/public/assets/skills-B2CRgO-U.js.gz +0 -0
  312. package/payload/server/public/assets/{tasks-BxApOIXI.js → tasks-8QLGtlSj.js} +1 -1
  313. package/payload/server/public/assets/tasks-8QLGtlSj.js.br +0 -0
  314. package/payload/server/public/assets/tasks-8QLGtlSj.js.gz +0 -0
  315. package/payload/server/public/assets/{triangle-alert-BYzMcXv8.js → triangle-alert-el772yUQ.js} +1 -1
  316. package/payload/server/public/assets/triangle-alert-el772yUQ.js.br +0 -0
  317. package/payload/server/public/assets/triangle-alert-el772yUQ.js.gz +0 -0
  318. package/payload/server/public/assets/{useCopyFeedback-Bk2HVcjy.js → useCopyFeedback-DfNAu8hQ.js} +1 -1
  319. package/payload/server/public/assets/useCopyFeedback-DfNAu8hQ.js.br +0 -0
  320. package/payload/server/public/assets/useCopyFeedback-DfNAu8hQ.js.gz +0 -0
  321. package/payload/server/public/assets/{useMediaQuery-DEti-vAx.js → useMediaQuery-B469O83-.js} +1 -1
  322. package/payload/server/public/assets/useMediaQuery-B469O83-.js.br +0 -0
  323. package/payload/server/public/assets/{useMediaQuery-DEti-vAx.js.gz → useMediaQuery-B469O83-.js.gz} +0 -0
  324. package/payload/server/public/assets/{useVoiceRecorder-kQ92rL-f.js → useVoiceRecorder-Bb-51cJv.js} +1 -1
  325. package/payload/server/public/assets/useVoiceRecorder-Bb-51cJv.js.br +0 -0
  326. package/payload/server/public/assets/useVoiceRecorder-Bb-51cJv.js.gz +0 -0
  327. package/payload/server/public/assets/{wrench-BhLkHffv.js → wrench-Ck4phkdB.js} +1 -1
  328. package/payload/server/public/assets/wrench-Ck4phkdB.js.br +0 -0
  329. package/payload/server/public/assets/wrench-Ck4phkdB.js.gz +0 -0
  330. package/payload/server/public/browser.html +5 -5
  331. package/payload/server/public/calendar.html +8 -8
  332. package/payload/server/public/chat.html +14 -14
  333. package/payload/server/public/data.html +12 -12
  334. package/payload/server/public/field.html +3 -3
  335. package/payload/server/public/graph.html +10 -10
  336. package/payload/server/public/index.html +14 -14
  337. package/payload/server/public/operator.html +15 -15
  338. package/payload/server/public/public.html +14 -14
  339. package/payload/server/public/routines.html +8 -8
  340. package/payload/server/public/skills.html +6 -6
  341. package/payload/server/public/tasks.html +7 -7
  342. package/payload/server/server.js +3020 -1267
  343. package/payload/server/public/assets/AdminLoginScreens-AnJZfgFz.js.br +0 -0
  344. package/payload/server/public/assets/AdminLoginScreens-AnJZfgFz.js.gz +0 -0
  345. package/payload/server/public/assets/AdminShell-CEVqyQqg.js.br +0 -0
  346. package/payload/server/public/assets/AdminShell-CEVqyQqg.js.gz +0 -0
  347. package/payload/server/public/assets/activity-czUaUl8I.js.br +0 -0
  348. package/payload/server/public/assets/activity-czUaUl8I.js.gz +0 -0
  349. package/payload/server/public/assets/admin-B0iRcfuk.js.br +0 -0
  350. package/payload/server/public/assets/admin-B0iRcfuk.js.gz +0 -0
  351. package/payload/server/public/assets/agents-BocONCeQ.js.br +0 -0
  352. package/payload/server/public/assets/agents-BocONCeQ.js.gz +0 -0
  353. package/payload/server/public/assets/browser-Cy-rJm3t.js.br +0 -0
  354. package/payload/server/public/assets/browser-Cy-rJm3t.js.gz +0 -0
  355. package/payload/server/public/assets/calendar-DUTKxWtd.js.br +0 -0
  356. package/payload/server/public/assets/calendar-DUTKxWtd.js.gz +0 -0
  357. package/payload/server/public/assets/chat-Cis7sHsZ.js +0 -1
  358. package/payload/server/public/assets/chat-Cis7sHsZ.js.br +0 -0
  359. package/payload/server/public/assets/chat-Cis7sHsZ.js.gz +0 -0
  360. package/payload/server/public/assets/chevron-left-Bhhx8j2r.js +0 -1
  361. package/payload/server/public/assets/chevron-left-Bhhx8j2r.js.br +0 -0
  362. package/payload/server/public/assets/clock-Ca3nx7Cc.js +0 -1
  363. package/payload/server/public/assets/clock-Ca3nx7Cc.js.br +0 -0
  364. package/payload/server/public/assets/clock-Ca3nx7Cc.js.gz +0 -0
  365. package/payload/server/public/assets/copy-DE9qmAs5.js.br +0 -0
  366. package/payload/server/public/assets/copy-DE9qmAs5.js.gz +0 -0
  367. package/payload/server/public/assets/data-CkaAEeP1.js +0 -1
  368. package/payload/server/public/assets/data-CkaAEeP1.js.br +0 -0
  369. package/payload/server/public/assets/data-CkaAEeP1.js.gz +0 -0
  370. package/payload/server/public/assets/field-DE2tEfTo.js.br +0 -0
  371. package/payload/server/public/assets/field-DE2tEfTo.js.gz +0 -0
  372. package/payload/server/public/assets/file-text-BHfL2gqo.js.br +0 -0
  373. package/payload/server/public/assets/file-text-BHfL2gqo.js.gz +0 -0
  374. package/payload/server/public/assets/graph-08S_BofN.js.br +0 -0
  375. package/payload/server/public/assets/graph-08S_BofN.js.gz +0 -0
  376. package/payload/server/public/assets/graph-labels-C640Er5R.js.br +0 -0
  377. package/payload/server/public/assets/graph-labels-C640Er5R.js.gz +0 -0
  378. package/payload/server/public/assets/jsx-runtime-FxjwOUbA.css.br +0 -0
  379. package/payload/server/public/assets/operator-DH5Kw3fL.js.br +0 -0
  380. package/payload/server/public/assets/operator-DH5Kw3fL.js.gz +0 -0
  381. package/payload/server/public/assets/page-BDpa4HWT.js.br +0 -0
  382. package/payload/server/public/assets/page-BDpa4HWT.js.gz +0 -0
  383. package/payload/server/public/assets/page-yn7ivq8O.js.br +0 -0
  384. package/payload/server/public/assets/page-yn7ivq8O.js.gz +0 -0
  385. package/payload/server/public/assets/play-CMN7ht-S.js +0 -1
  386. package/payload/server/public/assets/play-CMN7ht-S.js.br +0 -0
  387. package/payload/server/public/assets/play-CMN7ht-S.js.gz +0 -0
  388. package/payload/server/public/assets/public-D_qjqet7.js.br +0 -0
  389. package/payload/server/public/assets/public-D_qjqet7.js.gz +0 -0
  390. package/payload/server/public/assets/rotate-ccw-Ixkq1iUA.js.br +0 -0
  391. package/payload/server/public/assets/rotate-ccw-Ixkq1iUA.js.gz +0 -0
  392. package/payload/server/public/assets/routines-Cxjlmcp7.js.br +0 -0
  393. package/payload/server/public/assets/routines-Cxjlmcp7.js.gz +0 -0
  394. package/payload/server/public/assets/skills-DEo9hSVX.js.br +0 -0
  395. package/payload/server/public/assets/skills-DEo9hSVX.js.gz +0 -0
  396. package/payload/server/public/assets/tasks-BxApOIXI.js.br +0 -0
  397. package/payload/server/public/assets/tasks-BxApOIXI.js.gz +0 -0
  398. package/payload/server/public/assets/triangle-alert-BYzMcXv8.js.br +0 -0
  399. package/payload/server/public/assets/triangle-alert-BYzMcXv8.js.gz +0 -0
  400. package/payload/server/public/assets/useCopyFeedback-Bk2HVcjy.js.br +0 -0
  401. package/payload/server/public/assets/useCopyFeedback-Bk2HVcjy.js.gz +0 -0
  402. package/payload/server/public/assets/useMediaQuery-DEti-vAx.js.br +0 -0
  403. package/payload/server/public/assets/useVoiceRecorder-kQ92rL-f.js.br +0 -0
  404. package/payload/server/public/assets/useVoiceRecorder-kQ92rL-f.js.gz +0 -0
  405. package/payload/server/public/assets/wrench-BhLkHffv.js.br +0 -0
  406. package/payload/server/public/assets/wrench-BhLkHffv.js.gz +0 -0
  407. /package/payload/server/public/assets/{jsx-runtime-BL3pljPe.js → jsx-runtime-BmNepPEn.js} +0 -0
  408. /package/payload/server/public/assets/{jsx-runtime-BL3pljPe.js.br → jsx-runtime-BmNepPEn.js.br} +0 -0
  409. /package/payload/server/public/assets/{jsx-runtime-BL3pljPe.js.gz → jsx-runtime-BmNepPEn.js.gz} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { resolve, join, relative, isAbsolute } from "node:path";
2
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { writeTelegramBotEntry, } from "../../../../../lib/telegram-managed-bot/dist/index.js";
3
3
  /** The single canonical maxy Telegram webhook path. Duplicated (intentionally)
4
4
  * with platform/ui/server/public-host-gate.ts PUBLIC_ALLOWED_PREFIXES — a unit
5
5
  * test asserts they agree. The official plugin's /channels/telegram is NOT this. */
@@ -26,23 +26,34 @@ export function botIdFromToken(token) {
26
26
  const id = token.slice(0, i);
27
27
  return /^\d+$/.test(id) ? id : null;
28
28
  }
29
- /** The account's own directory inside this brand install, or a refusal.
29
+ /** A directory under this brand install, or a refusal.
30
30
  *
31
- * The containment assertion is the point and is why this is exported rather
32
- * than inlined twice: a traversal in `accountId` (e.g. "../../.claude") must
33
- * never let account state land outside ~/.<brand>/. `relative` is
34
- * separator-aware; a non-brand path yields a result that escapes ("..") or is
35
- * absolute. Task 2588 gave this a second caller (the card store), and
36
- * duplicating a security check is how the two drift. */
37
- export function resolveAccountDir(platformRoot, accountId) {
38
- const dir = join(resolve(platformRoot, "..", "data", "accounts"), accountId);
31
+ * The containment assertion is the point and is why it lives in ONE function: a
32
+ * traversal in `accountId` (e.g. "../../.claude") must never let account state
33
+ * land outside ~/.<brand>/. `relative` is separator-aware; a non-brand path
34
+ * yields a result that escapes ("..") or is absolute. Task 2588 gave this a
35
+ * second caller (the card store) and Task 2625 a third (the Telegram message
36
+ * store), and duplicating a security check is how the copies drift — so the two
37
+ * exported resolvers below differ only in which directory they name. */
38
+ function containedDir(platformRoot, ...segments) {
39
39
  const brandRoot = resolve(platformRoot, "..");
40
+ const dir = join(brandRoot, ...segments);
40
41
  const rel = relative(brandRoot, resolve(dir));
41
42
  const underBrand = rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
42
43
  if (!underBrand)
43
44
  return { ok: false, error: "non-brand-path" };
44
45
  return { ok: true, dir };
45
46
  }
47
+ /** The account's own configuration directory inside this brand install. */
48
+ export function resolveAccountDir(platformRoot, accountId) {
49
+ return containedDir(platformRoot, "data", "accounts", accountId);
50
+ }
51
+ /** Task 2625 — the account's Telegram message store. A SIBLING of the accounts
52
+ * directory, not a child of it: `ui/app/lib/telegram/message-store.ts` writes to
53
+ * <brand>/data/telegram-messages/<accountId>/. */
54
+ export function resolveTelegramStoreDir(platformRoot, accountId) {
55
+ return containedDir(platformRoot, "data", "telegram-messages", accountId);
56
+ }
46
57
  /** Persist one bot entry into account.json's `telegram.bots` array, replacing
47
58
  * any entry with the same id and leaving every other entry byte-identical.
48
59
  *
@@ -66,27 +77,11 @@ export function persistTelegramBot(platformRoot, accountId, entry) {
66
77
  };
67
78
  }
68
79
  const dir = resolved.dir;
69
- const configPath = join(dir, "account.json");
70
- if (!existsSync(configPath)) {
71
- return { ok: false, error: `account.json not found at ${configPath}` };
72
- }
73
- let config;
74
- try {
75
- config = JSON.parse(readFileSync(configPath, "utf-8"));
76
- }
77
- catch (e) {
78
- return { ok: false, error: `account.json parse failed: ${e.message}` };
79
- }
80
- const telegram = config.telegram ?? {};
81
- const bots = Array.isArray(telegram.bots) ? telegram.bots : [];
82
- const at = bots.findIndex((b) => b && typeof b === "object" && b.id === entry.id);
83
- if (at >= 0)
84
- bots[at] = entry;
85
- else
86
- bots.push(entry);
87
- telegram.bots = bots;
88
- config.telegram = telegram;
89
- writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
90
- return { ok: true, dir };
80
+ // Task 2618 — the array merge itself moved to the shared lib, which the UI
81
+ // webhook route also calls when it persists a newly provisioned bot. This
82
+ // function keeps the part that is genuinely its own: the containment assertion
83
+ // above, which exists because `accountId` reaches it from a tool parameter.
84
+ const written = writeTelegramBotEntry(dir, entry);
85
+ return written.ok ? { ok: true, dir } : { ok: false, error: written.error, dir };
91
86
  }
92
87
  //# sourceMappingURL=account-write.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"account-write.js","sourceRoot":"","sources":["../../src/lib/account-write.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"account-write.js","sourceRoot":"","sources":["../../src/lib/account-write.ts"],"names":[],"mappings":"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"}
@@ -9,4 +9,17 @@ export declare function accountDirFor(platformRoot: string, accountId: string):
9
9
  * rejects a nonexistent slug. telegram-agent-active.test.ts asserts the two
10
10
  * agree. A bot may only be paired to an agent that can actually answer. */
11
11
  export declare function isActiveAgentSlug(accountDir: string, slug: string): boolean;
12
+ /** Task 2619 — every specialist card's FILE BASENAME on this account, without
13
+ * `.md`, sorted.
14
+ *
15
+ * Duplicated from platform/ui/app/lib/claude-agent/specialist-roster.ts
16
+ * `listSpecialistCardNames`, the same plugin/platform boundary `isActiveAgentSlug`
17
+ * and `botIdFromToken` are duplicated across; telegram-account-write.test.ts
18
+ * asserts the two agree.
19
+ *
20
+ * The basename, not the frontmatter `name`: `--agent <value>` resolves
21
+ * `<accountDir>/.claude/agents/<value>.md`, a mirror the session manager builds
22
+ * by basename, so a bot may only be bound to a name that can actually be
23
+ * spawned. */
24
+ export declare function listSpecialistCardNames(accountDir: string): string[];
12
25
  //# sourceMappingURL=agent-active.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-active.d.ts","sourceRoot":"","sources":["../../src/lib/agent-active.ts"],"names":[],"mappings":"AAGA,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED;;;;;;;4EAO4E;AAC5E,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQ3E"}
1
+ {"version":3,"file":"agent-active.d.ts","sourceRoot":"","sources":["../../src/lib/agent-active.ts"],"names":[],"mappings":"AAGA,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED;;;;;;;4EAO4E;AAC5E,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQ3E;AAED;;;;;;;;;;;eAWe;AACf,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAOpE"}
@@ -1,5 +1,5 @@
1
1
  import { resolve, join } from "node:path";
2
- import { existsSync, readFileSync } from "node:fs";
2
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
3
3
  /** The account's own directory under the brand install. */
4
4
  export function accountDirFor(platformRoot, accountId) {
5
5
  return join(resolve(platformRoot, "..", "data", "accounts"), accountId);
@@ -23,4 +23,25 @@ export function isActiveAgentSlug(accountDir, slug) {
23
23
  return false;
24
24
  }
25
25
  }
26
+ /** Task 2619 — every specialist card's FILE BASENAME on this account, without
27
+ * `.md`, sorted.
28
+ *
29
+ * Duplicated from platform/ui/app/lib/claude-agent/specialist-roster.ts
30
+ * `listSpecialistCardNames`, the same plugin/platform boundary `isActiveAgentSlug`
31
+ * and `botIdFromToken` are duplicated across; telegram-account-write.test.ts
32
+ * asserts the two agree.
33
+ *
34
+ * The basename, not the frontmatter `name`: `--agent <value>` resolves
35
+ * `<accountDir>/.claude/agents/<value>.md`, a mirror the session manager builds
36
+ * by basename, so a bot may only be bound to a name that can actually be
37
+ * spawned. */
38
+ export function listSpecialistCardNames(accountDir) {
39
+ const dir = join(accountDir, "specialists", "agents");
40
+ if (!existsSync(dir))
41
+ return [];
42
+ return readdirSync(dir)
43
+ .filter((f) => f.endsWith(".md"))
44
+ .map((f) => f.slice(0, -3))
45
+ .sort();
46
+ }
26
47
  //# sourceMappingURL=agent-active.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-active.js","sourceRoot":"","sources":["../../src/lib/agent-active.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEnD,2DAA2D;AAC3D,MAAM,UAAU,aAAa,CAAC,YAAoB,EAAE,SAAiB;IACnE,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;;4EAO4E;AAC5E,MAAM,UAAU,iBAAiB,CAAC,UAAkB,EAAE,IAAY;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;IACnE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,CAAC;QACH,OAAQ,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAA0B,CAAC,MAAM,KAAK,QAAQ,CAAC;IACrG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"agent-active.js","sourceRoot":"","sources":["../../src/lib/agent-active.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEhE,2DAA2D;AAC3D,MAAM,UAAU,aAAa,CAAC,YAAoB,EAAE,SAAiB;IACnE,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;;4EAO4E;AAC5E,MAAM,UAAU,iBAAiB,CAAC,UAAkB,EAAE,IAAY;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;IACnE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,CAAC;QACH,OAAQ,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAA0B,CAAC,MAAM,KAAK,QAAQ,CAAC;IACrG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;;;eAWe;AACf,MAAM,UAAU,uBAAuB,CAAC,UAAkB;IACxD,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;IACtD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,OAAO,WAAW,CAAC,GAAG,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;SAC1B,IAAI,EAAE,CAAC;AACZ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"api-census.d.ts","sourceRoot":"","sources":["../../src/lib/api-census.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,UAAU,0BAA0B,CAAC;AAClD,eAAO,MAAM,SAAS,qBAAqB,CAAC;AAE5C;;;;;;;;;2EAS2E;AAC3E,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAe1F;AAED;;;;;;;;;;8BAU8B;AAC9B,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAMzD;AAED;;0EAE0E;AAC1E,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAO3F;AAED;;;;;;;;;;;oEAWoE;AACpE,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYzD,CAAC;AAQH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG;IACzD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC,CAWA;AAED;;yBAEyB;AACzB,eAAO,MAAM,kBAAkB,UAAY,CAAC;AAE5C;;;;;;;;;;;;;;gEAcgE;AAChE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAgCxE"}
1
+ {"version":3,"file":"api-census.d.ts","sourceRoot":"","sources":["../../src/lib/api-census.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,UAAU,0BAA0B,CAAC;AAClD,eAAO,MAAM,SAAS,qBAAqB,CAAC;AAE5C;;;;;;;;;2EAS2E;AAC3E,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAe1F;AAED;;;;;;;;;;8BAU8B;AAC9B,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAMzD;AAED;;0EAE0E;AAC1E,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAO3F;AAED;;;;;;;;;;;oEAWoE;AACpE,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBzD,CAAC;AAQH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG;IACzD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC,CAWA;AAED;;yBAEyB;AACzB,eAAO,MAAM,kBAAkB,UAAY,CAAC;AAE5C;;;;;;;;;;;;;;gEAcgE;AAChE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAgCxE"}
@@ -7,6 +7,7 @@ import { THREAD_METHOD } from "../tools/thread.js";
7
7
  import { ASK_METHOD } from "../tools/ask.js";
8
8
  import { MEDIA_SEND_METHOD } from "../tools/media-send.js";
9
9
  import { INVOICE_METHOD } from "../tools/invoice.js";
10
+ import { MANAGED_BOT_METHODS } from "../../../../../lib/telegram-managed-bot/dist/index.js";
10
11
  export const CENSUS_TAG = "[telegram-api-census]";
11
12
  export const TOOLS_TAG = "[telegram-tools]";
12
13
  /** The local half, emitted once at MCP boot. No network, so every session pays
@@ -85,6 +86,11 @@ export const OWNED_METHODS = Object.freeze({
85
86
  ...Object.fromEntries(Object.values(ASK_METHOD).map((m) => [m, "telegram-ask"])),
86
87
  ...Object.fromEntries(Object.values(MEDIA_SEND_METHOD).map((m) => [m, "telegram-media-send"])),
87
88
  ...Object.fromEntries(Object.values(INVOICE_METHOD).map((m) => [m, "telegram-invoice"])),
89
+ // Task 2618 — all four, including the two `api-guard` also refuses. A refused
90
+ // method emits no `op=call` line so it can never be tallied, but leaving it out
91
+ // here would make the map disagree with the tool about what the tool covers,
92
+ // which is the drift this map exists to prevent.
93
+ ...Object.fromEntries(Object.values(MANAGED_BOT_METHODS).map((m) => [m, "telegram-bot-provision"])),
88
94
  });
89
95
  /** Only `telegram-api`'s own op=call line. The typed tools emit
90
96
  * `[telegram-tools] op=call`, which must NOT be counted: this census answers
@@ -1 +1 @@
1
- {"version":3,"file":"api-census.js","sourceRoot":"","sources":["../../src/lib/api-census.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-census.js","sourceRoot":"","sources":["../../src/lib/api-census.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,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uDAAuD,CAAC;AAE5F,MAAM,CAAC,MAAM,UAAU,GAAG,uBAAuB,CAAC;AAClD,MAAM,CAAC,MAAM,SAAS,GAAG,kBAAkB,CAAC;AAE5C;;;;;;;;;2EAS2E;AAC3E,MAAM,UAAU,cAAc,CAAC,YAAoB,EAAE,SAA6B;IAChF,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,UAAU,GAAG,kBAAkB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;YAC/D,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC;YACzB,SAAS,GAAG,UAAU,CAAC,MAAM,CAC3B,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAC/D,CAAC,MAAM,CAAC;QACX,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4CAA4C;IAC9C,CAAC;IACD,OAAO,GAAG,UAAU,YAAY,eAAe,CAAC,MAAM,YAAY,aAAa,SAAS,IAAI,cAAc,SAAS,EAAE,CAAC;AACxH,CAAC;AAED;;;;;;;;;;8BAU8B;AAC9B,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,oDAAoD,CAAC,EAAE,CAAC;QACpF,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;AACpB,CAAC;AAED;;0EAE0E;AAC1E,MAAM,UAAU,WAAW,CAAC,IAAuB;IACjD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAC;IAC5C,OAAO;QACL,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QAC9D,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;KACrD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;oEAWoE;AACpE,MAAM,CAAC,MAAM,aAAa,GAAqC,MAAM,CAAC,MAAM,CAAC;IAC3E,WAAW,EAAE,eAAe;IAC5B,eAAe,EAAE,eAAe;IAChC,sBAAsB,EAAE,eAAe;IACvC,mBAAmB,EAAE,eAAe;IACpC,OAAO,EAAE,sBAAsB;IAC/B,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACtF,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;IAChF,GAAG,MAAM,CAAC,WAAW,CACnB,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC,CACxE;IACD,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACxF,8EAA8E;IAC9E,gFAAgF;IAChF,6EAA6E;IAC7E,iDAAiD;IACjD,GAAG,MAAM,CAAC,WAAW,CACnB,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC,CAC7E;CACF,CAAC,CAAC;AAEH;;;oCAGoC;AACpC,MAAM,SAAS,GAAG,4CAA4C,CAAC;AAE/D,MAAM,UAAU,gBAAgB,CAAC,KAAuB;IAItD,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,MAAM,WAAW,GAA2B,EAAE,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAW,CAAC;QAC9B,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;AAChC,CAAC;AAED;;yBAEyB;AACzB,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAE5C;;;;;;;;;;;;;;gEAcgE;AAChE,MAAM,UAAU,qBAAqB,CAAC,MAA0B;IAC9D,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,MAAM,WAAW,GAA2B,EAAE,CAAC;IAC/C,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,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC7C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;oBAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC7E,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC;oBAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACjG,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4CAA4C;IAC9C,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACxE,2EAA2E;IAC3E,2EAA2E;IAC3E,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;SAChC,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;SAC5B,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,GAAG,SAAS,oBAAoB,UAAU,gBAAgB,SAAS,YAAY,KAAK,IAAI,GAAG,EAAE,CAAC;AACvG,CAAC"}
@@ -1,4 +1,4 @@
1
- export type RefusalReason = "owned-by-webhook-register" | "mutually-exclusive-with-webhook" | "moves-bot-off-cloud";
1
+ export type RefusalReason = "owned-by-webhook-register" | "mutually-exclusive-with-webhook" | "moves-bot-off-cloud" | "returns-a-credential";
2
2
  export type MethodVerdict = {
3
3
  allowed: true;
4
4
  listed: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"api-guard.d.ts","sourceRoot":"","sources":["../../src/lib/api-guard.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GACrB,2BAA2B,GAC3B,iCAAiC,GACjC,qBAAqB,CAAC;AAyB1B,MAAM,MAAM,aAAa,GACrB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAClC;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D;;;;4BAI4B;AAC5B,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAIvD;AAED,qDAAqD;AACrD,eAAO,MAAM,aAAa,QAA+B,CAAC"}
1
+ {"version":3,"file":"api-guard.d.ts","sourceRoot":"","sources":["../../src/lib/api-guard.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,aAAa,GACrB,2BAA2B,GAC3B,iCAAiC,GACjC,qBAAqB,GACrB,sBAAsB,CAAC;AA4C3B,MAAM,MAAM,aAAa,GACrB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAClC;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D;;;;4BAI4B;AAC5B,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAIvD;AAED,qDAAqD;AACrD,eAAO,MAAM,aAAa,QAA+B,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { BOT_API_METHODS } from "./api-methods.js";
2
- /** The five methods `telegram-api` will not relay, each with the reason and the
2
+ import { MANAGED_BOT_METHODS } from "../../../../../lib/telegram-managed-bot/dist/index.js";
3
+ /** The seven methods `telegram-api` will not relay, each with the reason and the
3
4
  * surface that owns the capability instead.
4
5
  *
5
6
  * Webhook state belongs to `telegram-webhook-register`, which enforces the
@@ -10,13 +11,32 @@ import { BOT_API_METHODS } from "./api-methods.js";
10
11
  * getUpdates is, in Telegram's words, one of "two mutually exclusive ways of
11
12
  * receiving updates", and it "will not work if an outgoing webhook is set up".
12
13
  *
13
- * logOut and close both move the bot off the cloud Bot API server. */
14
+ * logOut and close both move the bot off the cloud Bot API server.
15
+ *
16
+ * Task 2618 — getManagedBotToken and replaceManagedBotToken both RETURN A LIVE
17
+ * BOT TOKEN as their result. A passthrough relay hands that straight back as a
18
+ * tool result, which puts it in the transcript, and nothing downstream would
19
+ * notice. `telegram-bot-provision` fetches the same tokens, persists them to
20
+ * account.json and returns only the bot id. Listing them in OWNED_METHODS is
21
+ * not a substitute: that governs the census bucket, not whether the call runs.
22
+ *
23
+ * The two access-settings methods are deliberately NOT here. They return no
24
+ * credential, so refusing them would remove a capability while protecting
25
+ * nothing. */
14
26
  const REFUSALS = Object.freeze({
15
27
  setWebhook: { reason: "owned-by-webhook-register", owner: "telegram-webhook-register" },
16
28
  deleteWebhook: { reason: "owned-by-webhook-register", owner: "telegram-webhook-register" },
17
29
  getUpdates: { reason: "mutually-exclusive-with-webhook", owner: "telegram-webhook-register" },
18
30
  logOut: { reason: "moves-bot-off-cloud", owner: "the cloud Bot API server" },
19
31
  close: { reason: "moves-bot-off-cloud", owner: "the cloud Bot API server" },
32
+ [MANAGED_BOT_METHODS.token]: {
33
+ reason: "returns-a-credential",
34
+ owner: "telegram-bot-provision",
35
+ },
36
+ [MANAGED_BOT_METHODS.rotate]: {
37
+ reason: "returns-a-credential",
38
+ owner: "telegram-bot-provision",
39
+ },
20
40
  });
21
41
  const LISTED = new Set(BOT_API_METHODS);
22
42
  /** An unlisted method is ALLOWED, not refused. `BOT_API_METHODS` is a snapshot
@@ -1 +1 @@
1
- {"version":3,"file":"api-guard.js","sourceRoot":"","sources":["../../src/lib/api-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAOnD;;;;;;;;;;;uEAWuE;AACvE,MAAM,QAAQ,GACZ,MAAM,CAAC,MAAM,CAAC;IACZ,UAAU,EAAE,EAAE,MAAM,EAAE,2BAA2B,EAAE,KAAK,EAAE,2BAA2B,EAAE;IACvF,aAAa,EAAE,EAAE,MAAM,EAAE,2BAA2B,EAAE,KAAK,EAAE,2BAA2B,EAAE;IAC1F,UAAU,EAAE,EAAE,MAAM,EAAE,iCAAiC,EAAE,KAAK,EAAE,2BAA2B,EAAE;IAC7F,MAAM,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,KAAK,EAAE,0BAA0B,EAAE;IAC5E,KAAK,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,KAAK,EAAE,0BAA0B,EAAE;CAC5E,CAAC,CAAC;AAEL,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAC;AAMxC;;;;4BAI4B;AAC5B,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC;IACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;AACrD,CAAC;AAED,qDAAqD;AACrD,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC"}
1
+ {"version":3,"file":"api-guard.js","sourceRoot":"","sources":["../../src/lib/api-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uDAAuD,CAAC;AAQ5F;;;;;;;;;;;;;;;;;;;;;;eAsBe;AACf,MAAM,QAAQ,GACZ,MAAM,CAAC,MAAM,CAAC;IACZ,UAAU,EAAE,EAAE,MAAM,EAAE,2BAA2B,EAAE,KAAK,EAAE,2BAA2B,EAAE;IACvF,aAAa,EAAE,EAAE,MAAM,EAAE,2BAA2B,EAAE,KAAK,EAAE,2BAA2B,EAAE;IAC1F,UAAU,EAAE,EAAE,MAAM,EAAE,iCAAiC,EAAE,KAAK,EAAE,2BAA2B,EAAE;IAC7F,MAAM,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,KAAK,EAAE,0BAA0B,EAAE;IAC5E,KAAK,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,KAAK,EAAE,0BAA0B,EAAE;IAC3E,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE;QAC3B,MAAM,EAAE,sBAAsB;QAC9B,KAAK,EAAE,wBAAwB;KAChC;IACD,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE;QAC5B,MAAM,EAAE,sBAAsB;QAC9B,KAAK,EAAE,wBAAwB;KAChC;CACF,CAAC,CAAC;AAEL,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAC;AAMxC;;;;4BAI4B;AAC5B,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC;IACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;AACrD,CAAC;AAED,qDAAqD;AACrD,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC"}
@@ -0,0 +1,55 @@
1
+ /** Task 2615 — the read side of Telegram's 24-hour business reply window.
2
+ *
3
+ * `BusinessBotRights.can_reply` grants the right to "send and edit messages in
4
+ * the private chats that had incoming messages in the last 24 hours". Outside
5
+ * that window Telegram refuses the send, and nothing is emitted when the window
6
+ * closes, so a customer simply becomes unanswerable with no event anywhere.
7
+ * Deciding before the call is what turns that silence into a refusal the agent
8
+ * can act on.
9
+ *
10
+ * The platform writes the conversation (`platform/ui/app/lib/telegram/
11
+ * message-store.ts`); this reads it back. The window constant, the row shape and
12
+ * the path derivation are duplicated across the boundary on purpose — the plugin
13
+ * cannot import from `platform/ui/app`, the same boundary that already
14
+ * duplicates the webhook secret path, the card store, the live-location store
15
+ * and the business connection — and
16
+ * `ui/app/lib/telegram/__tests__/business-window-boundary.test.ts` asserts the
17
+ * two derivations agree.
18
+ *
19
+ * TWO ROOTS, and they are not the same one. The connection record sits in the
20
+ * ACCOUNT dir (`data/accounts/<accountId>`); the conversation store is its
21
+ * SIBLING, `data/telegram-messages/<accountId>`. `resolveAccountDir` is still
22
+ * the containment authority: its refusal is what stops a traversal in the
23
+ * account id from reaching outside the install.
24
+ */
25
+ /** Telegram's window, in seconds. Restated rather than imported, for the reason
26
+ * the header gives; the boundary test is what keeps it equal to the platform's
27
+ * `BUSINESS_REPLY_WINDOW_S`. */
28
+ export declare const BUSINESS_REPLY_WINDOW_S = 86400;
29
+ /** The business conversation's key. Mirrors `telegramBusinessChannelKey`. */
30
+ export declare function businessChannelKey(botId: string, chatId: string | number): string;
31
+ /** The newest Telegram-clock second among INBOUND rows in one business chat, or
32
+ * null when the chat holds none carrying that field.
33
+ *
34
+ * Inbound only: the window runs from what the CUSTOMER last sent, and counting
35
+ * an agent reply would extend it on every send so the refusal could never fire.
36
+ *
37
+ * Null rather than 0 for "nothing to measure from". Zero is a real Unix second
38
+ * and would read as 1970, refusing every reply in a conversation whose rows
39
+ * predate the field. */
40
+ export declare function newestInboundTelegramDate(platformRoot: string, accountId: string, channelKey: string): number | null;
41
+ export interface BusinessWindowVerdict {
42
+ allowed: boolean;
43
+ ageS: number | null;
44
+ reason: "ok" | "no-inbound" | "lapsed";
45
+ }
46
+ export declare function businessWindowVerdict(input: {
47
+ newestInboundDate: number | null;
48
+ nowMs: number;
49
+ }): BusinessWindowVerdict;
50
+ /** The refusal the agent reads. It names the WINDOW and the chat, never a
51
+ * parameter: there is no argument the caller could add to make this send work,
52
+ * which is the shape Task 2611 gave `ask.ts` for a checklist with no
53
+ * connection. */
54
+ export declare function businessWindowRefusal(chatId: number | string, ageS: number | null): string;
55
+ //# sourceMappingURL=business-window-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"business-window-store.d.ts","sourceRoot":"","sources":["../../src/lib/business-window-store.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;iCAEiC;AACjC,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAE9C,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEjF;AAmBD;;;;;;;;yBAQyB;AACzB,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CA0Bf;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,IAAI,GAAG,YAAY,GAAG,QAAQ,CAAC;CACxC;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,qBAAqB,CAQxB;AAED;;;kBAGkB;AAClB,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAc1F"}
@@ -0,0 +1,116 @@
1
+ import { join, resolve } from "node:path";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { resolveAccountDir } from "./account-write.js";
4
+ /** Task 2615 — the read side of Telegram's 24-hour business reply window.
5
+ *
6
+ * `BusinessBotRights.can_reply` grants the right to "send and edit messages in
7
+ * the private chats that had incoming messages in the last 24 hours". Outside
8
+ * that window Telegram refuses the send, and nothing is emitted when the window
9
+ * closes, so a customer simply becomes unanswerable with no event anywhere.
10
+ * Deciding before the call is what turns that silence into a refusal the agent
11
+ * can act on.
12
+ *
13
+ * The platform writes the conversation (`platform/ui/app/lib/telegram/
14
+ * message-store.ts`); this reads it back. The window constant, the row shape and
15
+ * the path derivation are duplicated across the boundary on purpose — the plugin
16
+ * cannot import from `platform/ui/app`, the same boundary that already
17
+ * duplicates the webhook secret path, the card store, the live-location store
18
+ * and the business connection — and
19
+ * `ui/app/lib/telegram/__tests__/business-window-boundary.test.ts` asserts the
20
+ * two derivations agree.
21
+ *
22
+ * TWO ROOTS, and they are not the same one. The connection record sits in the
23
+ * ACCOUNT dir (`data/accounts/<accountId>`); the conversation store is its
24
+ * SIBLING, `data/telegram-messages/<accountId>`. `resolveAccountDir` is still
25
+ * the containment authority: its refusal is what stops a traversal in the
26
+ * account id from reaching outside the install.
27
+ */
28
+ /** Telegram's window, in seconds. Restated rather than imported, for the reason
29
+ * the header gives; the boundary test is what keeps it equal to the platform's
30
+ * `BUSINESS_REPLY_WINDOW_S`. */
31
+ export const BUSINESS_REPLY_WINDOW_S = 86_400;
32
+ /** The business conversation's key. Mirrors `telegramBusinessChannelKey`. */
33
+ export function businessChannelKey(botId, chatId) {
34
+ return `${botId}:biz:${chatId}`;
35
+ }
36
+ function conversationFile(platformRoot, accountId, channelKey) {
37
+ // The guard, not the path: a traversal in the account id must read as no
38
+ // conversation rather than reach outside the install.
39
+ if (!resolveAccountDir(platformRoot, accountId).ok)
40
+ return null;
41
+ // Both halves are Telegram numeric ids around the literal `biz`, so nothing
42
+ // here can carry a separator. Mirrors `isStorableChannelKey`.
43
+ if (!/^-?\d+:biz:-?\d+$/.test(channelKey))
44
+ return null;
45
+ return join(resolve(platformRoot, "..", "data", "telegram-messages", accountId), `${channelKey.replaceAll(":", "_")}.jsonl`);
46
+ }
47
+ /** The newest Telegram-clock second among INBOUND rows in one business chat, or
48
+ * null when the chat holds none carrying that field.
49
+ *
50
+ * Inbound only: the window runs from what the CUSTOMER last sent, and counting
51
+ * an agent reply would extend it on every send so the refusal could never fire.
52
+ *
53
+ * Null rather than 0 for "nothing to measure from". Zero is a real Unix second
54
+ * and would read as 1970, refusing every reply in a conversation whose rows
55
+ * predate the field. */
56
+ export function newestInboundTelegramDate(platformRoot, accountId, channelKey) {
57
+ const path = conversationFile(platformRoot, accountId, channelKey);
58
+ if (path === null || !existsSync(path))
59
+ return null;
60
+ let newest = null;
61
+ try {
62
+ for (const line of readFileSync(path, "utf-8").split("\n")) {
63
+ if (!line.trim())
64
+ continue;
65
+ let row;
66
+ try {
67
+ row = JSON.parse(line);
68
+ }
69
+ catch {
70
+ // A partial write from a crash mid-append is skipped, never fatal.
71
+ continue;
72
+ }
73
+ if (row.kind === "update")
74
+ continue;
75
+ if (row.fromMe === true)
76
+ continue;
77
+ const d = row.telegramDate;
78
+ if (typeof d !== "number" || !Number.isFinite(d))
79
+ continue;
80
+ if (newest === null || d > newest)
81
+ newest = d;
82
+ }
83
+ }
84
+ catch {
85
+ // An unreadable store reads as no inbound, so the tool refuses by name
86
+ // rather than taking the call down over a file the caller never sees.
87
+ return null;
88
+ }
89
+ return newest;
90
+ }
91
+ export function businessWindowVerdict(input) {
92
+ if (input.newestInboundDate === null) {
93
+ return { allowed: false, ageS: null, reason: "no-inbound" };
94
+ }
95
+ const ageS = Math.floor(input.nowMs / 1000) - input.newestInboundDate;
96
+ // Inclusive at the boundary: Telegram's wording is "in the last 24 hours".
97
+ if (ageS > BUSINESS_REPLY_WINDOW_S)
98
+ return { allowed: false, ageS, reason: "lapsed" };
99
+ return { allowed: true, ageS, reason: "ok" };
100
+ }
101
+ /** The refusal the agent reads. It names the WINDOW and the chat, never a
102
+ * parameter: there is no argument the caller could add to make this send work,
103
+ * which is the shape Task 2611 gave `ask.ts` for a checklist with no
104
+ * connection. */
105
+ export function businessWindowRefusal(chatId, ageS) {
106
+ if (ageS === null) {
107
+ return (`Cannot send to business chat ${chatId}: no message has ever been received from it. ` +
108
+ "Telegram allows a business account reply only in a chat that sent an incoming " +
109
+ "message in the last 24 hours.");
110
+ }
111
+ const hours = Math.floor(ageS / 3600);
112
+ return (`Cannot send to business chat ${chatId}: the last message from it arrived ${hours} hours ago. ` +
113
+ "Telegram allows a business account reply only within 24 hours of an incoming message, " +
114
+ "and that window has closed.");
115
+ }
116
+ //# sourceMappingURL=business-window-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"business-window-store.js","sourceRoot":"","sources":["../../src/lib/business-window-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Task 2617 — may this bot send to this chat id?
3
+ *
4
+ * THE TWIN of platform/ui/app/lib/telegram/chat-send-policy.ts. The plugin cannot
5
+ * import from platform/ui/app, so the rule lives twice; the two are held in step
6
+ * by one shared table of cases asserted in both test files. A divergence means the
7
+ * agent's tools and the platform's scheduled send disagree about what may be
8
+ * posted to, which is the failure that table exists to catch.
9
+ *
10
+ * THE PROBLEM. A Telegram chat id cannot tell a channel from a supergroup: both
11
+ * are `-100`-prefixed, and no local check separates them. So the gate is keyed on
12
+ * the prefix and closed by BOTH allowlists — a `-100` id the operator named in
13
+ * `allowChannels` (Task 2617) or in `allowGroups` (Task 2616) is a broadcast
14
+ * surface somebody sanctioned; one in neither is a broadcast surface nobody did.
15
+ *
16
+ * WHY BEFORE THE NETWORK CALL. A channel post reaches every subscriber and cannot
17
+ * be unsent. A gate that fired on Telegram's verdict would be a record of damage
18
+ * rather than a refusal, so `checkTelegramChatSend` is pure and every caller
19
+ * applies it before building a request.
20
+ */
21
+ export type ChatSendVerdict = {
22
+ allowed: true;
23
+ reason: "not-broadcast" | "allowlist-match";
24
+ } | {
25
+ allowed: false;
26
+ reason: "not-in-allowChannels";
27
+ };
28
+ export declare function checkTelegramChatSend(params: {
29
+ chatId: number;
30
+ allowChannels: readonly number[];
31
+ allowGroups: readonly number[];
32
+ }): ChatSendVerdict;
33
+ /**
34
+ * The gate as each tool applies it: read the allowlists, decide, print the line,
35
+ * and hand back the refusal text when refused.
36
+ *
37
+ * One home, because six tools applying one rule six ways is the drift this task
38
+ * exists to prevent. The line is printed on BOTH outcomes so an allowed send and a
39
+ * refused one are the same grep, and `messageId=none` is always present because a
40
+ * field that appears only on some outcomes cannot be aggregated on.
41
+ */
42
+ export declare function gateChatSend(input: {
43
+ platformRoot: string;
44
+ accountId: string;
45
+ botId: string;
46
+ chatId: string | number;
47
+ log: (line: string) => void;
48
+ }): {
49
+ allowed: true;
50
+ } | {
51
+ allowed: false;
52
+ text: string;
53
+ };
54
+ //# sourceMappingURL=chat-send-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-send-policy.d.ts","sourceRoot":"","sources":["../../src/lib/chat-send-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAYH,MAAM,MAAM,eAAe,GACvB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,eAAe,GAAG,iBAAiB,CAAA;CAAE,GAC9D;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAEvD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC,GAAG,eAAe,CAQlB;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAiDvD"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Task 2617 — may this bot send to this chat id?
3
+ *
4
+ * THE TWIN of platform/ui/app/lib/telegram/chat-send-policy.ts. The plugin cannot
5
+ * import from platform/ui/app, so the rule lives twice; the two are held in step
6
+ * by one shared table of cases asserted in both test files. A divergence means the
7
+ * agent's tools and the platform's scheduled send disagree about what may be
8
+ * posted to, which is the failure that table exists to catch.
9
+ *
10
+ * THE PROBLEM. A Telegram chat id cannot tell a channel from a supergroup: both
11
+ * are `-100`-prefixed, and no local check separates them. So the gate is keyed on
12
+ * the prefix and closed by BOTH allowlists — a `-100` id the operator named in
13
+ * `allowChannels` (Task 2617) or in `allowGroups` (Task 2616) is a broadcast
14
+ * surface somebody sanctioned; one in neither is a broadcast surface nobody did.
15
+ *
16
+ * WHY BEFORE THE NETWORK CALL. A channel post reaches every subscriber and cannot
17
+ * be unsent. A gate that fired on Telegram's verdict would be a record of damage
18
+ * rather than a refusal, so `checkTelegramChatSend` is pure and every caller
19
+ * applies it before building a request.
20
+ */
21
+ import { readBotChatAllowlists } from "./account-token.js";
22
+ const TAG = "[telegram-outbound]";
23
+ /** Telegram's own prefix for a supergroup or a channel. A private chat id is
24
+ * positive and a basic group id is negative without it, so this is the exact set
25
+ * of ids that COULD be a channel. Compared as digits rather than by magnitude:
26
+ * the question is what Telegram's id scheme says, not how large the number is. */
27
+ const BROADCAST_PREFIX = "-100";
28
+ export function checkTelegramChatSend(params) {
29
+ if (!String(params.chatId).startsWith(BROADCAST_PREFIX)) {
30
+ return { allowed: true, reason: "not-broadcast" };
31
+ }
32
+ if (params.allowChannels.includes(params.chatId) || params.allowGroups.includes(params.chatId)) {
33
+ return { allowed: true, reason: "allowlist-match" };
34
+ }
35
+ return { allowed: false, reason: "not-in-allowChannels" };
36
+ }
37
+ /**
38
+ * The gate as each tool applies it: read the allowlists, decide, print the line,
39
+ * and hand back the refusal text when refused.
40
+ *
41
+ * One home, because six tools applying one rule six ways is the drift this task
42
+ * exists to prevent. The line is printed on BOTH outcomes so an allowed send and a
43
+ * refused one are the same grep, and `messageId=none` is always present because a
44
+ * field that appears only on some outcomes cannot be aggregated on.
45
+ */
46
+ export function gateChatSend(input) {
47
+ // An @username addresses a CHANNEL or a supergroup and nothing else — Telegram
48
+ // documents `chat_id` as "the target chat or username of the target channel (in
49
+ // the format @channelusername)", and the tool schema offers both forms to the
50
+ // model. It cannot be resolved to a numeric id without asking Telegram, and the
51
+ // allowlists hold numeric ids, so there is nothing local to check it against.
52
+ //
53
+ // Refused rather than passed through. Passing it through would leave every
54
+ // allowlist in this file bypassable by naming the same channel a different way,
55
+ // which is the whole gate defeated by a string. A private chat cannot be
56
+ // addressed this way at all, so nothing else is lost.
57
+ const named = typeof input.chatId === "string" ? input.chatId.trim() : "";
58
+ if (named.startsWith("@")) {
59
+ input.log(`${TAG} op=channel-send botId=${input.botId} chatId=${named} ` +
60
+ `allowed=no reason=username-not-allowlistable messageId=none`);
61
+ return {
62
+ allowed: false,
63
+ text: `Refused: "${named}" names a channel or supergroup by @username, and this bot's ` +
64
+ `allowlist holds numeric chat ids, so there is nothing to check it against. ` +
65
+ `Nothing was sent. Use the numeric chat id, and make sure it is in allowChannels ` +
66
+ `(for a channel) or allowGroups (for a group) on bot ${input.botId}.`,
67
+ };
68
+ }
69
+ const chatId = Number(input.chatId);
70
+ // A chat id Telegram will reject anyway, and NOT an @username — that is refused
71
+ // above. Passed through so Telegram's own 400 is the verdict on a malformed id,
72
+ // rather than this gate inventing a refusal for a question it was not given.
73
+ if (!Number.isFinite(chatId))
74
+ return { allowed: true };
75
+ const lists = readBotChatAllowlists(input.platformRoot, input.accountId, input.botId);
76
+ const verdict = checkTelegramChatSend({ chatId, ...lists });
77
+ input.log(`${TAG} op=channel-send botId=${input.botId} chatId=${chatId} ` +
78
+ `allowed=${verdict.allowed ? "yes" : "no"} reason=${verdict.reason} messageId=none`);
79
+ if (verdict.allowed)
80
+ return { allowed: true };
81
+ return {
82
+ allowed: false,
83
+ text: `Refused: ${chatId} is a Telegram channel or supergroup that is not on this bot's ` +
84
+ `allowlist, so nothing was sent. A channel post reaches every subscriber and cannot ` +
85
+ `be unsent, which is why this is refused rather than attempted. To allow it, add ` +
86
+ `${chatId} to allowChannels (if it is a channel) or allowGroups (if it is a group) ` +
87
+ `on bot ${input.botId}.`,
88
+ };
89
+ }
90
+ //# sourceMappingURL=chat-send-policy.js.map