@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,6 +1,24 @@
1
+ import { loadConfig, resolveGatewayPort } from "../../config/config.js";
1
2
  import { resolveGatewayService } from "../../daemon/service.js";
3
+ import { defaultRuntime } from "../../runtime.js";
4
+ import { theme } from "../../terminal/theme.js";
5
+ import { formatCliCommand } from "../command-format.js";
2
6
  import { runServiceRestart, runServiceStart, runServiceStop, runServiceUninstall, } from "./lifecycle-core.js";
3
- import { renderGatewayServiceStartHints } from "./shared.js";
7
+ import { renderRestartDiagnostics, terminateStaleGatewayPids, waitForGatewayHealthyRestart, } from "./restart-health.js";
8
+ import { parsePortFromArgs, renderGatewayServiceStartHints } from "./shared.js";
9
+ const POST_RESTART_HEALTH_ATTEMPTS = 8;
10
+ const POST_RESTART_HEALTH_DELAY_MS = 450;
11
+ async function resolveGatewayRestartPort() {
12
+ const service = resolveGatewayService();
13
+ const command = await service.readCommand(process.env).catch(() => null);
14
+ const serviceEnv = command?.environment ?? undefined;
15
+ const mergedEnv = {
16
+ ...process.env,
17
+ ...(serviceEnv ?? undefined),
18
+ };
19
+ const portFromArgs = parsePortFromArgs(command?.programArguments);
20
+ return portFromArgs ?? resolveGatewayPort(loadConfig(), mergedEnv);
21
+ }
4
22
  export async function runDaemonUninstall(opts = {}) {
5
23
  return await runServiceUninstall({
6
24
  serviceNoun: "Gateway",
@@ -31,11 +49,55 @@ export async function runDaemonStop(opts = {}) {
31
49
  * Throws/exits on check or restart failures.
32
50
  */
33
51
  export async function runDaemonRestart(opts = {}) {
52
+ const json = Boolean(opts.json);
53
+ const service = resolveGatewayService();
54
+ const restartPort = await resolveGatewayRestartPort().catch(() => resolveGatewayPort(loadConfig(), process.env));
34
55
  return await runServiceRestart({
35
56
  serviceNoun: "Gateway",
36
- service: resolveGatewayService(),
57
+ service,
37
58
  renderStartHints: renderGatewayServiceStartHints,
38
59
  opts,
39
60
  checkTokenDrift: true,
61
+ postRestartCheck: async ({ warnings, fail, stdout }) => {
62
+ let health = await waitForGatewayHealthyRestart({
63
+ service,
64
+ port: restartPort,
65
+ attempts: POST_RESTART_HEALTH_ATTEMPTS,
66
+ delayMs: POST_RESTART_HEALTH_DELAY_MS,
67
+ });
68
+ if (!health.healthy && health.staleGatewayPids.length > 0) {
69
+ const staleMsg = `Found stale gateway process(es): ${health.staleGatewayPids.join(", ")}.`;
70
+ warnings.push(staleMsg);
71
+ if (!json) {
72
+ defaultRuntime.log(theme.warn(staleMsg));
73
+ defaultRuntime.log(theme.muted("Stopping stale process(es) and retrying restart..."));
74
+ }
75
+ await terminateStaleGatewayPids(health.staleGatewayPids);
76
+ await service.restart({ env: process.env, stdout });
77
+ health = await waitForGatewayHealthyRestart({
78
+ service,
79
+ port: restartPort,
80
+ attempts: POST_RESTART_HEALTH_ATTEMPTS,
81
+ delayMs: POST_RESTART_HEALTH_DELAY_MS,
82
+ });
83
+ }
84
+ if (health.healthy) {
85
+ return;
86
+ }
87
+ const diagnostics = renderRestartDiagnostics(health);
88
+ if (!json) {
89
+ defaultRuntime.log(theme.warn("Gateway did not become healthy after restart."));
90
+ for (const line of diagnostics) {
91
+ defaultRuntime.log(theme.muted(line));
92
+ }
93
+ }
94
+ else {
95
+ warnings.push(...diagnostics);
96
+ }
97
+ fail("Gateway restart failed health checks.", [
98
+ formatCliCommand("poolbot gateway status --probe --deep"),
99
+ formatCliCommand("poolbot doctor"),
100
+ ]);
101
+ },
40
102
  });
41
103
  }
@@ -0,0 +1,126 @@
1
+ import { classifyPortListener, formatPortDiagnostics, inspectPortUsage, } from "../../infra/ports.js";
2
+ import { sleep } from "../../utils.js";
3
+ export const DEFAULT_RESTART_HEALTH_ATTEMPTS = 8;
4
+ export const DEFAULT_RESTART_HEALTH_DELAY_MS = 450;
5
+ export async function inspectGatewayRestart(params) {
6
+ const env = params.env ?? process.env;
7
+ let runtime = { status: "unknown" };
8
+ try {
9
+ runtime = await params.service.readRuntime(env);
10
+ }
11
+ catch (err) {
12
+ runtime = { status: "unknown", detail: String(err) };
13
+ }
14
+ let portUsage;
15
+ try {
16
+ portUsage = await inspectPortUsage(params.port);
17
+ }
18
+ catch (err) {
19
+ portUsage = {
20
+ port: params.port,
21
+ status: "unknown",
22
+ listeners: [],
23
+ hints: [],
24
+ errors: [String(err)],
25
+ };
26
+ }
27
+ const gatewayListeners = portUsage.status === "busy"
28
+ ? portUsage.listeners.filter((listener) => classifyPortListener(listener, params.port) === "gateway")
29
+ : [];
30
+ const running = runtime.status === "running";
31
+ const ownsPort = runtime.pid != null
32
+ ? portUsage.listeners.some((listener) => listener.pid === runtime.pid)
33
+ : gatewayListeners.length > 0 ||
34
+ (portUsage.status === "busy" && portUsage.listeners.length === 0);
35
+ const healthy = running && ownsPort;
36
+ const staleGatewayPids = Array.from(new Set(gatewayListeners
37
+ .map((listener) => listener.pid)
38
+ .filter((pid) => Number.isFinite(pid))
39
+ .filter((pid) => runtime.pid == null || pid !== runtime.pid || !running)));
40
+ return {
41
+ runtime,
42
+ portUsage,
43
+ healthy,
44
+ staleGatewayPids,
45
+ };
46
+ }
47
+ export async function waitForGatewayHealthyRestart(params) {
48
+ const attempts = params.attempts ?? DEFAULT_RESTART_HEALTH_ATTEMPTS;
49
+ const delayMs = params.delayMs ?? DEFAULT_RESTART_HEALTH_DELAY_MS;
50
+ let snapshot = await inspectGatewayRestart({
51
+ service: params.service,
52
+ port: params.port,
53
+ env: params.env,
54
+ });
55
+ for (let attempt = 0; attempt < attempts; attempt += 1) {
56
+ if (snapshot.healthy) {
57
+ return snapshot;
58
+ }
59
+ if (snapshot.staleGatewayPids.length > 0 && snapshot.runtime.status !== "running") {
60
+ return snapshot;
61
+ }
62
+ await sleep(delayMs);
63
+ snapshot = await inspectGatewayRestart({
64
+ service: params.service,
65
+ port: params.port,
66
+ env: params.env,
67
+ });
68
+ }
69
+ return snapshot;
70
+ }
71
+ export function renderRestartDiagnostics(snapshot) {
72
+ const lines = [];
73
+ const runtimeSummary = [
74
+ snapshot.runtime.status ? `status=${snapshot.runtime.status}` : null,
75
+ snapshot.runtime.state ? `state=${snapshot.runtime.state}` : null,
76
+ snapshot.runtime.pid != null ? `pid=${snapshot.runtime.pid}` : null,
77
+ snapshot.runtime.lastExitStatus != null ? `lastExit=${snapshot.runtime.lastExitStatus}` : null,
78
+ ]
79
+ .filter(Boolean)
80
+ .join(", ");
81
+ if (runtimeSummary) {
82
+ lines.push(`Service runtime: ${runtimeSummary}`);
83
+ }
84
+ if (snapshot.portUsage.status === "busy") {
85
+ lines.push(...formatPortDiagnostics(snapshot.portUsage));
86
+ }
87
+ else {
88
+ lines.push(`Gateway port ${snapshot.portUsage.port} status: ${snapshot.portUsage.status}.`);
89
+ }
90
+ if (snapshot.portUsage.errors?.length) {
91
+ lines.push(`Port diagnostics errors: ${snapshot.portUsage.errors.join("; ")}`);
92
+ }
93
+ return lines;
94
+ }
95
+ export async function terminateStaleGatewayPids(pids) {
96
+ const killed = [];
97
+ for (const pid of pids) {
98
+ try {
99
+ process.kill(pid, "SIGTERM");
100
+ killed.push(pid);
101
+ }
102
+ catch (err) {
103
+ const code = err?.code;
104
+ if (code !== "ESRCH") {
105
+ throw err;
106
+ }
107
+ }
108
+ }
109
+ if (killed.length === 0) {
110
+ return killed;
111
+ }
112
+ await sleep(400);
113
+ for (const pid of killed) {
114
+ try {
115
+ process.kill(pid, 0);
116
+ process.kill(pid, "SIGKILL");
117
+ }
118
+ catch (err) {
119
+ const code = err?.code;
120
+ if (code !== "ESRCH") {
121
+ throw err;
122
+ }
123
+ }
124
+ }
125
+ return killed;
126
+ }
@@ -1,19 +1,20 @@
1
1
  import { createConfigIO, resolveConfigPath, resolveGatewayPort, resolveStateDir, } from "../../config/config.js";
2
2
  import { readLastGatewayErrorLine } from "../../daemon/diagnostics.js";
3
3
  import { findExtraGatewayServices } from "../../daemon/inspect.js";
4
- import { findLegacyGatewayServices } from "../../daemon/legacy.js";
5
- import { resolveGatewayService } from "../../daemon/service.js";
6
4
  import { auditGatewayServiceConfig } from "../../daemon/service-audit.js";
5
+ import { resolveGatewayService } from "../../daemon/service.js";
7
6
  import { resolveGatewayBindHost } from "../../gateway/net.js";
8
7
  import { formatPortDiagnostics, inspectPortUsage, } from "../../infra/ports.js";
9
8
  import { pickPrimaryTailnetIPv4 } from "../../infra/tailnet.js";
10
9
  import { probeGatewayStatus } from "./probe.js";
11
10
  import { normalizeListenerAddress, parsePortFromArgs, pickProbeHostForBind } from "./shared.js";
12
11
  function shouldReportPortUsage(status, rpcOk) {
13
- if (status !== "busy")
12
+ if (status !== "busy") {
14
13
  return false;
15
- if (rpcOk === true)
14
+ }
15
+ if (rpcOk === true) {
16
16
  return false;
17
+ }
17
18
  return true;
18
19
  }
19
20
  export async function gatherDaemonStatus(opts) {
@@ -73,7 +74,7 @@ export async function gatherDaemonStatus(opts) {
73
74
  const probeUrlOverride = typeof opts.rpc.url === "string" && opts.rpc.url.trim().length > 0 ? opts.rpc.url.trim() : null;
74
75
  const probeUrl = probeUrlOverride ?? `ws://${probeHost}:${daemonPort}`;
75
76
  const probeNote = !probeUrlOverride && bindMode === "lan"
76
- ? "Local probe uses loopback (127.0.0.1). bind=lan listens on 0.0.0.0 (all interfaces); use a LAN IP for remote clients."
77
+ ? `bind=lan listens on 0.0.0.0 (all interfaces); probing via ${probeHost}.`
77
78
  : !probeUrlOverride && bindMode === "loopback"
78
79
  ? "Loopback-only gateway; only local clients can connect."
79
80
  : undefined;
@@ -98,20 +99,15 @@ export async function gatherDaemonStatus(opts) {
98
99
  hints: portCliDiagnostics.hints,
99
100
  }
100
101
  : undefined;
101
- const legacyServices = await findLegacyGatewayServices(process.env).catch(() => []);
102
102
  const extraServices = await findExtraGatewayServices(process.env, { deep: Boolean(opts.deep) }).catch(() => []);
103
103
  const timeoutMsRaw = Number.parseInt(String(opts.rpc.timeout ?? "10000"), 10);
104
104
  const timeoutMs = Number.isFinite(timeoutMsRaw) && timeoutMsRaw > 0 ? timeoutMsRaw : 10_000;
105
105
  const rpc = opts.probe
106
106
  ? await probeGatewayStatus({
107
107
  url: probeUrl,
108
- token: opts.rpc.token ||
109
- mergedDaemonEnv.POOLBOT_GATEWAY_TOKEN ||
110
- mergedDaemonEnv.CLAWDBOT_GATEWAY_TOKEN ||
111
- daemonCfg.gateway?.auth?.token,
108
+ token: opts.rpc.token || mergedDaemonEnv.POOLBOT_GATEWAY_TOKEN || daemonCfg.gateway?.auth?.token,
112
109
  password: opts.rpc.password ||
113
110
  mergedDaemonEnv.POOLBOT_GATEWAY_PASSWORD ||
114
- mergedDaemonEnv.CLAWDBOT_GATEWAY_PASSWORD ||
115
111
  daemonCfg.gateway?.auth?.password,
116
112
  timeoutMs,
117
113
  json: opts.rpc.json,
@@ -150,13 +146,13 @@ export async function gatherDaemonStatus(opts) {
150
146
  ...(portCliStatus ? { portCli: portCliStatus } : {}),
151
147
  lastError,
152
148
  ...(rpc ? { rpc: { ...rpc, url: probeUrl } } : {}),
153
- legacyServices,
154
149
  extraServices,
155
150
  };
156
151
  }
157
152
  export function renderPortDiagnosticsForCli(status, rpcOk) {
158
- if (!status.port || !shouldReportPortUsage(status.port.status, rpcOk))
153
+ if (!status.port || !shouldReportPortUsage(status.port.status, rpcOk)) {
159
154
  return [];
155
+ }
160
156
  return formatPortDiagnostics({
161
157
  port: status.port.port,
162
158
  status: status.port.status,
@@ -42,7 +42,7 @@ export function printDaemonStatus(status, opts) {
42
42
  const warnText = (value) => colorize(rich, theme.warn, value);
43
43
  const errorText = (value) => colorize(rich, theme.error, value);
44
44
  const spacer = () => defaultRuntime.log("");
45
- const { service, rpc, legacyServices, extraServices } = status;
45
+ const { service, rpc, extraServices } = status;
46
46
  const serviceStatus = service.loaded
47
47
  ? okText(service.loadedText)
48
48
  : warnText(service.notLoadedText);
@@ -213,14 +213,6 @@ export function printDaemonStatus(status, opts) {
213
213
  }
214
214
  spacer();
215
215
  }
216
- if (legacyServices.length > 0) {
217
- defaultRuntime.error(errorText("Legacy gateway services detected:"));
218
- for (const svc of legacyServices) {
219
- defaultRuntime.error(`- ${errorText(svc.label)} (${svc.detail})`);
220
- }
221
- defaultRuntime.error(errorText(`Cleanup: ${formatCliCommand("poolbot doctor")}`));
222
- spacer();
223
- }
224
216
  if (extraServices.length > 0) {
225
217
  defaultRuntime.error(errorText("Other gateway-like services detected (best effort):"));
226
218
  for (const svc of extraServices) {
@@ -231,7 +223,7 @@ export function printDaemonStatus(status, opts) {
231
223
  }
232
224
  spacer();
233
225
  }
234
- if (legacyServices.length > 0 || extraServices.length > 0) {
226
+ if (extraServices.length > 0) {
235
227
  defaultRuntime.error(errorText("Recommendation: run a single gateway per machine for most setups. One gateway supports multiple agents (see docs: /gateway#multiple-gateways-same-host)."));
236
228
  defaultRuntime.error(errorText("If you need multiple gateways (e.g., a rescue bot on the same host), isolate ports + config/state (see docs: /gateway#multiple-gateways-same-host)."));
237
229
  spacer();
package/dist/cli/deps.js CHANGED
@@ -1,28 +1,33 @@
1
- import { logWebSelfId, sendMessageWhatsApp } from "../channels/web/index.js";
2
- import { sendMessageDiscord } from "../discord/send.js";
3
- import { sendMessageIMessage } from "../imessage/send.js";
4
- import { sendMessageSignal } from "../signal/send.js";
5
- import { sendMessageSlack } from "../slack/send.js";
6
- import { sendMessageTelegram } from "../telegram/send.js";
1
+ import { createOutboundSendDepsFromCliSource } from "./outbound-send-mapping.js";
7
2
  export function createDefaultDeps() {
8
3
  return {
9
- sendMessageWhatsApp,
10
- sendMessageTelegram,
11
- sendMessageDiscord,
12
- sendMessageSlack,
13
- sendMessageSignal,
14
- sendMessageIMessage,
4
+ sendMessageWhatsApp: async (...args) => {
5
+ const { sendMessageWhatsApp } = await import("../channels/web/index.js");
6
+ return await sendMessageWhatsApp(...args);
7
+ },
8
+ sendMessageTelegram: async (...args) => {
9
+ const { sendMessageTelegram } = await import("../telegram/send.js");
10
+ return await sendMessageTelegram(...args);
11
+ },
12
+ sendMessageDiscord: async (...args) => {
13
+ const { sendMessageDiscord } = await import("../discord/send.js");
14
+ return await sendMessageDiscord(...args);
15
+ },
16
+ sendMessageSlack: async (...args) => {
17
+ const { sendMessageSlack } = await import("../slack/send.js");
18
+ return await sendMessageSlack(...args);
19
+ },
20
+ sendMessageSignal: async (...args) => {
21
+ const { sendMessageSignal } = await import("../signal/send.js");
22
+ return await sendMessageSignal(...args);
23
+ },
24
+ sendMessageIMessage: async (...args) => {
25
+ const { sendMessageIMessage } = await import("../imessage/send.js");
26
+ return await sendMessageIMessage(...args);
27
+ },
15
28
  };
16
29
  }
17
- // Provider docking: extend this mapping when adding new outbound send deps.
18
30
  export function createOutboundSendDeps(deps) {
19
- return {
20
- sendWhatsApp: deps.sendMessageWhatsApp,
21
- sendTelegram: deps.sendMessageTelegram,
22
- sendDiscord: deps.sendMessageDiscord,
23
- sendSlack: deps.sendMessageSlack,
24
- sendSignal: deps.sendMessageSignal,
25
- sendIMessage: deps.sendMessageIMessage,
26
- };
31
+ return createOutboundSendDepsFromCliSource(deps);
27
32
  }
28
- export { logWebSelfId };
33
+ export { logWebSelfId } from "../web/auth-store.js";
@@ -1,5 +1,6 @@
1
1
  import { acquireGatewayLock } from "../../infra/gateway-lock.js";
2
- import { consumeGatewaySigusr1RestartAuthorization, isGatewaySigusr1RestartExternallyAllowed, } from "../../infra/restart.js";
2
+ import { restartGatewayProcessWithFreshPid } from "../../infra/process-respawn.js";
3
+ import { consumeGatewaySigusr1RestartAuthorization, isGatewaySigusr1RestartExternallyAllowed, markGatewaySigusr1RestartHandled, } from "../../infra/restart.js";
3
4
  import { createSubsystemLogger } from "../../logging/subsystem.js";
4
5
  import { getActiveTaskCount, resetAllLanes, waitForActiveTasks, } from "../../process/command-queue.js";
5
6
  import { createRestartIterationHook } from "../../process/restart-recovery.js";
@@ -60,9 +61,25 @@ export async function runGatewayLoop(params) {
60
61
  clearTimeout(forceExitTimer);
61
62
  server = null;
62
63
  if (isRestart) {
63
- // In-process restart (no process-respawn in pool-bot).
64
- shuttingDown = false;
65
- restartResolver?.();
64
+ const respawn = restartGatewayProcessWithFreshPid();
65
+ if (respawn.mode === "spawned" || respawn.mode === "supervised") {
66
+ const modeLabel = respawn.mode === "spawned"
67
+ ? `spawned pid ${respawn.pid ?? "unknown"}`
68
+ : "supervisor restart";
69
+ gatewayLog.info(`restart mode: full process restart (${modeLabel})`);
70
+ cleanupSignals();
71
+ params.runtime.exit(0);
72
+ }
73
+ else {
74
+ if (respawn.mode === "failed") {
75
+ gatewayLog.warn(`full process restart failed (${respawn.detail ?? "unknown error"}); falling back to in-process restart`);
76
+ }
77
+ else {
78
+ gatewayLog.info("restart mode: in-process restart (POOLBOT_NO_RESPAWN)");
79
+ }
80
+ shuttingDown = false;
81
+ restartResolver?.();
82
+ }
66
83
  }
67
84
  else {
68
85
  cleanupSignals();
@@ -83,9 +100,10 @@ export async function runGatewayLoop(params) {
83
100
  gatewayLog.info("signal SIGUSR1 received");
84
101
  const authorized = consumeGatewaySigusr1RestartAuthorization();
85
102
  if (!authorized && !isGatewaySigusr1RestartExternallyAllowed()) {
86
- gatewayLog.warn("SIGUSR1 restart ignored (not authorized; enable commands.restart or use gateway tool).");
103
+ gatewayLog.warn("SIGUSR1 restart ignored (not authorized; commands.restart=false or use gateway tool).");
87
104
  return;
88
105
  }
106
+ markGatewaySigusr1RestartHandled();
89
107
  request("restart", "SIGUSR1");
90
108
  };
91
109
  process.on("SIGTERM", onSigterm);
@@ -1,9 +1,10 @@
1
- import { formatDocsLink } from "../../terminal/links.js";
2
- import { theme } from "../../terminal/theme.js";
3
1
  import { loadNodeHostConfig } from "../../node-host/config.js";
4
2
  import { runNodeHost } from "../../node-host/runner.js";
5
- import { runNodeDaemonInstall, runNodeDaemonRestart, runNodeDaemonStatus, runNodeDaemonStop, runNodeDaemonUninstall, } from "./daemon.js";
3
+ import { formatDocsLink } from "../../terminal/links.js";
4
+ import { theme } from "../../terminal/theme.js";
6
5
  import { parsePort } from "../daemon-cli/shared.js";
6
+ import { formatHelpExamples } from "../help-format.js";
7
+ import { runNodeDaemonInstall, runNodeDaemonRestart, runNodeDaemonStatus, runNodeDaemonStop, runNodeDaemonUninstall, } from "./daemon.js";
7
8
  function parsePortWithFallback(value, fallback) {
8
9
  const parsed = parsePort(value);
9
10
  return parsed ?? fallback;
@@ -11,8 +12,16 @@ function parsePortWithFallback(value, fallback) {
11
12
  export function registerNodeCli(program) {
12
13
  const node = program
13
14
  .command("node")
14
- .description("Run a headless node host (system.run/system.which)")
15
- .addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/node", "docs.molt.bot/cli/node")}\n`);
15
+ .description("Run and manage the headless node host service")
16
+ .addHelpText("after", () => `\n${theme.heading("Examples:")}\n${formatHelpExamples([
17
+ [
18
+ "poolbot node run --host 127.0.0.1 --port 18789",
19
+ "Run the node host in the foreground.",
20
+ ],
21
+ ["poolbot node status", "Check node host service status."],
22
+ ["poolbot node install", "Install the node host service."],
23
+ ["poolbot node restart", "Restart the installed node host service."],
24
+ ])}\n\n${theme.muted("Docs:")} ${formatDocsLink("/cli/node", "docs.molt.bot/cli/node")}\n`);
16
25
  node
17
26
  .command("run")
18
27
  .description("Run the headless node host (foreground)")
@@ -1,5 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
- import * as os from "node:os";
2
+ import fs from "node:fs";
3
+ import { resolvePreferredPoolbotTmpDir } from "../infra/tmp-poolbot-dir.js";
3
4
  export function asRecord(value) {
4
5
  return typeof value === "object" && value !== null ? value : {};
5
6
  }
@@ -13,8 +14,12 @@ export function asBoolean(value) {
13
14
  return typeof value === "boolean" ? value : undefined;
14
15
  }
15
16
  export function resolveTempPathParts(opts) {
17
+ const tmpDir = opts.tmpDir ?? resolvePreferredPoolbotTmpDir();
18
+ if (!opts.tmpDir) {
19
+ fs.mkdirSync(tmpDir, { recursive: true, mode: 0o700 });
20
+ }
16
21
  return {
17
- tmpDir: opts.tmpDir ?? os.tmpdir(),
22
+ tmpDir,
18
23
  id: opts.id ?? randomUUID(),
19
24
  ext: opts.ext.startsWith(".") ? opts.ext : `.${opts.ext}`,
20
25
  };
@@ -1,11 +1,4 @@
1
- // Provider docking: extend this mapping when adding new outbound send deps.
1
+ import { createOutboundSendDepsFromCliSource, } from "./outbound-send-mapping.js";
2
2
  export function createOutboundSendDeps(deps) {
3
- return {
4
- sendWhatsApp: deps.sendMessageWhatsApp,
5
- sendTelegram: deps.sendMessageTelegram,
6
- sendDiscord: deps.sendMessageDiscord,
7
- sendSlack: deps.sendMessageSlack,
8
- sendSignal: deps.sendMessageSignal,
9
- sendIMessage: deps.sendMessageIMessage,
10
- };
3
+ return createOutboundSendDepsFromCliSource(deps);
11
4
  }
@@ -0,0 +1,11 @@
1
+ // Provider docking: extend this mapping when adding new outbound send deps.
2
+ export function createOutboundSendDepsFromCliSource(deps) {
3
+ return {
4
+ sendWhatsApp: deps.sendMessageWhatsApp,
5
+ sendTelegram: deps.sendMessageTelegram,
6
+ sendDiscord: deps.sendMessageDiscord,
7
+ sendSlack: deps.sendMessageSlack,
8
+ sendSignal: deps.sendMessageSignal,
9
+ sendIMessage: deps.sendMessageIMessage,
10
+ };
11
+ }
@@ -1,5 +1,5 @@
1
- import { listPairingChannels, notifyPairingApproved } from "../channels/plugins/pairing.js";
2
1
  import { normalizeChannelId } from "../channels/plugins/index.js";
2
+ import { listPairingChannels, notifyPairingApproved } from "../channels/plugins/pairing.js";
3
3
  import { loadConfig } from "../config/config.js";
4
4
  import { resolvePairingIdLabel } from "../pairing/pairing-labels.js";
5
5
  import { approveChannelPairingCode, listChannelPairingRequests, } from "../pairing/pairing-store.js";
@@ -17,8 +17,9 @@ function parseChannel(raw, channels) {
17
17
  : "")
18
18
  .trim()
19
19
  .toLowerCase();
20
- if (!value)
20
+ if (!value) {
21
21
  throw new Error("Channel required");
22
+ }
22
23
  const normalized = normalizeChannelId(value);
23
24
  if (normalized) {
24
25
  if (!channels.includes(normalized)) {
@@ -27,8 +28,9 @@ function parseChannel(raw, channels) {
27
28
  return normalized;
28
29
  }
29
30
  // Allow extension channels: validate format but don't require registry
30
- if (/^[a-z][a-z0-9_-]{0,63}$/.test(value))
31
+ if (/^[a-z][a-z0-9_-]{0,63}$/.test(value)) {
31
32
  return value;
33
+ }
32
34
  throw new Error(`Invalid channel: ${value}`);
33
35
  }
34
36
  async function notifyApproved(channel, id) {
@@ -40,20 +42,24 @@ export function registerPairingCli(program) {
40
42
  const pairing = program
41
43
  .command("pairing")
42
44
  .description("Secure DM pairing (approve inbound requests)")
43
- .addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/pairing", "docs.molt.bot/cli/pairing")}\n`);
45
+ .addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/pairing", "docs.poolbot.ai/cli/pairing")}\n`);
44
46
  pairing
45
47
  .command("list")
46
48
  .description("List pending pairing requests")
47
49
  .option("--channel <channel>", `Channel (${channels.join(", ")})`)
50
+ .option("--account <accountId>", "Account id (for multi-account channels)")
48
51
  .argument("[channel]", `Channel (${channels.join(", ")})`)
49
52
  .option("--json", "Print JSON", false)
50
53
  .action(async (channelArg, opts) => {
51
- const channelRaw = opts.channel ?? channelArg;
54
+ const channelRaw = opts.channel ?? channelArg ?? (channels.length === 1 ? channels[0] : "");
52
55
  if (!channelRaw) {
53
56
  throw new Error(`Channel required. Use --channel <channel> or pass it as the first argument (expected one of: ${channels.join(", ")})`);
54
57
  }
55
58
  const channel = parseChannel(channelRaw, channels);
56
- const requests = await listChannelPairingRequests(channel);
59
+ const accountId = String(opts.account ?? "").trim();
60
+ const requests = accountId
61
+ ? await listChannelPairingRequests(channel, process.env, accountId)
62
+ : await listChannelPairingRequests(channel);
57
63
  if (opts.json) {
58
64
  defaultRuntime.log(JSON.stringify({ channel, requests }, null, 2));
59
65
  return;
@@ -85,29 +91,49 @@ export function registerPairingCli(program) {
85
91
  .command("approve")
86
92
  .description("Approve a pairing code and allow that sender")
87
93
  .option("--channel <channel>", `Channel (${channels.join(", ")})`)
94
+ .option("--account <accountId>", "Account id (for multi-account channels)")
88
95
  .argument("<codeOrChannel>", "Pairing code (or channel when using 2 args)")
89
96
  .argument("[code]", "Pairing code (when channel is passed as the 1st arg)")
90
97
  .option("--notify", "Notify the requester on the same channel", false)
91
98
  .action(async (codeOrChannel, code, opts) => {
92
- const channelRaw = opts.channel ?? codeOrChannel;
93
- const resolvedCode = opts.channel ? codeOrChannel : code;
94
- if (!opts.channel && !code) {
99
+ const defaultChannel = channels.length === 1 ? channels[0] : "";
100
+ const usingExplicitChannel = Boolean(opts.channel);
101
+ const hasPositionalCode = code != null;
102
+ const channelRaw = usingExplicitChannel
103
+ ? opts.channel
104
+ : hasPositionalCode
105
+ ? codeOrChannel
106
+ : defaultChannel;
107
+ const resolvedCode = usingExplicitChannel
108
+ ? codeOrChannel
109
+ : hasPositionalCode
110
+ ? code
111
+ : codeOrChannel;
112
+ if (!channelRaw || !resolvedCode) {
95
113
  throw new Error(`Usage: ${formatCliCommand("poolbot pairing approve <channel> <code>")} (or: ${formatCliCommand("poolbot pairing approve --channel <channel> <code>")})`);
96
114
  }
97
115
  if (opts.channel && code != null) {
98
116
  throw new Error(`Too many arguments. Use: ${formatCliCommand("poolbot pairing approve --channel <channel> <code>")}`);
99
117
  }
100
118
  const channel = parseChannel(channelRaw, channels);
101
- const approved = await approveChannelPairingCode({
102
- channel,
103
- code: String(resolvedCode),
104
- });
119
+ const accountId = String(opts.account ?? "").trim();
120
+ const approved = accountId
121
+ ? await approveChannelPairingCode({
122
+ channel,
123
+ code: String(resolvedCode),
124
+ accountId,
125
+ })
126
+ : await approveChannelPairingCode({
127
+ channel,
128
+ code: String(resolvedCode),
129
+ });
105
130
  if (!approved) {
106
131
  throw new Error(`No pending pairing request found for code: ${String(resolvedCode)}`);
107
132
  }
108
133
  defaultRuntime.log(`${theme.success("Approved")} ${theme.muted(channel)} sender ${theme.command(approved.id)}.`);
109
- if (!opts.notify)
134
+ if (!opts.notify) {
110
135
  return;
136
+ }
111
137
  await notifyApproved(channel, approved.id).catch((err) => {
112
138
  defaultRuntime.log(theme.warn(`Failed to notify requester: ${String(err)}`));
113
139
  });