@poolzin/pool-bot 2026.1.39 → 2026.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (511) hide show
  1. package/assets/chrome-extension/README.md +3 -3
  2. package/assets/chrome-extension/background.js +5 -5
  3. package/assets/chrome-extension/manifest.json +3 -3
  4. package/assets/chrome-extension/options.html +4 -4
  5. package/assets/chrome-extension/options.js +1 -1
  6. package/dist/acp/client.js +3 -3
  7. package/dist/acp/types.js +1 -1
  8. package/dist/agents/agent-paths.js +3 -3
  9. package/dist/agents/auth-profiles/paths.js +3 -3
  10. package/dist/agents/bash-tools.exec.js +76 -25
  11. package/dist/agents/cli-runner/helpers.js +10 -12
  12. package/dist/agents/cli-runner.js +2 -2
  13. package/dist/agents/cloudflare-ai-gateway.js +31 -0
  14. package/dist/agents/compaction.js +16 -2
  15. package/dist/agents/context-window-guard.js +13 -10
  16. package/dist/agents/context.js +4 -4
  17. package/dist/agents/docs-path.js +1 -1
  18. package/dist/agents/identity.js +47 -7
  19. package/dist/agents/memory-search.js +25 -8
  20. package/dist/agents/minimax-vlm.js +1 -1
  21. package/dist/agents/model-auth.js +12 -1
  22. package/dist/agents/model-catalog.js +4 -4
  23. package/dist/agents/model-selection.js +31 -4
  24. package/dist/agents/models-config.js +3 -3
  25. package/dist/agents/models-config.providers.js +147 -39
  26. package/dist/agents/pi-embedded-block-chunker.js +117 -42
  27. package/dist/agents/pi-embedded-helpers/errors.js +183 -78
  28. package/dist/agents/pi-embedded-helpers/openai.js +1 -1
  29. package/dist/agents/pi-embedded-helpers.js +1 -1
  30. package/dist/agents/pi-embedded-runner/compact.js +9 -8
  31. package/dist/agents/pi-embedded-runner/model.js +63 -4
  32. package/dist/agents/pi-embedded-runner/run/attempt.js +27 -17
  33. package/dist/agents/pi-embedded-runner/run.js +203 -50
  34. package/dist/agents/pi-embedded-runner/system-prompt.js +10 -2
  35. package/dist/agents/pi-embedded-runner/tool-result-truncation.js +275 -0
  36. package/dist/agents/pi-embedded-runner/utils.js +1 -1
  37. package/dist/agents/pi-embedded-subscribe.js +118 -29
  38. package/dist/agents/pi-model-discovery.js +10 -0
  39. package/dist/agents/pi-tool-definition-adapter.js +50 -9
  40. package/dist/agents/pi-tools.before-tool-call.js +67 -0
  41. package/dist/agents/pi-tools.js +20 -10
  42. package/dist/agents/pi-tools.read.js +2 -2
  43. package/dist/agents/poolbot-tools.js +15 -10
  44. package/dist/agents/sandbox-paths.js +31 -0
  45. package/dist/agents/session-file-repair.js +83 -0
  46. package/dist/agents/session-tool-result-guard.js +94 -15
  47. package/dist/agents/session-transcript-repair.js +68 -0
  48. package/dist/agents/shell-utils.js +51 -0
  49. package/dist/agents/skills/bundled-context.js +23 -0
  50. package/dist/agents/skills/bundled-dir.js +41 -7
  51. package/dist/agents/skills/frontmatter.js +1 -1
  52. package/dist/agents/skills/workspace.js +2 -2
  53. package/dist/agents/skills-install.js +60 -23
  54. package/dist/agents/subagent-announce.js +79 -34
  55. package/dist/agents/system-prompt.js +28 -4
  56. package/dist/agents/together-models.js +127 -0
  57. package/dist/agents/tool-images.js +1 -1
  58. package/dist/agents/tool-policy.conformance.js +14 -0
  59. package/dist/agents/tool-policy.js +25 -1
  60. package/dist/agents/tools/browser-tool.js +3 -3
  61. package/dist/agents/tools/cron-tool.js +166 -19
  62. package/dist/agents/tools/discord-actions-presence.js +78 -0
  63. package/dist/agents/tools/image-tool.js +2 -2
  64. package/dist/agents/tools/memory-tool.js +93 -5
  65. package/dist/agents/tools/message-tool.js +56 -2
  66. package/dist/agents/tools/sessions-history-tool.js +69 -1
  67. package/dist/agents/tools/web-search.js +211 -42
  68. package/dist/agents/usage.js +23 -1
  69. package/dist/agents/workspace-run.js +67 -0
  70. package/dist/agents/workspace-templates.js +44 -0
  71. package/dist/auto-reply/command-auth.js +121 -6
  72. package/dist/auto-reply/commands-registry.data.js +1 -1
  73. package/dist/auto-reply/envelope.js +50 -72
  74. package/dist/auto-reply/reply/commands-compact.js +1 -0
  75. package/dist/auto-reply/reply/commands-context-report.js +3 -2
  76. package/dist/auto-reply/reply/commands-context.js +1 -0
  77. package/dist/auto-reply/reply/commands-models.js +107 -60
  78. package/dist/auto-reply/reply/commands-ptt.js +171 -0
  79. package/dist/auto-reply/reply/commands-session.js +2 -2
  80. package/dist/auto-reply/reply/get-reply-run.js +16 -5
  81. package/dist/auto-reply/reply/groups.js +1 -1
  82. package/dist/auto-reply/reply/inbound-context.js +9 -1
  83. package/dist/auto-reply/reply/inbound-meta.js +130 -0
  84. package/dist/auto-reply/reply/model-selection.js +3 -3
  85. package/dist/auto-reply/reply/untrusted-context.js +15 -0
  86. package/dist/auto-reply/status.js +1 -1
  87. package/dist/auto-reply/thinking.js +88 -43
  88. package/dist/browser/bridge-server.js +13 -0
  89. package/dist/browser/cdp.helpers.js +38 -24
  90. package/dist/browser/client-fetch.js +51 -8
  91. package/dist/browser/config.js +2 -11
  92. package/dist/browser/extension-relay.js +104 -43
  93. package/dist/browser/pw-ai.js +1 -1
  94. package/dist/browser/pw-session.js +143 -8
  95. package/dist/browser/pw-tools-core.interactions.js +125 -27
  96. package/dist/browser/pw-tools-core.responses.js +1 -1
  97. package/dist/browser/pw-tools-core.state.js +1 -1
  98. package/dist/browser/routes/agent.act.js +86 -41
  99. package/dist/browser/routes/dispatcher.js +4 -4
  100. package/dist/browser/screenshot.js +1 -1
  101. package/dist/browser/server-context.js +2 -2
  102. package/dist/browser/server.js +13 -0
  103. package/dist/build-info.json +3 -3
  104. package/dist/canvas-host/a2ui.js +3 -3
  105. package/dist/channels/plugins/catalog.js +2 -2
  106. package/dist/channels/plugins/onboarding/imessage.js +1 -1
  107. package/dist/channels/plugins/onboarding/signal.js +1 -1
  108. package/dist/channels/plugins/onboarding/slack.js +4 -4
  109. package/dist/channels/plugins/onboarding/whatsapp.js +3 -3
  110. package/dist/channels/plugins/pairing-message.js +1 -1
  111. package/dist/channels/reply-prefix.js +8 -1
  112. package/dist/cli/browser-cli-extension.js +2 -2
  113. package/dist/cli/cron-cli/register.cron-add.js +61 -40
  114. package/dist/cli/cron-cli/register.cron-edit.js +60 -34
  115. package/dist/cli/cron-cli/shared.js +56 -41
  116. package/dist/cli/dns-cli.js +26 -14
  117. package/dist/cli/docs-cli.js +1 -1
  118. package/dist/cli/gateway-cli/dev.js +1 -1
  119. package/dist/cli/gateway-cli/register.js +37 -19
  120. package/dist/cli/memory-cli.js +30 -20
  121. package/dist/cli/nodes-cli/register.canvas.js +1 -1
  122. package/dist/cli/parse-bytes.js +37 -0
  123. package/dist/cli/plugins-cli.js +1 -1
  124. package/dist/cli/run-main.js +2 -2
  125. package/dist/cli/security-cli.js +1 -1
  126. package/dist/cli/tagline.js +1 -1
  127. package/dist/cli/update-cli.js +173 -52
  128. package/dist/cli/webhooks-cli.js +5 -5
  129. package/dist/commands/agent.js +1 -0
  130. package/dist/commands/agents.commands.add.js +1 -1
  131. package/dist/commands/auth-choice.apply.api-providers.js +305 -17
  132. package/dist/commands/auth-choice.apply.js +4 -1
  133. package/dist/commands/auth-choice.apply.plugin-provider.js +2 -2
  134. package/dist/commands/auth-choice.apply.xai.js +63 -0
  135. package/dist/commands/auth-choice.preferred-provider.js +7 -1
  136. package/dist/commands/configure.wizard.js +1 -1
  137. package/dist/commands/dashboard.js +1 -1
  138. package/dist/commands/docs.js +1 -1
  139. package/dist/commands/doctor-config-flow.js +61 -5
  140. package/dist/commands/doctor-gateway-services.js +3 -3
  141. package/dist/commands/doctor-state-migrations.js +1 -1
  142. package/dist/commands/doctor-update.js +3 -3
  143. package/dist/commands/doctor.js +1 -1
  144. package/dist/commands/health.js +1 -1
  145. package/dist/commands/model-allowlist.js +29 -0
  146. package/dist/commands/model-picker.js +2 -1
  147. package/dist/commands/models/list.probe.js +2 -2
  148. package/dist/commands/models/list.registry.js +4 -4
  149. package/dist/commands/models/list.status-command.js +44 -24
  150. package/dist/commands/models/shared.js +15 -0
  151. package/dist/commands/onboard-auth.config-core.js +366 -28
  152. package/dist/commands/onboard-auth.credentials.js +71 -9
  153. package/dist/commands/onboard-auth.js +3 -3
  154. package/dist/commands/onboard-auth.models.js +26 -24
  155. package/dist/commands/onboard-custom.js +384 -0
  156. package/dist/commands/onboard-non-interactive/local/auth-choice-inference.js +35 -0
  157. package/dist/commands/onboard-non-interactive/local/auth-choice.js +146 -9
  158. package/dist/commands/onboard-skills.js +63 -38
  159. package/dist/commands/openai-model-default.js +41 -0
  160. package/dist/commands/status-all/report-lines.js +1 -1
  161. package/dist/commands/status.command.js +1 -1
  162. package/dist/commands/uninstall.js +3 -3
  163. package/dist/compat/legacy-names.js +1 -1
  164. package/dist/config/defaults.js +3 -2
  165. package/dist/config/io.js +3 -3
  166. package/dist/config/paths.js +136 -35
  167. package/dist/config/plugin-auto-enable.js +21 -5
  168. package/dist/config/redact-snapshot.js +153 -0
  169. package/dist/config/schema.field-metadata.js +590 -0
  170. package/dist/config/schema.js +3 -3
  171. package/dist/config/sessions/store.js +291 -23
  172. package/dist/config/types.memory.js +1 -0
  173. package/dist/config/version.js +4 -4
  174. package/dist/config/zod-schema.agent-defaults.js +3 -0
  175. package/dist/config/zod-schema.agent-runtime.js +13 -2
  176. package/dist/config/zod-schema.providers-core.js +142 -0
  177. package/dist/config/zod-schema.session.js +3 -0
  178. package/dist/cron/delivery.js +57 -0
  179. package/dist/cron/isolated-agent/delivery-target.js +18 -3
  180. package/dist/cron/isolated-agent/helpers.js +22 -5
  181. package/dist/cron/isolated-agent/run.js +171 -63
  182. package/dist/cron/isolated-agent/session.js +2 -0
  183. package/dist/cron/normalize.js +356 -28
  184. package/dist/cron/parse.js +10 -5
  185. package/dist/cron/run-log.js +35 -10
  186. package/dist/cron/schedule.js +41 -6
  187. package/dist/cron/service/jobs.js +208 -35
  188. package/dist/cron/service/ops.js +72 -16
  189. package/dist/cron/service/state.js +2 -0
  190. package/dist/cron/service/store.js +386 -14
  191. package/dist/cron/service/timer.js +390 -147
  192. package/dist/cron/session-reaper.js +86 -0
  193. package/dist/cron/store.js +23 -8
  194. package/dist/cron/validate-timestamp.js +43 -0
  195. package/dist/daemon/constants.js +7 -7
  196. package/dist/daemon/inspect.js +6 -6
  197. package/dist/daemon/systemd-unit.js +1 -1
  198. package/dist/discord/monitor/agent-components.js +438 -0
  199. package/dist/discord/monitor/allow-list.js +28 -5
  200. package/dist/discord/monitor/gateway-registry.js +29 -0
  201. package/dist/discord/monitor/native-command.js +44 -23
  202. package/dist/discord/monitor/sender-identity.js +45 -0
  203. package/dist/discord/pluralkit.js +27 -0
  204. package/dist/discord/send.outbound.js +92 -5
  205. package/dist/discord/send.shared.js +60 -23
  206. package/dist/discord/targets.js +84 -1
  207. package/dist/entry.js +15 -9
  208. package/dist/extensionAPI.js +8 -0
  209. package/dist/gateway/control-ui.js +8 -1
  210. package/dist/gateway/hooks-mapping.js +3 -0
  211. package/dist/gateway/hooks.js +65 -0
  212. package/dist/gateway/live-image-probe.js +1 -66
  213. package/dist/gateway/net.js +96 -31
  214. package/dist/gateway/node-command-policy.js +50 -15
  215. package/dist/gateway/openai-http.js +2 -2
  216. package/dist/gateway/openresponses-http.js +4 -4
  217. package/dist/gateway/origin-check.js +56 -0
  218. package/dist/gateway/protocol/client-info.js +9 -0
  219. package/dist/gateway/protocol/index.js +9 -2
  220. package/dist/gateway/protocol/schema/agents-models-skills.js +71 -1
  221. package/dist/gateway/protocol/schema/cron.js +22 -10
  222. package/dist/gateway/protocol/schema/protocol-schemas.js +16 -2
  223. package/dist/gateway/protocol/schema/sessions.js +12 -0
  224. package/dist/gateway/server/hooks.js +1 -1
  225. package/dist/gateway/server-broadcast.js +26 -9
  226. package/dist/gateway/server-chat.js +112 -23
  227. package/dist/gateway/server-discovery-runtime.js +10 -2
  228. package/dist/gateway/server-discovery.js +2 -2
  229. package/dist/gateway/server-http.js +110 -12
  230. package/dist/gateway/server-methods/agent-timestamp.js +60 -0
  231. package/dist/gateway/server-methods/agents.js +321 -2
  232. package/dist/gateway/server-methods/usage.js +559 -16
  233. package/dist/gateway/server-runtime-state.js +22 -8
  234. package/dist/gateway/server-startup-memory.js +16 -0
  235. package/dist/gateway/server.impl.js +7 -3
  236. package/dist/gateway/session-utils.fs.js +23 -25
  237. package/dist/gateway/session-utils.js +20 -10
  238. package/dist/gateway/sessions-patch.js +7 -22
  239. package/dist/gateway/test-helpers.server.js +35 -2
  240. package/dist/hooks/frontmatter.js +1 -1
  241. package/dist/hooks/hooks-status.js +1 -1
  242. package/dist/hooks/install.js +2 -2
  243. package/dist/hooks/loader.js +1 -1
  244. package/dist/hooks/workspace.js +3 -3
  245. package/dist/imessage/constants.js +2 -0
  246. package/dist/imessage/monitor/deliver.js +4 -1
  247. package/dist/imessage/monitor/monitor-provider.js +51 -1
  248. package/dist/index.js +2 -2
  249. package/dist/infra/bonjour-discovery.js +131 -70
  250. package/dist/infra/bonjour.js +3 -3
  251. package/dist/infra/control-ui-assets.js +134 -12
  252. package/dist/infra/errors.js +12 -0
  253. package/dist/infra/exec-approvals.js +266 -57
  254. package/dist/infra/format-time/format-datetime.js +79 -0
  255. package/dist/infra/format-time/format-duration.js +81 -0
  256. package/dist/infra/format-time/format-relative.js +80 -0
  257. package/dist/infra/heartbeat-runner.js +140 -49
  258. package/dist/infra/home-dir.js +54 -0
  259. package/dist/infra/net/fetch-guard.js +122 -0
  260. package/dist/infra/net/ssrf.js +65 -29
  261. package/dist/infra/outbound/abort.js +14 -0
  262. package/dist/infra/outbound/message-action-runner.js +77 -13
  263. package/dist/infra/outbound/outbound-session.js +143 -37
  264. package/dist/infra/path-env.js +3 -3
  265. package/dist/infra/poolbot-root.js +43 -1
  266. package/dist/infra/provider-usage.fetch.minimax.js +1 -1
  267. package/dist/infra/restart.js +1 -1
  268. package/dist/infra/session-cost-usage.js +631 -41
  269. package/dist/infra/state-migrations.js +317 -47
  270. package/dist/infra/tailscale.js +1 -1
  271. package/dist/infra/update-global.js +35 -0
  272. package/dist/infra/update-runner.js +149 -43
  273. package/dist/infra/warning-filter.js +65 -0
  274. package/dist/infra/widearea-dns.js +30 -9
  275. package/dist/logging/redact-identifier.js +12 -0
  276. package/dist/macos/relay.js +2 -2
  277. package/dist/media/fetch.js +81 -58
  278. package/dist/media/input-files.js +1 -1
  279. package/dist/media/mime.js +4 -0
  280. package/dist/media/png-encode.js +74 -0
  281. package/dist/media-understanding/apply.js +403 -3
  282. package/dist/media-understanding/attachments.js +38 -27
  283. package/dist/media-understanding/defaults.js +16 -0
  284. package/dist/media-understanding/providers/deepgram/audio.js +22 -14
  285. package/dist/media-understanding/providers/google/audio.js +24 -17
  286. package/dist/media-understanding/providers/google/video.js +24 -17
  287. package/dist/media-understanding/providers/image.js +4 -4
  288. package/dist/media-understanding/providers/index.js +4 -1
  289. package/dist/media-understanding/providers/openai/audio.js +22 -14
  290. package/dist/media-understanding/providers/shared.js +16 -11
  291. package/dist/media-understanding/providers/zai/index.js +6 -0
  292. package/dist/media-understanding/runner.js +158 -90
  293. package/dist/memory/backend-config.js +207 -0
  294. package/dist/memory/batch-voyage.js +277 -0
  295. package/dist/memory/embeddings-voyage.js +75 -0
  296. package/dist/memory/embeddings.js +29 -17
  297. package/dist/memory/internal.js +101 -18
  298. package/dist/memory/manager.js +155 -48
  299. package/dist/memory/search-manager.js +173 -0
  300. package/dist/memory/session-files.js +9 -3
  301. package/dist/memory/types.js +1 -0
  302. package/dist/node-host/runner.js +36 -26
  303. package/dist/node-host/with-timeout.js +27 -0
  304. package/dist/pairing/pairing-messages.js +1 -1
  305. package/dist/plugins/commands.js +5 -1
  306. package/dist/plugins/config-state.js +86 -7
  307. package/dist/plugins/discovery.js +1 -1
  308. package/dist/plugins/install.js +2 -2
  309. package/dist/plugins/source-display.js +51 -0
  310. package/dist/plugins/update.js +1 -1
  311. package/dist/process/exec.js +20 -2
  312. package/dist/routing/resolve-route.js +12 -0
  313. package/dist/routing/session-key.js +15 -0
  314. package/dist/runtime.js +2 -0
  315. package/dist/security/audit-extra.async.js +601 -0
  316. package/dist/security/audit-extra.js +2 -830
  317. package/dist/security/audit-extra.sync.js +505 -0
  318. package/dist/security/audit.js +2 -2
  319. package/dist/security/channel-metadata.js +34 -0
  320. package/dist/security/external-content.js +88 -6
  321. package/dist/security/skill-scanner.js +330 -0
  322. package/dist/sessions/session-key-utils.js +7 -0
  323. package/dist/shared/text/reasoning-tags.js +52 -7
  324. package/dist/signal/monitor/event-handler.js +80 -1
  325. package/dist/slack/monitor/media.js +85 -15
  326. package/dist/tailscale/detect.js +145 -0
  327. package/dist/telegram/bot/helpers.js +109 -28
  328. package/dist/telegram/bot-handlers.js +144 -3
  329. package/dist/telegram/bot-message-context.js +38 -11
  330. package/dist/telegram/bot-message-dispatch.js +48 -15
  331. package/dist/telegram/bot-native-commands.js +86 -29
  332. package/dist/telegram/bot.js +30 -29
  333. package/dist/telegram/model-buttons.js +163 -0
  334. package/dist/telegram/monitor.js +110 -85
  335. package/dist/telegram/send.js +129 -47
  336. package/dist/terminal/restore.js +45 -0
  337. package/dist/test-helpers/state-dir-env.js +16 -0
  338. package/dist/test-helpers/workspace.js +11 -0
  339. package/dist/test-utils/channel-plugins.js +82 -0
  340. package/dist/test-utils/ports.js +73 -0
  341. package/dist/tts/tts.js +12 -6
  342. package/dist/tui/tui-session-actions.js +166 -54
  343. package/dist/utils/fetch-timeout.js +20 -0
  344. package/dist/utils/normalize-secret-input.js +19 -0
  345. package/dist/utils/shell-argv.js +61 -0
  346. package/dist/utils/transcript-tools.js +58 -0
  347. package/dist/utils.js +55 -14
  348. package/dist/version.js +42 -5
  349. package/dist/web/qr-image.js +1 -61
  350. package/dist/wizard/onboarding.finalize.js +7 -7
  351. package/dist/wizard/onboarding.js +3 -3
  352. package/docs/RELEASE_WORKFOTS_COMPARISON.md +3 -3
  353. package/docs/_config.yml +2 -2
  354. package/docs/_layouts/default.html +9 -9
  355. package/docs/concepts/typebox.md +1 -1
  356. package/docs/docs.json +1 -1
  357. package/docs/northflank.mdx +7 -7
  358. package/docs/railway.mdx +3 -3
  359. package/docs/render.mdx +5 -5
  360. package/docs/start/lore.md +2 -2
  361. package/extensions/bluebubbles/index.ts +2 -2
  362. package/extensions/bluebubbles/package.json +1 -1
  363. package/extensions/bluebubbles/src/accounts.ts +8 -8
  364. package/extensions/bluebubbles/src/actions.test.ts +22 -22
  365. package/extensions/bluebubbles/src/actions.ts +5 -5
  366. package/extensions/bluebubbles/src/attachments.ts +2 -2
  367. package/extensions/bluebubbles/src/channel.ts +16 -16
  368. package/extensions/bluebubbles/src/chat.ts +2 -2
  369. package/extensions/bluebubbles/src/media-send.ts +2 -2
  370. package/extensions/bluebubbles/src/monitor.test.ts +46 -46
  371. package/extensions/bluebubbles/src/monitor.ts +5 -5
  372. package/extensions/bluebubbles/src/onboarding.ts +7 -7
  373. package/extensions/bluebubbles/src/reactions.ts +2 -2
  374. package/extensions/bluebubbles/src/send.ts +2 -2
  375. package/extensions/copilot-proxy/README.md +1 -1
  376. package/extensions/copilot-proxy/package.json +1 -1
  377. package/extensions/diagnostics-otel/index.ts +2 -2
  378. package/extensions/diagnostics-otel/package.json +1 -1
  379. package/extensions/diagnostics-otel/src/service.ts +3 -3
  380. package/extensions/discord/index.ts +2 -2
  381. package/extensions/discord/package.json +1 -1
  382. package/extensions/google-antigravity-auth/README.md +1 -1
  383. package/extensions/google-antigravity-auth/index.ts +1 -1
  384. package/extensions/google-antigravity-auth/package.json +1 -1
  385. package/extensions/google-gemini-cli-auth/README.md +1 -1
  386. package/extensions/google-gemini-cli-auth/oauth.ts +1 -1
  387. package/extensions/google-gemini-cli-auth/package.json +1 -1
  388. package/extensions/googlechat/index.ts +3 -3
  389. package/extensions/googlechat/package.json +1 -1
  390. package/extensions/googlechat/src/accounts.ts +8 -8
  391. package/extensions/googlechat/src/actions.ts +6 -6
  392. package/extensions/googlechat/src/channel.ts +21 -21
  393. package/extensions/googlechat/src/monitor.ts +8 -8
  394. package/extensions/googlechat/src/onboarding.ts +10 -10
  395. package/extensions/imessage/index.ts +2 -2
  396. package/extensions/imessage/package.json +1 -1
  397. package/extensions/line/index.ts +2 -2
  398. package/extensions/line/package.json +1 -1
  399. package/extensions/line/src/card-command.ts +2 -2
  400. package/extensions/line/src/channel.logout.test.ts +4 -4
  401. package/extensions/line/src/channel.sendPayload.test.ts +8 -8
  402. package/extensions/line/src/channel.ts +3 -3
  403. package/extensions/llm-task/README.md +3 -3
  404. package/extensions/llm-task/index.ts +2 -2
  405. package/extensions/llm-task/package.json +1 -1
  406. package/extensions/llm-task/src/llm-task-tool.ts +4 -4
  407. package/extensions/lobster/README.md +6 -6
  408. package/extensions/lobster/index.ts +2 -2
  409. package/extensions/lobster/src/lobster-tool.test.ts +4 -4
  410. package/extensions/lobster/src/lobster-tool.ts +2 -2
  411. package/extensions/matrix/index.ts +2 -2
  412. package/extensions/matrix/package.json +1 -1
  413. package/extensions/matrix/src/matrix/client/config.ts +1 -1
  414. package/extensions/matrix/src/matrix/monitor/handler.ts +1 -1
  415. package/extensions/matrix/src/onboarding.ts +1 -1
  416. package/extensions/mattermost/index.ts +2 -2
  417. package/extensions/mattermost/package.json +1 -1
  418. package/extensions/mattermost/src/mattermost/accounts.ts +8 -8
  419. package/extensions/mattermost/src/mattermost/monitor-helpers.ts +5 -5
  420. package/extensions/mattermost/src/mattermost/monitor.ts +2 -2
  421. package/extensions/mattermost/src/onboarding-helpers.ts +3 -3
  422. package/extensions/mattermost/src/onboarding.ts +2 -2
  423. package/extensions/memory-core/index.ts +2 -2
  424. package/extensions/memory-core/package.json +1 -1
  425. package/extensions/memory-lancedb/index.ts +3 -3
  426. package/extensions/memory-lancedb/package.json +1 -1
  427. package/extensions/msteams/index.ts +2 -2
  428. package/extensions/msteams/package.json +1 -1
  429. package/extensions/msteams/src/channel.directory.test.ts +2 -2
  430. package/extensions/msteams/src/channel.ts +2 -2
  431. package/extensions/msteams/src/graph-upload.ts +4 -4
  432. package/extensions/msteams/src/monitor-handler.ts +2 -2
  433. package/extensions/msteams/src/monitor.ts +2 -2
  434. package/extensions/msteams/src/onboarding.ts +9 -9
  435. package/extensions/msteams/src/reply-dispatcher.ts +2 -2
  436. package/extensions/msteams/src/send-context.ts +2 -2
  437. package/extensions/msteams/src/send.ts +4 -4
  438. package/extensions/nextcloud-talk/index.ts +2 -2
  439. package/extensions/nextcloud-talk/package.json +1 -1
  440. package/extensions/nextcloud-talk/src/channel.ts +7 -7
  441. package/extensions/nextcloud-talk/src/inbound.ts +7 -7
  442. package/extensions/nextcloud-talk/src/onboarding.ts +1 -1
  443. package/extensions/nostr/README.md +2 -2
  444. package/extensions/nostr/index.ts +5 -5
  445. package/extensions/nostr/package.json +1 -1
  446. package/extensions/nostr/src/types.ts +4 -4
  447. package/extensions/open-prose/index.ts +2 -2
  448. package/extensions/qwen-portal-auth/README.md +1 -1
  449. package/extensions/signal/index.ts +2 -2
  450. package/extensions/signal/package.json +1 -1
  451. package/extensions/slack/index.ts +2 -2
  452. package/extensions/slack/package.json +1 -1
  453. package/extensions/telegram/index.ts +2 -2
  454. package/extensions/telegram/package.json +1 -1
  455. package/extensions/telegram/src/channel.ts +2 -2
  456. package/extensions/tlon/README.md +2 -2
  457. package/extensions/tlon/index.ts +2 -2
  458. package/extensions/tlon/package.json +1 -1
  459. package/extensions/tlon/src/channel.ts +13 -13
  460. package/extensions/tlon/src/monitor/index.ts +3 -3
  461. package/extensions/tlon/src/onboarding.ts +3 -3
  462. package/extensions/tlon/src/types.ts +3 -3
  463. package/extensions/twitch/README.md +1 -1
  464. package/extensions/twitch/index.ts +2 -2
  465. package/extensions/twitch/package.json +1 -1
  466. package/extensions/twitch/src/config.ts +3 -3
  467. package/extensions/twitch/src/monitor.ts +3 -3
  468. package/extensions/twitch/src/onboarding.ts +9 -9
  469. package/extensions/twitch/src/outbound.test.ts +2 -2
  470. package/extensions/twitch/src/plugin.test.ts +2 -2
  471. package/extensions/twitch/src/plugin.ts +8 -8
  472. package/extensions/twitch/src/send.test.ts +2 -2
  473. package/extensions/twitch/src/send.ts +4 -4
  474. package/extensions/twitch/src/token.test.ts +8 -8
  475. package/extensions/twitch/src/token.ts +3 -3
  476. package/extensions/twitch/src/twitch-client.ts +3 -3
  477. package/extensions/twitch/src/types.ts +3 -3
  478. package/extensions/twitch/src/utils/markdown.ts +1 -1
  479. package/extensions/voice-call/README.md +3 -3
  480. package/extensions/voice-call/package.json +1 -1
  481. package/extensions/voice-call/src/core-bridge.ts +2 -2
  482. package/extensions/voice-call/src/response-generator.ts +1 -1
  483. package/extensions/whatsapp/index.ts +2 -2
  484. package/extensions/whatsapp/package.json +1 -1
  485. package/extensions/zalo/README.md +1 -1
  486. package/extensions/zalo/index.ts +2 -2
  487. package/extensions/zalo/package.json +1 -1
  488. package/extensions/zalo/src/accounts.ts +8 -8
  489. package/extensions/zalo/src/actions.ts +4 -4
  490. package/extensions/zalo/src/channel.directory.test.ts +2 -2
  491. package/extensions/zalo/src/channel.ts +18 -18
  492. package/extensions/zalo/src/monitor.ts +9 -9
  493. package/extensions/zalo/src/monitor.webhook.test.ts +2 -2
  494. package/extensions/zalo/src/onboarding.ts +24 -24
  495. package/extensions/zalo/src/send.ts +2 -2
  496. package/extensions/zalouser/README.md +2 -2
  497. package/extensions/zalouser/index.ts +2 -2
  498. package/extensions/zalouser/package.json +1 -1
  499. package/extensions/zalouser/src/accounts.ts +9 -9
  500. package/extensions/zalouser/src/channel.ts +24 -24
  501. package/extensions/zalouser/src/monitor.ts +4 -4
  502. package/extensions/zalouser/src/onboarding.ts +28 -28
  503. package/package.json +13 -251
  504. package/skills/nano-banana-pro/scripts/generate_image.py +1 -1
  505. package/skills/tmux/scripts/find-sessions.sh +1 -1
  506. package/CHANGELOG.md +0 -102
  507. package/README-header.png +0 -0
  508. package/git-hooks/pre-commit +0 -4
  509. package/scripts/format-staged.js +0 -148
  510. package/scripts/postinstall.js +0 -300
  511. package/scripts/setup-git-hooks.js +0 -96
@@ -1,9 +1,11 @@
1
1
  function normalizeProviderId(provider) {
2
- if (!provider)
2
+ if (!provider) {
3
3
  return "";
4
+ }
4
5
  const normalized = provider.trim().toLowerCase();
5
- if (normalized === "z.ai" || normalized === "z-ai")
6
+ if (normalized === "z.ai" || normalized === "z-ai") {
6
7
  return "zai";
8
+ }
7
9
  return normalized;
8
10
  }
9
11
  export function isBinaryThinkingProvider(provider) {
@@ -11,38 +13,52 @@ export function isBinaryThinkingProvider(provider) {
11
13
  }
12
14
  export const XHIGH_MODEL_REFS = [
13
15
  "openai/gpt-5.2",
16
+ "openai-codex/gpt-5.3-codex",
14
17
  "openai-codex/gpt-5.2-codex",
15
18
  "openai-codex/gpt-5.1-codex",
19
+ "github-copilot/gpt-5.2-codex",
20
+ "github-copilot/gpt-5.2",
16
21
  ];
17
22
  const XHIGH_MODEL_SET = new Set(XHIGH_MODEL_REFS.map((entry) => entry.toLowerCase()));
18
23
  const XHIGH_MODEL_IDS = new Set(XHIGH_MODEL_REFS.map((entry) => entry.split("/")[1]?.toLowerCase()).filter((entry) => Boolean(entry)));
19
24
  // Normalize user-provided thinking level strings to the canonical enum.
20
25
  export function normalizeThinkLevel(raw) {
21
- if (!raw)
26
+ if (!raw) {
22
27
  return undefined;
23
- const key = raw.toLowerCase();
24
- if (["off"].includes(key))
28
+ }
29
+ const key = raw.trim().toLowerCase();
30
+ const collapsed = key.replace(/[\s_-]+/g, "");
31
+ if (collapsed === "xhigh" || collapsed === "extrahigh") {
32
+ return "xhigh";
33
+ }
34
+ if (["off"].includes(key)) {
25
35
  return "off";
26
- if (["on", "enable", "enabled"].includes(key))
36
+ }
37
+ if (["on", "enable", "enabled"].includes(key)) {
27
38
  return "low";
28
- if (["min", "minimal"].includes(key))
39
+ }
40
+ if (["min", "minimal"].includes(key)) {
29
41
  return "minimal";
30
- if (["low", "thinkhard", "think-hard", "think_hard"].includes(key))
42
+ }
43
+ if (["low", "thinkhard", "think-hard", "think_hard"].includes(key)) {
31
44
  return "low";
32
- if (["mid", "med", "medium", "thinkharder", "think-harder", "harder"].includes(key))
45
+ }
46
+ if (["mid", "med", "medium", "thinkharder", "think-harder", "harder"].includes(key)) {
33
47
  return "medium";
34
- if (["high", "ultra", "ultrathink", "think-hard", "thinkhardest", "highest", "max"].includes(key))
48
+ }
49
+ if (["high", "ultra", "ultrathink", "think-hard", "thinkhardest", "highest", "max"].includes(key)) {
35
50
  return "high";
36
- if (["xhigh", "x-high", "x_high"].includes(key))
37
- return "xhigh";
38
- if (["think"].includes(key))
51
+ }
52
+ if (["think"].includes(key)) {
39
53
  return "minimal";
54
+ }
40
55
  return undefined;
41
56
  }
42
57
  export function supportsXHighThinking(provider, model) {
43
58
  const modelKey = model?.trim().toLowerCase();
44
- if (!modelKey)
59
+ if (!modelKey) {
45
60
  return false;
61
+ }
46
62
  const providerKey = provider?.trim().toLowerCase();
47
63
  if (providerKey) {
48
64
  return XHIGH_MODEL_SET.has(`${providerKey}/${modelKey}`);
@@ -51,13 +67,15 @@ export function supportsXHighThinking(provider, model) {
51
67
  }
52
68
  export function listThinkingLevels(provider, model) {
53
69
  const levels = ["off", "minimal", "low", "medium", "high"];
54
- if (supportsXHighThinking(provider, model))
70
+ if (supportsXHighThinking(provider, model)) {
55
71
  levels.push("xhigh");
72
+ }
56
73
  return levels;
57
74
  }
58
75
  export function listThinkingLevelLabels(provider, model) {
59
- if (isBinaryThinkingProvider(provider))
76
+ if (isBinaryThinkingProvider(provider)) {
60
77
  return ["off", "on"];
78
+ }
61
79
  return listThinkingLevels(provider, model);
62
80
  }
63
81
  export function formatThinkingLevels(provider, model, separator = ", ") {
@@ -65,53 +83,69 @@ export function formatThinkingLevels(provider, model, separator = ", ") {
65
83
  }
66
84
  export function formatXHighModelHint() {
67
85
  const refs = [...XHIGH_MODEL_REFS];
68
- if (refs.length === 0)
86
+ if (refs.length === 0) {
69
87
  return "unknown model";
70
- if (refs.length === 1)
88
+ }
89
+ if (refs.length === 1) {
71
90
  return refs[0];
72
- if (refs.length === 2)
91
+ }
92
+ if (refs.length === 2) {
73
93
  return `${refs[0]} or ${refs[1]}`;
94
+ }
74
95
  return `${refs.slice(0, -1).join(", ")} or ${refs[refs.length - 1]}`;
75
96
  }
76
97
  // Normalize verbose flags used to toggle agent verbosity.
77
98
  export function normalizeVerboseLevel(raw) {
78
- if (!raw)
99
+ if (!raw) {
79
100
  return undefined;
101
+ }
80
102
  const key = raw.toLowerCase();
81
- if (["off", "false", "no", "0"].includes(key))
103
+ if (["off", "false", "no", "0"].includes(key)) {
82
104
  return "off";
83
- if (["full", "all", "everything"].includes(key))
105
+ }
106
+ if (["full", "all", "everything"].includes(key)) {
84
107
  return "full";
85
- if (["on", "minimal", "true", "yes", "1"].includes(key))
108
+ }
109
+ if (["on", "minimal", "true", "yes", "1"].includes(key)) {
86
110
  return "on";
111
+ }
87
112
  return undefined;
88
113
  }
89
114
  // Normalize system notice flags used to toggle system notifications.
90
115
  export function normalizeNoticeLevel(raw) {
91
- if (!raw)
116
+ if (!raw) {
92
117
  return undefined;
118
+ }
93
119
  const key = raw.toLowerCase();
94
- if (["off", "false", "no", "0"].includes(key))
120
+ if (["off", "false", "no", "0"].includes(key)) {
95
121
  return "off";
96
- if (["full", "all", "everything"].includes(key))
122
+ }
123
+ if (["full", "all", "everything"].includes(key)) {
97
124
  return "full";
98
- if (["on", "minimal", "true", "yes", "1"].includes(key))
125
+ }
126
+ if (["on", "minimal", "true", "yes", "1"].includes(key)) {
99
127
  return "on";
128
+ }
100
129
  return undefined;
101
130
  }
102
131
  // Normalize response-usage display modes used to toggle per-response usage footers.
103
132
  export function normalizeUsageDisplay(raw) {
104
- if (!raw)
133
+ if (!raw) {
105
134
  return undefined;
135
+ }
106
136
  const key = raw.toLowerCase();
107
- if (["off", "false", "no", "0", "disable", "disabled"].includes(key))
137
+ if (["off", "false", "no", "0", "disable", "disabled"].includes(key)) {
108
138
  return "off";
109
- if (["on", "true", "yes", "1", "enable", "enabled"].includes(key))
139
+ }
140
+ if (["on", "true", "yes", "1", "enable", "enabled"].includes(key)) {
110
141
  return "tokens";
111
- if (["tokens", "token", "tok", "minimal", "min"].includes(key))
142
+ }
143
+ if (["tokens", "token", "tok", "minimal", "min"].includes(key)) {
112
144
  return "tokens";
113
- if (["full", "session"].includes(key))
145
+ }
146
+ if (["full", "session"].includes(key)) {
114
147
  return "full";
148
+ }
115
149
  return undefined;
116
150
  }
117
151
  export function resolveResponseUsageMode(raw) {
@@ -119,36 +153,47 @@ export function resolveResponseUsageMode(raw) {
119
153
  }
120
154
  // Normalize elevated flags used to toggle elevated bash permissions.
121
155
  export function normalizeElevatedLevel(raw) {
122
- if (!raw)
156
+ if (!raw) {
123
157
  return undefined;
158
+ }
124
159
  const key = raw.toLowerCase();
125
- if (["off", "false", "no", "0"].includes(key))
160
+ if (["off", "false", "no", "0"].includes(key)) {
126
161
  return "off";
127
- if (["full", "auto", "auto-approve", "autoapprove"].includes(key))
162
+ }
163
+ if (["full", "auto", "auto-approve", "autoapprove"].includes(key)) {
128
164
  return "full";
129
- if (["ask", "prompt", "approval", "approve"].includes(key))
165
+ }
166
+ if (["ask", "prompt", "approval", "approve"].includes(key)) {
130
167
  return "ask";
131
- if (["on", "true", "yes", "1"].includes(key))
168
+ }
169
+ if (["on", "true", "yes", "1"].includes(key)) {
132
170
  return "on";
171
+ }
133
172
  return undefined;
134
173
  }
135
174
  export function resolveElevatedMode(level) {
136
- if (!level || level === "off")
175
+ if (!level || level === "off") {
137
176
  return "off";
138
- if (level === "full")
177
+ }
178
+ if (level === "full") {
139
179
  return "full";
180
+ }
140
181
  return "ask";
141
182
  }
142
183
  // Normalize reasoning visibility flags used to toggle reasoning exposure.
143
184
  export function normalizeReasoningLevel(raw) {
144
- if (!raw)
185
+ if (!raw) {
145
186
  return undefined;
187
+ }
146
188
  const key = raw.toLowerCase();
147
- if (["off", "false", "no", "0", "hide", "hidden", "disable", "disabled"].includes(key))
189
+ if (["off", "false", "no", "0", "hide", "hidden", "disable", "disabled"].includes(key)) {
148
190
  return "off";
149
- if (["on", "true", "yes", "1", "show", "visible", "enable", "enabled"].includes(key))
191
+ }
192
+ if (["on", "true", "yes", "1", "show", "visible", "enable", "enabled"].includes(key)) {
150
193
  return "on";
151
- if (["stream", "streaming", "draft", "live"].includes(key))
194
+ }
195
+ if (["stream", "streaming", "draft", "live"].includes(key)) {
152
196
  return "stream";
197
+ }
153
198
  return undefined;
154
199
  }
@@ -6,6 +6,19 @@ export async function startBrowserBridgeServer(params) {
6
6
  const port = params.port ?? 0;
7
7
  const app = express();
8
8
  app.use(express.json({ limit: "1mb" }));
9
+ app.use((req, res, next) => {
10
+ const ctrl = new AbortController();
11
+ const abort = () => ctrl.abort(new Error("request aborted"));
12
+ req.once("aborted", abort);
13
+ res.once("close", () => {
14
+ if (!res.writableEnded) {
15
+ abort();
16
+ }
17
+ });
18
+ // Make the signal available to browser route handlers (best-effort).
19
+ req.signal = ctrl.signal;
20
+ next();
21
+ });
9
22
  const authToken = params.authToken?.trim();
10
23
  if (authToken) {
11
24
  app.use((req, res, next) => {
@@ -1,30 +1,26 @@
1
1
  import WebSocket from "ws";
2
+ import { isLoopbackHost } from "../gateway/net.js";
2
3
  import { rawDataToString } from "../infra/ws.js";
3
- export function isLoopbackHost(host) {
4
- const h = host.trim().toLowerCase();
5
- return (h === "localhost" ||
6
- h === "127.0.0.1" ||
7
- h === "0.0.0.0" ||
8
- h === "[::1]" ||
9
- h === "::1" ||
10
- h === "[::]" ||
11
- h === "::");
12
- }
4
+ import { getChromeExtensionRelayAuthHeaders } from "./extension-relay.js";
5
+ export { isLoopbackHost };
13
6
  export function getHeadersWithAuth(url, headers = {}) {
7
+ const relayHeaders = getChromeExtensionRelayAuthHeaders(url);
8
+ const mergedHeaders = { ...relayHeaders, ...headers };
14
9
  try {
15
10
  const parsed = new URL(url);
16
- const hasAuthHeader = Object.keys(headers).some((key) => key.toLowerCase() === "authorization");
17
- if (hasAuthHeader)
18
- return headers;
11
+ const hasAuthHeader = Object.keys(mergedHeaders).some((key) => key.toLowerCase() === "authorization");
12
+ if (hasAuthHeader) {
13
+ return mergedHeaders;
14
+ }
19
15
  if (parsed.username || parsed.password) {
20
16
  const auth = Buffer.from(`${parsed.username}:${parsed.password}`).toString("base64");
21
- return { ...headers, Authorization: `Basic ${auth}` };
17
+ return { ...mergedHeaders, Authorization: `Basic ${auth}` };
22
18
  }
23
19
  }
24
20
  catch {
25
21
  // ignore
26
22
  }
27
- return headers;
23
+ return mergedHeaders;
28
24
  }
29
25
  export function appendCdpPath(cdpUrl, path) {
30
26
  const url = new URL(cdpUrl);
@@ -36,17 +32,18 @@ export function appendCdpPath(cdpUrl, path) {
36
32
  function createCdpSender(ws) {
37
33
  let nextId = 1;
38
34
  const pending = new Map();
39
- const send = (method, params) => {
35
+ const send = (method, params, sessionId) => {
40
36
  const id = nextId++;
41
- const msg = { id, method, params };
37
+ const msg = { id, method, params, sessionId };
42
38
  ws.send(JSON.stringify(msg));
43
39
  return new Promise((resolve, reject) => {
44
40
  pending.set(id, { resolve, reject });
45
41
  });
46
42
  };
47
43
  const closeWithError = (err) => {
48
- for (const [, p] of pending)
44
+ for (const [, p] of pending) {
49
45
  p.reject(err);
46
+ }
50
47
  pending.clear();
51
48
  try {
52
49
  ws.close();
@@ -55,14 +52,19 @@ function createCdpSender(ws) {
55
52
  // ignore
56
53
  }
57
54
  };
55
+ ws.on("error", (err) => {
56
+ closeWithError(err instanceof Error ? err : new Error(String(err)));
57
+ });
58
58
  ws.on("message", (data) => {
59
59
  try {
60
60
  const parsed = JSON.parse(rawDataToString(data));
61
- if (typeof parsed.id !== "number")
61
+ if (typeof parsed.id !== "number") {
62
62
  return;
63
+ }
63
64
  const p = pending.get(parsed.id);
64
- if (!p)
65
+ if (!p) {
65
66
  return;
67
+ }
66
68
  pending.delete(parsed.id);
67
69
  if (parsed.error?.message) {
68
70
  p.reject(new Error(parsed.error.message));
@@ -85,8 +87,9 @@ export async function fetchJson(url, timeoutMs = 1500, init) {
85
87
  try {
86
88
  const headers = getHeadersWithAuth(url, init?.headers || {});
87
89
  const res = await fetch(url, { ...init, headers, signal: ctrl.signal });
88
- if (!res.ok)
90
+ if (!res.ok) {
89
91
  throw new Error(`HTTP ${res.status}`);
92
+ }
90
93
  return (await res.json());
91
94
  }
92
95
  finally {
@@ -99,8 +102,9 @@ export async function fetchOk(url, timeoutMs = 1500, init) {
99
102
  try {
100
103
  const headers = getHeadersWithAuth(url, init?.headers || {});
101
104
  const res = await fetch(url, { ...init, headers, signal: ctrl.signal });
102
- if (!res.ok)
105
+ if (!res.ok) {
103
106
  throw new Error(`HTTP ${res.status}`);
107
+ }
104
108
  }
105
109
  finally {
106
110
  clearTimeout(t);
@@ -108,16 +112,26 @@ export async function fetchOk(url, timeoutMs = 1500, init) {
108
112
  }
109
113
  export async function withCdpSocket(wsUrl, fn, opts) {
110
114
  const headers = getHeadersWithAuth(wsUrl, opts?.headers ?? {});
115
+ const handshakeTimeoutMs = typeof opts?.handshakeTimeoutMs === "number" && Number.isFinite(opts.handshakeTimeoutMs)
116
+ ? Math.max(1, Math.floor(opts.handshakeTimeoutMs))
117
+ : 5000;
111
118
  const ws = new WebSocket(wsUrl, {
112
- handshakeTimeout: 5000,
119
+ handshakeTimeout: handshakeTimeoutMs,
113
120
  ...(Object.keys(headers).length ? { headers } : {}),
114
121
  });
115
122
  const { send, closeWithError } = createCdpSender(ws);
116
123
  const openPromise = new Promise((resolve, reject) => {
117
124
  ws.once("open", () => resolve());
118
125
  ws.once("error", (err) => reject(err));
126
+ ws.once("close", () => reject(new Error("CDP socket closed")));
119
127
  });
120
- await openPromise;
128
+ try {
129
+ await openPromise;
130
+ }
131
+ catch (err) {
132
+ closeWithError(err instanceof Error ? err : new Error(String(err)));
133
+ throw err;
134
+ }
121
135
  try {
122
136
  return await fn(send);
123
137
  }
@@ -7,7 +7,7 @@ function isAbsoluteHttp(url) {
7
7
  function enhanceBrowserFetchError(url, err, timeoutMs) {
8
8
  const hint = isAbsoluteHttp(url)
9
9
  ? "If this is a sandboxed session, ensure the sandbox browser is running and try again."
10
- : `Start (or restart) the Moltbot gateway (Moltbot.app menubar, or \`${formatCliCommand("poolbot gateway")}\`) and try again.`;
10
+ : `Start (or restart) the Poolbot gateway (Poolbot.app menubar, or \`${formatCliCommand("poolbot gateway")}\`) and try again.`;
11
11
  const msg = String(err);
12
12
  const msgLower = msg.toLowerCase();
13
13
  const looksLikeTimeout = msgLower.includes("timed out") ||
@@ -23,7 +23,18 @@ function enhanceBrowserFetchError(url, err, timeoutMs) {
23
23
  async function fetchHttpJson(url, init) {
24
24
  const timeoutMs = init.timeoutMs ?? 5000;
25
25
  const ctrl = new AbortController();
26
- const t = setTimeout(() => ctrl.abort(), timeoutMs);
26
+ const upstreamSignal = init.signal;
27
+ let upstreamAbortListener;
28
+ if (upstreamSignal) {
29
+ if (upstreamSignal.aborted) {
30
+ ctrl.abort(upstreamSignal.reason);
31
+ }
32
+ else {
33
+ upstreamAbortListener = () => ctrl.abort(upstreamSignal.reason);
34
+ upstreamSignal.addEventListener("abort", upstreamAbortListener, { once: true });
35
+ }
36
+ }
37
+ const t = setTimeout(() => ctrl.abort(new Error("timed out")), timeoutMs);
27
38
  try {
28
39
  const res = await fetch(url, { ...init, signal: ctrl.signal });
29
40
  if (!res.ok) {
@@ -34,6 +45,9 @@ async function fetchHttpJson(url, init) {
34
45
  }
35
46
  finally {
36
47
  clearTimeout(t);
48
+ if (upstreamSignal && upstreamAbortListener) {
49
+ upstreamSignal.removeEventListener("abort", upstreamAbortListener);
50
+ }
37
51
  }
38
52
  }
39
53
  export async function fetchBrowserJson(url, init) {
@@ -61,6 +75,29 @@ export async function fetchBrowserJson(url, init) {
61
75
  // keep as string
62
76
  }
63
77
  }
78
+ const abortCtrl = new AbortController();
79
+ const upstreamSignal = init?.signal;
80
+ let upstreamAbortListener;
81
+ if (upstreamSignal) {
82
+ if (upstreamSignal.aborted) {
83
+ abortCtrl.abort(upstreamSignal.reason);
84
+ }
85
+ else {
86
+ upstreamAbortListener = () => abortCtrl.abort(upstreamSignal.reason);
87
+ upstreamSignal.addEventListener("abort", upstreamAbortListener, { once: true });
88
+ }
89
+ }
90
+ let abortListener;
91
+ const abortPromise = abortCtrl.signal.aborted
92
+ ? Promise.reject(abortCtrl.signal.reason ?? new Error("aborted"))
93
+ : new Promise((_, reject) => {
94
+ abortListener = () => reject(abortCtrl.signal.reason ?? new Error("aborted"));
95
+ abortCtrl.signal.addEventListener("abort", abortListener, { once: true });
96
+ });
97
+ let timer;
98
+ if (timeoutMs) {
99
+ timer = setTimeout(() => abortCtrl.abort(new Error("timed out")), timeoutMs);
100
+ }
64
101
  const dispatchPromise = dispatcher.dispatch({
65
102
  method: init?.method?.toUpperCase() === "DELETE"
66
103
  ? "DELETE"
@@ -70,13 +107,19 @@ export async function fetchBrowserJson(url, init) {
70
107
  path: parsed.pathname,
71
108
  query,
72
109
  body,
110
+ signal: abortCtrl.signal,
111
+ });
112
+ const result = await Promise.race([dispatchPromise, abortPromise]).finally(() => {
113
+ if (timer) {
114
+ clearTimeout(timer);
115
+ }
116
+ if (abortListener) {
117
+ abortCtrl.signal.removeEventListener("abort", abortListener);
118
+ }
119
+ if (upstreamSignal && upstreamAbortListener) {
120
+ upstreamSignal.removeEventListener("abort", upstreamAbortListener);
121
+ }
73
122
  });
74
- const result = await (timeoutMs
75
- ? Promise.race([
76
- dispatchPromise,
77
- new Promise((_, reject) => setTimeout(() => reject(new Error("timed out")), timeoutMs)),
78
- ])
79
- : dispatchPromise);
80
123
  if (result.status >= 400) {
81
124
  const message = result.body && typeof result.body === "object" && "error" in result.body
82
125
  ? String(result.body.error)
@@ -1,17 +1,8 @@
1
1
  import { deriveDefaultBrowserCdpPortRange, deriveDefaultBrowserControlPort, DEFAULT_BROWSER_CONTROL_PORT, } from "../config/port-defaults.js";
2
2
  import { resolveGatewayPort } from "../config/paths.js";
3
+ import { isLoopbackHost } from "../gateway/net.js";
3
4
  import { DEFAULT_CLAWD_BROWSER_COLOR, DEFAULT_CLAWD_BROWSER_ENABLED, DEFAULT_BROWSER_EVALUATE_ENABLED, DEFAULT_BROWSER_DEFAULT_PROFILE_NAME, DEFAULT_CLAWD_BROWSER_PROFILE_NAME, } from "./constants.js";
4
5
  import { CDP_PORT_RANGE_START, getUsedPorts } from "./profiles.js";
5
- function isLoopbackHost(host) {
6
- const h = host.trim().toLowerCase();
7
- return (h === "localhost" ||
8
- h === "127.0.0.1" ||
9
- h === "0.0.0.0" ||
10
- h === "[::1]" ||
11
- h === "::1" ||
12
- h === "[::]" ||
13
- h === "::");
14
- }
15
6
  function normalizeHexColor(raw) {
16
7
  const value = (raw ?? "").trim();
17
8
  if (!value)
@@ -62,7 +53,7 @@ function ensureDefaultProfile(profiles, defaultColor, legacyCdpPort, derivedDefa
62
53
  /**
63
54
  * Ensure a built-in "chrome" profile exists for the Chrome extension relay.
64
55
  *
65
- * Note: this is a Moltbot browser profile (routing config), not a Chrome user profile.
56
+ * Note: this is a Poolbot browser profile (routing config), not a Chrome user profile.
66
57
  * It points at the local relay CDP endpoint (controlPort + 1).
67
58
  */
68
59
  function ensureDefaultChromeExtensionProfile(profiles, controlPort) {