Browser automation
Driving Sirio's embedded browser from a script: open a page, read it, act on it and wait for it.
sirioctl browser drives the Browser tab of a worktree, so an agent can preview what it built and check it. Every command acts on the first Browser tab of the worktree selected in the sidebar, whatever surface id you pass, so a script works best with one Browser tab open there and the selection left where it is.
These commands run at once. The origin prompt belongs to Browser tabs that a raw control-socket client marks as agent-driven, and Settings → Permissions keeps the origins you grant there.
Open a page
browser open adds a Browser tab to the selected worktree and loads the URL. It prints four fields with a tab between each: the surface id, a short reference that only --id-format both fills in, the URL and the page title. With no worktree selected, it fails with no current workspace. Keep the surface id: every other verb takes it as its first argument.
SURFACE=$(sirioctl browser open http://localhost:4321 | cut -f1)With --json, the same fields arrive as JSON, the id under surface.
Read it
sirioctl browser get "$SURFACE" url
sirioctl browser get "$SURFACE" text --selector 'h1'
sirioctl browser get "$SURFACE" html --selector 'main'
sirioctl browser snapshot "$SURFACE" --json
sirioctl browser console "$SURFACE"get takes what to read as its second argument: url for the address, text for the rendered text, or html for the markup. text and html read the page’s body, or the first element a --selector matches.
snapshot returns a generation and a flat list of the visible elements a script can act on: links, buttons, form fields, headings down to h3, and anything with a role or an aria-label. Each entry carries a reference such as e12, a role, a name, a box, and the element’s value when it has one.
console returns what the page has logged through console, as a JSON array whose entries hold a level and a message.
Act on it
sirioctl browser act "$SURFACE" click --ref e12 --generation 3
sirioctl browser act "$SURFACE" fill --selector '#email' --value 'me@example.com'
sirioctl browser act "$SURFACE" press --selector '#email' --value Enter
sirioctl browser act "$SURFACE" scroll --selector '#results'The verbs are click, fill, type, press and scroll. Address the element either by --ref from a snapshot, which also needs the --generation that snapshot reported, or by --selector, and scroll needs --selector. Passing both is an error.
fillandtypeboth set a field’s value from--value.presssends one key. Name it with--valuebeside a--selector, or with--keybeside a--ref.scrollbrings the--selectorelement into the middle of the view. With--refit scrolls the page down by--valuepixels, 400 by default, whatever the ref names.
Add --snapshot-after to get a fresh snapshot back in the same call. Each act prints one JSON row.
A new snapshot or any navigation makes the earlier references stale, and an act that uses one fails with stale_ref. Take a new snapshot and use its generation.
Wait for it
sirioctl browser wait "$SURFACE" --timeout-ms 5000 --selector '#results'
sirioctl browser wait "$SURFACE" --timeout-ms 5000 --text 'Done'
sirioctl browser wait "$SURFACE" --timeout-ms 5000 --url-contains '/success'
sirioctl browser wait "$SURFACE" --timeout-ms 5000 --load-state completeA wait takes exactly one condition. --load-state compares with the page’s document.readyState, so it takes loading, interactive or complete. --function waits until an expression of your own turns true. Every wait needs --timeout-ms, so it always has an end: when the time runs out, the command fails with timeout.
The rest
browser navigate "$SURFACE" back | forward | reload moves through history and prints the new URL and title. browser eval "$SURFACE" '<script>' runs JavaScript in the page and prints the result. Sirio refuses browser screenshot on every platform.
--json switches open, get, snapshot and eval to machine-readable output. act, wait and console print JSON either way, and navigate always prints plain text.