mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 17:37:40 +00:00
* fix(browser): a split tab create joins a browser pane already beside the caller * fix(browser): the joined page is the pane's visible tab * fix(browser): a split with an unknown caller still splits beside the active pane
11 KiB
11 KiB
Built-in browser commands
Pin one page, snapshot it once, then act on it. Each action reports what it changed, so you rarely need to snapshot again:
ORCA tab current --json
ORCA goto --page <browserPageId> --url https://example.com --json
ORCA snapshot --page <browserPageId> --interactive
ORCA click --page <browserPageId> --element @e3 --json
Choosing what to look at, cheapest first:
snapshot --interactivelists only controls and links with their refs, often under half the size of the whole tree. It leaves out page text, including error and status messages.--deltais the cheap second look, for example after awaitwith no action in between: it returns only what changed since the last--deltasnapshot of that page, as "no change" or which lines of that tree to replace and with what. Each page keeps one baseline: a navigation, a large change, or a--deltacall with different flags returns the whole tree again and replaces it.--fullasks for the whole tree and restarts the baseline.--selector <css>limits the tree to one part of the page,--depth <n>limits nesting,--compactdrops empty structure, and--urlsadds link targets.- To read page text, run
exec --command "read"(the page as Markdown) or a plainsnapshot(the whole tree with its text). screenshotsaves a PNG of the visible page and prints its path; open that file to see the page. In Orca's desktop browser its pixels are CSS pixels, so x/y read off it work withORCA mouse.full-screenshotsaves the whole page the same way.--annotatelabels each control with its ref, and--if-changedsaves nothing when the page looks the same as last time.
Common commands:
ORCA goto --page <browserPageId> --url <url> --json
ORCA back --page <browserPageId> --json
ORCA reload --page <browserPageId> --json
ORCA snapshot --page <browserPageId> --interactive
ORCA snapshot --page <browserPageId> --interactive --delta
ORCA snapshot --page <browserPageId> --selector main --depth 4
ORCA screenshot --page <browserPageId>
ORCA screenshot --page <browserPageId> --annotate
ORCA full-screenshot --page <browserPageId>
ORCA pdf --page <browserPageId> --json
ORCA click --page <browserPageId> --element <ref> --json
ORCA fill --page <browserPageId> --element <ref> --value <text> --json
ORCA type --page <browserPageId> --input <text> --json
ORCA select --page <browserPageId> --element <ref> --value <value> --json
ORCA check --page <browserPageId> --element <ref> --json
ORCA scroll --page <browserPageId> --direction down --amount 1000 --json
ORCA hover --page <browserPageId> --element <ref> --json
ORCA focus --page <browserPageId> --element <ref> --json
ORCA keypress --page <browserPageId> --key Enter --json
ORCA upload --page <browserPageId> --element <ref> --files <paths> --json
ORCA wait --page <browserPageId> --text <text> --json
ORCA wait --page <browserPageId> --url <substring> --json
ORCA wait --page <browserPageId> --selector <css> --json
ORCA wait --page <browserPageId> --load load --json
ORCA eval --page <browserPageId> --expression <js> --json
ORCA dialog accept --page <browserPageId> [--text <answer>] --json
ORCA dialog dismiss --page <browserPageId> --json
ORCA set device --page <browserPageId> --name "iPhone 15" --json
ORCA viewport --page <browserPageId> --width 390 --height 844 --scale 3 --mobile --json
ORCA tab list --json
ORCA tab create --url <url> --json
ORCA tab create --url <url> --split right --json
ORCA tab switch --index <n> --json
ORCA tab close --index <n> --json
ORCA cookie get --page <browserPageId> --json
ORCA capture start --page <browserPageId> --json
ORCA console --page <browserPageId> --limit 50 --json
ORCA network --page <browserPageId> --limit 50 --json
ORCA exec --page <browserPageId> --command "read" --json
ORCA exec --page <browserPageId> --command "get text @e3" --json
Browser rules:
- Actions (
click,fill,type,keypress,select,check,hover,scroll,goto,back,reload,mouseand the rest) wait briefly for the page to settle and then report what they caused inresult.effects(text mode prints it under the action):url/titlewhen they changed,newTabswith theirbrowserPageId, blocked or openedpopups,downloadsstarted,consoleErrors, andpage:"unchanged", or the snapshot lines the action added or replaced, with their refs (full: truemeans the whole new page).loading: truemeans a navigation was still running:wait --load load, thensnapshot. Nopagemeans the page could not be read: runsnapshot.settled: falsemeans the page was still changing when it was read. An action that opens a JavaScript dialog fails withbrowser_dialog_openedinstead. - Snapshot again only when
page.truncatedis true, afterwait, after a tab switch, on abrowser_stale_ref, or when a result has noeffects(older Orca, or a server-hosted page). - Pass
--expect-url <url>with--pagewhen acting on the wrong resource would matter, such as writing or sending in one conversation of a chat app. Use the exact absolute URL fromresult.tab.urlinORCA tab current --json, orurlfrom asnapshot --jsonorgoto. Path, query and fragment must all match, so a page that rewrites its URL while you work refuses until you read the URL again. If the page's URL differs, or a navigation to another URL is under way, the command fails withbrowser_expected_url_mismatch, anderror.dataholdsexpectedUrl,actualUrl,browserPageIdandmayHaveStarted.mayHaveStarted: falsemeans nothing ran;truemeans a step of a longer command (a typed run, aselect-all) may have happened, so look at the page before retrying. Success addsbrowserPageIdandcheckedUrl, the URL last checked; the action itself may have navigated since, andeffects.urlsays where. The check runs right before the action and again before each later step, but it is not a lock: a route change in the instant after a check can still receive the action. It compares the top-level page only, so it says nothing about an iframe or an app that shows different content at one URL; read the page for those.execrefuses the flag, because one raw batch can navigate and retarget. A runtime, client or desktop that cannot check the URL refuses withincompatible_runtimeorbrowser_expect_url_unsupportedrather than acting unguarded. - Refs like
@e1are assigned bysnapshot, scoped to one tab, and invalidated by navigation or tab switch. - Pass
--page <browserPageId>on every command that acts on one page;ORCA <command> --helplists--pagewhen it does.tab list,tab current,tab createandopen-urltake no--page, andtab switch/tab closepick a tab by--indexor--page, never both, since--pagewins. Take the ID fromresult.tab.browserPageIdinORCA tab current --jsonorresult.browserPageIdinORCA tab create --jsonand keep it for the task;tab currentshows the routed tab, not the one you pin. When the user means a specific tab, find it by URL or title inORCA tab list --json. - Without
--page, a command goes to the worktree's current tab. That stays the agent's tab while it has had a command in the last 20 seconds or so, even after the user picks another (tab currentreports it too), then moves to the user's pick. - After
ORCA tab switch, pass the new page'sbrowserPageId. - A popup window a page opens (sign-in, payment) is listed in
ORCA tab list --jsonas apopup-<n>page withopenerBrowserPageId. If a click seems to do nothing, checktab list, then drive the popup with--page popup-<n>. When it closes, continue on the opener page. - Browser commands default to the current worktree.
--pagereaches the page in any worktree unless you also pass--worktree <selector>. Use--worktree allonly intentionally. tab listshows every tab in the tab bar. After a restart, tabs the user has not opened reportloaded: false;tab switchor any--pagecommand loads one in the background without changing the user's visible tab.tab create --split <right|left|down|up>opens the page in a new pane beside the calling terminal instead of as another tab; focus stays in the terminal. When a browser pane is already open beside it, the page opens as that pane's visible tab instead of adding another pane.- Use typed tab commands (
ORCA tab list/create/close/switch), notORCA exec --command "tab ...", so Orca keeps UI state synchronized. - Use
ORCA set deviceorORCA viewport --mobile, notORCA exec --command "set device ...", so the page also gets touch input andpointer: coarse. Each page load (reload,goto, link click) resets it, so run it again after navigating. - Prefer
wait --text,--url,--selector, or--loadafter async page changes instead of bare timeouts. Avoid--load networkidleexcept on pages known to go quiet: polling, websockets and streaming keep it from ever resolving. - Anything not listed above goes through
ORCA exec --page <browserPageId> --command "<agent-browser command>", which takes agent-browser's own command syntax (for example"get text @e3"or"is visible @e3") and prints JSON. It has nohelpcommand. uploadtakes the file input itself or the button that opens a file picker, in any frame, including cross-origin iframes; Orca catches the picker and sets the files on its input. UseORCA upload, notORCA exec --command "upload ...". On server-hosted pages pass the file input's ref.fillsets a field's whole value in one step, at any size.typepresses real keys into the focused element, sominlength/maxlength, key handlers, Enter and Tab act as they would for a person;ORCA focusthe element first. Usetypewhen the page reacts to keystrokes.- On server-hosted pages
fillandtypestill insert text the engine's own way. If either does nothing on a custom input there, tryORCA focus --page <browserPageId> --element @e1 --jsonthenORCA inserttext --page <browserPageId> --text "text" --json. - A client-hosted page renders in the paired desktop's browser engine, so every command against it needs that desktop online and returns
browser_host_unavailablewhile it is closed, asleep, or disconnected. Server-hosted pages run with no desktop attached; prefer them for long or unattended automation.
Common recoveries:
browser_no_tab: open a tab withORCA tab create --url <url> --json.browser_stale_ref: runORCA snapshot --page <browserPageId> --jsonand retry on the same page with fresh refs.browser_element_not_interactable: the element can't take that command, and the message says why (not a text field, disabled, read-only, not a<select>, opened no file picker). Re-snapshot and pick the right ref; for a custom dropdown, click it and then click the option.browser_tab_not_found: runORCA tab list --jsonbefore switching or closing.browser_dialog_open/browser_dialog_opened: the page has a JavaScript alert, confirm or prompt open, and the error quotes it. Answer it withORCA dialog accept(--textfor a prompt; without it a prompt takes its default) orORCA dialog dismissbefore any other command on that page; a command that opened it may already have taken effect, so check before repeating it.browser_host_unavailable: the desktop hosting the page is offline. Bring it back, or recreate the page with server placement if the work must outlive the desktop session.