@poolzin/pool-bot 2026.2.24 → 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 (646) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/acp/client.js +207 -18
  3. package/dist/acp/event-mapper.js +87 -22
  4. package/dist/acp/meta.js +12 -6
  5. package/dist/acp/secret-file.js +22 -0
  6. package/dist/agents/agent-paths.js +8 -9
  7. package/dist/agents/agent-scope.js +17 -5
  8. package/dist/agents/auth-profiles/oauth.js +148 -64
  9. package/dist/agents/auth-profiles/session-override.js +13 -7
  10. package/dist/agents/bash-process-registry.test-helpers.js +29 -0
  11. package/dist/agents/bash-tools.exec-approval-request.js +20 -0
  12. package/dist/agents/bash-tools.exec-host-gateway.js +240 -0
  13. package/dist/agents/bash-tools.exec-host-node.js +235 -0
  14. package/dist/agents/bash-tools.exec-runtime.js +2 -25
  15. package/dist/agents/bash-tools.exec-types.js +1 -0
  16. package/dist/agents/bash-tools.process.js +224 -218
  17. package/dist/agents/bedrock-discovery.js +3 -1
  18. package/dist/agents/byteplus-models.js +97 -0
  19. package/dist/agents/chutes-oauth.js +1 -0
  20. package/dist/agents/cli-runner/helpers.js +4 -0
  21. package/dist/agents/compaction.js +41 -14
  22. package/dist/agents/content-blocks.js +16 -0
  23. package/dist/agents/doubao-models.js +121 -0
  24. package/dist/agents/failover-error.js +2 -0
  25. package/dist/agents/huggingface-models.js +5 -3
  26. package/dist/agents/live-model-filter.js +5 -0
  27. package/dist/agents/minimax-vlm.js +10 -8
  28. package/dist/agents/model-auth.js +6 -0
  29. package/dist/agents/model-catalog.js +3 -1
  30. package/dist/agents/model-fallback.js +96 -101
  31. package/dist/agents/model-selection.js +7 -1
  32. package/dist/agents/models-config.providers.js +364 -165
  33. package/dist/agents/ollama-stream.js +117 -4
  34. package/dist/agents/opencode-zen-models.js +22 -11
  35. package/dist/agents/pi-embedded-helpers/errors.js +55 -33
  36. package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
  37. package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
  38. package/dist/agents/pi-embedded-helpers.js +1 -1
  39. package/dist/agents/pi-embedded-payloads.js +1 -0
  40. package/dist/agents/pi-embedded-runner/compact.js +29 -7
  41. package/dist/agents/pi-embedded-runner/extensions.js +28 -26
  42. package/dist/agents/pi-embedded-runner/google.js +20 -8
  43. package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
  44. package/dist/agents/pi-embedded-runner/run.js +71 -12
  45. package/dist/agents/pi-embedded-runner/run.overflow-compaction.fixture.js +34 -0
  46. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
  47. package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
  48. package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
  49. package/dist/agents/pi-embedded-runner/thinking.js +42 -0
  50. package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
  51. package/dist/agents/pi-embedded-runner/utils.js +7 -10
  52. package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
  53. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
  54. package/dist/agents/pi-embedded-subscribe.js +9 -4
  55. package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
  56. package/dist/agents/pi-embedded-utils.js +3 -0
  57. package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
  58. package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
  59. package/dist/agents/pi-settings.js +40 -0
  60. package/dist/agents/pi-tools.policy.js +2 -1
  61. package/dist/agents/provider/config-loader.js +1 -1
  62. package/dist/agents/sandbox/browser.js +170 -33
  63. package/dist/agents/sandbox/config-hash.js +14 -27
  64. package/dist/agents/sandbox/config.js +21 -2
  65. package/dist/agents/sandbox/constants.js +2 -0
  66. package/dist/agents/sandbox/docker.js +16 -2
  67. package/dist/agents/sandbox/novnc-auth.js +62 -0
  68. package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
  69. package/dist/agents/sandbox/shared.js +10 -6
  70. package/dist/agents/sandbox-paths.js +24 -11
  71. package/dist/agents/schema/clean-for-gemini.js +132 -85
  72. package/dist/agents/session-slug.js +10 -5
  73. package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
  74. package/dist/agents/session-tool-result-guard.js +3 -1
  75. package/dist/agents/session-transcript-repair.js +40 -6
  76. package/dist/agents/skills/bundled-dir.js +19 -5
  77. package/dist/agents/skills/env-overrides.js +124 -43
  78. package/dist/agents/skills/frontmatter.js +6 -6
  79. package/dist/agents/skills/plugin-skills.js +14 -7
  80. package/dist/agents/skills/workspace.js +1 -0
  81. package/dist/agents/skills.test-helpers.js +13 -0
  82. package/dist/agents/stable-stringify.js +12 -0
  83. package/dist/agents/subagent-announce.js +251 -49
  84. package/dist/agents/subagent-lifecycle-events.js +19 -0
  85. package/dist/agents/subagent-registry-cleanup.js +31 -0
  86. package/dist/agents/subagent-registry-completion.js +68 -0
  87. package/dist/agents/subagent-registry-queries.js +117 -0
  88. package/dist/agents/subagent-registry-state.js +46 -0
  89. package/dist/agents/subagent-registry.js +252 -221
  90. package/dist/agents/subagent-registry.mocks.shared.js +12 -0
  91. package/dist/agents/subagent-registry.store.js +1 -0
  92. package/dist/agents/subagent-registry.types.js +1 -0
  93. package/dist/agents/subagent-spawn.js +195 -7
  94. package/dist/agents/system-prompt.js +22 -6
  95. package/dist/agents/test-helpers/assistant-message-fixtures.js +29 -0
  96. package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
  97. package/dist/agents/test-helpers/fast-core-tools.js +1 -17
  98. package/dist/agents/test-helpers/pi-tools-sandbox-context.js +27 -0
  99. package/dist/agents/timeout.js +18 -6
  100. package/dist/agents/tool-call-id.js +1 -1
  101. package/dist/agents/tool-display-common.js +162 -29
  102. package/dist/agents/tool-images.js +82 -9
  103. package/dist/agents/tool-policy-shared.js +108 -0
  104. package/dist/agents/tool-policy.js +51 -26
  105. package/dist/agents/tools/browser-tool.js +160 -54
  106. package/dist/agents/tools/canvas-tool.js +27 -1
  107. package/dist/agents/tools/common.js +45 -0
  108. package/dist/agents/tools/cron-tool.test-helpers.js +12 -0
  109. package/dist/agents/tools/discord-actions-guild.js +4 -1
  110. package/dist/agents/tools/discord-actions-moderation-shared.js +27 -0
  111. package/dist/agents/tools/gateway-tool.js +3 -1
  112. package/dist/agents/tools/image-tool.js +214 -99
  113. package/dist/agents/tools/nodes-utils.js +1 -10
  114. package/dist/agents/tools/sessions-history-tool.js +140 -108
  115. package/dist/agents/tools/sessions-send-helpers.js +12 -6
  116. package/dist/agents/tools/sessions-spawn-tool.js +8 -2
  117. package/dist/agents/tools/subagents-tool.js +2 -1
  118. package/dist/agents/tools/whatsapp-actions.js +10 -2
  119. package/dist/agents/tools/whatsapp-target-auth.js +18 -0
  120. package/dist/agents/transcript-policy.js +22 -8
  121. package/dist/agents/venice-models.js +11 -3
  122. package/dist/agents/workspace.js +222 -46
  123. package/dist/auto-reply/commands-registry.data.js +51 -0
  124. package/dist/auto-reply/commands-registry.js +19 -21
  125. package/dist/auto-reply/fallback-state.js +114 -0
  126. package/dist/auto-reply/group-activation.js +10 -5
  127. package/dist/auto-reply/inbound-debounce.js +10 -5
  128. package/dist/auto-reply/model-runtime.js +68 -0
  129. package/dist/auto-reply/reply/abort.js +1 -1
  130. package/dist/auto-reply/reply/agent-runner-execution.js +40 -5
  131. package/dist/auto-reply/reply/agent-runner.js +165 -39
  132. package/dist/auto-reply/reply/bash-command.js +41 -39
  133. package/dist/auto-reply/reply/command-gates.js +25 -0
  134. package/dist/auto-reply/reply/commands-allowlist.js +111 -72
  135. package/dist/auto-reply/reply/commands-bash.js +6 -5
  136. package/dist/auto-reply/reply/commands-config.js +30 -28
  137. package/dist/auto-reply/reply/commands-core.js +2 -1
  138. package/dist/auto-reply/reply/commands-info.js +1 -0
  139. package/dist/auto-reply/reply/commands-models.js +65 -14
  140. package/dist/auto-reply/reply/commands-session.js +237 -82
  141. package/dist/auto-reply/reply/commands-setunset-standard.js +13 -0
  142. package/dist/auto-reply/reply/commands-setunset.js +45 -0
  143. package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
  144. package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
  145. package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
  146. package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
  147. package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
  148. package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
  149. package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
  150. package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
  151. package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
  152. package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
  153. package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
  154. package/dist/auto-reply/reply/commands-subagents.js +51 -587
  155. package/dist/auto-reply/reply/commands-tts.js +10 -5
  156. package/dist/auto-reply/reply/config-value.js +10 -5
  157. package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
  158. package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
  159. package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
  160. package/dist/auto-reply/reply/followup-runner.js +1 -0
  161. package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
  162. package/dist/auto-reply/reply/get-reply-directives.js +17 -28
  163. package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
  164. package/dist/auto-reply/reply/get-reply.js +71 -12
  165. package/dist/auto-reply/reply/model-selection.js +80 -39
  166. package/dist/auto-reply/reply/queue/enqueue.js +10 -5
  167. package/dist/auto-reply/reply/queue/state.js +13 -12
  168. package/dist/auto-reply/reply/reply-payloads.js +67 -36
  169. package/dist/auto-reply/reply/reply-reference.js +9 -8
  170. package/dist/auto-reply/reply/route-reply.js +15 -8
  171. package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
  172. package/dist/auto-reply/reply/session.js +22 -6
  173. package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
  174. package/dist/auto-reply/reply/subagents-utils.js +56 -30
  175. package/dist/auto-reply/reply/typing.js +46 -21
  176. package/dist/auto-reply/send-policy.js +14 -7
  177. package/dist/auto-reply/status.js +140 -16
  178. package/dist/auto-reply/templating.js +10 -5
  179. package/dist/auto-reply/thinking.js +7 -16
  180. package/dist/auto-reply/tokens.js +21 -5
  181. package/dist/browser/bridge-server.js +36 -20
  182. package/dist/browser/cdp.helpers.js +7 -14
  183. package/dist/browser/cdp.js +35 -15
  184. package/dist/browser/chrome.profile-decoration.js +7 -4
  185. package/dist/browser/config.js +30 -0
  186. package/dist/browser/extension-relay-auth.js +55 -0
  187. package/dist/browser/extension-relay.js +74 -29
  188. package/dist/browser/navigation-guard.js +39 -0
  189. package/dist/browser/paths.js +77 -0
  190. package/dist/browser/profiles.js +13 -8
  191. package/dist/browser/pw-ai-module.js +10 -5
  192. package/dist/browser/pw-session.js +76 -39
  193. package/dist/browser/pw-tools-core.interactions.js +14 -7
  194. package/dist/browser/pw-tools-core.state.js +12 -6
  195. package/dist/browser/routes/agent.act.js +431 -424
  196. package/dist/browser/routes/agent.shared.js +47 -3
  197. package/dist/browser/routes/agent.snapshot.js +122 -116
  198. package/dist/browser/routes/agent.storage.js +303 -297
  199. package/dist/browser/routes/tabs.js +154 -100
  200. package/dist/browser/server-context.js +7 -0
  201. package/dist/browser/server-lifecycle.js +37 -0
  202. package/dist/build-info.json +3 -3
  203. package/dist/channels/allow-from.js +26 -0
  204. package/dist/channels/allowlists/resolve-utils.js +43 -19
  205. package/dist/channels/channel-config.js +14 -7
  206. package/dist/channels/draft-stream-loop.js +7 -0
  207. package/dist/channels/model-overrides.js +82 -0
  208. package/dist/channels/plugins/account-action-gate.js +13 -0
  209. package/dist/channels/plugins/message-actions.js +10 -0
  210. package/dist/channels/plugins/normalize/imessage.js +14 -7
  211. package/dist/channels/plugins/normalize/slack.js +10 -5
  212. package/dist/channels/plugins/normalize/telegram.js +14 -7
  213. package/dist/channels/plugins/outbound/discord.js +80 -8
  214. package/dist/channels/plugins/outbound/signal.js +11 -11
  215. package/dist/channels/plugins/setup-helpers.js +10 -5
  216. package/dist/channels/sender-label.js +14 -7
  217. package/dist/channels/session.js +4 -2
  218. package/dist/channels/status-reactions.js +297 -0
  219. package/dist/channels/telegram/api.js +18 -0
  220. package/dist/cli/argv.js +84 -21
  221. package/dist/cli/banner.js +3 -2
  222. package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
  223. package/dist/cli/cli-name.js +11 -11
  224. package/dist/cli/cli-utils.js +13 -3
  225. package/dist/cli/command-format.js +1 -1
  226. package/dist/cli/config-cli.js +1 -1
  227. package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
  228. package/dist/cli/daemon-cli/lifecycle.js +64 -2
  229. package/dist/cli/daemon-cli/restart-health.js +126 -0
  230. package/dist/cli/daemon-cli/status.gather.js +9 -13
  231. package/dist/cli/daemon-cli/status.print.js +2 -10
  232. package/dist/cli/deps.js +27 -22
  233. package/dist/cli/exec-approvals-cli.js +92 -124
  234. package/dist/cli/gateway-cli/run-loop.js +23 -5
  235. package/dist/cli/memory-cli.js +158 -61
  236. package/dist/cli/node-cli/register.js +14 -5
  237. package/dist/cli/nodes-cli/register.push.js +63 -0
  238. package/dist/cli/nodes-media-utils.js +26 -0
  239. package/dist/cli/outbound-send-deps.js +2 -9
  240. package/dist/cli/outbound-send-mapping.js +11 -0
  241. package/dist/cli/pairing-cli.js +40 -14
  242. package/dist/cli/plugins-cli.js +250 -73
  243. package/dist/cli/ports.js +11 -10
  244. package/dist/cli/program/build-program.js +3 -1
  245. package/dist/cli/program/command-registry.js +214 -136
  246. package/dist/cli/program/command-tree.js +16 -0
  247. package/dist/cli/program/help.js +43 -12
  248. package/dist/cli/program/preaction.js +13 -9
  249. package/dist/cli/program/register.configure.js +3 -18
  250. package/dist/cli/program/register.maintenance.js +2 -2
  251. package/dist/cli/program/register.onboard.js +2 -0
  252. package/dist/cli/program/register.status-health-sessions.js +16 -17
  253. package/dist/cli/program/register.subclis.js +93 -52
  254. package/dist/cli/route.js +12 -8
  255. package/dist/cli/system-cli.js +36 -46
  256. package/dist/cli/test-runtime-capture.js +24 -0
  257. package/dist/cli/update-cli/shared.js +22 -9
  258. package/dist/cli/update-cli/update-command.js +89 -14
  259. package/dist/cli/update-cli/wizard.js +6 -12
  260. package/dist/commands/agent/run-context.js +18 -5
  261. package/dist/commands/agent/session-store.js +17 -4
  262. package/dist/commands/agent.js +185 -89
  263. package/dist/commands/agents.bindings.js +14 -7
  264. package/dist/commands/agents.commands.add.js +13 -9
  265. package/dist/commands/agents.commands.identity.js +12 -6
  266. package/dist/commands/agents.commands.list.js +11 -6
  267. package/dist/commands/agents.config.js +8 -10
  268. package/dist/commands/agents.providers.js +12 -6
  269. package/dist/commands/auth-choice-options.js +103 -75
  270. package/dist/commands/auth-choice.apply.byteplus.js +55 -0
  271. package/dist/commands/auth-choice.apply.js +4 -0
  272. package/dist/commands/auth-choice.apply.minimax.js +61 -13
  273. package/dist/commands/auth-choice.apply.openai.js +3 -1
  274. package/dist/commands/auth-choice.apply.volcengine.js +55 -0
  275. package/dist/commands/auth-choice.preferred-provider.js +2 -0
  276. package/dist/commands/channels/remove.js +13 -6
  277. package/dist/commands/channels/shared.js +4 -14
  278. package/dist/commands/channels.mock-harness.js +23 -0
  279. package/dist/commands/configure.commands.js +14 -0
  280. package/dist/commands/configure.gateway.js +2 -4
  281. package/dist/commands/configure.js +1 -1
  282. package/dist/commands/configure.shared.js +11 -0
  283. package/dist/commands/daemon-install-helpers.js +2 -2
  284. package/dist/commands/daemon-install-runtime-warning.js +11 -0
  285. package/dist/commands/dashboard.js +12 -10
  286. package/dist/commands/docs.js +14 -8
  287. package/dist/commands/doctor-config-flow.js +11 -9
  288. package/dist/commands/doctor-legacy-config.js +281 -0
  289. package/dist/commands/doctor-state-integrity.js +99 -23
  290. package/dist/commands/doctor-update.js +12 -9
  291. package/dist/commands/models/list.list-command.js +7 -5
  292. package/dist/commands/models/set-image.js +2 -21
  293. package/dist/commands/node-daemon-install-helpers.js +10 -8
  294. package/dist/commands/onboard-auth.config-minimax.js +54 -80
  295. package/dist/commands/onboard-auth.config-opencode.js +2 -18
  296. package/dist/commands/onboard-auth.credentials.js +90 -13
  297. package/dist/commands/onboard-auth.js +1 -1
  298. package/dist/commands/onboard-auth.models.js +6 -5
  299. package/dist/commands/onboard-hooks.js +1 -1
  300. package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
  301. package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
  302. package/dist/commands/onboard-provider-auth-flags.js +14 -0
  303. package/dist/commands/onboard-remote.js +14 -7
  304. package/dist/commands/onboard.js +11 -13
  305. package/dist/commands/sandbox-display.js +6 -5
  306. package/dist/commands/sessions.test-helpers.js +61 -0
  307. package/dist/commands/status-all/diagnosis.js +14 -10
  308. package/dist/commands/status-all/format.js +1 -0
  309. package/dist/commands/status.gateway-probe.js +1 -16
  310. package/dist/commands/systemd-linger.js +12 -6
  311. package/dist/config/agent-limits.js +2 -0
  312. package/dist/config/commands.js +32 -15
  313. package/dist/config/config-paths.js +9 -11
  314. package/dist/config/config.js +1 -1
  315. package/dist/config/defaults.js +22 -2
  316. package/dist/config/discord-preview-streaming.js +104 -0
  317. package/dist/config/env-substitution.js +62 -34
  318. package/dist/config/env-vars.js +45 -7
  319. package/dist/config/includes.js +4 -0
  320. package/dist/config/io.js +656 -171
  321. package/dist/config/legacy.migrations.part-1.js +189 -78
  322. package/dist/config/legacy.shared.js +3 -1
  323. package/dist/config/merge-patch.js +54 -4
  324. package/dist/config/prototype-keys.js +4 -0
  325. package/dist/config/redact-snapshot.js +404 -76
  326. package/dist/config/schema.help.js +44 -7
  327. package/dist/config/schema.js +58 -570
  328. package/dist/config/schema.labels.js +38 -6
  329. package/dist/config/sessions/delivery-info.js +10 -3
  330. package/dist/config/sessions/main-session.js +10 -5
  331. package/dist/config/sessions/session-file.js +33 -0
  332. package/dist/config/sessions/session-key.js +10 -5
  333. package/dist/config/sessions/store.js +1 -1
  334. package/dist/config/sessions.js +1 -0
  335. package/dist/config/validation.js +140 -85
  336. package/dist/config/zod-schema.agent-runtime.js +11 -0
  337. package/dist/config/zod-schema.hooks.js +40 -11
  338. package/dist/config/zod-schema.installs.js +20 -0
  339. package/dist/config/zod-schema.js +156 -20
  340. package/dist/config/zod-schema.providers-core.js +78 -4
  341. package/dist/config/zod-schema.providers.js +6 -1
  342. package/dist/config/zod-schema.session.js +41 -2
  343. package/dist/cron/run-log.js +3 -0
  344. package/dist/cron/schedule.js +21 -10
  345. package/dist/cron/service/ops.js +35 -21
  346. package/dist/cron/service/timer.js +116 -16
  347. package/dist/cron/stagger.js +3 -1
  348. package/dist/daemon/cmd-argv.js +21 -0
  349. package/dist/daemon/cmd-set.js +58 -0
  350. package/dist/daemon/service-types.js +1 -0
  351. package/dist/discord/api.js +12 -6
  352. package/dist/discord/draft-chunking.js +22 -0
  353. package/dist/discord/draft-stream.js +124 -0
  354. package/dist/discord/monitor/agent-components.js +1 -1
  355. package/dist/discord/monitor/commands.js +5 -0
  356. package/dist/discord/monitor/exec-approvals.js +357 -162
  357. package/dist/discord/monitor/gateway-plugin.js +2 -1
  358. package/dist/discord/monitor/listeners.js +37 -27
  359. package/dist/discord/monitor/message-handler.js +4 -1
  360. package/dist/discord/monitor/message-handler.preflight.js +65 -8
  361. package/dist/discord/monitor/message-handler.process.js +246 -217
  362. package/dist/discord/monitor/message-utils.js +143 -6
  363. package/dist/discord/monitor/model-picker-preferences.js +143 -0
  364. package/dist/discord/monitor/model-picker.js +651 -0
  365. package/dist/discord/monitor/native-command.js +573 -16
  366. package/dist/discord/monitor/provider.allowlist.js +223 -0
  367. package/dist/discord/monitor/provider.js +275 -347
  368. package/dist/discord/monitor/provider.lifecycle.js +100 -0
  369. package/dist/discord/monitor/reply-delivery.js +123 -16
  370. package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
  371. package/dist/discord/monitor/thread-bindings.js +4 -0
  372. package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
  373. package/dist/discord/monitor/thread-bindings.manager.js +423 -0
  374. package/dist/discord/monitor/thread-bindings.messages.js +55 -0
  375. package/dist/discord/monitor/thread-bindings.state.js +358 -0
  376. package/dist/discord/monitor/thread-bindings.types.js +6 -0
  377. package/dist/discord/resolve-users.js +33 -21
  378. package/dist/discord/send.channels.js +15 -0
  379. package/dist/discord/send.js +3 -2
  380. package/dist/discord/send.outbound.js +82 -26
  381. package/dist/discord/send.permissions.js +83 -30
  382. package/dist/discord/send.reactions.js +8 -4
  383. package/dist/discord/token.js +10 -5
  384. package/dist/discord/voice/command.js +263 -0
  385. package/dist/discord/voice/manager.js +531 -0
  386. package/dist/gateway/auth.js +72 -13
  387. package/dist/gateway/call.js +152 -83
  388. package/dist/gateway/canvas-capability.js +75 -0
  389. package/dist/gateway/client.js +28 -4
  390. package/dist/gateway/config-reload.js +3 -4
  391. package/dist/gateway/control-plane-audit.js +28 -0
  392. package/dist/gateway/control-plane-rate-limit.js +53 -0
  393. package/dist/gateway/control-ui.js +219 -96
  394. package/dist/gateway/events.js +1 -0
  395. package/dist/gateway/hooks-mapping.js +88 -38
  396. package/dist/gateway/hooks.js +109 -54
  397. package/dist/gateway/http-auth-helpers.js +3 -2
  398. package/dist/gateway/http-common.js +22 -0
  399. package/dist/gateway/http-endpoint-helpers.js +1 -0
  400. package/dist/gateway/method-scopes.js +169 -0
  401. package/dist/gateway/net.js +74 -9
  402. package/dist/gateway/node-invoke-system-run-approval.js +14 -35
  403. package/dist/gateway/node-registry.js +10 -5
  404. package/dist/gateway/openai-http.js +1 -0
  405. package/dist/gateway/openresponses-http.js +121 -110
  406. package/dist/gateway/origin-check.js +1 -18
  407. package/dist/gateway/probe-auth.js +2 -0
  408. package/dist/gateway/protocol/index.js +4 -2
  409. package/dist/gateway/protocol/schema/cron.js +1 -0
  410. package/dist/gateway/protocol/schema/devices.js +1 -0
  411. package/dist/gateway/protocol/schema/protocol-schemas.js +4 -1
  412. package/dist/gateway/protocol/schema/push.js +18 -0
  413. package/dist/gateway/protocol/schema/sessions.js +6 -0
  414. package/dist/gateway/protocol/schema.js +1 -0
  415. package/dist/gateway/role-policy.js +17 -0
  416. package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
  417. package/dist/gateway/server/ws-connection/message-handler.js +175 -148
  418. package/dist/gateway/server-chat.js +83 -25
  419. package/dist/gateway/server-constants.js +10 -9
  420. package/dist/gateway/server-cron.js +1 -0
  421. package/dist/gateway/server-http.js +247 -54
  422. package/dist/gateway/server-maintenance.js +20 -5
  423. package/dist/gateway/server-methods/agent.js +162 -24
  424. package/dist/gateway/server-methods/chat.js +465 -130
  425. package/dist/gateway/server-methods/config.js +193 -152
  426. package/dist/gateway/server-methods/devices.js +17 -3
  427. package/dist/gateway/server-methods/models.js +11 -1
  428. package/dist/gateway/server-methods/nodes.helpers.js +12 -0
  429. package/dist/gateway/server-methods/nodes.js +251 -69
  430. package/dist/gateway/server-methods/push.js +53 -0
  431. package/dist/gateway/server-methods/sessions.js +64 -8
  432. package/dist/gateway/server-methods/usage.js +162 -75
  433. package/dist/gateway/server-node-events.js +29 -0
  434. package/dist/gateway/server-reload-handlers.js +2 -3
  435. package/dist/gateway/server-runtime-config.js +39 -13
  436. package/dist/gateway/server-runtime-state.js +2 -0
  437. package/dist/gateway/server-startup-memory.js +17 -11
  438. package/dist/gateway/server-ws-runtime.js +1 -0
  439. package/dist/gateway/server.impl.js +296 -139
  440. package/dist/gateway/session-preview.test-helpers.js +11 -0
  441. package/dist/gateway/session-utils.fs.js +32 -34
  442. package/dist/gateway/sessions-resolve.js +17 -5
  443. package/dist/gateway/startup-auth.js +126 -0
  444. package/dist/gateway/test-helpers.agent-results.js +15 -0
  445. package/dist/gateway/test-helpers.mocks.js +37 -14
  446. package/dist/gateway/test-helpers.openai-mock.js +14 -7
  447. package/dist/gateway/test-helpers.server.js +161 -77
  448. package/dist/gateway/tools-invoke-http.js +21 -10
  449. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
  450. package/dist/hooks/bundled/command-logger/handler.js +7 -2
  451. package/dist/hooks/bundled/session-memory/handler.js +170 -38
  452. package/dist/hooks/frontmatter.js +6 -6
  453. package/dist/hooks/gmail-watcher-lifecycle.js +23 -0
  454. package/dist/hooks/gmail-watcher.js +11 -6
  455. package/dist/hooks/internal-hooks.js +11 -1
  456. package/dist/hooks/llm-slug-generator.js +4 -1
  457. package/dist/hooks/workspace.js +47 -17
  458. package/dist/imessage/accounts.js +9 -20
  459. package/dist/imessage/monitor/inbound-processing.js +2 -1
  460. package/dist/infra/archive-path.js +49 -0
  461. package/dist/infra/archive.js +174 -73
  462. package/dist/infra/control-ui-assets.js +14 -6
  463. package/dist/infra/device-pairing.js +204 -144
  464. package/dist/infra/env.js +10 -5
  465. package/dist/infra/exec-approvals-allowlist.js +141 -70
  466. package/dist/infra/exec-approvals-analysis.js +78 -20
  467. package/dist/infra/exec-approvals.js +5 -17
  468. package/dist/infra/exec-safe-bin-policy.js +277 -0
  469. package/dist/infra/fixed-window-rate-limit.js +33 -0
  470. package/dist/infra/fs-safe.js +71 -39
  471. package/dist/infra/gateway-lock.js +6 -2
  472. package/dist/infra/git-root.js +61 -0
  473. package/dist/infra/heartbeat-active-hours.js +2 -2
  474. package/dist/infra/heartbeat-reason.js +40 -0
  475. package/dist/infra/heartbeat-runner.js +72 -32
  476. package/dist/infra/heartbeat-wake.js +6 -12
  477. package/dist/infra/host-env-security-policy.json +19 -0
  478. package/dist/infra/host-env-security.js +66 -0
  479. package/dist/infra/install-source-utils.js +91 -7
  480. package/dist/infra/net/ssrf.js +131 -38
  481. package/dist/infra/node-pairing.js +50 -105
  482. package/dist/infra/npm-integrity.js +45 -0
  483. package/dist/infra/npm-pack-install.js +40 -0
  484. package/dist/infra/outbound/bound-delivery-router.js +88 -0
  485. package/dist/infra/outbound/channel-adapters.js +20 -7
  486. package/dist/infra/outbound/channel-selection.js +12 -6
  487. package/dist/infra/outbound/envelope.js +1 -1
  488. package/dist/infra/outbound/format.js +12 -6
  489. package/dist/infra/outbound/message-action-runner.js +107 -327
  490. package/dist/infra/outbound/message.js +59 -36
  491. package/dist/infra/outbound/outbound-policy.js +52 -25
  492. package/dist/infra/outbound/outbound-send-service.js +58 -71
  493. package/dist/infra/outbound/payloads.js +14 -7
  494. package/dist/infra/outbound/session-binding-service.js +123 -0
  495. package/dist/infra/pairing-files.js +10 -0
  496. package/dist/infra/path-guards.js +25 -0
  497. package/dist/infra/plain-object.js +9 -0
  498. package/dist/infra/provider-usage.fetch.codex.js +7 -15
  499. package/dist/infra/provider-usage.fetch.gemini.js +14 -11
  500. package/dist/infra/provider-usage.fetch.shared.js +30 -1
  501. package/dist/infra/provider-usage.fetch.zai.js +10 -9
  502. package/dist/infra/push-apns.js +365 -0
  503. package/dist/infra/restart-sentinel.js +16 -1
  504. package/dist/infra/restart.js +229 -26
  505. package/dist/infra/retry-policy.js +4 -2
  506. package/dist/infra/retry.js +9 -5
  507. package/dist/infra/scp-host.js +54 -0
  508. package/dist/infra/session-cost-usage.js +107 -59
  509. package/dist/infra/session-maintenance-warning.js +3 -1
  510. package/dist/infra/shell-env.js +98 -34
  511. package/dist/infra/ssh-config.js +12 -6
  512. package/dist/infra/system-run-command.js +49 -4
  513. package/dist/infra/update-channels.js +10 -5
  514. package/dist/infra/update-startup.js +86 -9
  515. package/dist/line/accounts.js +5 -7
  516. package/dist/line/bot-access.js +8 -20
  517. package/dist/line/bot-handlers.js +3 -1
  518. package/dist/link-understanding/detect.js +15 -7
  519. package/dist/media/constants.js +15 -6
  520. package/dist/media/image-ops.js +7 -0
  521. package/dist/media/inbound-path-policy.js +114 -0
  522. package/dist/media/input-files.js +16 -0
  523. package/dist/media/local-roots.js +3 -2
  524. package/dist/media-understanding/apply.js +4 -1
  525. package/dist/media-understanding/concurrency.js +8 -20
  526. package/dist/memory/backend-config.js +45 -6
  527. package/dist/memory/embeddings.js +10 -4
  528. package/dist/memory/fs-utils.js +23 -0
  529. package/dist/memory/manager-search.js +12 -6
  530. package/dist/memory/manager-sync-ops.js +12 -2
  531. package/dist/memory/qmd-manager.js +466 -53
  532. package/dist/memory/query-expansion.js +167 -3
  533. package/dist/memory/status-format.js +10 -5
  534. package/dist/memory/sync-memory-files.js +1 -1
  535. package/dist/memory/test-manager.js +8 -0
  536. package/dist/node-host/invoke-system-run.js +281 -0
  537. package/dist/node-host/invoke.js +55 -337
  538. package/dist/pairing/pairing-store.js +22 -0
  539. package/dist/plugin-sdk/allow-from.js +1 -1
  540. package/dist/plugin-sdk/command-auth.js +3 -1
  541. package/dist/plugin-sdk/index.js +6 -3
  542. package/dist/plugin-sdk/temp-path.js +47 -0
  543. package/dist/plugin-sdk/webhook-targets.js +32 -0
  544. package/dist/plugins/bundled-dir.js +9 -6
  545. package/dist/plugins/discovery.js +217 -23
  546. package/dist/plugins/hook-runner-global.js +16 -0
  547. package/dist/plugins/hooks.js +50 -0
  548. package/dist/plugins/install.js +28 -16
  549. package/dist/plugins/loader.js +192 -26
  550. package/dist/plugins/logger.js +8 -0
  551. package/dist/plugins/manifest-registry.js +3 -0
  552. package/dist/plugins/path-safety.js +34 -0
  553. package/dist/plugins/registry.js +5 -2
  554. package/dist/plugins/runtime/index.js +271 -206
  555. package/dist/plugins/runtime.js +3 -17
  556. package/dist/plugins/update.js +78 -12
  557. package/dist/process/spawn-utils.js +14 -7
  558. package/dist/providers/github-copilot-models.js +4 -1
  559. package/dist/providers/github-copilot-token.js +11 -6
  560. package/dist/providers/qwen-portal-oauth.js +14 -6
  561. package/dist/routing/account-id.js +30 -0
  562. package/dist/routing/resolve-route.js +3 -7
  563. package/dist/routing/session-key.js +2 -16
  564. package/dist/security/audit-channel.js +100 -20
  565. package/dist/security/audit-extra.async.js +505 -179
  566. package/dist/security/audit-extra.js +12 -2
  567. package/dist/security/audit-extra.sync.js +421 -35
  568. package/dist/security/audit-fs.js +31 -13
  569. package/dist/security/audit.js +180 -370
  570. package/dist/security/dm-policy-shared.js +68 -0
  571. package/dist/security/external-content.js +46 -14
  572. package/dist/security/fix.js +49 -85
  573. package/dist/security/scan-paths.js +20 -0
  574. package/dist/security/secret-equal.js +3 -7
  575. package/dist/security/windows-acl.js +30 -15
  576. package/dist/shared/entry-status.js +6 -0
  577. package/dist/shared/frontmatter.js +5 -5
  578. package/dist/shared/node-list-parse.js +13 -0
  579. package/dist/shared/node-match.js +11 -4
  580. package/dist/shared/operator-scope-compat.js +42 -0
  581. package/dist/shared/text-chunking.js +29 -0
  582. package/dist/signal/accounts.js +7 -20
  583. package/dist/signal/monitor/event-handler.js +3 -1
  584. package/dist/slack/accounts.js +6 -19
  585. package/dist/slack/actions.js +11 -3
  586. package/dist/slack/blocks.test-helpers.js +31 -0
  587. package/dist/slack/monitor/auth.js +1 -1
  588. package/dist/slack/monitor/message-handler/dispatch.js +50 -29
  589. package/dist/slack/monitor/mrkdwn.js +8 -0
  590. package/dist/slack/monitor/replies.js +15 -7
  591. package/dist/slack/monitor/slash.js +22 -13
  592. package/dist/slack/resolve-channels.js +10 -5
  593. package/dist/slack/send.js +102 -12
  594. package/dist/slack/stream-mode.js +10 -0
  595. package/dist/slack/streaming.js +4 -2
  596. package/dist/telegram/accounts.js +19 -14
  597. package/dist/telegram/bot/helpers.js +3 -5
  598. package/dist/telegram/bot-access.js +35 -36
  599. package/dist/telegram/bot-handlers.js +120 -148
  600. package/dist/telegram/bot-message-context.js +68 -9
  601. package/dist/telegram/bot-message-dispatch.js +477 -210
  602. package/dist/telegram/bot-native-commands.js +16 -0
  603. package/dist/telegram/draft-stream.js +44 -8
  604. package/dist/telegram/inline-buttons.js +5 -15
  605. package/dist/telegram/monitor.js +11 -7
  606. package/dist/telegram/network-config.js +19 -7
  607. package/dist/telegram/reasoning-lane-coordinator.js +128 -0
  608. package/dist/telegram/send.js +3 -2
  609. package/dist/telegram/sent-message-cache.js +5 -6
  610. package/dist/telegram/status-reaction-variants.js +208 -0
  611. package/dist/telegram/sticker-cache.js +11 -9
  612. package/dist/terminal/prompt-select-styled.js +9 -0
  613. package/dist/terminal/theme.js +12 -12
  614. package/dist/test-utils/command-runner.js +6 -0
  615. package/dist/test-utils/internal-hook-event-payload.js +10 -0
  616. package/dist/test-utils/model-auth-mock.js +12 -0
  617. package/dist/test-utils/provider-usage-fetch.js +14 -0
  618. package/dist/test-utils/temp-home.js +33 -0
  619. package/dist/tts/tts.js +80 -567
  620. package/dist/tui/components/chat-log.js +50 -8
  621. package/dist/tui/theme/theme.js +10 -12
  622. package/dist/tui/tui-command-handlers.js +36 -27
  623. package/dist/tui/tui-event-handlers.js +122 -32
  624. package/dist/tui/tui-local-shell.js +16 -6
  625. package/dist/tui/tui.js +236 -48
  626. package/dist/utils/account-id.js +2 -4
  627. package/dist/utils/boolean.js +10 -5
  628. package/dist/utils/directive-tags.js +11 -0
  629. package/dist/utils/mask-api-key.js +10 -0
  630. package/dist/utils/queue-helpers.js +67 -12
  631. package/dist/utils/run-with-concurrency.js +39 -0
  632. package/dist/web/auto-reply/deliver-reply.js +8 -4
  633. package/dist/web/auto-reply/mentions.js +10 -5
  634. package/dist/web/auto-reply/monitor/group-members.js +14 -7
  635. package/dist/web/auto-reply/monitor/process-message.js +45 -24
  636. package/dist/web/inbound/access-control.js +5 -2
  637. package/dist/web/login-qr.js +12 -6
  638. package/dist/web/media.js +126 -15
  639. package/docs/tools/slash-commands.md +5 -1
  640. package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
  641. package/extensions/bluebubbles/src/monitor.ts +208 -1950
  642. package/extensions/feishu/src/external-keys.ts +19 -0
  643. package/extensions/lobster/src/windows-spawn.ts +193 -0
  644. package/extensions/matrix/src/matrix/actions/limits.ts +6 -0
  645. package/extensions/mattermost/src/mattermost/reactions.test-helpers.ts +83 -0
  646. package/package.json +1 -1
@@ -2,18 +2,22 @@ export const DEFAULT_PACKAGE_CHANNEL = "stable";
2
2
  export const DEFAULT_GIT_CHANNEL = "dev";
3
3
  export const DEV_BRANCH = "main";
4
4
  export function normalizeUpdateChannel(value) {
5
- if (!value)
5
+ if (!value) {
6
6
  return null;
7
+ }
7
8
  const normalized = value.trim().toLowerCase();
8
- if (normalized === "stable" || normalized === "beta" || normalized === "dev")
9
+ if (normalized === "stable" || normalized === "beta" || normalized === "dev") {
9
10
  return normalized;
11
+ }
10
12
  return null;
11
13
  }
12
14
  export function channelToNpmTag(channel) {
13
- if (channel === "beta")
15
+ if (channel === "beta") {
14
16
  return "beta";
15
- if (channel === "dev")
17
+ }
18
+ if (channel === "dev") {
16
19
  return "dev";
20
+ }
17
21
  return "latest";
18
22
  }
19
23
  export function isBetaTag(tag) {
@@ -43,8 +47,9 @@ export function resolveEffectiveUpdateChannel(params) {
43
47
  return { channel: DEFAULT_PACKAGE_CHANNEL, source: "default" };
44
48
  }
45
49
  export function formatUpdateChannelLabel(params) {
46
- if (params.source === "config")
50
+ if (params.source === "config") {
47
51
  return `${params.channel} (config)`;
52
+ }
48
53
  if (params.source === "git-tag") {
49
54
  return params.gitTag ? `${params.channel} (${params.gitTag})` : `${params.channel} (tag)`;
50
55
  }
@@ -1,18 +1,27 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
+ import { formatCliCommand } from "../cli/command-format.js";
3
4
  import { resolveStateDir } from "../config/paths.js";
5
+ import { VERSION } from "../version.js";
4
6
  import { resolvePoolBotPackageRoot } from "./poolbot-root.js";
5
- import { compareSemverStrings, resolveNpmChannelTag, checkUpdateStatus } from "./update-check.js";
6
7
  import { normalizeUpdateChannel, DEFAULT_PACKAGE_CHANNEL } from "./update-channels.js";
7
- import { VERSION } from "../version.js";
8
- import { formatCliCommand } from "../cli/command-format.js";
8
+ import { compareSemverStrings, resolveNpmChannelTag, checkUpdateStatus } from "./update-check.js";
9
+ let updateAvailableCache = null;
10
+ export function getUpdateAvailable() {
11
+ return updateAvailableCache;
12
+ }
13
+ export function resetUpdateAvailableStateForTest() {
14
+ updateAvailableCache = null;
15
+ }
9
16
  const UPDATE_CHECK_FILENAME = "update-check.json";
10
17
  const UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
11
18
  function shouldSkipCheck(allowInTests) {
12
- if (allowInTests)
19
+ if (allowInTests) {
13
20
  return false;
14
- if (process.env.VITEST || process.env.NODE_ENV === "test")
21
+ }
22
+ if (process.env.VITEST || process.env.NODE_ENV === "test") {
15
23
  return true;
24
+ }
16
25
  return false;
17
26
  }
18
27
  async function readState(statePath) {
@@ -29,20 +38,63 @@ async function writeState(statePath, state) {
29
38
  await fs.mkdir(path.dirname(statePath), { recursive: true });
30
39
  await fs.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
31
40
  }
41
+ function sameUpdateAvailable(a, b) {
42
+ if (a === b) {
43
+ return true;
44
+ }
45
+ if (!a || !b) {
46
+ return false;
47
+ }
48
+ return (a.currentVersion === b.currentVersion &&
49
+ a.latestVersion === b.latestVersion &&
50
+ a.channel === b.channel);
51
+ }
52
+ function setUpdateAvailableCache(params) {
53
+ if (sameUpdateAvailable(updateAvailableCache, params.next)) {
54
+ return;
55
+ }
56
+ updateAvailableCache = params.next;
57
+ params.onUpdateAvailableChange?.(params.next);
58
+ }
59
+ function resolvePersistedUpdateAvailable(state) {
60
+ const latestVersion = state.lastAvailableVersion?.trim();
61
+ if (!latestVersion) {
62
+ return null;
63
+ }
64
+ const cmp = compareSemverStrings(VERSION, latestVersion);
65
+ if (cmp == null || cmp >= 0) {
66
+ return null;
67
+ }
68
+ const channel = state.lastAvailableTag?.trim() || DEFAULT_PACKAGE_CHANNEL;
69
+ return {
70
+ currentVersion: VERSION,
71
+ latestVersion,
72
+ channel,
73
+ };
74
+ }
32
75
  export async function runGatewayUpdateCheck(params) {
33
- if (shouldSkipCheck(Boolean(params.allowInTests)))
76
+ if (shouldSkipCheck(Boolean(params.allowInTests))) {
34
77
  return;
35
- if (params.isNixMode)
78
+ }
79
+ if (params.isNixMode) {
36
80
  return;
37
- if (params.cfg.update?.checkOnStart === false)
81
+ }
82
+ if (params.cfg.update?.checkOnStart === false) {
38
83
  return;
84
+ }
39
85
  const statePath = path.join(resolveStateDir(), UPDATE_CHECK_FILENAME);
40
86
  const state = await readState(statePath);
41
87
  const now = Date.now();
42
88
  const lastCheckedAt = state.lastCheckedAt ? Date.parse(state.lastCheckedAt) : null;
89
+ const persistedAvailable = resolvePersistedUpdateAvailable(state);
90
+ setUpdateAvailableCache({
91
+ next: persistedAvailable,
92
+ onUpdateAvailableChange: params.onUpdateAvailableChange,
93
+ });
43
94
  if (lastCheckedAt && Number.isFinite(lastCheckedAt)) {
44
- if (now - lastCheckedAt < UPDATE_CHECK_INTERVAL_MS)
95
+ if (now - lastCheckedAt < UPDATE_CHECK_INTERVAL_MS) {
45
96
  return;
97
+ }
46
98
  }
47
99
  const root = await resolvePoolBotPackageRoot({
48
100
  moduleUrl: import.meta.url,
@@ -60,6 +112,12 @@ export async function runGatewayUpdateCheck(params) {
60
112
  lastCheckedAt: new Date(now).toISOString(),
61
113
  };
62
114
  if (status.installKind !== "package") {
115
+ delete nextState.lastAvailableVersion;
116
+ delete nextState.lastAvailableTag;
117
+ setUpdateAvailableCache({
118
+ next: null,
119
+ onUpdateAvailableChange: params.onUpdateAvailableChange,
120
+ });
63
121
  await writeState(statePath, nextState);
64
122
  return;
65
123
  }
@@ -72,6 +130,17 @@ export async function runGatewayUpdateCheck(params) {
72
130
  }
73
131
  const cmp = compareSemverStrings(VERSION, resolved.version);
74
132
  if (cmp != null && cmp < 0) {
133
+ const nextAvailable = {
134
+ currentVersion: VERSION,
135
+ latestVersion: resolved.version,
136
+ channel: tag,
137
+ };
138
+ setUpdateAvailableCache({
139
+ next: nextAvailable,
140
+ onUpdateAvailableChange: params.onUpdateAvailableChange,
141
+ });
142
+ nextState.lastAvailableVersion = resolved.version;
143
+ nextState.lastAvailableTag = tag;
75
144
  const shouldNotify = state.lastNotifiedVersion !== resolved.version || state.lastNotifiedTag !== tag;
76
145
  if (shouldNotify) {
77
146
  params.log.info(`update available (${tag}): v${resolved.version} (current v${VERSION}). Run: ${formatCliCommand("poolbot update")}`);
@@ -79,6 +148,14 @@ export async function runGatewayUpdateCheck(params) {
79
148
  nextState.lastNotifiedTag = tag;
80
149
  }
81
150
  }
151
+ else {
152
+ delete nextState.lastAvailableVersion;
153
+ delete nextState.lastAvailableTag;
154
+ setUpdateAvailableCache({
155
+ next: null,
156
+ onUpdateAvailableChange: params.onUpdateAvailableChange,
157
+ });
158
+ }
82
159
  await writeState(statePath, nextState);
83
160
  }
84
161
  export function scheduleGatewayUpdateCheck(params) {
@@ -1,8 +1,10 @@
1
1
  import fs from "node:fs";
2
- export const DEFAULT_ACCOUNT_ID = "default";
2
+ import { DEFAULT_ACCOUNT_ID, normalizeAccountId as normalizeSharedAccountId, } from "../routing/account-id.js";
3
+ export { DEFAULT_ACCOUNT_ID } from "../routing/account-id.js";
3
4
  function readFileIfExists(filePath) {
4
- if (!filePath)
5
+ if (!filePath) {
5
6
  return undefined;
7
+ }
6
8
  try {
7
9
  return fs.readFileSync(filePath, "utf-8").trim();
8
10
  }
@@ -122,9 +124,5 @@ export function resolveDefaultLineAccountId(cfg) {
122
124
  return ids[0] ?? DEFAULT_ACCOUNT_ID;
123
125
  }
124
126
  export function normalizeAccountId(accountId) {
125
- const trimmed = accountId?.trim().toLowerCase();
126
- if (!trimmed || trimmed === "default") {
127
- return DEFAULT_ACCOUNT_ID;
128
- }
129
- return trimmed;
127
+ return normalizeSharedAccountId(accountId);
130
128
  }
@@ -1,9 +1,12 @@
1
+ import { firstDefined, isSenderIdAllowed, mergeAllowFromSources } from "../channels/allow-from.js";
1
2
  function normalizeAllowEntry(value) {
2
3
  const trimmed = String(value).trim();
3
- if (!trimmed)
4
+ if (!trimmed) {
4
5
  return "";
5
- if (trimmed === "*")
6
+ }
7
+ if (trimmed === "*") {
6
8
  return "*";
9
+ }
7
10
  return trimmed.replace(/^line:(?:user:)?/i, "");
8
11
  }
9
12
  export const normalizeAllowFrom = (list) => {
@@ -15,24 +18,9 @@ export const normalizeAllowFrom = (list) => {
15
18
  hasEntries: entries.length > 0,
16
19
  };
17
20
  };
18
- export const normalizeAllowFromWithStore = (params) => {
19
- const combined = [...(params.allowFrom ?? []), ...(params.storeAllowFrom ?? [])];
20
- return normalizeAllowFrom(combined);
21
- };
22
- export const firstDefined = (...values) => {
23
- for (const value of values) {
24
- if (typeof value !== "undefined")
25
- return value;
26
- }
27
- return undefined;
28
- };
21
+ export const normalizeAllowFromWithStore = (params) => normalizeAllowFrom(mergeAllowFromSources(params));
29
22
  export const isSenderAllowed = (params) => {
30
23
  const { allow, senderId } = params;
31
- if (!allow.hasEntries)
32
- return false;
33
- if (allow.hasWildcard)
34
- return true;
35
- if (!senderId)
36
- return false;
37
- return allow.entries.includes(senderId);
24
+ return isSenderIdAllowed(allow, senderId, false);
38
25
  };
26
+ export { firstDefined };
@@ -77,10 +77,12 @@ async function shouldProcessLineEvent(event, context) {
77
77
  const { cfg, account } = context;
78
78
  const { userId, groupId, roomId, isGroup } = getSourceInfo(event.source);
79
79
  const senderId = userId ?? "";
80
+ const dmPolicy = account.config.dmPolicy ?? "pairing";
80
81
  const storeAllowFrom = await readChannelAllowFromStore("line").catch(() => []);
81
82
  const effectiveDmAllow = normalizeAllowFromWithStore({
82
83
  allowFrom: account.config.allowFrom,
83
84
  storeAllowFrom,
85
+ dmPolicy,
84
86
  });
85
87
  const groupConfig = resolveLineGroupConfig({ config: account.config, groupId, roomId });
86
88
  const groupAllowOverride = groupConfig?.allowFrom;
@@ -91,8 +93,8 @@ async function shouldProcessLineEvent(event, context) {
91
93
  const effectiveGroupAllow = normalizeAllowFromWithStore({
92
94
  allowFrom: groupAllowFrom,
93
95
  storeAllowFrom,
96
+ dmPolicy,
94
97
  });
95
- const dmPolicy = account.config.dmPolicy ?? "pairing";
96
98
  const defaultGroupPolicy = cfg.channels?.defaults?.groupPolicy;
97
99
  const groupPolicy = account.config.groupPolicy ?? defaultGroupPolicy ?? "allowlist";
98
100
  if (isGroup) {
@@ -1,3 +1,4 @@
1
+ import { isBlockedHostnameOrIp } from "../infra/net/ssrf.js";
1
2
  import { DEFAULT_MAX_LINKS } from "./defaults.js";
2
3
  // Remove markdown link syntax so only bare URLs are considered.
3
4
  const MARKDOWN_LINK_RE = /\[[^\]]*]\((https?:\/\/\S+?)\)/gi;
@@ -14,10 +15,12 @@ function resolveMaxLinks(value) {
14
15
  function isAllowedUrl(raw) {
15
16
  try {
16
17
  const parsed = new URL(raw);
17
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
18
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
18
19
  return false;
19
- if (parsed.hostname === "127.0.0.1")
20
+ }
21
+ if (isBlockedHostnameOrIp(parsed.hostname)) {
20
22
  return false;
23
+ }
21
24
  return true;
22
25
  }
23
26
  catch {
@@ -26,24 +29,29 @@ function isAllowedUrl(raw) {
26
29
  }
27
30
  export function extractLinksFromMessage(message, opts) {
28
31
  const source = message?.trim();
29
- if (!source)
32
+ if (!source) {
30
33
  return [];
34
+ }
31
35
  const maxLinks = resolveMaxLinks(opts?.maxLinks);
32
36
  const sanitized = stripMarkdownLinks(source);
33
37
  const seen = new Set();
34
38
  const results = [];
35
39
  for (const match of sanitized.matchAll(BARE_LINK_RE)) {
36
40
  const raw = match[0]?.trim();
37
- if (!raw)
41
+ if (!raw) {
38
42
  continue;
39
- if (!isAllowedUrl(raw))
43
+ }
44
+ if (!isAllowedUrl(raw)) {
40
45
  continue;
41
- if (seen.has(raw))
46
+ }
47
+ if (seen.has(raw)) {
42
48
  continue;
49
+ }
43
50
  seen.add(raw);
44
51
  results.push(raw);
45
- if (results.length >= maxLinks)
52
+ if (results.length >= maxLinks) {
46
53
  break;
54
+ }
47
55
  }
48
56
  return results;
49
57
  }
@@ -3,18 +3,27 @@ export const MAX_AUDIO_BYTES = 16 * 1024 * 1024; // 16MB
3
3
  export const MAX_VIDEO_BYTES = 16 * 1024 * 1024; // 16MB
4
4
  export const MAX_DOCUMENT_BYTES = 100 * 1024 * 1024; // 100MB
5
5
  export function mediaKindFromMime(mime) {
6
- if (!mime)
6
+ if (!mime) {
7
7
  return "unknown";
8
- if (mime.startsWith("image/"))
8
+ }
9
+ if (mime.startsWith("image/")) {
9
10
  return "image";
10
- if (mime.startsWith("audio/"))
11
+ }
12
+ if (mime.startsWith("audio/")) {
11
13
  return "audio";
12
- if (mime.startsWith("video/"))
14
+ }
15
+ if (mime.startsWith("video/")) {
13
16
  return "video";
14
- if (mime === "application/pdf")
17
+ }
18
+ if (mime === "application/pdf") {
15
19
  return "document";
16
- if (mime.startsWith("application/"))
20
+ }
21
+ if (mime.startsWith("text/")) {
22
+ return "document";
23
+ }
24
+ if (mime.startsWith("application/")) {
17
25
  return "document";
26
+ }
18
27
  return "unknown";
19
28
  }
20
29
  export function maxBytesForKind(kind) {
@@ -2,6 +2,13 @@ import fs from "node:fs/promises";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
4
  import { runExec } from "../process/exec.js";
5
+ export const IMAGE_REDUCE_QUALITY_STEPS = [85, 75, 65, 55, 45, 35];
6
+ export function buildImageResizeSideGrid(maxSide, sideStart) {
7
+ return [sideStart, 1800, 1600, 1400, 1200, 1000, 800]
8
+ .map((value) => Math.min(maxSide, value))
9
+ .filter((value, idx, arr) => value > 0 && arr.indexOf(value) === idx)
10
+ .toSorted((a, b) => b - a);
11
+ }
5
12
  function isBun() {
6
13
  return typeof process.versions.bun === "string";
7
14
  }
@@ -0,0 +1,114 @@
1
+ import path from "node:path";
2
+ const WILDCARD_SEGMENT = "*";
3
+ const WINDOWS_DRIVE_ABS_RE = /^[A-Za-z]:\//;
4
+ const WINDOWS_DRIVE_ROOT_RE = /^[A-Za-z]:$/;
5
+ export const DEFAULT_IMESSAGE_ATTACHMENT_ROOTS = ["/Users/*/Library/Messages/Attachments"];
6
+ function normalizePosixAbsolutePath(value) {
7
+ const trimmed = value.trim();
8
+ if (!trimmed || trimmed.includes("\0")) {
9
+ return undefined;
10
+ }
11
+ const normalized = path.posix.normalize(trimmed.replaceAll("\\", "/"));
12
+ const isAbsolute = normalized.startsWith("/") || WINDOWS_DRIVE_ABS_RE.test(normalized);
13
+ if (!isAbsolute || normalized === "/") {
14
+ return undefined;
15
+ }
16
+ const withoutTrailingSlash = normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
17
+ if (WINDOWS_DRIVE_ROOT_RE.test(withoutTrailingSlash)) {
18
+ return undefined;
19
+ }
20
+ return withoutTrailingSlash;
21
+ }
22
+ function splitPathSegments(value) {
23
+ return value.split("/").filter(Boolean);
24
+ }
25
+ function matchesRootPattern(params) {
26
+ const candidateSegments = splitPathSegments(params.candidatePath);
27
+ const rootSegments = splitPathSegments(params.rootPattern);
28
+ if (candidateSegments.length < rootSegments.length) {
29
+ return false;
30
+ }
31
+ for (let idx = 0; idx < rootSegments.length; idx += 1) {
32
+ const expected = rootSegments[idx];
33
+ const actual = candidateSegments[idx];
34
+ if (expected === WILDCARD_SEGMENT) {
35
+ continue;
36
+ }
37
+ if (expected !== actual) {
38
+ return false;
39
+ }
40
+ }
41
+ return true;
42
+ }
43
+ export function isValidInboundPathRootPattern(value) {
44
+ const normalized = normalizePosixAbsolutePath(value);
45
+ if (!normalized) {
46
+ return false;
47
+ }
48
+ const segments = splitPathSegments(normalized);
49
+ if (segments.length === 0) {
50
+ return false;
51
+ }
52
+ return segments.every((segment) => segment === WILDCARD_SEGMENT || !segment.includes("*"));
53
+ }
54
+ export function normalizeInboundPathRoots(roots) {
55
+ const normalized = [];
56
+ const seen = new Set();
57
+ for (const root of roots ?? []) {
58
+ if (typeof root !== "string") {
59
+ continue;
60
+ }
61
+ if (!isValidInboundPathRootPattern(root)) {
62
+ continue;
63
+ }
64
+ const candidate = normalizePosixAbsolutePath(root);
65
+ if (!candidate || seen.has(candidate)) {
66
+ continue;
67
+ }
68
+ seen.add(candidate);
69
+ normalized.push(candidate);
70
+ }
71
+ return normalized;
72
+ }
73
+ export function mergeInboundPathRoots(...rootsLists) {
74
+ const merged = [];
75
+ const seen = new Set();
76
+ for (const roots of rootsLists) {
77
+ const normalized = normalizeInboundPathRoots(roots);
78
+ for (const root of normalized) {
79
+ if (seen.has(root)) {
80
+ continue;
81
+ }
82
+ seen.add(root);
83
+ merged.push(root);
84
+ }
85
+ }
86
+ return merged;
87
+ }
88
+ export function isInboundPathAllowed(params) {
89
+ const candidatePath = normalizePosixAbsolutePath(params.filePath);
90
+ if (!candidatePath) {
91
+ return false;
92
+ }
93
+ const roots = normalizeInboundPathRoots(params.roots);
94
+ const effectiveRoots = roots.length > 0 ? roots : normalizeInboundPathRoots(params.fallbackRoots ?? undefined);
95
+ if (effectiveRoots.length === 0) {
96
+ return false;
97
+ }
98
+ return effectiveRoots.some((rootPattern) => matchesRootPattern({ candidatePath, rootPattern }));
99
+ }
100
+ function resolveIMessageAccountConfig(params) {
101
+ const accountId = params.accountId?.trim();
102
+ if (!accountId) {
103
+ return undefined;
104
+ }
105
+ return params.cfg.channels?.imessage?.accounts?.[accountId];
106
+ }
107
+ export function resolveIMessageAttachmentRoots(params) {
108
+ const accountConfig = resolveIMessageAccountConfig(params);
109
+ return mergeInboundPathRoots(accountConfig?.attachmentRoots, params.cfg.channels?.imessage?.attachmentRoots, DEFAULT_IMESSAGE_ATTACHMENT_ROOTS);
110
+ }
111
+ export function resolveIMessageRemoteAttachmentRoots(params) {
112
+ const accountConfig = resolveIMessageAccountConfig(params);
113
+ return mergeInboundPathRoots(accountConfig?.remoteAttachmentRoots, params.cfg.channels?.imessage?.remoteAttachmentRoots, accountConfig?.attachmentRoots, params.cfg.channels?.imessage?.attachmentRoots, DEFAULT_IMESSAGE_ATTACHMENT_ROOTS);
114
+ }
@@ -62,6 +62,22 @@ export function normalizeMimeList(values, fallback) {
62
62
  const input = values && values.length > 0 ? values : fallback;
63
63
  return new Set(input.map((value) => normalizeMimeType(value)).filter(Boolean));
64
64
  }
65
+ export function resolveInputFileLimits(config) {
66
+ return {
67
+ allowUrl: config?.allowUrl ?? true,
68
+ allowedMimes: normalizeMimeList(config?.allowedMimes, DEFAULT_INPUT_FILE_MIMES),
69
+ maxBytes: config?.maxBytes ?? DEFAULT_INPUT_FILE_MAX_BYTES,
70
+ maxChars: config?.maxChars ?? DEFAULT_INPUT_FILE_MAX_CHARS,
71
+ maxRedirects: config?.maxRedirects ?? DEFAULT_INPUT_MAX_REDIRECTS,
72
+ timeoutMs: config?.timeoutMs ?? DEFAULT_INPUT_TIMEOUT_MS,
73
+ urlAllowlist: config?.urlAllowlist,
74
+ pdf: {
75
+ maxPages: config?.pdf?.maxPages ?? DEFAULT_INPUT_PDF_MAX_PAGES,
76
+ maxPixels: config?.pdf?.maxPixels ?? DEFAULT_INPUT_PDF_MAX_PIXELS,
77
+ minTextChars: config?.pdf?.minTextChars ?? DEFAULT_INPUT_PDF_MIN_TEXT_CHARS,
78
+ },
79
+ };
80
+ }
65
81
  export async function fetchWithGuard(params) {
66
82
  let currentUrl = params.url;
67
83
  let redirectCount = 0;
@@ -1,11 +1,12 @@
1
- import os from "node:os";
2
1
  import path from "node:path";
2
+ import { resolvePreferredPoolbotTmpDir } from "../infra/tmp-poolbot-dir.js";
3
3
  import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
4
4
  import { resolveStateDir } from "../config/paths.js";
5
5
  function buildMediaLocalRoots(stateDir) {
6
6
  const resolvedStateDir = path.resolve(stateDir);
7
+ const preferredTmpDir = resolvePreferredPoolbotTmpDir();
7
8
  return [
8
- os.tmpdir(),
9
+ preferredTmpDir,
9
10
  path.join(resolvedStateDir, "media"),
10
11
  path.join(resolvedStateDir, "agents"),
11
12
  path.join(resolvedStateDir, "workspace"),
@@ -315,7 +315,10 @@ async function extractFileBlocks(params) {
315
315
  }
316
316
  const utf16Charset = resolveUtf16Charset(bufferResult?.buffer);
317
317
  const textSample = decodeTextSample(bufferResult?.buffer);
318
- const textLike = Boolean(utf16Charset) || looksLikeUtf8Text(bufferResult?.buffer);
318
+ // Do not coerce real PDFs into text/plain via printable-byte heuristics.
319
+ // PDFs have a dedicated extraction path in extractFileContentFromSource.
320
+ const allowTextHeuristic = normalizedRawMime !== "application/pdf";
321
+ const textLike = allowTextHeuristic && (Boolean(utf16Charset) || looksLikeUtf8Text(bufferResult?.buffer));
319
322
  const guessedDelimited = textLike ? guessDelimitedMime(textSample) : undefined;
320
323
  const textHint = forcedTextMimeResolved ?? guessedDelimited ?? (textLike ? "text/plain" : undefined);
321
324
  const mimeType = sanitizeMimeType(textHint ?? normalizeMimeType(rawMime));
@@ -1,26 +1,14 @@
1
1
  import { logVerbose, shouldLogVerbose } from "../globals.js";
2
+ import { runTasksWithConcurrency } from "../utils/run-with-concurrency.js";
2
3
  export async function runWithConcurrency(tasks, limit) {
3
- if (tasks.length === 0)
4
- return [];
5
- const resolvedLimit = Math.max(1, Math.min(limit, tasks.length));
6
- const results = Array.from({ length: tasks.length });
7
- let next = 0;
8
- const workers = Array.from({ length: resolvedLimit }, async () => {
9
- while (true) {
10
- const index = next;
11
- next += 1;
12
- if (index >= tasks.length)
13
- return;
14
- try {
15
- results[index] = await tasks[index]();
4
+ const { results } = await runTasksWithConcurrency({
5
+ tasks,
6
+ limit,
7
+ onTaskError(err) {
8
+ if (shouldLogVerbose()) {
9
+ logVerbose(`Media understanding task failed: ${String(err)}`);
16
10
  }
17
- catch (err) {
18
- if (shouldLogVerbose()) {
19
- logVerbose(`Media understanding task failed: ${String(err)}`);
20
- }
21
- }
22
- }
11
+ },
23
12
  });
24
- await Promise.allSettled(workers);
25
13
  return results;
26
14
  }