reflex-browser
SKILL.md
Reflex Browser Skill (Agent-Only)
Purpose
Use this skill when you need browser automation through Reflex Agent via stateless CLI commands.
The CLI is single-action per process:
- run one
reflex-browser <command>invocation --sessionis optional; omitted commands use machine+repo auto-session- read one JSON response from stdout
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/browser-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
session-killin auto-session mode.- if you used an explicit session id, use
session-kill --session <sessionId>(orsession-kill <sessionId>)
- if you used an explicit session id, use
Agent defaults:
- do not pass
--sessionby habit afterstart; normal flows should stay in scoped auto-session mode - prefer
summarywith-i,-C,-c,-d, and-sfor selector discovery and recovery before tryingevalorhtml - use
--helponly as a compact reference; follow this skill and the README examples for workflow shape
Command Lifecycle (Required)
- Send actions as separate CLI invocations.
- 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, rerun the command as a new invocation.
- Cleanup with
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.
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 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 Output Handling
- Treat
luaaction output as a raw trace by default. - If
response.data.generationGuidanceis present, apply it to produce a human-usable Lua 5.2 script. - Keep discovered selectors as-is when guidance says selectors are fixed.
- Return both:
- raw generated script (for traceability)
- enhanced runnable script (for human use)
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.
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 before tryingsummaryfor selector recovery. - 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.
Output Contract (Required)
- Always evaluate envelope first:
okactionsession
- On failure (
ok: false), parse structured error fields first:response.errorCoderesponse.recoveryHint- then
message/response.messagefor display text
- Read actions (
text,value,attribute,property,tag,title,url) return extracted values in:response.data.value
- Interaction actions (
click,fill,type,enter,tab) return execution metadata in:response.selectorresponse.lua- optional
response.datafields
- Summary contract:
response.data.summary.versionresponse.data.summary.targets[]- Prefer targets with
status: "ready". - Treat
status: "retry"as a one-retry candidate, then refreshsummary. - Treat
status: "avoid"as a recovery hint, not a first-choice selector. - Use
fallbackonly when the primary selector fails or the target is markedavoid. - Use
refas the selector when present — it resolves directly to the live element without re-parsing CSS/XPath.
- Lua generation:
response.data.scriptas canonical script payloadresponse.data.generationGuidanceas post-processing constraints
- Screenshot contract:
response.data.imageBase64response.data.mimeType
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-browser 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-browser 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 example:
examples/books-to-scrape-summary.md
Weekly Installs
18
Repository
fruffel/reflex-…er-skillFirst Seen
12 days ago
Security Audits
Installed on
opencode18
antigravity18
claude-code18
junie18
github-copilot18
codex18