Skill v1.0.0
currentAutomated scan100/100version: "1.0.0" name: browser-macros description: Use when a browser task resembles a repeated flow or a reusable browser script may already cover the requested result
Browser Macros
Use indexed Playwright macros instead of re-deriving known browser flows.
Flows before macros
Compiled flows are checked before hand-written macros: run fast-browser flows find --intent "<task>" --origin <origin> --json, and if a candidate scores runnable: true, run it instead of reaching for a macro. See fast-browsing's task graph and its ### Runnable candidate? section for the full contract.
fast-browser flows approve <name> is the one consent gate for a mutating or js-step flow. It is separate from, and does not change, the per-macro approval below: a mined macro still requires the user's explicit approval for that individual macro.
The ## flow-runner entry in ~/.fast-browser/macros/MACROS.md documents the replay contract itself: the success shape, the FLOW_RUNNER_FAILURE: error shape, and the distinct SIDECAR_LOST: error shape for a lost browser connection.
Recording a quirk with fast-browser sites quirk add also feeds live interrupt recovery: a flow replay tries that recorded click once per step, only after its full locator walk has missed.
Run a macro
- Read
~/.fast-browser/macros/MACROS.md. - Match the task to an entry's description and target.
- Call
browser_run_code_unsafewithfilenameset to the entry'sScript:
path as an absolute path, your home directory written out in full, and the entry's args exactly. The runtime expands nothing: a bare or ~ name resolves against the browser server's own working directory and is refused by its containment check (ENOENT or "outside allowed roots"). Do not open the script and do not substitute inline code.
- Return the macro's distilled result.
If the macro fails, use its { failedStep, error, url } result to retry materially. After the same macro fails twice, append:
<macro-name> | <date> | <failedStep or reason>
to ~/.fast-browser/macro-failures.md, then switch to fast-browsing recovery. Do not keep repeating the macro.
Prefer the affordances digest to a snapshot
On an unfamiliar page the matching entry is usually page-affordances. It returns the page's visible fields, buttons, links and landmarks with a selector for each, which is enough to act on, where page-recon only says what the page is. Reach for browser_snapshot only after the digest comes back without the control you need: a full accessibility tree costs roughly 5k to 35k tokens and stays in context for the rest of the session.
The digest is partial on purpose. Nothing appears in it that could not be both labelled and addressed, and everything refused is counted in skipped as { list, reason, count }. Read those counts before concluding a control is absent, and never invent a selector for something the macro declined to address.
After a page-affordances run on a page worth remembering, pipe its JSON to fast-browser sites digest --url <url> on stdin. A later fast-browser sites affordances --url <url> --json call then returns that saved digest as a warm start instead of a cold page-affordances run, until it expires: the default TTL is 72 hours (three days), overridable with --ttl-hours.
Authoring contract
- Store scripts in
~/.fast-browser/macros/and use that stable path in the
index.
- Export an expression with signature
async (page, args) => result. - Merge optional arguments with defaults and return
{ failedStep: 'args', error: '<missing input>' } for missing required arguments.
- Wait for observable conditions inside the script.
- Catch each logical step and return
{ failedStep, error, url: page.url() }
on failure.
- Return a small value that proves completion.
Built-ins use Status: built-in. A mined user macro requires the user's explicit approval for that individual macro before writing its script or index entry. Never infer approval from usefulness, prior approval of another macro, or successful verification.
Quick reference
| Result | Next action | |
|---|---|---|
| Exact index match | Run its script path (home written out in full) plus args | |
| Unfamiliar page | page-affordances, not browser_snapshot | |
| Control missing from the digest | Read skipped, then snapshot | |
| Success | Return the distilled value | |
| First failure | Retry materially using failure context | |
| Second failure | Log it and use fast-browsing | |
| New mined macro | Wait for explicit per-macro approval |