Reflex Browser Skill
Purpose
Use this skill when the task involves a website or browser: navigating pages, clicking elements, reading content, filling forms, scraping data, or automating a web flow.
This skill covers interactive browser work via reflex browser ... CLI commands. Each command is a single stateless action — run one, inspect the JSON response, then decide the next step.
When the end goal is a reusable Lua or Python browser automation script, still start here first: use reflex browser ... to inspect the site, verify the flow, and stabilize selectors before writing script code. Then switch to the reflex-scripting skill for the script itself.
When To Use This Skill
- User asks to interact with a website (navigate, click, fill, read, scrape)
- User asks to inspect or explore a page
- User asks for browser-based data collection
- User asks whether a page, modal, overlay, or layout looks correct
- User asks for a browser automation script (start here for discovery, then
reflex-scripting for the script)
When NOT To Use This Skill
- One-off file manipulation (xlsx, csv, json) without a browser → use
reflex-scripting
- REST API calls → use
reflex-scripting
- Data transforms or batch processing without a browser → use
reflex-scripting
- Writing a script after browser discovery is done → use
reflex-scripting
Quick Start
- Install globally from Gitea npm:
npm config set @reflexautomation:registry "https://git.bqa-solutions.nl/api/packages/reflex/npm/" --location=user
npm config set "//git.bqa-solutions.nl/api/packages/reflex/npm/:_authToken" "YOUR_DEPLOY_TOKEN" --location=user
npm install -g @reflexautomation/reflex-cli
- Start or reuse a session:
- Default to auto-session mode for normal agent runs:
- do not pass
--session on follow-up commands
- example:
reflex browser open https://example.com
- Use explicit
--session only for deterministic override:
- example:
reflex browser open https://example.com --session <sessionId>
- End with
reflex browser session-kill in auto-session mode.
- if you used an explicit session id, use
reflex browser session-kill --session <sessionId> (or reflex browser session-kill <sessionId>)
Use the CLI itself as the command/protocol source of truth:
reflex browser --help
reflex browser help --json
Agent Defaults
- Do not pass
--session by habit after start; normal flows should stay in scoped auto-session mode.
- Start on the target page, not on broad capability audits; do not inventory libraries or call repeated help commands unless a concrete next step needs exact syntax.
- Prefer
summary first and fine-tune it (-i -c, then -s, -C, -d) for selector discovery and recovery before trying eval or html; treat html as last-resort evidence, not normal recovery. Start with count 20; increase only when the page has many repeated items.
- Use
summary --state --screenshot when selector recovery or page review needs visual evidence; keep screenshots opt-in instead of adding them to every pass.
- Use
reflex browser help --json for exact command/response/schema details instead of duplicating those rules here.
Discovery Before Capability Audits (Required)
- For normal tasks, start with the target page:
start -> open -> summary.
- Do not begin with broad audits such as
reflex lua libs, repeated help calls, external doc hunts, or speculative output-format work.
- Check exact command/library help only when you have a concrete next step that requires it.
- Once a browser command succeeds, continue the task instead of re-checking availability.
Agent Availability And Recovery (Required)
- Before assuming browser commands are broken, verify the local agent is available.
- If a browser command fails with a transport/connect error, use this recovery order:
reflex agent status
- if not running,
reflex agent start
- if the agent jar is missing,
reflex agent download
- if Java is missing or incompatible,
reflex agent runtime install
- retry the original browser command after recovery
- Prefer the CLI's own guidance text when it suggests
reflex agent start or reflex agent download.
- For local development tasks, the AI agent may run
reflex agent ... commands directly instead of only telling the human what to do.
- If the environment is clearly non-local, remote, or permission-sensitive, explain the exact
reflex agent ... command the human should run.
- Do not start multiple background agents on different ports unless the task explicitly requires it.
Recommended recovery flow:
reflex agent status
reflex agent start
reflex agent download
reflex agent runtime install
Command Lifecycle (Required)
- Send actions as separate CLI invocations.
- Do not chain browser commands with
&&, long shell pipelines, or opaque wrappers.
- Keep one logical session context for the task (auto-session by default).
- Default rule: omit
--session on commands unless explicit override is required.
- Execute sequentially: run one command, inspect response, then run the next.
- On transport failure, recover the local agent first, then rerun the command as a new invocation.
- Cleanup with
reflex browser session-kill when done unless the user explicitly asks to keep the session open.
Response Handling (Required)
- Always capture the full JSON response first, then parse fields from that captured payload.
- Do not pipe command output directly into filtering (
jq | head) as the only observable output; this hides critical context.
- Prefer in-memory capture over temp files; if temp files are needed, use ephemeral files and clean them up.
- Treat envelope fields (
ok, action, session) as source-of-truth; mirrored duplicates may be compacted out of response.
- Treat
response.state and response.artifacts as optional add-ons when explicitly requested; existing summary parsers can ignore them.
- When screenshots are requested, inspect them as visual evidence alongside
response.data.summary.targets[]; do not replace the parser contract with screenshot-only reasoning when actionable selectors are needed.
- For exact field names such as
summary.targets[], use reflex browser help --json as the contract reference.
Parser-First Summary Contract (Required)
- For selector discovery that feeds agent logic, use
summary first.
- Parse
response.data.summary.targets[] as the primary selector feed:
selector
selectorType
confidence
reason
- optional steering:
status
hint
fallback
ref — short-lived element ref (@r1, @r2, …); prefer over selector when present
- Treat
summary.version + summary.targets[] as the stable parser contract; avoid parsing deep fields from full summary output by default.
- Do not parse
elements/actions/candidates-style fields from summary output.
- Keep extraction flow deterministic:
- summary for candidate selection
- targeted action (
click/text/attribute/etc.)
- re-run summary only after DOM-changing actions when needed
Summary Count And Flags (Required)
The positional count argument controls how many targets (ranked actionable elements) and snapshot lines are returned. It does not control how much of the DOM is scanned — the agent always scans up to 2000 nodes regardless.
- Default: 20. Hard max: 100.
- Start with
summary 20 -i -c. This is enough for most pages.
- If you need more coverage, refine with flags first (
-s, -C, -d), not by increasing the count.
- Only increase the count when the page has many similar actionable items (e.g., a product listing with 50+ links) and you need targets for more of them.
- Do not use high counts like
summary 80 as a general "show me everything" — it adds low-confidence targets and more snapshot noise without improving discovery quality.
Summary Refinement Ladder (Required)
When the first summary pass is weak, noisy, or incomplete, stay in summary mode and refine it before escalating:
- Start with
summary 20 -i -c for normal interactive discovery.
- If the results are too broad, add
-s "<container>" to scope discovery to the relevant region.
- If the page relies on non-semantic clickable UI, add
-C.
- If the output is still noisy, tune depth (
-d <n>) and scope (-s) instead of increasing count or switching tools.
- Only increase count beyond 20 when you know the page has many repeated items and you need targets for more of them.
- Re-run
summary after DOM-changing actions and continue from fresh refs/targets.
- Use
html only after at least 2 materially different summary passes still fail to expose enough structure for a targeted click/text/attribute/property call.
- After consulting
html, immediately switch back to targeted commands; do not keep planning from raw HTML dumps.
Visual Evidence And Screenshots (Required)
- When the user asks for visual judgment such as "does this look good", "is this aligned", "is something covering it", or "what is visible here", capture screenshot evidence before answering.
- Use
reflex browser screenshot for pure visual review when no selector discovery is needed.
- Use
reflex browser summary 20 -i -c --state --screenshot when the task needs both selector recovery and visual confirmation.
- Prefer screenshot-assisted summary when the page is visually tricky:
- canvas-like or game-like UIs
- overlays, sticky headers, consent/chat widgets, or occlusion problems
- duplicated labels where DOM hints alone are ambiguous
- non-semantic click targets where visible placement matters
- Keep screenshots opt-in. If selectors are already clear from normal
summary, do not add screenshot payloads on every pass.
- Use the screenshot to confirm which visible element matches a candidate ref/selector or to explain why something is off-screen or obscured; keep
summary.targets[] as the action feed.
Overlay And Noise Recovery (Required)
When summary only surfaces cookie/consent/chat widgets or other overlays:
- Treat that output as page-state information, not discovery failure.
- Dismiss or accept the blocking UI with the returned refs/selectors when safe and necessary.
- Re-run
summary immediately after the overlay changes the DOM.
- Only escalate to
html or other last-resort evidence after overlay cleanup plus the normal summary refinement ladder still fails.
Summary Refs (Required)
Each summary call assigns short-lived refs (@r1, @r2, …) to interactive elements:
- Refs appear in
targets[].ref and inline in snapshot lines as [ref=@rN].
- Pass a ref directly as the selector to any action:
click "@r10", fill "@r5" "text", attribute "@r3" href.
- Prefer refs over CSS/XPath selectors when available — they resolve directly to the live DOM element, bypassing selector fragility entirely.
- Refs are invalidated after any navigation or DOM-mutating action (
click, fill, type, enter, tab, open, back, forward, refresh, tab switches). Re-run summary after such actions to obtain fresh refs.
- A stale ref returns
errorCode: ELEMENT_STALE with a recoveryHint — always re-run summary on that error.
# summary returns: - link "Fiction" [ref=@r10]
reflex browser click "@r10" # navigate using ref
# after navigation, refs are invalidated — re-run summary
reflex browser summary 20 -i -c
# - link "Soumission" [ref=@r150]
reflex browser attribute "@r150" title # read without re-discovering selector
reflex browser attribute "@r150" href
Shadow DOM Support
Shadow DOM is supported.
- Use shadow-piercing selector chains with
>>>.
- Example:
css=app-shell >>> css=book-item >>> css=button.buy
- Keep each hop explicit; select the shadow host before
>>>, then the element inside it.
- Prefer
summary refs when available, but if you must write a selector manually for a shadow-root element, use the full >>> chain instead of dropping to a flat CSS selector.
Helper script:
scripts/capture_json.sh provides rb_capture, rb_jq, and rb_pick_selector for safe full-response handling.
- source via
source skills/reflex-browser/scripts/capture_json.sh (from project root).
Lua Trace Generation
The reflex browser lua command generates a Lua trace of the current browser session:
- Only call
reflex browser lua after the browser flow is already stable and validated.
- Treat the output as a raw trace to refactor, not a finished script.
- If
response.data.generationGuidance is present, apply it when producing the script.
- Keep discovered selectors as-is when guidance says selectors are fixed.
- Do not use
reflex browser lua to rescue an unstable discovery session; the trace will mirror dead-end navigation.
- For the actual script authoring, switch to the
reflex-scripting skill.
Session Selection Rules
- Default to scoped auto-session mode.
- Use
start to get-or-create the scoped auto-session.
- After
start, continue commands without --session in normal flows.
- Use explicit
--session <id> only when:
- the user asks to pin/reuse a specific session id, or
- the task requires switching between multiple concurrent sessions.
- Use bare
--session (no value) only on start or open when a fresh backend-assigned session id is explicitly required.
- Do not pass
--session by habit in single-flow tasks.
- Pass
--profile only when persistent browser state is intentionally needed.
- Set
--engine selenium|playwright (aliases: sel, play) before bootstrapping when the task specifically needs one engine.
Handed-Off Script Sessions
A browser session may originate from a handed-off Lua or Python script run, not just from a reflex browser start command.
- When a script run with
--debug on-error or --debug always finishes and the debug policy triggers, the script's browser is promoted into a named browser CLI session.
- The run emits a
debug-ready NDJSON event with the session id. Use reflex browser --session <id> summary, screenshot, click, etc. to inspect and manipulate the same browser.
- This is post-run handoff, not pause/resume debugging — the script is fully finished before the browser session becomes CLI-controlled.
- Handed-off sessions auto-expire after their TTL. Use
session-kill for explicit cleanup.
- After inspection, switch back to the
reflex-scripting skill to fix and rerun the script.
- For an existing saved script, use this handed-off browser session to gather evidence and validate selectors, not to replace the script-repair loop with repeated
lua exec or python exec experiments.
- Prefer a short inspect -> confirm -> return-to-file cycle: inspect with browser commands, edit the saved script, rerun the saved script.
Hard Rules
- Bridge supports Selenium and Playwright; use
options.engine as the canonical engine field.
- Do not send
options.browser.
- Recompute selectors after DOM changes with
summary.
- Use
-i for interactive discovery.
- Add
-C for cursor-interactive components.
- Add
-c to reduce structural noise.
- Add
-s <selector> to scope discovery to a container.
- Auto-session engine changes are applied by
start/open, which recreate the same inferred auto-session id when needed.
- Stop on first failed command (
ok: false) to avoid cascading selector errors.
- Pass relative links directly to
open; CLI resolves them against current session URL.
- For repeated-item extraction, anchor selectors at the collection parent (for example list/grid item), then index that parent; do not index unrelated descendants.
- Treat repeated
no such element or timeout on the same intent as a selector-state mismatch, not a transient flake.
- When transport fails, recover via
reflex agent status / reflex agent start before switching selector strategy.
- Do not strip shadow DOM chains from validated selectors; keep
>>> hops intact when the target lives inside shadow roots.
Wait Strategy (Required)
click, fill, type, and open include waiting behavior; avoid redundant waits.
- Use explicit
wait for real state transitions:
- after navigation
- after
back / forward / refresh
- after async UI updates
- Prefer stable page-level wait targets over fragile positional selectors.
- If an action fails once, retry once. If it fails again, run
summary again with tighter flags and continue with updated selectors.
- After 2 consecutive failures for the same intent, stop the loop and run recovery; never keep incrementing positional selectors blindly.
- For
wait/visible/enabled/selected, pass per-check timeout as the positional argument (wait "<selector>" 8000); reserve global --cli-timeout for transport/command envelope timeout.
Anti-Patterns (Forbidden)
- Running commands without checking each JSON response.
- Using
eval as default extraction when text, summary, attribute, or property can answer the task.
- Running long blind command chains without validating page state.
- Continuing extraction loops after a failed
open.
- Using positional selectors on the wrong structural level (for example
article:nth-of-type(n) when siblings are actually li elements).
- Repeating the same failing selector pattern across increasing indexes without re-discovery.
- Jumping to full
html dumps after the first weak summary instead of fine-tuning summary scope/flags first.
- Starting extra sessions during the same task without explicit need and cleanup.
- Hiding browser flow in long shell scripts/loops instead of observable one-command-at-a-time CLI calls.
- Passing explicit
--session by habit in single-flow tasks that should use default auto-session behavior.
- Using
--help mid-task as a substitute for the documented selector/session workflow.
- Throwing away a validated browser flow in favor of direct HTTP or side-route fetching just because another layer exists.
- Starting with broad capability audits (
reflex lua libs, repeated help calls, external doc hunts) before trying start -> open -> summary on the target page.
- Treating cookie/consent/chat-only summary output as permission to jump to
eval, html, or external fetching instead of clearing the overlay and re-running summary.
Extending Beyond Browser
When browser commands alone are not enough to complete the task:
- If the task just needs data export or file output after browser collection, use direct library commands (
reflex xlsx ..., reflex csv ...) or reflex lua exec "..." — see the reflex-scripting skill.
- If the user asks for a reusable script, switch to the
reflex-scripting skill after browser discovery is done. Carry forward all discovered selectors, refs, URLs, and page transitions.
- Do not discard a validated browser flow just because another layer also exists; scripts should continue the workflow, not replace it.
Output Contract
Use reflex browser help --json for the exact machine-readable response schema, including:
- summary target fields such as
selector, ref, text, and href
- read-value paths such as
response.data.value
- optional summary add-ons such as
response.state and response.artifacts.screenshot
- error fields such as
response.errorCode and response.recoveryHint
- Lua generation and screenshot payload fields
Repeated Items Pattern (Required)
- Identify the repeated container first (for example
css=ol.row > li).
- Validate the container count/visibility with
wait or visible.
- Extract child fields within indexed container selectors (for example
... > li:nth-of-type(2) h3 a).
- Prefer semantic field reads:
attribute ... title for titles when present
text ... .price_color for visible price text
Bash URL Handling (Optional)
Use this only when writing shell wrappers around CLI JSON output.
For normal CLI usage, prefer open <href> directly (relative URLs are auto-resolved).
get_value() { jq -r '.response.data.value // empty'; }
get_url() { reflex url | get_value; }
open_target() {
local href="$1"
reflex browser open "$href" >/dev/null
get_url
}
PowerShell URL Handling (Optional)
Use the same pattern in PowerShell when running on Windows.
function Get-Value {
param([Parameter(ValueFromPipeline = $true)] $obj)
process { $obj.response.data.value }
}
function Get-Url {
reflex url | ConvertFrom-Json | Get-Value
}
function Open-Target {
param([string]$Href)
reflex browser open $Href | Out-Null
Get-Url
}
References
- Command catalog and flags:
- CLI protocol contract:
- Selector workflow:
- Session lifecycle and recovery:
references/session-management.md
- Worked examples:
examples/books-to-scrape-summary.md
examples/page-to-export-one-off.md
examples/careers-to-xlsx-lua.md
1---2name: reflex-browser3description: Use this skill for browser automation through Reflex Agent using the reflex CLI, including session handling, command flow, selectors, screenshot-assisted discovery, visual QA, and protocol-safe request patterns.4---56# Reflex Browser Skill78## Purpose910Use this skill when the task involves a **website or browser**: navigating pages, clicking elements, reading content, filling forms, scraping data, or automating a web flow.1112This skill covers interactive browser work via `reflex browser ...` CLI commands. Each command is a single stateless action — run one, inspect the JSON response, then decide the next step.1314When the end goal is a reusable Lua or Python browser automation script, **still start here first**: use `reflex browser ...` to inspect the site, verify the flow, and stabilize selectors before writing script code. Then switch to the `reflex-scripting` skill for the script itself.1516## When To Use This Skill1718- User asks to interact with a website (navigate, click, fill, read, scrape)19- User asks to inspect or explore a page20- User asks for browser-based data collection21- User asks whether a page, modal, overlay, or layout looks correct22- User asks for a browser automation script (start here for discovery, then `reflex-scripting` for the script)2324## When NOT To Use This Skill2526- One-off file manipulation (xlsx, csv, json) without a browser → use `reflex-scripting`27- REST API calls → use `reflex-scripting`28- Data transforms or batch processing without a browser → use `reflex-scripting`29- Writing a script after browser discovery is done → use `reflex-scripting`3031## Quick Start32331. Install globally from Gitea npm:34 - `npm config set @reflexautomation:registry "https://git.bqa-solutions.nl/api/packages/reflex/npm/" --location=user`35 - `npm config set "//git.bqa-solutions.nl/api/packages/reflex/npm/:_authToken" "YOUR_DEPLOY_TOKEN" --location=user`36 - `npm install -g @reflexautomation/reflex-cli`372. Start or reuse a session:38 - `reflex browser start`393. Default to auto-session mode for normal agent runs:40 - do **not** pass `--session` on follow-up commands41 - example: `reflex browser open https://example.com`424. Use explicit `--session` only for deterministic override:43 - example: `reflex browser open https://example.com --session <sessionId>`445. End with `reflex browser session-kill` in auto-session mode.45 - if you used an explicit session id, use `reflex browser session-kill --session <sessionId>` (or `reflex browser session-kill <sessionId>`)4647Use the CLI itself as the command/protocol source of truth:4849- `reflex browser --help`50- `reflex browser help --json`5152## Agent Defaults5354- Do not pass `--session` by habit after `start`; normal flows should stay in scoped auto-session mode.55- Start on the target page, not on broad capability audits; do not inventory libraries or call repeated help commands unless a concrete next step needs exact syntax.56- Prefer `summary` first and fine-tune it (`-i -c`, then `-s`, `-C`, `-d`) for selector discovery and recovery before trying `eval` or `html`; treat `html` as last-resort evidence, not normal recovery. Start with count 20; increase only when the page has many repeated items.57- Use `summary --state --screenshot` when selector recovery or page review needs visual evidence; keep screenshots opt-in instead of adding them to every pass.58- Use `reflex browser help --json` for exact command/response/schema details instead of duplicating those rules here.5960## Discovery Before Capability Audits (Required)61621. For normal tasks, start with the target page: `start` -> `open` -> `summary`.632. Do not begin with broad audits such as `reflex lua libs`, repeated `help` calls, external doc hunts, or speculative output-format work.643. Check exact command/library help only when you have a concrete next step that requires it.654. Once a browser command succeeds, continue the task instead of re-checking availability.6667## Agent Availability And Recovery (Required)68691. Before assuming browser commands are broken, verify the local agent is available.702. If a browser command fails with a transport/connect error, use this recovery order:71 - `reflex agent status`72 - if not running, `reflex agent start`73 - if the agent jar is missing, `reflex agent download`74 - if Java is missing or incompatible, `reflex agent runtime install`75 - retry the original browser command after recovery763. Prefer the CLI's own guidance text when it suggests `reflex agent start` or `reflex agent download`.774. For local development tasks, the AI agent may run `reflex agent ...` commands directly instead of only telling the human what to do.785. If the environment is clearly non-local, remote, or permission-sensitive, explain the exact `reflex agent ...` command the human should run.796. Do not start multiple background agents on different ports unless the task explicitly requires it.8081Recommended recovery flow:8283```bash84reflex agent status85reflex agent start86reflex agent download87reflex agent runtime install88```8990## Command Lifecycle (Required)91921. Send actions as separate CLI invocations.932. Do not chain browser commands with `&&`, long shell pipelines, or opaque wrappers.943. Keep one logical session context for the task (auto-session by default).954. Default rule: omit `--session` on commands unless explicit override is required.965. Execute sequentially: run one command, inspect response, then run the next.976. On transport failure, recover the local agent first, then rerun the command as a new invocation.987. Cleanup with `reflex browser session-kill` when done unless the user explicitly asks to keep the session open.99100## Response Handling (Required)1011021. Always capture the full JSON response first, then parse fields from that captured payload.1032. Do not pipe command output directly into filtering (`jq | head`) as the only observable output; this hides critical context.1043. Prefer in-memory capture over temp files; if temp files are needed, use ephemeral files and clean them up.1054. Treat envelope fields (`ok`, `action`, `session`) as source-of-truth; mirrored duplicates may be compacted out of `response`.1065. Treat `response.state` and `response.artifacts` as optional add-ons when explicitly requested; existing summary parsers can ignore them.1076. When screenshots are requested, inspect them as visual evidence alongside `response.data.summary.targets[]`; do not replace the parser contract with screenshot-only reasoning when actionable selectors are needed.1087. For exact field names such as `summary.targets[]`, use `reflex browser help --json` as the contract reference.109110## Parser-First Summary Contract (Required)1111121. For selector discovery that feeds agent logic, use `summary` first.1132. Parse `response.data.summary.targets[]` as the primary selector feed:114 - `selector`115 - `selectorType`116 - `confidence`117 - `reason`118 - optional steering:119 - `status`120 - `hint`121 - `fallback`122 - `ref` — short-lived element ref (`@r1`, `@r2`, …); prefer over `selector` when present1233. Treat `summary.version` + `summary.targets[]` as the stable parser contract; avoid parsing deep fields from full summary output by default.1244. Do not parse `elements`/`actions`/`candidates`-style fields from summary output.1255. Keep extraction flow deterministic:126 - summary for candidate selection127 - targeted action (`click`/`text`/`attribute`/etc.)128 - re-run summary only after DOM-changing actions when needed129130## Summary Count And Flags (Required)131132The positional `count` argument controls how many **targets** (ranked actionable elements) and **snapshot lines** are returned. It does not control how much of the DOM is scanned — the agent always scans up to 2000 nodes regardless.133134- Default: **20**. Hard max: **100**.135- Start with `summary 20 -i -c`. This is enough for most pages.136- If you need more coverage, **refine with flags first** (`-s`, `-C`, `-d`), not by increasing the count.137- Only increase the count when the page has many similar actionable items (e.g., a product listing with 50+ links) and you need targets for more of them.138- Do not use high counts like `summary 80` as a general "show me everything" — it adds low-confidence targets and more snapshot noise without improving discovery quality.139140## Summary Refinement Ladder (Required)141142When the first `summary` pass is weak, noisy, or incomplete, stay in `summary` mode and refine it before escalating:1431441. Start with `summary 20 -i -c` for normal interactive discovery.1452. If the results are too broad, add `-s "<container>"` to scope discovery to the relevant region.1463. If the page relies on non-semantic clickable UI, add `-C`.1474. If the output is still noisy, tune depth (`-d <n>`) and scope (`-s`) instead of increasing count or switching tools.1485. Only increase count beyond 20 when you know the page has many repeated items and you need targets for more of them.1496. Re-run `summary` after DOM-changing actions and continue from fresh refs/targets.1507. Use `html` only after at least 2 materially different `summary` passes still fail to expose enough structure for a targeted `click`/`text`/`attribute`/`property` call.1518. After consulting `html`, immediately switch back to targeted commands; do not keep planning from raw HTML dumps.152153## Visual Evidence And Screenshots (Required)1541551. When the user asks for visual judgment such as "does this look good", "is this aligned", "is something covering it", or "what is visible here", capture screenshot evidence before answering.1562. Use `reflex browser screenshot` for pure visual review when no selector discovery is needed.1573. Use `reflex browser summary 20 -i -c --state --screenshot` when the task needs both selector recovery and visual confirmation.1584. Prefer screenshot-assisted summary when the page is visually tricky:159 - canvas-like or game-like UIs160 - overlays, sticky headers, consent/chat widgets, or occlusion problems161 - duplicated labels where DOM hints alone are ambiguous162 - non-semantic click targets where visible placement matters1635. Keep screenshots opt-in. If selectors are already clear from normal `summary`, do not add screenshot payloads on every pass.1646. Use the screenshot to confirm which visible element matches a candidate ref/selector or to explain why something is off-screen or obscured; keep `summary.targets[]` as the action feed.165166## Overlay And Noise Recovery (Required)167168When `summary` only surfaces cookie/consent/chat widgets or other overlays:1691701. Treat that output as page-state information, not discovery failure.1712. Dismiss or accept the blocking UI with the returned refs/selectors when safe and necessary.1723. Re-run `summary` immediately after the overlay changes the DOM.1734. Only escalate to `html` or other last-resort evidence after overlay cleanup plus the normal summary refinement ladder still fails.174175## Summary Refs (Required)176177Each `summary` call assigns short-lived refs (`@r1`, `@r2`, …) to interactive elements:178179- Refs appear in `targets[].ref` and inline in `snapshot` lines as `[ref=@rN]`.180- Pass a ref directly as the selector to any action: `click "@r10"`, `fill "@r5" "text"`, `attribute "@r3" href`.181- **Prefer refs over CSS/XPath selectors when available** — they resolve directly to the live DOM element, bypassing selector fragility entirely.182- Refs are **invalidated after any navigation or DOM-mutating action** (`click`, `fill`, `type`, `enter`, `tab`, `open`, `back`, `forward`, `refresh`, tab switches). Re-run `summary` after such actions to obtain fresh refs.183- A stale ref returns `errorCode: ELEMENT_STALE` with a `recoveryHint` — always re-run `summary` on that error.184185```186# summary returns: - link "Fiction" [ref=@r10]187reflex browser click "@r10" # navigate using ref188189# after navigation, refs are invalidated — re-run summary190reflex browser summary 20 -i -c191# - link "Soumission" [ref=@r150]192reflex browser attribute "@r150" title # read without re-discovering selector193reflex browser attribute "@r150" href194```195196## Shadow DOM Support197198Shadow DOM is supported.199200- Use shadow-piercing selector chains with `>>>`.201- Example: `css=app-shell >>> css=book-item >>> css=button.buy`202- Keep each hop explicit; select the shadow host before `>>>`, then the element inside it.203- Prefer `summary` refs when available, but if you must write a selector manually for a shadow-root element, use the full `>>>` chain instead of dropping to a flat CSS selector.204205Helper script:206207- `scripts/capture_json.sh` provides `rb_capture`, `rb_jq`, and `rb_pick_selector` for safe full-response handling.208- source via `source skills/reflex-browser/scripts/capture_json.sh` (from project root).209210## Lua Trace Generation211212The `reflex browser lua` command generates a Lua trace of the current browser session:2132141. Only call `reflex browser lua` after the browser flow is already stable and validated.2152. Treat the output as a raw trace to refactor, not a finished script.2163. If `response.data.generationGuidance` is present, apply it when producing the script.2174. Keep discovered selectors as-is when guidance says selectors are fixed.2185. Do not use `reflex browser lua` to rescue an unstable discovery session; the trace will mirror dead-end navigation.2196. For the actual script authoring, switch to the `reflex-scripting` skill.220221## Session Selection Rules2222231. Default to scoped auto-session mode.2242. Use `start` to get-or-create the scoped auto-session.2253. After `start`, continue commands without `--session` in normal flows.2264. Use explicit `--session <id>` only when:227 - the user asks to pin/reuse a specific session id, or228 - the task requires switching between multiple concurrent sessions.2295. Use bare `--session` (no value) only on `start` or `open` when a fresh backend-assigned session id is explicitly required.2306. Do not pass `--session` by habit in single-flow tasks.2317. Pass `--profile` only when persistent browser state is intentionally needed.2328. Set `--engine selenium|playwright` (aliases: `sel`, `play`) before bootstrapping when the task specifically needs one engine.233234## Handed-Off Script Sessions235236A browser session may originate from a handed-off Lua or Python script run, not just from a `reflex browser start` command.237238- When a script run with `--debug on-error` or `--debug always` finishes and the debug policy triggers, the script's browser is promoted into a named browser CLI session.239- The run emits a `debug-ready` NDJSON event with the session id. Use `reflex browser --session <id> summary`, `screenshot`, `click`, etc. to inspect and manipulate the same browser.240- This is **post-run handoff**, not pause/resume debugging — the script is fully finished before the browser session becomes CLI-controlled.241- Handed-off sessions auto-expire after their TTL. Use `session-kill` for explicit cleanup.242- After inspection, switch back to the `reflex-scripting` skill to fix and rerun the script.243- For an existing saved script, use this handed-off browser session to gather evidence and validate selectors, not to replace the script-repair loop with repeated `lua exec` or `python exec` experiments.244- Prefer a short inspect -> confirm -> return-to-file cycle: inspect with browser commands, edit the saved script, rerun the saved script.245246## Hard Rules2472481. Bridge supports Selenium and Playwright; use `options.engine` as the canonical engine field.2492. Do **not** send `options.browser`.2503. Recompute selectors after DOM changes with `summary`.251 - Use `-i` for interactive discovery.252 - Add `-C` for cursor-interactive components.253 - Add `-c` to reduce structural noise.254 - Add `-s <selector>` to scope discovery to a container.2554. Auto-session engine changes are applied by `start`/`open`, which recreate the same inferred auto-session id when needed.2565. Stop on first failed command (`ok: false`) to avoid cascading selector errors.2576. Pass relative links directly to `open`; CLI resolves them against current session URL.2587. For repeated-item extraction, anchor selectors at the collection parent (for example list/grid item), then index that parent; do not index unrelated descendants.2598. Treat repeated `no such element` or timeout on the same intent as a selector-state mismatch, not a transient flake.2609. When transport fails, recover via `reflex agent status` / `reflex agent start` before switching selector strategy.26110. Do not strip shadow DOM chains from validated selectors; keep `>>>` hops intact when the target lives inside shadow roots.262263## Wait Strategy (Required)2642651. `click`, `fill`, `type`, and `open` include waiting behavior; avoid redundant waits.2662. Use explicit `wait` for real state transitions:267 - after navigation268 - after `back` / `forward` / `refresh`269 - after async UI updates2703. Prefer stable page-level wait targets over fragile positional selectors.2714. If an action fails once, retry once. If it fails again, run `summary` again with tighter flags and continue with updated selectors.2725. After 2 consecutive failures for the same intent, stop the loop and run recovery; never keep incrementing positional selectors blindly.2736. For `wait`/`visible`/`enabled`/`selected`, pass per-check timeout as the positional argument (`wait "<selector>" 8000`); reserve global `--cli-timeout` for transport/command envelope timeout.274275## Anti-Patterns (Forbidden)2762771. Running commands without checking each JSON response.2782. Using `eval` as default extraction when `text`, `summary`, `attribute`, or `property` can answer the task.2793. Running long blind command chains without validating page state.2804. Continuing extraction loops after a failed `open`.2815. Using positional selectors on the wrong structural level (for example `article:nth-of-type(n)` when siblings are actually `li` elements).2826. Repeating the same failing selector pattern across increasing indexes without re-discovery.2837. Jumping to full `html` dumps after the first weak `summary` instead of fine-tuning `summary` scope/flags first.2848. Starting extra sessions during the same task without explicit need and cleanup.2859. Hiding browser flow in long shell scripts/loops instead of observable one-command-at-a-time CLI calls.28610. Passing explicit `--session` by habit in single-flow tasks that should use default auto-session behavior.28711. Using `--help` mid-task as a substitute for the documented selector/session workflow.28812. Throwing away a validated browser flow in favor of direct HTTP or side-route fetching just because another layer exists.28913. Starting with broad capability audits (`reflex lua libs`, repeated `help` calls, external doc hunts) before trying `start` -> `open` -> `summary` on the target page.29014. Treating cookie/consent/chat-only summary output as permission to jump to `eval`, `html`, or external fetching instead of clearing the overlay and re-running `summary`.291292## Extending Beyond Browser293294When browser commands alone are not enough to complete the task:2952961. If the task just needs data export or file output after browser collection, use direct library commands (`reflex xlsx ...`, `reflex csv ...`) or `reflex lua exec "..."` — see the `reflex-scripting` skill.2972. If the user asks for a reusable script, switch to the `reflex-scripting` skill after browser discovery is done. Carry forward all discovered selectors, refs, URLs, and page transitions.2983. Do not discard a validated browser flow just because another layer also exists; scripts should continue the workflow, not replace it.299300## Output Contract301302Use `reflex browser help --json` for the exact machine-readable response schema, including:303304- summary target fields such as `selector`, `ref`, `text`, and `href`305- read-value paths such as `response.data.value`306- optional summary add-ons such as `response.state` and `response.artifacts.screenshot`307- error fields such as `response.errorCode` and `response.recoveryHint`308- Lua generation and screenshot payload fields309310## Repeated Items Pattern (Required)3113121. Identify the repeated container first (for example `css=ol.row > li`).3132. Validate the container count/visibility with `wait` or `visible`.3143. Extract child fields within indexed container selectors (for example `... > li:nth-of-type(2) h3 a`).3154. Prefer semantic field reads:316 - `attribute ... title` for titles when present317 - `text ... .price_color` for visible price text318319## Bash URL Handling (Optional)320321Use this only when writing shell wrappers around CLI JSON output.322For normal CLI usage, prefer `open <href>` directly (relative URLs are auto-resolved).323324```bash325get_value() { jq -r '.response.data.value // empty'; }326get_url() { reflex url | get_value; }327open_target() {328 local href="$1"329 reflex browser open "$href" >/dev/null330 get_url331}332```333334## PowerShell URL Handling (Optional)335336Use the same pattern in PowerShell when running on Windows.337338```powershell339function Get-Value {340 param([Parameter(ValueFromPipeline = $true)] $obj)341 process { $obj.response.data.value }342}343344function Get-Url {345 reflex url | ConvertFrom-Json | Get-Value346}347348function Open-Target {349 param([string]$Href)350 reflex browser open $Href | Out-Null351 Get-Url352}353```354355## References356357- Command catalog and flags:358 - `references/commands.md`359- CLI protocol contract:360 - `references/protocol.md`361- Selector workflow:362 - `references/selectors.md`363- Session lifecycle and recovery:364 - `references/session-management.md`365- Worked examples:366 - `examples/books-to-scrape-summary.md`367 - `examples/page-to-export-one-off.md`368 - `examples/careers-to-xlsx-lua.md`