name: reflex-browser description: Use this skill for browser automation through Reflex Agent using the reflex CLI, including session handling, command flow, selectors, and protocol-safe request patterns.
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 for a browser automation script (start here for discovery, then
reflex-scriptingfor 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=usernpm config set "//git.bqa-solutions.nl/api/packages/reflex/npm/:_authToken" "YOUR_DEPLOY_TOKEN" --location=usernpm install -g @reflexautomation/reflex-cli
- Start or reuse a session:
reflex browser start
- Default to auto-session mode for normal agent runs:
- do not pass
--sessionon follow-up commands - example:
reflex browser open https://example.com
- do not pass
- Use explicit
--sessiononly for deterministic override:- example:
reflex browser open https://example.com --session <sessionId>
- example:
- End with
reflex browser session-killin auto-session mode.- if you used an explicit session id, use
reflex browser session-kill --session <sessionId>(orreflex browser session-kill <sessionId>)
- if you used an explicit session id, use
Use the CLI itself as the command/protocol source of truth:
reflex browser --helpreflex browser help --json
Agent Defaults
- Do not pass
--sessionby habit afterstart; 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
summaryfirst and fine-tune it (-i -c, then-s,-C,-d) for selector discovery and recovery before tryingevalorhtml; treathtmlas last-resort evidence, not normal recovery. Start with count 20; increase only when the page has many repeated items. - Use
reflex browser help --jsonfor 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, repeatedhelpcalls, 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 startorreflex 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
--sessionon 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-killwhen 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 ofresponse. - For exact field names such as
summary.targets[], usereflex browser help --jsonas the contract reference.
Parser-First Summary Contract (Required)
- For selector discovery that feeds agent logic, use
summaryfirst. - Parse
response.data.summary.targets[]as the primary selector feed:selectorselectorTypeconfidencereason- optional steering:
statushintfallbackref— short-lived element ref (@r1,@r2, …); prefer overselectorwhen 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 80as 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 -cfor 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
summaryafter DOM-changing actions and continue from fresh refs/targets. - Use
htmlonly after at least 2 materially differentsummarypasses still fail to expose enough structure for a targetedclick/text/attribute/propertycall. - After consulting
html, immediately switch back to targeted commands; do not keep planning from raw HTML dumps.
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
summaryimmediately after the overlay changes the DOM. - Only escalate to
htmlor 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[].refand inline insnapshotlines 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-runsummaryafter such actions to obtain fresh refs. - A stale ref returns
errorCode: ELEMENT_STALEwith arecoveryHint— always re-runsummaryon 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
Helper script:
scripts/capture_json.shprovidesrb_capture,rb_jq, andrb_pick_selectorfor 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 luaafter the browser flow is already stable and validated. - Treat the output as a raw trace to refactor, not a finished script.
- If
response.data.generationGuidanceis present, apply it when producing the script. - Keep discovered selectors as-is when guidance says selectors are fixed.
- Do not use
reflex browser luato rescue an unstable discovery session; the trace will mirror dead-end navigation. - For the actual script authoring, switch to the
reflex-scriptingskill.
Session Selection Rules
- Default to scoped auto-session mode.
- Use
startto get-or-create the scoped auto-session. - After
start, continue commands without--sessionin 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 onstartoropenwhen a fresh backend-assigned session id is explicitly required. - Do not pass
--sessionby habit in single-flow tasks. - Pass
--profileonly when persistent browser state is intentionally needed. - Set
--engine selenium|playwright(aliases:sel,play) before bootstrapping when the task specifically needs one engine.
Hard Rules
- Bridge supports Selenium and Playwright; use
options.engineas the canonical engine field. - Do not send
options.browser. - Recompute selectors after DOM changes with
summary.- Use
-ifor interactive discovery. - Add
-Cfor cursor-interactive components. - Add
-cto reduce structural noise. - Add
-s <selector>to scope discovery to a container.
- Use
- 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 elementor timeout on the same intent as a selector-state mismatch, not a transient flake. - When transport fails, recover via
reflex agent status/reflex agent startbefore switching selector strategy.
Wait Strategy (Required)
click,fill,type, andopeninclude waiting behavior; avoid redundant waits.- Use explicit
waitfor 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
summaryagain 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-timeoutfor transport/command envelope timeout.
Anti-Patterns (Forbidden)
- Running commands without checking each JSON response.
- Using
evalas default extraction whentext,summary,attribute, orpropertycan 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 actuallylielements). - Repeating the same failing selector pattern across increasing indexes without re-discovery.
- Jumping to full
htmldumps after the first weaksummaryinstead of fine-tuningsummaryscope/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
--sessionby habit in single-flow tasks that should use default auto-session behavior. - Using
--helpmid-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, repeatedhelpcalls, external doc hunts) before tryingstart->open->summaryon 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-runningsummary.
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 ...) orreflex lua exec "..."— see thereflex-scriptingskill. - If the user asks for a reusable script, switch to the
reflex-scriptingskill 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, andhref - read-value paths such as
response.data.value - error fields such as
response.errorCodeandresponse.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
waitorvisible. - Extract child fields within indexed container selectors (for example
... > li:nth-of-type(2) h3 a). - Prefer semantic field reads:
attribute ... titlefor titles when presenttext ... .price_colorfor 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:
references/commands.md
- CLI protocol contract:
references/protocol.md
- Selector workflow:
references/selectors.md
- Session lifecycle and recovery:
references/session-management.md
- Worked examples:
examples/books-to-scrape-summary.mdexamples/page-to-export-one-off.mdexamples/careers-to-xlsx-lua.md