@poolzin/pool-bot 2026.1.39 → 2026.2.1

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 (511) hide show
  1. package/assets/chrome-extension/README.md +3 -3
  2. package/assets/chrome-extension/background.js +5 -5
  3. package/assets/chrome-extension/manifest.json +3 -3
  4. package/assets/chrome-extension/options.html +4 -4
  5. package/assets/chrome-extension/options.js +1 -1
  6. package/dist/acp/client.js +3 -3
  7. package/dist/acp/types.js +1 -1
  8. package/dist/agents/agent-paths.js +3 -3
  9. package/dist/agents/auth-profiles/paths.js +3 -3
  10. package/dist/agents/bash-tools.exec.js +76 -25
  11. package/dist/agents/cli-runner/helpers.js +10 -12
  12. package/dist/agents/cli-runner.js +2 -2
  13. package/dist/agents/cloudflare-ai-gateway.js +31 -0
  14. package/dist/agents/compaction.js +16 -2
  15. package/dist/agents/context-window-guard.js +13 -10
  16. package/dist/agents/context.js +4 -4
  17. package/dist/agents/docs-path.js +1 -1
  18. package/dist/agents/identity.js +47 -7
  19. package/dist/agents/memory-search.js +25 -8
  20. package/dist/agents/minimax-vlm.js +1 -1
  21. package/dist/agents/model-auth.js +12 -1
  22. package/dist/agents/model-catalog.js +4 -4
  23. package/dist/agents/model-selection.js +31 -4
  24. package/dist/agents/models-config.js +3 -3
  25. package/dist/agents/models-config.providers.js +147 -39
  26. package/dist/agents/pi-embedded-block-chunker.js +117 -42
  27. package/dist/agents/pi-embedded-helpers/errors.js +183 -78
  28. package/dist/agents/pi-embedded-helpers/openai.js +1 -1
  29. package/dist/agents/pi-embedded-helpers.js +1 -1
  30. package/dist/agents/pi-embedded-runner/compact.js +9 -8
  31. package/dist/agents/pi-embedded-runner/model.js +63 -4
  32. package/dist/agents/pi-embedded-runner/run/attempt.js +27 -17
  33. package/dist/agents/pi-embedded-runner/run.js +203 -50
  34. package/dist/agents/pi-embedded-runner/system-prompt.js +10 -2
  35. package/dist/agents/pi-embedded-runner/tool-result-truncation.js +275 -0
  36. package/dist/agents/pi-embedded-runner/utils.js +1 -1
  37. package/dist/agents/pi-embedded-subscribe.js +118 -29
  38. package/dist/agents/pi-model-discovery.js +10 -0
  39. package/dist/agents/pi-tool-definition-adapter.js +50 -9
  40. package/dist/agents/pi-tools.before-tool-call.js +67 -0
  41. package/dist/agents/pi-tools.js +20 -10
  42. package/dist/agents/pi-tools.read.js +2 -2
  43. package/dist/agents/poolbot-tools.js +15 -10
  44. package/dist/agents/sandbox-paths.js +31 -0
  45. package/dist/agents/session-file-repair.js +83 -0
  46. package/dist/agents/session-tool-result-guard.js +94 -15
  47. package/dist/agents/session-transcript-repair.js +68 -0
  48. package/dist/agents/shell-utils.js +51 -0
  49. package/dist/agents/skills/bundled-context.js +23 -0
  50. package/dist/agents/skills/bundled-dir.js +41 -7
  51. package/dist/agents/skills/frontmatter.js +1 -1
  52. package/dist/agents/skills/workspace.js +2 -2
  53. package/dist/agents/skills-install.js +60 -23
  54. package/dist/agents/subagent-announce.js +79 -34
  55. package/dist/agents/system-prompt.js +28 -4
  56. package/dist/agents/together-models.js +127 -0
  57. package/dist/agents/tool-images.js +1 -1
  58. package/dist/agents/tool-policy.conformance.js +14 -0
  59. package/dist/agents/tool-policy.js +25 -1
  60. package/dist/agents/tools/browser-tool.js +3 -3
  61. package/dist/agents/tools/cron-tool.js +166 -19
  62. package/dist/agents/tools/discord-actions-presence.js +78 -0
  63. package/dist/agents/tools/image-tool.js +2 -2
  64. package/dist/agents/tools/memory-tool.js +93 -5
  65. package/dist/agents/tools/message-tool.js +56 -2
  66. package/dist/agents/tools/sessions-history-tool.js +69 -1
  67. package/dist/agents/tools/web-search.js +211 -42
  68. package/dist/agents/usage.js +23 -1
  69. package/dist/agents/workspace-run.js +67 -0
  70. package/dist/agents/workspace-templates.js +44 -0
  71. package/dist/auto-reply/command-auth.js +121 -6
  72. package/dist/auto-reply/commands-registry.data.js +1 -1
  73. package/dist/auto-reply/envelope.js +50 -72
  74. package/dist/auto-reply/reply/commands-compact.js +1 -0
  75. package/dist/auto-reply/reply/commands-context-report.js +3 -2
  76. package/dist/auto-reply/reply/commands-context.js +1 -0
  77. package/dist/auto-reply/reply/commands-models.js +107 -60
  78. package/dist/auto-reply/reply/commands-ptt.js +171 -0
  79. package/dist/auto-reply/reply/commands-session.js +2 -2
  80. package/dist/auto-reply/reply/get-reply-run.js +16 -5
  81. package/dist/auto-reply/reply/groups.js +1 -1
  82. package/dist/auto-reply/reply/inbound-context.js +9 -1
  83. package/dist/auto-reply/reply/inbound-meta.js +130 -0
  84. package/dist/auto-reply/reply/model-selection.js +3 -3
  85. package/dist/auto-reply/reply/untrusted-context.js +15 -0
  86. package/dist/auto-reply/status.js +1 -1
  87. package/dist/auto-reply/thinking.js +88 -43
  88. package/dist/browser/bridge-server.js +13 -0
  89. package/dist/browser/cdp.helpers.js +38 -24
  90. package/dist/browser/client-fetch.js +51 -8
  91. package/dist/browser/config.js +2 -11
  92. package/dist/browser/extension-relay.js +104 -43
  93. package/dist/browser/pw-ai.js +1 -1
  94. package/dist/browser/pw-session.js +143 -8
  95. package/dist/browser/pw-tools-core.interactions.js +125 -27
  96. package/dist/browser/pw-tools-core.responses.js +1 -1
  97. package/dist/browser/pw-tools-core.state.js +1 -1
  98. package/dist/browser/routes/agent.act.js +86 -41
  99. package/dist/browser/routes/dispatcher.js +4 -4
  100. package/dist/browser/screenshot.js +1 -1
  101. package/dist/browser/server-context.js +2 -2
  102. package/dist/browser/server.js +13 -0
  103. package/dist/build-info.json +3 -3
  104. package/dist/canvas-host/a2ui.js +3 -3
  105. package/dist/channels/plugins/catalog.js +2 -2
  106. package/dist/channels/plugins/onboarding/imessage.js +1 -1
  107. package/dist/channels/plugins/onboarding/signal.js +1 -1
  108. package/dist/channels/plugins/onboarding/slack.js +4 -4
  109. package/dist/channels/plugins/onboarding/whatsapp.js +3 -3
  110. package/dist/channels/plugins/pairing-message.js +1 -1
  111. package/dist/channels/reply-prefix.js +8 -1
  112. package/dist/cli/browser-cli-extension.js +2 -2
  113. package/dist/cli/cron-cli/register.cron-add.js +61 -40
  114. package/dist/cli/cron-cli/register.cron-edit.js +60 -34
  115. package/dist/cli/cron-cli/shared.js +56 -41
  116. package/dist/cli/dns-cli.js +26 -14
  117. package/dist/cli/docs-cli.js +1 -1
  118. package/dist/cli/gateway-cli/dev.js +1 -1
  119. package/dist/cli/gateway-cli/register.js +37 -19
  120. package/dist/cli/memory-cli.js +30 -20
  121. package/dist/cli/nodes-cli/register.canvas.js +1 -1
  122. package/dist/cli/parse-bytes.js +37 -0
  123. package/dist/cli/plugins-cli.js +1 -1
  124. package/dist/cli/run-main.js +2 -2
  125. package/dist/cli/security-cli.js +1 -1
  126. package/dist/cli/tagline.js +1 -1
  127. package/dist/cli/update-cli.js +173 -52
  128. package/dist/cli/webhooks-cli.js +5 -5
  129. package/dist/commands/agent.js +1 -0
  130. package/dist/commands/agents.commands.add.js +1 -1
  131. package/dist/commands/auth-choice.apply.api-providers.js +305 -17
  132. package/dist/commands/auth-choice.apply.js +4 -1
  133. package/dist/commands/auth-choice.apply.plugin-provider.js +2 -2
  134. package/dist/commands/auth-choice.apply.xai.js +63 -0
  135. package/dist/commands/auth-choice.preferred-provider.js +7 -1
  136. package/dist/commands/configure.wizard.js +1 -1
  137. package/dist/commands/dashboard.js +1 -1
  138. package/dist/commands/docs.js +1 -1
  139. package/dist/commands/doctor-config-flow.js +61 -5
  140. package/dist/commands/doctor-gateway-services.js +3 -3
  141. package/dist/commands/doctor-state-migrations.js +1 -1
  142. package/dist/commands/doctor-update.js +3 -3
  143. package/dist/commands/doctor.js +1 -1
  144. package/dist/commands/health.js +1 -1
  145. package/dist/commands/model-allowlist.js +29 -0
  146. package/dist/commands/model-picker.js +2 -1
  147. package/dist/commands/models/list.probe.js +2 -2
  148. package/dist/commands/models/list.registry.js +4 -4
  149. package/dist/commands/models/list.status-command.js +44 -24
  150. package/dist/commands/models/shared.js +15 -0
  151. package/dist/commands/onboard-auth.config-core.js +366 -28
  152. package/dist/commands/onboard-auth.credentials.js +71 -9
  153. package/dist/commands/onboard-auth.js +3 -3
  154. package/dist/commands/onboard-auth.models.js +26 -24
  155. package/dist/commands/onboard-custom.js +384 -0
  156. package/dist/commands/onboard-non-interactive/local/auth-choice-inference.js +35 -0
  157. package/dist/commands/onboard-non-interactive/local/auth-choice.js +146 -9
  158. package/dist/commands/onboard-skills.js +63 -38
  159. package/dist/commands/openai-model-default.js +41 -0
  160. package/dist/commands/status-all/report-lines.js +1 -1
  161. package/dist/commands/status.command.js +1 -1
  162. package/dist/commands/uninstall.js +3 -3
  163. package/dist/compat/legacy-names.js +1 -1
  164. package/dist/config/defaults.js +3 -2
  165. package/dist/config/io.js +3 -3
  166. package/dist/config/paths.js +136 -35
  167. package/dist/config/plugin-auto-enable.js +21 -5
  168. package/dist/config/redact-snapshot.js +153 -0
  169. package/dist/config/schema.field-metadata.js +590 -0
  170. package/dist/config/schema.js +3 -3
  171. package/dist/config/sessions/store.js +291 -23
  172. package/dist/config/types.memory.js +1 -0
  173. package/dist/config/version.js +4 -4
  174. package/dist/config/zod-schema.agent-defaults.js +3 -0
  175. package/dist/config/zod-schema.agent-runtime.js +13 -2
  176. package/dist/config/zod-schema.providers-core.js +142 -0
  177. package/dist/config/zod-schema.session.js +3 -0
  178. package/dist/cron/delivery.js +57 -0
  179. package/dist/cron/isolated-agent/delivery-target.js +18 -3
  180. package/dist/cron/isolated-agent/helpers.js +22 -5
  181. package/dist/cron/isolated-agent/run.js +171 -63
  182. package/dist/cron/isolated-agent/session.js +2 -0
  183. package/dist/cron/normalize.js +356 -28
  184. package/dist/cron/parse.js +10 -5
  185. package/dist/cron/run-log.js +35 -10
  186. package/dist/cron/schedule.js +41 -6
  187. package/dist/cron/service/jobs.js +208 -35
  188. package/dist/cron/service/ops.js +72 -16
  189. package/dist/cron/service/state.js +2 -0
  190. package/dist/cron/service/store.js +386 -14
  191. package/dist/cron/service/timer.js +390 -147
  192. package/dist/cron/session-reaper.js +86 -0
  193. package/dist/cron/store.js +23 -8
  194. package/dist/cron/validate-timestamp.js +43 -0
  195. package/dist/daemon/constants.js +7 -7
  196. package/dist/daemon/inspect.js +6 -6
  197. package/dist/daemon/systemd-unit.js +1 -1
  198. package/dist/discord/monitor/agent-components.js +438 -0
  199. package/dist/discord/monitor/allow-list.js +28 -5
  200. package/dist/discord/monitor/gateway-registry.js +29 -0
  201. package/dist/discord/monitor/native-command.js +44 -23
  202. package/dist/discord/monitor/sender-identity.js +45 -0
  203. package/dist/discord/pluralkit.js +27 -0
  204. package/dist/discord/send.outbound.js +92 -5
  205. package/dist/discord/send.shared.js +60 -23
  206. package/dist/discord/targets.js +84 -1
  207. package/dist/entry.js +15 -9
  208. package/dist/extensionAPI.js +8 -0
  209. package/dist/gateway/control-ui.js +8 -1
  210. package/dist/gateway/hooks-mapping.js +3 -0
  211. package/dist/gateway/hooks.js +65 -0
  212. package/dist/gateway/live-image-probe.js +1 -66
  213. package/dist/gateway/net.js +96 -31
  214. package/dist/gateway/node-command-policy.js +50 -15
  215. package/dist/gateway/openai-http.js +2 -2
  216. package/dist/gateway/openresponses-http.js +4 -4
  217. package/dist/gateway/origin-check.js +56 -0
  218. package/dist/gateway/protocol/client-info.js +9 -0
  219. package/dist/gateway/protocol/index.js +9 -2
  220. package/dist/gateway/protocol/schema/agents-models-skills.js +71 -1
  221. package/dist/gateway/protocol/schema/cron.js +22 -10
  222. package/dist/gateway/protocol/schema/protocol-schemas.js +16 -2
  223. package/dist/gateway/protocol/schema/sessions.js +12 -0
  224. package/dist/gateway/server/hooks.js +1 -1
  225. package/dist/gateway/server-broadcast.js +26 -9
  226. package/dist/gateway/server-chat.js +112 -23
  227. package/dist/gateway/server-discovery-runtime.js +10 -2
  228. package/dist/gateway/server-discovery.js +2 -2
  229. package/dist/gateway/server-http.js +110 -12
  230. package/dist/gateway/server-methods/agent-timestamp.js +60 -0
  231. package/dist/gateway/server-methods/agents.js +321 -2
  232. package/dist/gateway/server-methods/usage.js +559 -16
  233. package/dist/gateway/server-runtime-state.js +22 -8
  234. package/dist/gateway/server-startup-memory.js +16 -0
  235. package/dist/gateway/server.impl.js +7 -3
  236. package/dist/gateway/session-utils.fs.js +23 -25
  237. package/dist/gateway/session-utils.js +20 -10
  238. package/dist/gateway/sessions-patch.js +7 -22
  239. package/dist/gateway/test-helpers.server.js +35 -2
  240. package/dist/hooks/frontmatter.js +1 -1
  241. package/dist/hooks/hooks-status.js +1 -1
  242. package/dist/hooks/install.js +2 -2
  243. package/dist/hooks/loader.js +1 -1
  244. package/dist/hooks/workspace.js +3 -3
  245. package/dist/imessage/constants.js +2 -0
  246. package/dist/imessage/monitor/deliver.js +4 -1
  247. package/dist/imessage/monitor/monitor-provider.js +51 -1
  248. package/dist/index.js +2 -2
  249. package/dist/infra/bonjour-discovery.js +131 -70
  250. package/dist/infra/bonjour.js +3 -3
  251. package/dist/infra/control-ui-assets.js +134 -12
  252. package/dist/infra/errors.js +12 -0
  253. package/dist/infra/exec-approvals.js +266 -57
  254. package/dist/infra/format-time/format-datetime.js +79 -0
  255. package/dist/infra/format-time/format-duration.js +81 -0
  256. package/dist/infra/format-time/format-relative.js +80 -0
  257. package/dist/infra/heartbeat-runner.js +140 -49
  258. package/dist/infra/home-dir.js +54 -0
  259. package/dist/infra/net/fetch-guard.js +122 -0
  260. package/dist/infra/net/ssrf.js +65 -29
  261. package/dist/infra/outbound/abort.js +14 -0
  262. package/dist/infra/outbound/message-action-runner.js +77 -13
  263. package/dist/infra/outbound/outbound-session.js +143 -37
  264. package/dist/infra/path-env.js +3 -3
  265. package/dist/infra/poolbot-root.js +43 -1
  266. package/dist/infra/provider-usage.fetch.minimax.js +1 -1
  267. package/dist/infra/restart.js +1 -1
  268. package/dist/infra/session-cost-usage.js +631 -41
  269. package/dist/infra/state-migrations.js +317 -47
  270. package/dist/infra/tailscale.js +1 -1
  271. package/dist/infra/update-global.js +35 -0
  272. package/dist/infra/update-runner.js +149 -43
  273. package/dist/infra/warning-filter.js +65 -0
  274. package/dist/infra/widearea-dns.js +30 -9
  275. package/dist/logging/redact-identifier.js +12 -0
  276. package/dist/macos/relay.js +2 -2
  277. package/dist/media/fetch.js +81 -58
  278. package/dist/media/input-files.js +1 -1
  279. package/dist/media/mime.js +4 -0
  280. package/dist/media/png-encode.js +74 -0
  281. package/dist/media-understanding/apply.js +403 -3
  282. package/dist/media-understanding/attachments.js +38 -27
  283. package/dist/media-understanding/defaults.js +16 -0
  284. package/dist/media-understanding/providers/deepgram/audio.js +22 -14
  285. package/dist/media-understanding/providers/google/audio.js +24 -17
  286. package/dist/media-understanding/providers/google/video.js +24 -17
  287. package/dist/media-understanding/providers/image.js +4 -4
  288. package/dist/media-understanding/providers/index.js +4 -1
  289. package/dist/media-understanding/providers/openai/audio.js +22 -14
  290. package/dist/media-understanding/providers/shared.js +16 -11
  291. package/dist/media-understanding/providers/zai/index.js +6 -0
  292. package/dist/media-understanding/runner.js +158 -90
  293. package/dist/memory/backend-config.js +207 -0
  294. package/dist/memory/batch-voyage.js +277 -0
  295. package/dist/memory/embeddings-voyage.js +75 -0
  296. package/dist/memory/embeddings.js +29 -17
  297. package/dist/memory/internal.js +101 -18
  298. package/dist/memory/manager.js +155 -48
  299. package/dist/memory/search-manager.js +173 -0
  300. package/dist/memory/session-files.js +9 -3
  301. package/dist/memory/types.js +1 -0
  302. package/dist/node-host/runner.js +36 -26
  303. package/dist/node-host/with-timeout.js +27 -0
  304. package/dist/pairing/pairing-messages.js +1 -1
  305. package/dist/plugins/commands.js +5 -1
  306. package/dist/plugins/config-state.js +86 -7
  307. package/dist/plugins/discovery.js +1 -1
  308. package/dist/plugins/install.js +2 -2
  309. package/dist/plugins/source-display.js +51 -0
  310. package/dist/plugins/update.js +1 -1
  311. package/dist/process/exec.js +20 -2
  312. package/dist/routing/resolve-route.js +12 -0
  313. package/dist/routing/session-key.js +15 -0
  314. package/dist/runtime.js +2 -0
  315. package/dist/security/audit-extra.async.js +601 -0
  316. package/dist/security/audit-extra.js +2 -830
  317. package/dist/security/audit-extra.sync.js +505 -0
  318. package/dist/security/audit.js +2 -2
  319. package/dist/security/channel-metadata.js +34 -0
  320. package/dist/security/external-content.js +88 -6
  321. package/dist/security/skill-scanner.js +330 -0
  322. package/dist/sessions/session-key-utils.js +7 -0
  323. package/dist/shared/text/reasoning-tags.js +52 -7
  324. package/dist/signal/monitor/event-handler.js +80 -1
  325. package/dist/slack/monitor/media.js +85 -15
  326. package/dist/tailscale/detect.js +145 -0
  327. package/dist/telegram/bot/helpers.js +109 -28
  328. package/dist/telegram/bot-handlers.js +144 -3
  329. package/dist/telegram/bot-message-context.js +38 -11
  330. package/dist/telegram/bot-message-dispatch.js +48 -15
  331. package/dist/telegram/bot-native-commands.js +86 -29
  332. package/dist/telegram/bot.js +30 -29
  333. package/dist/telegram/model-buttons.js +163 -0
  334. package/dist/telegram/monitor.js +110 -85
  335. package/dist/telegram/send.js +129 -47
  336. package/dist/terminal/restore.js +45 -0
  337. package/dist/test-helpers/state-dir-env.js +16 -0
  338. package/dist/test-helpers/workspace.js +11 -0
  339. package/dist/test-utils/channel-plugins.js +82 -0
  340. package/dist/test-utils/ports.js +73 -0
  341. package/dist/tts/tts.js +12 -6
  342. package/dist/tui/tui-session-actions.js +166 -54
  343. package/dist/utils/fetch-timeout.js +20 -0
  344. package/dist/utils/normalize-secret-input.js +19 -0
  345. package/dist/utils/shell-argv.js +61 -0
  346. package/dist/utils/transcript-tools.js +58 -0
  347. package/dist/utils.js +55 -14
  348. package/dist/version.js +42 -5
  349. package/dist/web/qr-image.js +1 -61
  350. package/dist/wizard/onboarding.finalize.js +7 -7
  351. package/dist/wizard/onboarding.js +3 -3
  352. package/docs/RELEASE_WORKFOTS_COMPARISON.md +3 -3
  353. package/docs/_config.yml +2 -2
  354. package/docs/_layouts/default.html +9 -9
  355. package/docs/concepts/typebox.md +1 -1
  356. package/docs/docs.json +1 -1
  357. package/docs/northflank.mdx +7 -7
  358. package/docs/railway.mdx +3 -3
  359. package/docs/render.mdx +5 -5
  360. package/docs/start/lore.md +2 -2
  361. package/extensions/bluebubbles/index.ts +2 -2
  362. package/extensions/bluebubbles/package.json +1 -1
  363. package/extensions/bluebubbles/src/accounts.ts +8 -8
  364. package/extensions/bluebubbles/src/actions.test.ts +22 -22
  365. package/extensions/bluebubbles/src/actions.ts +5 -5
  366. package/extensions/bluebubbles/src/attachments.ts +2 -2
  367. package/extensions/bluebubbles/src/channel.ts +16 -16
  368. package/extensions/bluebubbles/src/chat.ts +2 -2
  369. package/extensions/bluebubbles/src/media-send.ts +2 -2
  370. package/extensions/bluebubbles/src/monitor.test.ts +46 -46
  371. package/extensions/bluebubbles/src/monitor.ts +5 -5
  372. package/extensions/bluebubbles/src/onboarding.ts +7 -7
  373. package/extensions/bluebubbles/src/reactions.ts +2 -2
  374. package/extensions/bluebubbles/src/send.ts +2 -2
  375. package/extensions/copilot-proxy/README.md +1 -1
  376. package/extensions/copilot-proxy/package.json +1 -1
  377. package/extensions/diagnostics-otel/index.ts +2 -2
  378. package/extensions/diagnostics-otel/package.json +1 -1
  379. package/extensions/diagnostics-otel/src/service.ts +3 -3
  380. package/extensions/discord/index.ts +2 -2
  381. package/extensions/discord/package.json +1 -1
  382. package/extensions/google-antigravity-auth/README.md +1 -1
  383. package/extensions/google-antigravity-auth/index.ts +1 -1
  384. package/extensions/google-antigravity-auth/package.json +1 -1
  385. package/extensions/google-gemini-cli-auth/README.md +1 -1
  386. package/extensions/google-gemini-cli-auth/oauth.ts +1 -1
  387. package/extensions/google-gemini-cli-auth/package.json +1 -1
  388. package/extensions/googlechat/index.ts +3 -3
  389. package/extensions/googlechat/package.json +1 -1
  390. package/extensions/googlechat/src/accounts.ts +8 -8
  391. package/extensions/googlechat/src/actions.ts +6 -6
  392. package/extensions/googlechat/src/channel.ts +21 -21
  393. package/extensions/googlechat/src/monitor.ts +8 -8
  394. package/extensions/googlechat/src/onboarding.ts +10 -10
  395. package/extensions/imessage/index.ts +2 -2
  396. package/extensions/imessage/package.json +1 -1
  397. package/extensions/line/index.ts +2 -2
  398. package/extensions/line/package.json +1 -1
  399. package/extensions/line/src/card-command.ts +2 -2
  400. package/extensions/line/src/channel.logout.test.ts +4 -4
  401. package/extensions/line/src/channel.sendPayload.test.ts +8 -8
  402. package/extensions/line/src/channel.ts +3 -3
  403. package/extensions/llm-task/README.md +3 -3
  404. package/extensions/llm-task/index.ts +2 -2
  405. package/extensions/llm-task/package.json +1 -1
  406. package/extensions/llm-task/src/llm-task-tool.ts +4 -4
  407. package/extensions/lobster/README.md +6 -6
  408. package/extensions/lobster/index.ts +2 -2
  409. package/extensions/lobster/src/lobster-tool.test.ts +4 -4
  410. package/extensions/lobster/src/lobster-tool.ts +2 -2
  411. package/extensions/matrix/index.ts +2 -2
  412. package/extensions/matrix/package.json +1 -1
  413. package/extensions/matrix/src/matrix/client/config.ts +1 -1
  414. package/extensions/matrix/src/matrix/monitor/handler.ts +1 -1
  415. package/extensions/matrix/src/onboarding.ts +1 -1
  416. package/extensions/mattermost/index.ts +2 -2
  417. package/extensions/mattermost/package.json +1 -1
  418. package/extensions/mattermost/src/mattermost/accounts.ts +8 -8
  419. package/extensions/mattermost/src/mattermost/monitor-helpers.ts +5 -5
  420. package/extensions/mattermost/src/mattermost/monitor.ts +2 -2
  421. package/extensions/mattermost/src/onboarding-helpers.ts +3 -3
  422. package/extensions/mattermost/src/onboarding.ts +2 -2
  423. package/extensions/memory-core/index.ts +2 -2
  424. package/extensions/memory-core/package.json +1 -1
  425. package/extensions/memory-lancedb/index.ts +3 -3
  426. package/extensions/memory-lancedb/package.json +1 -1
  427. package/extensions/msteams/index.ts +2 -2
  428. package/extensions/msteams/package.json +1 -1
  429. package/extensions/msteams/src/channel.directory.test.ts +2 -2
  430. package/extensions/msteams/src/channel.ts +2 -2
  431. package/extensions/msteams/src/graph-upload.ts +4 -4
  432. package/extensions/msteams/src/monitor-handler.ts +2 -2
  433. package/extensions/msteams/src/monitor.ts +2 -2
  434. package/extensions/msteams/src/onboarding.ts +9 -9
  435. package/extensions/msteams/src/reply-dispatcher.ts +2 -2
  436. package/extensions/msteams/src/send-context.ts +2 -2
  437. package/extensions/msteams/src/send.ts +4 -4
  438. package/extensions/nextcloud-talk/index.ts +2 -2
  439. package/extensions/nextcloud-talk/package.json +1 -1
  440. package/extensions/nextcloud-talk/src/channel.ts +7 -7
  441. package/extensions/nextcloud-talk/src/inbound.ts +7 -7
  442. package/extensions/nextcloud-talk/src/onboarding.ts +1 -1
  443. package/extensions/nostr/README.md +2 -2
  444. package/extensions/nostr/index.ts +5 -5
  445. package/extensions/nostr/package.json +1 -1
  446. package/extensions/nostr/src/types.ts +4 -4
  447. package/extensions/open-prose/index.ts +2 -2
  448. package/extensions/qwen-portal-auth/README.md +1 -1
  449. package/extensions/signal/index.ts +2 -2
  450. package/extensions/signal/package.json +1 -1
  451. package/extensions/slack/index.ts +2 -2
  452. package/extensions/slack/package.json +1 -1
  453. package/extensions/telegram/index.ts +2 -2
  454. package/extensions/telegram/package.json +1 -1
  455. package/extensions/telegram/src/channel.ts +2 -2
  456. package/extensions/tlon/README.md +2 -2
  457. package/extensions/tlon/index.ts +2 -2
  458. package/extensions/tlon/package.json +1 -1
  459. package/extensions/tlon/src/channel.ts +13 -13
  460. package/extensions/tlon/src/monitor/index.ts +3 -3
  461. package/extensions/tlon/src/onboarding.ts +3 -3
  462. package/extensions/tlon/src/types.ts +3 -3
  463. package/extensions/twitch/README.md +1 -1
  464. package/extensions/twitch/index.ts +2 -2
  465. package/extensions/twitch/package.json +1 -1
  466. package/extensions/twitch/src/config.ts +3 -3
  467. package/extensions/twitch/src/monitor.ts +3 -3
  468. package/extensions/twitch/src/onboarding.ts +9 -9
  469. package/extensions/twitch/src/outbound.test.ts +2 -2
  470. package/extensions/twitch/src/plugin.test.ts +2 -2
  471. package/extensions/twitch/src/plugin.ts +8 -8
  472. package/extensions/twitch/src/send.test.ts +2 -2
  473. package/extensions/twitch/src/send.ts +4 -4
  474. package/extensions/twitch/src/token.test.ts +8 -8
  475. package/extensions/twitch/src/token.ts +3 -3
  476. package/extensions/twitch/src/twitch-client.ts +3 -3
  477. package/extensions/twitch/src/types.ts +3 -3
  478. package/extensions/twitch/src/utils/markdown.ts +1 -1
  479. package/extensions/voice-call/README.md +3 -3
  480. package/extensions/voice-call/package.json +1 -1
  481. package/extensions/voice-call/src/core-bridge.ts +2 -2
  482. package/extensions/voice-call/src/response-generator.ts +1 -1
  483. package/extensions/whatsapp/index.ts +2 -2
  484. package/extensions/whatsapp/package.json +1 -1
  485. package/extensions/zalo/README.md +1 -1
  486. package/extensions/zalo/index.ts +2 -2
  487. package/extensions/zalo/package.json +1 -1
  488. package/extensions/zalo/src/accounts.ts +8 -8
  489. package/extensions/zalo/src/actions.ts +4 -4
  490. package/extensions/zalo/src/channel.directory.test.ts +2 -2
  491. package/extensions/zalo/src/channel.ts +18 -18
  492. package/extensions/zalo/src/monitor.ts +9 -9
  493. package/extensions/zalo/src/monitor.webhook.test.ts +2 -2
  494. package/extensions/zalo/src/onboarding.ts +24 -24
  495. package/extensions/zalo/src/send.ts +2 -2
  496. package/extensions/zalouser/README.md +2 -2
  497. package/extensions/zalouser/index.ts +2 -2
  498. package/extensions/zalouser/package.json +1 -1
  499. package/extensions/zalouser/src/accounts.ts +9 -9
  500. package/extensions/zalouser/src/channel.ts +24 -24
  501. package/extensions/zalouser/src/monitor.ts +4 -4
  502. package/extensions/zalouser/src/onboarding.ts +28 -28
  503. package/package.json +13 -251
  504. package/skills/nano-banana-pro/scripts/generate_image.py +1 -1
  505. package/skills/tmux/scripts/find-sessions.sh +1 -1
  506. package/CHANGELOG.md +0 -102
  507. package/README-header.png +0 -0
  508. package/git-hooks/pre-commit +0 -4
  509. package/scripts/format-staged.js +0 -148
  510. package/scripts/postinstall.js +0 -300
  511. package/scripts/setup-git-hooks.js +0 -96
@@ -10,8 +10,9 @@ import { formatForLog } from "./ws-log.js";
10
10
  */
11
11
  function shouldSuppressHeartbeatBroadcast(runId) {
12
12
  const runContext = getAgentRunContext(runId);
13
- if (!runContext?.isHeartbeat)
13
+ if (!runContext?.isHeartbeat) {
14
14
  return false;
15
+ }
15
16
  try {
16
17
  const cfg = loadConfig();
17
18
  const visibility = resolveHeartbeatVisibility({ cfg, channel: "webchat" });
@@ -36,23 +37,28 @@ export function createChatRunRegistry() {
36
37
  const peek = (sessionId) => chatRunSessions.get(sessionId)?.[0];
37
38
  const shift = (sessionId) => {
38
39
  const queue = chatRunSessions.get(sessionId);
39
- if (!queue || queue.length === 0)
40
+ if (!queue || queue.length === 0) {
40
41
  return undefined;
42
+ }
41
43
  const entry = queue.shift();
42
- if (!queue.length)
44
+ if (!queue.length) {
43
45
  chatRunSessions.delete(sessionId);
46
+ }
44
47
  return entry;
45
48
  };
46
49
  const remove = (sessionId, clientRunId, sessionKey) => {
47
50
  const queue = chatRunSessions.get(sessionId);
48
- if (!queue || queue.length === 0)
51
+ if (!queue || queue.length === 0) {
49
52
  return undefined;
53
+ }
50
54
  const idx = queue.findIndex((entry) => entry.clientRunId === clientRunId && (sessionKey ? entry.sessionKey === sessionKey : true));
51
- if (idx < 0)
55
+ if (idx < 0) {
52
56
  return undefined;
57
+ }
53
58
  const [entry] = queue.splice(idx, 1);
54
- if (!queue.length)
59
+ if (!queue.length) {
55
60
  chatRunSessions.delete(sessionId);
61
+ }
56
62
  return entry;
57
63
  };
58
64
  const clear = () => {
@@ -79,13 +85,69 @@ export function createChatRunState() {
79
85
  clear,
80
86
  };
81
87
  }
82
- export function createAgentEventHandler({ broadcast, nodeSendToSession, agentRunSeq, chatRunState, resolveSessionKeyForRun, clearAgentRunContext, }) {
88
+ const TOOL_EVENT_RECIPIENT_TTL_MS = 10 * 60 * 1000;
89
+ const TOOL_EVENT_RECIPIENT_FINAL_GRACE_MS = 30 * 1000;
90
+ export function createToolEventRecipientRegistry() {
91
+ const recipients = new Map();
92
+ const prune = () => {
93
+ if (recipients.size === 0) {
94
+ return;
95
+ }
96
+ const now = Date.now();
97
+ for (const [runId, entry] of recipients) {
98
+ const cutoff = entry.finalizedAt
99
+ ? entry.finalizedAt + TOOL_EVENT_RECIPIENT_FINAL_GRACE_MS
100
+ : entry.updatedAt + TOOL_EVENT_RECIPIENT_TTL_MS;
101
+ if (now >= cutoff) {
102
+ recipients.delete(runId);
103
+ }
104
+ }
105
+ };
106
+ const add = (runId, connId) => {
107
+ if (!runId || !connId) {
108
+ return;
109
+ }
110
+ const now = Date.now();
111
+ const existing = recipients.get(runId);
112
+ if (existing) {
113
+ existing.connIds.add(connId);
114
+ existing.updatedAt = now;
115
+ }
116
+ else {
117
+ recipients.set(runId, {
118
+ connIds: new Set([connId]),
119
+ updatedAt: now,
120
+ });
121
+ }
122
+ prune();
123
+ };
124
+ const get = (runId) => {
125
+ const entry = recipients.get(runId);
126
+ if (!entry) {
127
+ return undefined;
128
+ }
129
+ entry.updatedAt = Date.now();
130
+ prune();
131
+ return entry.connIds;
132
+ };
133
+ const markFinal = (runId) => {
134
+ const entry = recipients.get(runId);
135
+ if (!entry) {
136
+ return;
137
+ }
138
+ entry.finalizedAt = Date.now();
139
+ prune();
140
+ };
141
+ return { add, get, markFinal };
142
+ }
143
+ export function createAgentEventHandler({ broadcast, broadcastToConnIds, nodeSendToSession, agentRunSeq, chatRunState, resolveSessionKeyForRun, clearAgentRunContext, toolEventRecipients, }) {
83
144
  const emitChatDelta = (sessionKey, clientRunId, seq, text) => {
84
145
  chatRunState.buffers.set(clientRunId, text);
85
146
  const now = Date.now();
86
147
  const last = chatRunState.deltaSentAt.get(clientRunId) ?? 0;
87
- if (now - last < 150)
148
+ if (now - last < 150) {
88
149
  return;
150
+ }
89
151
  chatRunState.deltaSentAt.set(clientRunId, now);
90
152
  const payload = {
91
153
  runId: clientRunId,
@@ -139,23 +201,26 @@ export function createAgentEventHandler({ broadcast, nodeSendToSession, agentRun
139
201
  broadcast("chat", payload);
140
202
  nodeSendToSession(sessionKey, "chat", payload);
141
203
  };
142
- const shouldEmitToolEvents = (runId, sessionKey) => {
204
+ const resolveToolVerboseLevel = (runId, sessionKey) => {
143
205
  const runContext = getAgentRunContext(runId);
144
206
  const runVerbose = normalizeVerboseLevel(runContext?.verboseLevel);
145
- if (runVerbose)
146
- return runVerbose === "on";
147
- if (!sessionKey)
148
- return false;
207
+ if (runVerbose) {
208
+ return runVerbose;
209
+ }
210
+ if (!sessionKey) {
211
+ return "off";
212
+ }
149
213
  try {
150
214
  const { cfg, entry } = loadSessionEntry(sessionKey);
151
215
  const sessionVerbose = normalizeVerboseLevel(entry?.verboseLevel);
152
- if (sessionVerbose)
153
- return sessionVerbose === "on";
216
+ if (sessionVerbose) {
217
+ return sessionVerbose;
218
+ }
154
219
  const defaultVerbose = normalizeVerboseLevel(cfg.agents?.defaults?.verboseDefault);
155
- return defaultVerbose === "on";
220
+ return defaultVerbose ?? "off";
156
221
  }
157
222
  catch {
158
- return false;
223
+ return "off";
159
224
  }
160
225
  };
161
226
  return (evt) => {
@@ -166,10 +231,17 @@ export function createAgentEventHandler({ broadcast, nodeSendToSession, agentRun
166
231
  // Include sessionKey so Control UI can filter tool streams per session.
167
232
  const agentPayload = sessionKey ? { ...evt, sessionKey } : evt;
168
233
  const last = agentRunSeq.get(evt.runId) ?? 0;
169
- if (evt.stream === "tool" && !shouldEmitToolEvents(evt.runId, sessionKey)) {
170
- agentRunSeq.set(evt.runId, evt.seq);
171
- return;
172
- }
234
+ const isToolEvent = evt.stream === "tool";
235
+ const toolVerbose = isToolEvent ? resolveToolVerboseLevel(evt.runId, sessionKey) : "off";
236
+ // Build tool payload: strip result/partialResult unless verbose=full
237
+ const toolPayload = isToolEvent && toolVerbose !== "full"
238
+ ? (() => {
239
+ const data = evt.data ? { ...evt.data } : {};
240
+ delete data.result;
241
+ delete data.partialResult;
242
+ return sessionKey ? { ...evt, sessionKey, data } : { ...evt, data };
243
+ })()
244
+ : agentPayload;
173
245
  if (evt.seq !== last + 1) {
174
246
  broadcast("agent", {
175
247
  runId: evt.runId,
@@ -184,10 +256,26 @@ export function createAgentEventHandler({ broadcast, nodeSendToSession, agentRun
184
256
  });
185
257
  }
186
258
  agentRunSeq.set(evt.runId, evt.seq);
187
- broadcast("agent", agentPayload);
259
+ if (isToolEvent) {
260
+ // Always broadcast tool events to registered WS recipients with
261
+ // tool-events capability, regardless of verboseLevel. The verbose
262
+ // setting only controls whether tool details are sent as channel
263
+ // messages to messaging surfaces (Telegram, Discord, etc.).
264
+ const recipients = toolEventRecipients.get(evt.runId);
265
+ if (recipients && recipients.size > 0) {
266
+ broadcastToConnIds("agent", toolPayload, recipients);
267
+ }
268
+ }
269
+ else {
270
+ broadcast("agent", agentPayload);
271
+ }
188
272
  const lifecyclePhase = evt.stream === "lifecycle" && typeof evt.data?.phase === "string" ? evt.data.phase : null;
189
273
  if (sessionKey) {
190
- nodeSendToSession(sessionKey, "agent", agentPayload);
274
+ // Send tool events to node/channel subscribers only when verbose is enabled;
275
+ // WS clients already received the event above via broadcastToConnIds.
276
+ if (!isToolEvent || toolVerbose !== "off") {
277
+ nodeSendToSession(sessionKey, "agent", isToolEvent ? toolPayload : agentPayload);
278
+ }
191
279
  if (!isAborted && evt.stream === "assistant" && typeof evt.data?.text === "string") {
192
280
  emitChatDelta(sessionKey, clientRunId, evt.seq, evt.data.text);
193
281
  }
@@ -215,6 +303,7 @@ export function createAgentEventHandler({ broadcast, nodeSendToSession, agentRun
215
303
  }
216
304
  }
217
305
  if (lifecyclePhase === "end" || lifecyclePhase === "error") {
306
+ toolEventRecipients.markFinal(evt.runId);
218
307
  clearAgentRunContext(evt.runId);
219
308
  }
220
309
  };
@@ -1,6 +1,6 @@
1
1
  import { startGatewayBonjourAdvertiser } from "../infra/bonjour.js";
2
2
  import { pickPrimaryTailnetIPv4, pickPrimaryTailnetIPv6 } from "../infra/tailnet.js";
3
- import { WIDE_AREA_DISCOVERY_DOMAIN, writeWideAreaGatewayZone } from "../infra/widearea-dns.js";
3
+ import { resolveWideAreaDiscoveryDomain, writeWideAreaGatewayZone } from "../infra/widearea-dns.js";
4
4
  import { formatBonjourInstanceName, resolveBonjourCliPath, resolveTailnetDnsHint, } from "./server-discovery.js";
5
5
  export async function startGatewayDiscovery(params) {
6
6
  let bonjourStop = null;
@@ -40,6 +40,13 @@ export async function startGatewayDiscovery(params) {
40
40
  }
41
41
  }
42
42
  if (params.wideAreaDiscoveryEnabled) {
43
+ const wideAreaDomain = resolveWideAreaDiscoveryDomain({
44
+ configDomain: params.wideAreaDiscoveryDomain ?? undefined,
45
+ });
46
+ if (!wideAreaDomain) {
47
+ params.logDiscovery.warn("discovery.wideArea.enabled is true, but no domain was configured; set discovery.wideArea.domain to enable unicast DNS-SD");
48
+ return { bonjourStop };
49
+ }
43
50
  const tailnetIPv4 = pickPrimaryTailnetIPv4();
44
51
  if (!tailnetIPv4) {
45
52
  params.logDiscovery.warn("discovery.wideArea.enabled is true, but no Tailscale IPv4 address was found; skipping unicast DNS-SD zone update");
@@ -48,6 +55,7 @@ export async function startGatewayDiscovery(params) {
48
55
  try {
49
56
  const tailnetIPv6 = pickPrimaryTailnetIPv6();
50
57
  const result = await writeWideAreaGatewayZone({
58
+ domain: wideAreaDomain,
51
59
  gatewayPort: params.port,
52
60
  displayName: formatBonjourInstanceName(params.machineDisplayName),
53
61
  tailnetIPv4,
@@ -58,7 +66,7 @@ export async function startGatewayDiscovery(params) {
58
66
  sshPort,
59
67
  cliPath: resolveBonjourCliPath(),
60
68
  });
61
- params.logDiscovery.info(`wide-area DNS-SD ${result.changed ? "updated" : "unchanged"} (${WIDE_AREA_DISCOVERY_DOMAIN} → ${result.zonePath})`);
69
+ params.logDiscovery.info(`wide-area DNS-SD ${result.changed ? "updated" : "unchanged"} (${wideAreaDomain} → ${result.zonePath})`);
62
70
  }
63
71
  catch (err) {
64
72
  params.logDiscovery.warn(`wide-area discovery update failed: ${String(err)}`);
@@ -5,10 +5,10 @@ import { runExec } from "../process/exec.js";
5
5
  export function formatBonjourInstanceName(displayName) {
6
6
  const trimmed = displayName.trim();
7
7
  if (!trimmed)
8
- return "Moltbot";
8
+ return "Poolbot";
9
9
  if (/poolbot/i.test(trimmed))
10
10
  return trimmed;
11
- return `${trimmed} (Moltbot)`;
11
+ return `${trimmed} (Poolbot)`;
12
12
  }
13
13
  export function resolveBonjourCliPath(opts = {}) {
14
14
  const env = opts.env ?? process.env;
@@ -1,12 +1,16 @@
1
1
  import { createServer as createHttpServer, } from "node:http";
2
2
  import { createServer as createHttpsServer } from "node:https";
3
- import { handleA2uiHttpRequest } from "../canvas-host/a2ui.js";
3
+ import { A2UI_PATH, CANVAS_HOST_PATH, CANVAS_WS_PATH, handleA2uiHttpRequest, } from "../canvas-host/a2ui.js";
4
4
  import { loadConfig } from "../config/config.js";
5
- import { handleSlackHttpRequest } from "../slack/http/index.js";
6
5
  import { resolveAgentAvatar } from "../agents/identity-avatar.js";
7
- import { handleControlUiAvatarRequest, handleControlUiHttpRequest } from "./control-ui.js";
8
- import { extractHookToken, getHookChannelError, normalizeAgentPayload, normalizeHookHeaders, normalizeWakePayload, readJsonBody, resolveHookChannel, resolveHookDeliver, } from "./hooks.js";
6
+ import { handleSlackHttpRequest } from "../slack/http/index.js";
7
+ import { authorizeGatewayConnect, isLocalDirectRequest } from "./auth.js";
8
+ import { handleControlUiAvatarRequest, handleControlUiHttpRequest, } from "./control-ui.js";
9
+ import { extractHookToken, getHookAgentPolicyError, getHookChannelError, isHookAgentAllowed, normalizeAgentPayload, normalizeHookHeaders, normalizeWakePayload, readJsonBody, resolveHookTargetAgentId, resolveHookChannel, resolveHookDeliver, } from "./hooks.js";
9
10
  import { applyHookMappings } from "./hooks-mapping.js";
11
+ import { sendUnauthorized } from "./http-common.js";
12
+ import { getBearerToken, getHeader } from "./http-utils.js";
13
+ import { resolveGatewayClientIp } from "./net.js";
10
14
  import { handleOpenAiHttpRequest } from "./openai-http.js";
11
15
  import { handleOpenResponsesHttpRequest } from "./openresponses-http.js";
12
16
  import { handleToolsInvokeHttpRequest } from "./tools-invoke-http.js";
@@ -15,6 +19,49 @@ function sendJson(res, status, body) {
15
19
  res.setHeader("Content-Type", "application/json; charset=utf-8");
16
20
  res.end(JSON.stringify(body));
17
21
  }
22
+ function isCanvasPath(pathname) {
23
+ return (pathname === A2UI_PATH ||
24
+ pathname.startsWith(`${A2UI_PATH}/`) ||
25
+ pathname === CANVAS_HOST_PATH ||
26
+ pathname.startsWith(`${CANVAS_HOST_PATH}/`) ||
27
+ pathname === CANVAS_WS_PATH);
28
+ }
29
+ function hasAuthorizedWsClientForIp(clients, clientIp) {
30
+ for (const client of clients) {
31
+ if (client.clientIp && client.clientIp === clientIp) {
32
+ return true;
33
+ }
34
+ }
35
+ return false;
36
+ }
37
+ async function authorizeCanvasRequest(params) {
38
+ const { req, auth, trustedProxies, clients } = params;
39
+ if (isLocalDirectRequest(req, trustedProxies)) {
40
+ return true;
41
+ }
42
+ const token = getBearerToken(req);
43
+ if (token) {
44
+ const authResult = await authorizeGatewayConnect({
45
+ auth: { ...auth, allowTailscale: false },
46
+ connectAuth: { token, password: token },
47
+ req,
48
+ trustedProxies,
49
+ });
50
+ if (authResult.ok) {
51
+ return true;
52
+ }
53
+ }
54
+ const clientIp = resolveGatewayClientIp({
55
+ remoteAddr: req.socket?.remoteAddress ?? "",
56
+ forwardedFor: getHeader(req, "x-forwarded-for"),
57
+ realIp: getHeader(req, "x-real-ip"),
58
+ trustedProxies,
59
+ });
60
+ if (!clientIp) {
61
+ return false;
62
+ }
63
+ return hasAuthorizedWsClientForIp(clients, clientIp);
64
+ }
18
65
  export function createHooksRequestHandler(opts) {
19
66
  const { getHooksConfig, bindHost, port, logHooks, dispatchAgentHook, dispatchWakeHook } = opts;
20
67
  return async (req, res) => {
@@ -26,6 +73,8 @@ export function createHooksRequestHandler(opts) {
26
73
  if (url.pathname !== basePath && !url.pathname.startsWith(`${basePath}/`)) {
27
74
  return false;
28
75
  }
76
+ // pool-bot keeps the deprecation-warning approach for query-param tokens
77
+ // (upstream hard-rejects; we warn and allow for now)
29
78
  const { token, fromQuery } = extractHookToken(req, url);
30
79
  if (!token || token !== hooksConfig.token) {
31
80
  res.statusCode = 401;
@@ -36,7 +85,7 @@ export function createHooksRequestHandler(opts) {
36
85
  if (fromQuery) {
37
86
  logHooks.warn("Hook token provided via query parameter is deprecated for security reasons. " +
38
87
  "Tokens in URLs appear in logs, browser history, and referrer headers. " +
39
- "Use Authorization: Bearer <token> or X-Moltbot-Token header instead.");
88
+ "Use Authorization: Bearer <token> or X-Poolbot-Token header instead.");
40
89
  }
41
90
  if (req.method !== "POST") {
42
91
  res.statusCode = 405;
@@ -76,7 +125,14 @@ export function createHooksRequestHandler(opts) {
76
125
  sendJson(res, 400, { ok: false, error: normalized.error });
77
126
  return true;
78
127
  }
79
- const runId = dispatchAgentHook(normalized.value);
128
+ if (!isHookAgentAllowed(hooksConfig, normalized.value.agentId)) {
129
+ sendJson(res, 400, { ok: false, error: getHookAgentPolicyError() });
130
+ return true;
131
+ }
132
+ const runId = dispatchAgentHook({
133
+ ...normalized.value,
134
+ agentId: resolveHookTargetAgentId(hooksConfig, normalized.value.agentId),
135
+ });
80
136
  sendJson(res, 202, { ok: true, runId });
81
137
  return true;
82
138
  }
@@ -111,9 +167,14 @@ export function createHooksRequestHandler(opts) {
111
167
  sendJson(res, 400, { ok: false, error: getHookChannelError() });
112
168
  return true;
113
169
  }
170
+ if (!isHookAgentAllowed(hooksConfig, mapped.action.agentId)) {
171
+ sendJson(res, 400, { ok: false, error: getHookAgentPolicyError() });
172
+ return true;
173
+ }
114
174
  const runId = dispatchAgentHook({
115
175
  message: mapped.action.message,
116
176
  name: mapped.action.name ?? "Hook",
177
+ agentId: resolveHookTargetAgentId(hooksConfig, mapped.action.agentId),
117
178
  wakeMode: mapped.action.wakeMode,
118
179
  sessionKey: mapped.action.sessionKey ?? "",
119
180
  deliver: resolveHookDeliver(mapped.action.deliver),
@@ -141,7 +202,7 @@ export function createHooksRequestHandler(opts) {
141
202
  };
142
203
  }
143
204
  export function createGatewayHttpServer(opts) {
144
- const { canvasHost, controlUiEnabled, controlUiBasePath, openAiChatCompletionsEnabled, openResponsesEnabled, openResponsesConfig, handleHooksRequest, handlePluginRequest, resolvedAuth, } = opts;
205
+ const { canvasHost, clients, controlUiEnabled, controlUiBasePath, controlUiRoot, openAiChatCompletionsEnabled, openResponsesEnabled, openResponsesConfig, handleHooksRequest, handlePluginRequest, resolvedAuth, } = opts;
145
206
  const httpServer = opts.tlsOptions
146
207
  ? createHttpsServer(opts.tlsOptions, (req, res) => {
147
208
  void handleRequest(req, res);
@@ -183,6 +244,19 @@ export function createGatewayHttpServer(opts) {
183
244
  return;
184
245
  }
185
246
  if (canvasHost) {
247
+ const url = new URL(req.url ?? "/", "http://localhost");
248
+ if (isCanvasPath(url.pathname)) {
249
+ const ok = await authorizeCanvasRequest({
250
+ req,
251
+ auth: resolvedAuth,
252
+ trustedProxies,
253
+ clients,
254
+ });
255
+ if (!ok) {
256
+ sendUnauthorized(res);
257
+ return;
258
+ }
259
+ }
186
260
  if (await handleA2uiHttpRequest(req, res))
187
261
  return;
188
262
  if (await canvasHost.handleHttpRequest(req, res))
@@ -197,6 +271,7 @@ export function createGatewayHttpServer(opts) {
197
271
  if (handleControlUiHttpRequest(req, res, {
198
272
  basePath: controlUiBasePath,
199
273
  config: configSnapshot,
274
+ root: controlUiRoot,
200
275
  }))
201
276
  return;
202
277
  }
@@ -213,12 +288,35 @@ export function createGatewayHttpServer(opts) {
213
288
  return httpServer;
214
289
  }
215
290
  export function attachGatewayUpgradeHandler(opts) {
216
- const { httpServer, wss, canvasHost } = opts;
291
+ const { httpServer, wss, canvasHost, clients, resolvedAuth } = opts;
217
292
  httpServer.on("upgrade", (req, socket, head) => {
218
- if (canvasHost?.handleUpgrade(req, socket, head))
219
- return;
220
- wss.handleUpgrade(req, socket, head, (ws) => {
221
- wss.emit("connection", ws, req);
293
+ void (async () => {
294
+ if (canvasHost) {
295
+ const url = new URL(req.url ?? "/", "http://localhost");
296
+ if (url.pathname === CANVAS_WS_PATH) {
297
+ const configSnapshot = loadConfig();
298
+ const trustedProxies = configSnapshot.gateway?.trustedProxies ?? [];
299
+ const ok = await authorizeCanvasRequest({
300
+ req,
301
+ auth: resolvedAuth,
302
+ trustedProxies,
303
+ clients,
304
+ });
305
+ if (!ok) {
306
+ socket.write("HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n");
307
+ socket.destroy();
308
+ return;
309
+ }
310
+ }
311
+ if (canvasHost.handleUpgrade(req, socket, head)) {
312
+ return;
313
+ }
314
+ }
315
+ wss.handleUpgrade(req, socket, head, (ws) => {
316
+ wss.emit("connection", ws, req);
317
+ });
318
+ })().catch(() => {
319
+ socket.destroy();
222
320
  });
223
321
  });
224
322
  }
@@ -0,0 +1,60 @@
1
+ import { resolveUserTimezone } from "../../agents/date-time.js";
2
+ import { formatZonedTimestamp } from "../../infra/format-time/format-datetime.js";
3
+ /**
4
+ * Cron jobs inject "Current time: ..." into their messages.
5
+ * Skip injection for those.
6
+ */
7
+ const CRON_TIME_PATTERN = /Current time: /;
8
+ /**
9
+ * Matches a leading `[... YYYY-MM-DD HH:MM ...]` envelope -- either from
10
+ * channel plugins or from a previous injection. Uses the same YYYY-MM-DD
11
+ * HH:MM format as {@link formatZonedTimestamp}, so detection stays in sync
12
+ * with the formatting.
13
+ */
14
+ const TIMESTAMP_ENVELOPE_PATTERN = /^\[.*\d{4}-\d{2}-\d{2} \d{2}:\d{2}/;
15
+ /**
16
+ * Injects a compact timestamp prefix into a message if one isn't already
17
+ * present. Uses the same `YYYY-MM-DD HH:MM TZ` format as channel envelope
18
+ * timestamps ({@link formatZonedTimestamp}), keeping token cost low (~7
19
+ * tokens) and format consistent across all agent contexts.
20
+ *
21
+ * Used by the gateway `agent` and `chat.send` handlers to give TUI, web,
22
+ * spawned subagents, `sessions_send`, and heartbeat wake events date/time
23
+ * awareness -- without modifying the system prompt (which is cached).
24
+ *
25
+ * Channel messages (Discord, Telegram, etc.) already have timestamps via
26
+ * envelope formatting and take a separate code path -- they never reach
27
+ * these handlers, so there is no double-stamping risk. The detection
28
+ * pattern is a safety net for edge cases.
29
+ */
30
+ export function injectTimestamp(message, opts) {
31
+ if (!message.trim()) {
32
+ return message;
33
+ }
34
+ // Already has an envelope or injected timestamp
35
+ if (TIMESTAMP_ENVELOPE_PATTERN.test(message)) {
36
+ return message;
37
+ }
38
+ // Already has a cron-injected timestamp
39
+ if (CRON_TIME_PATTERN.test(message)) {
40
+ return message;
41
+ }
42
+ const now = opts?.now ?? new Date();
43
+ const timezone = opts?.timezone ?? "UTC";
44
+ const formatted = formatZonedTimestamp(now, { timeZone: timezone });
45
+ if (!formatted) {
46
+ return message;
47
+ }
48
+ // 3-letter DOW: small models (8B) can't reliably derive day-of-week from
49
+ // a date, and may treat a bare "Wed" as a typo. Costs ~1 token.
50
+ const dow = new Intl.DateTimeFormat("en-US", { timeZone: timezone, weekday: "short" }).format(now);
51
+ return `[${dow} ${formatted}] ${message}`;
52
+ }
53
+ /**
54
+ * Build TimestampInjectionOptions from a PoolBotConfig.
55
+ */
56
+ export function timestampOptsFromConfig(cfg) {
57
+ return {
58
+ timezone: resolveUserTimezone(cfg.agents?.defaults?.userTimezone),
59
+ };
60
+ }