@poolzin/pool-bot 2026.2.21 → 2026.2.23
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.
- package/CHANGELOG.md +25 -0
- package/dist/agents/api-key-rotation.js +47 -0
- package/dist/agents/apply-patch-update.js +19 -9
- package/dist/agents/apply-patch.js +72 -47
- package/dist/agents/bash-tools.exec.js +141 -559
- package/dist/agents/cli-backends.js +49 -6
- package/dist/agents/cli-runner/helpers.js +69 -152
- package/dist/agents/cli-runner.js +70 -19
- package/dist/agents/identity.js +20 -1
- package/dist/agents/image-sanitization.js +9 -0
- package/dist/agents/live-auth-keys.js +123 -26
- package/dist/agents/live-model-filter.js +13 -4
- package/dist/agents/model-catalog.js +40 -9
- package/dist/agents/model-forward-compat.js +60 -23
- package/dist/agents/model-selection.js +134 -41
- package/dist/agents/pi-auth-json.js +2 -2
- package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
- package/dist/agents/pi-embedded-helpers/errors.js +140 -15
- package/dist/agents/pi-embedded-helpers/images.js +22 -12
- package/dist/agents/pi-embedded-helpers.js +2 -2
- package/dist/agents/pi-embedded-runner/abort.js +10 -3
- package/dist/agents/pi-embedded-runner/compact.js +230 -32
- package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
- package/dist/agents/pi-embedded-runner/google.js +109 -19
- package/dist/agents/pi-embedded-runner/history.js +35 -17
- package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
- package/dist/agents/pi-embedded-runner/run/images.js +81 -55
- package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
- package/dist/agents/pi-embedded-runner/run.js +193 -25
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
- package/dist/agents/pi-embedded-runner/runs.js +17 -8
- package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
- package/dist/agents/pi-embedded-runner.js +1 -1
- package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
- package/dist/agents/pi-embedded-subscribe.js +37 -0
- package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
- package/dist/agents/pi-model-discovery.js +9 -2
- package/dist/agents/pi-tool-definition-adapter.js +60 -8
- package/dist/agents/pi-tools.before-tool-call.js +1 -1
- package/dist/agents/pi-tools.js +113 -94
- package/dist/agents/pi-tools.read.js +337 -38
- package/dist/agents/poolbot-tools.js +14 -5
- package/dist/agents/sandbox/docker.js +10 -5
- package/dist/agents/sandbox/registry.js +96 -46
- package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
- package/dist/agents/sandbox-paths.js +43 -10
- package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
- package/dist/agents/session-tool-result-guard.js +39 -39
- package/dist/agents/session-transcript-repair.js +36 -33
- package/dist/agents/session-write-lock.js +62 -44
- package/dist/agents/skills/frontmatter.js +49 -88
- package/dist/agents/skills/workspace.js +335 -28
- package/dist/agents/subagent-announce.js +508 -174
- package/dist/agents/subagent-registry.js +45 -4
- package/dist/agents/subagent-spawn.js +16 -33
- package/dist/agents/system-prompt-report.js +27 -10
- package/dist/agents/system-prompt.js +26 -32
- package/dist/agents/tool-call-id.js +69 -17
- package/dist/agents/tool-display-common.js +1 -1
- package/dist/agents/tool-images.js +64 -31
- package/dist/agents/tools/canvas-tool.js +17 -11
- package/dist/agents/tools/common.js +37 -19
- package/dist/agents/tools/cron-tool.js +40 -38
- package/dist/agents/tools/gateway.js +70 -2
- package/dist/agents/tools/message-tool.js +181 -40
- package/dist/agents/tools/nodes-tool.js +128 -36
- package/dist/agents/tools/nodes-utils.js +12 -38
- package/dist/agents/tools/session-status-tool.js +24 -71
- package/dist/agents/tools/sessions-helpers.js +38 -210
- package/dist/agents/tools/sessions-spawn-tool.js +28 -198
- package/dist/agents/tools/telegram-actions.js +58 -7
- package/dist/agents/tools/web-fetch-utils.js +112 -7
- package/dist/agents/tools/web-fetch.js +279 -175
- package/dist/agents/tools/web-shared.js +71 -8
- package/dist/agents/usage.js +25 -16
- package/dist/auto-reply/commands-registry.data.js +85 -11
- package/dist/auto-reply/dispatch.js +40 -21
- package/dist/auto-reply/reply/abort.js +102 -33
- package/dist/auto-reply/reply/commands-core.js +82 -33
- package/dist/auto-reply/reply/commands-export-session.js +1 -1
- package/dist/auto-reply/reply/commands-info.js +41 -12
- package/dist/auto-reply/reply/commands-subagents.js +352 -100
- package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
- package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
- package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
- package/dist/auto-reply/reply/inbound-meta.js +12 -1
- package/dist/auto-reply/reply/mentions.js +18 -11
- package/dist/auto-reply/reply/normalize-reply.js +17 -8
- package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
- package/dist/auto-reply/reply/session.js +102 -21
- package/dist/auto-reply/reply/streaming-directives.js +16 -5
- package/dist/auto-reply/status.js +73 -50
- package/dist/browser/extension-relay.js +3 -3
- package/dist/browser/http-auth.js +1 -1
- package/dist/browser/paths.js +2 -2
- package/dist/build-info.json +3 -3
- package/dist/channels/allowlist-match.js +20 -0
- package/dist/channels/allowlists/resolve-utils.js +65 -2
- package/dist/channels/chat-type.js +8 -4
- package/dist/channels/dock.js +127 -35
- package/dist/channels/draft-stream-loop.js +6 -2
- package/dist/channels/plugins/actions/telegram.js +42 -18
- package/dist/channels/plugins/allowlist-match.js +1 -1
- package/dist/channels/plugins/group-mentions.js +51 -41
- package/dist/channels/plugins/message-action-names.js +2 -0
- package/dist/channels/plugins/message-actions.js +24 -5
- package/dist/channels/plugins/normalize/discord.js +26 -4
- package/dist/channels/plugins/normalize/signal.js +35 -22
- package/dist/channels/plugins/onboarding/helpers.js +8 -26
- package/dist/channels/plugins/outbound/imessage.js +15 -14
- package/dist/channels/registry.js +20 -7
- package/dist/cli/acp-cli.js +7 -5
- package/dist/cli/browser-cli-extension.js +25 -12
- package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
- package/dist/cli/browser-cli-state.js +101 -145
- package/dist/cli/command-options.js +28 -0
- package/dist/cli/completion-cli.js +6 -6
- package/dist/cli/cron-cli/register.cron-add.js +25 -1
- package/dist/cli/cron-cli/register.cron-edit.js +44 -0
- package/dist/cli/cron-cli/shared.js +7 -1
- package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
- package/dist/cli/daemon-cli/lifecycle.js +23 -247
- package/dist/cli/daemon-cli/register-service-commands.js +25 -4
- package/dist/cli/daemon-cli.js +1 -0
- package/dist/cli/devices-cli.js +33 -20
- package/dist/cli/gateway-cli/register.js +37 -105
- package/dist/cli/gateway-cli/run.js +49 -11
- package/dist/cli/nodes-camera.js +59 -4
- package/dist/cli/nodes-cli/register.camera.js +27 -24
- package/dist/cli/nodes-cli/rpc.js +21 -38
- package/dist/cli/qr-cli.js +2 -2
- package/dist/cli/skills-cli.format.js +2 -2
- package/dist/cli/update-cli/progress.js +2 -2
- package/dist/cli/update-cli/restart-helper.js +28 -7
- package/dist/cli/update-cli/shared.js +7 -7
- package/dist/cli/update-cli/status.js +1 -1
- package/dist/cli/update-cli/update-command.js +14 -8
- package/dist/cli/update-cli/wizard.js +2 -2
- package/dist/cli/update-cli.js +21 -1027
- package/dist/commands/auth-choice.apply.anthropic.js +10 -2
- package/dist/commands/channels/add-mutators.js +3 -35
- package/dist/commands/channels/add.js +39 -51
- package/dist/commands/config-validation.js +1 -1
- package/dist/commands/configure.gateway-auth.js +52 -15
- package/dist/commands/configure.gateway.js +84 -40
- package/dist/commands/doctor-completion.js +3 -3
- package/dist/commands/doctor-config-flow.js +536 -16
- package/dist/commands/doctor-gateway-services.js +103 -79
- package/dist/commands/doctor-memory-search.js +9 -9
- package/dist/commands/doctor-platform-notes.js +57 -30
- package/dist/commands/doctor-prompter.js +26 -15
- package/dist/commands/doctor-session-locks.js +1 -1
- package/dist/commands/doctor.js +21 -9
- package/dist/commands/model-picker.js +120 -95
- package/dist/commands/models/set.js +2 -21
- package/dist/commands/models/shared.js +65 -37
- package/dist/commands/onboard-helpers.js +81 -39
- package/dist/commands/openai-codex-oauth.js +1 -1
- package/dist/commands/sessions.js +52 -53
- package/dist/commands/status.summary.js +52 -34
- package/dist/commands/test-wizard-helpers.js +2 -2
- package/dist/config/defaults.js +79 -42
- package/dist/config/group-policy.js +50 -18
- package/dist/config/includes.js +37 -10
- package/dist/config/schema.help.js +5 -4
- package/dist/config/schema.hints.js +2 -2
- package/dist/config/schema.labels.js +1 -0
- package/dist/config/sessions/group.js +12 -11
- package/dist/config/sessions/paths.js +137 -11
- package/dist/config/sessions/store.js +185 -65
- package/dist/config/sessions/types.js +15 -1
- package/dist/config/sessions.js +1 -0
- package/dist/config/telegram-custom-commands.js +3 -2
- package/dist/config/types.js +2 -0
- package/dist/config/zod-schema.agent-defaults.js +6 -27
- package/dist/config/zod-schema.agent-runtime.js +171 -79
- package/dist/config/zod-schema.providers-core.js +138 -65
- package/dist/config/zod-schema.session.js +49 -22
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
- package/dist/cron/isolated-agent/run.js +224 -57
- package/dist/cron/normalize.js +48 -45
- package/dist/cron/run-log.js +14 -0
- package/dist/cron/service/jobs.js +190 -28
- package/dist/cron/service/normalize.js +29 -11
- package/dist/cron/service/store.js +30 -44
- package/dist/cron/service/timer.js +182 -96
- package/dist/cron/service.js +3 -0
- package/dist/cron/stagger.js +37 -0
- package/dist/daemon/inspect.js +132 -92
- package/dist/daemon/runtime-paths.js +25 -4
- package/dist/daemon/service-audit.js +47 -16
- package/dist/discord/accounts.js +23 -20
- package/dist/discord/monitor/agent-components.js +1115 -219
- package/dist/discord/monitor/allow-list.js +114 -34
- package/dist/discord/monitor/listeners.js +204 -97
- package/dist/discord/monitor/message-handler.js +21 -10
- package/dist/discord/monitor/message-handler.preflight.js +195 -101
- package/dist/discord/monitor/message-handler.process.js +384 -123
- package/dist/discord/monitor/message-utils.js +86 -23
- package/dist/discord/monitor/native-command.js +77 -57
- package/dist/discord/monitor/provider.js +122 -117
- package/dist/discord/monitor/reply-context.js +20 -16
- package/dist/discord/monitor/reply-delivery.js +40 -8
- package/dist/discord/monitor/rest-fetch.js +22 -0
- package/dist/discord/monitor/threading.js +117 -24
- package/dist/discord/send.js +2 -1
- package/dist/discord/send.outbound.js +124 -11
- package/dist/discord/send.shared.js +112 -72
- package/dist/discord/voice-message.js +3 -3
- package/dist/gateway/auth.js +119 -44
- package/dist/gateway/call.js +76 -34
- package/dist/gateway/channel-health-monitor.js +57 -50
- package/dist/gateway/client.js +63 -29
- package/dist/gateway/control-ui-contract.js +1 -1
- package/dist/gateway/gateway-config-prompts.shared.js +2 -2
- package/dist/gateway/net.js +109 -1
- package/dist/gateway/protocol/index.js +5 -8
- package/dist/gateway/protocol/schema/agent.js +19 -1
- package/dist/gateway/protocol/schema/channels.js +21 -0
- package/dist/gateway/protocol/schema/cron.js +43 -30
- package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
- package/dist/gateway/protocol/schema/sessions.js +5 -1
- package/dist/gateway/protocol/schema.js +0 -1
- package/dist/gateway/server/presence-events.js +12 -0
- package/dist/gateway/server/ws-connection/message-handler.js +203 -212
- package/dist/gateway/server/ws-connection.js +58 -21
- package/dist/gateway/server-broadcast.js +18 -13
- package/dist/gateway/server-cron.js +177 -10
- package/dist/gateway/server-methods/agent-job.js +131 -38
- package/dist/gateway/server-methods/send.js +60 -14
- package/dist/gateway/server-methods/sessions.js +160 -96
- package/dist/gateway/server-methods/system.js +5 -7
- package/dist/gateway/server-methods-list.js +8 -0
- package/dist/gateway/server-methods.js +24 -8
- package/dist/gateway/server-node-events.js +278 -68
- package/dist/gateway/session-utils.fs.js +316 -75
- package/dist/gateway/session-utils.js +224 -70
- package/dist/gateway/sessions-patch.js +63 -20
- package/dist/gateway/test-temp-config.js +1 -1
- package/dist/gateway/tools-invoke-http.js +118 -70
- package/dist/gateway/ws-log.js +135 -107
- package/dist/hooks/frontmatter.js +36 -82
- package/dist/hooks/install.js +149 -139
- package/dist/hooks/internal-hooks.js +29 -4
- package/dist/hooks/plugin-hooks.js +2 -1
- package/dist/imessage/monitor/deliver.js +10 -4
- package/dist/imessage/monitor/monitor-provider.js +138 -375
- package/dist/imessage/monitor/runtime.js +4 -8
- package/dist/imessage/send.js +65 -19
- package/dist/infra/exec-approvals-allowlist.js +7 -0
- package/dist/infra/exec-approvals.js +35 -920
- package/dist/infra/exec-safe-bin-trust.js +64 -0
- package/dist/infra/heartbeat-runner.js +207 -134
- package/dist/infra/heartbeat-wake.js +183 -22
- package/dist/infra/install-source-utils.js +47 -0
- package/dist/infra/net/ssrf.js +170 -36
- package/dist/infra/outbound/deliver.js +224 -58
- package/dist/infra/outbound/message-action-spec.js +12 -5
- package/dist/infra/outbound/outbound-session.js +27 -25
- package/dist/infra/poolbot-root.js +32 -22
- package/dist/infra/ports.js +14 -11
- package/dist/infra/skills-remote.js +48 -37
- package/dist/infra/system-events.js +25 -11
- package/dist/infra/system-presence.js +26 -33
- package/dist/infra/tmp-poolbot-dir.js +81 -2
- package/dist/infra/wsl.js +37 -1
- package/dist/line/bot-message-context.js +163 -191
- package/dist/logging/subsystem.js +59 -22
- package/dist/markdown/ir.js +124 -50
- package/dist/media/store.js +1 -1
- package/dist/media-understanding/runner.entries.js +42 -25
- package/dist/media-understanding/runner.js +53 -488
- package/dist/memory/embeddings-gemini.js +53 -38
- package/dist/memory/manager-embedding-ops.js +48 -69
- package/dist/pairing/pairing-store.js +178 -119
- package/dist/plugin-sdk/index.js +34 -6
- package/dist/plugins/hooks.js +135 -14
- package/dist/plugins/install.js +190 -152
- package/dist/polls.js +11 -0
- package/dist/routing/resolve-route.js +190 -56
- package/dist/routing/session-key.js +38 -22
- package/dist/runtime.js +35 -9
- package/dist/security/audit-channel.js +1 -1
- package/dist/sessions/session-key-utils.js +29 -11
- package/dist/shared/frontmatter.js +5 -5
- package/dist/shared/node-list-types.js +1 -0
- package/dist/shared/string-normalization.js +15 -0
- package/dist/signal/monitor/event-handler.js +68 -36
- package/dist/signal/send.js +29 -37
- package/dist/slack/monitor/allow-list.js +10 -11
- package/dist/slack/monitor/commands.js +14 -3
- package/dist/slack/monitor/events/interactions.js +4 -4
- package/dist/slack/monitor/media.js +224 -16
- package/dist/slack/monitor/message-handler/dispatch.js +247 -13
- package/dist/slack/monitor/message-handler/prepare.js +128 -45
- package/dist/slack/monitor/slash.js +357 -144
- package/dist/slack/streaming.js +77 -0
- package/dist/telegram/accounts.js +40 -13
- package/dist/telegram/allowed-updates.js +3 -0
- package/dist/telegram/bot/delivery.js +129 -66
- package/dist/telegram/bot/helpers.js +136 -122
- package/dist/telegram/bot-handlers.js +600 -339
- package/dist/telegram/bot-message-context.js +115 -73
- package/dist/telegram/bot-message-dispatch.js +235 -104
- package/dist/telegram/bot-native-command-menu.js +3 -1
- package/dist/telegram/bot-native-commands.js +213 -193
- package/dist/telegram/bot.js +24 -132
- package/dist/telegram/draft-stream.js +84 -75
- package/dist/telegram/format.js +150 -6
- package/dist/telegram/send.js +415 -255
- package/dist/telegram/targets.js +21 -2
- package/dist/telegram/update-offset-store.js +19 -3
- package/dist/terminal/restore.js +5 -2
- package/dist/test-utils/fetch-mock.js +5 -0
- package/dist/version.js +18 -5
- package/dist/web/auto-reply/monitor/broadcast.js +7 -3
- package/dist/web/auto-reply/monitor/on-message.js +6 -3
- package/dist/web/inbound/media.js +34 -8
- package/dist/web/inbound/monitor.js +34 -17
- package/dist/web/inbound/send-api.js +18 -17
- package/dist/web/outbound.js +12 -5
- package/dist/wizard/clack-prompter.js +40 -7
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/device-pair/index.ts +2 -2
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/irc/src/accounts.ts +1 -1
- package/extensions/irc/src/onboarding.ts +4 -4
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +10 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +10 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +10 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +10 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +10 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +10 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +10 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
- package/skills/apple-reminders/SKILL.md +100 -49
- package/skills/coding-agent/SKILL.md +34 -28
- package/skills/github/SKILL.md +131 -16
- package/skills/imsg/SKILL.md +112 -15
- package/skills/openhue/SKILL.md +101 -19
- package/skills/tmux/SKILL.md +111 -79
- package/skills/weather/SKILL.md +88 -25
- package/dist/agents/openclaw-tools.js +0 -151
- package/dist/agents/tool-security.js +0 -96
- package/dist/gateway/url-validation.js +0 -94
- package/dist/infra/openclaw-root.js +0 -109
- package/dist/infra/tmp-openclaw-dir.js +0 -81
- package/dist/media/path-sanitization.js +0 -78
|
@@ -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 {
|
|
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
|
|
14
|
-
|
|
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(
|
|
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 ??
|
|
35
|
+
const src = opts?.sourceDir ?? resolveBundledExtensionRootDir();
|
|
25
36
|
if (!hasManifest(src)) {
|
|
26
|
-
throw new Error("Bundled Chrome extension is missing. Reinstall
|
|
37
|
+
throw new Error("Bundled Chrome extension is missing. Reinstall Pool Bot and try again.");
|
|
27
38
|
}
|
|
28
|
-
const stateDir = opts?.stateDir ??
|
|
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 “
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
.
|
|
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
|
|
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("
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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() === "#
|
|
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 <(
|
|
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 = `#
|
|
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 <(
|
|
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
|
|
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 '
|
|
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) {
|