@poolzin/pool-bot 2026.2.25 → 2026.2.26

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 (506) hide show
  1. package/dist/acp/event-mapper.js +87 -22
  2. package/dist/acp/meta.js +12 -6
  3. package/dist/agents/agent-paths.js +8 -9
  4. package/dist/agents/agent-scope.js +7 -5
  5. package/dist/agents/auth-profiles/oauth.js +148 -64
  6. package/dist/agents/auth-profiles/session-override.js +13 -7
  7. package/dist/agents/bash-tools.exec-host-gateway.js +14 -4
  8. package/dist/agents/bash-tools.exec-runtime.js +2 -25
  9. package/dist/agents/bedrock-discovery.js +3 -1
  10. package/dist/agents/byteplus-models.js +97 -0
  11. package/dist/agents/chutes-oauth.js +1 -0
  12. package/dist/agents/cli-runner/helpers.js +4 -0
  13. package/dist/agents/compaction.js +41 -14
  14. package/dist/agents/doubao-models.js +121 -0
  15. package/dist/agents/failover-error.js +2 -0
  16. package/dist/agents/huggingface-models.js +5 -3
  17. package/dist/agents/live-model-filter.js +5 -0
  18. package/dist/agents/minimax-vlm.js +10 -8
  19. package/dist/agents/model-auth.js +6 -0
  20. package/dist/agents/model-catalog.js +3 -1
  21. package/dist/agents/model-selection.js +7 -1
  22. package/dist/agents/models-config.providers.js +93 -11
  23. package/dist/agents/ollama-stream.js +117 -4
  24. package/dist/agents/opencode-zen-models.js +22 -11
  25. package/dist/agents/pi-embedded-helpers/errors.js +55 -33
  26. package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
  27. package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
  28. package/dist/agents/pi-embedded-helpers.js +1 -1
  29. package/dist/agents/pi-embedded-runner/compact.js +29 -7
  30. package/dist/agents/pi-embedded-runner/extensions.js +28 -26
  31. package/dist/agents/pi-embedded-runner/google.js +20 -8
  32. package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
  33. package/dist/agents/pi-embedded-runner/run.js +71 -12
  34. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
  35. package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
  36. package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
  37. package/dist/agents/pi-embedded-runner/thinking.js +42 -0
  38. package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
  39. package/dist/agents/pi-embedded-runner/utils.js +7 -10
  40. package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
  41. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
  42. package/dist/agents/pi-embedded-subscribe.js +9 -4
  43. package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
  44. package/dist/agents/pi-embedded-utils.js +3 -0
  45. package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
  46. package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
  47. package/dist/agents/pi-settings.js +40 -0
  48. package/dist/agents/pi-tools.policy.js +2 -1
  49. package/dist/agents/provider/config-loader.js +1 -1
  50. package/dist/agents/sandbox/browser.js +170 -33
  51. package/dist/agents/sandbox/config-hash.js +14 -27
  52. package/dist/agents/sandbox/config.js +21 -2
  53. package/dist/agents/sandbox/constants.js +2 -0
  54. package/dist/agents/sandbox/docker.js +16 -2
  55. package/dist/agents/sandbox/novnc-auth.js +62 -0
  56. package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
  57. package/dist/agents/sandbox/shared.js +10 -6
  58. package/dist/agents/sandbox-paths.js +24 -11
  59. package/dist/agents/schema/clean-for-gemini.js +132 -85
  60. package/dist/agents/session-slug.js +10 -5
  61. package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
  62. package/dist/agents/session-tool-result-guard.js +3 -1
  63. package/dist/agents/session-transcript-repair.js +40 -6
  64. package/dist/agents/skills/bundled-dir.js +19 -5
  65. package/dist/agents/skills/env-overrides.js +124 -43
  66. package/dist/agents/skills/frontmatter.js +6 -6
  67. package/dist/agents/skills/plugin-skills.js +14 -7
  68. package/dist/agents/skills/workspace.js +1 -0
  69. package/dist/agents/subagent-announce.js +251 -49
  70. package/dist/agents/subagent-lifecycle-events.js +19 -0
  71. package/dist/agents/subagent-registry-cleanup.js +31 -0
  72. package/dist/agents/subagent-registry-completion.js +68 -0
  73. package/dist/agents/subagent-registry-queries.js +117 -0
  74. package/dist/agents/subagent-registry-state.js +46 -0
  75. package/dist/agents/subagent-registry.js +252 -221
  76. package/dist/agents/subagent-registry.store.js +1 -0
  77. package/dist/agents/subagent-registry.types.js +1 -0
  78. package/dist/agents/subagent-spawn.js +195 -7
  79. package/dist/agents/system-prompt.js +22 -6
  80. package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
  81. package/dist/agents/test-helpers/fast-core-tools.js +1 -17
  82. package/dist/agents/timeout.js +18 -6
  83. package/dist/agents/tool-call-id.js +1 -1
  84. package/dist/agents/tool-display-common.js +162 -29
  85. package/dist/agents/tool-images.js +82 -9
  86. package/dist/agents/tool-policy.js +51 -26
  87. package/dist/agents/tools/browser-tool.js +2 -2
  88. package/dist/agents/tools/canvas-tool.js +27 -1
  89. package/dist/agents/tools/common.js +45 -0
  90. package/dist/agents/tools/discord-actions-guild.js +4 -1
  91. package/dist/agents/tools/gateway-tool.js +3 -1
  92. package/dist/agents/tools/nodes-utils.js +1 -10
  93. package/dist/agents/tools/sessions-send-helpers.js +12 -6
  94. package/dist/agents/tools/sessions-spawn-tool.js +8 -2
  95. package/dist/agents/tools/subagents-tool.js +2 -1
  96. package/dist/agents/tools/whatsapp-actions.js +10 -2
  97. package/dist/agents/tools/whatsapp-target-auth.js +18 -0
  98. package/dist/agents/transcript-policy.js +22 -8
  99. package/dist/agents/venice-models.js +11 -3
  100. package/dist/auto-reply/commands-registry.data.js +51 -0
  101. package/dist/auto-reply/commands-registry.js +4 -3
  102. package/dist/auto-reply/group-activation.js +10 -5
  103. package/dist/auto-reply/inbound-debounce.js +10 -5
  104. package/dist/auto-reply/reply/abort.js +1 -1
  105. package/dist/auto-reply/reply/agent-runner-execution.js +4 -1
  106. package/dist/auto-reply/reply/bash-command.js +41 -39
  107. package/dist/auto-reply/reply/command-gates.js +25 -0
  108. package/dist/auto-reply/reply/commands-allowlist.js +111 -72
  109. package/dist/auto-reply/reply/commands-bash.js +6 -5
  110. package/dist/auto-reply/reply/commands-config.js +30 -28
  111. package/dist/auto-reply/reply/commands-core.js +2 -1
  112. package/dist/auto-reply/reply/commands-info.js +1 -0
  113. package/dist/auto-reply/reply/commands-models.js +65 -14
  114. package/dist/auto-reply/reply/commands-session.js +237 -82
  115. package/dist/auto-reply/reply/commands-setunset.js +45 -0
  116. package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
  117. package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
  118. package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
  119. package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
  120. package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
  121. package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
  122. package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
  123. package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
  124. package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
  125. package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
  126. package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
  127. package/dist/auto-reply/reply/commands-subagents.js +51 -587
  128. package/dist/auto-reply/reply/commands-tts.js +10 -5
  129. package/dist/auto-reply/reply/config-value.js +10 -5
  130. package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
  131. package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
  132. package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
  133. package/dist/auto-reply/reply/followup-runner.js +1 -0
  134. package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
  135. package/dist/auto-reply/reply/get-reply-directives.js +17 -28
  136. package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
  137. package/dist/auto-reply/reply/get-reply.js +71 -12
  138. package/dist/auto-reply/reply/model-selection.js +80 -39
  139. package/dist/auto-reply/reply/queue/enqueue.js +10 -5
  140. package/dist/auto-reply/reply/queue/state.js +13 -12
  141. package/dist/auto-reply/reply/reply-payloads.js +67 -36
  142. package/dist/auto-reply/reply/reply-reference.js +9 -8
  143. package/dist/auto-reply/reply/route-reply.js +15 -8
  144. package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
  145. package/dist/auto-reply/reply/session.js +22 -6
  146. package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
  147. package/dist/auto-reply/reply/subagents-utils.js +56 -30
  148. package/dist/auto-reply/reply/typing.js +46 -21
  149. package/dist/auto-reply/send-policy.js +14 -7
  150. package/dist/auto-reply/status.js +140 -16
  151. package/dist/auto-reply/templating.js +10 -5
  152. package/dist/auto-reply/thinking.js +7 -16
  153. package/dist/auto-reply/tokens.js +21 -5
  154. package/dist/browser/bridge-server.js +36 -20
  155. package/dist/browser/cdp.helpers.js +7 -14
  156. package/dist/browser/cdp.js +35 -15
  157. package/dist/browser/chrome.profile-decoration.js +7 -4
  158. package/dist/browser/config.js +4 -0
  159. package/dist/browser/extension-relay-auth.js +55 -0
  160. package/dist/browser/extension-relay.js +74 -29
  161. package/dist/browser/navigation-guard.js +9 -1
  162. package/dist/browser/paths.js +77 -0
  163. package/dist/browser/profiles.js +13 -8
  164. package/dist/browser/pw-ai-module.js +10 -5
  165. package/dist/browser/pw-session.js +76 -39
  166. package/dist/browser/pw-tools-core.interactions.js +14 -7
  167. package/dist/browser/pw-tools-core.state.js +12 -6
  168. package/dist/browser/routes/agent.act.js +2 -2
  169. package/dist/browser/server-context.js +7 -0
  170. package/dist/build-info.json +3 -3
  171. package/dist/channels/allow-from.js +2 -1
  172. package/dist/channels/allowlists/resolve-utils.js +43 -19
  173. package/dist/channels/channel-config.js +14 -7
  174. package/dist/channels/draft-stream-loop.js +7 -0
  175. package/dist/channels/model-overrides.js +82 -0
  176. package/dist/channels/plugins/normalize/imessage.js +14 -7
  177. package/dist/channels/plugins/normalize/slack.js +10 -5
  178. package/dist/channels/plugins/normalize/telegram.js +14 -7
  179. package/dist/channels/plugins/outbound/discord.js +80 -8
  180. package/dist/channels/plugins/outbound/signal.js +11 -11
  181. package/dist/channels/plugins/setup-helpers.js +10 -5
  182. package/dist/channels/sender-label.js +14 -7
  183. package/dist/channels/session.js +4 -2
  184. package/dist/channels/status-reactions.js +297 -0
  185. package/dist/cli/banner.js +1 -1
  186. package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
  187. package/dist/cli/cli-name.js +11 -11
  188. package/dist/cli/cli-utils.js +13 -3
  189. package/dist/cli/command-format.js +1 -1
  190. package/dist/cli/config-cli.js +1 -1
  191. package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
  192. package/dist/cli/daemon-cli/lifecycle.js +64 -2
  193. package/dist/cli/daemon-cli/restart-health.js +126 -0
  194. package/dist/cli/daemon-cli/status.gather.js +9 -13
  195. package/dist/cli/daemon-cli/status.print.js +2 -10
  196. package/dist/cli/deps.js +27 -22
  197. package/dist/cli/gateway-cli/run-loop.js +23 -5
  198. package/dist/cli/node-cli/register.js +14 -5
  199. package/dist/cli/nodes-media-utils.js +7 -2
  200. package/dist/cli/outbound-send-deps.js +2 -9
  201. package/dist/cli/outbound-send-mapping.js +11 -0
  202. package/dist/cli/pairing-cli.js +40 -14
  203. package/dist/cli/plugins-cli.js +34 -41
  204. package/dist/cli/ports.js +11 -10
  205. package/dist/cli/program/command-registry.js +2 -11
  206. package/dist/cli/program/command-tree.js +16 -0
  207. package/dist/cli/program/preaction.js +13 -9
  208. package/dist/cli/program/register.configure.js +3 -18
  209. package/dist/cli/program/register.maintenance.js +2 -2
  210. package/dist/cli/program/register.onboard.js +2 -0
  211. package/dist/cli/program/register.status-health-sessions.js +16 -17
  212. package/dist/cli/program/register.subclis.js +93 -52
  213. package/dist/cli/route.js +11 -7
  214. package/dist/cli/system-cli.js +36 -46
  215. package/dist/cli/update-cli/shared.js +22 -9
  216. package/dist/cli/update-cli/update-command.js +89 -14
  217. package/dist/cli/update-cli/wizard.js +6 -12
  218. package/dist/commands/agent/run-context.js +18 -5
  219. package/dist/commands/agent/session-store.js +17 -4
  220. package/dist/commands/agent.js +22 -2
  221. package/dist/commands/agents.bindings.js +14 -7
  222. package/dist/commands/agents.commands.add.js +13 -9
  223. package/dist/commands/agents.commands.identity.js +12 -6
  224. package/dist/commands/agents.commands.list.js +11 -6
  225. package/dist/commands/agents.config.js +8 -10
  226. package/dist/commands/agents.providers.js +12 -6
  227. package/dist/commands/auth-choice-options.js +103 -75
  228. package/dist/commands/auth-choice.apply.byteplus.js +55 -0
  229. package/dist/commands/auth-choice.apply.js +4 -0
  230. package/dist/commands/auth-choice.apply.minimax.js +61 -13
  231. package/dist/commands/auth-choice.apply.openai.js +3 -1
  232. package/dist/commands/auth-choice.apply.volcengine.js +55 -0
  233. package/dist/commands/auth-choice.preferred-provider.js +2 -0
  234. package/dist/commands/channels/remove.js +13 -6
  235. package/dist/commands/channels/shared.js +4 -14
  236. package/dist/commands/configure.commands.js +14 -0
  237. package/dist/commands/configure.gateway.js +2 -4
  238. package/dist/commands/configure.js +1 -1
  239. package/dist/commands/configure.shared.js +11 -0
  240. package/dist/commands/daemon-install-helpers.js +2 -2
  241. package/dist/commands/dashboard.js +12 -10
  242. package/dist/commands/docs.js +14 -8
  243. package/dist/commands/doctor-config-flow.js +11 -9
  244. package/dist/commands/doctor-legacy-config.js +281 -0
  245. package/dist/commands/doctor-state-integrity.js +99 -23
  246. package/dist/commands/doctor-update.js +12 -9
  247. package/dist/commands/models/list.list-command.js +7 -5
  248. package/dist/commands/models/set-image.js +2 -21
  249. package/dist/commands/node-daemon-install-helpers.js +10 -8
  250. package/dist/commands/onboard-auth.config-minimax.js +54 -80
  251. package/dist/commands/onboard-auth.config-opencode.js +2 -18
  252. package/dist/commands/onboard-auth.credentials.js +90 -13
  253. package/dist/commands/onboard-auth.js +1 -1
  254. package/dist/commands/onboard-auth.models.js +6 -5
  255. package/dist/commands/onboard-hooks.js +1 -1
  256. package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
  257. package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
  258. package/dist/commands/onboard-provider-auth-flags.js +14 -0
  259. package/dist/commands/onboard-remote.js +14 -7
  260. package/dist/commands/onboard.js +11 -13
  261. package/dist/commands/sandbox-display.js +6 -5
  262. package/dist/commands/status-all/diagnosis.js +14 -10
  263. package/dist/commands/status-all/format.js +1 -0
  264. package/dist/commands/status.gateway-probe.js +1 -16
  265. package/dist/commands/systemd-linger.js +12 -6
  266. package/dist/config/agent-limits.js +2 -0
  267. package/dist/config/commands.js +30 -16
  268. package/dist/config/config-paths.js +9 -11
  269. package/dist/config/defaults.js +22 -2
  270. package/dist/config/discord-preview-streaming.js +104 -0
  271. package/dist/config/env-vars.js +37 -8
  272. package/dist/config/includes.js +4 -0
  273. package/dist/config/io.js +97 -12
  274. package/dist/config/legacy.migrations.part-1.js +189 -78
  275. package/dist/config/legacy.shared.js +3 -1
  276. package/dist/config/merge-patch.js +4 -0
  277. package/dist/config/prototype-keys.js +4 -0
  278. package/dist/config/schema.help.js +44 -7
  279. package/dist/config/schema.labels.js +38 -6
  280. package/dist/config/sessions/delivery-info.js +10 -3
  281. package/dist/config/sessions/main-session.js +10 -5
  282. package/dist/config/sessions/session-file.js +33 -0
  283. package/dist/config/sessions/session-key.js +10 -5
  284. package/dist/config/sessions/store.js +1 -1
  285. package/dist/config/sessions.js +1 -0
  286. package/dist/config/zod-schema.agent-runtime.js +11 -0
  287. package/dist/config/zod-schema.js +148 -13
  288. package/dist/config/zod-schema.providers-core.js +78 -4
  289. package/dist/config/zod-schema.providers.js +6 -1
  290. package/dist/config/zod-schema.session.js +41 -2
  291. package/dist/cron/run-log.js +3 -0
  292. package/dist/cron/schedule.js +21 -10
  293. package/dist/cron/service/ops.js +35 -21
  294. package/dist/cron/service/timer.js +116 -16
  295. package/dist/cron/stagger.js +3 -1
  296. package/dist/discord/api.js +12 -6
  297. package/dist/discord/draft-chunking.js +22 -0
  298. package/dist/discord/draft-stream.js +124 -0
  299. package/dist/discord/monitor/agent-components.js +1 -1
  300. package/dist/discord/monitor/commands.js +5 -0
  301. package/dist/discord/monitor/gateway-plugin.js +2 -1
  302. package/dist/discord/monitor/listeners.js +37 -27
  303. package/dist/discord/monitor/message-handler.js +4 -1
  304. package/dist/discord/monitor/message-handler.preflight.js +65 -8
  305. package/dist/discord/monitor/message-handler.process.js +246 -217
  306. package/dist/discord/monitor/message-utils.js +143 -6
  307. package/dist/discord/monitor/model-picker-preferences.js +143 -0
  308. package/dist/discord/monitor/model-picker.js +651 -0
  309. package/dist/discord/monitor/native-command.js +573 -16
  310. package/dist/discord/monitor/provider.allowlist.js +223 -0
  311. package/dist/discord/monitor/provider.js +275 -347
  312. package/dist/discord/monitor/provider.lifecycle.js +100 -0
  313. package/dist/discord/monitor/reply-delivery.js +123 -16
  314. package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
  315. package/dist/discord/monitor/thread-bindings.js +4 -0
  316. package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
  317. package/dist/discord/monitor/thread-bindings.manager.js +423 -0
  318. package/dist/discord/monitor/thread-bindings.messages.js +55 -0
  319. package/dist/discord/monitor/thread-bindings.state.js +358 -0
  320. package/dist/discord/monitor/thread-bindings.types.js +6 -0
  321. package/dist/discord/resolve-users.js +33 -21
  322. package/dist/discord/send.channels.js +15 -0
  323. package/dist/discord/send.js +3 -2
  324. package/dist/discord/send.outbound.js +82 -26
  325. package/dist/discord/send.permissions.js +83 -30
  326. package/dist/discord/send.reactions.js +8 -4
  327. package/dist/discord/token.js +10 -5
  328. package/dist/discord/voice/command.js +263 -0
  329. package/dist/discord/voice/manager.js +531 -0
  330. package/dist/gateway/auth.js +34 -10
  331. package/dist/gateway/call.js +4 -16
  332. package/dist/gateway/client.js +28 -4
  333. package/dist/gateway/config-reload.js +3 -4
  334. package/dist/gateway/control-ui.js +219 -96
  335. package/dist/gateway/hooks-mapping.js +88 -38
  336. package/dist/gateway/http-auth-helpers.js +3 -2
  337. package/dist/gateway/http-endpoint-helpers.js +1 -0
  338. package/dist/gateway/net.js +54 -12
  339. package/dist/gateway/node-invoke-system-run-approval.js +14 -35
  340. package/dist/gateway/node-registry.js +10 -5
  341. package/dist/gateway/openai-http.js +1 -0
  342. package/dist/gateway/openresponses-http.js +1 -0
  343. package/dist/gateway/origin-check.js +1 -18
  344. package/dist/gateway/protocol/index.js +4 -3
  345. package/dist/gateway/protocol/schema/cron.js +1 -0
  346. package/dist/gateway/protocol/schema/devices.js +1 -0
  347. package/dist/gateway/protocol/schema/protocol-schemas.js +2 -1
  348. package/dist/gateway/protocol/schema/sessions.js +6 -0
  349. package/dist/gateway/role-policy.js +17 -0
  350. package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
  351. package/dist/gateway/server/ws-connection/message-handler.js +175 -148
  352. package/dist/gateway/server-chat.js +83 -25
  353. package/dist/gateway/server-constants.js +10 -9
  354. package/dist/gateway/server-cron.js +1 -0
  355. package/dist/gateway/server-http.js +16 -7
  356. package/dist/gateway/server-maintenance.js +20 -5
  357. package/dist/gateway/server-methods/chat.js +10 -6
  358. package/dist/gateway/server-methods/config.js +12 -14
  359. package/dist/gateway/server-methods/devices.js +17 -3
  360. package/dist/gateway/server-methods/models.js +11 -1
  361. package/dist/gateway/server-methods/sessions.js +64 -8
  362. package/dist/gateway/server-methods/usage.js +162 -75
  363. package/dist/gateway/server-node-events.js +29 -0
  364. package/dist/gateway/server-runtime-config.js +34 -13
  365. package/dist/gateway/server-startup-memory.js +17 -11
  366. package/dist/gateway/session-utils.fs.js +32 -34
  367. package/dist/gateway/sessions-resolve.js +17 -5
  368. package/dist/gateway/test-helpers.openai-mock.js +14 -7
  369. package/dist/gateway/tools-invoke-http.js +21 -10
  370. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
  371. package/dist/hooks/bundled/command-logger/handler.js +7 -2
  372. package/dist/hooks/bundled/session-memory/handler.js +6 -5
  373. package/dist/hooks/frontmatter.js +6 -6
  374. package/dist/hooks/gmail-watcher.js +11 -6
  375. package/dist/hooks/internal-hooks.js +11 -1
  376. package/dist/hooks/llm-slug-generator.js +4 -1
  377. package/dist/hooks/workspace.js +47 -17
  378. package/dist/imessage/accounts.js +9 -20
  379. package/dist/imessage/monitor/inbound-processing.js +2 -1
  380. package/dist/infra/archive.js +174 -73
  381. package/dist/infra/control-ui-assets.js +14 -6
  382. package/dist/infra/device-pairing.js +108 -29
  383. package/dist/infra/env.js +10 -5
  384. package/dist/infra/exec-approvals-allowlist.js +122 -0
  385. package/dist/infra/exec-approvals-analysis.js +34 -3
  386. package/dist/infra/exec-approvals.js +5 -17
  387. package/dist/infra/exec-safe-bin-policy.js +53 -45
  388. package/dist/infra/fs-safe.js +71 -39
  389. package/dist/infra/gateway-lock.js +6 -2
  390. package/dist/infra/heartbeat-wake.js +6 -12
  391. package/dist/infra/host-env-security-policy.json +19 -0
  392. package/dist/infra/host-env-security.js +66 -0
  393. package/dist/infra/net/ssrf.js +131 -38
  394. package/dist/infra/outbound/bound-delivery-router.js +88 -0
  395. package/dist/infra/outbound/channel-selection.js +12 -6
  396. package/dist/infra/outbound/envelope.js +1 -1
  397. package/dist/infra/outbound/format.js +12 -6
  398. package/dist/infra/outbound/payloads.js +14 -7
  399. package/dist/infra/outbound/session-binding-service.js +123 -0
  400. package/dist/infra/path-guards.js +25 -0
  401. package/dist/infra/provider-usage.fetch.codex.js +7 -15
  402. package/dist/infra/provider-usage.fetch.gemini.js +14 -11
  403. package/dist/infra/provider-usage.fetch.shared.js +30 -1
  404. package/dist/infra/provider-usage.fetch.zai.js +10 -9
  405. package/dist/infra/retry-policy.js +4 -2
  406. package/dist/infra/retry.js +9 -5
  407. package/dist/infra/session-cost-usage.js +107 -59
  408. package/dist/infra/session-maintenance-warning.js +3 -1
  409. package/dist/infra/shell-env.js +98 -34
  410. package/dist/infra/ssh-config.js +12 -6
  411. package/dist/infra/system-run-command.js +49 -4
  412. package/dist/infra/update-channels.js +10 -5
  413. package/dist/line/accounts.js +5 -7
  414. package/dist/line/bot-access.js +8 -20
  415. package/dist/line/bot-handlers.js +3 -1
  416. package/dist/link-understanding/detect.js +15 -7
  417. package/dist/media/constants.js +15 -6
  418. package/dist/media/image-ops.js +7 -0
  419. package/dist/media/local-roots.js +3 -2
  420. package/dist/media-understanding/apply.js +4 -1
  421. package/dist/media-understanding/concurrency.js +8 -20
  422. package/dist/memory/backend-config.js +45 -6
  423. package/dist/memory/embeddings.js +10 -4
  424. package/dist/memory/fs-utils.js +23 -0
  425. package/dist/memory/manager-search.js +12 -6
  426. package/dist/memory/manager-sync-ops.js +12 -2
  427. package/dist/memory/qmd-manager.js +466 -53
  428. package/dist/memory/query-expansion.js +167 -3
  429. package/dist/memory/status-format.js +10 -5
  430. package/dist/memory/sync-memory-files.js +1 -1
  431. package/dist/node-host/invoke-system-run.js +281 -0
  432. package/dist/node-host/invoke.js +55 -337
  433. package/dist/pairing/pairing-store.js +22 -0
  434. package/dist/plugin-sdk/allow-from.js +1 -1
  435. package/dist/plugin-sdk/command-auth.js +3 -1
  436. package/dist/plugin-sdk/index.js +6 -3
  437. package/dist/plugin-sdk/webhook-targets.js +32 -0
  438. package/dist/plugins/bundled-dir.js +9 -6
  439. package/dist/plugins/hooks.js +50 -0
  440. package/dist/plugins/install.js +28 -16
  441. package/dist/plugins/runtime.js +3 -17
  442. package/dist/plugins/update.js +78 -12
  443. package/dist/process/spawn-utils.js +14 -7
  444. package/dist/providers/github-copilot-token.js +11 -6
  445. package/dist/providers/qwen-portal-oauth.js +14 -6
  446. package/dist/routing/account-id.js +30 -0
  447. package/dist/routing/resolve-route.js +3 -7
  448. package/dist/routing/session-key.js +2 -16
  449. package/dist/security/audit-channel.js +93 -2
  450. package/dist/security/audit-extra.async.js +159 -5
  451. package/dist/security/audit-extra.js +1 -1
  452. package/dist/security/audit-extra.sync.js +85 -6
  453. package/dist/security/audit.js +40 -4
  454. package/dist/security/dm-policy-shared.js +44 -0
  455. package/dist/security/external-content.js +26 -6
  456. package/dist/shared/entry-status.js +6 -0
  457. package/dist/shared/frontmatter.js +5 -5
  458. package/dist/shared/node-match.js +11 -4
  459. package/dist/shared/operator-scope-compat.js +8 -3
  460. package/dist/signal/accounts.js +7 -20
  461. package/dist/signal/monitor/event-handler.js +3 -1
  462. package/dist/slack/accounts.js +6 -19
  463. package/dist/slack/actions.js +11 -3
  464. package/dist/slack/monitor/auth.js +1 -1
  465. package/dist/slack/monitor/message-handler/dispatch.js +50 -29
  466. package/dist/slack/monitor/replies.js +15 -7
  467. package/dist/slack/monitor/slash.js +22 -13
  468. package/dist/slack/resolve-channels.js +10 -5
  469. package/dist/slack/send.js +102 -12
  470. package/dist/slack/stream-mode.js +10 -0
  471. package/dist/slack/streaming.js +4 -2
  472. package/dist/telegram/accounts.js +19 -14
  473. package/dist/telegram/bot/helpers.js +3 -5
  474. package/dist/telegram/bot-access.js +35 -36
  475. package/dist/telegram/bot-handlers.js +120 -148
  476. package/dist/telegram/bot-message-context.js +68 -9
  477. package/dist/telegram/bot-message-dispatch.js +155 -90
  478. package/dist/telegram/bot-native-commands.js +16 -0
  479. package/dist/telegram/draft-stream.js +14 -1
  480. package/dist/telegram/inline-buttons.js +5 -15
  481. package/dist/telegram/monitor.js +11 -7
  482. package/dist/telegram/network-config.js +19 -7
  483. package/dist/telegram/send.js +3 -2
  484. package/dist/telegram/sent-message-cache.js +5 -6
  485. package/dist/telegram/status-reaction-variants.js +208 -0
  486. package/dist/telegram/sticker-cache.js +11 -9
  487. package/dist/terminal/theme.js +12 -12
  488. package/dist/tts/tts.js +80 -567
  489. package/dist/tui/components/chat-log.js +41 -8
  490. package/dist/tui/theme/theme.js +10 -12
  491. package/dist/tui/tui-local-shell.js +16 -6
  492. package/dist/tui/tui.js +58 -6
  493. package/dist/utils/account-id.js +2 -4
  494. package/dist/utils/boolean.js +10 -5
  495. package/dist/utils/directive-tags.js +11 -0
  496. package/dist/utils/queue-helpers.js +67 -12
  497. package/dist/web/auto-reply/deliver-reply.js +8 -4
  498. package/dist/web/auto-reply/mentions.js +10 -5
  499. package/dist/web/auto-reply/monitor/group-members.js +14 -7
  500. package/dist/web/auto-reply/monitor/process-message.js +45 -24
  501. package/dist/web/inbound/access-control.js +5 -2
  502. package/dist/web/login-qr.js +12 -6
  503. package/dist/web/media.js +123 -16
  504. package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
  505. package/extensions/bluebubbles/src/monitor.ts +208 -1950
  506. package/package.json +1 -1
@@ -19,6 +19,13 @@ const MIN_REFIRE_GAP_MS = 2_000;
19
19
  * from wedging the entire cron lane.
20
20
  */
21
21
  const DEFAULT_JOB_TIMEOUT_MS = 10 * 60_000; // 10 minutes
22
+ function resolveRunConcurrency(state) {
23
+ const raw = state.deps.cronConfig?.maxConcurrentRuns;
24
+ if (typeof raw !== "number" || !Number.isFinite(raw)) {
25
+ return 1;
26
+ }
27
+ return Math.max(1, Math.floor(raw));
28
+ }
22
29
  /**
23
30
  * Exponential backoff delays (in ms) indexed by consecutive error count.
24
31
  * After the last entry the delay stays constant.
@@ -45,6 +52,7 @@ function applyJobResult(state, job, result) {
45
52
  job.state.lastStatus = result.status;
46
53
  job.state.lastDurationMs = Math.max(0, result.endedAt - result.startedAt);
47
54
  job.state.lastError = result.error;
55
+ job.state.lastDelivered = result.delivered;
48
56
  job.updatedAtMs = result.endedAt;
49
57
  // Track consecutive errors for backoff / auto-disable.
50
58
  if (result.status === "error") {
@@ -187,8 +195,8 @@ export async function onTimer(state) {
187
195
  job: j,
188
196
  }));
189
197
  });
190
- const results = [];
191
- for (const { id, job } of dueJobs) {
198
+ const runDueJob = async (params) => {
199
+ const { id, job } = params;
192
200
  const startedAt = state.deps.nowMs();
193
201
  job.state.runningAtMs = startedAt;
194
202
  emit(state, { jobId: job.id, action: "started", runAtMs: startedAt });
@@ -219,23 +227,41 @@ export async function onTimer(state) {
219
227
  }
220
228
  })()
221
229
  : await executeJobCore(state, job);
222
- results.push({ jobId: id, ...result, startedAt, endedAt: state.deps.nowMs() });
230
+ return { jobId: id, ...result, startedAt, endedAt: state.deps.nowMs() };
223
231
  }
224
232
  catch (err) {
225
233
  state.deps.log.warn({ jobId: id, jobName: job.name, timeoutMs: jobTimeoutMs ?? null }, `cron: job failed: ${String(err)}`);
226
- results.push({
234
+ return {
227
235
  jobId: id,
228
236
  status: "error",
229
237
  error: String(err),
230
238
  startedAt,
231
239
  endedAt: state.deps.nowMs(),
232
- });
240
+ };
233
241
  }
234
- }
235
- if (results.length > 0) {
242
+ };
243
+ const concurrency = Math.min(resolveRunConcurrency(state), Math.max(1, dueJobs.length));
244
+ const results = Array.from({ length: dueJobs.length });
245
+ let cursor = 0;
246
+ const workers = Array.from({ length: concurrency }, async () => {
247
+ for (;;) {
248
+ const index = cursor++;
249
+ if (index >= dueJobs.length) {
250
+ return;
251
+ }
252
+ const due = dueJobs[index];
253
+ if (!due) {
254
+ return;
255
+ }
256
+ results[index] = await runDueJob(due);
257
+ }
258
+ });
259
+ await Promise.all(workers);
260
+ const completedResults = results.filter((entry) => entry !== undefined);
261
+ if (completedResults.length > 0) {
236
262
  await locked(state, async () => {
237
263
  await ensureLoaded(state, { forceReload: true, skipRecompute: true });
238
- for (const result of results) {
264
+ for (const result of completedResults) {
239
265
  const job = state.store?.jobs.find((j) => j.id === result.jobId);
240
266
  if (!job) {
241
267
  continue;
@@ -243,6 +269,7 @@ export async function onTimer(state) {
243
269
  const shouldDelete = applyJobResult(state, job, {
244
270
  status: result.status,
245
271
  error: result.error,
272
+ delivered: result.delivered,
246
273
  startedAt: result.startedAt,
247
274
  endedAt: result.endedAt,
248
275
  });
@@ -342,18 +369,88 @@ function collectRunnableJobs(state, nowMs, opts) {
342
369
  }));
343
370
  }
344
371
  export async function runMissedJobs(state, opts) {
345
- if (!state.store) {
346
- return;
347
- }
348
- const now = state.deps.nowMs();
349
- const skipJobIds = opts?.skipJobIds;
350
- const missed = collectRunnableJobs(state, now, { skipJobIds, skipAtIfAlreadyRan: true });
351
- if (missed.length > 0) {
372
+ const startupCandidates = await locked(state, async () => {
373
+ await ensureLoaded(state, { skipRecompute: true });
374
+ if (!state.store) {
375
+ return [];
376
+ }
377
+ const now = state.deps.nowMs();
378
+ const skipJobIds = opts?.skipJobIds;
379
+ const missed = collectRunnableJobs(state, now, { skipJobIds, skipAtIfAlreadyRan: true });
380
+ if (missed.length === 0) {
381
+ return [];
382
+ }
352
383
  state.deps.log.info({ count: missed.length, jobIds: missed.map((j) => j.id) }, "cron: running missed jobs after restart");
353
384
  for (const job of missed) {
354
- await executeJob(state, job, now, { forced: false });
385
+ job.state.runningAtMs = now;
386
+ job.state.lastError = undefined;
387
+ }
388
+ await persist(state);
389
+ return missed.map((job) => ({ jobId: job.id, job }));
390
+ });
391
+ if (startupCandidates.length === 0) {
392
+ return;
393
+ }
394
+ const outcomes = [];
395
+ for (const candidate of startupCandidates) {
396
+ const startedAt = state.deps.nowMs();
397
+ emit(state, { jobId: candidate.job.id, action: "started", runAtMs: startedAt });
398
+ try {
399
+ const result = await executeJobCore(state, candidate.job);
400
+ outcomes.push({
401
+ jobId: candidate.jobId,
402
+ status: result.status,
403
+ error: result.error,
404
+ summary: result.summary,
405
+ delivered: result.delivered,
406
+ sessionId: result.sessionId,
407
+ sessionKey: result.sessionKey,
408
+ model: result.model,
409
+ provider: result.provider,
410
+ usage: result.usage,
411
+ startedAt,
412
+ endedAt: state.deps.nowMs(),
413
+ });
414
+ }
415
+ catch (err) {
416
+ outcomes.push({
417
+ jobId: candidate.jobId,
418
+ status: "error",
419
+ error: String(err),
420
+ startedAt,
421
+ endedAt: state.deps.nowMs(),
422
+ });
355
423
  }
356
424
  }
425
+ await locked(state, async () => {
426
+ await ensureLoaded(state, { forceReload: true, skipRecompute: true });
427
+ if (!state.store) {
428
+ return;
429
+ }
430
+ for (const result of outcomes) {
431
+ const job = state.store.jobs.find((entry) => entry.id === result.jobId);
432
+ if (!job) {
433
+ continue;
434
+ }
435
+ const shouldDelete = applyJobResult(state, job, {
436
+ status: result.status,
437
+ error: result.error,
438
+ delivered: result.delivered,
439
+ startedAt: result.startedAt,
440
+ endedAt: result.endedAt,
441
+ });
442
+ emitJobFinished(state, job, result, result.startedAt);
443
+ if (shouldDelete) {
444
+ state.store.jobs = state.store.jobs.filter((entry) => entry.id !== job.id);
445
+ emit(state, { jobId: job.id, action: "removed" });
446
+ }
447
+ }
448
+ // Preserve any new past-due nextRunAtMs values that became due while
449
+ // startup catch-up was running. They should execute on a future tick
450
+ // instead of being silently advanced.
451
+ recomputeNextRunsForMaintenance(state);
452
+ await persist(state);
453
+ });
357
454
  }
358
455
  export async function runDueJobs(state) {
359
456
  if (!state.store) {
@@ -463,6 +560,7 @@ async function executeJobCore(state, job) {
463
560
  status: res.status,
464
561
  error: res.error,
465
562
  summary: res.summary,
563
+ delivered: res.delivered,
466
564
  sessionId: res.sessionId,
467
565
  sessionKey: res.sessionKey,
468
566
  model: res.model,
@@ -493,6 +591,7 @@ export async function executeJob(state, job, _nowMs, _opts) {
493
591
  const shouldDelete = applyJobResult(state, job, {
494
592
  status: coreResult.status,
495
593
  error: coreResult.error,
594
+ delivered: coreResult.delivered,
496
595
  startedAt,
497
596
  endedAt,
498
597
  });
@@ -509,6 +608,7 @@ function emitJobFinished(state, job, result, runAtMs) {
509
608
  status: result.status,
510
609
  error: result.error,
511
610
  summary: result.summary,
611
+ delivered: result.delivered,
512
612
  sessionId: result.sessionId,
513
613
  sessionKey: result.sessionKey,
514
614
  runAtMs,
@@ -33,5 +33,7 @@ export function resolveCronStaggerMs(schedule) {
33
33
  if (explicit !== undefined) {
34
34
  return explicit;
35
35
  }
36
- return resolveDefaultCronStaggerMs(schedule.expr) ?? 0;
36
+ const expr = schedule.expr;
37
+ const cronExpr = typeof expr === "string" ? expr : "";
38
+ return resolveDefaultCronStaggerMs(cronExpr) ?? 0;
37
39
  }
@@ -9,12 +9,14 @@ const DISCORD_API_RETRY_DEFAULTS = {
9
9
  };
10
10
  function parseDiscordApiErrorPayload(text) {
11
11
  const trimmed = text.trim();
12
- if (!trimmed.startsWith("{") || !trimmed.endsWith("}"))
12
+ if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) {
13
13
  return null;
14
+ }
14
15
  try {
15
16
  const payload = JSON.parse(trimmed);
16
- if (payload && typeof payload === "object")
17
+ if (payload && typeof payload === "object") {
17
18
  return payload;
19
+ }
18
20
  }
19
21
  catch {
20
22
  return null;
@@ -26,24 +28,28 @@ function parseRetryAfterSeconds(text, response) {
26
28
  const retryAfter = payload && typeof payload.retry_after === "number" && Number.isFinite(payload.retry_after)
27
29
  ? payload.retry_after
28
30
  : undefined;
29
- if (retryAfter !== undefined)
31
+ if (retryAfter !== undefined) {
30
32
  return retryAfter;
33
+ }
31
34
  const header = response.headers.get("Retry-After");
32
- if (!header)
35
+ if (!header) {
33
36
  return undefined;
37
+ }
34
38
  const parsed = Number(header);
35
39
  return Number.isFinite(parsed) ? parsed : undefined;
36
40
  }
37
41
  function formatRetryAfterSeconds(value) {
38
- if (value === undefined || !Number.isFinite(value) || value < 0)
42
+ if (value === undefined || !Number.isFinite(value) || value < 0) {
39
43
  return undefined;
44
+ }
40
45
  const rounded = value < 10 ? value.toFixed(1) : Math.round(value).toString();
41
46
  return `${rounded}s`;
42
47
  }
43
48
  function formatDiscordApiErrorText(text) {
44
49
  const trimmed = text.trim();
45
- if (!trimmed)
50
+ if (!trimmed) {
46
51
  return undefined;
52
+ }
47
53
  const payload = parseDiscordApiErrorPayload(trimmed);
48
54
  if (!payload) {
49
55
  const looksJson = trimmed.startsWith("{") && trimmed.endsWith("}");
@@ -0,0 +1,22 @@
1
+ import { resolveTextChunkLimit } from "../auto-reply/chunk.js";
2
+ import { getChannelDock } from "../channels/dock.js";
3
+ import { normalizeAccountId } from "../routing/session-key.js";
4
+ const DEFAULT_DISCORD_DRAFT_STREAM_MIN = 200;
5
+ const DEFAULT_DISCORD_DRAFT_STREAM_MAX = 800;
6
+ export function resolveDiscordDraftStreamingChunking(cfg, accountId) {
7
+ const providerChunkLimit = getChannelDock("discord")?.outbound?.textChunkLimit;
8
+ const textLimit = resolveTextChunkLimit(cfg, "discord", accountId, {
9
+ fallbackLimit: providerChunkLimit,
10
+ });
11
+ const normalizedAccountId = normalizeAccountId(accountId);
12
+ const draftCfg = cfg?.channels?.discord?.accounts?.[normalizedAccountId]?.draftChunk ??
13
+ cfg?.channels?.discord?.draftChunk;
14
+ const maxRequested = Math.max(1, Math.floor(draftCfg?.maxChars ?? DEFAULT_DISCORD_DRAFT_STREAM_MAX));
15
+ const maxChars = Math.max(1, Math.min(maxRequested, textLimit));
16
+ const minRequested = Math.max(1, Math.floor(draftCfg?.minChars ?? DEFAULT_DISCORD_DRAFT_STREAM_MIN));
17
+ const minChars = Math.min(minRequested, maxChars);
18
+ const breakPreference = draftCfg?.breakPreference === "newline" || draftCfg?.breakPreference === "sentence"
19
+ ? draftCfg.breakPreference
20
+ : "paragraph";
21
+ return { minChars, maxChars, breakPreference };
22
+ }
@@ -0,0 +1,124 @@
1
+ import { Routes } from "discord-api-types/v10";
2
+ import { createDraftStreamLoop } from "../channels/draft-stream-loop.js";
3
+ /** Discord messages cap at 2000 characters. */
4
+ const DISCORD_STREAM_MAX_CHARS = 2000;
5
+ const DEFAULT_THROTTLE_MS = 1200;
6
+ export function createDiscordDraftStream(params) {
7
+ const maxChars = Math.min(params.maxChars ?? DISCORD_STREAM_MAX_CHARS, DISCORD_STREAM_MAX_CHARS);
8
+ const throttleMs = Math.max(250, params.throttleMs ?? DEFAULT_THROTTLE_MS);
9
+ const minInitialChars = params.minInitialChars;
10
+ const channelId = params.channelId;
11
+ const rest = params.rest;
12
+ const resolveReplyToMessageId = () => typeof params.replyToMessageId === "function"
13
+ ? params.replyToMessageId()
14
+ : params.replyToMessageId;
15
+ let streamMessageId;
16
+ let lastSentText = "";
17
+ let stopped = false;
18
+ let isFinal = false;
19
+ const sendOrEditStreamMessage = async (text) => {
20
+ // Allow final flush even if stopped (e.g., after clear()).
21
+ if (stopped && !isFinal) {
22
+ return false;
23
+ }
24
+ const trimmed = text.trimEnd();
25
+ if (!trimmed) {
26
+ return false;
27
+ }
28
+ if (trimmed.length > maxChars) {
29
+ // Discord messages cap at 2000 chars.
30
+ // Stop streaming once we exceed the cap to avoid repeated API failures.
31
+ stopped = true;
32
+ params.warn?.(`discord stream preview stopped (text length ${trimmed.length} > ${maxChars})`);
33
+ return false;
34
+ }
35
+ if (trimmed === lastSentText) {
36
+ return true;
37
+ }
38
+ // Debounce first preview send for better push notification quality.
39
+ if (streamMessageId === undefined && minInitialChars != null && !isFinal) {
40
+ if (trimmed.length < minInitialChars) {
41
+ return false;
42
+ }
43
+ }
44
+ lastSentText = trimmed;
45
+ try {
46
+ if (streamMessageId !== undefined) {
47
+ // Edit existing message
48
+ await rest.patch(Routes.channelMessage(channelId, streamMessageId), {
49
+ body: { content: trimmed },
50
+ });
51
+ return true;
52
+ }
53
+ // Send new message
54
+ const replyToMessageId = resolveReplyToMessageId()?.trim();
55
+ const messageReference = replyToMessageId
56
+ ? { message_id: replyToMessageId, fail_if_not_exists: false }
57
+ : undefined;
58
+ const sent = (await rest.post(Routes.channelMessages(channelId), {
59
+ body: {
60
+ content: trimmed,
61
+ ...(messageReference ? { message_reference: messageReference } : {}),
62
+ },
63
+ }));
64
+ const sentMessageId = sent?.id;
65
+ if (typeof sentMessageId !== "string" || !sentMessageId) {
66
+ stopped = true;
67
+ params.warn?.("discord stream preview stopped (missing message id from send)");
68
+ return false;
69
+ }
70
+ streamMessageId = sentMessageId;
71
+ return true;
72
+ }
73
+ catch (err) {
74
+ stopped = true;
75
+ params.warn?.(`discord stream preview failed: ${err instanceof Error ? err.message : String(err)}`);
76
+ return false;
77
+ }
78
+ };
79
+ const loop = createDraftStreamLoop({
80
+ throttleMs,
81
+ isStopped: () => stopped,
82
+ sendOrEditStreamMessage,
83
+ });
84
+ const update = (text) => {
85
+ if (stopped || isFinal) {
86
+ return;
87
+ }
88
+ loop.update(text);
89
+ };
90
+ const stop = async () => {
91
+ isFinal = true;
92
+ await loop.flush();
93
+ };
94
+ const clear = async () => {
95
+ stopped = true;
96
+ loop.stop();
97
+ await loop.waitForInFlight();
98
+ const messageId = streamMessageId;
99
+ streamMessageId = undefined;
100
+ if (typeof messageId !== "string") {
101
+ return;
102
+ }
103
+ try {
104
+ await rest.delete(Routes.channelMessage(channelId, messageId));
105
+ }
106
+ catch (err) {
107
+ params.warn?.(`discord stream preview cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
108
+ }
109
+ };
110
+ const forceNewMessage = () => {
111
+ streamMessageId = undefined;
112
+ lastSentText = "";
113
+ loop.resetPending();
114
+ };
115
+ params.log?.(`discord stream preview ready (maxChars=${maxChars}, throttleMs=${throttleMs})`);
116
+ return {
117
+ update,
118
+ flush: loop.flush,
119
+ messageId: () => streamMessageId,
120
+ clear,
121
+ stop,
122
+ forceNewMessage,
123
+ };
124
+ }
@@ -283,7 +283,7 @@ async function ensureDmComponentAuthorized(params) {
283
283
  if (dmPolicy === "open") {
284
284
  return true;
285
285
  }
286
- const storeAllowFrom = await readChannelAllowFromStore("discord").catch(() => []);
286
+ const storeAllowFrom = dmPolicy === "allowlist" ? await readChannelAllowFromStore("discord").catch(() => []) : [];
287
287
  const effectiveAllowFrom = [...(ctx.allowFrom ?? []), ...storeAllowFrom];
288
288
  const allowList = normalizeDiscordAllowList(effectiveAllowFrom, ["discord:", "user:", "pk:"]);
289
289
  const allowMatch = allowList
@@ -0,0 +1,5 @@
1
+ export function resolveDiscordSlashCommandConfig(raw) {
2
+ return {
3
+ ephemeral: raw?.ephemeral !== false,
4
+ };
5
+ }
@@ -8,7 +8,8 @@ export function resolveDiscordGatewayIntents(intentsConfig) {
8
8
  GatewayIntents.MessageContent |
9
9
  GatewayIntents.DirectMessages |
10
10
  GatewayIntents.GuildMessageReactions |
11
- GatewayIntents.DirectMessageReactions;
11
+ GatewayIntents.DirectMessageReactions |
12
+ GatewayIntents.GuildVoiceStates;
12
13
  if (intentsConfig?.presence) {
13
14
  intents |= GatewayIntents.GuildPresences;
14
15
  }
@@ -28,6 +28,27 @@ function logSlowDiscordListener(params) {
28
28
  consoleMessage: message,
29
29
  });
30
30
  }
31
+ async function runDiscordListenerWithSlowLog(params) {
32
+ const startedAt = Date.now();
33
+ try {
34
+ await params.run();
35
+ }
36
+ catch (err) {
37
+ if (params.onError) {
38
+ params.onError(err);
39
+ return;
40
+ }
41
+ throw err;
42
+ }
43
+ finally {
44
+ logSlowDiscordListener({
45
+ logger: params.logger,
46
+ listener: params.listener,
47
+ event: params.event,
48
+ durationMs: Date.now() - startedAt,
49
+ });
50
+ }
51
+ }
31
52
  export function registerDiscordListener(listeners, listener) {
32
53
  if (listeners.some((existing) => existing.constructor === listener.constructor)) {
33
54
  return false;
@@ -44,20 +65,15 @@ export class DiscordMessageListener extends MessageCreateListener {
44
65
  this.logger = logger;
45
66
  }
46
67
  async handle(data, client) {
47
- const startedAt = Date.now();
48
- const task = Promise.resolve(this.handler(data, client));
49
- void task
50
- .catch((err) => {
51
- const logger = this.logger ?? discordEventQueueLog;
52
- logger.error(danger(`discord handler failed: ${String(err)}`));
53
- })
54
- .finally(() => {
55
- logSlowDiscordListener({
56
- logger: this.logger,
57
- listener: this.constructor.name,
58
- event: this.type,
59
- durationMs: Date.now() - startedAt,
60
- });
68
+ await runDiscordListenerWithSlowLog({
69
+ logger: this.logger,
70
+ listener: this.constructor.name,
71
+ event: this.type,
72
+ run: () => this.handler(data, client),
73
+ onError: (err) => {
74
+ const logger = this.logger ?? discordEventQueueLog;
75
+ logger.error(danger(`discord handler failed: ${String(err)}`));
76
+ },
61
77
  });
62
78
  }
63
79
  }
@@ -96,9 +112,11 @@ export class DiscordReactionRemoveListener extends MessageReactionRemoveListener
96
112
  }
97
113
  }
98
114
  async function runDiscordReactionHandler(params) {
99
- const startedAt = Date.now();
100
- try {
101
- await handleDiscordReactionEvent({
115
+ await runDiscordListenerWithSlowLog({
116
+ logger: params.handlerParams.logger,
117
+ listener: params.listener,
118
+ event: params.event,
119
+ run: () => handleDiscordReactionEvent({
102
120
  data: params.data,
103
121
  client: params.client,
104
122
  action: params.action,
@@ -107,16 +125,8 @@ async function runDiscordReactionHandler(params) {
107
125
  botUserId: params.handlerParams.botUserId,
108
126
  guildEntries: params.handlerParams.guildEntries,
109
127
  logger: params.handlerParams.logger,
110
- });
111
- }
112
- finally {
113
- logSlowDiscordListener({
114
- logger: params.handlerParams.logger,
115
- listener: params.listener,
116
- event: params.event,
117
- durationMs: Date.now() - startedAt,
118
- });
119
- }
128
+ }),
129
+ });
120
130
  }
121
131
  async function handleDiscordReactionEvent(params) {
122
132
  try {
@@ -3,7 +3,7 @@ import { createInboundDebouncer, resolveInboundDebounceMs, } from "../../auto-re
3
3
  import { danger } from "../../globals.js";
4
4
  import { preflightDiscordMessage } from "./message-handler.preflight.js";
5
5
  import { processDiscordMessage } from "./message-handler.process.js";
6
- import { resolveDiscordMessageChannelId, resolveDiscordMessageText } from "./message-utils.js";
6
+ import { hasDiscordMessageStickers, resolveDiscordMessageChannelId, resolveDiscordMessageText, } from "./message-utils.js";
7
7
  export function createDiscordMessageHandler(params) {
8
8
  const groupPolicy = params.discordConfig?.groupPolicy ?? "open";
9
9
  const ackReactionScope = params.cfg.messages?.ackReactionScope ?? "group-mentions";
@@ -33,6 +33,9 @@ export function createDiscordMessageHandler(params) {
33
33
  if (message.attachments && message.attachments.length > 0) {
34
34
  return false;
35
35
  }
36
+ if (hasDiscordMessageStickers(message)) {
37
+ return false;
38
+ }
36
39
  const baseText = resolveDiscordMessageText(message, { includeForwarded: false });
37
40
  if (!baseText.trim()) {
38
41
  return false;