@browserbridge/bbx 1.11.5 → 1.12.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/package.json +3 -1
- package/packages/agent-client/src/client.js +18 -1
- package/packages/agent-client/src/types.ts +2 -0
- package/packages/mcp-server/src/handlers-capture.js +17 -7
- package/packages/mcp-server/src/handlers-dom.js +6 -1
- package/packages/mcp-server/src/handlers-utils.js +3 -0
- package/packages/mcp-server/src/server.js +49 -2
- package/packages/protocol/src/protocol.js +146 -15
- package/packages/protocol/src/registry.js +8 -6
- package/packages/protocol/src/summary.js +184 -32
- package/packages/protocol/src/types.ts +58 -7
- package/skills/browser-bridge/SKILL.md +18 -12
- package/skills/browser-bridge/references/interaction.md +12 -16
- package/skills/browser-bridge/references/protocol.md +16 -6
- package/skills/browser-bridge/references/token-efficiency.md +12 -6
|
@@ -78,7 +78,7 @@ omit both for the group index.
|
|
|
78
78
|
| `dom.find_by_text` | Yes | - | inspect | `dom.read` | Find by visible text; returns `{nodes, count}` |
|
|
79
79
|
| `dom.find_by_role` | Yes | - | inspect | `dom.read` | Find by ARIA role; optional `name` filter |
|
|
80
80
|
| `dom.get_html` | Yes | - | inspect | `dom.read` | `innerHTML`/`outerHTML`; `maxLength` truncation |
|
|
81
|
-
| `dom.get_accessibility_tree` | Yes | CDP
|
|
81
|
+
| `dom.get_accessibility_tree` | Yes | CDP / none | inspect | `dom.read` | AX tree (CDP) or `source: "dom"` actionable outline with refs, no debugger |
|
|
82
82
|
| `layout.get_box_model` | Yes | - | inspect | `layout.read` | Element geometry |
|
|
83
83
|
| `layout.hit_test` | Yes | - | inspect | `layout.read` | Topmost element at viewport point |
|
|
84
84
|
| `styles.get_computed` | Yes | - | inspect | `styles.read` | Requested properties; omission returns display/position/width/height/color |
|
|
@@ -263,7 +263,7 @@ bbx call dom.wait_for '{"selector":".modal","state":"visible","timeoutMs":10000}
|
|
|
263
263
|
|
|
264
264
|
### dom.find_by_text
|
|
265
265
|
|
|
266
|
-
Find elements matching visible text content. Like Playwright's `getByText
|
|
266
|
+
Find elements matching visible text content. Like Playwright's `getByText`: own text and text-like attributes match first, otherwise the innermost element whose combined text matches (so `<button><b>Place</b> order</button>` matches "Place order" on the button). `script`/`style`/`template` content never matches. Searches open and closed shadow roots and, when the top document has no match, child iframes (nodes then carry `frameId`). Hidden matches are omitted and counted in `hiddenMatches`; pass `includeHidden: true` to list them (marked `visible: false`).
|
|
267
267
|
|
|
268
268
|
```bash
|
|
269
269
|
bbx find 'Submit Order'
|
|
@@ -272,7 +272,7 @@ bbx call dom.find_by_text '{"text":"Submit","selector":"button","exact":false}'
|
|
|
272
272
|
|
|
273
273
|
### dom.find_by_role
|
|
274
274
|
|
|
275
|
-
Find elements by ARIA role (explicit `role` attribute or implicit from HTML tag).
|
|
275
|
+
Find elements by ARIA role (explicit `role` attribute or implicit from HTML tag) and accessible name. Names come from `aria-labelledby`, `aria-label`, associated `<label for>` or wrapping `<label>`, `alt`, button values, content for name-from-content roles, `title`, then `placeholder`. A single `<select>` matches `combobox` and `listbox`; number inputs match `spinbutton` and `textbox`. `exact: true` requires the whole name. Same shadow DOM, iframe, and hidden-match behavior as `dom.find_by_text`. Results include the computed `role` and `name`.
|
|
276
276
|
|
|
277
277
|
```bash
|
|
278
278
|
bbx find-role button 'Save'
|
|
@@ -294,9 +294,13 @@ When `properties` is omitted, `styles.get_computed` returns exactly `display`, `
|
|
|
294
294
|
|
|
295
295
|
### Actionable input targets
|
|
296
296
|
|
|
297
|
+
Targets are `{ elementRef }`, `{ selector }`, or a semantic locator: `role` (+ `name`), `text`, `label`, `placeholder`, or `testId` (`data-testid`, `data-test-id`, `data-test`, `data-qa`), with optional `exact`, `nth` (pick among visible matches), and `selector` (narrows locator candidates). Selectors and locators reach into shadow roots; when the top document has no match, child iframes are probed and the action runs in the frame that has it (refs remember their frame).
|
|
298
|
+
|
|
299
|
+
Before dispatch, targeted actions wait up to `timeoutMs` (default 2500, max 15000; `0` disables) while the target is missing, not actionable, obscured, or still animating; `resolution.waitedMs` reports the wait. Click, press_key, set_checked, select_option, and type/fill with `submit` then observe for up to `observe.settleMs` (default 500) until the DOM is quiet for 150ms and return `effects`: `url` (same-document change), `navigation: "unloading"`, `title`, newly visible `dialogs` (`role`, `name`, `ref`), `messages` from alert/status/live regions, `focused`, `dom` (`added`/`removed`), `target` state (`value`, `checked`, `expanded`, `selected`, `pressed`, `disabled`, or `removed`), `changed`, and `settledMs`. Pass `observe: true` to other actions or `observe: false` to skip. Steps inside `input.perform` observe only on request.
|
|
300
|
+
|
|
297
301
|
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.
|
|
298
302
|
|
|
299
|
-
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
|
|
303
|
+
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: `dom` (default), `cdp`, or `auto`. `auto` uses CDP only when the debugger is already attached to the tab or the target likely needs trusted input (file input, media, `target=_blank` link, rich-text editor), and reports `execution.selectionReason`. It never retries an action through a second path. CDP is not available for targets inside iframes (`INPUT_UNSUPPORTED`); `auto` stays on DOM there. CDP is supported by click, hover, drag, type, fill, press_key, and touch; unsupported combinations return `INPUT_UNSUPPORTED` instead of falling back silently. DOM events mirror real device event order (pointer events, boundary transitions, `code`/`keyCode`) but are untrusted, so Chrome may refuse gesture-gated features such as audio/media start; use CDP for those.
|
|
300
304
|
|
|
301
305
|
`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"`.
|
|
302
306
|
|
|
@@ -462,7 +466,13 @@ artifact, and atomically write the output on the CLI host.
|
|
|
462
466
|
|
|
463
467
|
### dom.get_accessibility_tree
|
|
464
468
|
|
|
465
|
-
|
|
469
|
+
`source: "dom"` builds an actionable outline in the content script, with no debugger. It covers visible interactive controls (plus headings, landmarks, dialogs, alerts, and named regions unless `interactiveOnly: true`) across shadow roots and iframes. Each line looks like `- button "Save" [el_k7q2_1f] disabled`, and states include `checked`, `expanded`/`collapsed`, `selected`, `pressed`, `required`, `focused`, `level=N`, and `value="…"` (never for passwords). Refs work directly as input targets. `format: "tree"` returns the same entries as `nodes`. `maxNodes` bounds it (default 150).
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
bbx call dom.get_accessibility_tree '{"source":"dom","interactiveOnly":true}'
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
The default `source: "cdp"` retrieves a depth-limited accessibility tree via CDP. Full reads use `Accessibility.getFullAXTree`; an optional unique `selector` resolves through CDP DOM methods, starts with `Accessibility.getPartialAXTree`, and incrementally fetches selected descendant layers with `Accessibility.getChildAXNodes`. Only the selected subtree and required ancestor chain are retained. 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.
|
|
466
476
|
|
|
467
477
|
This is debugger-backed. Prefer `dom.find_by_role`, `dom.find_by_text`, and targeted `dom.query`/`dom.describe` first.
|
|
468
478
|
|
|
@@ -474,7 +484,7 @@ bbx call dom.get_accessibility_tree '{"maxNodes":100,"maxDepth":6,"interactiveOn
|
|
|
474
484
|
bbx call dom.get_accessibility_tree '{"selector":"[role=dialog]","maxNodes":50,"compact":true}'
|
|
475
485
|
```
|
|
476
486
|
|
|
477
|
-
Filtering occurs before `maxNodes`. Compact mode drops ignored, decorative, and empty nodes while reconnecting retained descendants; interactive-only keeps non-ignored semantic interactive roles. Full reads ask CDP for the requested depth, while selector-scoped reads fetch descendant layers up to that same bound.
|
|
487
|
+
Filtering occurs before `maxNodes`. Compact mode drops ignored, decorative, and empty nodes while reconnecting retained descendants; interactive-only keeps non-ignored semantic interactive roles. Full reads ask CDP for the requested depth, while selector-scoped reads fetch descendant layers up to that same bound. `truncated` and `partialTopology` are true only when `maxNodes` cut nodes or the depth bound left children unfetched (`missingChildCount`), and only then is a continuation hint returned. `format: "outline"` renders CDP nodes as compact lines. CDP AX nodes carry no element refs; use `source: "dom"` (or a role/name locator) to act on them.
|
|
478
488
|
|
|
479
489
|
### viewport.resize
|
|
480
490
|
|
|
@@ -61,13 +61,15 @@ Omitting allowlists or leaving the text budget wide open often returns 3–5× t
|
|
|
61
61
|
| Full-page screenshot | ~3000 tok | Use `screenshot.capture_element`, or `screenshot.capture_region` with a tight rect |
|
|
62
62
|
| Requesting broad computed styles via CDP | ~800 tok | Use `styles.get_computed`; omission returns five core props, or pass 3-8 explicit props |
|
|
63
63
|
| Multiple CLI calls for independent reads | overhead/call | Use `batch` command |
|
|
64
|
-
| Guessing selectors for known labels | ~300 tok wasted/try |
|
|
64
|
+
| Guessing selectors for known labels | ~300 tok wasted/try | Put a locator in the input target (`{"role":"button","name":"Save"}`, `{"label":"Email"}`) |
|
|
65
|
+
| Find, then act, then re-read | 3 round trips | One locator-targeted action; read its `effects` instead of re-querying |
|
|
66
|
+
| `dom.wait_for` before every action | 1 extra round trip | Actions auto-wait (`timeoutMs`, default 2500) |
|
|
65
67
|
| Polling page state with repeated queries | ~500 tok/poll | Use `dom.wait_for` (single call, waits async) |
|
|
66
68
|
| Inspecting DOM to read app state | ~800 tok | Use `page.evaluate` to read JS directly |
|
|
67
69
|
| Re-querying after HMR without waiting | ~500 tok stale | `dom.wait_for` first, then query |
|
|
68
70
|
| Separate call to verify a patch | ~500 tok wasted | Set `verify: true` on `patch.apply_styles` / `patch.apply_dom` to get computed result inline |
|
|
69
71
|
| `dom.query` on body for page text | ~2000 tok | Use `page.get_text` (extracts innerText directly) |
|
|
70
|
-
| Guessing interactive elements from DOM | ~600 tok/try |
|
|
72
|
+
| Guessing interactive elements from DOM | ~600 tok/try | `dom.get_accessibility_tree` with `source: "dom"`: ~10 tokens per control, refs included |
|
|
71
73
|
| Fetching network via evaluate hacks | ~400 tok | Use `page.get_network` (auto-interceptor) |
|
|
72
74
|
| Full a11y tree with no limits | ~3000 tok | Set `maxNodes` ≤ 50, `maxDepth` ≤ 4 |
|
|
73
75
|
| CDP network capture for API-only traffic | debugger lifecycle | Use default fetch/XHR capture; reserve CDP for all-resource failures |
|
|
@@ -143,15 +145,19 @@ for larger evidence. The five-minute opaque handle is owner-scoped and has no
|
|
|
143
145
|
browser-host path; `bbx har` downloads, verifies, deletes, and atomically writes
|
|
144
146
|
it on the CLI host through the same client.
|
|
145
147
|
|
|
146
|
-
## Accessibility
|
|
148
|
+
## Accessibility Outline for Semantic Discovery
|
|
147
149
|
|
|
148
|
-
When you need
|
|
150
|
+
When you need the page's interactive structure without guessing selectors:
|
|
149
151
|
|
|
150
152
|
```bash
|
|
151
|
-
bbx call dom.get_accessibility_tree '{"
|
|
153
|
+
bbx call dom.get_accessibility_tree '{"source":"dom","interactiveOnly":true,"maxNodes":60}'
|
|
152
154
|
```
|
|
153
155
|
|
|
154
|
-
|
|
156
|
+
Each control is one line (`- button "Save" [el_k7q2_1f]`, about 10 tokens versus about 80 for a JSON AX node), refs act directly, and no debugger is attached. The CDP tree (`source` omitted) is for audits; add `format: "outline"` to keep it compact.
|
|
157
|
+
|
|
158
|
+
## Act, Then Read Effects
|
|
159
|
+
|
|
160
|
+
Input actions return what changed (`effects`: URL, dialogs, alerts/status text, focus, DOM churn, target state), and the summary digests it in one line. Routine successes omit resolution/execution metadata; it appears only when something notable happened (scroll, wait, ranking, stale recovery, CDP). Element refs are short (`el_k7q2_1f`). Re-read the page only when the effects leave the question open.
|
|
155
161
|
|
|
156
162
|
## Semantic finding Saves Selector Guessing
|
|
157
163
|
|