@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
package/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## v2026.2.25 (2026-02-22)
2
+
3
+ ### Features
4
+ - **Upstream Port (OpenClaw):** ported 26 files from OpenClaw upstream covering agents, auto-reply, browser, gateway, hooks, plugins, config, and CLI
5
+ - **Agent tooling:** sandbox filesystem bridge, host sandbox bridge helpers, workspace sandbox integration, model fallback provider updates (openai/gpt-4.1-mini default)
6
+ - **Auto-reply:** commands registry extensions, templating updates, agent runner execution improvements, verbose-gated session notices
7
+ - **Browser:** config updates, agent act/snapshot/storage routes, tabs route enhancements, form layout contract tests
8
+ - **Gateway:** hook token extraction with query-string fallback, normalized agent payload with auto-generated session keys, HTTP server integration
9
+ - **Plugins:** plugin discovery and loading aligned with upstream patterns
10
+ - **Config:** browser config, CLI config, and schema updates
11
+
12
+ ### Fixes
13
+ - **Tests:** fixed 9 pre-existing test failures across 6 test files (52 tests total)
14
+ - `model-fallback.test.ts`: updated expectations for openai/gpt-4.1-mini default
15
+ - `image-tool.test.ts`: aligned sandbox parameter structure with new bridge API
16
+ - `hooks.test.ts`: updated for new `extractHookToken` and `normalizeAgentPayload` signatures
17
+ - `poolbot-tools.sessions.test.ts`: added mock sessions.list handler for spawned sessions
18
+ - `reply.media-note.test.ts` / `reply.raw-body.test.ts`: verbose-gated session notice, rebranded env vars and paths
19
+
20
+ ---
21
+
1
22
  ## v2026.2.24 (2026-02-19)
2
23
 
3
24
  ### Fixes
@@ -1,11 +1,187 @@
1
1
  import { spawn } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
2
4
  import * as readline from "node:readline";
3
5
  import { Readable, Writable } from "node:stream";
6
+ import { fileURLToPath } from "node:url";
4
7
  import { ClientSideConnection, PROTOCOL_VERSION, ndJsonStream, } from "@agentclientprotocol/sdk";
5
8
  import { ensurePoolbotCliOnPath } from "../infra/path-env.js";
9
+ import { DANGEROUS_ACP_TOOLS } from "../security/dangerous-tools.js";
10
+ const SAFE_AUTO_APPROVE_KINDS = new Set(["read", "search"]);
11
+ function asRecord(value) {
12
+ return value && typeof value === "object" && !Array.isArray(value)
13
+ ? value
14
+ : undefined;
15
+ }
16
+ function readFirstStringValue(source, keys) {
17
+ if (!source) {
18
+ return undefined;
19
+ }
20
+ for (const key of keys) {
21
+ const value = source[key];
22
+ if (typeof value === "string" && value.trim()) {
23
+ return value.trim();
24
+ }
25
+ }
26
+ return undefined;
27
+ }
28
+ function normalizeToolName(value) {
29
+ const normalized = value.trim().toLowerCase();
30
+ if (!normalized) {
31
+ return undefined;
32
+ }
33
+ return normalized;
34
+ }
35
+ function parseToolNameFromTitle(title) {
36
+ if (!title) {
37
+ return undefined;
38
+ }
39
+ const head = title.split(":", 1)[0]?.trim();
40
+ if (!head || !/^[a-zA-Z0-9._-]+$/.test(head)) {
41
+ return undefined;
42
+ }
43
+ return normalizeToolName(head);
44
+ }
45
+ function resolveToolKindForPermission(params, toolName) {
46
+ const toolCall = params.toolCall;
47
+ const kindRaw = typeof toolCall?.kind === "string" ? toolCall.kind.trim().toLowerCase() : "";
48
+ if (kindRaw) {
49
+ return kindRaw;
50
+ }
51
+ const name = toolName ??
52
+ parseToolNameFromTitle(typeof toolCall?.title === "string" ? toolCall.title : undefined);
53
+ if (!name) {
54
+ return undefined;
55
+ }
56
+ const normalized = name.toLowerCase();
57
+ const hasToken = (token) => {
58
+ // Tool names tend to be snake_case. Avoid substring heuristics (ex: "thread" contains "read").
59
+ const re = new RegExp(`(?:^|[._-])${token}(?:$|[._-])`);
60
+ return re.test(normalized);
61
+ };
62
+ // Prefer a conservative classifier: only classify safe kinds when confident.
63
+ if (normalized === "read" || hasToken("read")) {
64
+ return "read";
65
+ }
66
+ if (normalized === "search" || hasToken("search") || hasToken("find")) {
67
+ return "search";
68
+ }
69
+ if (normalized.includes("fetch") || normalized.includes("http")) {
70
+ return "fetch";
71
+ }
72
+ if (normalized.includes("write") || normalized.includes("edit") || normalized.includes("patch")) {
73
+ return "edit";
74
+ }
75
+ if (normalized.includes("delete") || normalized.includes("remove")) {
76
+ return "delete";
77
+ }
78
+ if (normalized.includes("move") || normalized.includes("rename")) {
79
+ return "move";
80
+ }
81
+ if (normalized.includes("exec") || normalized.includes("run") || normalized.includes("bash")) {
82
+ return "execute";
83
+ }
84
+ return "other";
85
+ }
86
+ function resolveToolNameForPermission(params) {
87
+ const toolCall = params.toolCall;
88
+ const toolMeta = asRecord(toolCall?._meta);
89
+ const rawInput = asRecord(toolCall?.rawInput);
90
+ const fromMeta = readFirstStringValue(toolMeta, ["toolName", "tool_name", "name"]);
91
+ const fromRawInput = readFirstStringValue(rawInput, ["tool", "toolName", "tool_name", "name"]);
92
+ const fromTitle = parseToolNameFromTitle(toolCall?.title);
93
+ return normalizeToolName(fromMeta ?? fromRawInput ?? fromTitle ?? "");
94
+ }
95
+ function pickOption(options, kinds) {
96
+ for (const kind of kinds) {
97
+ const match = options.find((option) => option.kind === kind);
98
+ if (match) {
99
+ return match;
100
+ }
101
+ }
102
+ return undefined;
103
+ }
104
+ function selectedPermission(optionId) {
105
+ return { outcome: { outcome: "selected", optionId } };
106
+ }
107
+ function cancelledPermission() {
108
+ return { outcome: { outcome: "cancelled" } };
109
+ }
110
+ function promptUserPermission(toolName, toolTitle) {
111
+ if (!process.stdin.isTTY || !process.stderr.isTTY) {
112
+ console.error(`[permission denied] ${toolName ?? "unknown"}: non-interactive terminal`);
113
+ return Promise.resolve(false);
114
+ }
115
+ return new Promise((resolve) => {
116
+ let settled = false;
117
+ const rl = readline.createInterface({
118
+ input: process.stdin,
119
+ output: process.stderr,
120
+ });
121
+ const finish = (approved) => {
122
+ if (settled) {
123
+ return;
124
+ }
125
+ settled = true;
126
+ clearTimeout(timeout);
127
+ rl.close();
128
+ resolve(approved);
129
+ };
130
+ const timeout = setTimeout(() => {
131
+ console.error(`\n[permission timeout] denied: ${toolName ?? "unknown"}`);
132
+ finish(false);
133
+ }, 30_000);
134
+ const label = toolTitle
135
+ ? toolName
136
+ ? `${toolTitle} (${toolName})`
137
+ : toolTitle
138
+ : (toolName ?? "unknown tool");
139
+ rl.question(`\n[permission] Allow "${label}"? (y/N) `, (answer) => {
140
+ const approved = answer.trim().toLowerCase() === "y";
141
+ console.error(`[permission ${approved ? "approved" : "denied"}] ${toolName ?? "unknown"}`);
142
+ finish(approved);
143
+ });
144
+ });
145
+ }
146
+ export async function resolvePermissionRequest(params, deps = {}) {
147
+ const log = deps.log ?? ((line) => console.error(line));
148
+ const prompt = deps.prompt ?? promptUserPermission;
149
+ const options = params.options ?? [];
150
+ const toolTitle = params.toolCall?.title ?? "tool";
151
+ const toolName = resolveToolNameForPermission(params);
152
+ const toolKind = resolveToolKindForPermission(params, toolName);
153
+ if (options.length === 0) {
154
+ log(`[permission cancelled] ${toolName ?? "unknown"}: no options available`);
155
+ return cancelledPermission();
156
+ }
157
+ const allowOption = pickOption(options, ["allow_once", "allow_always"]);
158
+ const rejectOption = pickOption(options, ["reject_once", "reject_always"]);
159
+ const isSafeKind = Boolean(toolKind && SAFE_AUTO_APPROVE_KINDS.has(toolKind));
160
+ const promptRequired = !toolName || !isSafeKind || DANGEROUS_ACP_TOOLS.has(toolName);
161
+ if (!promptRequired) {
162
+ const option = allowOption ?? options[0];
163
+ if (!option) {
164
+ log(`[permission cancelled] ${toolName}: no selectable options`);
165
+ return cancelledPermission();
166
+ }
167
+ log(`[permission auto-approved] ${toolName} (${toolKind ?? "unknown"})`);
168
+ return selectedPermission(option.optionId);
169
+ }
170
+ log(`\n[permission requested] ${toolTitle}${toolName ? ` (${toolName})` : ""}${toolKind ? ` [${toolKind}]` : ""}`);
171
+ const approved = await prompt(toolName, toolTitle);
172
+ if (approved && allowOption) {
173
+ return selectedPermission(allowOption.optionId);
174
+ }
175
+ if (!approved && rejectOption) {
176
+ return selectedPermission(rejectOption.optionId);
177
+ }
178
+ log(`[permission cancelled] ${toolName ?? "unknown"}: missing ${approved ? "allow" : "reject"} option`);
179
+ return cancelledPermission();
180
+ }
6
181
  function toArgs(value) {
7
- if (!value)
182
+ if (!value) {
8
183
  return [];
184
+ }
9
185
  return Array.isArray(value) ? value : [value];
10
186
  }
11
187
  function buildServerArgs(opts) {
@@ -15,10 +191,29 @@ function buildServerArgs(opts) {
15
191
  }
16
192
  return args;
17
193
  }
194
+ function resolveSelfEntryPath() {
195
+ // Prefer a path relative to the built module location (dist/acp/client.js -> dist/entry.js).
196
+ try {
197
+ const here = fileURLToPath(import.meta.url);
198
+ const candidate = path.resolve(path.dirname(here), "..", "entry.js");
199
+ if (fs.existsSync(candidate)) {
200
+ return candidate;
201
+ }
202
+ }
203
+ catch {
204
+ // ignore
205
+ }
206
+ const argv1 = process.argv[1]?.trim();
207
+ if (argv1) {
208
+ return path.isAbsolute(argv1) ? argv1 : path.resolve(process.cwd(), argv1);
209
+ }
210
+ return null;
211
+ }
18
212
  function printSessionUpdate(notification) {
19
213
  const update = notification.update;
20
- if (!("sessionUpdate" in update))
214
+ if (!("sessionUpdate" in update)) {
21
215
  return;
216
+ }
22
217
  switch (update.sessionUpdate) {
23
218
  case "agent_message_chunk": {
24
219
  if (update.content?.type === "text") {
@@ -38,8 +233,9 @@ function printSessionUpdate(notification) {
38
233
  }
39
234
  case "available_commands_update": {
40
235
  const names = update.availableCommands?.map((cmd) => `/${cmd.name}`).join(" ");
41
- if (names)
236
+ if (names) {
42
237
  console.log(`\n[commands] ${names}`);
238
+ }
43
239
  return;
44
240
  }
45
241
  default:
@@ -50,11 +246,13 @@ export async function createAcpClient(opts = {}) {
50
246
  const cwd = opts.cwd ?? process.cwd();
51
247
  const verbose = Boolean(opts.verbose);
52
248
  const log = verbose ? (msg) => console.error(`[acp-client] ${msg}`) : () => { };
53
- ensurePoolbotCliOnPath({ cwd });
54
- const serverCommand = opts.serverCommand ?? "poolbot";
249
+ ensurePoolbotCliOnPath();
55
250
  const serverArgs = buildServerArgs(opts);
56
- log(`spawning: ${serverCommand} ${serverArgs.join(" ")}`);
57
- const agent = spawn(serverCommand, serverArgs, {
251
+ const entryPath = resolveSelfEntryPath();
252
+ const serverCommand = opts.serverCommand ?? (entryPath ? process.execPath : "poolbot");
253
+ const effectiveArgs = opts.serverCommand || !entryPath ? serverArgs : [entryPath, ...serverArgs];
254
+ log(`spawning: ${serverCommand} ${effectiveArgs.join(" ")}`);
255
+ const agent = spawn(serverCommand, effectiveArgs, {
58
256
  stdio: ["pipe", "pipe", "inherit"],
59
257
  cwd,
60
258
  });
@@ -69,16 +267,7 @@ export async function createAcpClient(opts = {}) {
69
267
  printSessionUpdate(params);
70
268
  },
71
269
  requestPermission: async (params) => {
72
- console.log("\n[permission requested]", params.toolCall?.title ?? "tool");
73
- const options = params.options ?? [];
74
- const allowOnce = options.find((option) => option.kind === "allow_once");
75
- const fallback = options[0];
76
- return {
77
- outcome: {
78
- outcome: "selected",
79
- optionId: allowOnce?.optionId ?? fallback?.optionId ?? "allow",
80
- },
81
- };
270
+ return resolvePermissionRequest(params);
82
271
  },
83
272
  }), stream);
84
273
  log("initializing");
@@ -107,7 +296,7 @@ export async function runAcpClientInteractive(opts = {}) {
107
296
  input: process.stdin,
108
297
  output: process.stdout,
109
298
  });
110
- console.log("Poolbot ACP client");
299
+ console.log("Pool Bot ACP client");
111
300
  console.log(`Session: ${sessionId}`);
112
301
  console.log('Type a prompt, or "exit" to quit.\n');
113
302
  const prompt = () => {
@@ -1,21 +1,76 @@
1
- export function extractTextFromPrompt(prompt) {
1
+ const INLINE_CONTROL_ESCAPE_MAP = {
2
+ "\0": "\\0",
3
+ "\r": "\\r",
4
+ "\n": "\\n",
5
+ "\t": "\\t",
6
+ "\v": "\\v",
7
+ "\f": "\\f",
8
+ "\u2028": "\\u2028",
9
+ "\u2029": "\\u2029",
10
+ };
11
+ function escapeInlineControlChars(value) {
12
+ let escaped = "";
13
+ for (const char of value) {
14
+ const codePoint = char.codePointAt(0);
15
+ if (codePoint === undefined) {
16
+ escaped += char;
17
+ continue;
18
+ }
19
+ const isInlineControl = codePoint <= 0x1f ||
20
+ (codePoint >= 0x7f && codePoint <= 0x9f) ||
21
+ codePoint === 0x2028 ||
22
+ codePoint === 0x2029;
23
+ if (!isInlineControl) {
24
+ escaped += char;
25
+ continue;
26
+ }
27
+ const mapped = INLINE_CONTROL_ESCAPE_MAP[char];
28
+ if (mapped) {
29
+ escaped += mapped;
30
+ continue;
31
+ }
32
+ // Keep escaped control bytes readable and stable in logs/prompts.
33
+ escaped +=
34
+ codePoint <= 0xff
35
+ ? `\\x${codePoint.toString(16).padStart(2, "0")}`
36
+ : `\\u${codePoint.toString(16).padStart(4, "0")}`;
37
+ }
38
+ return escaped;
39
+ }
40
+ function escapeResourceTitle(value) {
41
+ // Keep title content, but escape characters that can break the resource-link annotation shape.
42
+ return escapeInlineControlChars(value).replace(/[()[\]]/g, (char) => `\\${char}`);
43
+ }
44
+ export function extractTextFromPrompt(prompt, maxBytes) {
2
45
  const parts = [];
46
+ // Track accumulated byte count per block to catch oversized prompts before full concatenation
47
+ let totalBytes = 0;
3
48
  for (const block of prompt) {
49
+ let blockText;
4
50
  if (block.type === "text") {
5
- parts.push(block.text);
6
- continue;
51
+ blockText = block.text;
7
52
  }
8
- if (block.type === "resource") {
53
+ else if (block.type === "resource") {
9
54
  const resource = block.resource;
10
- if (resource?.text)
11
- parts.push(resource.text);
12
- continue;
55
+ if (resource?.text) {
56
+ blockText = resource.text;
57
+ }
13
58
  }
14
- if (block.type === "resource_link") {
15
- const title = block.title ? ` (${block.title})` : "";
16
- const uri = block.uri ?? "";
17
- const line = uri ? `[Resource link${title}] ${uri}` : `[Resource link${title}]`;
18
- parts.push(line);
59
+ else if (block.type === "resource_link") {
60
+ const title = block.title ? ` (${escapeResourceTitle(block.title)})` : "";
61
+ const uri = block.uri ? escapeInlineControlChars(block.uri) : "";
62
+ blockText = uri ? `[Resource link${title}] ${uri}` : `[Resource link${title}]`;
63
+ }
64
+ if (blockText !== undefined) {
65
+ // Guard: reject before allocating the full concatenated string
66
+ if (maxBytes !== undefined) {
67
+ const separatorBytes = parts.length > 0 ? 1 : 0; // "\n" added by join() between blocks
68
+ totalBytes += separatorBytes + Buffer.byteLength(blockText, "utf-8");
69
+ if (totalBytes > maxBytes) {
70
+ throw new Error(`Prompt exceeds maximum allowed size of ${maxBytes} bytes`);
71
+ }
72
+ }
73
+ parts.push(blockText);
19
74
  }
20
75
  }
21
76
  return parts.join("\n");
@@ -23,11 +78,13 @@ export function extractTextFromPrompt(prompt) {
23
78
  export function extractAttachmentsFromPrompt(prompt) {
24
79
  const attachments = [];
25
80
  for (const block of prompt) {
26
- if (block.type !== "image")
81
+ if (block.type !== "image") {
27
82
  continue;
83
+ }
28
84
  const image = block;
29
- if (!image.data || !image.mimeType)
85
+ if (!image.data || !image.mimeType) {
30
86
  continue;
87
+ }
31
88
  attachments.push({
32
89
  type: "image",
33
90
  mimeType: image.mimeType,
@@ -38,8 +95,9 @@ export function extractAttachmentsFromPrompt(prompt) {
38
95
  }
39
96
  export function formatToolTitle(name, args) {
40
97
  const base = name ?? "tool";
41
- if (!args || Object.keys(args).length === 0)
98
+ if (!args || Object.keys(args).length === 0) {
42
99
  return base;
100
+ }
43
101
  const parts = Object.entries(args).map(([key, value]) => {
44
102
  const raw = typeof value === "string" ? value : JSON.stringify(value);
45
103
  const safe = raw.length > 100 ? `${raw.slice(0, 100)}...` : raw;
@@ -48,23 +106,30 @@ export function formatToolTitle(name, args) {
48
106
  return `${base}: ${parts.join(", ")}`;
49
107
  }
50
108
  export function inferToolKind(name) {
51
- if (!name)
109
+ if (!name) {
52
110
  return "other";
111
+ }
53
112
  const normalized = name.toLowerCase();
54
- if (normalized.includes("read"))
113
+ if (normalized.includes("read")) {
55
114
  return "read";
56
- if (normalized.includes("write") || normalized.includes("edit"))
115
+ }
116
+ if (normalized.includes("write") || normalized.includes("edit")) {
57
117
  return "edit";
58
- if (normalized.includes("delete") || normalized.includes("remove"))
118
+ }
119
+ if (normalized.includes("delete") || normalized.includes("remove")) {
59
120
  return "delete";
60
- if (normalized.includes("move") || normalized.includes("rename"))
121
+ }
122
+ if (normalized.includes("move") || normalized.includes("rename")) {
61
123
  return "move";
62
- if (normalized.includes("search") || normalized.includes("find"))
124
+ }
125
+ if (normalized.includes("search") || normalized.includes("find")) {
63
126
  return "search";
127
+ }
64
128
  if (normalized.includes("exec") || normalized.includes("run") || normalized.includes("bash")) {
65
129
  return "execute";
66
130
  }
67
- if (normalized.includes("fetch") || normalized.includes("http"))
131
+ if (normalized.includes("fetch") || normalized.includes("http")) {
68
132
  return "fetch";
133
+ }
69
134
  return "other";
70
135
  }
package/dist/acp/meta.js CHANGED
@@ -1,30 +1,36 @@
1
1
  export function readString(meta, keys) {
2
- if (!meta)
2
+ if (!meta) {
3
3
  return undefined;
4
+ }
4
5
  for (const key of keys) {
5
6
  const value = meta[key];
6
- if (typeof value === "string" && value.trim())
7
+ if (typeof value === "string" && value.trim()) {
7
8
  return value.trim();
9
+ }
8
10
  }
9
11
  return undefined;
10
12
  }
11
13
  export function readBool(meta, keys) {
12
- if (!meta)
14
+ if (!meta) {
13
15
  return undefined;
16
+ }
14
17
  for (const key of keys) {
15
18
  const value = meta[key];
16
- if (typeof value === "boolean")
19
+ if (typeof value === "boolean") {
17
20
  return value;
21
+ }
18
22
  }
19
23
  return undefined;
20
24
  }
21
25
  export function readNumber(meta, keys) {
22
- if (!meta)
26
+ if (!meta) {
23
27
  return undefined;
28
+ }
24
29
  for (const key of keys) {
25
30
  const value = meta[key];
26
- if (typeof value === "number" && Number.isFinite(value))
31
+ if (typeof value === "number" && Number.isFinite(value)) {
27
32
  return value;
33
+ }
28
34
  }
29
35
  return undefined;
30
36
  }
@@ -0,0 +1,22 @@
1
+ import fs from "node:fs";
2
+ import { resolveUserPath } from "../utils.js";
3
+ export function readSecretFromFile(filePath, label) {
4
+ const resolvedPath = resolveUserPath(filePath.trim());
5
+ if (!resolvedPath) {
6
+ throw new Error(`${label} file path is empty.`);
7
+ }
8
+ let raw = "";
9
+ try {
10
+ raw = fs.readFileSync(resolvedPath, "utf8");
11
+ }
12
+ catch (err) {
13
+ throw new Error(`Failed to read ${label} file at ${resolvedPath}: ${String(err)}`, {
14
+ cause: err,
15
+ });
16
+ }
17
+ const secret = raw.trim();
18
+ if (!secret) {
19
+ throw new Error(`${label} file at ${resolvedPath} is empty.`);
20
+ }
21
+ return secret;
22
+ }
@@ -3,21 +3,20 @@ import { resolveStateDir } from "../config/paths.js";
3
3
  import { DEFAULT_AGENT_ID } from "../routing/session-key.js";
4
4
  import { resolveUserPath } from "../utils.js";
5
5
  export function resolvePoolbotAgentDir() {
6
- const override = process.env.POOLBOT_AGENT_DIR?.trim() ||
7
- process.env.CLAWDBOT_AGENT_DIR?.trim() ||
8
- process.env.PI_CODING_AGENT_DIR?.trim();
9
- if (override)
6
+ const override = process.env.POOLBOT_AGENT_DIR?.trim() || process.env.PI_CODING_AGENT_DIR?.trim();
7
+ if (override) {
10
8
  return resolveUserPath(override);
9
+ }
11
10
  const defaultAgentDir = path.join(resolveStateDir(), "agents", DEFAULT_AGENT_ID, "agent");
12
11
  return resolveUserPath(defaultAgentDir);
13
12
  }
14
- export function ensurePoolbotAgentEnv() {
13
+ export function ensurePoolBotAgentEnv() {
15
14
  const dir = resolvePoolbotAgentDir();
16
- if (!process.env.POOLBOT_AGENT_DIR)
15
+ if (!process.env.POOLBOT_AGENT_DIR) {
17
16
  process.env.POOLBOT_AGENT_DIR = dir;
18
- if (!process.env.CLAWDBOT_AGENT_DIR)
19
- process.env.CLAWDBOT_AGENT_DIR = dir;
20
- if (!process.env.PI_CODING_AGENT_DIR)
17
+ }
18
+ if (!process.env.PI_CODING_AGENT_DIR) {
21
19
  process.env.PI_CODING_AGENT_DIR = dir;
20
+ }
22
21
  return dir;
23
22
  }
@@ -4,17 +4,19 @@ import { resolveStateDir } from "../config/paths.js";
4
4
  import { DEFAULT_AGENT_ID, normalizeAgentId, parseAgentSessionKey, } from "../routing/session-key.js";
5
5
  import { normalizeSkillFilter } from "./skills/filter.js";
6
6
  import { resolveUserPath } from "../utils.js";
7
+ import { createSubsystemLogger } from "../logging/subsystem.js";
7
8
  import { DEFAULT_AGENT_WORKSPACE_DIR } from "./workspace.js";
9
+ const log = createSubsystemLogger("agent-scope");
8
10
  export { resolveAgentIdFromSessionKey } from "../routing/session-key.js";
9
11
  let defaultAgentWarned = false;
10
- function listAgents(cfg) {
12
+ export function listAgentEntries(cfg) {
11
13
  const list = cfg.agents?.list;
12
14
  if (!Array.isArray(list))
13
15
  return [];
14
16
  return list.filter((entry) => Boolean(entry && typeof entry === "object"));
15
17
  }
16
18
  export function listAgentIds(cfg) {
17
- const agents = listAgents(cfg);
19
+ const agents = listAgentEntries(cfg);
18
20
  if (agents.length === 0)
19
21
  return [DEFAULT_AGENT_ID];
20
22
  const seen = new Set();
@@ -29,13 +31,13 @@ export function listAgentIds(cfg) {
29
31
  return ids.length > 0 ? ids : [DEFAULT_AGENT_ID];
30
32
  }
31
33
  export function resolveDefaultAgentId(cfg) {
32
- const agents = listAgents(cfg);
34
+ const agents = listAgentEntries(cfg);
33
35
  if (agents.length === 0)
34
36
  return DEFAULT_AGENT_ID;
35
37
  const defaults = agents.filter((agent) => agent?.default);
36
38
  if (defaults.length > 1 && !defaultAgentWarned) {
37
39
  defaultAgentWarned = true;
38
- console.warn("Multiple agents marked default=true; using the first entry as default.");
40
+ log.warn("Multiple agents marked default=true; using the first entry as default.");
39
41
  }
40
42
  const chosen = (defaults[0] ?? agents[0])?.id?.trim();
41
43
  return normalizeAgentId(chosen || DEFAULT_AGENT_ID);
@@ -53,7 +55,7 @@ export function resolveSessionAgentId(params) {
53
55
  }
54
56
  function resolveAgentEntry(cfg, agentId) {
55
57
  const id = normalizeAgentId(agentId);
56
- return listAgents(cfg).find((entry) => normalizeAgentId(entry.id) === id);
58
+ return listAgentEntries(cfg).find((entry) => normalizeAgentId(entry.id) === id);
57
59
  }
58
60
  export function resolveAgentConfig(cfg, agentId) {
59
61
  const id = normalizeAgentId(agentId);
@@ -98,6 +100,16 @@ export function resolveAgentModelFallbacksOverride(cfg, agentId) {
98
100
  return undefined;
99
101
  return Array.isArray(raw.fallbacks) ? raw.fallbacks : undefined;
100
102
  }
103
+ export function resolveEffectiveModelFallbacks(params) {
104
+ const agentFallbacksOverride = resolveAgentModelFallbacksOverride(params.cfg, params.agentId);
105
+ if (!params.hasSessionModelOverride) {
106
+ return agentFallbacksOverride;
107
+ }
108
+ const defaultFallbacks = typeof params.cfg.agents?.defaults?.model === "object"
109
+ ? (params.cfg.agents.defaults.model.fallbacks ?? [])
110
+ : [];
111
+ return agentFallbacksOverride ?? defaultFallbacks;
112
+ }
101
113
  export function resolveAgentWorkspaceDir(cfg, agentId) {
102
114
  const id = normalizeAgentId(agentId);
103
115
  const configured = resolveAgentConfig(cfg, id)?.workspace?.trim();