@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
@@ -1,25 +1,15 @@
1
1
  import { getChannelPlugin } from "../../channels/plugins/index.js";
2
- import { formatCliCommand } from "../../cli/command-format.js";
3
- import { readConfigFileSnapshot } from "../../config/config.js";
4
2
  import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js";
5
3
  import { defaultRuntime } from "../../runtime.js";
4
+ import { requireValidConfigSnapshot } from "../config-validation.js";
6
5
  export async function requireValidConfig(runtime = defaultRuntime) {
7
- const snapshot = await readConfigFileSnapshot();
8
- if (snapshot.exists && !snapshot.valid) {
9
- const issues = snapshot.issues.length > 0
10
- ? snapshot.issues.map((issue) => `- ${issue.path}: ${issue.message}`).join("\n")
11
- : "Unknown validation issue.";
12
- runtime.error(`Config invalid:\n${issues}`);
13
- runtime.error(`Fix the config or run ${formatCliCommand("poolbot doctor")}.`);
14
- runtime.exit(1);
15
- return null;
16
- }
17
- return snapshot.config;
6
+ return await requireValidConfigSnapshot(runtime);
18
7
  }
19
8
  export function formatAccountLabel(params) {
20
9
  const base = params.accountId || DEFAULT_ACCOUNT_ID;
21
- if (params.name?.trim())
10
+ if (params.name?.trim()) {
22
11
  return `${base} (${params.name.trim()})`;
12
+ }
23
13
  return base;
24
14
  }
25
15
  export const channelLabel = (channel) => {
@@ -1,4 +1,5 @@
1
1
  import { defaultRuntime } from "../runtime.js";
2
+ import { CONFIGURE_WIZARD_SECTIONS, parseConfigureWizardSections } from "./configure.shared.js";
2
3
  import { runConfigureWizard } from "./configure.wizard.js";
3
4
  export async function configureCommand(runtime = defaultRuntime) {
4
5
  await runConfigureWizard({ command: "configure" }, runtime);
@@ -6,3 +7,16 @@ export async function configureCommand(runtime = defaultRuntime) {
6
7
  export async function configureCommandWithSections(sections, runtime = defaultRuntime) {
7
8
  await runConfigureWizard({ command: "configure", sections }, runtime);
8
9
  }
10
+ export async function configureCommandFromSectionsArg(rawSections, runtime = defaultRuntime) {
11
+ const { sections, invalid } = parseConfigureWizardSections(rawSections);
12
+ if (sections.length === 0) {
13
+ await configureCommand(runtime);
14
+ return;
15
+ }
16
+ if (invalid.length > 0) {
17
+ runtime.error(`Invalid --section: ${invalid.join(", ")}. Expected one of: ${CONFIGURE_WIZARD_SECTIONS.join(", ")}.`);
18
+ runtime.exit(1);
19
+ return;
20
+ }
21
+ await configureCommandWithSections(sections, runtime);
22
+ }
@@ -92,10 +92,8 @@ export async function promptGatewayConfig(cfg, runtime) {
92
92
  note("Tailscale funnel requires password auth.", "Note");
93
93
  authMode = "password";
94
94
  }
95
- if (authMode === "trusted-proxy" && bind === "loopback") {
96
- note("Trusted proxy auth requires network bind. Adjusting bind to lan.", "Note");
97
- bind = "lan";
98
- }
95
+ // trusted-proxy + loopback is valid when the reverse proxy runs on the same
96
+ // host (e.g. cloudflared, nginx, Caddy). trustedProxies must include 127.0.0.1.
99
97
  if (authMode === "trusted-proxy" && tailscaleMode !== "off") {
100
98
  note("Trusted proxy auth is incompatible with Tailscale serve/funnel. Disabling Tailscale.", "Note");
101
99
  tailscaleMode = "off";
@@ -1,4 +1,4 @@
1
- export { configureCommand, configureCommandWithSections } from "./configure.commands.js";
1
+ export { configureCommand, configureCommandWithSections, configureCommandFromSectionsArg, } from "./configure.commands.js";
2
2
  export { buildGatewayAuthConfig } from "./configure.gateway-auth.js";
3
3
  export { CONFIGURE_WIZARD_SECTIONS } from "./configure.shared.js";
4
4
  export { runConfigureWizard } from "./configure.wizard.js";
@@ -10,6 +10,17 @@ export const CONFIGURE_WIZARD_SECTIONS = [
10
10
  "skills",
11
11
  "health",
12
12
  ];
13
+ export function parseConfigureWizardSections(raw) {
14
+ const sectionsRaw = Array.isArray(raw)
15
+ ? raw.map((value) => (typeof value === "string" ? value.trim() : "")).filter(Boolean)
16
+ : [];
17
+ if (sectionsRaw.length === 0) {
18
+ return { sections: [], invalid: [] };
19
+ }
20
+ const invalid = sectionsRaw.filter((s) => !CONFIGURE_WIZARD_SECTIONS.includes(s));
21
+ const sections = sectionsRaw.filter((s) => CONFIGURE_WIZARD_SECTIONS.includes(s));
22
+ return { sections, invalid };
23
+ }
13
24
  export const CONFIGURE_SECTION_OPTIONS = [
14
25
  { value: "workspace", label: "Workspace", hint: "Set workspace + sessions" },
15
26
  { value: "model", label: "Model", hint: "Pick provider + credentials" },
@@ -3,7 +3,7 @@ import { resolveGatewayProgramArguments } from "../daemon/program-args.js";
3
3
  import { renderSystemNodeWarning, resolvePreferredNodePath, resolveSystemNodeInfo, } from "../daemon/runtime-paths.js";
4
4
  import { buildServiceEnvironment } from "../daemon/service-env.js";
5
5
  import { formatCliCommand } from "../cli/command-format.js";
6
- import { collectConfigEnvVars } from "../config/env-vars.js";
6
+ import { collectConfigServiceEnvVars } from "../config/env-vars.js";
7
7
  export function resolveGatewayDevMode(argv = process.argv) {
8
8
  const entry = argv[1];
9
9
  const normalizedEntry = entry?.replaceAll("\\", "/");
@@ -39,7 +39,7 @@ export async function buildGatewayInstallPlan(params) {
39
39
  // Merge config env vars into the service environment (vars + inline env keys).
40
40
  // Config env vars are added first so service-specific vars take precedence.
41
41
  const environment = {
42
- ...collectConfigEnvVars(params.config),
42
+ ...collectConfigServiceEnvVars(params.config),
43
43
  };
44
44
  Object.assign(environment, serviceEnvironment);
45
45
  return { programArguments, workingDirectory, environment };
@@ -9,26 +9,28 @@ export async function dashboardCommand(runtime = defaultRuntime, options = {}) {
9
9
  const bind = cfg.gateway?.bind ?? "loopback";
10
10
  const basePath = cfg.gateway?.controlUi?.basePath;
11
11
  const customBindHost = cfg.gateway?.customBindHost;
12
- const token = cfg.gateway?.auth?.token ??
13
- process.env.POOLBOT_GATEWAY_TOKEN ??
14
- process.env.CLAWDBOT_GATEWAY_TOKEN ??
15
- "";
12
+ const token = cfg.gateway?.auth?.token ?? process.env.POOLBOT_GATEWAY_TOKEN ?? "";
13
+ // LAN URLs fail secure-context checks in browsers.
14
+ // Coerce only lan->loopback and preserve other bind modes.
16
15
  const links = resolveControlUiLinks({
17
16
  port,
18
- bind,
17
+ bind: bind === "lan" ? "loopback" : bind,
19
18
  customBindHost,
20
19
  basePath,
21
20
  });
22
- const authedUrl = token ? `${links.httpUrl}?token=${encodeURIComponent(token)}` : links.httpUrl;
23
- runtime.log(`Dashboard URL: ${authedUrl}`);
24
- const copied = await copyToClipboard(authedUrl).catch(() => false);
21
+ // Prefer URL fragment to avoid leaking auth tokens via query params.
22
+ const dashboardUrl = token
23
+ ? `${links.httpUrl}#token=${encodeURIComponent(token)}`
24
+ : links.httpUrl;
25
+ runtime.log(`Dashboard URL: ${dashboardUrl}`);
26
+ const copied = await copyToClipboard(dashboardUrl).catch(() => false);
25
27
  runtime.log(copied ? "Copied to clipboard." : "Copy to clipboard unavailable.");
26
28
  let opened = false;
27
29
  let hint;
28
30
  if (!options.noOpen) {
29
31
  const browserSupport = await detectBrowserOpenSupport();
30
32
  if (browserSupport.ok) {
31
- opened = await openUrl(authedUrl);
33
+ opened = await openUrl(dashboardUrl);
32
34
  }
33
35
  if (!opened) {
34
36
  hint = formatControlUiSshHint({
@@ -42,7 +44,7 @@ export async function dashboardCommand(runtime = defaultRuntime, options = {}) {
42
44
  hint = "Browser launch disabled (--no-open). Use the URL above.";
43
45
  }
44
46
  if (opened) {
45
- runtime.log("Opened in your browser. Keep that tab to control Poolbot.");
47
+ runtime.log("Opened in your browser. Keep that tab to control Pool Bot.");
46
48
  }
47
49
  else if (hint) {
48
50
  runtime.log(hint);
@@ -1,16 +1,18 @@
1
1
  import { hasBinary } from "../agents/skills.js";
2
+ import { formatCliCommand } from "../cli/command-format.js";
2
3
  import { runCommandWithTimeout } from "../process/exec.js";
3
4
  import { formatDocsLink } from "../terminal/links.js";
4
5
  import { isRich, theme } from "../terminal/theme.js";
5
- import { formatCliCommand } from "../cli/command-format.js";
6
- const SEARCH_TOOL = "https://docs.molt.bot/mcp.SearchPoolbot";
6
+ const SEARCH_TOOL = "https://docs.molt.bot/mcp.SearchPool Bot";
7
7
  const SEARCH_TIMEOUT_MS = 30_000;
8
8
  const DEFAULT_SNIPPET_MAX = 220;
9
9
  function resolveNodeRunner() {
10
- if (hasBinary("pnpm"))
10
+ if (hasBinary("pnpm")) {
11
11
  return { cmd: "pnpm", args: ["dlx"] };
12
- if (hasBinary("npx"))
12
+ }
13
+ if (hasBinary("npx")) {
13
14
  return { cmd: "npx", args: ["-y"] };
15
+ }
14
16
  throw new Error("Missing pnpm or npx; install a Node package runner.");
15
17
  }
16
18
  async function runNodeTool(tool, toolArgs, options = {}) {
@@ -32,17 +34,20 @@ async function runTool(tool, toolArgs, options = {}) {
32
34
  }
33
35
  function extractLine(lines, prefix) {
34
36
  const line = lines.find((value) => value.startsWith(prefix));
35
- if (!line)
37
+ if (!line) {
36
38
  return undefined;
39
+ }
37
40
  return line.slice(prefix.length).trim();
38
41
  }
39
42
  function normalizeSnippet(raw, fallback) {
40
43
  const base = raw && raw.trim().length > 0 ? raw : fallback;
41
44
  const cleaned = base.replace(/\s+/g, " ").trim();
42
- if (!cleaned)
45
+ if (!cleaned) {
43
46
  return "";
44
- if (cleaned.length <= DEFAULT_SNIPPET_MAX)
47
+ }
48
+ if (cleaned.length <= DEFAULT_SNIPPET_MAX) {
45
49
  return cleaned;
50
+ }
46
51
  return `${cleaned.slice(0, DEFAULT_SNIPPET_MAX - 3)}...`;
47
52
  }
48
53
  function firstParagraph(text) {
@@ -63,8 +68,9 @@ function parseSearchOutput(raw) {
63
68
  const lines = block.split("\n");
64
69
  const title = extractLine(lines, "Title:");
65
70
  const link = extractLine(lines, "Link:");
66
- if (!title || !link)
71
+ if (!title || !link) {
67
72
  continue;
73
+ }
68
74
  const content = extractLine(lines, "Content:");
69
75
  const contentIndex = lines.findIndex((line) => line.startsWith("Content:"));
70
76
  const body = contentIndex >= 0
@@ -1,6 +1,7 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { isNumericTelegramUserId, normalizeTelegramAllowFromEntry, } from "../channels/telegram/allow-from.js";
4
+ import { fetchTelegramChatId } from "../channels/telegram/api.js";
4
5
  import { formatCliCommand } from "../cli/command-format.js";
5
6
  import { PoolBotSchema, CONFIG_PATH, migrateLegacyConfig, readConfigFileSnapshot, } from "../config/config.js";
6
7
  import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js";
@@ -251,15 +252,13 @@ async function maybeRepairTelegramAllowFromUsernames(cfg) {
251
252
  const controller = new AbortController();
252
253
  const timeout = setTimeout(() => controller.abort(), 4000);
253
254
  try {
254
- const url = `https://api.telegram.org/bot${token}/getChat?chat_id=${encodeURIComponent(username)}`;
255
- const res = await fetch(url, { signal: controller.signal }).catch(() => null);
256
- if (!res || !res.ok) {
257
- continue;
258
- }
259
- const data = (await res.json().catch(() => null));
260
- const id = data?.ok ? data?.result?.id : undefined;
261
- if (typeof id === "number" || typeof id === "string") {
262
- return String(id);
255
+ const id = await fetchTelegramChatId({
256
+ token,
257
+ chatId: username,
258
+ signal: controller.signal,
259
+ });
260
+ if (id) {
261
+ return id;
263
262
  }
264
263
  }
265
264
  catch {
@@ -754,6 +753,9 @@ export async function loadAndMaybeMigrateDoctorConfig(params) {
754
753
  note(fixHints.join("\n"), "Doctor");
755
754
  }
756
755
  }
756
+ if (shouldRepair && pendingChanges) {
757
+ shouldWriteConfig = true;
758
+ }
757
759
  noteOpencodeProviderOverrides(cfg);
758
760
  return {
759
761
  cfg,
@@ -1,6 +1,287 @@
1
+ import { resolveDiscordPreviewStreamMode, resolveSlackNativeStreaming, resolveSlackStreamingMode, resolveTelegramPreviewStreamMode, } from "../config/discord-preview-streaming.js";
1
2
  export function normalizeLegacyConfigValues(cfg) {
2
3
  const changes = [];
3
4
  let next = cfg;
5
+ const isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
6
+ const normalizeDmAliases = (params) => {
7
+ let changed = false;
8
+ let updated = params.entry;
9
+ const rawDm = updated.dm;
10
+ const dm = isRecord(rawDm) ? structuredClone(rawDm) : null;
11
+ let dmChanged = false;
12
+ const allowFromEqual = (a, b) => {
13
+ if (!Array.isArray(a) || !Array.isArray(b)) {
14
+ return false;
15
+ }
16
+ const na = a.map((v) => String(v).trim()).filter(Boolean);
17
+ const nb = b.map((v) => String(v).trim()).filter(Boolean);
18
+ if (na.length !== nb.length) {
19
+ return false;
20
+ }
21
+ return na.every((v, i) => v === nb[i]);
22
+ };
23
+ const topDmPolicy = updated.dmPolicy;
24
+ const legacyDmPolicy = dm?.policy;
25
+ if (topDmPolicy === undefined && legacyDmPolicy !== undefined) {
26
+ updated = { ...updated, dmPolicy: legacyDmPolicy };
27
+ changed = true;
28
+ if (dm) {
29
+ delete dm.policy;
30
+ dmChanged = true;
31
+ }
32
+ changes.push(`Moved ${params.pathPrefix}.dm.policy → ${params.pathPrefix}.dmPolicy.`);
33
+ }
34
+ else if (topDmPolicy !== undefined && legacyDmPolicy !== undefined) {
35
+ if (topDmPolicy === legacyDmPolicy) {
36
+ if (dm) {
37
+ delete dm.policy;
38
+ dmChanged = true;
39
+ changes.push(`Removed ${params.pathPrefix}.dm.policy (dmPolicy already set).`);
40
+ }
41
+ }
42
+ }
43
+ const topAllowFrom = updated.allowFrom;
44
+ const legacyAllowFrom = dm?.allowFrom;
45
+ if (topAllowFrom === undefined && legacyAllowFrom !== undefined) {
46
+ updated = { ...updated, allowFrom: legacyAllowFrom };
47
+ changed = true;
48
+ if (dm) {
49
+ delete dm.allowFrom;
50
+ dmChanged = true;
51
+ }
52
+ changes.push(`Moved ${params.pathPrefix}.dm.allowFrom → ${params.pathPrefix}.allowFrom.`);
53
+ }
54
+ else if (topAllowFrom !== undefined && legacyAllowFrom !== undefined) {
55
+ if (allowFromEqual(topAllowFrom, legacyAllowFrom)) {
56
+ if (dm) {
57
+ delete dm.allowFrom;
58
+ dmChanged = true;
59
+ changes.push(`Removed ${params.pathPrefix}.dm.allowFrom (allowFrom already set).`);
60
+ }
61
+ }
62
+ }
63
+ if (dm && isRecord(rawDm) && dmChanged) {
64
+ const keys = Object.keys(dm);
65
+ if (keys.length === 0) {
66
+ if (updated.dm !== undefined) {
67
+ const { dm: _ignored, ...rest } = updated;
68
+ updated = rest;
69
+ changed = true;
70
+ changes.push(`Removed empty ${params.pathPrefix}.dm after migration.`);
71
+ }
72
+ }
73
+ else {
74
+ updated = { ...updated, dm };
75
+ changed = true;
76
+ }
77
+ }
78
+ return { entry: updated, changed };
79
+ };
80
+ const normalizeTelegramStreamingAliases = (params) => {
81
+ let updated = params.entry;
82
+ const hadLegacyStreamMode = updated.streamMode !== undefined;
83
+ const beforeStreaming = updated.streaming;
84
+ const resolved = resolveTelegramPreviewStreamMode(updated);
85
+ const shouldNormalize = hadLegacyStreamMode ||
86
+ typeof beforeStreaming === "boolean" ||
87
+ (typeof beforeStreaming === "string" && beforeStreaming !== resolved);
88
+ if (!shouldNormalize) {
89
+ return { entry: updated, changed: false };
90
+ }
91
+ let changed = false;
92
+ if (beforeStreaming !== resolved) {
93
+ updated = { ...updated, streaming: resolved };
94
+ changed = true;
95
+ }
96
+ if (hadLegacyStreamMode) {
97
+ const { streamMode: _ignored, ...rest } = updated;
98
+ updated = rest;
99
+ changed = true;
100
+ changes.push(`Moved ${params.pathPrefix}.streamMode → ${params.pathPrefix}.streaming (${resolved}).`);
101
+ }
102
+ if (typeof beforeStreaming === "boolean") {
103
+ changes.push(`Normalized ${params.pathPrefix}.streaming boolean → enum (${resolved}).`);
104
+ }
105
+ else if (typeof beforeStreaming === "string" && beforeStreaming !== resolved) {
106
+ changes.push(`Normalized ${params.pathPrefix}.streaming (${beforeStreaming}) → (${resolved}).`);
107
+ }
108
+ return { entry: updated, changed };
109
+ };
110
+ const normalizeDiscordStreamingAliases = (params) => {
111
+ let updated = params.entry;
112
+ const hadLegacyStreamMode = updated.streamMode !== undefined;
113
+ const beforeStreaming = updated.streaming;
114
+ const resolved = resolveDiscordPreviewStreamMode(updated);
115
+ const shouldNormalize = hadLegacyStreamMode ||
116
+ typeof beforeStreaming === "boolean" ||
117
+ (typeof beforeStreaming === "string" && beforeStreaming !== resolved);
118
+ if (!shouldNormalize) {
119
+ return { entry: updated, changed: false };
120
+ }
121
+ let changed = false;
122
+ if (beforeStreaming !== resolved) {
123
+ updated = { ...updated, streaming: resolved };
124
+ changed = true;
125
+ }
126
+ if (hadLegacyStreamMode) {
127
+ const { streamMode: _ignored, ...rest } = updated;
128
+ updated = rest;
129
+ changed = true;
130
+ changes.push(`Moved ${params.pathPrefix}.streamMode → ${params.pathPrefix}.streaming (${resolved}).`);
131
+ }
132
+ if (typeof beforeStreaming === "boolean") {
133
+ changes.push(`Normalized ${params.pathPrefix}.streaming boolean → enum (${resolved}).`);
134
+ }
135
+ else if (typeof beforeStreaming === "string" && beforeStreaming !== resolved) {
136
+ changes.push(`Normalized ${params.pathPrefix}.streaming (${beforeStreaming}) → (${resolved}).`);
137
+ }
138
+ return { entry: updated, changed };
139
+ };
140
+ const normalizeSlackStreamingAliases = (params) => {
141
+ let updated = params.entry;
142
+ const hadLegacyStreamMode = updated.streamMode !== undefined;
143
+ const legacyStreaming = updated.streaming;
144
+ const beforeStreaming = updated.streaming;
145
+ const beforeNativeStreaming = updated.nativeStreaming;
146
+ const resolvedStreaming = resolveSlackStreamingMode(updated);
147
+ const resolvedNativeStreaming = resolveSlackNativeStreaming(updated);
148
+ const shouldNormalize = hadLegacyStreamMode ||
149
+ typeof legacyStreaming === "boolean" ||
150
+ (typeof legacyStreaming === "string" && legacyStreaming !== resolvedStreaming);
151
+ if (!shouldNormalize) {
152
+ return { entry: updated, changed: false };
153
+ }
154
+ let changed = false;
155
+ if (beforeStreaming !== resolvedStreaming) {
156
+ updated = { ...updated, streaming: resolvedStreaming };
157
+ changed = true;
158
+ }
159
+ if (typeof beforeNativeStreaming !== "boolean" ||
160
+ beforeNativeStreaming !== resolvedNativeStreaming) {
161
+ updated = { ...updated, nativeStreaming: resolvedNativeStreaming };
162
+ changed = true;
163
+ }
164
+ if (hadLegacyStreamMode) {
165
+ const { streamMode: _ignored, ...rest } = updated;
166
+ updated = rest;
167
+ changed = true;
168
+ changes.push(`Moved ${params.pathPrefix}.streamMode → ${params.pathPrefix}.streaming (${resolvedStreaming}).`);
169
+ }
170
+ if (typeof legacyStreaming === "boolean") {
171
+ changes.push(`Moved ${params.pathPrefix}.streaming (boolean) → ${params.pathPrefix}.nativeStreaming (${resolvedNativeStreaming}).`);
172
+ }
173
+ else if (typeof legacyStreaming === "string" && legacyStreaming !== resolvedStreaming) {
174
+ changes.push(`Normalized ${params.pathPrefix}.streaming (${legacyStreaming}) → (${resolvedStreaming}).`);
175
+ }
176
+ return { entry: updated, changed };
177
+ };
178
+ const normalizeProvider = (provider) => {
179
+ const channels = next.channels;
180
+ const rawEntry = channels?.[provider];
181
+ if (!isRecord(rawEntry)) {
182
+ return;
183
+ }
184
+ let updated = rawEntry;
185
+ let changed = false;
186
+ if (provider !== "telegram") {
187
+ const base = normalizeDmAliases({
188
+ provider,
189
+ entry: rawEntry,
190
+ pathPrefix: `channels.${provider}`,
191
+ });
192
+ updated = base.entry;
193
+ changed = base.changed;
194
+ }
195
+ if (provider === "telegram") {
196
+ const streaming = normalizeTelegramStreamingAliases({
197
+ entry: updated,
198
+ pathPrefix: `channels.${provider}`,
199
+ });
200
+ updated = streaming.entry;
201
+ changed = changed || streaming.changed;
202
+ }
203
+ else if (provider === "discord") {
204
+ const streaming = normalizeDiscordStreamingAliases({
205
+ entry: updated,
206
+ pathPrefix: `channels.${provider}`,
207
+ });
208
+ updated = streaming.entry;
209
+ changed = changed || streaming.changed;
210
+ }
211
+ else if (provider === "slack") {
212
+ const streaming = normalizeSlackStreamingAliases({
213
+ entry: updated,
214
+ pathPrefix: `channels.${provider}`,
215
+ });
216
+ updated = streaming.entry;
217
+ changed = changed || streaming.changed;
218
+ }
219
+ const rawAccounts = updated.accounts;
220
+ if (isRecord(rawAccounts)) {
221
+ let accountsChanged = false;
222
+ const accounts = { ...rawAccounts };
223
+ for (const [accountId, rawAccount] of Object.entries(rawAccounts)) {
224
+ if (!isRecord(rawAccount)) {
225
+ continue;
226
+ }
227
+ let accountEntry = rawAccount;
228
+ let accountChanged = false;
229
+ if (provider !== "telegram") {
230
+ const res = normalizeDmAliases({
231
+ provider,
232
+ entry: rawAccount,
233
+ pathPrefix: `channels.${provider}.accounts.${accountId}`,
234
+ });
235
+ accountEntry = res.entry;
236
+ accountChanged = res.changed;
237
+ }
238
+ if (provider === "telegram") {
239
+ const streaming = normalizeTelegramStreamingAliases({
240
+ entry: accountEntry,
241
+ pathPrefix: `channels.${provider}.accounts.${accountId}`,
242
+ });
243
+ accountEntry = streaming.entry;
244
+ accountChanged = accountChanged || streaming.changed;
245
+ }
246
+ else if (provider === "discord") {
247
+ const streaming = normalizeDiscordStreamingAliases({
248
+ entry: accountEntry,
249
+ pathPrefix: `channels.${provider}.accounts.${accountId}`,
250
+ });
251
+ accountEntry = streaming.entry;
252
+ accountChanged = accountChanged || streaming.changed;
253
+ }
254
+ else if (provider === "slack") {
255
+ const streaming = normalizeSlackStreamingAliases({
256
+ entry: accountEntry,
257
+ pathPrefix: `channels.${provider}.accounts.${accountId}`,
258
+ });
259
+ accountEntry = streaming.entry;
260
+ accountChanged = accountChanged || streaming.changed;
261
+ }
262
+ if (accountChanged) {
263
+ accounts[accountId] = accountEntry;
264
+ accountsChanged = true;
265
+ }
266
+ }
267
+ if (accountsChanged) {
268
+ updated = { ...updated, accounts };
269
+ changed = true;
270
+ }
271
+ }
272
+ if (changed) {
273
+ next = {
274
+ ...next,
275
+ channels: {
276
+ ...next.channels,
277
+ [provider]: updated,
278
+ },
279
+ };
280
+ }
281
+ };
282
+ normalizeProvider("telegram");
283
+ normalizeProvider("slack");
284
+ normalizeProvider("discord");
4
285
  const legacyAckReaction = cfg.messages?.ackReaction?.trim();
5
286
  const hasWhatsAppConfig = cfg.channels?.whatsapp !== undefined;
6
287
  if (legacyAckReaction && hasWhatsAppConfig) {