@browserbridge/bbx 1.7.7 → 1.8.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 +111 -0
- package/README.md +13 -5
- package/RESPONSIBLE_USE.md +16 -0
- package/SECURITY.md +52 -0
- package/package.json +12 -6
- package/packages/agent-client/src/cli-args.js +24 -0
- package/packages/agent-client/src/cli.js +46 -52
- package/packages/agent-client/src/client.js +140 -5
- package/packages/agent-client/src/command-registry.js +56 -53
- package/packages/agent-client/src/content-extract.js +198 -0
- package/packages/agent-client/src/remotes.js +1 -1
- package/packages/agent-client/src/runtime.js +768 -35
- package/packages/agent-client/src/types.ts +131 -6
- package/packages/mcp-server/src/guidance.js +1 -1
- package/packages/mcp-server/src/handlers-capture.js +41 -5
- package/packages/mcp-server/src/handlers-dom.js +8 -2
- package/packages/mcp-server/src/handlers-navigation.js +2 -1
- package/packages/mcp-server/src/handlers-page.js +41 -4
- package/packages/mcp-server/src/handlers-utils.js +67 -7
- package/packages/mcp-server/src/handlers.js +4 -4
- package/packages/mcp-server/src/server.js +102 -6
- package/packages/native-host/src/daemon.js +158 -6
- package/packages/native-host/src/native-host.js +3 -1
- package/packages/protocol/src/defaults.js +3 -0
- package/packages/protocol/src/errors.js +54 -1
- package/packages/protocol/src/protocol.js +297 -1
- package/packages/protocol/src/registry.js +66 -35
- package/packages/protocol/src/summary.js +87 -5
- package/packages/protocol/src/types.ts +234 -0
- package/skills/browser-bridge/SKILL.md +34 -13
- 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 +157 -82
- package/skills/browser-bridge/references/token-efficiency.md +19 -13
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
| Method | CLI Shortcut | Purpose |
|
|
6
6
|
| ------------------------ | ------------------------------------- | ----------------------------------------------------------- |
|
|
7
|
-
| `input.click` | `click <ref> [button]` |
|
|
7
|
+
| `input.click` | `click <ref> [button]` | Actionability-aware DOM click; optional CDP native click |
|
|
8
8
|
| `input.focus` | `focus <ref>` | Focus an element |
|
|
9
|
-
| `input.type` | `type <ref> <text>` |
|
|
10
|
-
| `input.fill` | `fill <ref> <value>` |
|
|
9
|
+
| `input.type` | `type <ref> <text>` | DOM key sequence; optional CDP native text insertion |
|
|
10
|
+
| `input.fill` | `fill <ref> <value>` | DOM fill strategy; optional CDP clear and text insertion |
|
|
11
11
|
| `input.press_key` | `press-key <key> [ref]` | Send keyboard key (Enter, Backspace, etc.) |
|
|
12
12
|
| `cdp.dispatch_key_event` | `cdp-press-key --tab <id> <key>` | CDP keyDown/keyUp without focusing the target tab |
|
|
13
13
|
| `input.set_checked` | `call input.set_checked '{...}'` | Toggle checkbox/radio |
|
|
14
14
|
| `input.select_option` | `call input.select_option '{...}'` | Select native `<select>` by value/label/index |
|
|
15
|
-
| `input.hover` | `hover <ref>` |
|
|
16
|
-
| `input.drag` | `call input.drag '{...}'` |
|
|
15
|
+
| `input.hover` | `hover <ref>` | DOM hover events or optional CDP pointer move |
|
|
16
|
+
| `input.drag` | `call input.drag '{...}'` | DOM drag events or optional CDP pointer drag |
|
|
17
17
|
| `input.scroll_into_view` | `call input.scroll_into_view '{...}'` | Ensure a target is visible before inspect/capture |
|
|
18
18
|
|
|
19
19
|
## Navigation
|
|
@@ -29,6 +29,14 @@ bbx call navigation.go_forward
|
|
|
29
29
|
- `waitForLoad` defaults `true`; set `false` for long-lived pages.
|
|
30
30
|
- If navigation times out, retry with larger `timeoutMs` or check with `page.get_state`.
|
|
31
31
|
|
|
32
|
+
For a navigation or SPA route caused by input, use event-aware URL conditions instead of polling:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bbx call page.wait_for_load_state '{"url":"/dashboard","urlMatch":"contains","waitForLoad":false,"timeoutMs":10000}'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The current URL is checked first. The wait then observes full navigation, tab URL/status updates, `pushState`, `replaceState`, `popstate`, and hash changes. It returns the final URL, elapsed time, and observed navigation kind. `waitForLoad: true` means Chrome tab status `complete`, not `networkidle`. Regex mode is deliberately restricted to a bounded linear subset without grouping, alternation, quantifiers, or backreferences.
|
|
39
|
+
|
|
32
40
|
## Viewport
|
|
33
41
|
|
|
34
42
|
```bash
|
|
@@ -78,15 +86,17 @@ Typical workflow - compare two pages (only when comparison is required):
|
|
|
78
86
|
|
|
79
87
|
## Accessibility Tree
|
|
80
88
|
|
|
81
|
-
Retrieve
|
|
89
|
+
Retrieve a depth-limited accessibility tree for the page. Useful for understanding semantic structure, finding interactive elements, and accessibility audits.
|
|
82
90
|
|
|
83
91
|
```bash
|
|
84
92
|
bbx a11y-tree # default limits
|
|
85
93
|
bbx a11y-tree 50 3 # max 50 nodes, depth 3
|
|
86
94
|
bbx call dom.get_accessibility_tree '{"maxNodes":100,"maxDepth":5}'
|
|
95
|
+
bbx call dom.get_accessibility_tree '{"maxNodes":100,"maxDepth":6,"compact":true}'
|
|
96
|
+
bbx call dom.get_accessibility_tree '{"maxNodes":100,"maxDepth":6,"interactiveOnly":true}'
|
|
87
97
|
```
|
|
88
98
|
|
|
89
|
-
Each node
|
|
99
|
+
Each node includes semantic state plus `interactive`, `semanticInteractive`, `focusable`, `focusableAndEnabled`, `ignored`, and `childIds`. `interactive` is not a current actionability guarantee. Compact and interactive-only filters run before `maxNodes`; results report partial depth topology, missing children, and continuation guidance. AX nodes do not become page refs, so use `dom.find_by_role` before input.
|
|
90
100
|
|
|
91
101
|
Typical workflow - find interactive controls:
|
|
92
102
|
|
|
@@ -151,7 +161,7 @@ bbx network 50 # newly captured requests
|
|
|
151
161
|
bbx console error # newly captured errors
|
|
152
162
|
```
|
|
153
163
|
|
|
154
|
-
|
|
164
|
+
Default fetch/XHR entries are retained in capture order and contain `method`, `url`, `status`, `duration`, `type`, `ts`, and `size`.
|
|
155
165
|
|
|
156
166
|
Typical workflow - debug API calls:
|
|
157
167
|
|
|
@@ -161,6 +171,17 @@ Typical workflow - debug API calls:
|
|
|
161
171
|
4. Cross-reference with `page.get_console` for errors
|
|
162
172
|
5. Use `page.evaluate` only if lighter evidence cannot expose the needed response state
|
|
163
173
|
|
|
174
|
+
For document, script, stylesheet, image, WebSocket, WebTransport, and other resource metadata, explicitly arm CDP before reproducing:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
bbx call page.get_network '{"source":"cdp","capture":"start"}'
|
|
178
|
+
# reproduce activity
|
|
179
|
+
bbx call page.get_network '{"source":"cdp","capture":"read","limit":50}'
|
|
180
|
+
bbx call page.get_network '{"source":"cdp","capture":"stop"}'
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
This holds debugger ownership and is more expensive than default instrumentation. A plain read cannot recover events from before `start`. CDP results report armed/ownership/inflight/drop state and redact URL credentials, fragments, and query values; bodies, cookies, authorization values, and complete headers are excluded.
|
|
184
|
+
|
|
164
185
|
## Network Interception
|
|
165
186
|
|
|
166
187
|
Block, stub, or modify matching requests via CDP (debugger-backed). Patterns are globs: `*` matches any characters, `?` matches one character.
|
|
@@ -204,6 +225,28 @@ bbx type el_123 hello # simulate per-character keystrokes
|
|
|
204
225
|
|
|
205
226
|
Prefer `fill` for setting form values: it uses the native prototype setter plus `input`/`change`/`blur` events, which React, Vue, and Angular pick up reliably. `mode` defaults to `auto` (setter first, keystroke fallback if the value did not stick); pass `"mode":"keystrokes"` via `bbx call input.fill` for components that only react to per-key events. Use `type` when page logic depends on individual key events (autocomplete, masked inputs).
|
|
206
227
|
|
|
228
|
+
`mode` is not `executionMode`. The latter accepts only `dom` or `cdp`, defaults to `dom` for compatibility, and selects the dispatch path. CDP execution is available only for click, hover, drag, type, and fill; unsupported combinations fail with `INPUT_UNSUPPORTED` instead of silently changing paths.
|
|
229
|
+
|
|
230
|
+
## Actionability And Stale Refs
|
|
231
|
+
|
|
232
|
+
Input selectors preserve the first match when it is actionable. Otherwise Browser Bridge evaluates at most 25 candidates and proceeds only when one is uniquely preferable. It scrolls the selected target as needed, then rechecks rendered bounds, hidden/disabled/inert state, and pointer hit testing. Expect structured `ELEMENT_NOT_FOUND`, `ELEMENT_NOT_ACTIONABLE`, `ELEMENT_OBSCURED`, or `ELEMENT_AMBIGUOUS` errors rather than best-effort retargeting.
|
|
233
|
+
|
|
234
|
+
Successful targeted click, focus, type, fill, press-key, checked-state, option-selection, hover, and drag results report `resolution` and `execution` metadata. `cdp_press_key` and `scroll_into_view` use separate contracts. Explicit refs preserve exact identity. Stale refs fail by default; `recoverStale: true` allows a single same-document, unchanged-URL recovery only from a strong unique semantic descriptor, and reports old/new refs and matched fields. The recovery scan evaluates at most 100 same-tag candidates and returns `ELEMENT_AMBIGUOUS` with `reason: "scan_incomplete"` whenever additional candidates make uniqueness unprovable. Prefer a fresh query unless this strict recovery contract clearly applies.
|
|
235
|
+
|
|
236
|
+
After any DOM or CDP input, verify the intended application outcome with a targeted wait or structured read. Event dispatch alone is not proof that application state changed.
|
|
237
|
+
|
|
238
|
+
## JavaScript Dialogs
|
|
239
|
+
|
|
240
|
+
Dialogs are never accepted or dismissed automatically:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
bbx call page.handle_dialog '{"action":"inspect"}'
|
|
244
|
+
bbx call page.handle_dialog '{"action":"accept","expectedDialogId":"00000000-0000-4000-8000-000000000000:1"}' # replace with inspected dialogId
|
|
245
|
+
bbx call page.handle_dialog '{"action":"dismiss","expectedDialogId":"00000000-0000-4000-8000-000000000000:1"}' # replace with inspected dialogId
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
`expectedDialogId` is checked immediately before the CDP command, but Chrome cannot atomically bind that command to the observation. A successful mutation reports `commandDispatched: true` and `atomicDialogBinding: false`. On `DIALOG_ACTION_CONFLICT`, inspect again and do not automatically repeat the mutation. Dialog text is returned only to the caller and is excluded from persisted action logs.
|
|
249
|
+
|
|
207
250
|
## Hover
|
|
208
251
|
|
|
209
252
|
Dispatch mouse events to trigger CSS `:hover` rules, tooltip display, dropdown menus, etc.
|
|
@@ -297,7 +340,7 @@ Use after clicking navigation links.
|
|
|
297
340
|
|
|
298
341
|
## Raw `bbx call` for Interaction Methods
|
|
299
342
|
|
|
300
|
-
|
|
343
|
+
Targeted DOM input methods require the target wrapped in a `target` object; `input.press_key` may omit it to use the active element. Do not pass `ref` or `elementRef` at the top level. `cdp.dispatch_key_event` targets the tab, while `input.scroll_into_view` accepts `target` but does not return actionability/execution metadata:
|
|
301
344
|
|
|
302
345
|
```bash
|
|
303
346
|
# CORRECT
|
|
@@ -318,5 +361,6 @@ The CLI shortcuts (`bbx click el_xxx`) handle this wrapping automatically, but `
|
|
|
318
361
|
1. **Find target**: `dom.find_by_text`, `dom.find_by_role`, or `dom.query` → get `elementRef`
|
|
319
362
|
2. **Focus** if needed: `input.focus` (for keyboard input)
|
|
320
363
|
3. **Act**: `click`, `type`, `press_key`, `hover`, `drag`, `scroll_into_view`, etc.
|
|
321
|
-
4. **
|
|
322
|
-
5. **
|
|
364
|
+
4. **Inspect metadata**: confirm resolution strategy, hit test, stale recovery, and actual execution path
|
|
365
|
+
5. **Wait**: use `dom.wait_for` or an event-aware URL wait if the action triggers async updates
|
|
366
|
+
6. **Verify**: `dom.describe`, `styles.get_computed`, `page.get_state`, or `page.get_console`; never infer app success from dispatch alone
|
|
@@ -41,3 +41,5 @@ After any patch:
|
|
|
41
41
|
|
|
42
42
|
- Roll back every patch before finishing.
|
|
43
43
|
- If multiple patches are active, list them before rolling back so the subagent can explain what was tested.
|
|
44
|
+
- Rollback records live in the current document. Browser Bridge attempts to roll them back when access is disabled or switched to another window; navigation or document replacement removes the page-side registry and may make old patch IDs unusable.
|
|
45
|
+
- `patch.commit_session_baseline` keeps the current DOM/style changes but clears their rollback records. Use it only when the user intentionally wants those live changes to become the new patch baseline; it does not write source files or grant a longer-lived browser session.
|
|
@@ -27,75 +27,77 @@ 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 (67)
|
|
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, enabled-window routing, debugger, and capture state |
|
|
43
|
+
| `log.tail` | No | - | system | `-` | Recent redacted bridge logs |
|
|
44
|
+
| `daemon.metrics` | No | - | system | `-` | Daemon health and performance 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` | `localStorage`/`sessionStorage`; optional `keys` |
|
|
51
|
+
| `page.get_text` | Yes | - | page | `page.read` | Full page text; `textBudget` limits size |
|
|
52
|
+
| `page.extract_content` | Yes | - | page | `page.read` | Node-processed semantic text/Markdown with bounded HTML snapshots and optional settlement |
|
|
53
|
+
| `page.get_network` | Yes | Conditional | page | `network.read` | Fetch/XHR by default; explicit CDP all-resource capture lifecycle |
|
|
54
|
+
| `network.intercept.add` | Yes | CDP | page | `network.intercept` | Add interception rule; action fulfill/continue/block |
|
|
55
|
+
| `network.intercept.remove` | Yes | CDP | page | `network.intercept` | Remove rule by `ruleId` |
|
|
56
|
+
| `network.intercept.list` | Yes | CDP | page | `network.intercept` | List active rules (rules drop on debugger detach) |
|
|
57
|
+
| `network.intercept.clear` | Yes | CDP | page | `network.intercept` | Remove all rules and release interception |
|
|
58
|
+
| `navigation.navigate` | Yes | - | navigate | `navigation.control` | Go to URL; `waitForLoad` default true |
|
|
59
|
+
| `navigation.reload` | Yes | - | navigate | `navigation.control` | Reload; `waitForLoad` default true |
|
|
60
|
+
| `navigation.go_back` | Yes | - | navigate | `navigation.control` | History back |
|
|
61
|
+
| `navigation.go_forward` | Yes | - | navigate | `navigation.control` | History forward |
|
|
62
|
+
| `dom.query` | Yes | - | inspect | `dom.read` | Query subtree with budget constraints |
|
|
63
|
+
| `dom.describe` | Yes | - | inspect | `dom.read` | Single element details via `elementRef` |
|
|
64
|
+
| `dom.get_text` | Yes | - | inspect | `dom.read` | Text content with `textBudget` |
|
|
65
|
+
| `dom.get_attributes` | Yes | - | inspect | `dom.read` | Targeted attribute read |
|
|
66
|
+
| `dom.wait_for` | Yes | - | wait | `dom.read` | Wait for DOM condition; MutationObserver and polling |
|
|
67
|
+
| `dom.find_by_text` | Yes | - | inspect | `dom.read` | Find by visible text; returns `{nodes, count}` |
|
|
68
|
+
| `dom.find_by_role` | Yes | - | inspect | `dom.read` | Find by ARIA role; optional `name` filter |
|
|
69
|
+
| `dom.get_html` | Yes | - | inspect | `dom.read` | `innerHTML`/`outerHTML`; `maxLength` truncation |
|
|
70
|
+
| `dom.get_accessibility_tree` | Yes | CDP | inspect | `dom.read` | Full or uniquely selector-scoped AX tree with compact/interactive filters |
|
|
71
|
+
| `layout.get_box_model` | Yes | - | inspect | `layout.read` | Element geometry |
|
|
72
|
+
| `layout.hit_test` | Yes | - | inspect | `layout.read` | Topmost element at viewport point |
|
|
73
|
+
| `styles.get_computed` | Yes | - | inspect | `styles.read` | Requested properties; omission returns display/position/width/height/color |
|
|
74
|
+
| `styles.get_matched_rules` | Yes | - | inspect | `styles.read` | Element ref, class list, and inline style only; not stylesheet cascade data |
|
|
75
|
+
| `viewport.scroll` | Yes | - | navigate | `viewport.control` | Window or element scroll |
|
|
76
|
+
| `viewport.resize` | Yes | CDP | navigate | `viewport.control` | Set viewport via device emulation; `reset: true` |
|
|
77
|
+
| `input.click` | Yes | Optional | interact | `automation.input` | Actionability-aware DOM or CDP click |
|
|
78
|
+
| `input.focus` | Yes | - | interact | `automation.input` | Actionability-aware DOM focus |
|
|
79
|
+
| `input.type` | Yes | Optional | interact | `automation.input` | DOM key sequence or CDP text insertion |
|
|
80
|
+
| `input.fill` | Yes | Optional | interact | `automation.input` | DOM fill strategy or CDP clear/insert; see `mode` versus `executionMode` |
|
|
81
|
+
| `input.press_key` | Yes | - | interact | `automation.input` | DOM key event |
|
|
82
|
+
| `input.set_checked` | Yes | - | interact | `automation.input` | Checkbox/radio toggle |
|
|
83
|
+
| `input.select_option` | Yes | - | interact | `automation.input` | Native select by value/label/index |
|
|
84
|
+
| `input.hover` | Yes | Optional | interact | `automation.input` | DOM hover events or native CDP pointer move |
|
|
85
|
+
| `input.drag` | Yes | Optional | interact | `automation.input` | DOM drag events or native interpolated pointer drag |
|
|
86
|
+
| `input.scroll_into_view` | Yes | - | interact | `automation.input` | Explicitly scroll target into view before inspect/capture |
|
|
87
|
+
| `screenshot.capture_element` | Yes | CDP | capture | `screenshot.partial` | Complete element screenshot with explicit completeness metadata |
|
|
88
|
+
| `screenshot.capture_region` | Yes | CDP | capture | `screenshot.partial` | Cropped viewport region in PNG, JPEG, or WebP |
|
|
89
|
+
| `screenshot.capture_full_page` | Yes | CDP | capture | `screenshot.partial` | Full document screenshot; fails coherently above Chrome capture limits |
|
|
90
|
+
| `patch.apply_styles` | Yes | - | patch | `patch.styles` | Reversible CSS patch; `verify` returns computed result |
|
|
91
|
+
| `patch.apply_dom` | Yes | - | patch | `patch.dom` | Reversible DOM mutation; `verify` returns result |
|
|
92
|
+
| `patch.list` | Yes | - | patch | `patch.dom` | Active rollback records in the current document |
|
|
93
|
+
| `patch.rollback` | Yes | - | patch | `patch.dom` | Revert one active patch |
|
|
94
|
+
| `patch.commit_session_baseline` | Yes | - | patch | `patch.dom` | Keep current mutations and discard their rollback history |
|
|
95
|
+
| `performance.get_metrics` | Yes | CDP | performance | `performance.read` | Chrome performance counters |
|
|
96
|
+
| `cdp.get_document` | Yes | CDP | cdp | `cdp.dom_snapshot` | DevTools document tree |
|
|
97
|
+
| `cdp.get_dom_snapshot` | Yes | CDP | cdp | `cdp.dom_snapshot` | DevTools DOM snapshot |
|
|
98
|
+
| `cdp.get_box_model` | Yes | CDP | cdp | `cdp.box_model` | DevTools-backed element geometry |
|
|
99
|
+
| `cdp.get_computed_styles_for_node` | Yes | CDP | cdp | `cdp.styles` | DevTools-backed computed styles |
|
|
100
|
+
| `cdp.dispatch_key_event` | Yes | CDP | cdp | `cdp.input` | DevTools keyDown/keyUp without foreground focus |
|
|
99
101
|
|
|
100
102
|
## CLI
|
|
101
103
|
|
|
@@ -114,13 +116,16 @@ Newer bridge methods such as `input.scroll_into_view` and `screenshot.capture_fu
|
|
|
114
116
|
|
|
115
117
|
### access.request
|
|
116
118
|
|
|
117
|
-
Request Browser Bridge access for the focused browser window. Surfaces an Enable prompt in the extension popup or side panel
|
|
119
|
+
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
120
|
|
|
119
121
|
```bash
|
|
120
122
|
bbx access-request
|
|
121
|
-
bbx
|
|
123
|
+
bbx access-request inspect
|
|
124
|
+
bbx call access.request '{"intent":"capture"}'
|
|
122
125
|
```
|
|
123
126
|
|
|
127
|
+
`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.
|
|
128
|
+
|
|
124
129
|
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
130
|
|
|
126
131
|
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,14 +156,29 @@ bbx call page.get_console '{"level":"error","limit":20,"clear":true}'
|
|
|
151
156
|
|
|
152
157
|
Responses include `dropped` when older buffered entries were discarded on noisy pages.
|
|
153
158
|
|
|
159
|
+
### page.handle_dialog
|
|
160
|
+
|
|
161
|
+
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.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
bbx call page.handle_dialog '{"action":"inspect"}'
|
|
165
|
+
bbx call page.handle_dialog '{"action":"accept","expectedDialogId":"00000000-0000-4000-8000-000000000000:1","promptText":"value"}' # replace with inspected dialogId
|
|
166
|
+
bbx call page.handle_dialog '{"action":"dismiss","expectedDialogId":"00000000-0000-4000-8000-000000000000:1"}' # replace with inspected dialogId
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`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.
|
|
170
|
+
|
|
154
171
|
### page.wait_for_load_state
|
|
155
172
|
|
|
156
|
-
|
|
173
|
+
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
174
|
|
|
158
175
|
```bash
|
|
159
176
|
bbx call page.wait_for_load_state '{"timeoutMs":10000}'
|
|
177
|
+
bbx call page.wait_for_load_state '{"url":"/dashboard","urlMatch":"contains","waitForLoad":false}'
|
|
160
178
|
```
|
|
161
179
|
|
|
180
|
+
`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.
|
|
181
|
+
|
|
162
182
|
### page.get_storage
|
|
163
183
|
|
|
164
184
|
Read `localStorage` or `sessionStorage` entries. Values truncated at 500 chars each.
|
|
@@ -220,9 +240,25 @@ bbx html el_abc123
|
|
|
220
240
|
bbx call dom.get_html '{"elementRef":"el_abc123","outer":true,"maxLength":2000}'
|
|
221
241
|
```
|
|
222
242
|
|
|
243
|
+
### styles.get_computed and styles.get_matched_rules
|
|
244
|
+
|
|
245
|
+
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.
|
|
246
|
+
|
|
247
|
+
### Actionable input targets
|
|
248
|
+
|
|
249
|
+
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.
|
|
250
|
+
|
|
251
|
+
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.
|
|
252
|
+
|
|
253
|
+
`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"`.
|
|
254
|
+
|
|
255
|
+
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.
|
|
256
|
+
|
|
257
|
+
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.
|
|
258
|
+
|
|
223
259
|
### input.hover
|
|
224
260
|
|
|
225
|
-
Trigger
|
|
261
|
+
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
262
|
|
|
227
263
|
```bash
|
|
228
264
|
bbx hover el_abc123
|
|
@@ -231,7 +267,7 @@ bbx call input.hover '{"target":{"elementRef":"el_abc123"},"duration":1000}'
|
|
|
231
267
|
|
|
232
268
|
### input.drag
|
|
233
269
|
|
|
234
|
-
|
|
270
|
+
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
271
|
|
|
236
272
|
```bash
|
|
237
273
|
bbx call input.drag '{"source":{"elementRef":"el_src"},"destination":{"elementRef":"el_dst"}}'
|
|
@@ -285,11 +321,22 @@ bbx page-text 8000
|
|
|
285
321
|
bbx call page.get_text '{"textBudget":2000}'
|
|
286
322
|
```
|
|
287
323
|
|
|
324
|
+
### page.extract_content
|
|
325
|
+
|
|
326
|
+
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.
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
bbx call page.extract_content '{"format":"text"}'
|
|
330
|
+
bbx call page.extract_content '{"format":"markdown","selector":"main","textBudget":8000}'
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
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.
|
|
334
|
+
|
|
288
335
|
### page.get_network
|
|
289
336
|
|
|
290
337
|
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
338
|
|
|
292
|
-
|
|
339
|
+
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
340
|
|
|
294
341
|
```bash
|
|
295
342
|
bbx network
|
|
@@ -297,20 +344,37 @@ bbx network 50
|
|
|
297
344
|
bbx call page.get_network '{"limit":20,"clear":true}'
|
|
298
345
|
```
|
|
299
346
|
|
|
300
|
-
Each entry
|
|
347
|
+
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.
|
|
348
|
+
|
|
349
|
+
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:
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
bbx call page.get_network '{"source":"cdp","capture":"start"}'
|
|
353
|
+
# reproduce the activity
|
|
354
|
+
bbx call page.get_network '{"source":"cdp","capture":"read","limit":50}'
|
|
355
|
+
bbx call page.get_network '{"source":"cdp","capture":"stop"}'
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
`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`.
|
|
359
|
+
|
|
360
|
+
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.
|
|
301
361
|
|
|
302
362
|
### dom.get_accessibility_tree
|
|
303
363
|
|
|
304
|
-
Retrieve
|
|
364
|
+
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
365
|
|
|
306
366
|
This is debugger-backed. Prefer `dom.find_by_role`, `dom.find_by_text`, and targeted `dom.query`/`dom.describe` first.
|
|
307
367
|
|
|
308
368
|
```bash
|
|
309
369
|
bbx a11y-tree
|
|
310
370
|
bbx a11y-tree 50 3
|
|
311
|
-
bbx call dom.get_accessibility_tree '{"maxNodes":100,"maxDepth":5}'
|
|
371
|
+
bbx call dom.get_accessibility_tree '{"maxNodes":100,"maxDepth":5,"compact":true}'
|
|
372
|
+
bbx call dom.get_accessibility_tree '{"maxNodes":100,"maxDepth":6,"interactiveOnly":true}'
|
|
373
|
+
bbx call dom.get_accessibility_tree '{"selector":"[role=dialog]","maxNodes":50,"compact":true}'
|
|
312
374
|
```
|
|
313
375
|
|
|
376
|
+
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.
|
|
377
|
+
|
|
314
378
|
### viewport.resize
|
|
315
379
|
|
|
316
380
|
Set the browser viewport to specific dimensions using CDP device emulation. Pass `reset: true` to clear the override.
|
|
@@ -334,14 +398,16 @@ bbx perf
|
|
|
334
398
|
bbx call performance.get_metrics
|
|
335
399
|
```
|
|
336
400
|
|
|
337
|
-
### screenshot.
|
|
401
|
+
### screenshot.capture_\*
|
|
402
|
+
|
|
403
|
+
Capture a complete element, a tight viewport region, or a full document. All methods accept `format: "png" | "jpeg" | "webp"`; JPEG and WebP additionally accept integer `quality` from 0 to 100. Results include matching `format`, `mimeType`, `complete`, and `clipped` metadata.
|
|
338
404
|
|
|
339
|
-
|
|
405
|
+
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.
|
|
340
406
|
|
|
341
|
-
|
|
407
|
+
Raw calls return base64 JSON. Prefer `bbx screenshot [--format png|jpeg|webp] [--quality 0-100] <ref> [outPath]` when one element is enough; the CLI chooses or validates the output extension from the encoding.
|
|
342
408
|
|
|
343
409
|
```bash
|
|
344
|
-
bbx call screenshot.capture_full_page '{}'
|
|
410
|
+
bbx call screenshot.capture_full_page '{"format":"jpeg","quality":75}'
|
|
345
411
|
```
|
|
346
412
|
|
|
347
413
|
## Request Envelope
|
|
@@ -363,6 +429,15 @@ bbx call screenshot.capture_full_page '{}'
|
|
|
363
429
|
| `ACCESS_DENIED` | Turn on Browser Bridge for the target window | `retry: false` |
|
|
364
430
|
| `TAB_MISMATCH` | Explicit `tabId` is missing, closed, or outside enabled window | `retry: false`, use `tabs.list` |
|
|
365
431
|
| `ELEMENT_STALE` | Re-query DOM for fresh `elementRef` | `retry: false`, use `dom.query` |
|
|
432
|
+
| `ELEMENT_AMBIGUOUS` | Narrow selector or use an explicit ref | `retry: false`, use `dom.query` |
|
|
433
|
+
| `ELEMENT_NOT_ACTIONABLE` | Inspect hidden/disabled/inert/zero-size target | `retry: false`, use `dom.describe` |
|
|
434
|
+
| `ELEMENT_OBSCURED` | Inspect the element blocking the target point | `retry: false`, use `layout.hit_test` |
|
|
435
|
+
| `ELEMENT_NOT_FOUND` | Correct or narrow the selector | `retry: false`, use `dom.query` |
|
|
436
|
+
| `INPUT_UNSUPPORTED` | Use DOM execution or a CDP-supported input method | `retry: false` |
|
|
437
|
+
| `INPUT_INVALID_TARGET` | Choose a control compatible with the input | `retry: false`, use `dom.describe` |
|
|
438
|
+
| `INPUT_FOCUS_CHANGED` | Inspect focus handlers; do not replay native text blindly | `retry: false`, use `dom.describe` |
|
|
439
|
+
| `DIALOG_NOT_OPEN` | Trigger or inspect the current dialog | `retry: false` |
|
|
440
|
+
| `DIALOG_ACTION_CONFLICT` | Inspect again; never auto-repeat a dialog mutation | `retry: false` |
|
|
366
441
|
| `CONTENT_SCRIPT_UNAVAILABLE` | Page is restricted (chrome://, extensions, etc.) | `retry: false` |
|
|
367
442
|
| `NATIVE_HOST_UNAVAILABLE` | Check daemon: `bbx status` | `retry: false` |
|
|
368
443
|
| `EXTENSION_DISCONNECTED` | Extension not connected to daemon | `retry: true` after 3 s, check `health.ping` |
|