mirror of
https://github.com/stablyai/orca.git
synced 2026-09-24 16:02:41 +00:00
* Revert "Enable accessibility tree (`ax`) command on iOS emulator sessions (#10007)"
This reverts commit 43ae014a64.
* fix(emulator): expose iOS accessibility tree
* fix(emulator): support device-only iOS AX
* fix(emulator): normalize iOS ax to 0..1 and heal missing axUrl
serve-sim's helper /ax reports element frames in absolute pixels, but
tap/gesture take normalized 0..1 coords. Normalize the raw AX node tree
into a compact nested shape whose frames are 0..1 over the device screen
(first root's frame), mirroring serve-sim's own normalizeAxTree, so agents
can feed ax output straight back into input commands.
Also heal sessions that were registered without an axUrl: #9924 only
derived /ax at parse time, so already-active sessions had no endpoint.
The bridge now derives it from the session's mjpeg stream URL, guarded to
the /stream.mjpeg suffix so a non-mjpeg URL never fabricates a bogus /ax.
* docs(emulator): mark ax working on iOS with correct raw-AX-tree shape
Both skill guides and the CLI summary described iOS ax as unsupported (or,
via the reverted #10007, as a normalized "screen + elements" shape that
never matched the endpoint). ax works on both backends: Android via
uiautomator, iOS via the serve-sim helper. Document the real iOS output —
a raw AX node tree (labels, roles, nested children) with frames normalized
to 0..1 — and regenerate the bundled skill guides.
* chore(skills): regenerate skill bundle manifests
CI verify failed because generated skill artifacts were stale after version/skill revision bumps.
* fix(emulator): read ax from explicit device without active session
Fall back to udid-keyed session lookup when a worktree has no active emulator,
allowing `--device` targeting to work the same way for ax as it does for tap/type.
Also clarify in docs that AX frames are normalized 0..1 with top-left origin,
and show how to tap an element at its frame center (x+width/2, y+height/2).
* fix(emulator): cap iOS AX tree at 500 nodes
Unbounded accessibility trees can flood agent output. Enforce a 500-node limit (matching serve-sim's snapshot cap) and mark truncated parents so consumers know the tree was cut.
---------
Co-authored-by: 5Hyeons <ohs2251@naver.com>
122 lines
4.9 KiB
TypeScript
122 lines
4.9 KiB
TypeScript
import type { CommandSpec } from '../args'
|
|
import { GLOBAL_FLAGS } from '../args'
|
|
|
|
export const EMULATOR_COMMAND_SPECS: CommandSpec[] = [
|
|
{
|
|
path: ['emulator', 'list'],
|
|
summary: 'List available/running emulators (Orca-managed + raw serve-sim)',
|
|
usage: 'orca emulator list [--worktree <selector>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'worktree']
|
|
},
|
|
{
|
|
path: ['emulator', 'devices'],
|
|
summary: 'List all emulator devices/AVDs across iOS and Android',
|
|
usage: 'orca emulator devices [--worktree <selector>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'worktree']
|
|
},
|
|
{
|
|
path: ['emulator', 'attach'],
|
|
summary: 'Attach/start helper for a device and make it active for the worktree',
|
|
usage: 'orca emulator attach [device] [--worktree <selector>] [--focus] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'worktree', 'focus', 'device'],
|
|
positionalArgs: ['device']
|
|
},
|
|
{
|
|
path: ['emulator', 'tap'],
|
|
summary: 'Tap at normalized 0..1 coords (preferred for single taps)',
|
|
usage: 'orca emulator tap <x> <y> [--device <id>] [--worktree <selector>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'device', 'emulator', 'worktree', 'x', 'y'],
|
|
positionalArgs: ['x', 'y']
|
|
},
|
|
{
|
|
path: ['emulator', 'type'],
|
|
summary: 'Type text (US ASCII only)',
|
|
usage: 'orca emulator type <text> [--device <id>] [--worktree <selector>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'text', 'device', 'emulator', 'worktree'],
|
|
positionalArgs: ['text']
|
|
},
|
|
{
|
|
path: ['emulator', 'gesture'],
|
|
summary: 'Send a multi-point gesture sequence',
|
|
usage: "orca emulator gesture '<json>' [--device <id>] [--worktree <selector>] [--json]",
|
|
allowedFlags: [...GLOBAL_FLAGS, 'points', 'device', 'emulator', 'worktree'],
|
|
positionalArgs: ['points']
|
|
},
|
|
{
|
|
path: ['emulator', 'button'],
|
|
summary: 'Hardware button (home, side_button, etc.)',
|
|
usage: 'orca emulator button <name> [--device <id>] [--worktree <selector>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'device', 'emulator', 'worktree', 'name'],
|
|
positionalArgs: ['name']
|
|
},
|
|
{
|
|
path: ['emulator', 'rotate'],
|
|
summary: 'Rotate device',
|
|
usage: 'orca emulator rotate <orientation> [--device <id>] [--worktree <selector>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'device', 'emulator', 'worktree', 'orientation'],
|
|
positionalArgs: ['orientation']
|
|
},
|
|
{
|
|
path: ['emulator', 'exec'],
|
|
summary:
|
|
'Raw passthrough (e.g. orca emulator exec --command "tap 0.5 0.7" or "ca-debug blended on")',
|
|
usage: 'orca emulator exec --command <cmd> [--device <id>] [--worktree <selector>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'command', 'device', 'emulator', 'worktree']
|
|
},
|
|
{
|
|
path: ['emulator', 'kill'],
|
|
summary: 'Stop helper for device',
|
|
usage: 'orca emulator kill [--device <id>] [--worktree <selector>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'device', 'emulator', 'worktree']
|
|
},
|
|
{
|
|
path: ['emulator', 'shutdown'],
|
|
summary: 'Stop helper and shut down the simulator device',
|
|
usage:
|
|
'orca emulator shutdown [--device <id>] [--emulator <id>] [--worktree <selector>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'device', 'emulator', 'worktree']
|
|
},
|
|
{
|
|
path: ['emulator', 'install'],
|
|
summary: 'Install an APK onto the target Android device',
|
|
usage: 'orca emulator install <apkPath> [--reinstall] [--device <id>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'device', 'emulator', 'worktree', 'path', 'reinstall'],
|
|
positionalArgs: ['path']
|
|
},
|
|
{
|
|
path: ['emulator', 'launch'],
|
|
summary: 'Launch an Android app by package (and optional activity)',
|
|
usage: 'orca emulator launch <package> [--activity <name>] [--device <id>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'device', 'emulator', 'worktree', 'package', 'activity'],
|
|
positionalArgs: ['package']
|
|
},
|
|
{
|
|
path: ['emulator', 'permissions'],
|
|
summary: 'Grant/revoke an Android runtime permission, or reset all runtime grants',
|
|
usage:
|
|
'orca emulator permissions <grant|revoke> <package> <permission> [--device <id>] [--json]\n orca emulator permissions reset [--device <id>] [--json]',
|
|
allowedFlags: [
|
|
...GLOBAL_FLAGS,
|
|
'device',
|
|
'emulator',
|
|
'worktree',
|
|
'op',
|
|
'package',
|
|
'permission'
|
|
],
|
|
positionalArgs: ['op', 'package', 'permission']
|
|
},
|
|
{
|
|
path: ['emulator', 'ax'],
|
|
summary: 'Dump the accessibility tree (Android uiautomator; iOS serve-sim AX, frames 0..1)',
|
|
usage: 'orca emulator ax [--device <id>] [--worktree <selector>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'device', 'emulator', 'worktree']
|
|
},
|
|
{
|
|
path: ['emulator', 'logcat'],
|
|
summary: 'Capture a one-shot logcat dump from the Android device',
|
|
usage: 'orca emulator logcat [--lines <n>] [--device <id>] [--worktree <selector>] [--json]',
|
|
allowedFlags: [...GLOBAL_FLAGS, 'device', 'emulator', 'worktree', 'lines']
|
|
}
|
|
]
|