@browserbridge/bbx 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/docs/api-reference.md +33 -33
- package/docs/mcp-vs-cli.md +104 -104
- package/docs/publishing.md +1 -3
- package/docs/quickstart.md +6 -6
- package/docs/unpacked-extension.md +72 -0
- package/manifest.json +3 -17
- package/package.json +44 -42
- package/packages/agent-client/src/cli-helpers.js +10 -5
- package/packages/agent-client/src/cli.js +65 -135
- package/packages/agent-client/src/client.js +37 -17
- package/packages/agent-client/src/command-registry.js +101 -69
- package/packages/agent-client/src/detect.js +3 -6
- package/packages/agent-client/src/install.js +10 -27
- package/packages/agent-client/src/mcp-config.js +11 -30
- package/packages/agent-client/src/runtime.js +41 -20
- package/packages/agent-client/src/setup-status.js +13 -28
- package/packages/extension/src/background-helpers.js +51 -36
- package/packages/extension/src/background-routing.js +11 -13
- package/packages/extension/src/background.js +562 -299
- package/packages/extension/src/content-script-helpers.js +17 -16
- package/packages/extension/src/content-script.js +175 -109
- package/packages/extension/src/sidepanel-helpers.js +3 -1
- package/packages/extension/ui/popup.js +39 -20
- package/packages/extension/ui/sidepanel.js +108 -191
- package/packages/extension/ui/ui.css +2 -1
- package/packages/mcp-server/src/handlers.js +546 -250
- package/packages/mcp-server/src/server.js +558 -257
- package/packages/native-host/bin/bridge-daemon.js +6 -2
- package/packages/native-host/bin/install-manifest.js +2 -2
- package/packages/native-host/bin/postinstall.js +4 -2
- package/packages/native-host/src/config.js +11 -7
- package/packages/native-host/src/daemon.js +143 -92
- package/packages/native-host/src/install-manifest.js +73 -22
- package/packages/native-host/src/native-host.js +55 -40
- package/packages/protocol/src/budget.js +3 -7
- package/packages/protocol/src/capabilities.js +3 -3
- package/packages/protocol/src/errors.js +11 -11
- package/packages/protocol/src/protocol.js +104 -71
- package/packages/protocol/src/registry.js +300 -45
- package/packages/protocol/src/summary.js +249 -106
- package/packages/protocol/src/types.js +1 -1
- package/skills/browser-bridge/SKILL.md +1 -1
- package/skills/browser-bridge/agents/openai.yaml +3 -3
- package/skills/browser-bridge/references/interaction.md +33 -11
- package/skills/browser-bridge/references/patch-workflow.md +3 -0
- package/skills/browser-bridge/references/protocol.md +125 -70
- package/skills/browser-bridge/references/tailwind.md +12 -11
- package/skills/browser-bridge/references/token-efficiency.md +23 -22
- package/skills/browser-bridge/references/ui-workflows.md +8 -0
- package/packages/extension/ui/offscreen.html +0 -6
- package/packages/extension/ui/offscreen.js +0 -61
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Input Methods
|
|
4
4
|
|
|
5
|
-
| Method
|
|
6
|
-
|
|
7
|
-
| `input.click`
|
|
8
|
-
| `input.focus`
|
|
9
|
-
| `input.type`
|
|
10
|
-
| `input.press_key`
|
|
11
|
-
| `input.set_checked`
|
|
12
|
-
| `input.select_option`
|
|
13
|
-
| `input.hover`
|
|
14
|
-
| `input.drag`
|
|
15
|
-
| `input.scroll_into_view` | `call input.scroll_into_view '{...}'` | Ensure a target is visible before inspect/capture
|
|
5
|
+
| Method | CLI Shortcut | Purpose |
|
|
6
|
+
| ------------------------ | ------------------------------------- | ----------------------------------------------------------- |
|
|
7
|
+
| `input.click` | `click <ref> [button]` | DOM-level click |
|
|
8
|
+
| `input.focus` | `focus <ref>` | Focus an element |
|
|
9
|
+
| `input.type` | `type <ref> <text>` | Type into input/textarea/contenteditable |
|
|
10
|
+
| `input.press_key` | `press-key <key> [ref]` | Send keyboard key (Enter, Backspace, etc.) |
|
|
11
|
+
| `input.set_checked` | `call input.set_checked '{...}'` | Toggle checkbox/radio |
|
|
12
|
+
| `input.select_option` | `call input.select_option '{...}'` | Select native `<select>` by value/label/index |
|
|
13
|
+
| `input.hover` | `hover <ref>` | Trigger CSS `:hover` state (mouseenter/mouseover/mousemove) |
|
|
14
|
+
| `input.drag` | `call input.drag '{...}'` | Full drag-and-drop event sequence |
|
|
15
|
+
| `input.scroll_into_view` | `call input.scroll_into_view '{...}'` | Ensure a target is visible before inspect/capture |
|
|
16
16
|
|
|
17
17
|
## Navigation
|
|
18
18
|
|
|
@@ -39,6 +39,7 @@ Scrolls the window or a specific scrollable element.
|
|
|
39
39
|
### Resize Viewport
|
|
40
40
|
|
|
41
41
|
Set device viewport dimensions (useful for responsive testing):
|
|
42
|
+
|
|
42
43
|
```bash
|
|
43
44
|
bbx resize 375 812 # iPhone-size
|
|
44
45
|
bbx resize 1024 768 # tablet
|
|
@@ -50,6 +51,7 @@ Uses CDP device emulation - the page re-renders at the new size immediately.
|
|
|
50
51
|
## Tab Management
|
|
51
52
|
|
|
52
53
|
**IMPORTANT: Prefer existing tabs.** Never create new tabs unless:
|
|
54
|
+
|
|
53
55
|
- The user explicitly requests opening a new page
|
|
54
56
|
- The task requires a clean/fresh page state (e.g., testing initial load)
|
|
55
57
|
- You need to compare multiple pages simultaneously
|
|
@@ -65,6 +67,7 @@ bbx call tabs.create '{"url":"https://example.com","active":false}'
|
|
|
65
67
|
```
|
|
66
68
|
|
|
67
69
|
Typical workflow - compare two pages (only when comparison is required):
|
|
70
|
+
|
|
68
71
|
1. `tabs.list` to see current tabs
|
|
69
72
|
2. `tabs.create` with second URL
|
|
70
73
|
3. Inspect both tabs (`--tab <id>` or MCP `tabId` only when you need the non-active tab)
|
|
@@ -83,6 +86,7 @@ bbx call dom.get_accessibility_tree '{"maxNodes":100,"maxDepth":5}'
|
|
|
83
86
|
Each node: `role`, `name`, `description`, `value`, `focused`, `required`, `checked`, `disabled`, `interactive`, `childIds`.
|
|
84
87
|
|
|
85
88
|
Typical workflow - find interactive controls:
|
|
89
|
+
|
|
86
90
|
1. `dom.get_accessibility_tree` with small `maxNodes`
|
|
87
91
|
2. Scan for nodes with `interactive: true`
|
|
88
92
|
3. Use role/name to identify the right control
|
|
@@ -103,6 +107,7 @@ bbx call --tab 200 dom.query '{"selector":"main"}'
|
|
|
103
107
|
```
|
|
104
108
|
|
|
105
109
|
Open a new tab programmatically:
|
|
110
|
+
|
|
106
111
|
```bash
|
|
107
112
|
bbx tab-create https://example.com # creates a new tab in the enabled window
|
|
108
113
|
bbx call --tab <new-tabId> page.get_state
|
|
@@ -127,6 +132,7 @@ Scrolls the window by default. Pass an `elementRef` to scroll an inner scrollabl
|
|
|
127
132
|
### Scroll target into view
|
|
128
133
|
|
|
129
134
|
Use this when the page has nested containers or when you want the target centered before a screenshot or hover:
|
|
135
|
+
|
|
130
136
|
```bash
|
|
131
137
|
bbx call input.scroll_into_view '{"target":{"elementRef":"el_123"}}'
|
|
132
138
|
bbx call input.scroll_into_view '{"target":{"selector":"[data-testid=\"submit-button\"]"}}'
|
|
@@ -143,6 +149,7 @@ bbx call page.get_network '{"limit":20,"clear":true}'
|
|
|
143
149
|
Each entry: `method`, `url`, `status`, `duration`, `initiator`.
|
|
144
150
|
|
|
145
151
|
Typical workflow - debug API calls:
|
|
152
|
+
|
|
146
153
|
1. `page.get_network` to see recent requests
|
|
147
154
|
2. Filter by URL pattern or status code
|
|
148
155
|
3. Cross-reference with `page.get_console` for errors
|
|
@@ -151,11 +158,13 @@ Typical workflow - debug API calls:
|
|
|
151
158
|
## Form Controls
|
|
152
159
|
|
|
153
160
|
**Checkbox/radio:**
|
|
161
|
+
|
|
154
162
|
```bash
|
|
155
163
|
bbx call input.set_checked '{"target":{"elementRef":"el_123"},"checked":true}'
|
|
156
164
|
```
|
|
157
165
|
|
|
158
166
|
**Select dropdown:**
|
|
167
|
+
|
|
159
168
|
```bash
|
|
160
169
|
bbx call input.select_option '{"target":{"elementRef":"el_456"},"values":["us"]}'
|
|
161
170
|
```
|
|
@@ -172,11 +181,13 @@ bbx call input.hover '{"target":{"elementRef":"el_abc123"}}'
|
|
|
172
181
|
```
|
|
173
182
|
|
|
174
183
|
**Hold hover for inspection:** set `duration` (ms) to keep hover active before auto-releasing with `mouseleave`:
|
|
184
|
+
|
|
175
185
|
```bash
|
|
176
186
|
bbx call input.hover '{"target":{"elementRef":"el_abc123"},"duration":2000}'
|
|
177
187
|
```
|
|
178
188
|
|
|
179
189
|
Typical workflow - inspect a tooltip:
|
|
190
|
+
|
|
180
191
|
1. `dom.query` to find the trigger element → `elementRef`
|
|
181
192
|
2. `input.hover` with `duration: 2000`
|
|
182
193
|
3. While hover holds, `dom.query` for tooltip content (e.g. `[role="tooltip"]`)
|
|
@@ -191,6 +202,7 @@ bbx call input.drag '{"source":{"elementRef":"el_src"},"destination":{"elementRe
|
|
|
191
202
|
```
|
|
192
203
|
|
|
193
204
|
With pixel offsets for precise positioning:
|
|
205
|
+
|
|
194
206
|
```bash
|
|
195
207
|
bbx call input.drag '{"source":{"elementRef":"el_src"},"destination":{"elementRef":"el_dst"},"sourceOffset":{"x":10,"y":10},"destinationOffset":{"x":5,"y":5}}'
|
|
196
208
|
```
|
|
@@ -198,6 +210,7 @@ bbx call input.drag '{"source":{"elementRef":"el_src"},"destination":{"elementRe
|
|
|
198
210
|
Event sequence: `mousedown → dragstart → drag → dragenter → dragover → drop → dragend → mouseup`.
|
|
199
211
|
|
|
200
212
|
Typical workflow - reorder a list:
|
|
213
|
+
|
|
201
214
|
1. `dom.query` to find draggable items → get source and destination `elementRef` values
|
|
202
215
|
2. `input.drag` from source to destination
|
|
203
216
|
3. `dom.wait_for` to confirm the DOM updated
|
|
@@ -206,16 +219,21 @@ Typical workflow - reorder a list:
|
|
|
206
219
|
## Finding Elements
|
|
207
220
|
|
|
208
221
|
### By text content
|
|
222
|
+
|
|
209
223
|
Find elements matching visible text. Faster than `dom.query` when you know the label:
|
|
224
|
+
|
|
210
225
|
```bash
|
|
211
226
|
bbx find 'Submit Order'
|
|
212
227
|
bbx call dom.find_by_text '{"text":"Add to Cart","scope":"button","exact":false}'
|
|
213
228
|
```
|
|
229
|
+
|
|
214
230
|
- `scope`: optional CSS selector to narrow search (e.g. `"button"`, `".sidebar"`)
|
|
215
231
|
- `exact`: `true` for exact match, `false` (default) for substring/case-insensitive
|
|
216
232
|
|
|
217
233
|
### By ARIA role
|
|
234
|
+
|
|
218
235
|
Find elements by explicit `role` attribute or implicit HTML role (e.g. `<nav>` → `navigation`):
|
|
236
|
+
|
|
219
237
|
```bash
|
|
220
238
|
bbx find-role button 'Save'
|
|
221
239
|
bbx call dom.find_by_role '{"role":"navigation"}'
|
|
@@ -225,19 +243,23 @@ bbx call dom.find_by_role '{"role":"heading","name":"Dashboard"}'
|
|
|
225
243
|
## Waiting
|
|
226
244
|
|
|
227
245
|
### Wait for DOM condition
|
|
246
|
+
|
|
228
247
|
```bash
|
|
229
248
|
bbx wait '.success-message' 10000
|
|
230
249
|
bbx call dom.wait_for '{"selector":".modal","state":"visible","timeoutMs":10000}'
|
|
231
250
|
bbx call dom.wait_for '{"selector":".spinner","state":"detached","timeoutMs":5000}'
|
|
232
251
|
```
|
|
252
|
+
|
|
233
253
|
- `state`: `attached` (exists in DOM), `detached` (removed), `visible` (non-zero size), `hidden`
|
|
234
254
|
- Uses MutationObserver + 250 ms polling fallback
|
|
235
255
|
- Returns `{found, elementRef, duration}` - NOT an error on timeout
|
|
236
256
|
|
|
237
257
|
### Wait for page load
|
|
258
|
+
|
|
238
259
|
```bash
|
|
239
260
|
bbx call page.wait_for_load_state '{"timeoutMs":10000}'
|
|
240
261
|
```
|
|
262
|
+
|
|
241
263
|
Use after clicking navigation links.
|
|
242
264
|
|
|
243
265
|
## Interaction Flow
|
|
@@ -12,6 +12,7 @@ Use this order for layout or styling issues:
|
|
|
12
12
|
6. `patch.rollback`
|
|
13
13
|
|
|
14
14
|
Prefer style patches for:
|
|
15
|
+
|
|
15
16
|
- overflow fixes
|
|
16
17
|
- spacing adjustments
|
|
17
18
|
- flex or grid tuning
|
|
@@ -21,6 +22,7 @@ Prefer style patches for:
|
|
|
21
22
|
## DOM patch loop
|
|
22
23
|
|
|
23
24
|
Use DOM patches for:
|
|
25
|
+
|
|
24
26
|
- text replacement
|
|
25
27
|
- setting or removing an attribute
|
|
26
28
|
- toggling a class
|
|
@@ -30,6 +32,7 @@ Keep DOM patches minimal and reversible.
|
|
|
30
32
|
## Verification
|
|
31
33
|
|
|
32
34
|
After any patch:
|
|
35
|
+
|
|
33
36
|
- compare box metrics when geometry matters
|
|
34
37
|
- compare computed styles when appearance matters
|
|
35
38
|
- capture a cropped screenshot only when the visual outcome is still unclear
|
|
@@ -29,65 +29,65 @@ The table below includes the legacy capability bucket for each method so agents
|
|
|
29
29
|
|
|
30
30
|
## All Methods (57)
|
|
31
31
|
|
|
32
|
-
| #
|
|
33
|
-
|
|
34
|
-
| 1
|
|
35
|
-
| 2
|
|
36
|
-
| 3
|
|
37
|
-
| 4
|
|
38
|
-
| 5
|
|
39
|
-
| 6
|
|
40
|
-
| 7
|
|
41
|
-
| 8
|
|
42
|
-
| 9
|
|
43
|
-
| 10
|
|
44
|
-
| 11
|
|
45
|
-
| 12
|
|
46
|
-
| 13
|
|
47
|
-
| 14
|
|
48
|
-
| 15
|
|
49
|
-
| 16
|
|
50
|
-
| 17
|
|
51
|
-
| 18
|
|
52
|
-
| 19
|
|
53
|
-
| 20
|
|
54
|
-
| 21
|
|
55
|
-
| 22
|
|
56
|
-
| 23
|
|
57
|
-
| 24
|
|
58
|
-
| 25
|
|
59
|
-
| 26
|
|
60
|
-
| 27
|
|
61
|
-
| 28
|
|
62
|
-
| 29
|
|
63
|
-
| 30
|
|
64
|
-
| 31
|
|
65
|
-
| 32
|
|
66
|
-
| 33
|
|
67
|
-
| 34
|
|
68
|
-
| 35
|
|
69
|
-
| 36
|
|
70
|
-
| 37
|
|
71
|
-
| 38
|
|
72
|
-
| 39
|
|
73
|
-
| 40
|
|
74
|
-
| 41
|
|
75
|
-
| 42
|
|
76
|
-
| 43
|
|
77
|
-
| 44
|
|
78
|
-
| 45
|
|
79
|
-
| 46
|
|
80
|
-
| 47
|
|
81
|
-
| 48
|
|
82
|
-
| 49
|
|
83
|
-
| 50
|
|
84
|
-
| 51
|
|
85
|
-
| 52
|
|
86
|
-
| 53
|
|
87
|
-
| 54
|
|
88
|
-
| 55
|
|
89
|
-
| 56
|
|
90
|
-
| 57
|
|
32
|
+
| # | Method | Tab? | CDP? | Group | Capability | Notes |
|
|
33
|
+
| --- | ---------------------------------- | ---- | ---- | ----------- | -------------------- | ----------------------------------------------------------------------- |
|
|
34
|
+
| 1 | `access.request` | No | - | system | `-` | Request window access; surfaces Enable prompt in extension UI |
|
|
35
|
+
| 2 | `tabs.list` | No | - | tabs | `-` | Discover available tabs |
|
|
36
|
+
| 3 | `tabs.create` | No | - | tabs | `tabs.manage` | Open a new tab; optional `url` and `active` |
|
|
37
|
+
| 4 | `tabs.close` | No | - | tabs | `tabs.manage` | Close a tab by `tabId` |
|
|
38
|
+
| 5 | `skill.get_runtime_context` | No | - | system | `-` | Live budget presets + method groups |
|
|
39
|
+
| 6 | `setup.get_status` | No | - | system | `-` | Global MCP config + CLI skill install status |
|
|
40
|
+
| 7 | `setup.install` | No | - | system | `-` | Install or uninstall MCP/skill integration targets |
|
|
41
|
+
| 8 | `health.ping` | No | - | system | `-` | Connectivity check + access routing state |
|
|
42
|
+
| 9 | `log.tail` | No | - | system | `-` | Recent bridge logs |
|
|
43
|
+
| 10 | `page.get_state` | Yes | - | page | `page.read` | URL, readiness, focus, scroll, viewport |
|
|
44
|
+
| 11 | `page.evaluate` | Yes | CDP | page | `page.evaluate` | JS expression in page context; last resort |
|
|
45
|
+
| 12 | `page.get_console` | Yes | - | page | `page.read` | Buffered console messages; filter by `level`, `limit` |
|
|
46
|
+
| 13 | `page.wait_for_load_state` | Yes | - | wait | `page.read` | Block until tab `complete`; `timeoutMs` capped 30 s |
|
|
47
|
+
| 14 | `page.get_storage` | Yes | - | page | `page.read` | `localStorage`/`sessionStorage`; optional `keys` |
|
|
48
|
+
| 15 | `page.get_text` | Yes | - | page | `page.read` | Full page text; `textBudget` limits size |
|
|
49
|
+
| 16 | `page.get_network` | Yes | - | page | `network.read` | Intercepted fetch/XHR; `limit` entries |
|
|
50
|
+
| 17 | `navigation.navigate` | Yes | - | navigate | `navigation.control` | Go to URL; `waitForLoad` default true |
|
|
51
|
+
| 18 | `navigation.reload` | Yes | - | navigate | `navigation.control` | Reload; `waitForLoad` default true |
|
|
52
|
+
| 19 | `navigation.go_back` | Yes | - | navigate | `navigation.control` | History back |
|
|
53
|
+
| 20 | `navigation.go_forward` | Yes | - | navigate | `navigation.control` | History forward |
|
|
54
|
+
| 21 | `dom.query` | Yes | - | inspect | `dom.read` | Query subtree with budget constraints |
|
|
55
|
+
| 22 | `dom.describe` | Yes | - | inspect | `dom.read` | Single element details via `elementRef` |
|
|
56
|
+
| 23 | `dom.get_text` | Yes | - | inspect | `dom.read` | Text content with `textBudget` |
|
|
57
|
+
| 24 | `dom.get_attributes` | Yes | - | inspect | `dom.read` | Targeted attribute read |
|
|
58
|
+
| 25 | `dom.wait_for` | Yes | - | wait | `dom.read` | Wait for DOM condition; MutationObserver + polling |
|
|
59
|
+
| 26 | `dom.find_by_text` | Yes | - | inspect | `dom.read` | Find by visible text; returns `{nodes, count}` |
|
|
60
|
+
| 27 | `dom.find_by_role` | Yes | - | inspect | `dom.read` | Find by ARIA role; optional `name` filter |
|
|
61
|
+
| 28 | `dom.get_html` | Yes | - | inspect | `dom.read` | `innerHTML`/`outerHTML`; `maxLength` truncation |
|
|
62
|
+
| 29 | `dom.get_accessibility_tree` | Yes | CDP | inspect | `dom.read` | Full a11y tree; `maxNodes`/`maxDepth` limits |
|
|
63
|
+
| 30 | `layout.get_box_model` | Yes | - | inspect | `layout.read` | Element geometry (no budget needed) |
|
|
64
|
+
| 31 | `layout.hit_test` | Yes | - | inspect | `layout.read` | Element at viewport point |
|
|
65
|
+
| 32 | `styles.get_computed` | Yes | - | inspect | `styles.read` | Computed CSS; always set `properties` |
|
|
66
|
+
| 33 | `styles.get_matched_rules` | Yes | - | inspect | `styles.read` | Matching CSS rules |
|
|
67
|
+
| 34 | `viewport.scroll` | Yes | - | navigate | `viewport.control` | Window or element scroll |
|
|
68
|
+
| 35 | `viewport.resize` | Yes | CDP | navigate | `viewport.control` | Set viewport via device emulation; `reset: true` |
|
|
69
|
+
| 36 | `input.click` | Yes | - | interact | `automation.input` | DOM-level click |
|
|
70
|
+
| 37 | `input.focus` | Yes | - | interact | `automation.input` | Focus element |
|
|
71
|
+
| 38 | `input.type` | Yes | - | interact | `automation.input` | Type into input/textarea/contenteditable |
|
|
72
|
+
| 39 | `input.press_key` | Yes | - | interact | `automation.input` | Single key event |
|
|
73
|
+
| 40 | `input.set_checked` | Yes | - | interact | `automation.input` | Checkbox/radio toggle |
|
|
74
|
+
| 41 | `input.select_option` | Yes | - | interact | `automation.input` | Native select by value/label/index |
|
|
75
|
+
| 42 | `input.hover` | Yes | - | interact | `automation.input` | mouseenter/mouseover/mousemove; optional `duration` |
|
|
76
|
+
| 43 | `input.drag` | Yes | - | interact | `automation.input` | Full drag-and-drop event sequence |
|
|
77
|
+
| 44 | `input.scroll_into_view` | Yes | - | interact | `automation.input` | Explicitly scroll target into view before inspect/capture |
|
|
78
|
+
| 45 | `screenshot.capture_element` | Yes | CDP | capture | `screenshot.partial` | Cropped element screenshot |
|
|
79
|
+
| 46 | `screenshot.capture_region` | Yes | CDP | capture | `screenshot.partial` | Cropped viewport region |
|
|
80
|
+
| 47 | `screenshot.capture_full_page` | Yes | CDP | capture | `screenshot.partial` | Full document screenshot; use only when page-level context is necessary |
|
|
81
|
+
| 48 | `patch.apply_styles` | Yes | - | patch | `patch.styles` | Reversible CSS patch; `verify` returns computed result |
|
|
82
|
+
| 49 | `patch.apply_dom` | Yes | - | patch | `patch.dom` | Reversible DOM mutation; `verify` returns result |
|
|
83
|
+
| 50 | `patch.list` | Yes | - | patch | `patch.dom` | Active patches |
|
|
84
|
+
| 51 | `patch.rollback` | Yes | - | patch | `patch.dom` | Revert one patch |
|
|
85
|
+
| 52 | `patch.commit_session_baseline` | Yes | - | patch | `patch.dom` | Accept current state as baseline |
|
|
86
|
+
| 53 | `performance.get_metrics` | Yes | CDP | performance | `performance.read` | Chrome performance counters |
|
|
87
|
+
| 54 | `cdp.get_document` | Yes | CDP | cdp | `cdp.dom_snapshot` | DevTools document tree |
|
|
88
|
+
| 55 | `cdp.get_dom_snapshot` | Yes | CDP | cdp | `cdp.dom_snapshot` | DevTools DOM snapshot |
|
|
89
|
+
| 56 | `cdp.get_box_model` | Yes | CDP | cdp | `cdp.box_model` | DevTools-backed element geometry |
|
|
90
|
+
| 57 | `cdp.get_computed_styles_for_node` | Yes | CDP | cdp | `cdp.styles` | DevTools-backed computed styles |
|
|
91
91
|
|
|
92
92
|
## CLI
|
|
93
93
|
|
|
@@ -105,19 +105,24 @@ Newer bridge methods such as `input.scroll_into_view` and `screenshot.capture_fu
|
|
|
105
105
|
## Method Details
|
|
106
106
|
|
|
107
107
|
### access.request
|
|
108
|
+
|
|
108
109
|
Request Browser Bridge access for the focused browser window. Surfaces an Enable prompt in the extension popup or side panel so the user can grant access. Does not require an existing session.
|
|
110
|
+
|
|
109
111
|
```bash
|
|
110
112
|
bbx access-request
|
|
111
113
|
bbx call access.request
|
|
112
114
|
```
|
|
115
|
+
|
|
113
116
|
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.
|
|
114
117
|
|
|
115
118
|
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.
|
|
116
119
|
|
|
117
120
|
### page.evaluate
|
|
121
|
+
|
|
118
122
|
Run a JS expression in the page context via CDP `Runtime.evaluate`. Expression is evaluated as a statement and the return value is serialized. Supports `awaitPromise` for async expressions.
|
|
119
123
|
|
|
120
124
|
Use only when non-debugger reads are insufficient. Prefer `page.get_storage`, `page.get_text`, `page.get_console`, `page.get_network`, or DOM methods first.
|
|
125
|
+
|
|
121
126
|
```bash
|
|
122
127
|
bbx eval 'document.title'
|
|
123
128
|
bbx eval 'window.__NEXT_DATA__.props'
|
|
@@ -125,22 +130,29 @@ bbx call page.evaluate '{"expression":"await fetch(\"/api/health\").then(r=>r.js
|
|
|
125
130
|
```
|
|
126
131
|
|
|
127
132
|
### page.get_console
|
|
133
|
+
|
|
128
134
|
Read buffered console output. The console interceptor is auto-installed on first call. Captures `log`, `warn`, `error`, `info`, `debug` plus uncaught exceptions and unhandled rejections.
|
|
135
|
+
|
|
129
136
|
```bash
|
|
130
137
|
bbx console # all levels
|
|
131
138
|
bbx console error # errors only
|
|
132
139
|
bbx call page.get_console '{"level":"error","limit":20,"clear":true}'
|
|
133
140
|
```
|
|
141
|
+
|
|
134
142
|
Responses include `dropped` when older buffered entries were discarded on noisy pages.
|
|
135
143
|
|
|
136
144
|
### page.wait_for_load_state
|
|
145
|
+
|
|
137
146
|
Block until the tab reaches `complete` status. Useful after `input.click` on a navigation link.
|
|
147
|
+
|
|
138
148
|
```bash
|
|
139
149
|
bbx call page.wait_for_load_state '{"timeoutMs":10000}'
|
|
140
150
|
```
|
|
141
151
|
|
|
142
152
|
### page.get_storage
|
|
153
|
+
|
|
143
154
|
Read `localStorage` or `sessionStorage` entries. Values truncated at 500 chars each.
|
|
155
|
+
|
|
144
156
|
```bash
|
|
145
157
|
bbx storage # all localStorage
|
|
146
158
|
bbx storage session token,user # specific sessionStorage keys
|
|
@@ -148,67 +160,87 @@ bbx call page.get_storage '{"type":"session","keys":["token"]}'
|
|
|
148
160
|
```
|
|
149
161
|
|
|
150
162
|
### dom.query
|
|
163
|
+
|
|
151
164
|
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.
|
|
165
|
+
|
|
152
166
|
```bash
|
|
153
167
|
bbx dom-query main
|
|
154
168
|
bbx call dom.query '{"selector":"main","maxNodes":10,"attributeAllowlist":["class","data-testid"]}'
|
|
155
169
|
```
|
|
170
|
+
|
|
156
171
|
If `_registryPruned` is true, refresh previously cached refs before reusing them.
|
|
157
172
|
|
|
158
173
|
### dom.wait_for
|
|
174
|
+
|
|
159
175
|
Wait for a DOM condition using MutationObserver + 250 ms polling fallback. Returns `{found, elementRef, duration}`.
|
|
176
|
+
|
|
160
177
|
- `state`: `attached` (default), `detached`, `visible`, `hidden`
|
|
161
178
|
- `text`: optional text content filter
|
|
162
179
|
- `timeoutMs`: 100–30000 (default 5000)
|
|
180
|
+
|
|
163
181
|
```bash
|
|
164
182
|
bbx wait '.toast-success' 5000
|
|
165
183
|
bbx call dom.wait_for '{"selector":".modal","state":"visible","timeoutMs":10000}'
|
|
166
184
|
```
|
|
167
185
|
|
|
168
186
|
### dom.find_by_text
|
|
187
|
+
|
|
169
188
|
Find elements matching visible text content. Like Playwright's `getByText`.
|
|
189
|
+
|
|
170
190
|
```bash
|
|
171
191
|
bbx find 'Submit Order'
|
|
172
192
|
bbx call dom.find_by_text '{"text":"Submit","scope":"button","exact":false}'
|
|
173
193
|
```
|
|
174
194
|
|
|
175
195
|
### dom.find_by_role
|
|
196
|
+
|
|
176
197
|
Find elements by ARIA role (explicit `role` attribute or implicit from HTML tag). Covers 25+ implicit role mappings.
|
|
198
|
+
|
|
177
199
|
```bash
|
|
178
200
|
bbx find-role button 'Save'
|
|
179
201
|
bbx call dom.find_by_role '{"role":"navigation"}'
|
|
180
202
|
```
|
|
181
203
|
|
|
182
204
|
### dom.get_html
|
|
205
|
+
|
|
183
206
|
Get raw HTML of an element. Defaults to `innerHTML`; set `outer: true` for `outerHTML`.
|
|
207
|
+
|
|
184
208
|
```bash
|
|
185
209
|
bbx html el_abc123
|
|
186
210
|
bbx call dom.get_html '{"elementRef":"el_abc123","outer":true,"maxLength":2000}'
|
|
187
211
|
```
|
|
188
212
|
|
|
189
213
|
### input.hover
|
|
214
|
+
|
|
190
215
|
Trigger CSS `:hover` state by dispatching `mouseenter`, `mouseover`, `mousemove`. Optional `duration` to hold hover before auto-releasing.
|
|
216
|
+
|
|
191
217
|
```bash
|
|
192
218
|
bbx hover el_abc123
|
|
193
219
|
bbx call input.hover '{"target":{"elementRef":"el_abc123"},"duration":1000}'
|
|
194
220
|
```
|
|
195
221
|
|
|
196
222
|
### input.drag
|
|
223
|
+
|
|
197
224
|
Full drag-and-drop sequence: `mousedown → dragstart → drag → dragenter → dragover → drop → dragend → mouseup`. Accepts source target, destination target, and optional pixel offsets.
|
|
225
|
+
|
|
198
226
|
```bash
|
|
199
227
|
bbx call input.drag '{"source":{"elementRef":"el_src"},"destination":{"elementRef":"el_dst"}}'
|
|
200
228
|
bbx call input.drag '{"source":{"elementRef":"el_src"},"destination":{"elementRef":"el_dst"},"sourceOffset":{"x":10,"y":10}}'
|
|
201
229
|
```
|
|
202
230
|
|
|
203
231
|
### input.scroll_into_view
|
|
232
|
+
|
|
204
233
|
Explicitly scroll an element into the visible viewport before inspecting, hovering, or capturing it.
|
|
234
|
+
|
|
205
235
|
```bash
|
|
206
236
|
bbx call input.scroll_into_view '{"target":{"elementRef":"el_abc123"}}'
|
|
207
237
|
bbx call input.scroll_into_view '{"target":{"selector":"[data-testid=\\"checkout-summary\\"]"}}'
|
|
208
238
|
```
|
|
209
239
|
|
|
210
240
|
### tabs.create
|
|
241
|
+
|
|
211
242
|
Open a new browser tab. Optional `url` (defaults to `about:blank`) and `active` flag (defaults to `true`). Does not require a session.
|
|
243
|
+
|
|
212
244
|
```bash
|
|
213
245
|
bbx tab-create https://example.com
|
|
214
246
|
bbx call tabs.create '{"url":"https://example.com","active":false}'
|
|
@@ -217,20 +249,26 @@ bbx call tabs.create '{"url":"https://example.com","active":false}'
|
|
|
217
249
|
The `bbx tab-create` shortcut intentionally covers the common case. Use `bbx call tabs.create ...` when you need advanced fields such as `active:false`.
|
|
218
250
|
|
|
219
251
|
### setup.get_status
|
|
252
|
+
|
|
220
253
|
Inspect the host-side Browser Bridge setup. Returns global MCP config status for supported clients and global CLI skill install status for supported targets.
|
|
254
|
+
|
|
221
255
|
```bash
|
|
222
256
|
bbx call setup.get_status
|
|
223
257
|
```
|
|
224
258
|
|
|
225
259
|
### tabs.close
|
|
260
|
+
|
|
226
261
|
Close a tab by its `tabId`. Does not require a session.
|
|
262
|
+
|
|
227
263
|
```bash
|
|
228
264
|
bbx tab-close 12345
|
|
229
265
|
bbx call tabs.close '{"tabId":12345}'
|
|
230
266
|
```
|
|
231
267
|
|
|
232
268
|
### page.get_text
|
|
269
|
+
|
|
233
270
|
Extract the full visible text content of the page (`document.body.innerText`). Truncated to `textBudget` (default 8000 chars). Lighter than `dom.query` on `body` when you only need text.
|
|
271
|
+
|
|
234
272
|
```bash
|
|
235
273
|
bbx page-text
|
|
236
274
|
bbx page-text 8000
|
|
@@ -238,18 +276,23 @@ bbx call page.get_text '{"textBudget":2000}'
|
|
|
238
276
|
```
|
|
239
277
|
|
|
240
278
|
### page.get_network
|
|
279
|
+
|
|
241
280
|
Read intercepted fetch/XHR requests. The interceptor is auto-installed on first call (via MAIN world script). Returns `{entries, count}` sorted newest-first.
|
|
281
|
+
|
|
242
282
|
```bash
|
|
243
283
|
bbx network
|
|
244
284
|
bbx network 50
|
|
245
285
|
bbx call page.get_network '{"limit":20,"clear":true}'
|
|
246
286
|
```
|
|
287
|
+
|
|
247
288
|
Each entry: `{method, url, status, duration, initiator}`. Responses include `dropped` when older buffered entries were discarded.
|
|
248
289
|
|
|
249
290
|
### dom.get_accessibility_tree
|
|
291
|
+
|
|
250
292
|
Retrieve the page's accessibility tree via CDP `Accessibility.getFullAXTree`. Each node is simplified to: `role`, `name`, `description`, `value`, `focused`, `required`, `checked`, `disabled`, `interactive`, `childIds`. Use `maxNodes` and `maxDepth` to control size.
|
|
251
293
|
|
|
252
294
|
This is debugger-backed. Prefer `dom.find_by_role`, `dom.find_by_text`, and targeted `dom.query`/`dom.describe` first.
|
|
295
|
+
|
|
253
296
|
```bash
|
|
254
297
|
bbx a11y-tree
|
|
255
298
|
bbx a11y-tree 50 3
|
|
@@ -257,9 +300,11 @@ bbx call dom.get_accessibility_tree '{"maxNodes":100,"maxDepth":5}'
|
|
|
257
300
|
```
|
|
258
301
|
|
|
259
302
|
### viewport.resize
|
|
303
|
+
|
|
260
304
|
Set the browser viewport to specific dimensions using CDP device emulation. Pass `reset: true` to clear the override.
|
|
261
305
|
|
|
262
306
|
Debugger-backed. Use only when an exact viewport override is required for responsive verification.
|
|
307
|
+
|
|
263
308
|
```bash
|
|
264
309
|
bbx resize 375 812
|
|
265
310
|
bbx call viewport.resize '{"width":1024,"height":768}'
|
|
@@ -267,16 +312,20 @@ bbx call viewport.resize '{"reset":true}'
|
|
|
267
312
|
```
|
|
268
313
|
|
|
269
314
|
### performance.get_metrics
|
|
315
|
+
|
|
270
316
|
Read Chrome performance counters via CDP `Performance.getMetrics`. Returns a flat `{metrics}` object with keys like `JSHeapUsedSize`, `LayoutCount`, `TaskDuration`, etc.
|
|
271
317
|
|
|
272
318
|
Debugger-backed. Use after lighter reads fail to explain a performance symptom.
|
|
319
|
+
|
|
273
320
|
```bash
|
|
274
321
|
bbx perf
|
|
275
322
|
bbx call performance.get_metrics
|
|
276
323
|
```
|
|
277
324
|
|
|
278
325
|
### screenshot.capture_full_page
|
|
326
|
+
|
|
279
327
|
Capture a full-document screenshot beyond the current viewport. Use only when element or tight region captures cannot express the issue. Chrome capture limits still apply on very large pages.
|
|
328
|
+
|
|
280
329
|
```bash
|
|
281
330
|
bbx call screenshot.capture_full_page '{}'
|
|
282
331
|
```
|
|
@@ -284,21 +333,27 @@ bbx call screenshot.capture_full_page '{}'
|
|
|
284
333
|
## Request Envelope
|
|
285
334
|
|
|
286
335
|
```json
|
|
287
|
-
{
|
|
336
|
+
{
|
|
337
|
+
"id": "req_1",
|
|
338
|
+
"tab_id": 123,
|
|
339
|
+
"method": "dom.query",
|
|
340
|
+
"params": {},
|
|
341
|
+
"meta": { "protocol_version": "1.0", "token_budget": 1200 }
|
|
342
|
+
}
|
|
288
343
|
```
|
|
289
344
|
|
|
290
345
|
## Error Codes
|
|
291
346
|
|
|
292
|
-
| Code
|
|
293
|
-
|
|
294
|
-
| `ACCESS_DENIED`
|
|
295
|
-
| `TAB_MISMATCH`
|
|
296
|
-
| `ELEMENT_STALE`
|
|
297
|
-
| `CONTENT_SCRIPT_UNAVAILABLE` | Page is restricted (chrome://, extensions, etc.)
|
|
298
|
-
| `NATIVE_HOST_UNAVAILABLE`
|
|
299
|
-
| `EXTENSION_DISCONNECTED`
|
|
300
|
-
| `TIMEOUT`
|
|
301
|
-
| `RATE_LIMITED`
|
|
347
|
+
| Code | Action | Recovery |
|
|
348
|
+
| ---------------------------- | -------------------------------------------------------------- | -------------------------------------------- |
|
|
349
|
+
| `ACCESS_DENIED` | Turn on Browser Bridge for the target window | `retry: false` |
|
|
350
|
+
| `TAB_MISMATCH` | Explicit `tabId` is missing, closed, or outside enabled window | `retry: false`, use `tabs.list` |
|
|
351
|
+
| `ELEMENT_STALE` | Re-query DOM for fresh `elementRef` | `retry: false`, use `dom.query` |
|
|
352
|
+
| `CONTENT_SCRIPT_UNAVAILABLE` | Page is restricted (chrome://, extensions, etc.) | `retry: false` |
|
|
353
|
+
| `NATIVE_HOST_UNAVAILABLE` | Check daemon: `bbx status` | `retry: false` |
|
|
354
|
+
| `EXTENSION_DISCONNECTED` | Extension not connected to daemon | `retry: true` after 3 s, check `health.ping` |
|
|
355
|
+
| `TIMEOUT` | Wait/evaluate exceeded `timeoutMs` | `retry: true` after 1 s |
|
|
356
|
+
| `RATE_LIMITED` | Too many requests | `retry: true` after 2 s |
|
|
302
357
|
|
|
303
358
|
Timeout on content-script request → use narrower `dom.query` or CDP fallback.
|
|
304
359
|
Timeout on navigation → increase `timeoutMs`, set `waitForLoad:false`, or check `page.get_state`.
|