@poolzin/pool-bot 2026.2.25 → 2026.2.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. package/dist/acp/event-mapper.js +87 -22
  2. package/dist/acp/meta.js +12 -6
  3. package/dist/agents/agent-paths.js +8 -9
  4. package/dist/agents/agent-scope.js +7 -5
  5. package/dist/agents/auth-profiles/oauth.js +148 -64
  6. package/dist/agents/auth-profiles/session-override.js +13 -7
  7. package/dist/agents/bash-tools.exec-host-gateway.js +14 -4
  8. package/dist/agents/bash-tools.exec-runtime.js +2 -25
  9. package/dist/agents/bedrock-discovery.js +3 -1
  10. package/dist/agents/byteplus-models.js +97 -0
  11. package/dist/agents/chutes-oauth.js +1 -0
  12. package/dist/agents/cli-runner/helpers.js +4 -0
  13. package/dist/agents/compaction.js +41 -14
  14. package/dist/agents/doubao-models.js +121 -0
  15. package/dist/agents/failover-error.js +2 -0
  16. package/dist/agents/huggingface-models.js +5 -3
  17. package/dist/agents/live-model-filter.js +5 -0
  18. package/dist/agents/minimax-vlm.js +10 -8
  19. package/dist/agents/model-auth.js +6 -0
  20. package/dist/agents/model-catalog.js +3 -1
  21. package/dist/agents/model-selection.js +7 -1
  22. package/dist/agents/models-config.providers.js +93 -11
  23. package/dist/agents/ollama-stream.js +117 -4
  24. package/dist/agents/opencode-zen-models.js +22 -11
  25. package/dist/agents/pi-embedded-helpers/errors.js +55 -33
  26. package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
  27. package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
  28. package/dist/agents/pi-embedded-helpers.js +1 -1
  29. package/dist/agents/pi-embedded-runner/compact.js +29 -7
  30. package/dist/agents/pi-embedded-runner/extensions.js +28 -26
  31. package/dist/agents/pi-embedded-runner/google.js +20 -8
  32. package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
  33. package/dist/agents/pi-embedded-runner/run.js +71 -12
  34. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
  35. package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
  36. package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
  37. package/dist/agents/pi-embedded-runner/thinking.js +42 -0
  38. package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
  39. package/dist/agents/pi-embedded-runner/utils.js +7 -10
  40. package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
  41. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
  42. package/dist/agents/pi-embedded-subscribe.js +9 -4
  43. package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
  44. package/dist/agents/pi-embedded-utils.js +3 -0
  45. package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
  46. package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
  47. package/dist/agents/pi-settings.js +40 -0
  48. package/dist/agents/pi-tools.policy.js +2 -1
  49. package/dist/agents/provider/config-loader.js +1 -1
  50. package/dist/agents/sandbox/browser.js +170 -33
  51. package/dist/agents/sandbox/config-hash.js +14 -27
  52. package/dist/agents/sandbox/config.js +21 -2
  53. package/dist/agents/sandbox/constants.js +2 -0
  54. package/dist/agents/sandbox/docker.js +16 -2
  55. package/dist/agents/sandbox/novnc-auth.js +62 -0
  56. package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
  57. package/dist/agents/sandbox/shared.js +10 -6
  58. package/dist/agents/sandbox-paths.js +24 -11
  59. package/dist/agents/schema/clean-for-gemini.js +132 -85
  60. package/dist/agents/session-slug.js +10 -5
  61. package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
  62. package/dist/agents/session-tool-result-guard.js +3 -1
  63. package/dist/agents/session-transcript-repair.js +40 -6
  64. package/dist/agents/skills/bundled-dir.js +19 -5
  65. package/dist/agents/skills/env-overrides.js +124 -43
  66. package/dist/agents/skills/frontmatter.js +6 -6
  67. package/dist/agents/skills/plugin-skills.js +14 -7
  68. package/dist/agents/skills/workspace.js +1 -0
  69. package/dist/agents/subagent-announce.js +251 -49
  70. package/dist/agents/subagent-lifecycle-events.js +19 -0
  71. package/dist/agents/subagent-registry-cleanup.js +31 -0
  72. package/dist/agents/subagent-registry-completion.js +68 -0
  73. package/dist/agents/subagent-registry-queries.js +117 -0
  74. package/dist/agents/subagent-registry-state.js +46 -0
  75. package/dist/agents/subagent-registry.js +252 -221
  76. package/dist/agents/subagent-registry.store.js +1 -0
  77. package/dist/agents/subagent-registry.types.js +1 -0
  78. package/dist/agents/subagent-spawn.js +195 -7
  79. package/dist/agents/system-prompt.js +22 -6
  80. package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
  81. package/dist/agents/test-helpers/fast-core-tools.js +1 -17
  82. package/dist/agents/timeout.js +18 -6
  83. package/dist/agents/tool-call-id.js +1 -1
  84. package/dist/agents/tool-display-common.js +162 -29
  85. package/dist/agents/tool-images.js +82 -9
  86. package/dist/agents/tool-policy.js +51 -26
  87. package/dist/agents/tools/browser-tool.js +2 -2
  88. package/dist/agents/tools/canvas-tool.js +27 -1
  89. package/dist/agents/tools/common.js +45 -0
  90. package/dist/agents/tools/discord-actions-guild.js +4 -1
  91. package/dist/agents/tools/gateway-tool.js +3 -1
  92. package/dist/agents/tools/nodes-utils.js +1 -10
  93. package/dist/agents/tools/sessions-send-helpers.js +12 -6
  94. package/dist/agents/tools/sessions-spawn-tool.js +8 -2
  95. package/dist/agents/tools/subagents-tool.js +2 -1
  96. package/dist/agents/tools/whatsapp-actions.js +10 -2
  97. package/dist/agents/tools/whatsapp-target-auth.js +18 -0
  98. package/dist/agents/transcript-policy.js +22 -8
  99. package/dist/agents/venice-models.js +11 -3
  100. package/dist/auto-reply/commands-registry.data.js +51 -0
  101. package/dist/auto-reply/commands-registry.js +4 -3
  102. package/dist/auto-reply/group-activation.js +10 -5
  103. package/dist/auto-reply/inbound-debounce.js +10 -5
  104. package/dist/auto-reply/reply/abort.js +1 -1
  105. package/dist/auto-reply/reply/agent-runner-execution.js +4 -1
  106. package/dist/auto-reply/reply/bash-command.js +41 -39
  107. package/dist/auto-reply/reply/command-gates.js +25 -0
  108. package/dist/auto-reply/reply/commands-allowlist.js +111 -72
  109. package/dist/auto-reply/reply/commands-bash.js +6 -5
  110. package/dist/auto-reply/reply/commands-config.js +30 -28
  111. package/dist/auto-reply/reply/commands-core.js +2 -1
  112. package/dist/auto-reply/reply/commands-info.js +1 -0
  113. package/dist/auto-reply/reply/commands-models.js +65 -14
  114. package/dist/auto-reply/reply/commands-session.js +237 -82
  115. package/dist/auto-reply/reply/commands-setunset.js +45 -0
  116. package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
  117. package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
  118. package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
  119. package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
  120. package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
  121. package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
  122. package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
  123. package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
  124. package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
  125. package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
  126. package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
  127. package/dist/auto-reply/reply/commands-subagents.js +51 -587
  128. package/dist/auto-reply/reply/commands-tts.js +10 -5
  129. package/dist/auto-reply/reply/config-value.js +10 -5
  130. package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
  131. package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
  132. package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
  133. package/dist/auto-reply/reply/followup-runner.js +1 -0
  134. package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
  135. package/dist/auto-reply/reply/get-reply-directives.js +17 -28
  136. package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
  137. package/dist/auto-reply/reply/get-reply.js +71 -12
  138. package/dist/auto-reply/reply/model-selection.js +80 -39
  139. package/dist/auto-reply/reply/queue/enqueue.js +10 -5
  140. package/dist/auto-reply/reply/queue/state.js +13 -12
  141. package/dist/auto-reply/reply/reply-payloads.js +67 -36
  142. package/dist/auto-reply/reply/reply-reference.js +9 -8
  143. package/dist/auto-reply/reply/route-reply.js +15 -8
  144. package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
  145. package/dist/auto-reply/reply/session.js +22 -6
  146. package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
  147. package/dist/auto-reply/reply/subagents-utils.js +56 -30
  148. package/dist/auto-reply/reply/typing.js +46 -21
  149. package/dist/auto-reply/send-policy.js +14 -7
  150. package/dist/auto-reply/status.js +140 -16
  151. package/dist/auto-reply/templating.js +10 -5
  152. package/dist/auto-reply/thinking.js +7 -16
  153. package/dist/auto-reply/tokens.js +21 -5
  154. package/dist/browser/bridge-server.js +36 -20
  155. package/dist/browser/cdp.helpers.js +7 -14
  156. package/dist/browser/cdp.js +35 -15
  157. package/dist/browser/chrome.profile-decoration.js +7 -4
  158. package/dist/browser/config.js +4 -0
  159. package/dist/browser/extension-relay-auth.js +55 -0
  160. package/dist/browser/extension-relay.js +74 -29
  161. package/dist/browser/navigation-guard.js +9 -1
  162. package/dist/browser/paths.js +77 -0
  163. package/dist/browser/profiles.js +13 -8
  164. package/dist/browser/pw-ai-module.js +10 -5
  165. package/dist/browser/pw-session.js +76 -39
  166. package/dist/browser/pw-tools-core.interactions.js +14 -7
  167. package/dist/browser/pw-tools-core.state.js +12 -6
  168. package/dist/browser/routes/agent.act.js +2 -2
  169. package/dist/browser/server-context.js +7 -0
  170. package/dist/build-info.json +3 -3
  171. package/dist/channels/allow-from.js +2 -1
  172. package/dist/channels/allowlists/resolve-utils.js +43 -19
  173. package/dist/channels/channel-config.js +14 -7
  174. package/dist/channels/draft-stream-loop.js +7 -0
  175. package/dist/channels/model-overrides.js +82 -0
  176. package/dist/channels/plugins/normalize/imessage.js +14 -7
  177. package/dist/channels/plugins/normalize/slack.js +10 -5
  178. package/dist/channels/plugins/normalize/telegram.js +14 -7
  179. package/dist/channels/plugins/outbound/discord.js +80 -8
  180. package/dist/channels/plugins/outbound/signal.js +11 -11
  181. package/dist/channels/plugins/setup-helpers.js +10 -5
  182. package/dist/channels/sender-label.js +14 -7
  183. package/dist/channels/session.js +4 -2
  184. package/dist/channels/status-reactions.js +297 -0
  185. package/dist/cli/banner.js +1 -1
  186. package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
  187. package/dist/cli/cli-name.js +11 -11
  188. package/dist/cli/cli-utils.js +13 -3
  189. package/dist/cli/command-format.js +1 -1
  190. package/dist/cli/config-cli.js +1 -1
  191. package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
  192. package/dist/cli/daemon-cli/lifecycle.js +64 -2
  193. package/dist/cli/daemon-cli/restart-health.js +126 -0
  194. package/dist/cli/daemon-cli/status.gather.js +9 -13
  195. package/dist/cli/daemon-cli/status.print.js +2 -10
  196. package/dist/cli/deps.js +27 -22
  197. package/dist/cli/gateway-cli/run-loop.js +23 -5
  198. package/dist/cli/node-cli/register.js +14 -5
  199. package/dist/cli/nodes-media-utils.js +7 -2
  200. package/dist/cli/outbound-send-deps.js +2 -9
  201. package/dist/cli/outbound-send-mapping.js +11 -0
  202. package/dist/cli/pairing-cli.js +40 -14
  203. package/dist/cli/plugins-cli.js +34 -41
  204. package/dist/cli/ports.js +11 -10
  205. package/dist/cli/program/command-registry.js +2 -11
  206. package/dist/cli/program/command-tree.js +16 -0
  207. package/dist/cli/program/preaction.js +13 -9
  208. package/dist/cli/program/register.configure.js +3 -18
  209. package/dist/cli/program/register.maintenance.js +2 -2
  210. package/dist/cli/program/register.onboard.js +2 -0
  211. package/dist/cli/program/register.status-health-sessions.js +16 -17
  212. package/dist/cli/program/register.subclis.js +93 -52
  213. package/dist/cli/route.js +11 -7
  214. package/dist/cli/system-cli.js +36 -46
  215. package/dist/cli/update-cli/shared.js +22 -9
  216. package/dist/cli/update-cli/update-command.js +89 -14
  217. package/dist/cli/update-cli/wizard.js +6 -12
  218. package/dist/commands/agent/run-context.js +18 -5
  219. package/dist/commands/agent/session-store.js +17 -4
  220. package/dist/commands/agent.js +22 -2
  221. package/dist/commands/agents.bindings.js +14 -7
  222. package/dist/commands/agents.commands.add.js +13 -9
  223. package/dist/commands/agents.commands.identity.js +12 -6
  224. package/dist/commands/agents.commands.list.js +11 -6
  225. package/dist/commands/agents.config.js +8 -10
  226. package/dist/commands/agents.providers.js +12 -6
  227. package/dist/commands/auth-choice-options.js +103 -75
  228. package/dist/commands/auth-choice.apply.byteplus.js +55 -0
  229. package/dist/commands/auth-choice.apply.js +4 -0
  230. package/dist/commands/auth-choice.apply.minimax.js +61 -13
  231. package/dist/commands/auth-choice.apply.openai.js +3 -1
  232. package/dist/commands/auth-choice.apply.volcengine.js +55 -0
  233. package/dist/commands/auth-choice.preferred-provider.js +2 -0
  234. package/dist/commands/channels/remove.js +13 -6
  235. package/dist/commands/channels/shared.js +4 -14
  236. package/dist/commands/configure.commands.js +14 -0
  237. package/dist/commands/configure.gateway.js +2 -4
  238. package/dist/commands/configure.js +1 -1
  239. package/dist/commands/configure.shared.js +11 -0
  240. package/dist/commands/daemon-install-helpers.js +2 -2
  241. package/dist/commands/dashboard.js +12 -10
  242. package/dist/commands/docs.js +14 -8
  243. package/dist/commands/doctor-config-flow.js +11 -9
  244. package/dist/commands/doctor-legacy-config.js +281 -0
  245. package/dist/commands/doctor-state-integrity.js +99 -23
  246. package/dist/commands/doctor-update.js +12 -9
  247. package/dist/commands/models/list.list-command.js +7 -5
  248. package/dist/commands/models/set-image.js +2 -21
  249. package/dist/commands/node-daemon-install-helpers.js +10 -8
  250. package/dist/commands/onboard-auth.config-minimax.js +54 -80
  251. package/dist/commands/onboard-auth.config-opencode.js +2 -18
  252. package/dist/commands/onboard-auth.credentials.js +90 -13
  253. package/dist/commands/onboard-auth.js +1 -1
  254. package/dist/commands/onboard-auth.models.js +6 -5
  255. package/dist/commands/onboard-hooks.js +1 -1
  256. package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
  257. package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
  258. package/dist/commands/onboard-provider-auth-flags.js +14 -0
  259. package/dist/commands/onboard-remote.js +14 -7
  260. package/dist/commands/onboard.js +11 -13
  261. package/dist/commands/sandbox-display.js +6 -5
  262. package/dist/commands/status-all/diagnosis.js +14 -10
  263. package/dist/commands/status-all/format.js +1 -0
  264. package/dist/commands/status.gateway-probe.js +1 -16
  265. package/dist/commands/systemd-linger.js +12 -6
  266. package/dist/config/agent-limits.js +2 -0
  267. package/dist/config/commands.js +30 -16
  268. package/dist/config/config-paths.js +9 -11
  269. package/dist/config/defaults.js +22 -2
  270. package/dist/config/discord-preview-streaming.js +104 -0
  271. package/dist/config/env-vars.js +37 -8
  272. package/dist/config/includes.js +4 -0
  273. package/dist/config/io.js +97 -12
  274. package/dist/config/legacy.migrations.part-1.js +189 -78
  275. package/dist/config/legacy.shared.js +3 -1
  276. package/dist/config/merge-patch.js +4 -0
  277. package/dist/config/prototype-keys.js +4 -0
  278. package/dist/config/schema.help.js +44 -7
  279. package/dist/config/schema.labels.js +38 -6
  280. package/dist/config/sessions/delivery-info.js +10 -3
  281. package/dist/config/sessions/main-session.js +10 -5
  282. package/dist/config/sessions/session-file.js +33 -0
  283. package/dist/config/sessions/session-key.js +10 -5
  284. package/dist/config/sessions/store.js +1 -1
  285. package/dist/config/sessions.js +1 -0
  286. package/dist/config/zod-schema.agent-runtime.js +11 -0
  287. package/dist/config/zod-schema.js +148 -13
  288. package/dist/config/zod-schema.providers-core.js +78 -4
  289. package/dist/config/zod-schema.providers.js +6 -1
  290. package/dist/config/zod-schema.session.js +41 -2
  291. package/dist/cron/run-log.js +3 -0
  292. package/dist/cron/schedule.js +21 -10
  293. package/dist/cron/service/ops.js +35 -21
  294. package/dist/cron/service/timer.js +116 -16
  295. package/dist/cron/stagger.js +3 -1
  296. package/dist/discord/api.js +12 -6
  297. package/dist/discord/draft-chunking.js +22 -0
  298. package/dist/discord/draft-stream.js +124 -0
  299. package/dist/discord/monitor/agent-components.js +1 -1
  300. package/dist/discord/monitor/commands.js +5 -0
  301. package/dist/discord/monitor/gateway-plugin.js +2 -1
  302. package/dist/discord/monitor/listeners.js +37 -27
  303. package/dist/discord/monitor/message-handler.js +4 -1
  304. package/dist/discord/monitor/message-handler.preflight.js +65 -8
  305. package/dist/discord/monitor/message-handler.process.js +246 -217
  306. package/dist/discord/monitor/message-utils.js +143 -6
  307. package/dist/discord/monitor/model-picker-preferences.js +143 -0
  308. package/dist/discord/monitor/model-picker.js +651 -0
  309. package/dist/discord/monitor/native-command.js +573 -16
  310. package/dist/discord/monitor/provider.allowlist.js +223 -0
  311. package/dist/discord/monitor/provider.js +275 -347
  312. package/dist/discord/monitor/provider.lifecycle.js +100 -0
  313. package/dist/discord/monitor/reply-delivery.js +123 -16
  314. package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
  315. package/dist/discord/monitor/thread-bindings.js +4 -0
  316. package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
  317. package/dist/discord/monitor/thread-bindings.manager.js +423 -0
  318. package/dist/discord/monitor/thread-bindings.messages.js +55 -0
  319. package/dist/discord/monitor/thread-bindings.state.js +358 -0
  320. package/dist/discord/monitor/thread-bindings.types.js +6 -0
  321. package/dist/discord/resolve-users.js +33 -21
  322. package/dist/discord/send.channels.js +15 -0
  323. package/dist/discord/send.js +3 -2
  324. package/dist/discord/send.outbound.js +82 -26
  325. package/dist/discord/send.permissions.js +83 -30
  326. package/dist/discord/send.reactions.js +8 -4
  327. package/dist/discord/token.js +10 -5
  328. package/dist/discord/voice/command.js +263 -0
  329. package/dist/discord/voice/manager.js +531 -0
  330. package/dist/gateway/auth.js +34 -10
  331. package/dist/gateway/call.js +4 -16
  332. package/dist/gateway/client.js +28 -4
  333. package/dist/gateway/config-reload.js +3 -4
  334. package/dist/gateway/control-ui.js +219 -96
  335. package/dist/gateway/hooks-mapping.js +88 -38
  336. package/dist/gateway/http-auth-helpers.js +3 -2
  337. package/dist/gateway/http-endpoint-helpers.js +1 -0
  338. package/dist/gateway/net.js +54 -12
  339. package/dist/gateway/node-invoke-system-run-approval.js +14 -35
  340. package/dist/gateway/node-registry.js +10 -5
  341. package/dist/gateway/openai-http.js +1 -0
  342. package/dist/gateway/openresponses-http.js +1 -0
  343. package/dist/gateway/origin-check.js +1 -18
  344. package/dist/gateway/protocol/index.js +4 -3
  345. package/dist/gateway/protocol/schema/cron.js +1 -0
  346. package/dist/gateway/protocol/schema/devices.js +1 -0
  347. package/dist/gateway/protocol/schema/protocol-schemas.js +2 -1
  348. package/dist/gateway/protocol/schema/sessions.js +6 -0
  349. package/dist/gateway/role-policy.js +17 -0
  350. package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
  351. package/dist/gateway/server/ws-connection/message-handler.js +175 -148
  352. package/dist/gateway/server-chat.js +83 -25
  353. package/dist/gateway/server-constants.js +10 -9
  354. package/dist/gateway/server-cron.js +1 -0
  355. package/dist/gateway/server-http.js +16 -7
  356. package/dist/gateway/server-maintenance.js +20 -5
  357. package/dist/gateway/server-methods/chat.js +10 -6
  358. package/dist/gateway/server-methods/config.js +12 -14
  359. package/dist/gateway/server-methods/devices.js +17 -3
  360. package/dist/gateway/server-methods/models.js +11 -1
  361. package/dist/gateway/server-methods/sessions.js +64 -8
  362. package/dist/gateway/server-methods/usage.js +162 -75
  363. package/dist/gateway/server-node-events.js +29 -0
  364. package/dist/gateway/server-runtime-config.js +34 -13
  365. package/dist/gateway/server-startup-memory.js +17 -11
  366. package/dist/gateway/session-utils.fs.js +32 -34
  367. package/dist/gateway/sessions-resolve.js +17 -5
  368. package/dist/gateway/test-helpers.openai-mock.js +14 -7
  369. package/dist/gateway/tools-invoke-http.js +21 -10
  370. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
  371. package/dist/hooks/bundled/command-logger/handler.js +7 -2
  372. package/dist/hooks/bundled/session-memory/handler.js +6 -5
  373. package/dist/hooks/frontmatter.js +6 -6
  374. package/dist/hooks/gmail-watcher.js +11 -6
  375. package/dist/hooks/internal-hooks.js +11 -1
  376. package/dist/hooks/llm-slug-generator.js +4 -1
  377. package/dist/hooks/workspace.js +47 -17
  378. package/dist/imessage/accounts.js +9 -20
  379. package/dist/imessage/monitor/inbound-processing.js +2 -1
  380. package/dist/infra/archive.js +174 -73
  381. package/dist/infra/control-ui-assets.js +14 -6
  382. package/dist/infra/device-pairing.js +108 -29
  383. package/dist/infra/env.js +10 -5
  384. package/dist/infra/exec-approvals-allowlist.js +122 -0
  385. package/dist/infra/exec-approvals-analysis.js +34 -3
  386. package/dist/infra/exec-approvals.js +5 -17
  387. package/dist/infra/exec-safe-bin-policy.js +53 -45
  388. package/dist/infra/fs-safe.js +71 -39
  389. package/dist/infra/gateway-lock.js +6 -2
  390. package/dist/infra/heartbeat-wake.js +6 -12
  391. package/dist/infra/host-env-security-policy.json +19 -0
  392. package/dist/infra/host-env-security.js +66 -0
  393. package/dist/infra/net/ssrf.js +131 -38
  394. package/dist/infra/outbound/bound-delivery-router.js +88 -0
  395. package/dist/infra/outbound/channel-selection.js +12 -6
  396. package/dist/infra/outbound/envelope.js +1 -1
  397. package/dist/infra/outbound/format.js +12 -6
  398. package/dist/infra/outbound/payloads.js +14 -7
  399. package/dist/infra/outbound/session-binding-service.js +123 -0
  400. package/dist/infra/path-guards.js +25 -0
  401. package/dist/infra/provider-usage.fetch.codex.js +7 -15
  402. package/dist/infra/provider-usage.fetch.gemini.js +14 -11
  403. package/dist/infra/provider-usage.fetch.shared.js +30 -1
  404. package/dist/infra/provider-usage.fetch.zai.js +10 -9
  405. package/dist/infra/retry-policy.js +4 -2
  406. package/dist/infra/retry.js +9 -5
  407. package/dist/infra/session-cost-usage.js +107 -59
  408. package/dist/infra/session-maintenance-warning.js +3 -1
  409. package/dist/infra/shell-env.js +98 -34
  410. package/dist/infra/ssh-config.js +12 -6
  411. package/dist/infra/system-run-command.js +49 -4
  412. package/dist/infra/update-channels.js +10 -5
  413. package/dist/line/accounts.js +5 -7
  414. package/dist/line/bot-access.js +8 -20
  415. package/dist/line/bot-handlers.js +3 -1
  416. package/dist/link-understanding/detect.js +15 -7
  417. package/dist/media/constants.js +15 -6
  418. package/dist/media/image-ops.js +7 -0
  419. package/dist/media/local-roots.js +3 -2
  420. package/dist/media-understanding/apply.js +4 -1
  421. package/dist/media-understanding/concurrency.js +8 -20
  422. package/dist/memory/backend-config.js +45 -6
  423. package/dist/memory/embeddings.js +10 -4
  424. package/dist/memory/fs-utils.js +23 -0
  425. package/dist/memory/manager-search.js +12 -6
  426. package/dist/memory/manager-sync-ops.js +12 -2
  427. package/dist/memory/qmd-manager.js +466 -53
  428. package/dist/memory/query-expansion.js +167 -3
  429. package/dist/memory/status-format.js +10 -5
  430. package/dist/memory/sync-memory-files.js +1 -1
  431. package/dist/node-host/invoke-system-run.js +281 -0
  432. package/dist/node-host/invoke.js +55 -337
  433. package/dist/pairing/pairing-store.js +22 -0
  434. package/dist/plugin-sdk/allow-from.js +1 -1
  435. package/dist/plugin-sdk/command-auth.js +3 -1
  436. package/dist/plugin-sdk/index.js +6 -3
  437. package/dist/plugin-sdk/webhook-targets.js +32 -0
  438. package/dist/plugins/bundled-dir.js +9 -6
  439. package/dist/plugins/hooks.js +50 -0
  440. package/dist/plugins/install.js +28 -16
  441. package/dist/plugins/runtime.js +3 -17
  442. package/dist/plugins/update.js +78 -12
  443. package/dist/process/spawn-utils.js +14 -7
  444. package/dist/providers/github-copilot-token.js +11 -6
  445. package/dist/providers/qwen-portal-oauth.js +14 -6
  446. package/dist/routing/account-id.js +30 -0
  447. package/dist/routing/resolve-route.js +3 -7
  448. package/dist/routing/session-key.js +2 -16
  449. package/dist/security/audit-channel.js +93 -2
  450. package/dist/security/audit-extra.async.js +159 -5
  451. package/dist/security/audit-extra.js +1 -1
  452. package/dist/security/audit-extra.sync.js +85 -6
  453. package/dist/security/audit.js +40 -4
  454. package/dist/security/dm-policy-shared.js +44 -0
  455. package/dist/security/external-content.js +26 -6
  456. package/dist/shared/entry-status.js +6 -0
  457. package/dist/shared/frontmatter.js +5 -5
  458. package/dist/shared/node-match.js +11 -4
  459. package/dist/shared/operator-scope-compat.js +8 -3
  460. package/dist/signal/accounts.js +7 -20
  461. package/dist/signal/monitor/event-handler.js +3 -1
  462. package/dist/slack/accounts.js +6 -19
  463. package/dist/slack/actions.js +11 -3
  464. package/dist/slack/monitor/auth.js +1 -1
  465. package/dist/slack/monitor/message-handler/dispatch.js +50 -29
  466. package/dist/slack/monitor/replies.js +15 -7
  467. package/dist/slack/monitor/slash.js +22 -13
  468. package/dist/slack/resolve-channels.js +10 -5
  469. package/dist/slack/send.js +102 -12
  470. package/dist/slack/stream-mode.js +10 -0
  471. package/dist/slack/streaming.js +4 -2
  472. package/dist/telegram/accounts.js +19 -14
  473. package/dist/telegram/bot/helpers.js +3 -5
  474. package/dist/telegram/bot-access.js +35 -36
  475. package/dist/telegram/bot-handlers.js +120 -148
  476. package/dist/telegram/bot-message-context.js +68 -9
  477. package/dist/telegram/bot-message-dispatch.js +155 -90
  478. package/dist/telegram/bot-native-commands.js +16 -0
  479. package/dist/telegram/draft-stream.js +14 -1
  480. package/dist/telegram/inline-buttons.js +5 -15
  481. package/dist/telegram/monitor.js +11 -7
  482. package/dist/telegram/network-config.js +19 -7
  483. package/dist/telegram/send.js +3 -2
  484. package/dist/telegram/sent-message-cache.js +5 -6
  485. package/dist/telegram/status-reaction-variants.js +208 -0
  486. package/dist/telegram/sticker-cache.js +11 -9
  487. package/dist/terminal/theme.js +12 -12
  488. package/dist/tts/tts.js +80 -567
  489. package/dist/tui/components/chat-log.js +41 -8
  490. package/dist/tui/theme/theme.js +10 -12
  491. package/dist/tui/tui-local-shell.js +16 -6
  492. package/dist/tui/tui.js +58 -6
  493. package/dist/utils/account-id.js +2 -4
  494. package/dist/utils/boolean.js +10 -5
  495. package/dist/utils/directive-tags.js +11 -0
  496. package/dist/utils/queue-helpers.js +67 -12
  497. package/dist/web/auto-reply/deliver-reply.js +8 -4
  498. package/dist/web/auto-reply/mentions.js +10 -5
  499. package/dist/web/auto-reply/monitor/group-members.js +14 -7
  500. package/dist/web/auto-reply/monitor/process-message.js +45 -24
  501. package/dist/web/inbound/access-control.js +5 -2
  502. package/dist/web/login-qr.js +12 -6
  503. package/dist/web/media.js +123 -16
  504. package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
  505. package/extensions/bluebubbles/src/monitor.ts +208 -1950
  506. package/package.json +1 -1
@@ -1,26 +1,100 @@
1
1
  import { execFileSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
2
4
  import { isTruthyEnvValue } from "./env.js";
3
5
  const DEFAULT_TIMEOUT_MS = 15_000;
4
6
  const DEFAULT_MAX_BUFFER_BYTES = 2 * 1024 * 1024;
7
+ const DEFAULT_SHELL = "/bin/sh";
8
+ const TRUSTED_SHELL_PREFIXES = [
9
+ "/bin/",
10
+ "/usr/bin/",
11
+ "/usr/local/bin/",
12
+ "/opt/homebrew/bin/",
13
+ "/run/current-system/sw/bin/",
14
+ ];
5
15
  let lastAppliedKeys = [];
6
16
  let cachedShellPath;
17
+ let cachedEtcShells;
18
+ function resolveTimeoutMs(timeoutMs) {
19
+ if (typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs)) {
20
+ return DEFAULT_TIMEOUT_MS;
21
+ }
22
+ return Math.max(0, timeoutMs);
23
+ }
24
+ function readEtcShells() {
25
+ if (cachedEtcShells !== undefined) {
26
+ return cachedEtcShells;
27
+ }
28
+ try {
29
+ const raw = fs.readFileSync("/etc/shells", "utf8");
30
+ const entries = raw
31
+ .split(/\r?\n/)
32
+ .map((line) => line.trim())
33
+ .filter((line) => line.length > 0 && !line.startsWith("#") && path.isAbsolute(line));
34
+ cachedEtcShells = new Set(entries);
35
+ }
36
+ catch {
37
+ cachedEtcShells = null;
38
+ }
39
+ return cachedEtcShells;
40
+ }
41
+ function isTrustedShellPath(shell) {
42
+ if (!path.isAbsolute(shell)) {
43
+ return false;
44
+ }
45
+ const normalized = path.normalize(shell);
46
+ if (normalized !== shell) {
47
+ return false;
48
+ }
49
+ // Primary trust anchor: shell registered in /etc/shells.
50
+ const registeredShells = readEtcShells();
51
+ if (registeredShells?.has(shell)) {
52
+ return true;
53
+ }
54
+ // Fallback for environments where /etc/shells is incomplete/unavailable.
55
+ if (!TRUSTED_SHELL_PREFIXES.some((prefix) => shell.startsWith(prefix))) {
56
+ return false;
57
+ }
58
+ try {
59
+ fs.accessSync(shell, fs.constants.X_OK);
60
+ return true;
61
+ }
62
+ catch {
63
+ return false;
64
+ }
65
+ }
7
66
  function resolveShell(env) {
8
67
  const shell = env.SHELL?.trim();
9
- return shell && shell.length > 0 ? shell : "/bin/sh";
68
+ if (shell && isTrustedShellPath(shell)) {
69
+ return shell;
70
+ }
71
+ return DEFAULT_SHELL;
72
+ }
73
+ function execLoginShellEnvZero(params) {
74
+ return params.exec(params.shell, ["-l", "-c", "env -0"], {
75
+ encoding: "buffer",
76
+ timeout: params.timeoutMs,
77
+ maxBuffer: DEFAULT_MAX_BUFFER_BYTES,
78
+ env: params.env,
79
+ stdio: ["ignore", "pipe", "pipe"],
80
+ });
10
81
  }
11
82
  function parseShellEnv(stdout) {
12
83
  const shellEnv = new Map();
13
84
  const parts = stdout.toString("utf8").split("\0");
14
85
  for (const part of parts) {
15
- if (!part)
86
+ if (!part) {
16
87
  continue;
88
+ }
17
89
  const eq = part.indexOf("=");
18
- if (eq <= 0)
90
+ if (eq <= 0) {
19
91
  continue;
92
+ }
20
93
  const key = part.slice(0, eq);
21
94
  const value = part.slice(eq + 1);
22
- if (!key)
95
+ if (!key) {
23
96
  continue;
97
+ }
24
98
  shellEnv.set(key, value);
25
99
  }
26
100
  return shellEnv;
@@ -37,19 +111,11 @@ export function loadShellEnvFallback(opts) {
37
111
  lastAppliedKeys = [];
38
112
  return { ok: true, applied: [], skippedReason: "already-has-keys" };
39
113
  }
40
- const timeoutMs = typeof opts.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
41
- ? Math.max(0, opts.timeoutMs)
42
- : DEFAULT_TIMEOUT_MS;
114
+ const timeoutMs = resolveTimeoutMs(opts.timeoutMs);
43
115
  const shell = resolveShell(opts.env);
44
116
  let stdout;
45
117
  try {
46
- stdout = exec(shell, ["-l", "-c", "env -0"], {
47
- encoding: "buffer",
48
- timeout: timeoutMs,
49
- maxBuffer: DEFAULT_MAX_BUFFER_BYTES,
50
- env: opts.env,
51
- stdio: ["ignore", "pipe", "pipe"],
52
- });
118
+ stdout = execLoginShellEnvZero({ shell, env: opts.env, exec, timeoutMs });
53
119
  }
54
120
  catch (err) {
55
121
  const msg = err instanceof Error ? err.message : String(err);
@@ -60,11 +126,13 @@ export function loadShellEnvFallback(opts) {
60
126
  const shellEnv = parseShellEnv(stdout);
61
127
  const applied = [];
62
128
  for (const key of opts.expectedKeys) {
63
- if (opts.env[key]?.trim())
129
+ if (opts.env[key]?.trim()) {
64
130
  continue;
131
+ }
65
132
  const value = shellEnv.get(key);
66
- if (!value?.trim())
133
+ if (!value?.trim()) {
67
134
  continue;
135
+ }
68
136
  opts.env[key] = value;
69
137
  applied.push(key);
70
138
  }
@@ -72,42 +140,37 @@ export function loadShellEnvFallback(opts) {
72
140
  return { ok: true, applied };
73
141
  }
74
142
  export function shouldEnableShellEnvFallback(env) {
75
- return (isTruthyEnvValue(env.POOLBOT_LOAD_SHELL_ENV) || isTruthyEnvValue(env.CLAWDBOT_LOAD_SHELL_ENV));
143
+ return isTruthyEnvValue(env.POOLBOT_LOAD_SHELL_ENV);
76
144
  }
77
145
  export function shouldDeferShellEnvFallback(env) {
78
- return (isTruthyEnvValue(env.POOLBOT_DEFER_SHELL_ENV_FALLBACK) ||
79
- isTruthyEnvValue(env.CLAWDBOT_DEFER_SHELL_ENV_FALLBACK));
146
+ return isTruthyEnvValue(env.POOLBOT_DEFER_SHELL_ENV_FALLBACK);
80
147
  }
81
148
  export function resolveShellEnvFallbackTimeoutMs(env) {
82
- const raw = env.POOLBOT_SHELL_ENV_TIMEOUT_MS?.trim() || env.CLAWDBOT_SHELL_ENV_TIMEOUT_MS?.trim();
83
- if (!raw)
149
+ const raw = env.POOLBOT_SHELL_ENV_TIMEOUT_MS?.trim();
150
+ if (!raw) {
84
151
  return DEFAULT_TIMEOUT_MS;
152
+ }
85
153
  const parsed = Number.parseInt(raw, 10);
86
- if (!Number.isFinite(parsed))
154
+ if (!Number.isFinite(parsed)) {
87
155
  return DEFAULT_TIMEOUT_MS;
156
+ }
88
157
  return Math.max(0, parsed);
89
158
  }
90
159
  export function getShellPathFromLoginShell(opts) {
91
- if (cachedShellPath !== undefined)
160
+ if (cachedShellPath !== undefined) {
92
161
  return cachedShellPath;
93
- if (process.platform === "win32") {
162
+ }
163
+ const platform = opts.platform ?? process.platform;
164
+ if (platform === "win32") {
94
165
  cachedShellPath = null;
95
166
  return cachedShellPath;
96
167
  }
97
168
  const exec = opts.exec ?? execFileSync;
98
- const timeoutMs = typeof opts.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
99
- ? Math.max(0, opts.timeoutMs)
100
- : DEFAULT_TIMEOUT_MS;
169
+ const timeoutMs = resolveTimeoutMs(opts.timeoutMs);
101
170
  const shell = resolveShell(opts.env);
102
171
  let stdout;
103
172
  try {
104
- stdout = exec(shell, ["-l", "-c", "env -0"], {
105
- encoding: "buffer",
106
- timeout: timeoutMs,
107
- maxBuffer: DEFAULT_MAX_BUFFER_BYTES,
108
- env: opts.env,
109
- stdio: ["ignore", "pipe", "pipe"],
110
- });
173
+ stdout = execLoginShellEnvZero({ shell, env: opts.env, exec, timeoutMs });
111
174
  }
112
175
  catch {
113
176
  cachedShellPath = null;
@@ -120,6 +183,7 @@ export function getShellPathFromLoginShell(opts) {
120
183
  }
121
184
  export function resetShellPathCacheForTests() {
122
185
  cachedShellPath = undefined;
186
+ cachedEtcShells = undefined;
123
187
  }
124
188
  export function getShellEnvAppliedKeys() {
125
189
  return [...lastAppliedKeys];
@@ -1,10 +1,12 @@
1
1
  import { spawn } from "node:child_process";
2
2
  function parsePort(value) {
3
- if (!value)
3
+ if (!value) {
4
4
  return undefined;
5
+ }
5
6
  const parsed = Number.parseInt(value, 10);
6
- if (!Number.isFinite(parsed) || parsed <= 0)
7
+ if (!Number.isFinite(parsed) || parsed <= 0) {
7
8
  return undefined;
9
+ }
8
10
  return parsed;
9
11
  }
10
12
  export function parseSshConfigOutput(output) {
@@ -12,12 +14,14 @@ export function parseSshConfigOutput(output) {
12
14
  const lines = output.split("\n");
13
15
  for (const raw of lines) {
14
16
  const line = raw.trim();
15
- if (!line)
17
+ if (!line) {
16
18
  continue;
19
+ }
17
20
  const [key, ...rest] = line.split(/\s+/);
18
21
  const value = rest.join(" ").trim();
19
- if (!key || !value)
22
+ if (!key || !value) {
20
23
  continue;
24
+ }
21
25
  switch (key) {
22
26
  case "user":
23
27
  result.user = value;
@@ -29,8 +33,9 @@ export function parseSshConfigOutput(output) {
29
33
  result.port = parsePort(value);
30
34
  break;
31
35
  case "identityfile":
32
- if (value !== "none")
36
+ if (value !== "none") {
33
37
  result.identityFiles.push(value);
38
+ }
34
39
  break;
35
40
  default:
36
41
  break;
@@ -48,7 +53,8 @@ export async function resolveSshConfig(target, opts = {}) {
48
53
  args.push("-i", opts.identity.trim());
49
54
  }
50
55
  const userHost = target.user ? `${target.user}@${target.host}` : target.host;
51
- args.push(userHost);
56
+ // Use "--" so userHost can't be parsed as an ssh option.
57
+ args.push("--", userHost);
52
58
  return await new Promise((resolve) => {
53
59
  const child = spawn(sshPath, args, {
54
60
  stdio: ["ignore", "pipe", "ignore"],
@@ -45,8 +45,12 @@ export function extractShellCommandFromArgv(argv) {
45
45
  if (idx === -1) {
46
46
  return null;
47
47
  }
48
- const cmd = argv[idx + 1];
49
- return typeof cmd === "string" ? cmd : null;
48
+ const tail = argv.slice(idx + 1).map((item) => String(item));
49
+ if (tail.length === 0) {
50
+ return null;
51
+ }
52
+ const cmd = tail.join(" ").trim();
53
+ return cmd.length > 0 ? cmd : null;
50
54
  }
51
55
  return null;
52
56
  }
@@ -55,7 +59,7 @@ export function validateSystemRunCommandConsistency(params) {
55
59
  ? params.rawCommand.trim()
56
60
  : null;
57
61
  const shellCommand = extractShellCommandFromArgv(params.argv);
58
- const inferred = shellCommand ? shellCommand.trim() : formatExecCommand(params.argv);
62
+ const inferred = shellCommand !== null ? shellCommand.trim() : formatExecCommand(params.argv);
59
63
  if (raw && raw !== inferred) {
60
64
  return {
61
65
  ok: false,
@@ -72,7 +76,48 @@ export function validateSystemRunCommandConsistency(params) {
72
76
  // Only treat this as a shell command when argv is a recognized shell wrapper.
73
77
  // For direct argv execution, rawCommand is purely display/approval text and
74
78
  // must match the formatted argv.
75
- shellCommand: shellCommand ? (raw ?? shellCommand) : null,
79
+ shellCommand: shellCommand !== null ? (raw ?? shellCommand) : null,
76
80
  cmdText: raw ?? shellCommand ?? inferred,
77
81
  };
78
82
  }
83
+ export function resolveSystemRunCommand(params) {
84
+ const raw = typeof params.rawCommand === "string" && params.rawCommand.trim().length > 0
85
+ ? params.rawCommand.trim()
86
+ : null;
87
+ const command = Array.isArray(params.command) ? params.command : [];
88
+ if (command.length === 0) {
89
+ if (raw) {
90
+ return {
91
+ ok: false,
92
+ message: "rawCommand requires params.command",
93
+ details: { code: "MISSING_COMMAND" },
94
+ };
95
+ }
96
+ return {
97
+ ok: true,
98
+ argv: [],
99
+ rawCommand: null,
100
+ shellCommand: null,
101
+ cmdText: "",
102
+ };
103
+ }
104
+ const argv = command.map((v) => String(v));
105
+ const validation = validateSystemRunCommandConsistency({
106
+ argv,
107
+ rawCommand: raw,
108
+ });
109
+ if (!validation.ok) {
110
+ return {
111
+ ok: false,
112
+ message: validation.message,
113
+ details: validation.details ?? { code: "RAW_COMMAND_MISMATCH" },
114
+ };
115
+ }
116
+ return {
117
+ ok: true,
118
+ argv,
119
+ rawCommand: raw,
120
+ shellCommand: validation.shellCommand,
121
+ cmdText: validation.cmdText,
122
+ };
123
+ }
@@ -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,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
  }
@@ -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
  }