@flrande/browserctl 0.1.0 → 0.2.0-dev.9.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/README.md CHANGED
@@ -2,1154 +2,65 @@
2
2
 
3
3
  English | [简体中文](README-CN.md)
4
4
 
5
- Universal browser control CLI + daemon with MCP-style tool routing.
5
+ Fastest path: control your current Edge/Chrome through the relay extension.
6
6
 
7
- ## What This CLI Does
8
-
9
- `browserctl` is a TCP client for `browserd`.
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
7
+ ## Extension Quick Start (Recommended)
21
8
 
22
9
  Prerequisites:
23
10
 
24
11
  - Node.js 22+
25
- - pnpm
12
+ - npm or pnpm
26
13
  - PowerShell 7 (`pwsh`)
14
+ - Edge or Chrome
27
15
 
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:
16
+ 1. Install the released package:
71
17
 
72
18
  ```powershell
73
- $version = node -p "require('./package.json').version"
74
- git tag "v$version"
75
- git push origin "v$version"
19
+ npm install --global @flrande/browserctl
20
+ # or: pnpm add --global @flrande/browserctl
76
21
  ```
77
22
 
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:
23
+ 2. Start daemon in extension relay mode:
113
24
 
114
25
  ```powershell
115
26
  $env:BROWSERD_DEFAULT_DRIVER = "chrome-relay"
116
27
  $env:BROWSERD_CHROME_RELAY_MODE = "extension"
117
28
  $env:BROWSERD_CHROME_RELAY_URL = "http://127.0.0.1:9223"
118
29
  $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:
147
-
148
- ```text
149
- dom-query <targetId> <selector>
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
- }
30
+ browserctl daemon-stop --json
31
+ browserctl daemon-start --json
257
32
  ```
258
33
 
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.
34
+ 3. Load extension:
335
35
 
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
342
- ```
343
-
344
- `remote-cdp` notes:
345
-
346
- - Uses `BROWSERD_REMOTE_CDP_URL` (default `http://127.0.0.1:9222/devtools/browser/default`).
347
- - Connects directly over CDP to the configured URL.
348
-
349
- Example:
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
- ```
356
-
357
- ## Driver Modes and How To Use Them
358
-
359
- Driver comparison:
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)
375
-
376
- ```powershell
377
- $env:BROWSERD_DEFAULT_DRIVER = "managed"
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)
383
-
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
- $env:BROWSERD_DEFAULT_DRIVER = "chrome-relay"
407
- $env:BROWSERD_CHROME_RELAY_MODE = "extension"
408
- $env:BROWSERD_CHROME_RELAY_URL = "http://127.0.0.1:9223"
409
- $env:BROWSERD_CHROME_RELAY_EXTENSION_TOKEN = "relay-secret"
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`.
36
+ 1. Open `edge://extensions` or `chrome://extensions`.
418
37
  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.
38
+ 3. Load unpacked extension from `extensions/chrome-relay`.
39
+ 4. In extension popup, set:
40
+ - `Bridge URL`: `ws://127.0.0.1:9223/bridge`
41
+ - `Token`: `relay-secret`
42
+ 5. Click `Save` then `Reconnect`.
421
43
 
422
- ### Use `remote-cdp`
44
+ 4. Verify and run first command:
423
45
 
424
46
  ```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
47
+ browserctl status --json --session relay --profile chrome-relay
48
+ browserctl tab-open --json --session relay --profile chrome-relay https://example.com
429
49
  ```
430
50
 
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:
51
+ ## 30-Second Troubleshooting
472
52
 
473
53
  ```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:
588
-
589
- ```powershell
590
- pnpm exec tsx .\apps\browserctl\src\main.ts status --json --session demo --profile managed-local
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
- }
54
+ browserctl daemon-status --json
55
+ Invoke-WebRequest -UseBasicParsing -Uri "http://127.0.0.1:9223/browserctl/relay/status" -TimeoutSec 3
1124
56
  ```
1125
57
 
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`.
58
+ If `connected` is `false`, reopen extension popup and click `Reconnect`.
1135
59
 
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
1148
- ```
60
+ ## Full Docs
1149
61
 
1150
- Smoke flow behavior:
62
+ - [Full User Guide (English)](docs/user-guide.md)
63
+ - [完整使用文档(中文)](docs/user-guide-cn.md)
64
+ - [Chrome Relay Extension README (English)](extensions/chrome-relay/README.md)
65
+ - [Chrome Relay 扩展文档(中文)](extensions/chrome-relay/README-CN.md)
1151
66
 
1152
- 1. Starts `browserd`.
1153
- 2. Runs `browserctl status --json`.
1154
- 3. Waits until daemon is reachable via TCP.
1155
- 4. Fails if response contains an error or `ok` is `false`.