@flrande/browserctl 0.1.0 → 0.2.0-dev.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL-CN.md +28 -0
- package/INSTALL.md +28 -0
- package/README-CN.md +27 -1131
- package/README.md +27 -1131
- package/apps/browserctl/src/commands/command-wrappers.test.ts +386 -0
- package/apps/browserctl/src/commands/network-wait-for.test.ts +90 -0
- package/apps/browserctl/src/e2e.test.ts +9 -5
- package/apps/browserctl/src/main.dispatch.test.ts +256 -0
- package/apps/browserctl/src/smoke.e2e.test.ts +97 -0
- package/apps/browserctl/src/test-port.ts +26 -0
- package/apps/browserd/src/chrome-relay-extension-bridge.test.ts +6 -31
- package/apps/browserd/src/container.ts +12 -10
- package/apps/browserd/src/main.test.ts +81 -46
- package/apps/browserd/src/test-port.ts +26 -0
- package/apps/browserd/src/tool-matrix.test.ts +398 -0
- package/extensions/chrome-relay/README-CN.md +39 -0
- package/extensions/chrome-relay/README.md +3 -0
- package/package.json +6 -4
- package/apps/browserctl/src/smoke.test.ts +0 -16
- package/apps/browserctl/src/smoke.ts +0 -5
- package/scripts/smoke.ps1 +0 -127
package/README.md
CHANGED
|
@@ -2,1154 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
English | [简体中文](README-CN.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Extension-first browser control toolkit for coding agents.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Install In Agents
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
1. It parses command arguments.
|
|
12
|
-
2. It sends tool calls to `browserd`.
|
|
13
|
-
3. If the daemon is not reachable, it auto-starts `browserd` and retries once.
|
|
14
|
-
|
|
15
|
-
The root package also publishes:
|
|
16
|
-
|
|
17
|
-
- `browserctl` -> `bin/browserctl.cjs`
|
|
18
|
-
- `browserd` -> `bin/browserd.cjs`
|
|
19
|
-
|
|
20
|
-
## Quick Start
|
|
21
|
-
|
|
22
|
-
Prerequisites:
|
|
23
|
-
|
|
24
|
-
- Node.js 22+
|
|
25
|
-
- pnpm
|
|
26
|
-
- PowerShell 7 (`pwsh`)
|
|
27
|
-
|
|
28
|
-
Minimum setup (first run, ~2 minutes):
|
|
29
|
-
|
|
30
|
-
```powershell
|
|
31
|
-
pnpm install
|
|
32
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts status --json
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Full repository checks (recommended before you contribute code):
|
|
36
|
-
|
|
37
|
-
```powershell
|
|
38
|
-
pnpm lint
|
|
39
|
-
pnpm typecheck
|
|
40
|
-
pnpm run test:all
|
|
41
|
-
pnpm build
|
|
42
|
-
pwsh -NoLogo -NoProfile -File .\scripts\smoke.ps1
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Start daemon in persistent TCP mode:
|
|
46
|
-
|
|
47
|
-
```powershell
|
|
48
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-start --json
|
|
49
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-status --json
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Change daemon port for current shell:
|
|
53
|
-
|
|
54
|
-
```powershell
|
|
55
|
-
$env:BROWSERCTL_DAEMON_PORT = "42491"
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## Release Workflow
|
|
59
|
-
|
|
60
|
-
Use this checklist before pushing a release tag:
|
|
61
|
-
|
|
62
|
-
```powershell
|
|
63
|
-
pnpm lint
|
|
64
|
-
pnpm typecheck
|
|
65
|
-
pnpm run test:all
|
|
66
|
-
pnpm build
|
|
67
|
-
pwsh -NoLogo -NoProfile -File .\scripts\smoke.ps1
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Tag publish flow:
|
|
71
|
-
|
|
72
|
-
```powershell
|
|
73
|
-
$version = node -p "require('./package.json').version"
|
|
74
|
-
git tag "v$version"
|
|
75
|
-
git push origin "v$version"
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Notes:
|
|
79
|
-
|
|
80
|
-
- `publish.yml` runs a cross-platform verify matrix before publish.
|
|
81
|
-
- Publish job uploads dry-run and npm dist-tag artifacts for traceability.
|
|
82
|
-
- Manual publish (`workflow_dispatch`) supports `dry_run` and `dist_tag`.
|
|
83
|
-
|
|
84
|
-
## Start Here (Beginner Guide)
|
|
85
|
-
|
|
86
|
-
If you are new, use this order:
|
|
87
|
-
|
|
88
|
-
1. Run the minimum setup once.
|
|
89
|
-
2. Start with Path A (`managed-local`, recommended).
|
|
90
|
-
3. Use Path B (`chrome-relay`) only when you need to control your already-open browser.
|
|
91
|
-
|
|
92
|
-
### Path A: Control a New Local Browser (Recommended)
|
|
93
|
-
|
|
94
|
-
```powershell
|
|
95
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-start --json
|
|
96
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts status --json --session demo --profile managed-local
|
|
97
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts tab-open --json --session demo --profile managed-local https://example.com
|
|
98
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts tabs --json --session demo --profile managed-local
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
Optional snapshot in PowerShell:
|
|
102
|
-
|
|
103
|
-
```powershell
|
|
104
|
-
$tabs = pnpm exec tsx .\apps\browserctl\src\main.ts tabs --json --session demo --profile managed-local | ConvertFrom-Json
|
|
105
|
-
$targetId = $tabs.data.tabs[0]
|
|
106
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts snapshot --json --session demo --profile managed-local $targetId
|
|
107
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts screenshot --json --session demo --profile managed-local $targetId
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Path B: Control Your Current Edge/Chrome (Extension Relay)
|
|
111
|
-
|
|
112
|
-
1. Configure daemon for extension relay:
|
|
113
|
-
|
|
114
|
-
```powershell
|
|
115
|
-
$env:BROWSERD_DEFAULT_DRIVER = "chrome-relay"
|
|
116
|
-
$env:BROWSERD_CHROME_RELAY_MODE = "extension"
|
|
117
|
-
$env:BROWSERD_CHROME_RELAY_URL = "http://127.0.0.1:9223"
|
|
118
|
-
$env:BROWSERD_CHROME_RELAY_EXTENSION_TOKEN = "relay-secret"
|
|
119
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-stop --json
|
|
120
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-start --json
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
2. In `edge://extensions` or `chrome://extensions`, enable Developer mode and load unpacked extension from `extensions/chrome-relay`.
|
|
124
|
-
3. Open extension popup, set `Bridge URL` to `ws://127.0.0.1:9223/bridge`, set the same token (`relay-secret`), click Save, then Reconnect.
|
|
125
|
-
4. Verify connection:
|
|
126
|
-
|
|
127
|
-
```powershell
|
|
128
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts status --json --session relay --profile chrome-relay
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Expected signal: `status.data.status.connected = true`.
|
|
132
|
-
|
|
133
|
-
### Quick Failure Checks
|
|
134
|
-
|
|
135
|
-
If commands fail, run these first:
|
|
136
|
-
|
|
137
|
-
```powershell
|
|
138
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-status --json
|
|
139
|
-
Invoke-WebRequest -UseBasicParsing -Uri "http://127.0.0.1:9223/browserctl/relay/status" -TimeoutSec 3
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
If relay status says `connected: false`, re-open extension popup and click Reconnect.
|
|
143
|
-
|
|
144
|
-
## Extended Read/Control APIs
|
|
145
|
-
|
|
146
|
-
The CLI now includes additional browser reading/control commands:
|
|
9
|
+
Paste this to your agent:
|
|
147
10
|
|
|
148
11
|
```text
|
|
149
|
-
|
|
150
|
-
dom-query-all <targetId> <selector>
|
|
151
|
-
element-screenshot <targetId> <selector>
|
|
152
|
-
a11y-snapshot <targetId> [selector]
|
|
153
|
-
network-wait-for <targetId> <urlPattern> [--method <METHOD>] [--status <CODE>] [--timeout-ms <ms>] [--poll-ms <ms>]
|
|
154
|
-
cookie-get <targetId> [name]
|
|
155
|
-
cookie-set <targetId> <name> <value> [url]
|
|
156
|
-
cookie-clear <targetId> [name]
|
|
157
|
-
storage-get <targetId> <local|session> <key>
|
|
158
|
-
storage-set <targetId> <local|session> <key> <value>
|
|
159
|
-
frame-list <targetId>
|
|
160
|
-
frame-snapshot <targetId> <frameId>
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
Example:
|
|
164
|
-
|
|
165
|
-
```powershell
|
|
166
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts dom-query --json --session demo $targetId "article h1"
|
|
167
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts element-screenshot --json --session demo $targetId "#main"
|
|
168
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts network-wait-for --json --session demo $targetId "/api/items" --method GET --status 200 --timeout-ms 15000
|
|
169
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts cookie-get --json --session demo $targetId
|
|
170
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts storage-set --json --session demo $targetId local theme dark
|
|
171
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts frame-list --json --session demo $targetId
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
## Global Command Model
|
|
175
|
-
|
|
176
|
-
Syntax:
|
|
177
|
-
|
|
178
|
-
```text
|
|
179
|
-
browserctl [--json] <command> [command-options] [positionals]
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Global options handled by command context:
|
|
183
|
-
|
|
184
|
-
- `--session <id>`: session namespace, default `cli:local`
|
|
185
|
-
- `--profile <driverKey>`: driver key override (`managed`, `managed-local`, `chrome-relay`, `remote-cdp`)
|
|
186
|
-
- `--token <authToken>`: auth token override
|
|
187
|
-
- `--browser <preset>`: startup browser preset (`chromium`, `chrome`, `edge`)
|
|
188
|
-
|
|
189
|
-
Notes:
|
|
190
|
-
|
|
191
|
-
- `--json` is consumed globally and controls envelope output.
|
|
192
|
-
- Unknown flags are not validated as option schema; they may be treated as positional tokens.
|
|
193
|
-
- `--browser` affects daemon startup only. If daemon is already running, it does not hot-reconfigure the existing process.
|
|
194
|
-
|
|
195
|
-
## Core Concepts
|
|
196
|
-
|
|
197
|
-
## Session Namespace (`--session`)
|
|
198
|
-
|
|
199
|
-
A session namespace is the `sessionId` used by daemon-side session store.
|
|
200
|
-
|
|
201
|
-
1. Daemon tracks per-session state such as current `profile` (driver key) and current `targetId`.
|
|
202
|
-
2. Default is `cli:local`; override with `--session <id>`.
|
|
203
|
-
3. Different session IDs isolate control context from each other.
|
|
204
|
-
4. This is context isolation, not security isolation.
|
|
205
|
-
5. Session state is in-memory and resets when daemon restarts.
|
|
206
|
-
|
|
207
|
-
## Auth Token (`--token`, `BROWSERD_AUTH_TOKEN`)
|
|
208
|
-
|
|
209
|
-
Auth token is a shared secret string used for request authentication.
|
|
210
|
-
|
|
211
|
-
1. If daemon sets `BROWSERD_AUTH_TOKEN`, each tool call must include matching `authToken`.
|
|
212
|
-
2. CLI forwards token from `--token` or `BROWSERCTL_AUTH_TOKEN`.
|
|
213
|
-
3. Missing or mismatched token returns `E_PERMISSION: Invalid auth token.`.
|
|
214
|
-
4. Token controls authentication; operation scope is separately limited by `BROWSERD_AUTH_SCOPES`.
|
|
215
|
-
|
|
216
|
-
## Browser Presets (`--browser`)
|
|
217
|
-
|
|
218
|
-
Browser preset controls managed-local startup channel selection.
|
|
219
|
-
|
|
220
|
-
1. `chromium`: `browserName=chromium` with no channel override.
|
|
221
|
-
2. `chrome`: `browserName=chromium`, `channel=chrome`.
|
|
222
|
-
3. `edge`: `browserName=chromium`, `channel=msedge`.
|
|
223
|
-
4. Presets do not affect `chrome-relay` or `remote-cdp`.
|
|
224
|
-
5. Presets apply when daemon starts. If daemon is already running, restart daemon to switch preset.
|
|
225
|
-
|
|
226
|
-
## Exit Codes and Output
|
|
227
|
-
|
|
228
|
-
Exit codes:
|
|
229
|
-
|
|
230
|
-
- `0`: success
|
|
231
|
-
- `1`: command execution error
|
|
232
|
-
- `2`: invalid args or unknown command
|
|
233
|
-
|
|
234
|
-
Success envelope (`--json`):
|
|
235
|
-
|
|
236
|
-
```json
|
|
237
|
-
{
|
|
238
|
-
"ok": true,
|
|
239
|
-
"command": "status",
|
|
240
|
-
"data": {
|
|
241
|
-
"kind": "browserd",
|
|
242
|
-
"ready": true
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
Error envelope (`--json`, written to stderr):
|
|
248
|
-
|
|
249
|
-
```json
|
|
250
|
-
{
|
|
251
|
-
"ok": false,
|
|
252
|
-
"error": {
|
|
253
|
-
"message": "E_PERMISSION: Invalid auth token.",
|
|
254
|
-
"exitCode": 1
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
## Environment Variables
|
|
260
|
-
|
|
261
|
-
### CLI (`browserctl`)
|
|
262
|
-
|
|
263
|
-
| Variable | Default | Notes |
|
|
264
|
-
| --- | --- | --- |
|
|
265
|
-
| `BROWSERCTL_DAEMON_PORT` | `41337` | TCP port for daemon requests. |
|
|
266
|
-
| `BROWSERCTL_DAEMON_STARTUP_TIMEOUT_MS` | `10000` | Max wait for daemon readiness. |
|
|
267
|
-
| `BROWSERCTL_DAEMON_REQUEST_TIMEOUT_MS` | `5000` | Per-request socket timeout. |
|
|
268
|
-
| `BROWSERCTL_BROWSER` | unset | Default browser preset for daemon startup (`chromium`, `chrome`, `edge`). |
|
|
269
|
-
| `BROWSERCTL_AUTH_TOKEN` | unset | Default auth token for requests. |
|
|
270
|
-
|
|
271
|
-
Precedence:
|
|
272
|
-
|
|
273
|
-
- token: `--token` > `BROWSERCTL_AUTH_TOKEN`
|
|
274
|
-
- browser preset: `--browser` > `BROWSERCTL_BROWSER`
|
|
275
|
-
|
|
276
|
-
### Daemon (`browserd`)
|
|
277
|
-
|
|
278
|
-
| Variable | Default | Notes |
|
|
279
|
-
| --- | --- | --- |
|
|
280
|
-
| `BROWSERD_TRANSPORT` | `stdio` | CLI-managed daemon startup uses `tcp`. |
|
|
281
|
-
| `BROWSERD_STDIO_PROTOCOL` | `mcp` | `legacy` is JSON-line legacy mode. |
|
|
282
|
-
| `BROWSERD_HOST` | `127.0.0.1` | TCP host when transport is tcp. |
|
|
283
|
-
| `BROWSERD_PORT` | `41337` | TCP port when transport is tcp. |
|
|
284
|
-
| `BROWSERD_DEFAULT_DRIVER` | `managed-local` if enabled, else `managed` | Falls back to `managed` if unavailable. |
|
|
285
|
-
| `BROWSERD_MANAGED_LOCAL_ENABLED` | `true` | Disable to unregister `managed-local`. |
|
|
286
|
-
| `BROWSERD_MANAGED_LOCAL_BROWSER` | `chromium` | `chromium`, `firefox`, `webkit`. |
|
|
287
|
-
| `BROWSERD_MANAGED_LOCAL_HEADLESS` | `true` | Supports `1/0`, `true/false`, `yes/no`, `on/off`. |
|
|
288
|
-
| `BROWSERD_MANAGED_LOCAL_CHANNEL` | unset | Optional channel override. |
|
|
289
|
-
| `BROWSERD_MANAGED_LOCAL_EXECUTABLE_PATH` | unset | Optional executable path. |
|
|
290
|
-
| `BROWSERD_MANAGED_LOCAL_LAUNCH_TIMEOUT_MS` | unset | Non-negative integer. |
|
|
291
|
-
| `BROWSERD_MANAGED_LOCAL_ARGS` | unset (`[]`) | Comma-separated launch args. |
|
|
292
|
-
| `BROWSERD_CHROME_RELAY_URL` | `http://127.0.0.1:9223` | `chrome-relay` endpoint. |
|
|
293
|
-
| `BROWSERD_CHROME_RELAY_MODE` | `cdp` | `chrome-relay` mode: `cdp` or `extension`. |
|
|
294
|
-
| `BROWSERD_CHROME_RELAY_EXTENSION_TOKEN` | unset | Required when `BROWSERD_CHROME_RELAY_MODE=extension`. |
|
|
295
|
-
| `BROWSERD_CHROME_RELAY_EXTENSION_REQUEST_TIMEOUT_MS` | `5000` | Extension bridge RPC timeout (ms). |
|
|
296
|
-
| `BROWSERD_REMOTE_CDP_URL` | `http://127.0.0.1:9222/devtools/browser/default` | `remote-cdp` endpoint. |
|
|
297
|
-
| `BROWSERD_AUTH_TOKEN` | unset | Required when `BROWSERD_TRANSPORT=tcp`; each tool call must include matching `authToken`. |
|
|
298
|
-
| `BROWSERD_AUTH_SCOPES` | `read,act,upload,download` | Allowed scopes. |
|
|
299
|
-
| `BROWSERD_UPLOAD_ROOT` | unset | Upload path allowlist root. |
|
|
300
|
-
| `BROWSERD_DOWNLOAD_ROOT` | unset | Download path allowlist root. |
|
|
301
|
-
|
|
302
|
-
## Runtime Defaults and Driver Notes
|
|
303
|
-
|
|
304
|
-
Default runtime behavior:
|
|
305
|
-
|
|
306
|
-
- `managed-local` is enabled by default and selected as default driver.
|
|
307
|
-
- `managed`, `chrome-relay`, and `remote-cdp` are always registered.
|
|
308
|
-
- `BROWSERD_DEFAULT_DRIVER` can force a default driver key.
|
|
309
|
-
- If the configured default is unavailable, runtime falls back to `managed`.
|
|
310
|
-
- Default remote endpoints:
|
|
311
|
-
- `BROWSERD_CHROME_RELAY_URL=http://127.0.0.1:9223`
|
|
312
|
-
- `BROWSERD_REMOTE_CDP_URL=http://127.0.0.1:9222/devtools/browser/default`
|
|
313
|
-
|
|
314
|
-
`managed-local` notes:
|
|
315
|
-
|
|
316
|
-
- Browser launch is lazy (first operation requiring a browser context).
|
|
317
|
-
- Optional launch controls:
|
|
318
|
-
- `BROWSERD_MANAGED_LOCAL_BROWSER` (`chromium|firefox|webkit`, default `chromium`)
|
|
319
|
-
- `BROWSERD_MANAGED_LOCAL_HEADLESS` (default `true`)
|
|
320
|
-
- `BROWSERD_MANAGED_LOCAL_CHANNEL`
|
|
321
|
-
- `BROWSERD_MANAGED_LOCAL_EXECUTABLE_PATH`
|
|
322
|
-
- `BROWSERD_MANAGED_LOCAL_LAUNCH_TIMEOUT_MS`
|
|
323
|
-
- `BROWSERD_MANAGED_LOCAL_ARGS` (comma-separated)
|
|
324
|
-
|
|
325
|
-
`chrome-relay` notes:
|
|
326
|
-
|
|
327
|
-
- Uses `BROWSERD_CHROME_RELAY_URL` (default `http://127.0.0.1:9223`).
|
|
328
|
-
- Default mode is `BROWSERD_CHROME_RELAY_MODE=cdp` and accepts `ws(s)` or `http(s)` URLs.
|
|
329
|
-
- For `http(s)`, runtime attempts `/json/version` and uses `webSocketDebuggerUrl` if available.
|
|
330
|
-
- `BROWSERD_CHROME_RELAY_MODE=extension` starts a local extension bridge on `BROWSERD_CHROME_RELAY_URL`.
|
|
331
|
-
- In extension mode, install `extensions/chrome-relay` as unpacked extension and set popup Bridge URL to `ws://127.0.0.1:9223/bridge` (or your custom relay host/port).
|
|
332
|
-
- Extension mode requires `BROWSERD_CHROME_RELAY_EXTENSION_TOKEN` and the same popup token.
|
|
333
|
-
- Extension mode now streams console and network telemetry (including response bodies when available) through the bridge.
|
|
334
|
-
- On connection failures while using `--profile chrome-relay`, CLI appends guided checklist text.
|
|
335
|
-
|
|
336
|
-
Example:
|
|
337
|
-
|
|
338
|
-
```powershell
|
|
339
|
-
$env:BROWSERD_DEFAULT_DRIVER = "chrome-relay"
|
|
340
|
-
$env:BROWSERD_CHROME_RELAY_URL = "http://127.0.0.1:9223"
|
|
341
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts status --json --session cli:relay --profile chrome-relay
|
|
12
|
+
Fetch and follow instructions from https://raw.githubusercontent.com/Flrande/browserctl/refs/heads/master/INSTALL.md
|
|
342
13
|
```
|
|
343
14
|
|
|
344
|
-
|
|
15
|
+
Platform shortcuts:
|
|
345
16
|
|
|
346
|
-
-
|
|
347
|
-
-
|
|
17
|
+
- Codex: `https://raw.githubusercontent.com/Flrande/browserctl/refs/heads/master/.codex/INSTALL.md`
|
|
18
|
+
- Claude Code: `https://raw.githubusercontent.com/Flrande/browserctl/refs/heads/master/.claude-plugin/INSTALL.md`
|
|
19
|
+
- Cursor: `https://raw.githubusercontent.com/Flrande/browserctl/refs/heads/master/.cursor-plugin/INSTALL.md`
|
|
20
|
+
- OpenCode: `https://raw.githubusercontent.com/Flrande/browserctl/refs/heads/master/.opencode/INSTALL.md`
|
|
348
21
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
```powershell
|
|
352
|
-
$env:BROWSERD_DEFAULT_DRIVER = "remote-cdp"
|
|
353
|
-
$env:BROWSERD_REMOTE_CDP_URL = "http://127.0.0.1:9222/devtools/browser/default"
|
|
354
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts status --json --session cli:remote --profile remote-cdp
|
|
355
|
-
```
|
|
22
|
+
Default skill:
|
|
356
23
|
|
|
357
|
-
|
|
24
|
+
- Name: `browserctl`
|
|
25
|
+
- Path: `skills/browserctl`
|
|
358
26
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
| Driver | What it is | Best for | Requirements | Typical status field |
|
|
362
|
-
| --- | --- | --- | --- | --- |
|
|
363
|
-
| `managed` | In-memory managed stub driver | Contract tests, deterministic local checks | None | `status.kind = managed` |
|
|
364
|
-
| `managed-local` | Real local browser launched by Playwright | Default local automation | Local browser runtime; optional channel/executable config | `status.kind = managed-local` |
|
|
365
|
-
| `chrome-relay` | CDP connection via relay endpoint (`ws/http`) | Attach workflow, extension relay workflow | Reachable relay endpoint (`BROWSERD_CHROME_RELAY_URL`) | `status.kind = chrome-relay` |
|
|
366
|
-
| `remote-cdp` | Direct CDP connection to remote/local browser endpoint | Existing browser/CDP infra | Reachable CDP endpoint (`BROWSERD_REMOTE_CDP_URL`) | `status.kind = remote-cdp` |
|
|
367
|
-
|
|
368
|
-
How to select a driver:
|
|
369
|
-
|
|
370
|
-
1. Per command: pass `--profile <driverKey>`.
|
|
371
|
-
2. Per session: `profile-use <driverKey> --session <id>`.
|
|
372
|
-
3. Daemon default: set `BROWSERD_DEFAULT_DRIVER`.
|
|
373
|
-
|
|
374
|
-
### Use `managed` (stub)
|
|
27
|
+
## Browser Quick Start (Extension Default)
|
|
375
28
|
|
|
376
29
|
```powershell
|
|
377
|
-
|
|
378
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts status --json --session demo --profile managed
|
|
379
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts tab-open --json --session demo --profile managed https://example.com
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
### Use `managed-local` (real local browser)
|
|
30
|
+
npm install --global @flrande/browserctl
|
|
383
31
|
|
|
384
|
-
```powershell
|
|
385
|
-
$env:BROWSERD_DEFAULT_DRIVER = "managed-local"
|
|
386
|
-
$env:BROWSERD_MANAGED_LOCAL_HEADLESS = "false"
|
|
387
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-stop --json
|
|
388
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-start --json --browser edge
|
|
389
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts status --json --session demo --profile managed-local
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
### Use `chrome-relay`
|
|
393
|
-
|
|
394
|
-
```powershell
|
|
395
|
-
$env:BROWSERD_DEFAULT_DRIVER = "chrome-relay"
|
|
396
|
-
$env:BROWSERD_CHROME_RELAY_URL = "http://127.0.0.1:9223"
|
|
397
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts status --json --session relay --profile chrome-relay
|
|
398
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts tab-open --json --session relay --profile chrome-relay https://example.com
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
If connection fails, CLI appends relay guidance (extension activation, endpoint check, URL check).
|
|
402
|
-
|
|
403
|
-
Extension mode example:
|
|
404
|
-
|
|
405
|
-
```powershell
|
|
406
32
|
$env:BROWSERD_DEFAULT_DRIVER = "chrome-relay"
|
|
407
33
|
$env:BROWSERD_CHROME_RELAY_MODE = "extension"
|
|
408
34
|
$env:BROWSERD_CHROME_RELAY_URL = "http://127.0.0.1:9223"
|
|
409
|
-
$env:BROWSERD_CHROME_RELAY_EXTENSION_TOKEN = "relay
|
|
410
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-stop --json
|
|
411
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-start --json
|
|
412
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts status --json --session relay --profile chrome-relay
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
Install extension (Chrome/Edge):
|
|
416
|
-
|
|
417
|
-
1. Open `chrome://extensions` or `edge://extensions`.
|
|
418
|
-
2. Enable Developer mode.
|
|
419
|
-
3. Click Load unpacked and select `extensions/chrome-relay`.
|
|
420
|
-
4. Open extension popup, set Bridge URL and the same token, then click Save/Reconnect.
|
|
421
|
-
|
|
422
|
-
### Use `remote-cdp`
|
|
423
|
-
|
|
424
|
-
```powershell
|
|
425
|
-
$env:BROWSERD_DEFAULT_DRIVER = "remote-cdp"
|
|
426
|
-
$env:BROWSERD_REMOTE_CDP_URL = "http://127.0.0.1:9222/devtools/browser/default"
|
|
427
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts status --json --session remote --profile remote-cdp
|
|
428
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts tab-open --json --session remote --profile remote-cdp https://example.com
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
Recommended switching pattern:
|
|
432
|
-
|
|
433
|
-
1. Use one dedicated session per driver (`session:local`, `session:relay`, `session:remote`).
|
|
434
|
-
2. Prefer explicit `--profile` in automation scripts to avoid implicit session carry-over.
|
|
435
|
-
|
|
436
|
-
## Auth and Guardrails
|
|
437
|
-
|
|
438
|
-
- `BROWSERD_TRANSPORT=tcp` requires `BROWSERD_AUTH_TOKEN`.
|
|
439
|
-
- If `BROWSERD_AUTH_TOKEN` is set, every tool call must include matching `authToken`.
|
|
440
|
-
- `BROWSERD_AUTH_SCOPES` is a comma-separated allowlist of `read`, `act`, `upload`, `download`.
|
|
441
|
-
- `browser.upload.arm` is denied unless `BROWSERD_UPLOAD_ROOT` is set.
|
|
442
|
-
- `browser.download.wait` is denied unless `BROWSERD_DOWNLOAD_ROOT` is set.
|
|
443
|
-
- `BROWSERD_UPLOAD_ROOT` restricts `upload-arm` files to paths under that root.
|
|
444
|
-
- `BROWSERD_DOWNLOAD_ROOT` restricts `download-wait` output paths to that root.
|
|
445
|
-
- `download-wait` accepts optional positional `path`.
|
|
446
|
-
- If `BROWSERD_DOWNLOAD_ROOT` is set and neither request path nor driver payload path exists, `download-wait` returns an internal error.
|
|
447
|
-
|
|
448
|
-
## Driver and Session Behavior
|
|
449
|
-
|
|
450
|
-
Registered drivers:
|
|
451
|
-
|
|
452
|
-
- `managed`
|
|
453
|
-
- `managed-local` (unless disabled)
|
|
454
|
-
- `chrome-relay`
|
|
455
|
-
- `remote-cdp`
|
|
456
|
-
|
|
457
|
-
Session store behavior:
|
|
458
|
-
|
|
459
|
-
1. `--profile` overrides driver for the current call and updates the session profile.
|
|
460
|
-
2. If `--profile` is omitted, daemon resolves from session profile first, then default driver.
|
|
461
|
-
3. `tab-open` updates session target to the newly opened target.
|
|
462
|
-
|
|
463
|
-
## Edge and Browser Presets
|
|
464
|
-
|
|
465
|
-
`--browser` or `BROWSERCTL_BROWSER` mapping:
|
|
466
|
-
|
|
467
|
-
- `edge` -> `chromium + channel=msedge`
|
|
468
|
-
- `chrome` -> `chromium + channel=chrome`
|
|
469
|
-
- `chromium` -> `chromium` without channel override
|
|
470
|
-
|
|
471
|
-
Examples:
|
|
472
|
-
|
|
473
|
-
```powershell
|
|
474
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-stop --json
|
|
475
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-start --json --browser edge
|
|
476
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts status --json
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
## Command Reference (With JSON Examples)
|
|
480
|
-
|
|
481
|
-
All examples below use:
|
|
482
|
-
|
|
483
|
-
```powershell
|
|
484
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
## `daemon-start`
|
|
488
|
-
|
|
489
|
-
Purpose: Ensure daemon is running. Starts it if not running.
|
|
490
|
-
|
|
491
|
-
Syntax:
|
|
492
|
-
|
|
493
|
-
```text
|
|
494
|
-
daemon-start [--json] [--token <authToken>] [--browser <chromium|chrome|edge>]
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
Example command:
|
|
498
|
-
|
|
499
|
-
```powershell
|
|
500
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-start --json --browser edge
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
Example JSON output:
|
|
504
|
-
|
|
505
|
-
```json
|
|
506
|
-
{
|
|
507
|
-
"ok": true,
|
|
508
|
-
"command": "daemon-start",
|
|
509
|
-
"data": {
|
|
510
|
-
"running": true,
|
|
511
|
-
"port": 41337,
|
|
512
|
-
"pid": 24680
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
```
|
|
516
|
-
|
|
517
|
-
## `daemon-status`
|
|
518
|
-
|
|
519
|
-
Purpose: Check if daemon is reachable.
|
|
520
|
-
|
|
521
|
-
Syntax:
|
|
522
|
-
|
|
523
|
-
```text
|
|
524
|
-
daemon-status [--json] [--token <authToken>]
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
Example command:
|
|
528
|
-
|
|
529
|
-
```powershell
|
|
530
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-status --json
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
Example JSON output:
|
|
534
|
-
|
|
535
|
-
```json
|
|
536
|
-
{
|
|
537
|
-
"ok": true,
|
|
538
|
-
"command": "daemon-status",
|
|
539
|
-
"data": {
|
|
540
|
-
"running": true,
|
|
541
|
-
"port": 41337,
|
|
542
|
-
"pid": 24680
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
```
|
|
546
|
-
|
|
547
|
-
## `daemon-stop`
|
|
548
|
-
|
|
549
|
-
Purpose: Stop daemon using PID file.
|
|
550
|
-
|
|
551
|
-
Syntax:
|
|
552
|
-
|
|
553
|
-
```text
|
|
554
|
-
daemon-stop [--json]
|
|
555
|
-
```
|
|
556
|
-
|
|
557
|
-
Example command:
|
|
558
|
-
|
|
559
|
-
```powershell
|
|
560
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts daemon-stop --json
|
|
561
|
-
```
|
|
562
|
-
|
|
563
|
-
Example JSON output:
|
|
564
|
-
|
|
565
|
-
```json
|
|
566
|
-
{
|
|
567
|
-
"ok": true,
|
|
568
|
-
"command": "daemon-stop",
|
|
569
|
-
"data": {
|
|
570
|
-
"stopped": true,
|
|
571
|
-
"port": 41337,
|
|
572
|
-
"pid": 24680
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
## `status`
|
|
578
|
-
|
|
579
|
-
Purpose: Get browserd status plus selected driver status.
|
|
580
|
-
|
|
581
|
-
Syntax:
|
|
582
|
-
|
|
583
|
-
```text
|
|
584
|
-
status [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
585
|
-
```
|
|
586
|
-
|
|
587
|
-
Example command:
|
|
35
|
+
$env:BROWSERD_CHROME_RELAY_EXTENSION_TOKEN = "browserctl-relay"
|
|
588
36
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
Example JSON output:
|
|
594
|
-
|
|
595
|
-
```json
|
|
596
|
-
{
|
|
597
|
-
"ok": true,
|
|
598
|
-
"command": "status",
|
|
599
|
-
"data": {
|
|
600
|
-
"kind": "browserd",
|
|
601
|
-
"ready": true,
|
|
602
|
-
"driver": "managed-local",
|
|
603
|
-
"drivers": [
|
|
604
|
-
"chrome-relay",
|
|
605
|
-
"managed",
|
|
606
|
-
"managed-local",
|
|
607
|
-
"remote-cdp"
|
|
608
|
-
],
|
|
609
|
-
"status": {
|
|
610
|
-
"kind": "managed-local",
|
|
611
|
-
"connected": false,
|
|
612
|
-
"launched": false,
|
|
613
|
-
"browserName": "chromium",
|
|
614
|
-
"headless": true
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
```
|
|
619
|
-
|
|
620
|
-
## `tabs`
|
|
621
|
-
|
|
622
|
-
Purpose: List target IDs for current driver/profile context.
|
|
623
|
-
|
|
624
|
-
Syntax:
|
|
625
|
-
|
|
626
|
-
```text
|
|
627
|
-
tabs [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
628
|
-
```
|
|
629
|
-
|
|
630
|
-
Example command:
|
|
631
|
-
|
|
632
|
-
```powershell
|
|
633
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts tabs --json --session demo
|
|
634
|
-
```
|
|
635
|
-
|
|
636
|
-
Example JSON output:
|
|
637
|
-
|
|
638
|
-
```json
|
|
639
|
-
{
|
|
640
|
-
"ok": true,
|
|
641
|
-
"command": "tabs",
|
|
642
|
-
"data": {
|
|
643
|
-
"driver": "managed-local",
|
|
644
|
-
"tabs": [
|
|
645
|
-
"target:managed-local:profile:managed-local:default:1"
|
|
646
|
-
]
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
```
|
|
650
|
-
|
|
651
|
-
## `profile-list`
|
|
652
|
-
|
|
653
|
-
Purpose: List profiles for the selected driver.
|
|
654
|
-
|
|
655
|
-
Syntax:
|
|
656
|
-
|
|
657
|
-
```text
|
|
658
|
-
profile-list [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
659
|
-
```
|
|
660
|
-
|
|
661
|
-
Example command:
|
|
662
|
-
|
|
663
|
-
```powershell
|
|
664
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts profile-list --json --profile managed-local
|
|
665
|
-
```
|
|
666
|
-
|
|
667
|
-
Example JSON output:
|
|
668
|
-
|
|
669
|
-
```json
|
|
670
|
-
{
|
|
671
|
-
"ok": true,
|
|
672
|
-
"command": "profile-list",
|
|
673
|
-
"data": {
|
|
674
|
-
"driver": "managed-local",
|
|
675
|
-
"profiles": [
|
|
676
|
-
"profile:managed-local:default"
|
|
677
|
-
]
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
```
|
|
681
|
-
|
|
682
|
-
## `profile-use`
|
|
683
|
-
|
|
684
|
-
Purpose: Bind session to a driver key.
|
|
685
|
-
|
|
686
|
-
Syntax:
|
|
687
|
-
|
|
688
|
-
```text
|
|
689
|
-
profile-use <driverKey> [--json] [--session <id>] [--token <authToken>]
|
|
690
|
-
```
|
|
691
|
-
|
|
692
|
-
Example command:
|
|
693
|
-
|
|
694
|
-
```powershell
|
|
695
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts profile-use --json --session demo chrome-relay
|
|
696
|
-
```
|
|
697
|
-
|
|
698
|
-
Example JSON output:
|
|
699
|
-
|
|
700
|
-
```json
|
|
701
|
-
{
|
|
702
|
-
"ok": true,
|
|
703
|
-
"command": "profile-use",
|
|
704
|
-
"data": {
|
|
705
|
-
"profile": "chrome-relay"
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
```
|
|
709
|
-
|
|
710
|
-
## `tab-open`
|
|
711
|
-
|
|
712
|
-
Purpose: Open a new tab and navigate to URL.
|
|
713
|
-
|
|
714
|
-
Syntax:
|
|
715
|
-
|
|
716
|
-
```text
|
|
717
|
-
tab-open <url> [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
718
|
-
```
|
|
719
|
-
|
|
720
|
-
Example command:
|
|
721
|
-
|
|
722
|
-
```powershell
|
|
723
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts tab-open --json --session demo https://example.com
|
|
724
|
-
```
|
|
725
|
-
|
|
726
|
-
Example JSON output:
|
|
727
|
-
|
|
728
|
-
```json
|
|
729
|
-
{
|
|
730
|
-
"ok": true,
|
|
731
|
-
"command": "tab-open",
|
|
732
|
-
"data": {
|
|
733
|
-
"driver": "managed-local",
|
|
734
|
-
"targetId": "target:managed-local:profile:managed-local:default:2"
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
```
|
|
738
|
-
|
|
739
|
-
## `tab-focus`
|
|
740
|
-
|
|
741
|
-
Purpose: Focus an existing target.
|
|
742
|
-
|
|
743
|
-
Syntax:
|
|
744
|
-
|
|
745
|
-
```text
|
|
746
|
-
tab-focus <targetId> [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
747
|
-
```
|
|
748
|
-
|
|
749
|
-
Example command:
|
|
750
|
-
|
|
751
|
-
```powershell
|
|
752
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts tab-focus --json --session demo target:managed-local:profile:managed-local:default:2
|
|
753
|
-
```
|
|
754
|
-
|
|
755
|
-
Example JSON output:
|
|
756
|
-
|
|
757
|
-
```json
|
|
758
|
-
{
|
|
759
|
-
"ok": true,
|
|
760
|
-
"command": "tab-focus",
|
|
761
|
-
"data": {
|
|
762
|
-
"driver": "managed-local",
|
|
763
|
-
"targetId": "target:managed-local:profile:managed-local:default:2",
|
|
764
|
-
"focused": true
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
```
|
|
768
|
-
|
|
769
|
-
## `tab-close`
|
|
770
|
-
|
|
771
|
-
Purpose: Close an existing target.
|
|
772
|
-
|
|
773
|
-
Syntax:
|
|
774
|
-
|
|
775
|
-
```text
|
|
776
|
-
tab-close <targetId> [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
777
|
-
```
|
|
778
|
-
|
|
779
|
-
Example command:
|
|
780
|
-
|
|
781
|
-
```powershell
|
|
782
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts tab-close --json --session demo target:managed-local:profile:managed-local:default:2
|
|
783
|
-
```
|
|
784
|
-
|
|
785
|
-
Example JSON output:
|
|
786
|
-
|
|
787
|
-
```json
|
|
788
|
-
{
|
|
789
|
-
"ok": true,
|
|
790
|
-
"command": "tab-close",
|
|
791
|
-
"data": {
|
|
792
|
-
"driver": "managed-local",
|
|
793
|
-
"targetId": "target:managed-local:profile:managed-local:default:2",
|
|
794
|
-
"closed": true
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
```
|
|
798
|
-
|
|
799
|
-
## `snapshot`
|
|
800
|
-
|
|
801
|
-
Purpose: Capture target snapshot (URL/title/HTML/request summaries when available).
|
|
802
|
-
|
|
803
|
-
Syntax:
|
|
804
|
-
|
|
805
|
-
```text
|
|
806
|
-
snapshot <targetId> [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
807
|
-
```
|
|
808
|
-
|
|
809
|
-
Example command:
|
|
810
|
-
|
|
811
|
-
```powershell
|
|
812
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts snapshot --json --session demo target:managed-local:profile:managed-local:default:1
|
|
813
|
-
```
|
|
814
|
-
|
|
815
|
-
Example JSON output:
|
|
816
|
-
|
|
817
|
-
```json
|
|
818
|
-
{
|
|
819
|
-
"ok": true,
|
|
820
|
-
"command": "snapshot",
|
|
821
|
-
"data": {
|
|
822
|
-
"driver": "managed-local",
|
|
823
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
824
|
-
"snapshot": {
|
|
825
|
-
"kind": "managed-local",
|
|
826
|
-
"profile": "profile:managed-local:default",
|
|
827
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
828
|
-
"hasTarget": true,
|
|
829
|
-
"url": "https://example.com/",
|
|
830
|
-
"title": "Example Domain",
|
|
831
|
-
"html": "<!doctype html>...",
|
|
832
|
-
"requestSummaries": []
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
```
|
|
837
|
-
|
|
838
|
-
## `screenshot`
|
|
839
|
-
|
|
840
|
-
Purpose: Capture target screenshot (PNG base64 payload).
|
|
841
|
-
|
|
842
|
-
Syntax:
|
|
843
|
-
|
|
844
|
-
```text
|
|
845
|
-
screenshot <targetId> [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
846
|
-
```
|
|
847
|
-
|
|
848
|
-
Example command:
|
|
849
|
-
|
|
850
|
-
```powershell
|
|
851
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts screenshot --json --session demo target:managed-local:profile:managed-local:default:1
|
|
852
|
-
```
|
|
853
|
-
|
|
854
|
-
Example JSON output:
|
|
855
|
-
|
|
856
|
-
```json
|
|
857
|
-
{
|
|
858
|
-
"ok": true,
|
|
859
|
-
"command": "screenshot",
|
|
860
|
-
"data": {
|
|
861
|
-
"driver": "managed-local",
|
|
862
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
863
|
-
"screenshot": {
|
|
864
|
-
"kind": "managed-local",
|
|
865
|
-
"profile": "profile:managed-local:default",
|
|
866
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
867
|
-
"hasTarget": true,
|
|
868
|
-
"mimeType": "image/png",
|
|
869
|
-
"encoding": "base64",
|
|
870
|
-
"imageBase64": "iVBORw0KGgoAAAANSUhEUgAA..."
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
```
|
|
875
|
-
|
|
876
|
-
## `act`
|
|
877
|
-
|
|
878
|
-
Purpose: Execute an action by type on a target.
|
|
879
|
-
|
|
880
|
-
Syntax:
|
|
881
|
-
|
|
882
|
-
```text
|
|
883
|
-
act <actionType> <targetId> [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
884
|
-
```
|
|
885
|
-
|
|
886
|
-
Important behavior in current CLI:
|
|
887
|
-
|
|
888
|
-
- CLI sends only `action.type`.
|
|
889
|
-
- It does not send `action.payload`.
|
|
890
|
-
- Actions that require payload may return `ok: false` in `data.result`.
|
|
891
|
-
|
|
892
|
-
Example command:
|
|
893
|
-
|
|
894
|
-
```powershell
|
|
895
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts act --json --session demo click target:managed-local:profile:managed-local:default:1
|
|
896
|
-
```
|
|
897
|
-
|
|
898
|
-
Example JSON output:
|
|
899
|
-
|
|
900
|
-
```json
|
|
901
|
-
{
|
|
902
|
-
"ok": true,
|
|
903
|
-
"command": "act",
|
|
904
|
-
"data": {
|
|
905
|
-
"driver": "managed-local",
|
|
906
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
907
|
-
"result": {
|
|
908
|
-
"actionType": "click",
|
|
909
|
-
"profile": "profile:managed-local:default",
|
|
910
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
911
|
-
"targetKnown": true,
|
|
912
|
-
"ok": false,
|
|
913
|
-
"executed": false,
|
|
914
|
-
"error": "action.payload.selector is required for click action."
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
```
|
|
919
|
-
|
|
920
|
-
## `upload-arm`
|
|
921
|
-
|
|
922
|
-
Purpose: Arm upload files for target.
|
|
923
|
-
|
|
924
|
-
Syntax:
|
|
925
|
-
|
|
926
|
-
```text
|
|
927
|
-
upload-arm <targetId> <file1> [file2 ...] [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
928
|
-
```
|
|
929
|
-
|
|
930
|
-
Example command:
|
|
931
|
-
|
|
932
|
-
```powershell
|
|
933
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts upload-arm --json --session demo target:managed-local:profile:managed-local:default:1 .\fixtures\a.txt .\fixtures\b.txt
|
|
934
|
-
```
|
|
935
|
-
|
|
936
|
-
Example JSON output:
|
|
937
|
-
|
|
938
|
-
```json
|
|
939
|
-
{
|
|
940
|
-
"ok": true,
|
|
941
|
-
"command": "upload-arm",
|
|
942
|
-
"data": {
|
|
943
|
-
"driver": "managed-local",
|
|
944
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
945
|
-
"armed": true,
|
|
946
|
-
"files": [
|
|
947
|
-
"C:\\repo\\fixtures\\a.txt",
|
|
948
|
-
"C:\\repo\\fixtures\\b.txt"
|
|
949
|
-
]
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
```
|
|
953
|
-
|
|
954
|
-
## `dialog-arm`
|
|
955
|
-
|
|
956
|
-
Purpose: Arm dialog handling for target.
|
|
957
|
-
|
|
958
|
-
Syntax:
|
|
959
|
-
|
|
960
|
-
```text
|
|
961
|
-
dialog-arm <targetId> [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
962
|
-
```
|
|
963
|
-
|
|
964
|
-
Example command:
|
|
965
|
-
|
|
966
|
-
```powershell
|
|
967
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts dialog-arm --json --session demo target:managed-local:profile:managed-local:default:1
|
|
968
|
-
```
|
|
969
|
-
|
|
970
|
-
Example JSON output:
|
|
971
|
-
|
|
972
|
-
```json
|
|
973
|
-
{
|
|
974
|
-
"ok": true,
|
|
975
|
-
"command": "dialog-arm",
|
|
976
|
-
"data": {
|
|
977
|
-
"driver": "managed-local",
|
|
978
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
979
|
-
"armed": true
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
```
|
|
983
|
-
|
|
984
|
-
## `download-trigger`
|
|
985
|
-
|
|
986
|
-
Purpose: Trigger download flow for target.
|
|
987
|
-
|
|
988
|
-
Syntax:
|
|
989
|
-
|
|
990
|
-
```text
|
|
991
|
-
download-trigger <targetId> [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
992
|
-
```
|
|
993
|
-
|
|
994
|
-
Example command:
|
|
995
|
-
|
|
996
|
-
```powershell
|
|
997
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts download-trigger --json --session demo target:managed-local:profile:managed-local:default:1
|
|
998
|
-
```
|
|
999
|
-
|
|
1000
|
-
Example JSON output:
|
|
1001
|
-
|
|
1002
|
-
```json
|
|
1003
|
-
{
|
|
1004
|
-
"ok": true,
|
|
1005
|
-
"command": "download-trigger",
|
|
1006
|
-
"data": {
|
|
1007
|
-
"driver": "managed-local",
|
|
1008
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
1009
|
-
"triggered": true
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
```
|
|
1013
|
-
|
|
1014
|
-
## `download-wait`
|
|
1015
|
-
|
|
1016
|
-
Purpose: Wait for and return download metadata.
|
|
1017
|
-
|
|
1018
|
-
Syntax:
|
|
1019
|
-
|
|
1020
|
-
```text
|
|
1021
|
-
download-wait <targetId> [path] [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
1022
|
-
```
|
|
1023
|
-
|
|
1024
|
-
Example command:
|
|
1025
|
-
|
|
1026
|
-
```powershell
|
|
1027
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts download-wait --json --session demo target:managed-local:profile:managed-local:default:1 .\downloads\artifact.bin
|
|
1028
|
-
```
|
|
1029
|
-
|
|
1030
|
-
Example JSON output:
|
|
1031
|
-
|
|
1032
|
-
```json
|
|
1033
|
-
{
|
|
1034
|
-
"ok": true,
|
|
1035
|
-
"command": "download-wait",
|
|
1036
|
-
"data": {
|
|
1037
|
-
"driver": "managed-local",
|
|
1038
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
1039
|
-
"download": {
|
|
1040
|
-
"path": "C:\\repo\\downloads\\artifact.bin",
|
|
1041
|
-
"profile": "profile:managed-local:default",
|
|
1042
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
1043
|
-
"uploadFiles": [
|
|
1044
|
-
"C:\\repo\\fixtures\\a.txt"
|
|
1045
|
-
],
|
|
1046
|
-
"dialogArmedCount": 1,
|
|
1047
|
-
"triggerCount": 1
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
```
|
|
1052
|
-
|
|
1053
|
-
## `console-list`
|
|
1054
|
-
|
|
1055
|
-
Purpose: Read console telemetry entries for target.
|
|
1056
|
-
|
|
1057
|
-
Syntax:
|
|
1058
|
-
|
|
1059
|
-
```text
|
|
1060
|
-
console-list <targetId> [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
1061
|
-
```
|
|
1062
|
-
|
|
1063
|
-
Example command:
|
|
1064
|
-
|
|
1065
|
-
```powershell
|
|
1066
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts console-list --json --session demo target:managed-local:profile:managed-local:default:1
|
|
1067
|
-
```
|
|
1068
|
-
|
|
1069
|
-
Example JSON output:
|
|
1070
|
-
|
|
1071
|
-
```json
|
|
1072
|
-
{
|
|
1073
|
-
"ok": true,
|
|
1074
|
-
"command": "console-list",
|
|
1075
|
-
"data": {
|
|
1076
|
-
"driver": "managed-local",
|
|
1077
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
1078
|
-
"entries": [
|
|
1079
|
-
{
|
|
1080
|
-
"type": "warning",
|
|
1081
|
-
"text": "Example warning",
|
|
1082
|
-
"timestamp": "2026-02-23T10:00:00.000Z",
|
|
1083
|
-
"location": {
|
|
1084
|
-
"url": "https://example.com",
|
|
1085
|
-
"lineNumber": 12,
|
|
1086
|
-
"columnNumber": 4
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
]
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
```
|
|
1093
|
-
|
|
1094
|
-
## `response-body`
|
|
1095
|
-
|
|
1096
|
-
Purpose: Read captured network response body for a request ID.
|
|
1097
|
-
|
|
1098
|
-
Syntax:
|
|
1099
|
-
|
|
1100
|
-
```text
|
|
1101
|
-
response-body <targetId> <requestId> [--json] [--session <id>] [--profile <driverKey>] [--token <authToken>]
|
|
1102
|
-
```
|
|
1103
|
-
|
|
1104
|
-
Example command:
|
|
1105
|
-
|
|
1106
|
-
```powershell
|
|
1107
|
-
pnpm exec tsx .\apps\browserctl\src\main.ts response-body --json --session demo target:managed-local:profile:managed-local:default:1 request:managed-local:profile%3Amanaged-local%3Adefault:target%3Amanaged-local%3Aprofile%3Amanaged-local%3Adefault%3A1:1
|
|
1108
|
-
```
|
|
1109
|
-
|
|
1110
|
-
Example JSON output:
|
|
1111
|
-
|
|
1112
|
-
```json
|
|
1113
|
-
{
|
|
1114
|
-
"ok": true,
|
|
1115
|
-
"command": "response-body",
|
|
1116
|
-
"data": {
|
|
1117
|
-
"driver": "managed-local",
|
|
1118
|
-
"targetId": "target:managed-local:profile:managed-local:default:1",
|
|
1119
|
-
"requestId": "request:managed-local:profile%3Amanaged-local%3Adefault:target%3Amanaged-local%3Aprofile%3Amanaged-local%3Adefault%3A1:1",
|
|
1120
|
-
"body": "{\"ok\":true}",
|
|
1121
|
-
"encoding": "utf8"
|
|
1122
|
-
}
|
|
1123
|
-
}
|
|
1124
|
-
```
|
|
1125
|
-
|
|
1126
|
-
## Relay Troubleshooting
|
|
1127
|
-
|
|
1128
|
-
When relay profile operations fail with connection errors (`ECONNREFUSED`, timeout, `ENOTFOUND`, etc.), CLI appends guidance:
|
|
1129
|
-
|
|
1130
|
-
1. For extension relay, set `BROWSERD_CHROME_RELAY_MODE=extension`.
|
|
1131
|
-
2. Load unpacked extension from `extensions/chrome-relay` and keep it active.
|
|
1132
|
-
3. Ensure extension popup Bridge URL matches `BROWSERD_CHROME_RELAY_URL` (`ws://<host>:<port>/bridge`).
|
|
1133
|
-
4. For CDP relay, verify browser remote debugging endpoint is running.
|
|
1134
|
-
5. Verify `BROWSERD_CHROME_RELAY_URL`.
|
|
1135
|
-
|
|
1136
|
-
## Notes on Accuracy of Example Payloads
|
|
1137
|
-
|
|
1138
|
-
- The JSON examples are representative and aligned with current command/result shapes.
|
|
1139
|
-
- Runtime values vary by active driver, browser state, and environment policy.
|
|
1140
|
-
- `snapshot.html`, `screenshot.imageBase64`, and telemetry fields can be large and are abbreviated in examples.
|
|
1141
|
-
|
|
1142
|
-
## Smoke Flow
|
|
1143
|
-
|
|
1144
|
-
Run smoke flow:
|
|
1145
|
-
|
|
1146
|
-
```powershell
|
|
1147
|
-
pwsh -NoLogo -NoProfile -File .\scripts\smoke.ps1
|
|
37
|
+
browserctl daemon-stop --json
|
|
38
|
+
browserctl daemon-start --json
|
|
39
|
+
browserctl status --json --session relay --profile chrome-relay
|
|
1148
40
|
```
|
|
1149
41
|
|
|
1150
|
-
|
|
42
|
+
## Full Docs
|
|
1151
43
|
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
44
|
+
- [Install Guide (English)](INSTALL.md)
|
|
45
|
+
- [安装指南(中文)](INSTALL-CN.md)
|
|
46
|
+
- [User Guide (English)](docs/user-guide.md)
|
|
47
|
+
- [使用指南(中文)](docs/user-guide-cn.md)
|
|
48
|
+
- [CLI Reference (English)](docs/cli-reference.md)
|
|
49
|
+
- [CLI 参考(中文)](docs/cli-reference-cn.md)
|
|
50
|
+
- [Maintainer Onboarding (English)](docs/maintainer-onboarding.md)
|
|
51
|
+
- [维护者上手文档(中文)](docs/maintainer-onboarding-cn.md)
|