mirror of
https://github.com/stablyai/orca.git
synced 2026-11-14 01:47:24 +00:00
* feat(cli): open a browser tab in a split pane with `tab create --split` `orca tab create` could only add a tab to an existing pane, so an agent had no way to put a page beside its terminal. `--split <right|left|down|up>` creates a new pane next to the calling terminal (ORCA_TAB_ID), falling back to the active pane, and opens the page there without taking focus. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UNtbMA9iVj9T4rBUjn5u6W * refactor(browser): share one type for the tab-create IPC payload The preload listener, its callback, the preload API contract and main's sender each declared the payload separately, and the listener copy had already drifted from the new split fields. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(browser): open the CLI split pane and its tab in one step Creating an empty group and then filling it fails when main owns the layout, because the window's group doesn't exist until main's frame lands. createBrowserTab's split option carries both to whichever owner draws them, so the rollback for a half-made pane goes away. SSH hosts already cannot choose a new tab's group, so their CLI's split is stripped like targetGroupId. * fix(browser): split in the caller's workspace and refuse splits that can't happen A CLI run outside its workspace's directory sends no workspace, so the renderer fell back to the active one and missed the caller's terminal. The caller's tab now picks the workspace when none was named. An SSH host's split and an empty --split= both turned into a plain tab reported as success; both are refused instead. --------- Co-authored-by: Kalvin Mizzi <kalvin@mizzi.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
9.7 KiB
9.7 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). - 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.- 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.