@divebell/agent-browser 0.33.1-divebell.1 → 0.33.2-divebell.2
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 +53 -3
- package/bin/agent-browser-darwin-arm64 +0 -0
- package/bin/agent-browser-darwin-x64 +0 -0
- package/bin/agent-browser-linux-arm64 +0 -0
- package/bin/agent-browser-linux-musl-arm64 +0 -0
- package/bin/agent-browser-linux-musl-x64 +0 -0
- package/bin/agent-browser-linux-x64 +0 -0
- package/bin/agent-browser-win32-x64.exe +0 -0
- package/package.json +1 -1
- package/skill-data/core/SKILL.md +1 -0
- package/skill-data/core/references/authentication.md +8 -0
- package/skill-data/core/references/commands.md +12 -1
- package/skill-data/core/references/session-management.md +1 -1
- package/skill-data/core/references/streaming.md +104 -0
- package/skill-data/core/references/trust-boundaries.md +1 -1
package/README.md
CHANGED
|
@@ -400,7 +400,7 @@ agent-browser errors # View page errors (uncaught JavaScript ex
|
|
|
400
400
|
agent-browser errors --clear # Clear errors
|
|
401
401
|
agent-browser highlight <sel> # Highlight element
|
|
402
402
|
agent-browser inspect # Open Chrome DevTools for the active page
|
|
403
|
-
agent-browser state save <path>
|
|
403
|
+
agent-browser state save <path> [--include-origin <url>]... # Save auth state
|
|
404
404
|
agent-browser state load <path> # Load auth state
|
|
405
405
|
agent-browser state list # List saved state files
|
|
406
406
|
agent-browser state show <file> # Show state summary
|
|
@@ -647,6 +647,14 @@ agent-browser --session "$SESSION" --restore --state ./my-auth.json open https:/
|
|
|
647
647
|
# From now on, --session "$SESSION" --restore auto-saves/restores this state
|
|
648
648
|
```
|
|
649
649
|
|
|
650
|
+
State files preserve HTTP-only and partitioned cookie metadata. Cookies are collected for the whole browser session. To also collect localStorage from an authentication origin that the active agent-browser session did not visit, repeat `--include-origin`:
|
|
651
|
+
|
|
652
|
+
```bash
|
|
653
|
+
agent-browser --auto-connect state save ./my-auth.json \
|
|
654
|
+
--include-origin https://sso.example.com \
|
|
655
|
+
--include-origin https://accounts.example.net
|
|
656
|
+
```
|
|
657
|
+
|
|
650
658
|
> **Security notes:**
|
|
651
659
|
> - `--remote-debugging-port` exposes full browser control on localhost. Any local process can connect. Only use on trusted machines and close Chrome when done.
|
|
652
660
|
> - State files contain session tokens in plaintext. Add them to `.gitignore` and delete when no longer needed. For encryption at rest, set `AGENT_BROWSER_ENCRYPTION_KEY` (see [State Encryption](#state-encryption)).
|
|
@@ -1043,7 +1051,7 @@ Create an `agent-browser.json` file to set persistent defaults instead of repeat
|
|
|
1043
1051
|
|
|
1044
1052
|
**Locations (lowest to highest priority):**
|
|
1045
1053
|
|
|
1046
|
-
1. `~/.agent-browser/config.json`: user-level defaults
|
|
1054
|
+
1. `~/.agent-browser/config.json`: user-level defaults (or `$AGENT_BROWSER_HOME/config.json`)
|
|
1047
1055
|
2. `./agent-browser.json`: project-level overrides (in working directory)
|
|
1048
1056
|
3. `AGENT_BROWSER_*` environment variables override config file values
|
|
1049
1057
|
4. CLI flags override everything
|
|
@@ -1075,6 +1083,15 @@ agent-browser --config ./ci-config.json open example.com
|
|
|
1075
1083
|
AGENT_BROWSER_CONFIG=./ci-config.json agent-browser open example.com
|
|
1076
1084
|
```
|
|
1077
1085
|
|
|
1086
|
+
For sandboxed agents whose home directory is read-only, set
|
|
1087
|
+
`AGENT_BROWSER_HOME` to a writable directory such as `/tmp/agent-browser`.
|
|
1088
|
+
This relocates agent-browser-owned configuration, session state, browser
|
|
1089
|
+
downloads, temporary artifacts, and daemon files without changing `HOME` for
|
|
1090
|
+
other tools. When no override is set and `~/.agent-browser` is not writable,
|
|
1091
|
+
agent-browser automatically uses a short per-user directory under `/tmp` on
|
|
1092
|
+
Unix. Sandboxes that prohibit local sockets or browser processes entirely
|
|
1093
|
+
still require a browser running outside the sandbox and a reachable CDP URL.
|
|
1094
|
+
|
|
1078
1095
|
All options from the table above can be set in the config file using camelCase keys (e.g., `--executable-path` becomes `"executablePath"`, `--proxy-bypass` becomes `"proxyBypass"`). Plugins are configured with the `"plugins"` array shown above. Unknown keys are ignored for forward compatibility.
|
|
1079
1096
|
|
|
1080
1097
|
A [JSON Schema](agent-browser.schema.json) is available for IDE autocomplete and validation. Add a `$schema` key to your config file to enable it:
|
|
@@ -1448,6 +1465,24 @@ To bind to a specific port, set `AGENT_BROWSER_STREAM_PORT`:
|
|
|
1448
1465
|
AGENT_BROWSER_STREAM_PORT=9223 agent-browser open example.com
|
|
1449
1466
|
```
|
|
1450
1467
|
|
|
1468
|
+
Frame encoding is daemon-wide:
|
|
1469
|
+
|
|
1470
|
+
| Variable | Default | Description |
|
|
1471
|
+
|---|---|---|
|
|
1472
|
+
| `AGENT_BROWSER_STREAM_QUALITY` | `80` | JPEG quality, 0 to 100 |
|
|
1473
|
+
| `AGENT_BROWSER_STREAM_MAX_WIDTH` | the viewport | Caps frame width in pixels |
|
|
1474
|
+
| `AGENT_BROWSER_STREAM_MAX_HEIGHT` | the viewport | Caps frame height in pixels |
|
|
1475
|
+
|
|
1476
|
+
Width and height cap the encoded frame and leave the page size alone, so a portrait or HiDPI viewport keeps its resolution unless you cap it. The live stream requests jpeg. An explicit `screencast_start` reconfigures the same screencast, so a client can see the format change mid-stream. On a busy page at 1280x720, quality 80 costs about 54 KB per frame, quality 20 about 25 KB, and quality 20 at 640x360 about 9 KB.
|
|
1477
|
+
|
|
1478
|
+
```bash
|
|
1479
|
+
# Cheaper frames for a constrained link
|
|
1480
|
+
AGENT_BROWSER_STREAM_QUALITY=20 \
|
|
1481
|
+
AGENT_BROWSER_STREAM_MAX_WIDTH=640 \
|
|
1482
|
+
AGENT_BROWSER_STREAM_MAX_HEIGHT=360 \
|
|
1483
|
+
agent-browser open example.com
|
|
1484
|
+
```
|
|
1485
|
+
|
|
1451
1486
|
You can also manage streaming at runtime with `stream enable`, `stream disable`, and `stream status`:
|
|
1452
1487
|
|
|
1453
1488
|
```bash
|
|
@@ -1466,6 +1501,7 @@ Connect to `ws://localhost:9223` to receive frames and send input:
|
|
|
1466
1501
|
```json
|
|
1467
1502
|
{
|
|
1468
1503
|
"type": "frame",
|
|
1504
|
+
"seq": 41,
|
|
1469
1505
|
"data": "<base64-encoded-jpeg>",
|
|
1470
1506
|
"metadata": {
|
|
1471
1507
|
"deviceWidth": 1280,
|
|
@@ -1473,11 +1509,14 @@ Connect to `ws://localhost:9223` to receive frames and send input:
|
|
|
1473
1509
|
"pageScaleFactor": 1,
|
|
1474
1510
|
"offsetTop": 0,
|
|
1475
1511
|
"scrollOffsetX": 0,
|
|
1476
|
-
"scrollOffsetY": 0
|
|
1512
|
+
"scrollOffsetY": 0,
|
|
1513
|
+
"timestamp": 1785038682238
|
|
1477
1514
|
}
|
|
1478
1515
|
}
|
|
1479
1516
|
```
|
|
1480
1517
|
|
|
1518
|
+
`seq` is a monotonic frame id, echoed back in an `ack` message under ack pacing. `metadata.timestamp` is the capture time in epoch milliseconds, so a client can tell how old a frame is by the time it draws it.
|
|
1519
|
+
|
|
1481
1520
|
**Send mouse events:**
|
|
1482
1521
|
|
|
1483
1522
|
```json
|
|
@@ -1512,6 +1551,17 @@ Connect to `ws://localhost:9223` to receive frames and send input:
|
|
|
1512
1551
|
}
|
|
1513
1552
|
```
|
|
1514
1553
|
|
|
1554
|
+
**Cap the frame rate (per client):**
|
|
1555
|
+
|
|
1556
|
+
```json
|
|
1557
|
+
{
|
|
1558
|
+
"type": "config",
|
|
1559
|
+
"maxFps": 10
|
|
1560
|
+
}
|
|
1561
|
+
```
|
|
1562
|
+
|
|
1563
|
+
Frames are delivered latest-first: the server picks the newest frame at send time, so frames produced while an earlier one is still being written are skipped rather than queued. `maxFps` (1 to 120, `0` = uncapped) limits delivery for that client only. A client that sends `{"type":"config","pacing":"ack"}` receives one frame at a time and acknowledges it with `{"type":"ack","seq":N}`, so nothing stale reaches the socket even if that client stalls; in the default push pacing, frames already handed to the transport are still delivered in order. Both settings can also be declared on the URL (`ws://127.0.0.1:<port>/?pacing=ack&maxFps=10`), which is the only way to cover the connection's opening frame. Input events are read on a dedicated task per connection, so clicks and keystrokes dispatch immediately even while frames are mid-write to a slow client. They are sent to the browser without waiting for its reply, so a click stays responsive behind a burst of mouse moves, and ordering is preserved.
|
|
1564
|
+
|
|
1515
1565
|
## Architecture
|
|
1516
1566
|
|
|
1517
1567
|
agent-browser uses a client-daemon architecture:
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/skill-data/core/SKILL.md
CHANGED
|
@@ -513,6 +513,7 @@ That pulls in:
|
|
|
513
513
|
- `references/session-management.md` — persistence, multi-session workflows
|
|
514
514
|
- `references/profiling.md` — Chrome DevTools tracing and profiling
|
|
515
515
|
- `references/video-recording.md` — video capture options
|
|
516
|
+
- `references/streaming.md` covers live viewport streaming, remote input, per-client frame rate, and the encoding vars that set bandwidth cost
|
|
516
517
|
- `references/proxy-support.md` — proxy configuration
|
|
517
518
|
- `references/webgpu.md` — screenshots/video of WebGPU pages (three.js, Babylon.js), Linux/CI setup
|
|
518
519
|
- `templates/*` — starter shell scripts for auth, capture, form automation
|
|
@@ -48,6 +48,14 @@ Log in to your target site(s) in this Chrome window as you normally would.
|
|
|
48
48
|
agent-browser --auto-connect state save ./my-auth.json
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
State files retain HTTP-only and partitioned cookie metadata. Cookies are collected for the whole browser session. If an SSO or authentication origin stores additional localStorage and was not visited by the active session, include it explicitly. Repeat the flag for multiple origins:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
agent-browser --auto-connect state save ./my-auth.json \
|
|
55
|
+
--include-origin https://sso.example.com \
|
|
56
|
+
--include-origin https://accounts.example.net
|
|
57
|
+
```
|
|
58
|
+
|
|
51
59
|
**Step 3: Reuse in automation**
|
|
52
60
|
|
|
53
61
|
```bash
|
|
@@ -324,10 +324,21 @@ Other capabilities use the same protocol:
|
|
|
324
324
|
## State Management
|
|
325
325
|
|
|
326
326
|
```bash
|
|
327
|
-
agent-browser state save auth.json
|
|
327
|
+
agent-browser state save auth.json [--include-origin <url>]... # Save cookies and storage
|
|
328
328
|
agent-browser state load auth.json # Restore saved state
|
|
329
329
|
```
|
|
330
330
|
|
|
331
|
+
## Live Streaming
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
agent-browser stream status --json # Enabled state, port, client count
|
|
335
|
+
agent-browser stream enable # Start the WebSocket stream server
|
|
336
|
+
agent-browser stream enable --port 9223
|
|
337
|
+
agent-browser stream disable # Stop it
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Clients connect to `ws://127.0.0.1:<port>` and receive `frame`, `status`, `tabs`, `url`, and `console` messages. They send `input_mouse`, `input_keyboard`, and `input_touch` to drive the page, `{"type":"config","maxFps":N}` (1 to 120, `0` = uncapped) to cap their own frame rate, and `{"type":"config","pacing":"ack"}` to receive one frame at a time, acknowledged with `{"type":"ack","seq":N}`. Both settings can be declared on the URL instead (`ws://127.0.0.1:<port>/?pacing=ack&maxFps=10`). See [streaming.md](streaming.md).
|
|
341
|
+
|
|
331
342
|
## MCP Server
|
|
332
343
|
|
|
333
344
|
```bash
|
|
@@ -73,7 +73,7 @@ agent-browser --session "$SESSION" session info --json
|
|
|
73
73
|
|
|
74
74
|
### Manual State Files
|
|
75
75
|
|
|
76
|
-
Use `state save`, `state load`, and `--state <path>` when you need an explicit portable JSON file. Do not make agents construct paths under `~/.agent-browser/sessions/`; prefer `--restore` for reusable agent sessions.
|
|
76
|
+
Use `state save`, `state load`, and `--state <path>` when you need an explicit portable JSON file. Repeat `state save --include-origin <url>` when a known SSO origin has localStorage that the active session did not visit. Do not make agents construct paths under `~/.agent-browser/sessions/`; prefer `--restore` for reusable agent sessions.
|
|
77
77
|
|
|
78
78
|
## Common Patterns
|
|
79
79
|
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Live Streaming
|
|
2
|
+
|
|
3
|
+
Stream a session's viewport over WebSocket and drive it with remote input. This is what a remote preview or embedded dashboard connects to: the browser runs wherever the daemon runs (a sandbox, a container, a CI box), and the client renders frames and sends clicks back.
|
|
4
|
+
|
|
5
|
+
**Related**: [commands.md](commands.md) for full command reference, [SKILL.md](../SKILL.md) for quick start.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
- [Enabling the stream](#enabling-the-stream)
|
|
10
|
+
- [Connecting](#connecting)
|
|
11
|
+
- [Messages from the server](#messages-from-the-server)
|
|
12
|
+
- [Messages from the client](#messages-from-the-client)
|
|
13
|
+
- [Frame rate and staleness](#frame-rate-and-staleness)
|
|
14
|
+
- [Limitations](#limitations)
|
|
15
|
+
|
|
16
|
+
## Enabling the stream
|
|
17
|
+
|
|
18
|
+
Streaming is always available; the server binds an OS-assigned localhost port unless told otherwise.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
agent-browser stream status --json # Report enabled state, port, client count
|
|
22
|
+
agent-browser stream enable # Create the server (--port to pin one)
|
|
23
|
+
agent-browser stream disable # Tear it down
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`AGENT_BROWSER_STREAM_PORT` pins the port for the whole daemon instead of passing `--port`.
|
|
27
|
+
|
|
28
|
+
Frame encoding is daemon-wide, read once at startup:
|
|
29
|
+
|
|
30
|
+
| Variable | Default | Notes |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| `AGENT_BROWSER_STREAM_QUALITY` | `80` | 0 to 100, clamped |
|
|
33
|
+
| `AGENT_BROWSER_STREAM_MAX_WIDTH` | the viewport | caps the frame, does not resize the page |
|
|
34
|
+
| `AGENT_BROWSER_STREAM_MAX_HEIGHT` | the viewport | same |
|
|
35
|
+
|
|
36
|
+
The live stream requests jpeg, since a `frame` message carries no format field. An explicit `screencast_start` reconfigures the same underlying screencast, so a client can still see the format change mid-stream; sniff the bytes rather than assuming. Measured on a busy page at 1280x720: quality 80 gives ~54 KB per frame, quality 20 gives ~25 KB, and quality 20 at 640x360 gives ~9 KB. An unusable value leaves the default.
|
|
37
|
+
|
|
38
|
+
Read the port from `stream status --json` rather than assuming one; the OS-assigned default changes per daemon.
|
|
39
|
+
|
|
40
|
+
## Connecting
|
|
41
|
+
|
|
42
|
+
Connect a WebSocket client to `ws://127.0.0.1:<port>`. Frame delivery starts automatically once a client attaches, so there is no subscribe message. Browser clients must load from `localhost`, `127.0.0.1`, `::1` or `file://`. Any other origin gets a 403 on the upgrade and needs a proxy.
|
|
43
|
+
|
|
44
|
+
## Messages from the server
|
|
45
|
+
|
|
46
|
+
Every message is JSON text with a `type` field.
|
|
47
|
+
|
|
48
|
+
- `frame`: a viewport image plus its metadata. Delivered latest-first (see below).
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"type": "frame",
|
|
53
|
+
"seq": 41,
|
|
54
|
+
"data": "<base64-encoded-jpeg>",
|
|
55
|
+
"metadata": {
|
|
56
|
+
"deviceWidth": 1280, "deviceHeight": 720, "pageScaleFactor": 1,
|
|
57
|
+
"offsetTop": 0, "scrollOffsetX": 0, "scrollOffsetY": 0,
|
|
58
|
+
"timestamp": 1785038682238
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`seq` is a monotonic frame id, echoed back under ack pacing and stable across browser relaunches. `metadata.timestamp` is the capture time in epoch milliseconds, so `Date.now() - timestamp` is the age of the frame being drawn. The other message types:
|
|
64
|
+
|
|
65
|
+
- `status`: connection state, screencasting flag, viewport size, engine, recording flag. Sent once on connect and again on change.
|
|
66
|
+
- `tabs`: the current tab list, sent on connect when tabs are known and on change.
|
|
67
|
+
- `url`, `console`: navigation and console events.
|
|
68
|
+
|
|
69
|
+
Status, tabs, url, and console travel on an ordered channel: they are delivered in order and are never replaced by a newer message the way frames are. They are not unconditionally durable. A client that falls far enough behind can lag out of that channel and lose messages it never saw, so treat console output as a live feed, not an audit log.
|
|
70
|
+
|
|
71
|
+
## Messages from the client
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{"type": "input_mouse", "eventType": "mousePressed", "x": 40, "y": 40, "button": "left", "clickCount": 1}
|
|
75
|
+
{"type": "input_keyboard", "eventType": "keyDown", "key": "a", "text": "a"}
|
|
76
|
+
{"type": "input_touch", "eventType": "touchStart", "touchPoints": []}
|
|
77
|
+
{"type": "config", "maxFps": 10}
|
|
78
|
+
{"type": "config", "pacing": "ack"}
|
|
79
|
+
{"type": "ack", "seq": 41}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Input dispatches to the browser on a task of its own, separate from frame delivery, so a click is not queued behind a frame write. Events are sent to the browser without waiting for its reply, so a click stays responsive behind a burst of mouse moves. Ordering is preserved: press never overtakes move. Mouse, keyboard, and touch input also reset the daemon idle timer, so an actively driven preview is not shut down by the idle timeout.
|
|
83
|
+
|
|
84
|
+
`config` sets a per-client frame cap: 1 to 120, or `0` for uncapped (the default). It takes effect immediately, including when it loosens the cap. Each client's cap is its own; other connected clients are unaffected. A value above 120 is clamped to 120; a negative or non-numeric value is ignored, leaving the current cap in place. Neither rejects the connection.
|
|
85
|
+
|
|
86
|
+
Both settings can also be declared on the URL, which is the only way to have them cover the connection's opening frame: `ws://127.0.0.1:<port>/?pacing=ack&maxFps=10`. A `config` message sent after connecting still wins.
|
|
87
|
+
|
|
88
|
+
## Frame rate and staleness
|
|
89
|
+
|
|
90
|
+
The server holds only the newest frame per client and reads it at send time. A frame produced while an earlier one is still being written is skipped, not queued, so the application never builds a backlog.
|
|
91
|
+
|
|
92
|
+
Push pacing (the default) stops there, and the transport underneath is still ordered: frames already accepted by the socket are delivered in order, so a client that stalls drains whatever the kernel buffered before the writer blocked.
|
|
93
|
+
|
|
94
|
+
Ack pacing closes that gap. Send `{"type":"config","pacing":"ack"}` and the server keeps at most one frame in flight, waiting for `{"type":"ack","seq":N}` before sending the next. Every frame carries a monotonic `seq`; echo the one you finished rendering. Frames produced while an ack is outstanding replace each other and never reach the socket, so a client that stalls for ten seconds and resumes gets the current page, not ten seconds of history.
|
|
95
|
+
|
|
96
|
+
Under ack pacing one frame is in flight at a time, so the rate is one frame per transfer plus one acknowledgement round trip. Both the link's bandwidth and its latency bound it, and a link whose bandwidth-delay product exceeds a single frame goes underused. Ack pacing bounds one hop. With a proxy in the path, forward the renderer's acks; acks generated on receipt leave frames queued on the far side. Acks are cumulative, so acknowledging a newer id covers any older one. A client that opts in and then stops acking simply stops receiving frames; status, tabs, url, and console keep flowing.
|
|
97
|
+
|
|
98
|
+
The two settings compose: `pacing` bounds how much is in flight, `maxFps` bounds the rate. A constrained preview usually wants both.
|
|
99
|
+
|
|
100
|
+
## Limitations
|
|
101
|
+
|
|
102
|
+
- Localhost only. Exposing the stream beyond the machine is the embedder's job (tunnel, proxy, or port forward), and the origin allowlist applies to browser clients.
|
|
103
|
+
- Frames are images, not a video codec. Bandwidth scales with viewport size and page activity; cap the rate for constrained links.
|
|
104
|
+
- In push pacing the server cannot tell a slow renderer from a fast one beyond transport backpressure. Use ack pacing when that distinction matters.
|
|
@@ -29,7 +29,7 @@ Session cookies, bearer tokens, API keys, OAuth codes, and any other credentials
|
|
|
29
29
|
|
|
30
30
|
- **If a user pastes a secret into chat, stop.** Ask them to save it to a file instead. Don't try to "be helpful" by using the pasted value — that teaches them an unsafe habit and the secret is already in the transcript.
|
|
31
31
|
|
|
32
|
-
- **Auth state files are secrets too.** `state save` / `state load` persists cookies
|
|
32
|
+
- **Auth state files are secrets too.** `state save` / `state load` persists cookies, cookie partition metadata, localStorage, and sessionStorage to a JSON file. Treat the path the same as a cookies file: don't paste its contents, don't share it with third-party services.
|
|
33
33
|
|
|
34
34
|
## Stay on the user's target
|
|
35
35
|
|