@poolzin/pool-bot 2026.2.21 → 2026.2.22

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 (369) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/agents/api-key-rotation.js +47 -0
  3. package/dist/agents/apply-patch-update.js +19 -9
  4. package/dist/agents/apply-patch.js +72 -47
  5. package/dist/agents/bash-tools.exec.js +141 -559
  6. package/dist/agents/cli-backends.js +49 -6
  7. package/dist/agents/cli-runner/helpers.js +69 -152
  8. package/dist/agents/cli-runner.js +70 -19
  9. package/dist/agents/identity.js +20 -1
  10. package/dist/agents/image-sanitization.js +9 -0
  11. package/dist/agents/live-auth-keys.js +123 -26
  12. package/dist/agents/live-model-filter.js +13 -4
  13. package/dist/agents/model-catalog.js +40 -9
  14. package/dist/agents/model-forward-compat.js +60 -23
  15. package/dist/agents/model-selection.js +134 -41
  16. package/dist/agents/pi-auth-json.js +2 -2
  17. package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
  18. package/dist/agents/pi-embedded-helpers/errors.js +140 -15
  19. package/dist/agents/pi-embedded-helpers/images.js +22 -12
  20. package/dist/agents/pi-embedded-helpers.js +2 -2
  21. package/dist/agents/pi-embedded-runner/abort.js +10 -3
  22. package/dist/agents/pi-embedded-runner/compact.js +230 -32
  23. package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
  24. package/dist/agents/pi-embedded-runner/google.js +109 -19
  25. package/dist/agents/pi-embedded-runner/history.js +35 -17
  26. package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
  27. package/dist/agents/pi-embedded-runner/run/images.js +81 -55
  28. package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
  29. package/dist/agents/pi-embedded-runner/run.js +193 -25
  30. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
  31. package/dist/agents/pi-embedded-runner/runs.js +17 -8
  32. package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
  33. package/dist/agents/pi-embedded-runner.js +1 -1
  34. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
  35. package/dist/agents/pi-embedded-subscribe.js +37 -0
  36. package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
  37. package/dist/agents/pi-model-discovery.js +9 -2
  38. package/dist/agents/pi-tool-definition-adapter.js +60 -8
  39. package/dist/agents/pi-tools.before-tool-call.js +1 -1
  40. package/dist/agents/pi-tools.js +113 -94
  41. package/dist/agents/pi-tools.read.js +337 -38
  42. package/dist/agents/poolbot-tools.js +14 -5
  43. package/dist/agents/sandbox/docker.js +10 -5
  44. package/dist/agents/sandbox/registry.js +96 -46
  45. package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
  46. package/dist/agents/sandbox-paths.js +43 -10
  47. package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
  48. package/dist/agents/session-tool-result-guard.js +39 -39
  49. package/dist/agents/session-transcript-repair.js +36 -33
  50. package/dist/agents/session-write-lock.js +62 -44
  51. package/dist/agents/skills/frontmatter.js +49 -88
  52. package/dist/agents/skills/workspace.js +335 -28
  53. package/dist/agents/subagent-announce.js +508 -174
  54. package/dist/agents/subagent-registry.js +45 -4
  55. package/dist/agents/subagent-spawn.js +16 -33
  56. package/dist/agents/system-prompt-report.js +27 -10
  57. package/dist/agents/system-prompt.js +26 -32
  58. package/dist/agents/tool-call-id.js +69 -17
  59. package/dist/agents/tool-display-common.js +1 -1
  60. package/dist/agents/tool-images.js +64 -31
  61. package/dist/agents/tools/canvas-tool.js +17 -11
  62. package/dist/agents/tools/common.js +37 -19
  63. package/dist/agents/tools/cron-tool.js +40 -38
  64. package/dist/agents/tools/gateway.js +70 -2
  65. package/dist/agents/tools/message-tool.js +181 -40
  66. package/dist/agents/tools/nodes-tool.js +128 -36
  67. package/dist/agents/tools/nodes-utils.js +12 -38
  68. package/dist/agents/tools/session-status-tool.js +24 -71
  69. package/dist/agents/tools/sessions-helpers.js +38 -210
  70. package/dist/agents/tools/sessions-spawn-tool.js +28 -198
  71. package/dist/agents/tools/telegram-actions.js +58 -7
  72. package/dist/agents/tools/web-fetch-utils.js +112 -7
  73. package/dist/agents/tools/web-fetch.js +279 -175
  74. package/dist/agents/tools/web-shared.js +71 -8
  75. package/dist/agents/usage.js +25 -16
  76. package/dist/auto-reply/commands-registry.data.js +85 -11
  77. package/dist/auto-reply/dispatch.js +40 -21
  78. package/dist/auto-reply/reply/abort.js +102 -33
  79. package/dist/auto-reply/reply/commands-core.js +82 -33
  80. package/dist/auto-reply/reply/commands-export-session.js +1 -1
  81. package/dist/auto-reply/reply/commands-info.js +41 -12
  82. package/dist/auto-reply/reply/commands-subagents.js +352 -100
  83. package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
  84. package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
  85. package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
  86. package/dist/auto-reply/reply/inbound-meta.js +12 -1
  87. package/dist/auto-reply/reply/mentions.js +18 -11
  88. package/dist/auto-reply/reply/normalize-reply.js +17 -8
  89. package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
  90. package/dist/auto-reply/reply/session.js +102 -21
  91. package/dist/auto-reply/reply/streaming-directives.js +16 -5
  92. package/dist/auto-reply/status.js +73 -50
  93. package/dist/browser/extension-relay.js +3 -3
  94. package/dist/browser/http-auth.js +1 -1
  95. package/dist/browser/paths.js +2 -2
  96. package/dist/build-info.json +3 -3
  97. package/dist/channels/allowlist-match.js +20 -0
  98. package/dist/channels/allowlists/resolve-utils.js +65 -2
  99. package/dist/channels/chat-type.js +8 -4
  100. package/dist/channels/dock.js +127 -35
  101. package/dist/channels/draft-stream-loop.js +6 -2
  102. package/dist/channels/plugins/actions/telegram.js +42 -18
  103. package/dist/channels/plugins/allowlist-match.js +1 -1
  104. package/dist/channels/plugins/group-mentions.js +51 -41
  105. package/dist/channels/plugins/message-action-names.js +2 -0
  106. package/dist/channels/plugins/message-actions.js +24 -5
  107. package/dist/channels/plugins/normalize/discord.js +26 -4
  108. package/dist/channels/plugins/normalize/signal.js +35 -22
  109. package/dist/channels/plugins/onboarding/helpers.js +8 -26
  110. package/dist/channels/plugins/outbound/imessage.js +15 -14
  111. package/dist/channels/registry.js +20 -7
  112. package/dist/cli/acp-cli.js +7 -5
  113. package/dist/cli/browser-cli-extension.js +25 -12
  114. package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
  115. package/dist/cli/browser-cli-state.js +101 -145
  116. package/dist/cli/command-options.js +28 -0
  117. package/dist/cli/completion-cli.js +6 -6
  118. package/dist/cli/cron-cli/register.cron-add.js +25 -1
  119. package/dist/cli/cron-cli/register.cron-edit.js +44 -0
  120. package/dist/cli/cron-cli/shared.js +7 -1
  121. package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
  122. package/dist/cli/daemon-cli/lifecycle.js +23 -247
  123. package/dist/cli/daemon-cli/register-service-commands.js +25 -4
  124. package/dist/cli/daemon-cli.js +1 -0
  125. package/dist/cli/devices-cli.js +33 -20
  126. package/dist/cli/gateway-cli/register.js +37 -105
  127. package/dist/cli/gateway-cli/run.js +49 -11
  128. package/dist/cli/nodes-camera.js +59 -4
  129. package/dist/cli/nodes-cli/register.camera.js +27 -24
  130. package/dist/cli/nodes-cli/rpc.js +21 -38
  131. package/dist/cli/qr-cli.js +2 -2
  132. package/dist/cli/skills-cli.format.js +2 -2
  133. package/dist/cli/update-cli/progress.js +2 -2
  134. package/dist/cli/update-cli/restart-helper.js +28 -7
  135. package/dist/cli/update-cli/shared.js +7 -7
  136. package/dist/cli/update-cli/status.js +1 -1
  137. package/dist/cli/update-cli/update-command.js +14 -8
  138. package/dist/cli/update-cli/wizard.js +2 -2
  139. package/dist/cli/update-cli.js +21 -1027
  140. package/dist/commands/auth-choice.apply.anthropic.js +10 -2
  141. package/dist/commands/channels/add-mutators.js +3 -35
  142. package/dist/commands/channels/add.js +39 -51
  143. package/dist/commands/config-validation.js +1 -1
  144. package/dist/commands/configure.gateway-auth.js +52 -15
  145. package/dist/commands/configure.gateway.js +84 -40
  146. package/dist/commands/doctor-completion.js +3 -3
  147. package/dist/commands/doctor-config-flow.js +536 -16
  148. package/dist/commands/doctor-gateway-services.js +103 -79
  149. package/dist/commands/doctor-memory-search.js +9 -9
  150. package/dist/commands/doctor-platform-notes.js +57 -30
  151. package/dist/commands/doctor-prompter.js +26 -15
  152. package/dist/commands/doctor-session-locks.js +1 -1
  153. package/dist/commands/doctor.js +21 -9
  154. package/dist/commands/model-picker.js +120 -95
  155. package/dist/commands/models/set.js +2 -21
  156. package/dist/commands/models/shared.js +65 -37
  157. package/dist/commands/onboard-helpers.js +81 -39
  158. package/dist/commands/openai-codex-oauth.js +1 -1
  159. package/dist/commands/sessions.js +52 -53
  160. package/dist/commands/status.summary.js +52 -34
  161. package/dist/commands/test-wizard-helpers.js +2 -2
  162. package/dist/config/defaults.js +79 -42
  163. package/dist/config/group-policy.js +50 -18
  164. package/dist/config/includes.js +37 -10
  165. package/dist/config/schema.help.js +5 -4
  166. package/dist/config/schema.hints.js +2 -2
  167. package/dist/config/schema.labels.js +1 -0
  168. package/dist/config/sessions/group.js +12 -11
  169. package/dist/config/sessions/paths.js +137 -11
  170. package/dist/config/sessions/store.js +185 -65
  171. package/dist/config/sessions/types.js +15 -1
  172. package/dist/config/sessions.js +1 -0
  173. package/dist/config/telegram-custom-commands.js +3 -2
  174. package/dist/config/types.js +2 -0
  175. package/dist/config/zod-schema.agent-defaults.js +6 -27
  176. package/dist/config/zod-schema.agent-runtime.js +171 -79
  177. package/dist/config/zod-schema.providers-core.js +138 -65
  178. package/dist/config/zod-schema.session.js +49 -22
  179. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
  180. package/dist/cron/isolated-agent/run.js +224 -57
  181. package/dist/cron/normalize.js +48 -45
  182. package/dist/cron/run-log.js +14 -0
  183. package/dist/cron/service/jobs.js +190 -28
  184. package/dist/cron/service/normalize.js +29 -11
  185. package/dist/cron/service/store.js +30 -44
  186. package/dist/cron/service/timer.js +182 -96
  187. package/dist/cron/service.js +3 -0
  188. package/dist/cron/stagger.js +37 -0
  189. package/dist/daemon/inspect.js +132 -92
  190. package/dist/daemon/runtime-paths.js +25 -4
  191. package/dist/daemon/service-audit.js +47 -16
  192. package/dist/discord/accounts.js +23 -20
  193. package/dist/discord/monitor/agent-components.js +1115 -219
  194. package/dist/discord/monitor/allow-list.js +114 -34
  195. package/dist/discord/monitor/listeners.js +204 -97
  196. package/dist/discord/monitor/message-handler.js +21 -10
  197. package/dist/discord/monitor/message-handler.preflight.js +195 -101
  198. package/dist/discord/monitor/message-handler.process.js +384 -123
  199. package/dist/discord/monitor/message-utils.js +86 -23
  200. package/dist/discord/monitor/native-command.js +77 -57
  201. package/dist/discord/monitor/provider.js +122 -117
  202. package/dist/discord/monitor/reply-context.js +20 -16
  203. package/dist/discord/monitor/reply-delivery.js +40 -8
  204. package/dist/discord/monitor/rest-fetch.js +22 -0
  205. package/dist/discord/monitor/threading.js +117 -24
  206. package/dist/discord/send.js +2 -1
  207. package/dist/discord/send.outbound.js +124 -11
  208. package/dist/discord/send.shared.js +112 -72
  209. package/dist/discord/voice-message.js +3 -3
  210. package/dist/gateway/auth.js +119 -44
  211. package/dist/gateway/call.js +76 -34
  212. package/dist/gateway/channel-health-monitor.js +57 -50
  213. package/dist/gateway/client.js +63 -29
  214. package/dist/gateway/control-ui-contract.js +1 -1
  215. package/dist/gateway/gateway-config-prompts.shared.js +2 -2
  216. package/dist/gateway/net.js +109 -1
  217. package/dist/gateway/protocol/index.js +5 -8
  218. package/dist/gateway/protocol/schema/agent.js +19 -1
  219. package/dist/gateway/protocol/schema/channels.js +21 -0
  220. package/dist/gateway/protocol/schema/cron.js +43 -30
  221. package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
  222. package/dist/gateway/protocol/schema/sessions.js +5 -1
  223. package/dist/gateway/protocol/schema.js +0 -1
  224. package/dist/gateway/server/presence-events.js +12 -0
  225. package/dist/gateway/server/ws-connection/message-handler.js +203 -212
  226. package/dist/gateway/server/ws-connection.js +58 -21
  227. package/dist/gateway/server-broadcast.js +18 -13
  228. package/dist/gateway/server-cron.js +177 -10
  229. package/dist/gateway/server-methods/agent-job.js +131 -38
  230. package/dist/gateway/server-methods/send.js +60 -14
  231. package/dist/gateway/server-methods/sessions.js +160 -96
  232. package/dist/gateway/server-methods/system.js +5 -7
  233. package/dist/gateway/server-methods-list.js +8 -0
  234. package/dist/gateway/server-methods.js +24 -8
  235. package/dist/gateway/server-node-events.js +278 -68
  236. package/dist/gateway/session-utils.fs.js +316 -75
  237. package/dist/gateway/session-utils.js +224 -70
  238. package/dist/gateway/sessions-patch.js +63 -20
  239. package/dist/gateway/test-temp-config.js +1 -1
  240. package/dist/gateway/tools-invoke-http.js +118 -70
  241. package/dist/gateway/ws-log.js +135 -107
  242. package/dist/hooks/frontmatter.js +36 -82
  243. package/dist/hooks/install.js +149 -139
  244. package/dist/hooks/internal-hooks.js +29 -4
  245. package/dist/hooks/plugin-hooks.js +2 -1
  246. package/dist/imessage/monitor/deliver.js +10 -4
  247. package/dist/imessage/monitor/monitor-provider.js +138 -375
  248. package/dist/imessage/monitor/runtime.js +4 -8
  249. package/dist/imessage/send.js +65 -19
  250. package/dist/infra/exec-approvals-allowlist.js +7 -0
  251. package/dist/infra/exec-approvals.js +35 -920
  252. package/dist/infra/exec-safe-bin-trust.js +64 -0
  253. package/dist/infra/heartbeat-runner.js +207 -134
  254. package/dist/infra/heartbeat-wake.js +183 -22
  255. package/dist/infra/install-source-utils.js +47 -0
  256. package/dist/infra/net/ssrf.js +170 -36
  257. package/dist/infra/outbound/deliver.js +224 -58
  258. package/dist/infra/outbound/message-action-spec.js +12 -5
  259. package/dist/infra/outbound/outbound-session.js +27 -25
  260. package/dist/infra/poolbot-root.js +32 -22
  261. package/dist/infra/ports.js +14 -11
  262. package/dist/infra/skills-remote.js +48 -37
  263. package/dist/infra/system-events.js +25 -11
  264. package/dist/infra/system-presence.js +26 -33
  265. package/dist/infra/tmp-poolbot-dir.js +81 -2
  266. package/dist/infra/wsl.js +37 -1
  267. package/dist/line/bot-message-context.js +163 -191
  268. package/dist/logging/subsystem.js +59 -22
  269. package/dist/markdown/ir.js +124 -50
  270. package/dist/media/store.js +1 -1
  271. package/dist/media-understanding/runner.entries.js +42 -25
  272. package/dist/media-understanding/runner.js +53 -488
  273. package/dist/memory/embeddings-gemini.js +53 -38
  274. package/dist/memory/manager-embedding-ops.js +48 -69
  275. package/dist/pairing/pairing-store.js +178 -119
  276. package/dist/plugin-sdk/index.js +34 -6
  277. package/dist/plugins/hooks.js +135 -14
  278. package/dist/plugins/install.js +190 -152
  279. package/dist/polls.js +11 -0
  280. package/dist/routing/resolve-route.js +190 -56
  281. package/dist/routing/session-key.js +38 -22
  282. package/dist/runtime.js +35 -9
  283. package/dist/security/audit-channel.js +1 -1
  284. package/dist/sessions/session-key-utils.js +29 -11
  285. package/dist/shared/frontmatter.js +5 -5
  286. package/dist/shared/node-list-types.js +1 -0
  287. package/dist/shared/string-normalization.js +15 -0
  288. package/dist/signal/monitor/event-handler.js +68 -36
  289. package/dist/signal/send.js +29 -37
  290. package/dist/slack/monitor/allow-list.js +10 -11
  291. package/dist/slack/monitor/commands.js +14 -3
  292. package/dist/slack/monitor/events/interactions.js +4 -4
  293. package/dist/slack/monitor/media.js +224 -16
  294. package/dist/slack/monitor/message-handler/dispatch.js +247 -13
  295. package/dist/slack/monitor/message-handler/prepare.js +128 -45
  296. package/dist/slack/monitor/slash.js +357 -144
  297. package/dist/slack/streaming.js +77 -0
  298. package/dist/telegram/accounts.js +40 -13
  299. package/dist/telegram/allowed-updates.js +3 -0
  300. package/dist/telegram/bot/delivery.js +129 -66
  301. package/dist/telegram/bot/helpers.js +136 -122
  302. package/dist/telegram/bot-handlers.js +600 -339
  303. package/dist/telegram/bot-message-context.js +115 -73
  304. package/dist/telegram/bot-message-dispatch.js +235 -104
  305. package/dist/telegram/bot-native-command-menu.js +3 -1
  306. package/dist/telegram/bot-native-commands.js +213 -193
  307. package/dist/telegram/bot.js +24 -132
  308. package/dist/telegram/draft-stream.js +84 -75
  309. package/dist/telegram/format.js +150 -6
  310. package/dist/telegram/send.js +415 -255
  311. package/dist/telegram/targets.js +21 -2
  312. package/dist/telegram/update-offset-store.js +19 -3
  313. package/dist/terminal/restore.js +5 -2
  314. package/dist/test-utils/fetch-mock.js +5 -0
  315. package/dist/version.js +18 -5
  316. package/dist/web/auto-reply/monitor/broadcast.js +7 -3
  317. package/dist/web/auto-reply/monitor/on-message.js +6 -3
  318. package/dist/web/inbound/media.js +34 -8
  319. package/dist/web/inbound/monitor.js +34 -17
  320. package/dist/web/inbound/send-api.js +18 -17
  321. package/dist/web/outbound.js +12 -5
  322. package/dist/wizard/clack-prompter.js +40 -7
  323. package/extensions/bluebubbles/package.json +1 -1
  324. package/extensions/copilot-proxy/package.json +1 -1
  325. package/extensions/diagnostics-otel/package.json +1 -1
  326. package/extensions/discord/package.json +1 -1
  327. package/extensions/feishu/package.json +1 -1
  328. package/extensions/google-antigravity-auth/package.json +1 -1
  329. package/extensions/google-gemini-cli-auth/package.json +1 -1
  330. package/extensions/googlechat/package.json +1 -1
  331. package/extensions/imessage/package.json +1 -1
  332. package/extensions/irc/package.json +1 -1
  333. package/extensions/line/package.json +1 -1
  334. package/extensions/llm-task/package.json +1 -1
  335. package/extensions/lobster/package.json +1 -1
  336. package/extensions/matrix/CHANGELOG.md +5 -0
  337. package/extensions/matrix/package.json +1 -1
  338. package/extensions/mattermost/package.json +1 -1
  339. package/extensions/memory-core/package.json +1 -1
  340. package/extensions/memory-lancedb/package.json +1 -1
  341. package/extensions/minimax-portal-auth/package.json +1 -1
  342. package/extensions/msteams/CHANGELOG.md +5 -0
  343. package/extensions/msteams/package.json +1 -1
  344. package/extensions/nextcloud-talk/package.json +1 -1
  345. package/extensions/nostr/CHANGELOG.md +5 -0
  346. package/extensions/nostr/package.json +1 -1
  347. package/extensions/open-prose/package.json +1 -1
  348. package/extensions/openai-codex-auth/package.json +1 -1
  349. package/extensions/signal/package.json +1 -1
  350. package/extensions/slack/package.json +1 -1
  351. package/extensions/telegram/package.json +1 -1
  352. package/extensions/tlon/package.json +1 -1
  353. package/extensions/twitch/CHANGELOG.md +5 -0
  354. package/extensions/twitch/package.json +1 -1
  355. package/extensions/voice-call/CHANGELOG.md +5 -0
  356. package/extensions/voice-call/package.json +1 -1
  357. package/extensions/whatsapp/package.json +1 -1
  358. package/extensions/zalo/CHANGELOG.md +5 -0
  359. package/extensions/zalo/package.json +1 -1
  360. package/extensions/zalouser/CHANGELOG.md +5 -0
  361. package/extensions/zalouser/package.json +1 -1
  362. package/package.json +1 -1
  363. package/skills/apple-reminders/SKILL.md +100 -49
  364. package/skills/coding-agent/SKILL.md +34 -28
  365. package/skills/github/SKILL.md +131 -16
  366. package/skills/imsg/SKILL.md +112 -15
  367. package/skills/openhue/SKILL.md +101 -19
  368. package/skills/tmux/SKILL.md +111 -79
  369. package/skills/weather/SKILL.md +88 -25
@@ -1,31 +1,42 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { STATE_DIR } from "../config/paths.js";
4
+ import { movePathToTrash } from "../browser/trash.js";
5
+ import { resolveStateDir } from "../config/paths.js";
5
6
  import { danger, info } from "../globals.js";
6
7
  import { copyToClipboard } from "../infra/clipboard.js";
7
8
  import { defaultRuntime } from "../runtime.js";
8
- import { movePathToTrash } from "../browser/trash.js";
9
9
  import { formatDocsLink } from "../terminal/links.js";
10
10
  import { theme } from "../terminal/theme.js";
11
11
  import { shortenHomePath } from "../utils.js";
12
12
  import { formatCliCommand } from "./command-format.js";
13
- function bundledExtensionRootDir() {
14
- const here = path.dirname(fileURLToPath(import.meta.url));
13
+ export function resolveBundledExtensionRootDir(here = path.dirname(fileURLToPath(import.meta.url))) {
14
+ let current = here;
15
+ while (true) {
16
+ const candidate = path.join(current, "assets", "chrome-extension");
17
+ if (hasManifest(candidate)) {
18
+ return candidate;
19
+ }
20
+ const parent = path.dirname(current);
21
+ if (parent === current) {
22
+ break;
23
+ }
24
+ current = parent;
25
+ }
15
26
  return path.resolve(here, "../../assets/chrome-extension");
16
27
  }
17
28
  function installedExtensionRootDir() {
18
- return path.join(STATE_DIR, "browser", "chrome-extension");
29
+ return path.join(resolveStateDir(), "browser", "chrome-extension");
19
30
  }
20
31
  function hasManifest(dir) {
21
32
  return fs.existsSync(path.join(dir, "manifest.json"));
22
33
  }
23
34
  export async function installChromeExtension(opts) {
24
- const src = opts?.sourceDir ?? bundledExtensionRootDir();
35
+ const src = opts?.sourceDir ?? resolveBundledExtensionRootDir();
25
36
  if (!hasManifest(src)) {
26
- throw new Error("Bundled Chrome extension is missing. Reinstall Poolbot and try again.");
37
+ throw new Error("Bundled Chrome extension is missing. Reinstall Pool Bot and try again.");
27
38
  }
28
- const stateDir = opts?.stateDir ?? STATE_DIR;
39
+ const stateDir = opts?.stateDir ?? resolveStateDir();
29
40
  const dest = path.join(stateDir, "browser", "chrome-extension");
30
41
  fs.mkdirSync(path.dirname(dest), { recursive: true });
31
42
  if (fs.existsSync(dest)) {
@@ -54,6 +65,7 @@ export function registerBrowserExtensionCommands(browser, parentOpts) {
54
65
  catch (err) {
55
66
  defaultRuntime.error(danger(String(err)));
56
67
  defaultRuntime.exit(1);
68
+ return;
57
69
  }
58
70
  if (parent?.json) {
59
71
  defaultRuntime.log(JSON.stringify({ ok: true, path: installed.path }, null, 2));
@@ -67,9 +79,9 @@ export function registerBrowserExtensionCommands(browser, parentOpts) {
67
79
  "Next:",
68
80
  `- Chrome → chrome://extensions → enable “Developer mode”`,
69
81
  `- “Load unpacked” → select: ${displayPath}`,
70
- `- Pin “Poolbot Browser Relay”, then click it on the tab (badge shows ON)`,
82
+ `- Pin “Pool Bot Browser Relay”, then click it on the tab (badge shows ON)`,
71
83
  "",
72
- `${theme.muted("Docs:")} ${formatDocsLink("/tools/chrome-extension", "docs.molt.bot/tools/chrome-extension")}`,
84
+ `${theme.muted("Docs:")} ${formatDocsLink("/tools/chrome-extension", "docs.poolbot.ai/tools/chrome-extension")}`,
73
85
  ].join("\n")));
74
86
  });
75
87
  ext
@@ -81,7 +93,7 @@ export function registerBrowserExtensionCommands(browser, parentOpts) {
81
93
  if (!hasManifest(dir)) {
82
94
  defaultRuntime.error(danger([
83
95
  `Chrome extension is not installed. Run: "${formatCliCommand("poolbot browser extension install")}"`,
84
- `Docs: ${formatDocsLink("/tools/chrome-extension", "docs.molt.bot/tools/chrome-extension")}`,
96
+ `Docs: ${formatDocsLink("/tools/chrome-extension", "docs.poolbot.ai/tools/chrome-extension")}`,
85
97
  ].join("\n")));
86
98
  defaultRuntime.exit(1);
87
99
  }
@@ -92,7 +104,8 @@ export function registerBrowserExtensionCommands(browser, parentOpts) {
92
104
  const displayPath = shortenHomePath(dir);
93
105
  defaultRuntime.log(displayPath);
94
106
  const copied = await copyToClipboard(dir).catch(() => false);
95
- if (copied)
107
+ if (copied) {
96
108
  defaultRuntime.error(info("Copied to clipboard."));
109
+ }
97
110
  });
98
111
  }
@@ -1,6 +1,19 @@
1
1
  import { danger } from "../globals.js";
2
2
  import { defaultRuntime } from "../runtime.js";
3
3
  import { callBrowserRequest } from "./browser-cli-shared.js";
4
+ import { inheritOptionFromParent } from "./command-options.js";
5
+ function resolveTargetId(rawTargetId, command) {
6
+ const local = typeof rawTargetId === "string" ? rawTargetId.trim() : "";
7
+ if (local) {
8
+ return local;
9
+ }
10
+ const inherited = inheritOptionFromParent(command, "targetId");
11
+ if (typeof inherited !== "string") {
12
+ return undefined;
13
+ }
14
+ const trimmed = inherited.trim();
15
+ return trimmed ? trimmed : undefined;
16
+ }
4
17
  export function registerBrowserCookiesAndStorageCommands(browser, parentOpts) {
5
18
  const cookies = browser.command("cookies").description("Read/write cookies");
6
19
  cookies
@@ -8,12 +21,13 @@ export function registerBrowserCookiesAndStorageCommands(browser, parentOpts) {
8
21
  .action(async (opts, cmd) => {
9
22
  const parent = parentOpts(cmd);
10
23
  const profile = parent?.browserProfile;
24
+ const targetId = resolveTargetId(opts.targetId, cmd);
11
25
  try {
12
26
  const result = await callBrowserRequest(parent, {
13
27
  method: "GET",
14
28
  path: "/cookies",
15
29
  query: {
16
- targetId: opts.targetId?.trim() || undefined,
30
+ targetId,
17
31
  profile,
18
32
  },
19
33
  }, { timeoutMs: 20000 });
@@ -38,13 +52,14 @@ export function registerBrowserCookiesAndStorageCommands(browser, parentOpts) {
38
52
  .action(async (name, value, opts, cmd) => {
39
53
  const parent = parentOpts(cmd);
40
54
  const profile = parent?.browserProfile;
55
+ const targetId = resolveTargetId(opts.targetId, cmd);
41
56
  try {
42
57
  const result = await callBrowserRequest(parent, {
43
58
  method: "POST",
44
59
  path: "/cookies/set",
45
60
  query: profile ? { profile } : undefined,
46
61
  body: {
47
- targetId: opts.targetId?.trim() || undefined,
62
+ targetId,
48
63
  cookie: { name, value, url: opts.url },
49
64
  },
50
65
  }, { timeoutMs: 20000 });
@@ -66,13 +81,14 @@ export function registerBrowserCookiesAndStorageCommands(browser, parentOpts) {
66
81
  .action(async (opts, cmd) => {
67
82
  const parent = parentOpts(cmd);
68
83
  const profile = parent?.browserProfile;
84
+ const targetId = resolveTargetId(opts.targetId, cmd);
69
85
  try {
70
86
  const result = await callBrowserRequest(parent, {
71
87
  method: "POST",
72
88
  path: "/cookies/clear",
73
89
  query: profile ? { profile } : undefined,
74
90
  body: {
75
- targetId: opts.targetId?.trim() || undefined,
91
+ targetId,
76
92
  },
77
93
  }, { timeoutMs: 20000 });
78
94
  if (parent?.json) {
@@ -97,13 +113,14 @@ export function registerBrowserCookiesAndStorageCommands(browser, parentOpts) {
97
113
  .action(async (key, opts, cmd2) => {
98
114
  const parent = parentOpts(cmd2);
99
115
  const profile = parent?.browserProfile;
116
+ const targetId = resolveTargetId(opts.targetId, cmd2);
100
117
  try {
101
118
  const result = await callBrowserRequest(parent, {
102
119
  method: "GET",
103
120
  path: `/storage/${kind}`,
104
121
  query: {
105
122
  key: key?.trim() || undefined,
106
- targetId: opts.targetId?.trim() || undefined,
123
+ targetId,
107
124
  profile,
108
125
  },
109
126
  }, { timeoutMs: 20000 });
@@ -127,6 +144,7 @@ export function registerBrowserCookiesAndStorageCommands(browser, parentOpts) {
127
144
  .action(async (key, value, opts, cmd2) => {
128
145
  const parent = parentOpts(cmd2);
129
146
  const profile = parent?.browserProfile;
147
+ const targetId = resolveTargetId(opts.targetId, cmd2);
130
148
  try {
131
149
  const result = await callBrowserRequest(parent, {
132
150
  method: "POST",
@@ -135,7 +153,7 @@ export function registerBrowserCookiesAndStorageCommands(browser, parentOpts) {
135
153
  body: {
136
154
  key,
137
155
  value,
138
- targetId: opts.targetId?.trim() || undefined,
156
+ targetId,
139
157
  },
140
158
  }, { timeoutMs: 20000 });
141
159
  if (parent?.json) {
@@ -156,13 +174,14 @@ export function registerBrowserCookiesAndStorageCommands(browser, parentOpts) {
156
174
  .action(async (opts, cmd2) => {
157
175
  const parent = parentOpts(cmd2);
158
176
  const profile = parent?.browserProfile;
177
+ const targetId = resolveTargetId(opts.targetId, cmd2);
159
178
  try {
160
179
  const result = await callBrowserRequest(parent, {
161
180
  method: "POST",
162
181
  path: `/storage/${kind}/clear`,
163
182
  query: profile ? { profile } : undefined,
164
183
  body: {
165
- targetId: opts.targetId?.trim() || undefined,
184
+ targetId,
166
185
  },
167
186
  }, { timeoutMs: 20000 });
168
187
  if (parent?.json) {
@@ -1,6 +1,7 @@
1
1
  import { danger } from "../globals.js";
2
2
  import { defaultRuntime } from "../runtime.js";
3
3
  import { parseBooleanValue } from "../utils/boolean.js";
4
+ import { runBrowserResizeWithOutput } from "./browser-cli-resize.js";
4
5
  import { callBrowserRequest } from "./browser-cli-shared.js";
5
6
  import { registerBrowserCookiesAndStorageCommands } from "./browser-cli-state.cookies-storage.js";
6
7
  import { runCommandWithRuntime } from "./cli-utils.js";
@@ -14,6 +15,22 @@ function runBrowserCommand(action) {
14
15
  defaultRuntime.exit(1);
15
16
  });
16
17
  }
18
+ async function runBrowserSetRequest(params) {
19
+ await runBrowserCommand(async () => {
20
+ const profile = params.parent?.browserProfile;
21
+ const result = await callBrowserRequest(params.parent, {
22
+ method: "POST",
23
+ path: params.path,
24
+ query: profile ? { profile } : undefined,
25
+ body: params.body,
26
+ }, { timeoutMs: 20000 });
27
+ if (params.parent?.json) {
28
+ defaultRuntime.log(JSON.stringify(result, null, 2));
29
+ return;
30
+ }
31
+ defaultRuntime.log(params.successMessage);
32
+ });
33
+ }
17
34
  export function registerBrowserStateCommands(browser, parentOpts) {
18
35
  registerBrowserCookiesAndStorageCommands(browser, parentOpts);
19
36
  const set = browser.command("set").description("Browser environment settings");
@@ -26,28 +43,16 @@ export function registerBrowserStateCommands(browser, parentOpts) {
26
43
  .action(async (width, height, opts, cmd) => {
27
44
  const parent = parentOpts(cmd);
28
45
  const profile = parent?.browserProfile;
29
- if (!Number.isFinite(width) || !Number.isFinite(height)) {
30
- defaultRuntime.error(danger("width and height must be numbers"));
31
- defaultRuntime.exit(1);
32
- return;
33
- }
34
46
  await runBrowserCommand(async () => {
35
- const result = await callBrowserRequest(parent, {
36
- method: "POST",
37
- path: "/act",
38
- query: profile ? { profile } : undefined,
39
- body: {
40
- kind: "resize",
41
- width,
42
- height,
43
- targetId: opts.targetId?.trim() || undefined,
44
- },
45
- }, { timeoutMs: 20000 });
46
- if (parent?.json) {
47
- defaultRuntime.log(JSON.stringify(result, null, 2));
48
- return;
49
- }
50
- defaultRuntime.log(`viewport set: ${width}x${height}`);
47
+ await runBrowserResizeWithOutput({
48
+ parent,
49
+ profile,
50
+ width,
51
+ height,
52
+ targetId: opts.targetId,
53
+ timeoutMs: 20000,
54
+ successMessage: `viewport set: ${width}x${height}`,
55
+ });
51
56
  });
52
57
  });
53
58
  set
@@ -57,48 +62,47 @@ export function registerBrowserStateCommands(browser, parentOpts) {
57
62
  .option("--target-id <id>", "CDP target id (or unique prefix)")
58
63
  .action(async (value, opts, cmd) => {
59
64
  const parent = parentOpts(cmd);
60
- const profile = parent?.browserProfile;
61
65
  const offline = parseOnOff(value);
62
66
  if (offline === null) {
63
67
  defaultRuntime.error(danger("Expected on|off"));
64
68
  defaultRuntime.exit(1);
65
69
  return;
66
70
  }
67
- await runBrowserCommand(async () => {
68
- const result = await callBrowserRequest(parent, {
69
- method: "POST",
70
- path: "/set/offline",
71
- query: profile ? { profile } : undefined,
72
- body: {
73
- offline,
74
- targetId: opts.targetId?.trim() || undefined,
75
- },
76
- }, { timeoutMs: 20000 });
77
- if (parent?.json) {
78
- defaultRuntime.log(JSON.stringify(result, null, 2));
79
- return;
80
- }
81
- defaultRuntime.log(`offline: ${offline}`);
71
+ await runBrowserSetRequest({
72
+ parent,
73
+ path: "/set/offline",
74
+ body: {
75
+ offline,
76
+ targetId: opts.targetId?.trim() || undefined,
77
+ },
78
+ successMessage: `offline: ${offline}`,
82
79
  });
83
80
  });
84
81
  set
85
82
  .command("headers")
86
83
  .description("Set extra HTTP headers (JSON object)")
87
- .requiredOption("--json <json>", "JSON object of headers")
84
+ .argument("[headersJson]", "JSON object of headers (alternative to --headers-json)")
85
+ .option("--headers-json <json>", "JSON object of headers")
88
86
  .option("--target-id <id>", "CDP target id (or unique prefix)")
89
- .action(async (opts, cmd) => {
87
+ .action(async (headersJson, opts, cmd) => {
90
88
  const parent = parentOpts(cmd);
91
- const profile = parent?.browserProfile;
92
89
  await runBrowserCommand(async () => {
93
- const parsed = JSON.parse(String(opts.json));
90
+ const headersJsonValue = (typeof opts.headersJson === "string" && opts.headersJson.trim()) ||
91
+ (headersJson?.trim() ? headersJson.trim() : undefined);
92
+ if (!headersJsonValue) {
93
+ throw new Error("Missing headers JSON (pass --headers-json or positional JSON argument)");
94
+ }
95
+ const parsed = JSON.parse(String(headersJsonValue));
94
96
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
95
- throw new Error("headers json must be an object");
97
+ throw new Error("Headers JSON must be a JSON object");
96
98
  }
97
99
  const headers = {};
98
100
  for (const [k, v] of Object.entries(parsed)) {
99
- if (typeof v === "string")
101
+ if (typeof v === "string") {
100
102
  headers[k] = v;
103
+ }
101
104
  }
105
+ const profile = parent?.browserProfile;
102
106
  const result = await callBrowserRequest(parent, {
103
107
  method: "POST",
104
108
  path: "/set/headers",
@@ -124,24 +128,16 @@ export function registerBrowserStateCommands(browser, parentOpts) {
124
128
  .option("--target-id <id>", "CDP target id (or unique prefix)")
125
129
  .action(async (username, password, opts, cmd) => {
126
130
  const parent = parentOpts(cmd);
127
- const profile = parent?.browserProfile;
128
- await runBrowserCommand(async () => {
129
- const result = await callBrowserRequest(parent, {
130
- method: "POST",
131
- path: "/set/credentials",
132
- query: profile ? { profile } : undefined,
133
- body: {
134
- username: username?.trim() || undefined,
135
- password,
136
- clear: Boolean(opts.clear),
137
- targetId: opts.targetId?.trim() || undefined,
138
- },
139
- }, { timeoutMs: 20000 });
140
- if (parent?.json) {
141
- defaultRuntime.log(JSON.stringify(result, null, 2));
142
- return;
143
- }
144
- defaultRuntime.log(opts.clear ? "credentials cleared" : "credentials set");
131
+ await runBrowserSetRequest({
132
+ parent,
133
+ path: "/set/credentials",
134
+ body: {
135
+ username: username?.trim() || undefined,
136
+ password,
137
+ clear: Boolean(opts.clear),
138
+ targetId: opts.targetId?.trim() || undefined,
139
+ },
140
+ successMessage: opts.clear ? "credentials cleared" : "credentials set",
145
141
  });
146
142
  });
147
143
  set
@@ -155,26 +151,18 @@ export function registerBrowserStateCommands(browser, parentOpts) {
155
151
  .option("--target-id <id>", "CDP target id (or unique prefix)")
156
152
  .action(async (latitude, longitude, opts, cmd) => {
157
153
  const parent = parentOpts(cmd);
158
- const profile = parent?.browserProfile;
159
- await runBrowserCommand(async () => {
160
- const result = await callBrowserRequest(parent, {
161
- method: "POST",
162
- path: "/set/geolocation",
163
- query: profile ? { profile } : undefined,
164
- body: {
165
- latitude: Number.isFinite(latitude) ? latitude : undefined,
166
- longitude: Number.isFinite(longitude) ? longitude : undefined,
167
- accuracy: Number.isFinite(opts.accuracy) ? opts.accuracy : undefined,
168
- origin: opts.origin?.trim() || undefined,
169
- clear: Boolean(opts.clear),
170
- targetId: opts.targetId?.trim() || undefined,
171
- },
172
- }, { timeoutMs: 20000 });
173
- if (parent?.json) {
174
- defaultRuntime.log(JSON.stringify(result, null, 2));
175
- return;
176
- }
177
- defaultRuntime.log(opts.clear ? "geolocation cleared" : "geolocation set");
154
+ await runBrowserSetRequest({
155
+ parent,
156
+ path: "/set/geolocation",
157
+ body: {
158
+ latitude: Number.isFinite(latitude) ? latitude : undefined,
159
+ longitude: Number.isFinite(longitude) ? longitude : undefined,
160
+ accuracy: Number.isFinite(opts.accuracy) ? opts.accuracy : undefined,
161
+ origin: opts.origin?.trim() || undefined,
162
+ clear: Boolean(opts.clear),
163
+ targetId: opts.targetId?.trim() || undefined,
164
+ },
165
+ successMessage: opts.clear ? "geolocation cleared" : "geolocation set",
178
166
  });
179
167
  });
180
168
  set
@@ -184,7 +172,6 @@ export function registerBrowserStateCommands(browser, parentOpts) {
184
172
  .option("--target-id <id>", "CDP target id (or unique prefix)")
185
173
  .action(async (value, opts, cmd) => {
186
174
  const parent = parentOpts(cmd);
187
- const profile = parent?.browserProfile;
188
175
  const v = value.trim().toLowerCase();
189
176
  const colorScheme = v === "dark" ? "dark" : v === "light" ? "light" : v === "none" ? "none" : null;
190
177
  if (!colorScheme) {
@@ -192,21 +179,14 @@ export function registerBrowserStateCommands(browser, parentOpts) {
192
179
  defaultRuntime.exit(1);
193
180
  return;
194
181
  }
195
- await runBrowserCommand(async () => {
196
- const result = await callBrowserRequest(parent, {
197
- method: "POST",
198
- path: "/set/media",
199
- query: profile ? { profile } : undefined,
200
- body: {
201
- colorScheme,
202
- targetId: opts.targetId?.trim() || undefined,
203
- },
204
- }, { timeoutMs: 20000 });
205
- if (parent?.json) {
206
- defaultRuntime.log(JSON.stringify(result, null, 2));
207
- return;
208
- }
209
- defaultRuntime.log(`media colorScheme: ${colorScheme}`);
182
+ await runBrowserSetRequest({
183
+ parent,
184
+ path: "/set/media",
185
+ body: {
186
+ colorScheme,
187
+ targetId: opts.targetId?.trim() || undefined,
188
+ },
189
+ successMessage: `media colorScheme: ${colorScheme}`,
210
190
  });
211
191
  });
212
192
  set
@@ -216,22 +196,14 @@ export function registerBrowserStateCommands(browser, parentOpts) {
216
196
  .option("--target-id <id>", "CDP target id (or unique prefix)")
217
197
  .action(async (timezoneId, opts, cmd) => {
218
198
  const parent = parentOpts(cmd);
219
- const profile = parent?.browserProfile;
220
- await runBrowserCommand(async () => {
221
- const result = await callBrowserRequest(parent, {
222
- method: "POST",
223
- path: "/set/timezone",
224
- query: profile ? { profile } : undefined,
225
- body: {
226
- timezoneId,
227
- targetId: opts.targetId?.trim() || undefined,
228
- },
229
- }, { timeoutMs: 20000 });
230
- if (parent?.json) {
231
- defaultRuntime.log(JSON.stringify(result, null, 2));
232
- return;
233
- }
234
- defaultRuntime.log(`timezone: ${timezoneId}`);
199
+ await runBrowserSetRequest({
200
+ parent,
201
+ path: "/set/timezone",
202
+ body: {
203
+ timezoneId,
204
+ targetId: opts.targetId?.trim() || undefined,
205
+ },
206
+ successMessage: `timezone: ${timezoneId}`,
235
207
  });
236
208
  });
237
209
  set
@@ -241,22 +213,14 @@ export function registerBrowserStateCommands(browser, parentOpts) {
241
213
  .option("--target-id <id>", "CDP target id (or unique prefix)")
242
214
  .action(async (locale, opts, cmd) => {
243
215
  const parent = parentOpts(cmd);
244
- const profile = parent?.browserProfile;
245
- await runBrowserCommand(async () => {
246
- const result = await callBrowserRequest(parent, {
247
- method: "POST",
248
- path: "/set/locale",
249
- query: profile ? { profile } : undefined,
250
- body: {
251
- locale,
252
- targetId: opts.targetId?.trim() || undefined,
253
- },
254
- }, { timeoutMs: 20000 });
255
- if (parent?.json) {
256
- defaultRuntime.log(JSON.stringify(result, null, 2));
257
- return;
258
- }
259
- defaultRuntime.log(`locale: ${locale}`);
216
+ await runBrowserSetRequest({
217
+ parent,
218
+ path: "/set/locale",
219
+ body: {
220
+ locale,
221
+ targetId: opts.targetId?.trim() || undefined,
222
+ },
223
+ successMessage: `locale: ${locale}`,
260
224
  });
261
225
  });
262
226
  set
@@ -266,22 +230,14 @@ export function registerBrowserStateCommands(browser, parentOpts) {
266
230
  .option("--target-id <id>", "CDP target id (or unique prefix)")
267
231
  .action(async (name, opts, cmd) => {
268
232
  const parent = parentOpts(cmd);
269
- const profile = parent?.browserProfile;
270
- await runBrowserCommand(async () => {
271
- const result = await callBrowserRequest(parent, {
272
- method: "POST",
273
- path: "/set/device",
274
- query: profile ? { profile } : undefined,
275
- body: {
276
- name,
277
- targetId: opts.targetId?.trim() || undefined,
278
- },
279
- }, { timeoutMs: 20000 });
280
- if (parent?.json) {
281
- defaultRuntime.log(JSON.stringify(result, null, 2));
282
- return;
283
- }
284
- defaultRuntime.log(`device: ${name}`);
233
+ await runBrowserSetRequest({
234
+ parent,
235
+ path: "/set/device",
236
+ body: {
237
+ name,
238
+ targetId: opts.targetId?.trim() || undefined,
239
+ },
240
+ successMessage: `device: ${name}`,
285
241
  });
286
242
  });
287
243
  }
@@ -4,3 +4,31 @@ export function hasExplicitOptions(command, names) {
4
4
  }
5
5
  return names.some((name) => command.getOptionValueSource(name) === "cli");
6
6
  }
7
+ function getOptionSource(command, name) {
8
+ if (typeof command.getOptionValueSource !== "function") {
9
+ return undefined;
10
+ }
11
+ return command.getOptionValueSource(name);
12
+ }
13
+ // Defensive guardrail: allow expected parent/grandparent inheritance without unbounded deep traversal.
14
+ const MAX_INHERIT_DEPTH = 2;
15
+ export function inheritOptionFromParent(command, name) {
16
+ if (!command) {
17
+ return undefined;
18
+ }
19
+ const childSource = getOptionSource(command, name);
20
+ if (childSource && childSource !== "default") {
21
+ return undefined;
22
+ }
23
+ let depth = 0;
24
+ let ancestor = command.parent;
25
+ while (ancestor && depth < MAX_INHERIT_DEPTH) {
26
+ const source = getOptionSource(ancestor, name);
27
+ if (source && source !== "default") {
28
+ return ancestor.opts()[name];
29
+ }
30
+ depth += 1;
31
+ ancestor = ancestor.parent;
32
+ }
33
+ return undefined;
34
+ }
@@ -78,7 +78,7 @@ function formatCompletionSourceLine(shell, binName, cachePath) {
78
78
  return `source "${cachePath}"`;
79
79
  }
80
80
  function isCompletionProfileHeader(line) {
81
- return line.trim() === "# OpenClaw Completion";
81
+ return line.trim() === "# Pool Bot Completion";
82
82
  }
83
83
  function isCompletionProfileLine(line, binName, cachePath) {
84
84
  if (line.includes(`${binName} completion`)) {
@@ -91,7 +91,7 @@ function isCompletionProfileLine(line, binName, cachePath) {
91
91
  }
92
92
  /** Check if a line uses the slow dynamic completion pattern (source <(...)) */
93
93
  function isSlowDynamicCompletionLine(line, binName) {
94
- // Matches patterns like: source <(openclaw completion --shell zsh)
94
+ // Matches patterns like: source <(poolbot completion --shell zsh)
95
95
  return (line.includes(`<(${binName} completion`) ||
96
96
  (line.includes(`${binName} completion`) && line.includes("| source")));
97
97
  }
@@ -113,7 +113,7 @@ function updateCompletionProfile(content, binName, cachePath, sourceLine) {
113
113
  filtered.push(line);
114
114
  }
115
115
  const trimmed = filtered.join("\n").trimEnd();
116
- const block = `# OpenClaw Completion\n${sourceLine}`;
116
+ const block = `# Pool Bot Completion\n${sourceLine}`;
117
117
  const next = trimmed ? `${trimmed}\n\n${block}\n` : `${block}\n`;
118
118
  return { next, changed: next !== content, hadExisting };
119
119
  }
@@ -147,7 +147,7 @@ export async function isCompletionInstalled(shell, binName = "poolbot") {
147
147
  }
148
148
  /**
149
149
  * Check if the profile uses the slow dynamic completion pattern.
150
- * Returns true if profile has `source <(openclaw completion ...)` instead of cached file.
150
+ * Returns true if profile has `source <(poolbot completion ...)` instead of cached file.
151
151
  */
152
152
  export async function usesSlowDynamicCompletion(shell, binName = "poolbot") {
153
153
  const profilePath = getShellProfilePath(shell);
@@ -498,7 +498,7 @@ function generateFishCompletion(program) {
498
498
  fullPath.push(cmdName);
499
499
  } // Only push if not root, or consistent root handling
500
500
  // Fish uses 'seen_subcommand_from' to determine context.
501
- // For root: complete -c openclaw -n "__fish_use_subcommand" -a "subcmd" -d "desc"
501
+ // For root: complete -c poolbot -n "__fish_use_subcommand" -a "subcmd" -d "desc"
502
502
  // Root logic
503
503
  if (parents.length === 0) {
504
504
  // Subcommands of root
@@ -531,7 +531,7 @@ function generateFishCompletion(program) {
531
531
  // But fish completion logic is simpler if we just say "if we haven't seen THIS command yet but seen parent"
532
532
  // Actually, a robust fish completion often requires defining a function to check current line.
533
533
  // For simplicity, we'll assume standard fish helper __fish_seen_subcommand_from.
534
- // To properly scope to 'openclaw gateway' and not 'openclaw other gateway', we need to check the sequence.
534
+ // To properly scope to 'poolbot gateway' and not 'poolbot other gateway', we need to check the sequence.
535
535
  // A simplified approach:
536
536
  // Subcommands
537
537
  for (const sub of cmd.commands) {