Commands
This page summarizes the primary command groups.
For persistent defaults and project-scoped CLI settings, see Configuration.
Navigation
bootensures the selected target is ready without launching an app.bootrequires either an active session or an explicit device selector.--platform appleis an alias for the Apple automation backend (ios,tvOS,macOSselection).- Use
--target mobile|tv|desktopwith--platform(required) to select phone/tablet vs TV-class vs desktop-class targets. bootis mainly needed when starting a new session andopenfails because no booted simulator/emulator is available.- Android:
boot --platform android --device <avd-name>launches that emulator in GUI mode when needed. - Android: add
--headlessto launch without opening a GUI window. open [app|url] [url]already boots/activates the selected target when needed.open <url>deep links are supported on Android and iOS.open <app> <url>opens a deep link on iOS.- On iOS devices,
http(s)://URLs open in Safari when no app is active. Custom scheme URLs require an active app in the session. AGENT_DEVICE_SESSIONandAGENT_DEVICE_PLATFORMcan pre-bind a default session/platform for CLI automation runs, so normal commands (open,snapshot,press,fill,screenshot,devices, andbatch) do not need those flags repeated on every call.- A configured
AGENT_DEVICE_SESSIONnow implies bound-session lock mode by default. The CLI forwards that policy to the daemon, which enforces the same conflict handling for CLI, typed client, and direct RPC requests. --session-lock reject|stripsets the lock policy for a single CLI invocation, including nested batch steps.AGENT_DEVICE_SESSION_LOCK=reject|stripsets the default lock policy for bound-session automation runs. The older--session-locked,--session-lock-conflicts,AGENT_DEVICE_SESSION_LOCKED, andAGENT_DEVICE_SESSION_LOCK_CONFLICTSforms remain supported as compatibility aliases.- Direct RPC callers can pass
meta.lockPolicyand optionalmeta.lockPlatformonagent_device.commandrequests for the same daemon-enforced behavior. - In
batch, steps that omitplatformstill inherit the parent batch--platform; lock-mode defaults do not override that parent setting. - Tenant-scoped daemon runs can pass
--tenant,--session-isolation tenant,--run-id, and--lease-idto enforce lease admission. - Remote daemon clients can pass
--daemon-base-url http(s)://host:port[/base-path]to skip local daemon discovery/startup and call a remote HTTP daemon directly. - Use
--daemon-auth-token <token>(orAGENT_DEVICE_DAEMON_AUTH_TOKEN) when the remote daemon expects the shared daemon token over HTTP; the client sends it in both the JSON-RPC request token and HTTP auth headers. open <app> --remote-config <path> --relaunchis the canonical remote Metro-backed launch flow for sandbox agents. The remote profile supplies the remote host + Metro settings,openprepares Metro locally when needed, derives platform runtime hints, and forwards them inline to the remote daemon before launch.metro prepare --remote-config <path>remains available for inspection and debugging. It prints JSON runtime hints to stdout,--jsonwraps them in the standard{ success, data }envelope, and--runtime-file <path>persists the same payload when callers need an artifact.- Android React Native relaunch flows require an installed package name for
open --relaunch; install/reinstall the APK first, then relaunch by package.open <apk|aab> --relaunchis rejected because runtime hints are written through the installed app sandbox. - Remote daemon screenshots and recordings are downloaded back to the caller path, so
screenshot page.pngandrecord start session.mp4remain usable when the daemon runs on another host.
Device isolation scopes
--ios-simulator-device-set <path>constrains simulator discovery and simulator command execution viaxcrun simctl --set <path> ....--android-device-allowlist <serials>constrains Android discovery/selection to comma or space separated serials.- Scope is applied before selectors (
--device,--udid,--serial), so out-of-scope selectors fail withDEVICE_NOT_FOUND. - With iOS simulator-set scope enabled, iOS physical devices are not enumerated.
- Environment equivalents:
- iOS:
AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET(compat:IOS_SIMULATOR_DEVICE_SET) - Android:
AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST(compat:ANDROID_DEVICE_ALLOWLIST)
- iOS:
- CLI scope flags override environment values unless bound-session lock mode is active with
strip, in which case conflicting per-call selectors are ignored.
Device discovery
deviceslists available targets after applying any platform selector or isolation scope flags.- Use
--platformto narrow discovery to Apple-family (ios,tvOS,macOS) or Android targets. - Use
--ios-simulator-device-setand--android-device-allowlistwhen you need tenant- or lab-scoped discovery.
Simulator provisioning
ensure-simulatorensures a named iOS simulator exists inside a device set, creating it viasimctl createif missing.- Requires
--device <name>(the simulator name / device type, e.g."iPhone 16 Pro"). --runtime <id>pins a specific CoreSimulator runtime (e.g.com.apple.CoreSimulator.SimRuntime.iOS-18-4). Omit to use the newest compatible runtime.--bootboots the simulator after ensuring it exists.- Reuse of an existing matching simulator is the default; the command is idempotent.
- JSON output includes
udid,device,runtime,ios_simulator_device_set,created, andbooted. - Does not require an active session — safe to call before
open.
TV targets
- AndroidTV app launch and app listing resolve TV launchable activities via
LEANBACK_LAUNCHER. - TV target selection supports both simulator/emulator and connected physical devices (AppleTV + AndroidTV).
- tvOS supports the same runner-driven interaction/snapshot flow as iOS (
snapshot,wait,press,fill,get,scroll,back,home,app-switcher,record, and related selector flows). - On tvOS, runner
back/home/app-switchermap to Siri Remote actions (menu,home, double-home). - tvOS follows iOS simulator-only command semantics for helpers like
pinch,settings, andpush.
Desktop targets
--platform macosselects the host Mac as adesktoptarget.--platform apple --target desktopselects the same macOS backend through the Apple-family alias.- macOS uses the same runner-driven interaction/snapshot flow as iOS/tvOS for
open,appstate,snapshot,press,fill,scroll,back,screenshot,record, and selector-based commands. - macOS also supports
clipboard read|write,trigger-app-event, and onlysettings appearance light|dark|toggle. - Prefer selector or
@ref-driven interactions on macOS. Window position can shift between runs, so raw x/y point commands are less stable than snapshot-derived targets. - Mobile-only helpers remain unsupported on macOS:
boot,home,app-switcher,install,reinstall,install-from-source,push,logs, andnetwork.
Snapshot and inspect
- iOS snapshots use XCTest on simulators and physical devices.
diff snapshotcompares the current snapshot with the previous session baseline and then updates baseline.
Wait and alerts
waitaccepts a millisecond duration,text <value>, a snapshot ref (@eN), or a selector.wait <selector> [timeoutMs]polls until the selector resolves or the timeout expires.wait @ref [timeoutMs]requires an existing session snapshot from a priorsnapshotcommand.wait @refresolves the ref to its label/text from that stored snapshot, then polls for that text; it does not track the original node identity.- Because
wait @refis text-based after resolution, duplicate labels can match a different element than the original ref target. waitshares the selector/snapshot resolution flow used byclick,fill,get, andis.alertinspects or handles system alerts on iOS simulator targets.alertwithout an action is equivalent toalert get.alert wait [timeout]waits for an alert to appear before returning it.
Interactions
fill clears then types. type does not clear.
On Android, fill also verifies text and performs one clear-and-retry pass on mismatch.
Some Android images cannot enter non-ASCII text over shell input; in that case use a trusted ADB keyboard IME and verify APK checksum/signature before install.
click --button secondary is the desktop context-menu flow on macOS.
click --button middle is reserved for future runner support and currently returns an explicit unsupported-operation error on macOS.
swipe accepts an optional durationMs argument (default 250ms, range 16..10000).
On iOS, swipe duration is clamped to a safe range (16..60ms) to avoid longpress side effects.
scrollintoview accepts plain text or a snapshot ref (@eN); ref mode uses best-effort geometry-based scrolling without post-scroll verification. Run snapshot again before follow-up @ref commands.
longpress is supported on iOS and Android.
pinch is iOS simulator-only.
Find (semantic)
Assertions
isevaluates UI predicates against a selector expression and exits non-zero on failure.- Supported predicates are
visible,hidden,exists,editable,selected, andtext. is text <selector> <value>compares the resolved element text against the expected value.isdoes not accept snapshot refs like@e3; use a selector expression instead.isaccepts the same selector-oriented snapshot flags asclick,fill,get, andwait.
Replay
replayruns deterministic.adscripts.replay -uupdates stale recorded actions and rewrites the same script.--save-scriptrecords a replay script onclose; optional path is a file path and parent directories are created.
See Replay & E2E (Experimental) for recording and CI workflow details.
Batch
batchruns a JSON array of steps in a single daemon request.- Each step has
command, optionalpositionals, and optionalflags. - Stop-on-first-error is the supported behavior (
--on-error stop). - Use
--max-steps <n>to tighten per-request safety limits. - Batch requests inherit the same daemon lock policy and session binding metadata as the parent command.
See Batching for payload format, response shape, and usage guidelines.
App install (in-place)
install <app> <path>installs from binary path without uninstalling first.- Supports Android devices/emulators, iOS simulators, and iOS physical devices.
- Useful for upgrade flows where you want to keep existing app data when supported by the platform.
- Remote daemons automatically upload local app artifacts for
install; prefix the path withremote:to use a daemon-side path verbatim. - Supported binary formats: Android
.apk/.aab, iOS.app/.ipa. .aabrequiresbundletoolinPATH, orAGENT_DEVICE_BUNDLETOOL_JAR=<path-to-bundletool-all.jar>withjavainPATH.- Optional:
AGENT_DEVICE_ANDROID_BUNDLETOOL_MODE=<mode>overrides bundletoolbuild-apks --mode(default:universal). .ipainstalls by extractingPayload/*.app; if multiple app bundles exist,<app>is used as a bundle id/name hint to select one.
App reinstall (fresh state)
reinstall <app> <path>uninstalls and installs in one command.- Supports Android devices/emulators, iOS simulators, and iOS physical devices.
- Useful for login/logout reset flows and deterministic test setup.
- Remote daemons automatically upload local app artifacts for
reinstall; prefix the path withremote:to use a daemon-side path verbatim. - Supported binary formats: Android
.apk/.aab, iOS.app/.ipa. .aabaccepts the same bundletool requirements and optionalAGENT_DEVICE_ANDROID_BUNDLETOOL_MODEoverride asinstall..ipauses<app>as the selection hint when multiplePayload/*.appbundles are present.
App install from source URL
install-from-source <url>installs from a URL source through the normal daemon artifact flow.- Repeat
--header <name:value>for authenticated or signed artifact requests. - Supports the same device coverage as
install: Android devices/emulators, iOS simulators, and iOS physical devices. --retain-pathskeeps retained materialized artifact paths after install, and--retention-ms <ms>sets their TTL.- URL downloads follow the same
installFromSource()safety checks and host restrictions as the JS client API.
Push notification simulation
push <bundle|package> <payload.json|inline-json>simulates push notification delivery.- iOS push simulation is simulator-only (
xcrun simctl push) and requires an APNs-style JSON object payload. - Android uses
adb shell am broadcastand accepts payload shape:{"action":"<intent-action>","receiver":"<optional component>","extras":{"key":"value","flag":true,"count":3}}. - Android extras support
string,boolean, andnumbervalues. pushworks with the active session device, or with explicit selectors (--platform,--device,--udid,--serial).
App event triggers (app hook)
trigger-app-event <event> [payloadJson]dispatches app-defined events via deep link.trigger-app-eventrequires either an active session or explicit device selectors (--platform,--device,--udid,--serial).- On macOS, use
AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATEto override the desktop deep-link template. - On iOS physical devices, custom-scheme deep links require active app context (open app first in the session).
- Configure one of:
AGENT_DEVICE_APP_EVENT_URL_TEMPLATEAGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATEAGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATEAGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE
- Template placeholders:
{event},{payload},{platform}. - Example template:
myapp://agent-device/event?name={event}&payload={payload}. payloadJsonmust be a JSON object.- This is app-hook-based simulation and does not inject OS-global notifications.
Settings helpers
- iOS
settingssupport is simulator-only except forsettings appearanceon macOS. settings appearancemaps to macOS appearance, iOS simulator appearance, and Android night mode.- Face ID and Touch ID controls are iOS simulator-only.
- Fingerprint simulation is supported on Android targets where
cmd fingerprintoradb emu fingeris available. On physical Android devices, onlycmd fingerprintis attempted. - Permission actions are scoped to the active session app.
- iOS permission targets:
camera,microphone,photos(fullorlimited),contacts,notifications. - Android permission targets:
camera,microphone,photos,contacts,notifications. - Android uses
pm grant|revokefor runtime permissions (resetmaps to revoke) andappopsfor notifications. full|limitedmode is supported only for iOSphotos; other targets reject mode.- Use
match/nonmatchto simulate valid/invalid Face ID, Touch ID, and Android fingerprint outcomes.
App state and app lists
- Android
appstatereports live foreground package/activity. - iOS
appstateis session-scoped and reports the app tracked by the active session on the target device. appsincludes default/system apps by default (use--user-installedto filter).
Clipboard
clipboard readreturns clipboard text for the selected target.clipboard write <text>updates clipboard text on the selected target.- Works with an active session device or explicit selectors (
--platform,--device,--udid,--serial). - Supported on macOS, Android emulator/device, and iOS simulator.
- iOS physical devices currently return
UNSUPPORTED_OPERATIONfor clipboard commands.
Keyboard (Android)
keyboard status(orkeyboard get) returns keyboard visibility and best-effort input type classification.keyboard dismissdismisses keyboard with Android back keyevent only when the keyboard is visible, then confirms hidden state.- Works with active sessions and explicit selectors (
--platform,--device,--udid,--serial). - Supported on Android emulator/device.
Performance metrics
perf(alias:metrics) returns a session-scoped metrics JSON blob.- Current metric:
startupfromopen-command-roundtripsampling. - Sampling method: elapsed wall-clock time around each
opencommand dispatch for the active session app target. - Unit: milliseconds (
ms). - Platform support for current startup sampling: iOS simulator, iOS physical device, Android emulator/device.
fps,memory, andcpuare surfaced as unavailable placeholders in this release.- If no startup sample exists yet for the session, run
open <app|url>first and retryperf. - Interpretation note: this startup metric is command round-trip timing and does not represent true first frame / first interactive app instrumentation.
Media and logs
- Recordings always produce a video artifact. When touch visualization is enabled, they also produce a gesture telemetry sidecar that can be used for post-processing or inspection.
- Burned-in touch overlays are exported only on macOS hosts, because the overlay pipeline depends on Swift + AVFoundation helpers.
- On Linux or other non-macOS hosts,
record stopstill succeeds and returns the raw video plus telemetry sidecar, and includesoverlayWarningwhen burn-in overlays were skipped.
Session app logs (token-efficient debugging): Logging is off by default in normal flows. Enable it on demand for debugging. Logs are written to a file so agents can grep instead of loading full output into context.
- Supported on iOS simulator, iOS physical device, and Android.
- Preferred debug entrypoint:
logs clear --restartfor clean-window repro loops. logs startappends toapp.logand rotates toapp.log.1when the file exceeds 5 MB.network dump [limit] [summary|headers|body|all]parses recent HTTP(s) entries fromapp.log;network log ...is an alias.- Network dump limits: scans up to 4000 recent log lines, returns up to 200 entries, and truncates payload/header fields at 2048 characters.
- Android log streaming automatically rebinds to the app PID after process restarts.
- iOS log capture relies on Unified Logging signals (for example
os_log); plain stdout/stderr output may be limited depending on app/runtime. - Retention knobs: set
AGENT_DEVICE_APP_LOG_MAX_BYTESandAGENT_DEVICE_APP_LOG_MAX_FILESto override rotation limits. - Optional write-time redaction patterns: set
AGENT_DEVICE_APP_LOG_REDACT_PATTERNSto a comma-separated regex list.
Grepping app logs: Use logs path to get the file path, then run grep (or grep -E) on that path so only matching lines enter context—keeping token use low.
-
Use
-nto include line numbers. Use-Efor extended regex and|without escaping in the pattern. -
Prefer targeted patterns (e.g.
Error,Exception, your log tags) over reading the whole file. -
iOS
recordworks on simulators and physical devices. -
iOS simulator recording uses native
simctl io ... recordVideo. -
Physical iOS device capture is runner-based and built from repeated
XCUIScreen.main.screenshot()frames (no native video stream/audio capture). -
Physical iOS device recording requires an active app session context (
open <app>first). -
Physical iOS device capture is best-effort: dropped frames are expected and true 60 FPS is not guaranteed even with
--fps 60. -
Physical-device capture defaults to 15 FPS.
-
--fps <n>(1-120) applies to physical iOS device recording as an explicit FPS cap.
Tracing
trace start [path]begins trace-log capture for the active session.trace stop [path]stops capture and optionally writes or finalizes the trace artifact at the provided path.traceis intended for lower-level session diagnostics thanrecordorlogs.
Remote Metro workflow
--remote-config <path>points to a remote workflow profile that captures stable host + Metro settings.open --remote-config ... --relaunchis the main agent flow. It prepares Metro locally, derives platform runtime hints, and forwards them inline to the remote daemon before launch.snapshot,press,fill,screenshot, and other normal commands can reuse the same--remote-configprofile so agents do not need to repeat remote host/session selectors inline.metro prepare --remote-config ...remains the inspection/debug path and can still write a--runtime-file <path>artifact when needed.
Session inspection
session listshows active daemon sessions and their tracked device/app context.- Use
--jsonwhen you want to inspect or script against the raw session metadata.
iOS device prerequisites
- Xcode +
xcrun devicectlavailable. - Paired physical device with Developer Mode enabled.
- Use Automatic Signing in Xcode, or pass optional env overrides:
AGENT_DEVICE_IOS_TEAM_IDAGENT_DEVICE_IOS_SIGNING_IDENTITY(optional)AGENT_DEVICE_IOS_PROVISIONING_PROFILEAGENT_DEVICE_IOS_BUNDLE_ID(runner bundle-id base; tests use<id>.uitests)
- Free Apple Developer (Personal Team) accounts can fail on unavailable generic bundle IDs; set
AGENT_DEVICE_IOS_BUNDLE_IDto a unique reverse-DNS value. - If first-run XCTest setup/build is slow, increase daemon request timeout:
AGENT_DEVICE_DAEMON_TIMEOUT_MS=120000(default is90000)
- For daemon startup troubleshooting:
- follow stale metadata hints for
<state-dir>/daemon.jsonand<state-dir>/daemon.lock(state-dirdefaults to~/.agent-device)
- follow stale metadata hints for
