mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 17:37:40 +00:00
* fix(browser): stop agent clicks from opening the system file picker An agent click on a file input opened the macOS Open panel, which brought Orca's window forward over the app the user was in. Page actions now catch the picker the way upload does and tell the agent to use upload. * fix(browser): enable Page, cancel the picker, and clean up outside host scope * fix(browser): limit picker blocking to input delivery and bound its setup * perf(browser): skip picker blocking for actions without user activation * fix(browser): bound picker interception cleanup on a hung page * fix(browser): bound the picker interception setup as a whole
12 KiB
12 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, apasskeyRequeststill waiting, 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. One that opens a file picker fails withbrowser_file_chooser_opened: Orca closes the picker so the system dialog never covers the user's screen; useORCA uploadon the file input or its button instead. - 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. - When the user says they left notes or comments on a page, read them with
ORCA tab annotations --page <browserPageId>(the current tab without--page). It prints the notes they haven't sent, the same text the tab's Copy button gives, and--jsonreturns them inresult.annotations. Notes the user already sent arrive in your chat instead. - Passkey, fingerprint, Face ID, Windows Hello and security-key prompts can't be completed by you. When
snapshotor an action'seffectshaspasskeyRequest, the page is waiting on one from that origin and will wait for minutes. Ask the user to finish the sign-in, or runORCA dialog dismiss --page <browserPageId>to cancel it so the page offers another way to sign in. - 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.