@browserbridge/bbx 1.7.8 → 1.9.0
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/PRIVACY.md +57 -12
- package/README.md +19 -8
- package/SECURITY.md +12 -0
- package/package.json +15 -6
- package/packages/agent-client/src/cli-args.js +59 -0
- package/packages/agent-client/src/cli-batch.js +121 -58
- package/packages/agent-client/src/cli-output.js +8 -1
- package/packages/agent-client/src/cli.js +272 -70
- package/packages/agent-client/src/client.js +296 -8
- package/packages/agent-client/src/command-registry.js +64 -55
- package/packages/agent-client/src/config.js +195 -0
- package/packages/agent-client/src/content-extract.js +198 -0
- package/packages/agent-client/src/npm-self-update.js +305 -0
- package/packages/agent-client/src/remotes.js +4 -2
- package/packages/agent-client/src/runtime.js +864 -39
- package/packages/agent-client/src/types.ts +169 -6
- package/packages/mcp-server/src/guidance.js +1 -1
- package/packages/mcp-server/src/handlers-capture.js +69 -6
- package/packages/mcp-server/src/handlers-dom.js +61 -4
- package/packages/mcp-server/src/handlers-navigation.js +2 -1
- package/packages/mcp-server/src/handlers-page.js +211 -54
- package/packages/mcp-server/src/handlers-utils.js +101 -10
- package/packages/mcp-server/src/handlers.js +14 -7
- package/packages/mcp-server/src/server.js +176 -11
- package/packages/native-host/src/artifact-store.js +353 -0
- package/packages/native-host/src/config.js +9 -1
- package/packages/native-host/src/daemon-logger.js +3 -1
- package/packages/native-host/src/daemon.js +701 -33
- package/packages/native-host/src/native-host.js +28 -3
- package/packages/protocol/src/capability-values.js +2 -0
- package/packages/protocol/src/defaults.js +31 -0
- package/packages/protocol/src/errors.js +102 -6
- package/packages/protocol/src/incidental-sanitizer.js +197 -0
- package/packages/protocol/src/index.js +2 -0
- package/packages/protocol/src/protocol.js +612 -6
- package/packages/protocol/src/recovery-telemetry.js +302 -0
- package/packages/protocol/src/registry.js +206 -38
- package/packages/protocol/src/summary.js +203 -30
- package/packages/protocol/src/types.ts +721 -2
- package/skills/browser-bridge/SKILL.md +54 -19
- package/skills/browser-bridge/references/interaction.md +55 -11
- package/skills/browser-bridge/references/patch-workflow.md +2 -0
- package/skills/browser-bridge/references/protocol.md +265 -86
- package/skills/browser-bridge/references/token-efficiency.md +29 -13
|
@@ -27,75 +27,89 @@ The table below includes the legacy capability bucket for each method so agents
|
|
|
27
27
|
- `-` means the method is global/system-scoped and was never gated by a former capability bucket.
|
|
28
28
|
- Capability names are descriptive coverage labels only. Browser Bridge access is window-scoped now; there are no capability-scoped sessions.
|
|
29
29
|
|
|
30
|
-
## All Methods (
|
|
31
|
-
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
|
|
|
76
|
-
|
|
|
77
|
-
|
|
|
78
|
-
|
|
|
79
|
-
|
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
|
|
|
98
|
-
|
|
|
30
|
+
## All Methods (75)
|
|
31
|
+
|
|
32
|
+
| Method | Tab? | CDP? | Group | Capability | Notes |
|
|
33
|
+
| ---------------------------------- | ---- | ---------- | ----------- | -------------------- | ------------------------------------------------------------------------------------------ |
|
|
34
|
+
| `access.request` | No | - | system | `intent?` | Request window access with bounded operation context in the extension UI |
|
|
35
|
+
| `tabs.list` | No | - | tabs | `-` | Discover tabs in the enabled window |
|
|
36
|
+
| `tabs.create` | No | - | tabs | `tabs.manage` | Open a new tab; optional `url` and `active` |
|
|
37
|
+
| `tabs.close` | No | - | tabs | `tabs.manage` | Close a tab by `tabId` |
|
|
38
|
+
| `tabs.activate` | No | - | tabs | `tabs.manage` | Bring a tab to the foreground in the enabled window |
|
|
39
|
+
| `skill.get_runtime_context` | No | - | system | `-` | Live budget presets and method groups |
|
|
40
|
+
| `setup.get_status` | No | - | system | `-` | Global MCP config and CLI skill install status |
|
|
41
|
+
| `setup.install` | No | - | system | `-` | Install or uninstall MCP/skill integration targets |
|
|
42
|
+
| `health.ping` | No | - | system | `-` | Connectivity, routing, capture, and daemon/routed-extension recovery summaries |
|
|
43
|
+
| `log.tail` | No | - | system | `-` | Recent redacted bridge logs |
|
|
44
|
+
| `daemon.metrics` | No | - | system | `-` | Daemon health, performance, and process-local recovery metrics |
|
|
45
|
+
| `page.get_state` | Yes | - | page | `page.read` | URL, readiness, focus, viewport, and observable dialog status |
|
|
46
|
+
| `page.evaluate` | Yes | CDP | page | `page.evaluate` | JS expression in page context; last resort |
|
|
47
|
+
| `page.get_console` | Yes | - | page | `page.read` | Buffered console messages; filter by `level`, `limit` |
|
|
48
|
+
| `page.handle_dialog` | Yes | CDP | page | `navigation.control` | Inspect or explicitly accept/dismiss the currently observable dialog |
|
|
49
|
+
| `page.wait_for_load_state` | Yes | - | wait | `page.read` | Wait for truthful tab `complete` state and/or a URL condition |
|
|
50
|
+
| `page.get_storage` | Yes | - | page | `page.read` | Bounded storage key/presence metadata; optional `keys`; never values |
|
|
51
|
+
| `sensitive.read` | Yes | - | sensitive | `sensitive.read` | One exact local/session storage key; sequential, non-retryable, whole-or-error |
|
|
52
|
+
| `page.get_text` | Yes | - | page | `page.read` | Full page text; `textBudget` limits size |
|
|
53
|
+
| `page.extract_content` | Yes | - | page | `page.read` | Node-processed semantic text/Markdown with bounded HTML snapshots and optional settlement |
|
|
54
|
+
| `page.get_network` | Yes | Conditional | page | `network.read` | Fetch/XHR by default; explicit CDP all-resource capture lifecycle |
|
|
55
|
+
| `network.export_har` | Yes | No* | page | `network.read` | Read an already armed CDP capture as bounded metadata-only HAR 1.2 |
|
|
56
|
+
| `network.intercept.add` | Yes | CDP | page | `network.intercept` | Add interception rule; action fulfill/continue/block |
|
|
57
|
+
| `network.intercept.remove` | Yes | CDP | page | `network.intercept` | Remove rule by `ruleId` |
|
|
58
|
+
| `network.intercept.list` | Yes | CDP | page | `network.intercept` | List active rules (rules drop on debugger detach) |
|
|
59
|
+
| `network.intercept.clear` | Yes | CDP | page | `network.intercept` | Remove all rules and release interception |
|
|
60
|
+
| `navigation.navigate` | Yes | - | navigate | `navigation.control` | Go to URL; `waitForLoad` default true |
|
|
61
|
+
| `navigation.reload` | Yes | - | navigate | `navigation.control` | Reload; `waitForLoad` default true |
|
|
62
|
+
| `navigation.go_back` | Yes | - | navigate | `navigation.control` | History back |
|
|
63
|
+
| `navigation.go_forward` | Yes | - | navigate | `navigation.control` | History forward |
|
|
64
|
+
| `dom.query` | Yes | - | inspect | `dom.read` | Query subtree with budget constraints |
|
|
65
|
+
| `dom.baseline.create` | Yes | - | inspect | `dom.read` | Retain a short-lived memory-only semantic snapshot; sequential only |
|
|
66
|
+
| `dom.baseline.compare` | Yes | - | inspect | `dom.read` | Compare current semantic DOM to an explicit retained baseline; batch-safe |
|
|
67
|
+
| `dom.baseline.describe` | Yes | - | inspect | `dom.read` | Return exact baseline scope, options, expiry, and snapshot statistics; batch-safe |
|
|
68
|
+
| `dom.baseline.release` | Yes | - | inspect | `dom.read` | Idempotently release retained baseline state; sequential only |
|
|
69
|
+
| `dom.describe` | Yes | - | inspect | `dom.read` | Single element details via `elementRef` |
|
|
70
|
+
| `dom.get_text` | Yes | - | inspect | `dom.read` | Text content with `textBudget` |
|
|
71
|
+
| `dom.get_attributes` | Yes | - | inspect | `dom.read` | Targeted attribute read |
|
|
72
|
+
| `dom.wait_for` | Yes | - | wait | `dom.read` | Wait for DOM condition; MutationObserver and polling |
|
|
73
|
+
| `dom.find_by_text` | Yes | - | inspect | `dom.read` | Find by visible text; returns `{nodes, count}` |
|
|
74
|
+
| `dom.find_by_role` | Yes | - | inspect | `dom.read` | Find by ARIA role; optional `name` filter |
|
|
75
|
+
| `dom.get_html` | Yes | - | inspect | `dom.read` | `innerHTML`/`outerHTML`; `maxLength` truncation |
|
|
76
|
+
| `dom.get_accessibility_tree` | Yes | CDP | inspect | `dom.read` | Full or uniquely selector-scoped AX tree with compact/interactive filters |
|
|
77
|
+
| `layout.get_box_model` | Yes | - | inspect | `layout.read` | Element geometry |
|
|
78
|
+
| `layout.hit_test` | Yes | - | inspect | `layout.read` | Topmost element at viewport point |
|
|
79
|
+
| `styles.get_computed` | Yes | - | inspect | `styles.read` | Requested properties; omission returns display/position/width/height/color |
|
|
80
|
+
| `styles.get_matched_rules` | Yes | - | inspect | `styles.read` | Element ref, class list, and inline style only; not stylesheet cascade data |
|
|
81
|
+
| `viewport.scroll` | Yes | - | navigate | `viewport.control` | Window or element scroll |
|
|
82
|
+
| `viewport.resize` | Yes | CDP | navigate | `viewport.control` | Set viewport via device emulation; `reset: true` |
|
|
83
|
+
| `input.click` | Yes | Optional | interact | `automation.input` | Actionability-aware DOM or CDP click |
|
|
84
|
+
| `input.focus` | Yes | - | interact | `automation.input` | Actionability-aware DOM focus |
|
|
85
|
+
| `input.type` | Yes | Optional | interact | `automation.input` | DOM key sequence or CDP text insertion |
|
|
86
|
+
| `input.fill` | Yes | Optional | interact | `automation.input` | DOM fill strategy or CDP clear/insert; see `mode` versus `executionMode` |
|
|
87
|
+
| `input.press_key` | Yes | - | interact | `automation.input` | DOM key event |
|
|
88
|
+
| `input.set_checked` | Yes | - | interact | `automation.input` | Checkbox/radio toggle |
|
|
89
|
+
| `input.select_option` | Yes | - | interact | `automation.input` | Native select by value/label/index |
|
|
90
|
+
| `input.hover` | Yes | Optional | interact | `automation.input` | DOM hover events or native CDP pointer move |
|
|
91
|
+
| `input.drag` | Yes | Optional | interact | `automation.input` | DOM drag events or native interpolated pointer drag |
|
|
92
|
+
| `input.scroll_into_view` | Yes | - | interact | `automation.input` | Explicitly scroll target into view before inspect/capture |
|
|
93
|
+
| `screenshot.capture_element` | Yes | CDP | capture | `screenshot.partial` | Complete element screenshot with explicit completeness metadata |
|
|
94
|
+
| `screenshot.capture_region` | Yes | CDP | capture | `screenshot.partial` | Cropped viewport region in PNG, JPEG, or WebP |
|
|
95
|
+
| `screenshot.capture_full_page` | Yes | CDP | capture | `screenshot.partial` | Full document screenshot; fails coherently above Chrome capture limits |
|
|
96
|
+
| `artifact.read` | No | daemon | raw | None | Read one bounded chunk from an owner-scoped artifact handle |
|
|
97
|
+
| `artifact.delete` | No | daemon | raw | None | Delete an owner-scoped artifact handle |
|
|
98
|
+
| `patch.apply_styles` | Yes | - | patch | `patch.styles` | Reversible CSS patch; `verify` returns computed result |
|
|
99
|
+
| `patch.apply_dom` | Yes | - | patch | `patch.dom` | Reversible text, attribute, add/remove/toggle-class mutation; `verify` returns result |
|
|
100
|
+
| `patch.list` | Yes | - | patch | `patch.dom` | Active rollback records in the current document |
|
|
101
|
+
| `patch.rollback` | Yes | - | patch | `patch.dom` | Revert one active patch |
|
|
102
|
+
| `patch.commit_session_baseline` | Yes | - | patch | `patch.dom` | Keep current mutations and discard their rollback history |
|
|
103
|
+
| `performance.get_metrics` | Yes | CDP | performance | `performance.read` | Chrome performance counters |
|
|
104
|
+
| `cdp.get_document` | Yes | CDP | cdp | `cdp.dom_snapshot` | DevTools document tree |
|
|
105
|
+
| `cdp.get_dom_snapshot` | Yes | CDP | cdp | `cdp.dom_snapshot` | DevTools DOM snapshot; optional bounded `computedStyles` property names |
|
|
106
|
+
| `cdp.get_box_model` | Yes | CDP | cdp | `cdp.box_model` | DevTools-backed element geometry |
|
|
107
|
+
| `cdp.get_computed_styles_for_node` | Yes | CDP | cdp | `cdp.styles` | DevTools-backed computed styles |
|
|
108
|
+
| `cdp.dispatch_key_event` | Yes | CDP | cdp | `cdp.input` | DevTools keyDown/keyUp without foreground focus |
|
|
109
|
+
|
|
110
|
+
`No*` means HAR export issues no CDP command itself, but its source capture must
|
|
111
|
+
already be armed and continues to hold debugger ownership until explicitly
|
|
112
|
+
stopped.
|
|
99
113
|
|
|
100
114
|
## CLI
|
|
101
115
|
|
|
@@ -106,7 +120,7 @@ bbx call --tab 123 <method> '{...}' # explicit tab target inside enabled
|
|
|
106
120
|
bbx batch '[{"method":"...","params":{}}]' # parallel calls
|
|
107
121
|
```
|
|
108
122
|
|
|
109
|
-
**Convenience shortcuts:** `access-request`, `dom-query`, `describe`, `text`, `styles`, `box`, `click`, `focus`, `type`, `press-key`, `cdp-press-key`, `patch-style`, `patch-text`, `patches`, `rollback`, `screenshot`, `eval`, `console`, `wait`, `find`, `find-role`, `html`, `hover`, `navigate`, `storage`, `tab-create`, `tab-close`, `page-text`, `network`, `a11y-tree`, `perf`, `scroll`, `resize`, `reload`, `back`, `forward`, `attrs`, `matched-rules`
|
|
123
|
+
**Convenience shortcuts:** `access-request`, `dom-query`, `describe`, `text`, `styles`, `box`, `click`, `focus`, `type`, `press-key`, `cdp-press-key`, `patch-style`, `patch-text`, `patches`, `rollback`, `screenshot`, `har`, `eval`, `console`, `wait`, `find`, `find-role`, `html`, `hover`, `navigate`, `storage`, `tab-create`, `tab-close`, `page-text`, `network`, `a11y-tree`, `perf`, `scroll`, `resize`, `reload`, `back`, `forward`, `attrs`, `matched-rules`
|
|
110
124
|
|
|
111
125
|
Newer bridge methods such as `input.scroll_into_view` and `screenshot.capture_full_page` currently use the raw path: `bbx call <method> '{...}'`.
|
|
112
126
|
|
|
@@ -114,13 +128,16 @@ Newer bridge methods such as `input.scroll_into_view` and `screenshot.capture_fu
|
|
|
114
128
|
|
|
115
129
|
### access.request
|
|
116
130
|
|
|
117
|
-
Request Browser Bridge access for the focused browser window. Surfaces an Enable prompt in the extension popup or side panel
|
|
131
|
+
Request Browser Bridge access for the focused browser window. Surfaces an Enable prompt in the extension popup or side panel with the reported source, bounded operation intent, tab title, and sanitized origin. Does not require existing access.
|
|
118
132
|
|
|
119
133
|
```bash
|
|
120
134
|
bbx access-request
|
|
121
|
-
bbx
|
|
135
|
+
bbx access-request inspect
|
|
136
|
+
bbx call access.request '{"intent":"capture"}'
|
|
122
137
|
```
|
|
123
138
|
|
|
139
|
+
`intent` is optional and defaults to `general`. Accepted values are `inspect`, `interact`, `capture`, `navigate`, `debugger`, and `general`; arbitrary prompt text is rejected. The source and intent are reported context, while the title and origin are resolved and sanitized by the extension.
|
|
140
|
+
|
|
124
141
|
If a tab-bound call returns `ACCESS_DENIED`, it also surfaces the Enable prompt automatically - so explicit `access.request` is optional but useful for proactive setup.
|
|
125
142
|
|
|
126
143
|
If access is already pending for a window, do not call `access.request` again. Ask the user to click `Enable` for the requested window and wait for confirmation before continuing.
|
|
@@ -151,17 +168,32 @@ bbx call page.get_console '{"level":"error","limit":20,"clear":true}'
|
|
|
151
168
|
|
|
152
169
|
Responses include `dropped` when older buffered entries were discarded on noisy pages.
|
|
153
170
|
|
|
171
|
+
### page.handle_dialog
|
|
172
|
+
|
|
173
|
+
Inspecting is read-only; accepting or dismissing must be explicit. `promptText` is valid only with `action: "accept"`. An optional `expectedDialogId` checks that the current observation still matches immediately before dispatch, but Chrome's `Page.handleJavaScriptDialog` command cannot atomically bind to that identifier. A successful mutation therefore reports `commandDispatched: true` and `atomicDialogBinding: false`; it does not prove which application follow-up occurred.
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
bbx call page.handle_dialog '{"action":"inspect"}'
|
|
177
|
+
bbx call page.handle_dialog '{"action":"accept","expectedDialogId":"00000000-0000-4000-8000-000000000000:1","promptText":"value"}' # replace with inspected dialogId
|
|
178
|
+
bbx call page.handle_dialog '{"action":"dismiss","expectedDialogId":"00000000-0000-4000-8000-000000000000:1"}' # replace with inspected dialogId
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`DIALOG_NOT_OPEN` means no current dialog was observable. `DIALOG_ACTION_CONFLICT` means the observation changed before or around dispatch; inspect again and never automatically repeat the mutating action. Dialog messages and prompt defaults are bounded and excluded from persisted action logs.
|
|
182
|
+
|
|
154
183
|
### page.wait_for_load_state
|
|
155
184
|
|
|
156
|
-
|
|
185
|
+
Wait for truthful Chrome tab `complete` status, a URL condition, or both. URL waits check the current URL first, then observe tab updates plus `pushState`, `replaceState`, `popstate`, and hash changes. Results include `finalUrl`, `urlMatch`, `elapsedMs`, and `observedNavigationKind`; this method does not call DOMContentLoaded behavior `networkidle`.
|
|
157
186
|
|
|
158
187
|
```bash
|
|
159
188
|
bbx call page.wait_for_load_state '{"timeoutMs":10000}'
|
|
189
|
+
bbx call page.wait_for_load_state '{"url":"/dashboard","urlMatch":"contains","waitForLoad":false}'
|
|
160
190
|
```
|
|
161
191
|
|
|
192
|
+
`urlMatch: "regex"` accepts at most 256 characters and only a bounded linear subset: literals, escapes, anchors, dots, and character classes. Grouping, alternation, quantifiers, and backreferences are rejected.
|
|
193
|
+
|
|
162
194
|
### page.get_storage
|
|
163
195
|
|
|
164
|
-
Read `localStorage` or `sessionStorage`
|
|
196
|
+
Read bounded `localStorage` or `sessionStorage` key/presence metadata. Values are never returned.
|
|
165
197
|
|
|
166
198
|
```bash
|
|
167
199
|
bbx storage # all localStorage
|
|
@@ -169,6 +201,17 @@ bbx storage session token,user # specific sessionStorage keys
|
|
|
169
201
|
bbx call page.get_storage '{"type":"session","keys":["token"]}'
|
|
170
202
|
```
|
|
171
203
|
|
|
204
|
+
### sensitive.read
|
|
205
|
+
|
|
206
|
+
Deliberately read one exact Web Storage value after discovering its key. The
|
|
207
|
+
value bypasses token truncation, is never batched or automatically retried, and
|
|
208
|
+
is returned whole or rejected whole. Every attempt creates a Sensitive access
|
|
209
|
+
Recent Activity warning without retaining the key or value.
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
bbx call sensitive.read '{"source":"session_storage","key":"token"}'
|
|
213
|
+
```
|
|
214
|
+
|
|
172
215
|
### dom.query
|
|
173
216
|
|
|
174
217
|
Run a bounded breadth-first DOM summary rooted at a selector or existing ref. Returns `{nodes, revision, truncated, registrySize}` and may also include `_registryPruned: true` when the element registry evicted older refs.
|
|
@@ -180,6 +223,23 @@ bbx call dom.query '{"selector":"main","maxNodes":10,"attributeAllowlist":["clas
|
|
|
180
223
|
|
|
181
224
|
If `_registryPruned` is true, refresh previously cached refs before reusing them.
|
|
182
225
|
|
|
226
|
+
### dom.baseline.create, compare, describe, and release
|
|
227
|
+
|
|
228
|
+
Use an explicit semantic baseline when an action must be verified against a known before-state without returning two full DOM snapshots. Baselines retain bounded structured summaries in extension memory only; they do not add attributes, scripts, or markers to the application page.
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
bbx call dom.baseline.create '{"selector":"main","maxNodes":100,"maxDepth":8,"textBudget":160,"attributeAllowlist":["data-testid"]}'
|
|
232
|
+
bbx call dom.baseline.compare '{"baselineId":"baseline_...","maxChanges":50}'
|
|
233
|
+
bbx call dom.baseline.describe '{"baselineId":"baseline_..."}'
|
|
234
|
+
bbx call dom.baseline.release '{"baselineId":"baseline_..."}'
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
The create result is a destination-bound opaque handle plus creation/expiry timestamps, window/tab/frame/document/selector/representation scope, effective capture options, and snapshot counts. It never returns retained nodes. `compare` reports exact `added`, `removed`, `changed`, `moved`, `unchanged`, and total counts while bounding returned examples with `maxChanges`; ambiguity and omitted evidence are explicit. `describe` returns the exact descriptor. `release` is idempotent.
|
|
238
|
+
|
|
239
|
+
Creation and release are stateful and excluded from read-only batch. Compare and describe do not mutate the baseline or extend its five-minute expiry, so they are batch-safe. Navigation, document replacement, tab/window cleanup, access disable, destination disconnect, expiry, quota eviction, or explicit release makes the handle unavailable. Navigation and document replacement return `DOM_BASELINE_INVALIDATED`; missing, expired, released, or evicted handles return `DOM_BASELINE_NOT_FOUND`.
|
|
240
|
+
|
|
241
|
+
Capture defaults to stable semantic fields and safe attributes. Form values and event-handler attributes are never retained, URL credentials/fragments/query values are removed, opaque URL payloads are redacted, and caller-provided attribute names are canonicalized and bounded. Use a narrow selector for dialogs, forms, lists, or application regions.
|
|
242
|
+
|
|
183
243
|
### dom.wait_for
|
|
184
244
|
|
|
185
245
|
Wait for a DOM condition using MutationObserver + 250 ms polling fallback. A text-only wait searches all elements. `hidden` succeeds when no matching visible element remains, including when it is absent. Returns `{found, elementRef, duration}`.
|
|
@@ -220,9 +280,25 @@ bbx html el_abc123
|
|
|
220
280
|
bbx call dom.get_html '{"elementRef":"el_abc123","outer":true,"maxLength":2000}'
|
|
221
281
|
```
|
|
222
282
|
|
|
283
|
+
### styles.get_computed and styles.get_matched_rules
|
|
284
|
+
|
|
285
|
+
When `properties` is omitted, `styles.get_computed` returns exactly `display`, `position`, `width`, `height`, and `color`. Pass an explicit list for any other properties. `styles.get_matched_rules` currently returns only `{elementRef, classes, inlineStyle}`; it does not inspect stylesheet rules, specificity, or cascade order.
|
|
286
|
+
|
|
287
|
+
### Actionable input targets
|
|
288
|
+
|
|
289
|
+
Input calls preserve an explicit `elementRef`. For selectors, the first actionable match wins; if it is not actionable, Browser Bridge evaluates at most 25 matches and chooses only a uniquely better candidate. It scrolls the selected target if needed and rechecks visibility, disabled/inert state, rendered bounds, and pointer hit testing before dispatch. Failures use `ELEMENT_NOT_FOUND`, `ELEMENT_NOT_ACTIONABLE`, `ELEMENT_OBSCURED`, or `ELEMENT_AMBIGUOUS` with bounded details.
|
|
290
|
+
|
|
291
|
+
Successful targeted click, focus, type, fill, press-key, checked-state, option-selection, hover, and drag results include `resolution` (`strategy`, candidate/evaluated counts, scrolling, hit test, and recovery fields) and `execution` (`requestedMode`, `actualMode`, `fallbackReason`, `debuggerUsed`, and coordinates). `cdp.dispatch_key_event`/MCP `cdp_press_key` and `input.scroll_into_view` use separate response contracts. `executionMode` is the dispatch path and accepts only `dom` or `cdp`, defaulting to `dom` for compatibility. CDP is supported only by click, hover, drag, type, and fill; unsupported combinations return `INPUT_UNSUPPORTED` instead of falling back silently.
|
|
292
|
+
|
|
293
|
+
`input.fill.mode` is separate: `auto`, `setter`, and `keystrokes` choose the DOM fill strategy. `mode: "auto"` may fall back from the setter to keystrokes and reports the used `mode`; it does not select CDP. With `executionMode: "cdp"`, fill uses native clear/text dispatch and reports `mode: "cdp"`.
|
|
294
|
+
|
|
295
|
+
Stale refs still fail by default. `recoverStale: true` permits one strict recovery attempt only within the current document and unchanged URL, based on a strong unique descriptor such as test ID, ID, role/name, label, or href plus semantic context. Recovery evaluates at most 100 same-tag candidates. If more exist, it returns `ELEMENT_AMBIGUOUS` with `reason: "scan_incomplete"` because uniqueness is not provable, even when the evaluated prefix contains one match. Ambiguous, weak, or changed-URL recovery also fails. Recovered results identify old/new refs and matched fields.
|
|
296
|
+
|
|
297
|
+
Browser input dispatch is not a generic application-state assertion. Follow each action with the cheapest relevant `dom.wait_for`, `page.wait_for_load_state`, `dom.describe`, or other structured read.
|
|
298
|
+
|
|
223
299
|
### input.hover
|
|
224
300
|
|
|
225
|
-
Trigger
|
|
301
|
+
Trigger hover with DOM events by default, or a native pointer move with `executionMode: "cdp"`. Optional `duration` waits before returning; it does not promise a persistent hover after the call.
|
|
226
302
|
|
|
227
303
|
```bash
|
|
228
304
|
bbx hover el_abc123
|
|
@@ -231,7 +307,7 @@ bbx call input.hover '{"target":{"elementRef":"el_abc123"},"duration":1000}'
|
|
|
231
307
|
|
|
232
308
|
### input.drag
|
|
233
309
|
|
|
234
|
-
|
|
310
|
+
The DOM path dispatches `mousedown → dragstart → drag → dragenter → dragover → drop → dragend → mouseup`. The CDP path performs a bounded interpolated native pointer drag and guarantees a release attempt after failure. Both accept source, destination, and optional destination offsets.
|
|
235
311
|
|
|
236
312
|
```bash
|
|
237
313
|
bbx call input.drag '{"source":{"elementRef":"el_src"},"destination":{"elementRef":"el_dst"}}'
|
|
@@ -285,11 +361,22 @@ bbx page-text 8000
|
|
|
285
361
|
bbx call page.get_text '{"textBudget":2000}'
|
|
286
362
|
```
|
|
287
363
|
|
|
364
|
+
### page.extract_content
|
|
365
|
+
|
|
366
|
+
Extract article-like or documentation content without returning source HTML to the agent. The Node client reads a bounded HTML snapshot through the existing bridge, runs pinned Mozilla Readability locally, then falls back to the largest `article`, `main`, or `[role="main"]` subtree and finally sanitized body text. Scripts, styles, hidden regions, and form controls are excluded before extraction.
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
bbx call page.extract_content '{"format":"text"}'
|
|
370
|
+
bbx call page.extract_content '{"format":"markdown","selector":"main","textBudget":8000}'
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Parameters: `format` (`text` default or `markdown`), optional `selector`, `includeMetadata` (default `true`), `consistency` (`best_effort` default or `settled`), `textBudget` (default 8000), and `settleTimeoutMs` (default 2000, maximum 10000). Settled extraction requires two identical bounded snapshots at least 100 ms apart; it does not claim network idle or a frozen page. Results report source, original length, truncation, omitted characters, bounded metadata, and settlement timeout state. An oversized snapshot fails coherently with guidance to narrow `selector` rather than returning partial semantic content.
|
|
374
|
+
|
|
288
375
|
### page.get_network
|
|
289
376
|
|
|
290
377
|
The fetch/XHR interceptor is installed on the first call. Before reproducing a network issue, call `page.get_network` with `clear: true`, trigger the action, then read the buffer again without `clear` so the relevant request is not missed or erased.
|
|
291
378
|
|
|
292
|
-
|
|
379
|
+
The default `source: "fetch-xhr"` path auto-installs MAIN-world instrumentation on first call and returns completed entries in capture order (oldest to newest among the retained/limited entries). Prime with `clear: true`, reproduce, then read without clearing.
|
|
293
380
|
|
|
294
381
|
```bash
|
|
295
382
|
bbx network
|
|
@@ -297,20 +384,73 @@ bbx network 50
|
|
|
297
384
|
bbx call page.get_network '{"limit":20,"clear":true}'
|
|
298
385
|
```
|
|
299
386
|
|
|
300
|
-
Each entry
|
|
387
|
+
Each fetch/XHR entry is `{method, url, status, duration, type, ts, size}`. Responses also include `count`, `total`, `filteredTotal`, `source`, `captureState: "instrumented"`, `dropped`, and limit truncation metadata.
|
|
388
|
+
|
|
389
|
+
For optional all-resource metadata, use the explicit debugger-backed CDP lifecycle. Start clears prior state and holds debugger ownership until stop (or the 10-minute safety expiry); read does not retroactively capture events:
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
bbx call page.get_network '{"source":"cdp","capture":"start"}'
|
|
393
|
+
# reproduce the activity
|
|
394
|
+
bbx call page.get_network '{"source":"cdp","capture":"read","limit":50}'
|
|
395
|
+
bbx call page.get_network '{"source":"cdp","capture":"stop"}'
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
`capture: "clear"` clears completed/in-flight entries while leaving an armed capture running. CDP entries contain `requestId`, redacted `url`, `method`, `resourceType`, `status`, `mimeType`, `protocol`, cache flags, bounded redirect summary, `failureReason`, `duration`, and `timestamp`. Result lifecycle fields include `armed`, `armedDuringCapture`, `captureState`, `ownershipHeld`, `startedAt`, `inflight`, `dropped`, and `abandoned`.
|
|
399
|
+
|
|
400
|
+
CDP URL output removes credentials and fragments, replaces every query value with `[redacted]`, and summarizes data/blob URLs. Request/response bodies, cookies, authorization values, and complete headers are not returned. This mode captures all observed resource classes and is materially more expensive and intrusive than fetch/XHR instrumentation; always stop it when finished.
|
|
401
|
+
|
|
402
|
+
### network.export_har
|
|
403
|
+
|
|
404
|
+
Export metadata-only HAR 1.2 from a CDP capture that is currently armed. The
|
|
405
|
+
method is a read and does not attach, start, stop, clear, or otherwise change the
|
|
406
|
+
capture. Use this exact sequence:
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
bbx call page.get_network '{"source":"cdp","capture":"start"}'
|
|
410
|
+
# reproduce the activity
|
|
411
|
+
bbx har --limit 100 --url-pattern /api/ reproduction.har
|
|
412
|
+
bbx call page.get_network '{"source":"cdp","capture":"stop"}'
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
Parameters are `limit` (1-200, default 50), `urlPattern` (at most 2048
|
|
416
|
+
characters; substring match on sanitized URLs), and `delivery` (`auto` default,
|
|
417
|
+
`inline`, or `artifact`). Count and inline byte/token limits retain the newest
|
|
418
|
+
matching entries and remove complete oldest entries; fields are not truncated to
|
|
419
|
+
fit. `auto` uses an artifact above 256 KiB, while explicit `artifact` always
|
|
420
|
+
returns one. Artifacts last five minutes, are readable/deletable only by their
|
|
421
|
+
requesting client, use private daemon files, and expose no browser-host path.
|
|
422
|
+
|
|
423
|
+
HAR URLs preserve schemes, hosts, paths, and query names, remove credentials and
|
|
424
|
+
fragments, and replace query values with `[redacted]`. `queryString`, headers,
|
|
425
|
+
and cookies are empty; bodies and authorization data are absent. Unsupported
|
|
426
|
+
header/body/content sizes and send/wait/receive timing phases are `-1`.
|
|
427
|
+
`entry.time` is observed total duration. Redirects are separate observed entries;
|
|
428
|
+
`_bbx` reports resource type, failure reason, and memory/disk/prefetch cache and
|
|
429
|
+
service-worker observations. Result counters expose completed-entry loss as
|
|
430
|
+
`dropped`, discarded unfinished activity as `abandoned`, and requests still
|
|
431
|
+
unfinished and omitted from the HAR as `inflight`.
|
|
432
|
+
|
|
433
|
+
MCP uses `browser_page` with `action: "har"`. `bbx har` accepts the same limit,
|
|
434
|
+
URL pattern, and delivery choices, then uses one client connection to download
|
|
435
|
+
owner-scoped chunks, verify byte length/SHA-256 and HAR shape, delete the
|
|
436
|
+
artifact, and atomically write the output on the CLI host.
|
|
301
437
|
|
|
302
438
|
### dom.get_accessibility_tree
|
|
303
439
|
|
|
304
|
-
Retrieve
|
|
440
|
+
Retrieve a depth-limited accessibility tree via CDP. Full reads use `Accessibility.getFullAXTree`; an optional unique `selector` resolves through CDP DOM methods and uses `Accessibility.getPartialAXTree`, retaining only the selected subtree and required ancestor chain. Missing and ambiguous selectors return typed errors instead of selecting an arbitrary candidate. Nodes include `role`, `name`, `description`, `value`, state fields, `interactive`, `semanticInteractive`, `focusable`, `focusableAndEnabled`, `ignored`, and `childIds`. `interactive` is semantic/focusability metadata, not current pointer actionability.
|
|
305
441
|
|
|
306
442
|
This is debugger-backed. Prefer `dom.find_by_role`, `dom.find_by_text`, and targeted `dom.query`/`dom.describe` first.
|
|
307
443
|
|
|
308
444
|
```bash
|
|
309
445
|
bbx a11y-tree
|
|
310
446
|
bbx a11y-tree 50 3
|
|
311
|
-
bbx call dom.get_accessibility_tree '{"maxNodes":100,"maxDepth":5}'
|
|
447
|
+
bbx call dom.get_accessibility_tree '{"maxNodes":100,"maxDepth":5,"compact":true}'
|
|
448
|
+
bbx call dom.get_accessibility_tree '{"maxNodes":100,"maxDepth":6,"interactiveOnly":true}'
|
|
449
|
+
bbx call dom.get_accessibility_tree '{"selector":"[role=dialog]","maxNodes":50,"compact":true}'
|
|
312
450
|
```
|
|
313
451
|
|
|
452
|
+
Filtering occurs before `maxNodes`. Compact mode drops ignored, decorative, and empty nodes while reconnecting retained descendants; interactive-only keeps non-ignored semantic interactive roles. Because CDP applies `maxDepth` before Browser Bridge receives the tree, every result truthfully reports `truncated: true`, `partialTopology: true`, depth metadata, missing-child counts, and a continuation hint. No AX node is written into the page DOM or converted directly into an actionable element ref; use role/name with `dom.find_by_role` before input.
|
|
453
|
+
|
|
314
454
|
### viewport.resize
|
|
315
455
|
|
|
316
456
|
Set the browser viewport to specific dimensions using CDP device emulation. Pass `reset: true` to clear the override.
|
|
@@ -325,7 +465,9 @@ bbx call viewport.resize '{"reset":true}'
|
|
|
325
465
|
|
|
326
466
|
### performance.get_metrics
|
|
327
467
|
|
|
328
|
-
Read Chrome
|
|
468
|
+
Read a browser-maintained point sample of raw Chrome counters via CDP `Performance.getMetrics`. The additive result is `{metrics, measurement}`, where `measurement` identifies the CDP source, `timeTicks` domain, sample timestamp, point-sample observation, and `webVitals: "not_measured"`. Metric names, availability, and units are defined by Chrome/CDP and can vary by browser version.
|
|
469
|
+
|
|
470
|
+
BBX does not establish a navigation observation window and does not measure LCP, CLS, or INP. Do not interpret the returned counters as Web Vitals or page-load measurements.
|
|
329
471
|
|
|
330
472
|
Debugger-backed. Use after lighter reads fail to explain a performance symptom.
|
|
331
473
|
|
|
@@ -334,16 +476,42 @@ bbx perf
|
|
|
334
476
|
bbx call performance.get_metrics
|
|
335
477
|
```
|
|
336
478
|
|
|
337
|
-
### screenshot.
|
|
479
|
+
### screenshot.capture_\*
|
|
338
480
|
|
|
339
|
-
Capture a full
|
|
481
|
+
Capture a complete element, a tight viewport region, or a full document. All methods accept `format: "png" | "jpeg" | "webp"`, `scale` from 0.1 to 4, and `delivery: "inline" | "artifact" | "auto"`; JPEG and WebP additionally accept integer `quality` from 0 to 100. Results include matching `format`, `mimeType`, encoded `byteLength`, actual `dimensions`, `complete`, `clipped`, and `delivery` metadata.
|
|
340
482
|
|
|
341
|
-
|
|
483
|
+
Element capture uses full page-coordinate bounds with CDP capture beyond the viewport. If Browser Bridge cannot guarantee the entire element, or if an element/page exceeds Chrome capture limits, it returns a typed failure rather than a viewport-clipped image labeled complete. Use full-page capture only when element or tight region captures cannot express the issue.
|
|
484
|
+
|
|
485
|
+
Raw calls default to inline base64 for compatibility. `auto` keeps small captures inline and returns a short-lived, daemon-owned opaque artifact handle for large captures; explicit `inline` preserves MCP image content when model vision is needed. Artifact handles expose no browser-host path and support owner-scoped bounded `artifact.read` and `artifact.delete` calls. Prefer `bbx screenshot [--format png|jpeg|webp] [--quality 0-100] <ref> [outPath]` when one element is enough; the CLI downloads, verifies, deletes, and atomically writes the artifact on the CLI host.
|
|
486
|
+
|
|
487
|
+
Artifact handles expire after five minutes and can be read or deleted only by
|
|
488
|
+
the requesting client. The daemon creates a private artifact directory and
|
|
489
|
+
owner-only files on POSIX hosts, removes artifacts on expiry/teardown, and never
|
|
490
|
+
returns its browser-host filesystem path.
|
|
342
491
|
|
|
343
492
|
```bash
|
|
344
|
-
bbx call screenshot.capture_full_page '{}'
|
|
493
|
+
bbx call screenshot.capture_full_page '{"format":"jpeg","quality":75,"delivery":"auto","scale":0.75}'
|
|
345
494
|
```
|
|
346
495
|
|
|
496
|
+
## Recovery Telemetry
|
|
497
|
+
|
|
498
|
+
Recovery telemetry is process-local and uses fixed five-second buckets over a
|
|
499
|
+
five-minute window. Three failures for the same hidden group within 60 seconds
|
|
500
|
+
set `activeLoop` for that category. Public summaries always use only these fixed
|
|
501
|
+
categories: `automatic_mcp_retry`, `stale_ref_recovery`, `debugger_reattach`,
|
|
502
|
+
`content_script_reinjection`, `native_host_reconnect`, and `request_outcome`.
|
|
503
|
+
They contain attempts/successes/failures/pending, bounded rates, saturation,
|
|
504
|
+
last-event timestamps, and loop flags, but no page data, URL, selector, payload,
|
|
505
|
+
error text, method name, tab identifier, or internal group name.
|
|
506
|
+
|
|
507
|
+
`health.ping` includes daemon and available routed-extension summaries;
|
|
508
|
+
`daemon.metrics` includes daemon scope. `bbx doctor` combines both, marks active
|
|
509
|
+
loops as issues, and emits fixed guidance. Stop repeated attempts: re-query stale
|
|
510
|
+
refs, close competing debuggers, reload extension/page after reinjection
|
|
511
|
+
failures, restart for native-host reconnect failures, stop automatic MCP retry
|
|
512
|
+
loops, or inspect the first typed error for request failures. Extension data
|
|
513
|
+
resets with the service worker and daemon data resets with the daemon.
|
|
514
|
+
|
|
347
515
|
## Request Envelope
|
|
348
516
|
|
|
349
517
|
```json
|
|
@@ -363,11 +531,22 @@ bbx call screenshot.capture_full_page '{}'
|
|
|
363
531
|
| `ACCESS_DENIED` | Turn on Browser Bridge for the target window | `retry: false` |
|
|
364
532
|
| `TAB_MISMATCH` | Explicit `tabId` is missing, closed, or outside enabled window | `retry: false`, use `tabs.list` |
|
|
365
533
|
| `ELEMENT_STALE` | Re-query DOM for fresh `elementRef` | `retry: false`, use `dom.query` |
|
|
534
|
+
| `ELEMENT_AMBIGUOUS` | Narrow selector or use an explicit ref | `retry: false`, use `dom.query` |
|
|
535
|
+
| `ELEMENT_NOT_ACTIONABLE` | Inspect hidden/disabled/inert/zero-size target | `retry: false`, use `dom.describe` |
|
|
536
|
+
| `ELEMENT_OBSCURED` | Inspect the element blocking the target point | `retry: false`, use `layout.hit_test` |
|
|
537
|
+
| `ELEMENT_NOT_FOUND` | Correct or narrow the selector | `retry: false`, use `dom.query` |
|
|
538
|
+
| `DOM_BASELINE_NOT_FOUND` | Handle expired, released, evicted, or does not exist | `retry: false`, create a new baseline |
|
|
539
|
+
| `DOM_BASELINE_INVALIDATED` | Navigation, document, or access scope changed | `retry: false`, create a new baseline |
|
|
540
|
+
| `DOM_BASELINE_QUOTA_EXCEEDED` | Snapshot or retained-state quota was exceeded | `retry: false`, narrow selector or release |
|
|
541
|
+
| `INPUT_UNSUPPORTED` | Use DOM execution or a CDP-supported input method | `retry: false` |
|
|
542
|
+
| `INPUT_INVALID_TARGET` | Choose a control compatible with the input | `retry: false`, use `dom.describe` |
|
|
543
|
+
| `INPUT_FOCUS_CHANGED` | Inspect focus handlers; do not replay native text blindly | `retry: false`, use `dom.describe` |
|
|
544
|
+
| `DIALOG_NOT_OPEN` | Trigger or inspect the current dialog | `retry: false` |
|
|
545
|
+
| `DIALOG_ACTION_CONFLICT` | Inspect again; never auto-repeat a dialog mutation | `retry: false` |
|
|
366
546
|
| `CONTENT_SCRIPT_UNAVAILABLE` | Page is restricted (chrome://, extensions, etc.) | `retry: false` |
|
|
367
547
|
| `NATIVE_HOST_UNAVAILABLE` | Check daemon: `bbx status` | `retry: false` |
|
|
368
548
|
| `EXTENSION_DISCONNECTED` | Extension not connected to daemon | `retry: true` after 3 s, check `health.ping` |
|
|
369
549
|
| `TIMEOUT` | Wait/evaluate exceeded `timeoutMs` | `retry: true` after 1 s |
|
|
370
|
-
| `RATE_LIMITED` | Too many requests | `retry: true` after 2 s |
|
|
371
550
|
|
|
372
551
|
Timeout on content-script request → use narrower `dom.query` or CDP fallback.
|
|
373
552
|
Timeout on navigation → increase `timeoutMs`, set `waitForLoad:false`, or check `page.get_state`.
|