{"about":"Drive and debug Android apps from the command line: agent-first UI automation, a streaming JSON event timeline (UI, crashes, network), HTTP(S) interception, and an in-process runtime for debuggable apps.","commands":[{"about":"Reserve devices for drivers and provide passive observations to advisers","contract":{"output_mode":"json"},"examples":["--device emulator-5554 session open --agent driver-a","--device emulator-5554 session observe --subscription adviser-b"],"name":"session","path":"session","runs":"remote","subcommands":[{"about":"Reserve an online device across commands, in one command: it observes the device for the new driver, applies settings and starting state, and keeps a journal. Opened by a caller that already holds the reservation, it nests: own settings, folder and cleanup on the shared reservation. Ownership has no automatic expiry","args":[{"action":"Set","help":"Human-readable agent identity (not an authentication credential)","long":"agent","name":"agent","required":true,"takes_value":true,"value_names":["AGENT"]},{"action":"Set","dir":"out","help":"Write the driver token to a new private file instead of stdout. Required with --redact; reuse it with --session-file","long":"token-out","name":"token_out","takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"Set","help":"The app under test (package or configured alias): turns on the foreground, crash and covered-screen guards, and is the default package for starting-state flags","long":"app","name":"app","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","default_values":["10000"],"help":"How long later actions wait for their target to appear, be unique and enabled (actions that support a target wait)","long":"wait-ms","name":"wait_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["10000"],"help":"How long later `--expect-*` checks and `ui wait` wait, unless the command sets its own --timeout-ms","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["0"],"help":"Minimum gap between commands, for slow devices or demos. Never needed for correctness; reported as a flake signal when set","long":"pace-ms","name":"pace_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Evidence per command: `steps` saves screens and a screenshot around every action; `failures` only when one fails; `off` none. Default: `failures` under `olef test run`, else `steps`","long":"capture","name":"capture","possible_values":["steps","failures","off"],"takes_value":true,"value_names":["CAPTURE"]},{"action":"SetTrue","help":"Do not keep the session journal (no journal, screens or failure reports)","long":"no-journal","name":"no_journal","possible_values":["true","false"],"value_names":["NO_JOURNAL"]},{"action":"Set","dir":"dir","help":"Folder for the journal, screens, failure reports and report.html. Default: $OLEF_RUN_DIR under `test run`, else `.olef/sessions/<id>/`","long":"run-dir","name":"run_dir","takes_value":true,"value_hint":"AnyPath","value_names":["DIR"]},{"action":"SetTrue","help":"A crash of an app process does not fail a step in this session","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"Skip the preflight checks (system UI in front, a foreign http_proxy, clock skew, leftover notifications)","long":"no-preflight","name":"no_preflight","possible_values":["true","false"],"value_names":["NO_PREFLIGHT"]},{"action":"SetTrue","help":"Start from a fresh install's state: clear the app's data","long":"clear-data","name":"clear_data","possible_values":["true","false"],"value_names":["CLEAR_DATA"]},{"action":"SetTrue","help":"Return every runtime permission to its fresh-install state (not granted, and asking again even after \"don't ask again\"), so the app's permission dialogs appear as on a first run. Not restored at close","long":"reset-permissions","name":"reset_permissions","possible_values":["true","false"],"value_names":["RESET_PERMISSIONS"]},{"action":"Append","help":"Grant this runtime permission to the app at open; restored at close","long":"grant","name":"grant","takes_value":true,"value_names":["PERMISSION"]},{"action":"Append","help":"Revoke this runtime permission at open; restored at close","long":"revoke","name":"revoke","takes_value":true,"value_names":["PERMISSION"]},{"action":"Append","help":"Deny this runtime permission with \"don't ask again\" at open (revoked, user-set and user-fixed), so the app's dialog for it never shows; restored at close","long":"deny","name":"deny","takes_value":true,"value_names":["PERMISSION"]},{"action":"Append","help":"Return this one runtime permission to its fresh-install state (not granted, asking again), so its dialog appears as on a first run. Not restored at close","long":"reset-permission","name":"reset_permission","takes_value":true,"value_names":["PERMISSION"]},{"action":"Set","help":"Apply a display profile preset (`automation`: animations off); restored at close","long":"profile","name":"profile","takes_value":true,"value_names":["PRESET"]},{"action":"Set","help":"Launch the app at open, optionally at this activity (`.MainActivity`)","long":"launch","name":"launch","num_args":"0..=1","takes_value":true,"value_names":["ACTIVITY"]},{"action":"Set","help":"With --launch: wait until this text is on screen","long":"expect-text","name":"expect_text","requires":["launch"],"takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"With --launch: wait until this resource id or test tag is on screen","long":"expect-rid","name":"expect_rid","requires":["launch"],"takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","wait_ms","timeout_ms","pace_ms","capture","no_journal","run_dir","allow_crash","no_preflight","clear_data","reset_permissions","grant","revoke","deny","reset_permission","profile","launch","expect_text","expect_rid"],"multiple":true,"name":"OpenArgs","required":false}],"contract":{"output_mode":"json"},"examples":["session open --agent explorer --token-out session.token --app io.github.andriyo.shadowdroid.sample --launch .MainActivity --expect-rid status_text"],"name":"open","path":"session open","runs":"remote"},{"about":"Read owner and interrupted-operation metadata without changing ownership","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"examples":["--device emulator-5554 session open --agent driver-a","--device emulator-5554 session observe --subscription adviser-b"],"name":"status","path":"session status","runs":"remote"},{"about":"Undo the session's starting state, write its summary and report.html, and release the reservation (or return to the outer session when nested). Stop its proxy/recorder first. A token file that was never written closes nothing, so a script can arm its trap before opening","args":[{"action":"Set","allow_hyphen_values":true,"help":"The script's exit status (`$?` in a trap): 0 marks the run passed","long":"exit-code","name":"exit_code","takes_value":true,"value_names":["CODE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"examples":["--session-file session.token session close --exit-code 0"],"name":"close","path":"session close","runs":"remote"},{"about":"Clear an interrupted operation: on the same boot when it was only server UI input and that server is idle or gone, otherwise after a verified device reboot and external-worker review","args":[{"action":"SetTrue","help":"Attest that all external test/build/ADB workers from the interrupted command are stopped","long":"external-workers-stopped","name":"external_workers_stopped","possible_values":["true","false"],"value_names":["EXTERNAL_WORKERS_STOPPED"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"examples":["--device emulator-5554 session open --agent driver-a","--device emulator-5554 session observe --subscription adviser-b"],"name":"recover","path":"session recover","runs":"remote"},{"about":"Transfer an idle device, revoking the old token; retain a handoff context artifact","args":[{"action":"Set","long":"agent","name":"agent","required":true,"takes_value":true,"value_names":["AGENT"]},{"action":"Set","dir":"in","help":"Path to a JSON file (an object, at most 1 MiB) with candidate, plan, backend and starting-state references","long":"context","name":"context","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"Set","dir":"out","help":"Write the recipient's token to a new private file instead of stdout. Required with --redact; reuse it with --session-file","long":"token-out","name":"token_out","takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["agent","context","token_out"],"multiple":true,"name":"Handoff","required":false}],"contract":{"output_mode":"json"},"examples":["--device emulator-5554 session open --agent driver-a","--device emulator-5554 session observe --subscription adviser-b"],"name":"handoff","path":"session handoff","runs":"remote"},{"about":"Observe existing UI and independently consume crashes; never installs or reconnects","args":[{"action":"Set","help":"Independent event consumer ID; use a different ID for each adviser","long":"subscription","name":"subscription","required":true,"takes_value":true,"value_names":["SUBSCRIPTION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"examples":["--device emulator-5554 session open --agent driver-a","--device emulator-5554 session observe --subscription adviser-b"],"name":"observe","path":"session observe","runs":"remote"}]},{"about":"Plan verification and inspect test evidence with explicit coverage","contract":{"output_mode":"json"},"examples":["verify plan validate verification.json","verify junit --report TEST-app.xml --selection all --out baseline.json"],"name":"verify","path":"verify","runs":"remote","subcommands":[{"about":"Execute a bounded plan and preserve immutable per-check evidence","args":[{"action":"Set","dir":"in","name":"plan","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["PLAN"]},{"action":"Set","dir":"out","help":"New evidence directory outside the source root","long":"out","name":"out","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"SetTrue","help":"Run only host adapters; refuse all device and instrumentation checks","long":"host-only","name":"host_only","possible_values":["true","false"],"value_names":["HOST_ONLY"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["plan","out","host_only"],"multiple":true,"name":"Run","required":false}],"contract":{"output_mode":"json"},"examples":["verify run verification.json --host-only --out /tmp/verification-run"],"name":"run","path":"verify run","runs":"remote"},{"about":"Read a saved run and recheck source/plan and evidence hashes without a device","args":[{"action":"Set","dir":"in","name":"run","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["RUN"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"report","path":"verify report","runs":"remote"},{"about":"Release an interrupted run's source/build ownership after external-worker review","args":[{"action":"Set","dir":"dir","name":"run","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["RUN"]},{"action":"SetTrue","long":"external-workers-stopped","name":"external_workers_stopped","possible_values":["true","false"],"value_names":["EXTERNAL_WORKERS_STOPPED"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["run","external_workers_stopped"],"multiple":true,"name":"Recover","required":false}],"contract":{"output_mode":"json"},"name":"recover","path":"verify recover","runs":"remote"},{"about":"Validate requirement coverage, adapter inputs and dependency ordering offline","contract":{"output_mode":"json"},"examples":["verify plan validate verification.json","verify junit --report TEST-app.xml --selection all --out baseline.json"],"name":"plan","path":"verify plan","runs":"remote","subcommands":[{"about":"Validate schema version 1 without connecting to a device or running tests","args":[{"action":"Set","dir":"in","name":"plan","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["PLAN"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"examples":["verify plan validate verification.json","verify junit --report TEST-app.xml --selection all --out baseline.json"],"name":"validate","path":"verify plan validate","runs":"remote"}]},{"about":"Parse saved JUnit reports. This is an observation, not proof of a fresh execution","args":[{"action":"Append","dir":"in","help":"XML reports; each expected report must be present and complete","long":"report","name":"report","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["REPORT"]},{"action":"Set","help":"Stable description of the test selection, used for baseline comparisons","long":"selection","name":"selection","required":true,"takes_value":true,"value_names":["SELECTION"]},{"action":"Set","default_values":["1"],"help":"Minimum expected number of test cases; empty suites never pass","long":"minimum-tests","name":"minimum_tests","takes_value":true,"value_names":["MINIMUM_TESTS"]},{"action":"Set","dir":"out","help":"Save the normalized report for later baseline comparison","long":"out","name":"out","takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["report","selection","minimum_tests","out"],"multiple":true,"name":"Junit","required":false}],"contract":{"output_mode":"json"},"examples":["verify plan validate verification.json","verify junit --report TEST-app.xml --selection all --out baseline.json"],"name":"junit","path":"verify junit","runs":"remote"},{"about":"Compare two normalized reports without silently discarding missing tests","args":[{"action":"Set","dir":"in","long":"baseline","name":"baseline","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["BASELINE"]},{"action":"Set","dir":"in","long":"candidate","name":"candidate","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["CANDIDATE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["baseline","candidate"],"multiple":true,"name":"Compare","required":false}],"contract":{"output_mode":"json"},"examples":["verify plan validate verification.json","verify junit --report TEST-app.xml --selection all --out baseline.json"],"name":"compare","path":"verify compare","runs":"remote"}]},{"about":"Correlate UI, network, video and projected application state","contract":{"output_mode":"json"},"examples":["evidence checkpoint 'after refresh' --out evidence --spec probes.json"],"name":"evidence","path":"evidence","runs":"remote","subcommands":[{"about":"Link a UI snapshot, network checkpoint, video marker and selected fields","args":[{"action":"Set","name":"label","positional":true,"required":true,"takes_value":true,"value_names":["LABEL"]},{"action":"Set","dir":"dir","help":"New or existing Olef evidence bundle directory","long":"out","name":"out","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"Set","dir":"in","help":"JSON storage/flow projections; only selected fields are retained","long":"spec","name":"spec","takes_value":true,"value_hint":"AnyPath","value_names":["SPEC"]},{"action":"Set","default_values":["300"],"long":"since-seconds","name":"since_seconds","takes_value":true,"value_names":["SINCE_SECONDS"]},{"action":"Set","default_values":["100"],"long":"flow-limit","name":"flow_limit","takes_value":true,"value_names":["FLOW_LIMIT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["label","out","spec","since_seconds","flow_limit"],"multiple":true,"name":"Checkpoint","required":false}],"contract":{"output_mode":"json"},"examples":["evidence checkpoint 'after refresh' --out evidence --spec probes.json"],"name":"checkpoint","path":"evidence checkpoint","runs":"remote"},{"about":"Read all saved checkpoints, deduplicate events, and sort by event time","args":[{"action":"Set","dir":"in","name":"bundle","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["BUNDLE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"timeline","path":"evidence timeline","runs":"remote"}]},{"about":"Olef Cloud (invite-only alpha): sign in, link this project, and run its commands on a cloud emulator (`cloud login`, `cloud link`, `cloud status`)","args":[],"contract":{"output_mode":"json"},"name":"cloud","path":"cloud","runs":"local","subcommands":[{"about":"Sign in to Olef Cloud: approve this machine at app.olef.dev/activate (opens the browser when there is one)","args":[{"action":"SetTrue","help":"Print the sign-in URL and code instead of opening a browser","long":"no-browser","name":"no_browser","possible_values":["true","false"],"value_names":["NO_BROWSER"]},{"action":"SetTrue","help":"Return at once with the code and URL; run `cloud login` again to finish after the person approved","long":"no-wait","name":"no_wait","possible_values":["true","false"],"value_names":["NO_WAIT"]},{"action":"SetTrue","help":"Read an access key (or a refresh token) from stdin instead of signing in through a browser (CI, cloud agents)","long":"key-stdin","name":"key_stdin","possible_values":["true","false"],"value_names":["KEY_STDIN"]},{"action":"Set","help":"API base URL (development)","long":"api","name":"api","takes_value":true,"value_names":["URL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["no_browser","no_wait","key_stdin","api"],"multiple":true,"name":"Login","required":false}],"contract":{"output_mode":"json"},"name":"login","path":"cloud login","runs":"local"},{"about":"Sign out: revoke this machine's token and forget it","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"logout","path":"cloud logout","runs":"local"},{"about":"The signed-in account: email, invite state, plan","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"whoami","path":"cloud whoami","runs":"local"},{"about":"Link this project folder to a cloud workspace, after the person approves the upload (on this terminal, or in a browser)","args":[{"action":"Set","dir":"in","help":"The project root (default: the current folder)","name":"path","positional":true,"takes_value":true,"value_hint":"AnyPath","value_names":["PATH"]},{"action":"Set","help":"Workspace name (default: the folder name)","long":"name","name":"name","takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"Don't open the approval page; print its URL","long":"no-browser","name":"no_browser","possible_values":["true","false"],"value_names":["NO_BROWSER"]},{"action":"SetTrue","help":"Return at once with the approval URL; run `cloud link` again to finish after the person approved","long":"no-wait","name":"no_wait","possible_values":["true","false"],"value_names":["NO_WAIT"]},{"action":"SetTrue","help":"Only show what would upload; create nothing","long":"preview","name":"preview","possible_values":["true","false"],"value_names":["PREVIEW"]},{"action":"Set","help":"Record a link to this workspace without the API (development)","long":"dev-workspace","name":"dev_workspace","takes_value":true,"value_names":["ID"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["path","name","no_browser","no_wait","preview","dev_workspace"],"multiple":true,"name":"Link","required":false}],"contract":{"output_mode":"json"},"name":"link","path":"cloud link","runs":"local"},{"about":"Stop the cloud session and unlink a project: commands run locally again","args":[{"action":"Set","dir":"in","help":"The project root (default: the linked project around the current folder)","name":"path","positional":true,"takes_value":true,"value_hint":"AnyPath","value_names":["PATH"]},{"action":"SetTrue","help":"Also delete the cloud workspace (its disk; your files stay here)","long":"delete-workspace","name":"delete_workspace","possible_values":["true","false"],"value_names":["DELETE_WORKSPACE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["path","delete_workspace"],"multiple":true,"name":"Unlink","required":false}],"contract":{"output_mode":"json"},"name":"unlink","path":"cloud unlink","runs":"local"},{"about":"Turn cloud mode on for this linked project","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"on","path":"cloud on","runs":"local"},{"about":"Turn cloud mode off for this linked project (commands run locally; the link stays)","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"off","path":"cloud off","runs":"local"},{"about":"Link, account, session and sync state for this project","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"status","path":"cloud status","runs":"local"},{"about":"Start (or attach to) this project's cloud session and wait until it is ready","args":[{"action":"SetTrue","help":"Return while the session is still starting","long":"no-wait","name":"no_wait","possible_values":["true","false"],"value_names":["NO_WAIT"]},{"action":"Set","default_values":["600000"],"help":"How long to wait for the session","long":"wait-ms","name":"wait_ms","takes_value":true,"value_names":["WAIT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["no_wait","wait_ms"],"multiple":true,"name":"Start","required":false}],"contract":{"output_mode":"json"},"name":"start","path":"cloud start","runs":"local"},{"about":"Stop this project's cloud session (the workspace disk is kept)","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"stop","path":"cloud stop","runs":"local"},{"about":"Sync the project to the workspace now and wait for it to apply","args":[{"action":"SetTrue","help":"Show what would upload, without connecting","long":"dry-run","name":"dry_run","possible_values":["true","false"],"value_names":["DRY_RUN"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"sync","path":"cloud sync","runs":"local"},{"about":"Run any command in the cloud workspace (`cloud run -- ./gradlew testDebugUnitTest`), then bring its source changes back","args":[{"action":"SetTrue","help":"Don't apply the command's source changes locally","long":"no-sync-back","name":"no_sync_back","possible_values":["true","false"],"value_names":["NO_SYNC_BACK"]},{"action":"Append","allow_hyphen_values":true,"help":"The command, after `--`","name":"command","num_args":"1..","positional":true,"required":true,"takes_value":true,"trailing_var_arg":true,"value_names":["COMMAND"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["no_sync_back","command"],"multiple":true,"name":"Run","required":false}],"contract":{"output_mode":"json"},"examples":["cloud run -- ./gradlew testDebugUnitTest","cloud run --no-sync-back -- ./gradlew lint"],"name":"run","path":"cloud run","runs":"local"},{"about":"Usage this period against the plan: included vs used per meter, overage, credits, spend cap, reset date","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"usage","path":"cloud usage","runs":"local"},{"about":"The plan: list plans, change plan, the payment portal, the spend cap, credits","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"plan","path":"cloud plan","runs":"local","subcommands":[{"about":"Switch plan. Without a paid plan: opens Checkout. A higher plan (or monthly to yearly) applies now, prorated; a lower plan or `free` applies at the end of the period. The current plan again undoes a pending change","aliases":["upgrade","downgrade"],"args":[{"action":"Set","help":"The plan id (`olef cloud plan` lists them): free, pro","name":"plan","positional":true,"required":true,"takes_value":true,"value_names":["PLAN"]},{"action":"SetTrue","conflicts_with":["monthly"],"help":"Bill yearly (two months free)","long":"yearly","name":"yearly","possible_values":["true","false"],"value_names":["YEARLY"]},{"action":"SetTrue","help":"Bill monthly","long":"monthly","name":"monthly","possible_values":["true","false"],"value_names":["MONTHLY"]},{"action":"SetTrue","help":"Print the Checkout URL instead of opening a browser","long":"no-browser","name":"no_browser","possible_values":["true","false"],"value_names":["NO_BROWSER"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["plan","yearly","monthly","no_browser"],"multiple":true,"name":"Change","required":false}],"contract":{"output_mode":"json"},"examples":["cloud plan change pro","cloud plan change pro --yearly","cloud plan change free"],"name":"change","path":"cloud plan change","runs":"local"},{"about":"Open the payment portal: card, invoices and receipts, cancel","args":[{"action":"SetTrue","help":"Print the portal URL instead of opening a browser","long":"no-browser","name":"no_browser","possible_values":["true","false"],"value_names":["NO_BROWSER"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"portal","path":"cloud plan portal","runs":"local"},{"about":"Cap this period's bill (plan price plus overage); usage beyond the included amounts stops at the cap. `default` = the plan price + $50","args":[{"action":"Set","name":"usd","positional":true,"required":true,"takes_value":true,"value_names":["USD|default"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"examples":["cloud plan spend-cap 150","cloud plan spend-cap default"],"name":"spend-cap","path":"cloud plan spend-cap","runs":"local"},{"about":"Prepaid credits: the balance and its history. They pay for usage beyond a plan's included amounts before the card","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"credits","path":"cloud plan credits","runs":"local","subcommands":[{"about":"Buy a credit pack at Checkout: 50, 200 or 1000 (= $1,100 of credits)","args":[{"action":"Set","name":"pack","positional":true,"required":true,"takes_value":true,"value_names":["PACK"]},{"action":"SetTrue","help":"Print the Checkout URL instead of opening a browser","long":"no-browser","name":"no_browser","possible_values":["true","false"],"value_names":["NO_BROWSER"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["pack","no_browser"],"multiple":true,"name":"Buy","required":false}],"contract":{"output_mode":"json"},"examples":["cloud plan credits buy 50"],"name":"buy","path":"cloud plan credits buy","runs":"local"}]}]},{"about":"Orgs: the ones you're in, which one cloud verbs use, team orgs, members and invite links","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"org","path":"cloud org","runs":"local","subcommands":[{"about":"The orgs you're in, your role in each, and the one in use","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"list","path":"cloud org list","runs":"local"},{"about":"Use an org for cloud verbs on this machine: new links, leases, `cloud usage` and `cloud plan`. `--clear` goes back to the account's default org","args":[{"action":"Set","help":"The org's slug (or id)","name":"slug","positional":true,"takes_value":true,"value_names":["ORG"]},{"action":"SetTrue","conflicts_with":["slug"],"long":"clear","name":"clear","possible_values":["true","false"],"value_names":["CLEAR"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["slug","clear"],"multiple":true,"name":"Use","required":false}],"contract":{"output_mode":"json"},"examples":["cloud org use acme-mobile","cloud org use --clear"],"name":"use","path":"cloud org use","runs":"local"},{"about":"Create a team org; you're its owner","args":[{"action":"Set","help":"The org's name (\"Acme Mobile\")","name":"name","positional":true,"required":true,"takes_value":true,"value_names":["NAME"]},{"action":"Set","help":"The slug for URLs and `--org` (default: from the name)","long":"slug","name":"slug","takes_value":true,"value_names":["SLUG"]},{"action":"SetTrue","help":"Use it for cloud verbs right away","long":"use","name":"use_it","possible_values":["true","false"],"value_names":["USE_IT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["name","slug","use_it"],"multiple":true,"name":"Create","required":false}],"contract":{"output_mode":"json"},"examples":["cloud org create \"Acme Mobile\" --use"],"name":"create","path":"cloud org create","runs":"local"},{"about":"An invite link to the org in use, for you to share (it's never emailed). Valid 14 days, for one person","args":[{"action":"Set","help":"Only this address can accept it","long":"email","name":"email","takes_value":true,"value_names":["EMAIL"]},{"action":"Set","default_values":["developer"],"help":"developer (default), guest, billing or admin","long":"role","name":"role","takes_value":true,"value_names":["ROLE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["email","role"],"multiple":true,"name":"Invite","required":false}],"contract":{"output_mode":"json"},"examples":["cloud org invite --email dev@example.com","cloud org invite --role guest"],"name":"invite","path":"cloud org invite","runs":"local"},{"about":"The members of the org in use, and its pending invites","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"members","path":"cloud org members","runs":"local"},{"about":"Leave the org in use: your sessions there stop; your workspaces stay with its admins","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"leave","path":"cloud org leave","runs":"local"}]},{"about":"Projects in the org in use: shared repo, settings and secrets, who works on them, and your own workspace from one","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"project","path":"cloud project","runs":"local","subcommands":[{"about":"The projects in the org in use and your role on each","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"list","path":"cloud project list","runs":"local"},{"about":"One project: its repo, shared settings, shared secret names, who works on it, and the workspaces you may see","args":[{"action":"Set","help":"The project's id or slug","name":"project","positional":true,"required":true,"takes_value":true,"value_names":["PROJECT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"show","path":"cloud project show","runs":"local"},{"about":"Create a project in the org in use, from a repo the org's GitHub installations reach (`--repo-id`), or with none (`--name`)","args":[{"action":"Set","help":"GitHub's id of the repository","long":"repo-id","name":"repo_id","takes_value":true,"value_names":["REPO_ID"]},{"action":"Set","help":"Its name (default: the repository's)","long":"name","name":"name","takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility","requires":["name"]}],"argument_groups":[{"args":["repo_id","name"],"multiple":true,"name":"Create","required":false}],"contract":{"output_mode":"json"},"examples":["cloud project create --repo-id 123456","cloud project create --name \"Notes app\""],"name":"create","path":"cloud project create","runs":"local"},{"about":"Make your own workspace from a project (a GitHub working copy of `--branch`, default the repo's default branch)","args":[{"action":"Set","name":"project","positional":true,"required":true,"takes_value":true,"value_names":["PROJECT"]},{"action":"Set","long":"branch","name":"branch","takes_value":true,"value_names":["BRANCH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["project","branch"],"multiple":true,"name":"Workspace","required":false}],"contract":{"output_mode":"json"},"name":"workspace","path":"cloud project workspace","runs":"local"},{"about":"Store a shared secret (project admins). Values are write-only","args":[{"action":"Set","name":"project","positional":true,"required":true,"takes_value":true,"value_names":["PROJECT"]},{"action":"Set","help":"Env name, like `MAPS_API_KEY`","name":"name","positional":true,"required":true,"takes_value":true,"value_names":["NAME"]},{"action":"Set","default_values":["all"],"help":"Who gets it","long":"scope","name":"scope","possible_values":["all","ci","agents"],"takes_value":true,"value_names":["SCOPE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["project","name","scope"],"multiple":true,"name":"SecretSet","required":false}],"contract":{"output_mode":"json"},"examples":["printf %s \"$TOKEN\" | olef cloud project secret-set notes MAPS_API_KEY"],"name":"secret-set","path":"cloud project secret-set","runs":"local"},{"about":"Delete a shared secret (project admins)","args":[{"action":"Set","name":"project","positional":true,"required":true,"takes_value":true,"value_names":["PROJECT"]},{"action":"Set","name":"name","positional":true,"required":true,"takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["project","name"],"multiple":true,"name":"SecretRm","required":false}],"contract":{"output_mode":"json"},"name":"secret-rm","path":"cloud project secret-rm","runs":"local"},{"about":"Give a member (email) or a team (`team:<slug>`) a role on a project (project admins)","args":[{"action":"Set","name":"project","positional":true,"required":true,"takes_value":true,"value_names":["PROJECT"]},{"action":"Set","help":"`dev@example.com` or `team:mobile`","name":"who","positional":true,"required":true,"takes_value":true,"value_names":["WHO"]},{"action":"Set","default_values":["developer"],"long":"role","name":"role","possible_values":["developer","viewer","admin"],"takes_value":true,"value_names":["ROLE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["project","who","role"],"multiple":true,"name":"Grant","required":false}],"contract":{"output_mode":"json"},"examples":["cloud project grant notes dev@example.com --role developer","cloud project grant notes team:mobile --role viewer"],"name":"grant","path":"cloud project grant","runs":"local"}]},{"about":"Share the linked workspace with a teammate to pair or watch","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"share","path":"cloud share","runs":"local","subcommands":[{"about":"Who the linked workspace is shared with, any admin looking inside, and who is attached to its running session","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"list","path":"cloud share list","runs":"local"},{"about":"Invite a member (email) or a team (`team:<slug>`) of the workspace's org to pair (drive the viewer; a linked workspace's files stay on this computer) or, with `--watch`, to watch","args":[{"action":"Set","help":"`dev@example.com` or `team:mobile`","name":"who","positional":true,"required":true,"takes_value":true,"value_names":["WHO"]},{"action":"SetTrue","help":"View only","long":"watch","name":"watch","possible_values":["true","false"],"value_names":["WATCH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["who","watch"],"multiple":true,"name":"Add","required":false}],"contract":{"output_mode":"json"},"examples":["cloud share add dev@example.com","cloud share add team:mobile --watch"],"name":"add","path":"cloud share add","runs":"local"},{"about":"Take someone's access away","args":[{"action":"Set","help":"`dev@example.com` or `team:mobile`","name":"who","positional":true,"required":true,"takes_value":true,"value_names":["WHO"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"rm","path":"cloud share rm","runs":"local"}]},{"about":"Check the cloud client: sign-in, link, daemon, session, sync","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"doctor","path":"cloud doctor","runs":"local"},{"about":"Secrets: files the secret guard holds back from uploads, and the workspace's stored secrets","contract":{"output_mode":"json"},"name":"secret","path":"cloud secret","runs":"local","subcommands":[{"about":"Allow a file that looks like a secret to upload (an `#allow-secret:` line in the project's .olefignore)","args":[{"action":"Set","dir":"in","name":"path","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["PATH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"allow","path":"cloud secret allow","runs":"local"},{"about":"Files held back, files allowed, and secrets stored in the workspace","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"list","path":"cloud secret list","runs":"local"},{"about":"Store a secret in the cloud workspace: an env value for builds (`--value-stdin`), or a file that appears at `--path` in the cloud copy only (`--file`). Values are write-only","args":[{"action":"Set","help":"Env name (`MAPS_API_KEY`) or file secret name","name":"name","positional":true,"required":true,"takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","conflicts_with":["file"],"help":"Read the value from stdin","long":"value-stdin","name":"value_stdin","possible_values":["true","false"],"value_names":["VALUE_STDIN"]},{"action":"Set","dir":"in","help":"A file whose contents become the secret (e.g. app/google-services.json)","long":"file","name":"file","takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"Set","help":"Where the file appears in the source (default: the file's path in the linked project)","long":"path","name":"path","requires":["file"],"takes_value":true,"value_names":["PATH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["name","value_stdin","file","path"],"multiple":true,"name":"Set","required":false}],"contract":{"output_mode":"json"},"name":"set","path":"cloud secret set","runs":"local"},{"about":"Delete a stored secret","args":[{"action":"Set","name":"name","positional":true,"required":true,"takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"rm","path":"cloud secret rm","runs":"local"}]}]},{"about":"List attached devices / emulators, or reserve billed remote ones. `devices catalog|reserve|extend|release|leases` manage remote devices (preview: Google Cloud Developer Device Platform)","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"devices","path":"devices","runs":"both","subcommands":[{"about":"Every device: attached, AVDs, the Cloud emulator, real phones","args":[{"action":"Set","help":"`attached`, `avd`, `cloud`, `real_phone`, `lab`","long":"source","name":"source","takes_value":true,"value_names":["SOURCE"]},{"action":"Set","long":"form","name":"form","takes_value":true,"value_names":["FORM"]},{"action":"Set","long":"api","name":"api","takes_value":true,"value_names":["API"]},{"action":"SetTrue","long":"physical","name":"physical","possible_values":["true","false"],"value_names":["PHYSICAL"]},{"action":"SetTrue","help":"Usable now","long":"available","name":"available","possible_values":["true","false"],"value_names":["AVAILABLE"]},{"action":"Set","help":"Words that must all match","long":"query","name":"query","takes_value":true,"value_names":["QUERY"]},{"action":"SetTrue","help":"Skip the 10-minute catalog cache","long":"refresh","name":"refresh","possible_values":["true","false"],"value_names":["REFRESH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["source","form","api","physical","available","query","refresh"],"multiple":true,"name":"ListArgs","required":false}],"contract":{"output_mode":"json"},"name":"list","path":"devices list","runs":"remote"},{"about":"List remote devices that can be reserved (preview: Google Cloud Developer Device Platform, billed to your own Google Cloud project)","args":[{"action":"Set","help":"Who pays (default `ddp.billing`)","long":"billing","name":"billing","possible_values":["project","olef","shadowdroid"],"takes_value":true,"value_names":["BILLING"]},{"action":"Set","help":"Only devices with this Android API level","long":"api","name":"api","takes_value":true,"value_names":["API"]},{"action":"Set","help":"Only this form factor (`phone`, `tablet`, `wearable`, …)","long":"form","name":"form","takes_value":true,"value_names":["FORM"]},{"action":"SetTrue","conflicts_with":["virtual_only"],"help":"Only physical devices","long":"physical","name":"physical","possible_values":["true","false"],"value_names":["PHYSICAL"]},{"action":"SetTrue","help":"Only virtual devices","long":"virtual","name":"virtual_only","possible_values":["true","false"],"value_names":["virtual_only"]},{"action":"SetTrue","help":"Only devices available now","long":"available","name":"available","possible_values":["true","false"],"value_names":["AVAILABLE"]},{"action":"SetTrue","help":"Also list devices that can't be streamed or that your project can't use","long":"all","name":"all","possible_values":["true","false"],"value_names":["ALL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["billing","api","form","physical","virtual_only","available","all"],"multiple":true,"name":"CatalogArgs","required":false}],"contract":{"output_mode":"json"},"name":"catalog","path":"devices catalog","runs":"remote"},{"about":"Reserve a remote device and attach it to adb as `127.0.0.1:<port>`. Billed while held; released when idle, by `devices release`, or when its maximum duration is reached","args":[{"action":"Set","help":"Device spec from `devices catalog`, e.g. `ddp:komodo-35`","name":"spec","positional":true,"required":true,"takes_value":true,"value_names":["SPEC"]},{"action":"Set","help":"Who pays (default `ddp.billing`)","long":"billing","name":"billing","possible_values":["project","olef","shadowdroid"],"takes_value":true,"value_names":["BILLING"]},{"action":"Set","default_values":["1800000"],"help":"Initial session length","long":"ttl-ms","name":"ttl_ms","takes_value":true,"value_names":["TTL_MS"]},{"action":"Set","help":"The longest the lease is extended automatically while in use (default `ddp.max_duration_ms`, else 2 h)","long":"max-duration-ms","name":"max_duration_ms","takes_value":true,"value_names":["MAX_DURATION_MS"]},{"action":"Set","help":"Release after this long without any adb traffic (default `ddp.idle_release_ms`, else 10 min)","long":"idle-release-ms","name":"idle_release_ms","takes_value":true,"value_names":["IDLE_RELEASE_MS"]},{"action":"Set","default_values":["360000"],"help":"How long to wait for the device to be allocated and online","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["spec","billing","ttl_ms","max_duration_ms","idle_release_ms","timeout_ms"],"multiple":true,"name":"ReserveArgs","required":false}],"contract":{"output_mode":"json"},"name":"reserve","path":"devices reserve","runs":"remote"},{"about":"Give a reserved device more time","args":[{"action":"Set","help":"Lease id, serial or spec (`devices leases`)","name":"lease","positional":true,"required":true,"takes_value":true,"value_names":["LEASE"]},{"action":"Set","help":"Time left after extending","long":"ttl-ms","name":"ttl_ms","required":true,"takes_value":true,"value_names":["TTL_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["lease","ttl_ms"],"multiple":true,"name":"ExtendArgs","required":false}],"contract":{"output_mode":"json"},"name":"extend","path":"devices extend","runs":"remote"},{"about":"Release reserved devices: detach them and end the provider session","args":[{"action":"Set","help":"Lease id, serial or spec (`devices leases`)","name":"lease","positional":true,"takes_value":true,"value_names":["LEASE"]},{"action":"SetTrue","conflicts_with":["lease"],"help":"Release every lease held on this machine","long":"all","name":"all","possible_values":["true","false"],"value_names":["ALL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["lease","all"],"multiple":true,"name":"ReleaseArgs","required":false}],"contract":{"output_mode":"json"},"name":"release","path":"devices release","runs":"remote"},{"about":"The remote devices held now, with time left and idle time","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"leases","path":"devices leases","runs":"remote"},{"about":"A viewer link (`view.shadowdroid.dev`) for a held Olef device","args":[{"action":"Set","help":"Lease id, serial or spec","name":"lease","positional":true,"required":true,"takes_value":true,"value_names":["LEASE"]},{"action":"Set","default_values":["control"],"long":"mode","name":"mode","possible_values":["control","view"],"takes_value":true,"value_names":["MODE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["lease","mode"],"multiple":true,"name":"ViewArgs","required":false}],"contract":{"output_mode":"json"},"name":"view","path":"devices view","runs":"remote"}]},{"about":"This machine as a device lab for Olef Cloud: `lab register`, `lab add <serial|ip:port>`, `lab serve`; leased as `lab:<lab>/<device>`","contract":{"output_mode":"json"},"name":"lab","path":"lab","runs":"local","subcommands":[{"about":"Register this machine as a lab with your Olef Cloud account (needs `cloud login`); keeps the lab credential under `~/.olef/lab/`","args":[{"action":"Set","help":"The lab's name (letters, digits, '-', '_')","long":"name","name":"name","required":true,"takes_value":true,"value_names":["NAME"]},{"action":"Set","default_values":["full"],"help":"What a reset undoes after each lease: `full` (back to the enrolment baseline), `lease_only` (only what the lease installed, created or changed; for devices people also use) or `none`","long":"reset","name":"reset","possible_values":["full","lease_only","none"],"takes_value":true,"value_names":["RESET"]},{"action":"Set","default_values":["5047"],"help":"The lab's adb server port","long":"adb-port","name":"adb_port","takes_value":true,"value_names":["ADB_PORT"]},{"action":"SetTrue","help":"Replace an existing lab registration on this machine","long":"force","name":"force","possible_values":["true","false"],"value_names":["FORCE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["name","reset","adb_port","force"],"multiple":true,"name":"RegisterArgs","required":false}],"contract":{"output_mode":"json"},"name":"register","path":"lab register","runs":"local"},{"about":"Devices the lab's own adb server sees, enrolled or not","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"devices","path":"lab devices","runs":"local"},{"about":"Pair an Android 11+ device for wireless debugging with the lab's adb key (the code and port from Settings › Wireless debugging › Pair)","args":[{"action":"Set","help":"`host:port` from the pairing dialog","name":"address","positional":true,"required":true,"takes_value":true,"value_names":["ADDRESS"]},{"action":"Set","help":"The six-digit pairing code","name":"code","positional":true,"required":true,"takes_value":true,"value_names":["CODE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["address","code"],"multiple":true,"name":"Pair","required":false}],"contract":{"output_mode":"json"},"name":"pair","path":"lab pair","runs":"local"},{"about":"Enrol a device: probe it, record its baseline, offer it in the Cloud. For a network device give `host:port` (Fire TV: `<ip>:5555`); the device asks once to trust the lab's adb key","args":[{"action":"Set","help":"The device's serial on the lab's adb server, or `host:port` for a network device","name":"lab_device","positional":true,"required":true,"takes_value":true,"value_names":["DEVICE"]},{"action":"Set","help":"Its name in the lab (`lab:<lab>/<name>`)","long":"name","name":"name","required":true,"takes_value":true,"value_names":["NAME"]},{"action":"Set","default_values":["120000"],"help":"How long to wait for the device to trust the lab key","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["lab_device","name","timeout_ms"],"multiple":true,"name":"AddArgs","required":false}],"contract":{"output_mode":"json"},"name":"add","path":"lab add","runs":"local"},{"about":"Run the lab agent: tunnel to the Cloud, serve leases, reset devices","args":[{"action":"Set","help":"Exit after this long (tests)","long":"for-ms","name":"for_ms","takes_value":true,"value_names":["FOR_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"serve","path":"lab serve","runs":"local"},{"about":"The lab, its devices and their states","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"status","path":"lab status","runs":"local"},{"about":"Stop offering a device and forget it","args":[{"action":"Set","help":"Device name or id","name":"lab_device","positional":true,"required":true,"takes_value":true,"value_names":["DEVICE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"remove","path":"lab remove","runs":"local"},{"about":"Ask the Cloud to reset a device now (it must be free)","args":[{"action":"Set","help":"Device name or id","name":"lab_device","positional":true,"required":true,"takes_value":true,"value_names":["DEVICE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"reset","path":"lab reset","runs":"local"},{"about":"A device's enrolment baseline, or what differs from it now","contract":{"output_mode":"json"},"name":"baseline","path":"lab baseline","runs":"local","subcommands":[{"about":"What was recorded at enrolment","args":[{"action":"Set","help":"Device name or id","name":"lab_device","positional":true,"required":true,"takes_value":true,"value_names":["DEVICE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"show","path":"lab baseline show","runs":"local"},{"about":"What differs from it now","args":[{"action":"Set","help":"Device name or id","name":"lab_device","positional":true,"required":true,"takes_value":true,"value_names":["DEVICE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"diff","path":"lab baseline diff","runs":"local"}]},{"about":"Run the agent as a system service (macOS LaunchDaemon, Linux systemd)","contract":{"output_mode":"json"},"name":"service","path":"lab service","runs":"local","subcommands":[{"about":"Write the service definition and print the one command (`sudo`) that installs it","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"install","path":"lab service install","runs":"local"},{"about":"Print the command that removes it","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"uninstall","path":"lab service uninstall","runs":"local"},{"about":"Let the installed service run the agent (no `sudo`)","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"start","path":"lab service start","runs":"local"},{"about":"Stop the agent and keep the service from restarting it (no `sudo`); its devices go offline in the Cloud","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"stop","path":"lab service stop","runs":"local"}]}]},{"about":"Install the server APK, start it, and verify (disables the stylus tutorial until disconnect)","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"connect","path":"connect","runs":"remote"},{"about":"Stop the server and remove the port forward","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"disconnect","path":"disconnect","runs":"remote"},{"about":"Run a command that needs the device's single UiAutomation slot (instrumentation tests, `uiautomator dump`, `android layout`): disconnects Olef, runs the given command (stdio inherited), then reconnects (unless `--no-reconnect`). Exits with the command's status","args":[{"action":"SetTrue","help":"Leave Olef disconnected after the command finishes","long":"no-reconnect","name":"no_reconnect","possible_values":["true","false"],"value_names":["NO_RECONNECT"]},{"action":"Append","allow_hyphen_values":true,"help":"The command to run, after `--`","name":"command","num_args":"1..","positional":true,"required":true,"takes_value":true,"trailing_var_arg":true,"value_names":["COMMAND"]}],"argument_groups":[{"args":["no_reconnect","command"],"multiple":true,"name":"Test","required":false}],"contract":{"output_mode":"passthrough_with_json_trailer"},"name":"test","path":"test","runs":"remote","subcommands":[{"about":"Run test folders (each with a `test.sh`), or folders of them, one at a time per device. Each run gets its own folder (journal, failure report, report.html); the run writes JUnit XML, report.json and an index report.html, with flake classification when --repeat > 1. Exits non-zero when any repetition of a test still failed after its retries","args":[{"action":"Append","dir":"in","help":"Test folders (with `test.sh`), folders of test folders, or scripts. Default: `tests/olef`","name":"paths","num_args":"1..","positional":true,"takes_value":true,"value_hint":"AnyPath","value_names":["TEST"]},{"action":"Set","default_values":["1"],"help":"Run every test this many times and classify each test and step as stable_pass, stable_fail or flaky","long":"repeat","name":"repeat","takes_value":true,"value_names":["REPEAT"]},{"action":"Set","default_values":["0"],"help":"Rerun a failed test up to this many times; a pass after a retry is reported as flaky (JUnit `<flakyFailure>`), never as a plain pass","long":"retries","name":"retries","takes_value":true,"value_names":["RETRIES"]},{"action":"Append","help":"Set a script parameter (environment variable), e.g. `--env CALLSIGN=Grace`","long":"env","name":"env","takes_value":true,"value_names":["KEY=VALUE"]},{"action":"Set","help":"Run each test once per data set: `.env` files matching this glob (relative to the test folder, else the working directory), each a list of KEY=VALUE lines","long":"params","name":"params","takes_value":true,"value_names":["GLOB"]},{"action":"Set","help":"Evidence per step: `failures` (default under test run), `steps` (a screenshot after every step, ~0.1 s each) or `off`","long":"capture","name":"capture","possible_values":["steps","failures","off"],"takes_value":true,"value_names":["CAPTURE"]},{"action":"Set","help":"Run only shard I of N (1-based) of the sorted test list, e.g. `2/4`","long":"shard","name":"shard","takes_value":true,"value_names":["I/N"]},{"action":"Set","dir":"out","help":"Write JUnit XML here (default: `<artifacts-dir>/junit.xml`)","long":"junit-out","name":"junit_out","takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"Set","dir":"dir","help":"Where run folders and reports go (default: `.olef/test-runs/<timestamp>/`)","long":"artifacts-dir","name":"artifacts_dir","takes_value":true,"value_hint":"AnyPath","value_names":["DIR"]},{"action":"SetTrue","help":"Stop after the first test that fails (after its retries)","long":"fail-fast","name":"fail_fast","possible_values":["true","false"],"value_names":["FAIL_FAST"]},{"action":"Set","default_values":["900000"],"help":"Stop a script (and every command it started) that runs longer than this; the attempt fails with `test_timeout`","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["paths","repeat","retries","env","params","capture","shard","junit_out","artifacts_dir","fail_fast","timeout_ms"],"multiple":true,"name":"RunArgs","required":false}],"contract":{"output_mode":"json"},"examples":["test run tests/olef --repeat 10 --junit-out build/junit.xml","test run tests/olef/mission_recovery --retries 1 --env CALLSIGN=Grace"],"name":"run","path":"test run","runs":"remote"},{"about":"Build JUnit XML and a flake report from run folders left by direct `bash test.sh` runs or by `test run`","args":[{"action":"Append","dir":"in","help":"Run folders, or folders holding them (a `test run` artifacts folder)","name":"runs","num_args":"1..","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["RUN_FOLDER"]},{"action":"Set","dir":"out","help":"Write JUnit XML here","long":"junit-out","name":"junit_out","takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"SetTrue","help":"Include the whole report (every run and step) in the output","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]},{"action":"Set","dir":"in","help":"Flag steps that got slower than in this earlier run folder (or test run artifacts folder)","long":"baseline","name":"baseline","takes_value":true,"value_hint":"AnyPath","value_names":["RUN"]}],"argument_groups":[{"args":["runs","junit_out","json","baseline"],"multiple":true,"name":"ReportArgs","required":false}],"contract":{"output_mode":"json"},"examples":["test report .olef/sessions --junit-out junit.xml"],"name":"report","path":"test report","runs":"local"},{"about":"Check scripts for coordinates, text-only selectors, missing checks, sleeps, missing `set -euo pipefail` or trap, unquoted parameters, secrets in literal text, Bash 4 features and custom code. Exits non-zero on errors","args":[{"action":"Append","dir":"in","help":"Test folders, folders of test folders, or scripts. Default: `tests/olef`","name":"paths","num_args":"1..","positional":true,"takes_value":true,"value_hint":"AnyPath","value_names":["TEST"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"examples":["test lint tests/olef"],"name":"lint","path":"test lint","runs":"local"},{"about":"Print a script's parameters, steps and commands as read back (argv lists for other tools), without running it","args":[{"action":"Set","dir":"in","help":"The script (`test.sh`) or its test folder","name":"script","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["SCRIPT"]},{"action":"SetTrue","help":"Print JSON (the default output is plain text)","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]}],"argument_groups":[{"args":["script","json"],"multiple":true,"name":"ShowArgs","required":false}],"contract":{"output_mode":"json"},"examples":["test show tests/olef/mission_recovery/test.sh --json"],"name":"show","path":"test show","runs":"local"},{"about":"Propose a one-line patch for a failed run (a selector from the failure's closest candidates, or a changed expectation to confirm). Never edits the script","args":[{"action":"Set","dir":"in","help":"The test folder (with `test.sh`) or the script","name":"test","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["TEST"]},{"action":"Set","dir":"in","help":"The failed run folder to heal from","long":"from","name":"from","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["RUN_FOLDER"]},{"action":"Set","dir":"out","help":"Write the patch here (default: `<run-folder>/heal.patch`)","long":"out","name":"out","short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["test","from","out"],"multiple":true,"name":"HealArgs","required":false}],"contract":{"output_mode":"json"},"examples":["test heal tests/olef/mission_recovery --from .olef/test-runs/run-1/mission_recovery/r001-a1"],"name":"heal","path":"test heal","runs":"local"}]},{"about":"Turn what was done in a session (an agent's commands, a person's viewer input) into a test folder: `record save <name>` cleans up the journal, writes a Bash script of one olef command per step, replays it once from a fresh start, and saves `tests/olef/<name>/`","contract":{"output_mode":"json"},"name":"record","path":"record","runs":"remote","subcommands":[{"about":"Start a recording in this session, optionally from a fresh start (`--app P --clear-data --launch`): what follows becomes the test. The viewer's Record button runs this","args":[{"action":"Set","help":"The app the test is for (default: the session's app, else the app in front)","long":"app","name":"app","takes_value":true,"value_names":["PACKAGE"]},{"action":"SetTrue","help":"Clear the app's data first, so the recording starts where the test will","long":"clear-data","name":"clear_data","possible_values":["true","false"],"value_names":["CLEAR_DATA"]},{"action":"Set","help":"Launch the app first, optionally at this activity (`.MainActivity`)","long":"launch","name":"launch","num_args":"0..=1","takes_value":true,"value_names":["ACTIVITY"]},{"action":"Set","help":"With --launch: wait until this text is on screen","long":"expect-text","name":"expect_text","requires":["launch"],"takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"With --launch: wait until this resource id or test tag is on screen","long":"expect-rid","name":"expect_rid","requires":["launch"],"takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","clear_data","launch","expect_text","expect_rid"],"multiple":true,"name":"StartArgs","required":false}],"contract":{"output_mode":"json"},"examples":["record start --app io.github.andriyo.shadowdroid.sample --clear-data --launch .MainActivity --expect-rid status_text"],"name":"start","path":"record start","runs":"remote"},{"about":"Stop the recording; keeps the screen it ended on (the last step's checks are read against it). `record save` then makes the test","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"stop","path":"record stop","runs":"remote"},{"about":"Clean up the recording, compile it into a test folder, replay it once from a fresh start (putting back any step removed by mistake), and write `tests/olef/<NAME>/` (test.sh, screens/, README.md, recording.json, and responses/ + expect/ when the proxy captured the flow). Works on the whole session when no recording was started","args":[{"action":"Set","help":"The test's name (folder name): letters, digits, `-` and `_`","name":"name","positional":true,"required":true,"takes_value":true,"value_names":["NAME"]},{"action":"Set","dir":"out","help":"The test folder (default: `<tests.dir>/<NAME>`, `tests/olef/<NAME>`)","long":"out","name":"out","short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["DIR"]},{"action":"Set","help":"Start at this `record mark`","long":"from","name":"from","takes_value":true,"value_names":["MARK"]},{"action":"Set","help":"End at this `record mark`","long":"to","name":"to","takes_value":true,"value_names":["MARK"]},{"action":"Set","help":"Only the last N commands","long":"last","name":"last","takes_value":true,"value_names":["N"]},{"action":"Set","dir":"in","help":"Read this session folder's journal instead of the current session's (a closed session, or one left by a script)","long":"journal","name":"journal","takes_value":true,"value_hint":"AnyPath","value_names":["DIR"]},{"action":"SetTrue","help":"Skip the replay check: write the folder as compiled","long":"no-verify","name":"no_verify","possible_values":["true","false"],"value_names":["NO_VERIFY"]},{"action":"SetTrue","help":"Replace an existing test folder's generated files (mocks/, data/ and other files are kept)","long":"force","name":"force","possible_values":["true","false"],"value_names":["FORCE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["from","to","last","journal"],"multiple":true,"name":"WindowArgs","required":false}],"contract":{"output_mode":"json"},"examples":["record save mission_recovery","record save checkout --from cart-ready --no-verify","record save login --to logged-in -o tests/olef/login"],"name":"save","path":"record save","runs":"remote"},{"about":"Whether a recording is on, and how much it holds","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"status","path":"record status","runs":"remote"},{"about":"The recording as it would be saved: each step as its script line, what clean-up would remove and why, and the script. Changes nothing","args":[{"action":"Set","help":"Start at this `record mark`","long":"from","name":"from","takes_value":true,"value_names":["MARK"]},{"action":"Set","help":"End at this `record mark`","long":"to","name":"to","takes_value":true,"value_names":["MARK"]},{"action":"Set","help":"Only the last N commands","long":"last","name":"last","takes_value":true,"value_names":["N"]},{"action":"Set","dir":"in","help":"Read this session folder's journal instead of the current session's (a closed session, or one left by a script)","long":"journal","name":"journal","takes_value":true,"value_hint":"AnyPath","value_names":["DIR"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["from","to","last","journal"],"multiple":true,"name":"WindowArgs","required":false}],"contract":{"output_mode":"json"},"name":"show","path":"record show","runs":"remote"},{"about":"Name the commands that follow (a step of the test): `record step \"pay with the saved card\"` becomes `step pay-with-the-saved-card`","args":[{"action":"Set","help":"What the following commands do","name":"name","positional":true,"required":true,"takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"examples":["record step \"pay with the saved card\""],"name":"step","path":"record step","runs":"remote"},{"about":"Name the current point (`logged-in`), for `record save --from/--to`","args":[{"action":"Set","name":"name","positional":true,"required":true,"takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"mark","path":"record mark","runs":"remote"},{"about":"Add a check at this point (it must hold now), written into the test as a `ui wait` marked `# checked by you`","args":[{"action":"Set","help":"Match text by case-insensitive substring. Single-target actions prefer a unique full-text match; multiple remaining matches are ambiguous","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Match by resource-id substring; actions prefer a unique exact match","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Match by content-description substring; actions prefer a unique exact match","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"Set","help":"The element shows this text (its own, its description, or inside it)","long":"has-text","name":"has_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"The element is checked (`false`: unchecked)","long":"checked","name":"checked","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"The element is selected (`false`: not selected)","long":"selected","name":"selected","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"The element is enabled (`false`: disabled)","long":"enabled","name":"enabled","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"SetTrue","help":"The element is gone","long":"gone","name":"gone","possible_values":["true","false"],"value_names":["GONE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["text","rid","desc"],"multiple":true,"name":"SelectorArgs","required":false}],"contract":{"output_mode":"json"},"examples":["record check --rid status_text --has-text claimed","record check --rid mission_telemetry_switch --checked"],"name":"check","path":"record check","runs":"remote"},{"about":"Forget the recording so far: `record save` starts from here","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"discard","path":"record discard","runs":"remote"}]},{"about":"Print the Olef License and the notices of the open-source components Olef includes","contract":{"output_mode":"human_text"},"name":"licenses","path":"licenses","runs":"local"},{"about":"Check for a newer release and print the command that updates this install (Homebrew, Scoop or the installer). Never changes anything","args":[{"action":"SetTrue","help":"Accepted for compatibility; `update` is always a read-only check","long":"check","name":"check","possible_values":["true","false"],"value_names":["CHECK"]},{"action":"SetTrue","help":"Emit the result as JSON instead of human text","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]},{"action":"SetTrue","help":"Internal: the detached daily check that refreshes the cache behind the update notice. Prints nothing","long":"refresh-cache","name":"refresh_cache","possible_values":["true","false"],"value_names":["REFRESH_CACHE"]}],"argument_groups":[{"args":["check","json","refresh_cache"],"multiple":true,"name":"Update","required":false}],"contract":{"output_mode":"human_or_json"},"name":"update","path":"update","runs":"local"},{"about":"Initialize host setup: install or update the Claude Code and Codex plugins (asks first) and the agent skill files","args":[{"action":"SetTrue","conflicts_with":["no_plugins"],"help":"Install or update the Claude Code and Codex plugins without asking. Without it, `init` asks in a terminal and otherwise only reports","long":"plugins","name":"plugins","possible_values":["true","false"],"value_names":["PLUGINS"]},{"action":"SetTrue","help":"Do not install or update agent plugins","long":"no-plugins","name":"no_plugins","possible_values":["true","false"],"value_names":["NO_PLUGINS"]},{"action":"SetTrue","conflicts_with":["no_auto_approve_device_actions"],"help":"Claude Code plugin: let Claude act on a device you allowed in the viewer without a prompt per action","long":"auto-approve-device-actions","name":"auto_approve_device_actions","possible_values":["true","false"],"value_names":["AUTO_APPROVE_DEVICE_ACTIONS"]},{"action":"SetTrue","help":"Claude Code plugin: ask before each device action (the default)","long":"no-auto-approve-device-actions","name":"no_auto_approve_device_actions","possible_values":["true","false"],"value_names":["NO_AUTO_APPROVE_DEVICE_ACTIONS"]},{"action":"SetTrue","help":"Do not install/update agent skill files","long":"no-skills","name":"no_skills","possible_values":["true","false"],"value_names":["NO_SKILLS"]},{"action":"SetTrue","help":"Emit JSON instead of human output","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]},{"action":"SetTrue","help":"Accepted and ignored: there is no Android Studio plugin any more","long":"no-studio-plugin","name":"no_studio_plugin","possible_values":["true","false"],"value_names":["NO_STUDIO_PLUGIN"]},{"action":"SetTrue","help":"Accepted and ignored: there is no Android Studio plugin any more","long":"install-studio-plugin","name":"install_studio_plugin","possible_values":["true","false"],"value_names":["INSTALL_STUDIO_PLUGIN"]},{"action":"Set","dir":"in","help":"Accepted and ignored: there is no Android Studio plugin any more","long":"studio","name":"studio","takes_value":true,"value_hint":"AnyPath","value_names":["PATH"]},{"action":"Set","dir":"in","help":"Accepted and ignored: there is no Android Studio plugin any more","long":"plugin","name":"plugin","takes_value":true,"value_hint":"AnyPath","value_names":["PATH"]}],"argument_groups":[{"args":["plugins","no_plugins","auto_approve_device_actions","no_auto_approve_device_actions","no_skills","json","no_studio_plugin","install_studio_plugin","studio","plugin"],"multiple":true,"name":"InitArgs","required":false}],"contract":{"output_mode":"human_or_json"},"name":"init","path":"init","runs":"local"},{"about":"Diagnose (and optionally repair) the host↔device pipe: device state, APK version, port forward, server reachability, UiAutomation owners","args":[{"action":"Set","aliases":["package"],"help":"Also run the per-app interceptability verdict (`net check <app>`)","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"SetTrue","help":"Attempt to repair the issues found","long":"fix","name":"fix","possible_values":["true","false"],"value_names":["FIX"]},{"action":"SetTrue","help":"Allow --fix to kill a competing (non-Olef) UiAutomation owner","long":"force","name":"force","possible_values":["true","false"],"value_names":["FORCE"]},{"action":"SetTrue","help":"Emit the report as a single JSON object instead of human text","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]}],"argument_groups":[{"args":["app","fix","force","json"],"multiple":true,"name":"Doctor","required":false}],"contract":{"output_mode":"human_or_json"},"name":"doctor","path":"doctor","runs":"both"},{"about":"Gather a self-contained diagnostic bundle (doctor report, device info, recent logcat + crash buffer, and — if an existing server is reachable — screen dump, screenshot, current activity, app info) into a directory","args":[{"action":"Set","aliases":["package"],"help":"App package to scope the bundle to (defaults to the configured app)","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","dir":"out","help":"Output directory for the bundle (default: a timestamped temp dir)","long":"out","name":"out","short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"SetTrue","help":"Skip capturing a screenshot","long":"no-screenshot","name":"no_screenshot","possible_values":["true","false"],"value_names":["NO_SCREENSHOT"]},{"action":"SetTrue","help":"With global --redact enabled, black out accessibility bounds whose text matches the policy before writing screenshot.png","long":"redact-screenshots","name":"redact_screenshots","possible_values":["true","false"],"value_names":["REDACT_SCREENSHOTS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","out","no_screenshot","redact_screenshots"],"multiple":true,"name":"Collect","required":false}],"contract":{"output_mode":"json"},"name":"collect","path":"collect","runs":"remote"},{"about":"Emit the full command catalog (machine-readable self-introspection for agents)","args":[{"action":"Append","conflicts_with":["depth","describe","guide","search"],"help":"Command path to inspect directly, e.g. `net rule add`","name":"path","num_args":"0..","positional":true,"takes_value":true,"value_names":["COMMAND_PATH"]},{"action":"SetTrue","help":"Emit JSON instead of a human tree","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]},{"action":"Set","conflicts_with":["describe","guide","path","search"],"help":"Limit command-tree expansion (1 = top-level routing catalog)","long":"depth","name":"depth","takes_value":true,"value_names":["N"]},{"action":"Set","conflicts_with":["depth","guide","path","search"],"help":"Return one command contract by its space-separated path, e.g. \"ui tap\"","long":"describe","name":"describe","takes_value":true,"value_names":["COMMAND_PATH"]},{"action":"Set","conflicts_with":["depth","describe","guide","path"],"help":"Search command names, summaries, argument help, and examples","long":"search","name":"search","takes_value":true,"value_names":["QUERY"]},{"action":"Set","conflicts_with":["depth","describe","path","search"],"help":"Return the driving guide for a domain before first use: workflow, verification, test (test scripts, sessions with settings, test runs), evidence, net, debugger, faults, state, feedback (reporting Olef bugs), or cloud. Covered command groups alias to their guide (ui → workflow; verify/session → verification; video → evidence; debug/layout/runtime → debugger; fault → faults; app/device/perm/appops/profile/files → state)","long":"guide","name":"guide","takes_value":true,"value_names":["TOPIC"]},{"action":"SetTrue","help":"Include long agent guidance and every argument field. JSON output is compact by default (the invocation contract without guidance)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","conflicts_with":["full"],"help":"Accepted for compatibility: compact is the default","long":"compact","name":"compact","possible_values":["true","false"],"value_names":["COMPACT"]}],"argument_groups":[{"args":["path","json","depth","describe","search","guide","full","compact"],"multiple":true,"name":"Commands","required":false}],"contract":{"output_mode":"human_or_json"},"examples":["commands --json --depth 1","commands net rule add --json --compact","commands --search 'response body' --json","commands --guide net --json"],"name":"commands","path":"commands","runs":"local"},{"about":"Structured, bounded logcat: app-scoped JSON log lines with crash/ANR blocks parsed out, windowed (`--last 60s`) and deduplicated. Works without the on-device server","args":[{"action":"Set","aliases":["package"],"help":"App package or config alias to scope to (default: the configured app; `--all` for every process)","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"SetTrue","help":"Include every process (ignore the configured default app)","long":"all","name":"all","possible_values":["true","false"],"value_names":["ALL"]},{"action":"Set","help":"Minimum level: v, d, i, w, e, or f (default: everything)","long":"level","name":"level","possible_values":["v","d","i","w","e","f"],"takes_value":true,"value_names":["LEVEL"]},{"action":"Append","help":"Only lines whose tag contains this (repeatable; case-insensitive)","long":"tag","name":"tag","takes_value":true,"value_names":["TAG"]},{"action":"Set","help":"Only lines whose tag or message matches this regex","long":"grep","name":"grep","takes_value":true,"value_names":["GREP"]},{"action":"Set","default_values":["60s"],"help":"How far back to look: a duration like 30s, 5m, 2h (default 60s)","long":"last","name":"last","takes_value":true,"value_names":["LAST"]},{"action":"Set","default_values":["100"],"help":"Maximum log entries to emit after filtering (most recent kept)","long":"max","name":"max","takes_value":true,"value_names":["MAX"]},{"action":"Append","default_values":["main,system,crash"],"help":"Logcat buffers to read (comma-separated: main, system, crash, events)","long":"buffer","name":"buffer","takes_value":true,"value_delimiter":",","value_names":["BUFFER"]},{"action":"SetTrue","help":"Keep consecutive duplicate lines instead of collapsing them with a `repeat` count","long":"no-dedup","name":"no_dedup","possible_values":["true","false"],"value_names":["NO_DEDUP"]}],"argument_groups":[{"args":["app","all","level","tag","grep","last","max","buffer","no_dedup"],"multiple":true,"name":"LogArgs","required":false}],"contract":{"output_mode":"jsonl"},"name":"log","path":"log","runs":"remote"},{"about":"One bounded triage read: what just went wrong? Fuses the last crash/ANR, recent error logs, the current screen, and network failures into a verdict with evidence and next steps","args":[{"action":"Set","aliases":["package"],"help":"App package or config alias to focus on (default: the configured app)","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","default_values":["120s"],"help":"How far back to look, e.g. 120s, 5m (default 120s)","long":"last","name":"last","takes_value":true,"value_names":["LAST"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","last"],"multiple":true,"name":"WhyArgs","required":false}],"contract":{"output_mode":"json"},"name":"why","path":"why","runs":"remote"},{"about":"Opt-in local usage log (verb + duration + error code per invocation; never argument values, never leaves this machine)","contract":{"output_mode":"json"},"name":"usage","path":"usage","runs":"local","subcommands":[{"about":"Is usage logging on, where does it write, how big is the log?","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"status","path":"usage status","runs":"local"},{"about":"Turn usage logging on (writes `\"usage_log\": true` to the user config)","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"enable","path":"usage enable","runs":"local"},{"about":"Turn usage logging off","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"disable","path":"usage disable","runs":"local"},{"about":"Aggregate the log: verb frequencies, error codes, durations","args":[{"action":"Set","default_values":["30"],"help":"Only include entries from the last N days","long":"days","name":"days","takes_value":true,"value_names":["DAYS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"report","path":"usage report","runs":"local"},{"about":"Delete the usage log files","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"clear","path":"usage clear","runs":"local"}]},{"about":"Report an Olef bug, missing capability, friction or doc mismatch: drafts locally, the user approves, then it becomes a GitHub issue","contract":{"output_mode":"json"},"name":"feedback","path":"feedback","runs":"local","subcommands":[{"about":"Draft a report locally: context is filled in and redacted; nothing is sent","args":[{"action":"Set","long":"kind","name":"kind","possible_values":["bug","gap","friction","docs"],"takes_value":true,"value_names":["KIND"]},{"action":"Set","help":"One line: what went wrong (becomes the issue title). Defaults to the last error with --from-last-error","long":"summary","name":"summary","takes_value":true,"value_names":["SUMMARY"]},{"action":"Set","help":"What you were trying to do","long":"goal","name":"goal","takes_value":true,"value_names":["GOAL"]},{"action":"Set","long":"expected","name":"expected","takes_value":true,"value_names":["EXPECTED"]},{"action":"Set","long":"actual","name":"actual","takes_value":true,"value_names":["ACTUAL"]},{"action":"Append","help":"A olef command that reproduces it; repeat in order","long":"repro","name":"repro","takes_value":true,"value_names":["REPRO"]},{"action":"Set","help":"What you did instead (required for --kind gap)","long":"workaround","name":"workaround","takes_value":true,"value_names":["WORKAROUND"]},{"action":"Set","long":"impact","name":"impact","possible_values":["blocked","slowed","cosmetic"],"takes_value":true,"value_names":["IMPACT"]},{"action":"SetTrue","help":"Include Olef's last error (the `fault: \"olef\"` one)","long":"from-last-error","name":"from_last_error","possible_values":["true","false"],"value_names":["FROM_LAST_ERROR"]},{"action":"Append","long":"attach","name":"attach","possible_values":["doctor","why","usage"],"takes_value":true,"value_names":["ATTACH"]},{"action":"SetTrue","help":"Leave out the device profile","long":"no-device","name":"no_device","possible_values":["true","false"],"value_names":["NO_DEVICE"]},{"action":"Set","dir":"in","help":"The same fields as a JSON object (a file, or `-` for stdin); flags win","long":"json-input","name":"json_input","takes_value":true,"value_names":["FILE|-"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["kind","summary","goal","expected","actual","repro","workaround","impact","from_last_error","attach","no_device","json_input"],"multiple":true,"name":"DraftArgs","required":false}],"contract":{"output_mode":"json"},"name":"draft","path":"feedback draft","runs":"local"},{"about":"The exact title and text a draft would send","args":[{"action":"Set","help":"Draft id (fb-YYYYMMDD-xxxx), from `feedback draft` or `feedback list`","name":"id","positional":true,"required":true,"takes_value":true,"value_names":["ID"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"show","path":"feedback show","runs":"local"},{"about":"Local drafts and submitted reports, newest first","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"list","path":"feedback list","runs":"local"},{"about":"Send a draft. `browser` (default) prints a prefilled public GitHub issue link for the user to review and submit; `gh` creates the issue with the user's gh login, only with --yes","args":[{"action":"Set","name":"id","positional":true,"required":true,"takes_value":true,"value_names":["ID"]},{"action":"Set","default_values":["browser"],"long":"via","name":"via","possible_values":["browser","gh"],"takes_value":true,"value_names":["VIA"]},{"action":"SetTrue","help":"Create the issue now (`--via gh`). Pass it only after the user approved this report","long":"yes","name":"yes","possible_values":["true","false"],"value_names":["YES"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["id","via","yes"],"multiple":true,"name":"Submit","required":false}],"contract":{"output_mode":"json"},"name":"submit","path":"feedback submit","runs":"local"},{"about":"Whether submitted reports are open or fixed, from the known-issues index","args":[{"action":"Set","help":"One report; all submitted reports when omitted","name":"id","positional":true,"takes_value":true,"value_names":["ID"]},{"action":"SetTrue","help":"Fetch the latest known-issues index first (a GitHub download)","long":"refresh","name":"refresh","possible_values":["true","false"],"value_names":["REFRESH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["id","refresh"],"multiple":true,"name":"Status","required":false}],"contract":{"output_mode":"json"},"name":"status","path":"feedback status","runs":"local"},{"about":"Delete a draft or report from this machine","args":[{"action":"Set","name":"id","positional":true,"required":true,"takes_value":true,"value_names":["ID"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"discard","path":"feedback discard","runs":"local"}]},{"about":"Inspect, generate, and validate user/project JSON config","contract":{"output_mode":"human_or_json"},"name":"config","path":"config","runs":"local","subcommands":[{"about":"Print config paths, precedence, and currently loaded config files","args":[{"action":"SetTrue","help":"Emit JSON instead of human text","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]}],"contract":{"output_mode":"human_or_json"},"name":"paths","path":"config paths","runs":"local"},{"about":"Print the machine-readable config schema and example","args":[{"action":"SetTrue","help":"Emit JSON instead of human text","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]}],"contract":{"output_mode":"human_or_json"},"name":"schema","path":"config schema","runs":"local"},{"about":"Explain how config is loaded and how agents should use it","args":[{"action":"SetTrue","help":"Emit JSON instead of human text","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]}],"contract":{"output_mode":"human_or_json"},"name":"explain","path":"config explain","runs":"local"},{"about":"Create or update a user/project config file from CLI values","args":[{"action":"SetTrue","conflicts_with":["project"],"help":"Write ~/.olef/config.json","long":"user","name":"user","possible_values":["true","false"],"value_names":["USER"]},{"action":"SetTrue","conflicts_with":["user"],"help":"Write ./.olef/config.json. This is the default","long":"project","name":"project","possible_values":["true","false"],"value_names":["PROJECT"]},{"action":"Set","help":"Default app alias agents can use, e.g. Livd","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","help":"Package for --app, e.g. com.example.app","long":"package","name":"package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Default named target used when --device/--target are absent","long":"default-target","name":"default_target","takes_value":true,"value_names":["NAME"]},{"action":"Set","help":"Target entry to create/update. Pair with --target-avd or --target-serial","long":"target-name","name":"target_name","takes_value":true,"value_names":["NAME"]},{"action":"Set","conflicts_with":["target_serial"],"help":"Stable AVD name for --target-name","long":"target-avd","name":"target_avd","requires":["target_name"],"takes_value":true,"value_names":["AVD"]},{"action":"Set","conflicts_with":["target_avd"],"help":"Stable physical/remote adb serial for --target-name","long":"target-serial","name":"target_serial","requires":["target_name"],"takes_value":true,"value_names":["SERIAL"]},{"action":"Set","help":"Target startup policy. `if-needed` is valid only for AVD targets","long":"target-start","name":"target_start","possible_values":["never","if-needed"],"requires":["target_name"],"takes_value":true,"value_names":["TARGET_START"]},{"action":"Set","help":"Assert the resolved target is a mobile or TV device","long":"target-form-factor","name":"target_form_factor","possible_values":["mobile","tv"],"requires":["target_name"],"takes_value":true,"value_names":["TARGET_FORM_FACTOR"]},{"action":"SetTrue","help":"Cold-boot the AVD when Olef starts it","long":"target-cold-boot","name":"target_cold_boot","possible_values":["true","false"],"requires":["target_name"],"value_names":["TARGET_COLD_BOOT"]},{"action":"Set","help":"AVD boot timeout in seconds (10..=900)","long":"target-boot-timeout","name":"target_boot_timeout","requires":["target_name"],"takes_value":true,"value_names":["SECONDS"]},{"action":"Set","help":"Named target for --app. The alias must be created in the same command or already exist","long":"app-target","name":"app_target","requires":["app"],"takes_value":true,"value_names":["NAME"]},{"action":"Set","dir":"in","help":"Default project root: where breakpoints, layout source mapping and `app apply` look for sources and build outputs","long":"project-path","name":"project_path","takes_value":true,"value_names":["PATH"]},{"action":"Set","help":"Gradle application module to build when not told (`app apply`, the build tool). With --app, for that app alias","long":"module","name":"module","takes_value":true,"value_names":["MODULE"]},{"action":"Set","help":"Build variant to build when not told, e.g. `mobileDebug`. With --app, for that app alias","long":"variant","name":"variant","takes_value":true,"value_names":["VARIANT"]},{"action":"Set","help":"Default debugger mode: auto, java, native, or mixed","long":"debug-mode","name":"debug_mode","takes_value":true,"value_names":["MODE"]},{"action":"Set","help":"How the agent shows you the device: viewer (the live viewer in the agent app's browser pane) or window (the emulator's own window)","long":"show-device","name":"show_device","possible_values":["viewer","window"],"takes_value":true,"value_names":["WHERE"]},{"action":"Set","dir":"in","help":"Proxy signing CA certificate path (absolute or ~/). Sets proxy.ca_cert","long":"ca-cert","name":"ca_cert","takes_value":true,"value_names":["PATH"]},{"action":"Set","dir":"in","help":"Proxy signing CA private key path (absolute or ~/). Sets proxy.ca_key","long":"ca-key","name":"ca_key","takes_value":true,"value_names":["PATH"]},{"action":"SetTrue","help":"Assert the proxy CA is already trusted on the device (skip install + readback). Sets proxy.ca_trusted","long":"ca-trusted","name":"ca_trusted","possible_values":["true","false"],"value_names":["CA_TRUSTED"]},{"action":"SetTrue","help":"Replace an existing app alias if it points at a different package","long":"force","name":"force","possible_values":["true","false"],"value_names":["FORCE"]},{"action":"SetTrue","help":"Emit JSON instead of human text","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]}],"argument_groups":[{"args":["user","project","app","package","default_target","target_name","target_avd","target_serial","target_start","target_form_factor","target_cold_boot","target_boot_timeout","app_target","project_path","module","variant","debug_mode","show_device","ca_cert","ca_key","ca_trusted","force","json"],"multiple":true,"name":"ConfigInitArgs","required":false}],"contract":{"output_mode":"human_or_json"},"name":"init","path":"config init","runs":"local"},{"about":"Parse and validate all discovered config files","args":[{"action":"SetTrue","help":"Emit JSON instead of human text","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]}],"contract":{"output_mode":"human_or_json"},"name":"validate","path":"config validate","runs":"local"}]},{"about":"Generate, install, or refresh Agent Skills (claude-code / cursor / codex / gemini / antigravity) at user or project scope","args":[{"action":"Set","conflicts_with":["sync"],"help":"Target agent system. Omit together with `--sync` to refresh every already-installed skill instead","name":"agent","positional":true,"possible_values":["claude-code","cursor","codex","gemini","antigravity"],"takes_value":true,"value_names":["AGENT"]},{"action":"Set","conflicts_with":["install","sync"],"dir":"out","help":"Write the generated SKILL.md to this path (default: print to stdout)","long":"out","name":"out","short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"SetTrue","conflicts_with":["sync"],"help":"Install to the agent's conventional skill directory instead of stdout","long":"install","name":"install","possible_values":["true","false"],"value_names":["INSTALL"]},{"action":"Set","default_values":["user"],"help":"Installation/sync scope. User is global; project is relative to the CWD","long":"scope","name":"scope","possible_values":["user","project"],"takes_value":true,"value_names":["SCOPE"]},{"action":"SetTrue","help":"Refresh every already-installed Olef skill to this CLI's version. Unmodified skills are rewritten in place; skills you've hand-edited are left alone and reported — unless you also pass --force","long":"sync","name":"sync","possible_values":["true","false"],"value_names":["SYNC"]},{"action":"SetTrue","help":"Allow overwriting a customized or markerless destination. Without this, every install/sync preserves user-authored content","long":"force","name":"force","possible_values":["true","false"],"value_names":["FORCE"]}],"argument_groups":[{"args":["agent","out","install","scope","sync","force"],"multiple":true,"name":"SkillArgs","required":false}],"contract":{"output_mode":"source_text_or_json_action"},"name":"skill","path":"skill","runs":"local"},{"about":"Serve the Model Context Protocol over stdio for Claude Code: device control with dp coordinates and image screenshots, plus a live viewer for the Claude Desktop browser pane","contract":{"output_mode":"mcp_stdio_jsonrpc"},"name":"mcp","path":"mcp","runs":"remote"},{"about":"Serve the live, interactive device viewer (video, touch, keys) on a loopback URL until Ctrl-C; or read what the person annotated or recorded in a running viewer","args":[{"action":"Set","help":"Loopback port for the viewer (default: a free port)","long":"port","name":"port","takes_value":true,"value_names":["PORT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"pane","path":"pane","runs":"remote","subcommands":[{"about":"What the person annotated in a running viewer (its Annotate mode): each note's comment, the element and a selector for it, and the composables that drew it (file:line), plus an overview PNG of each screen with its notes outlined and numbered (and a crop of the tiny ones). Reading takes them off the viewer unless --keep","args":[{"action":"SetTrue","help":"Leave them on the viewer","long":"keep","name":"keep","possible_values":["true","false"],"value_names":["KEEP"]},{"action":"SetTrue","help":"Also save a crop of every note, not only the tiny ones","long":"crops","name":"crops","possible_values":["true","false"],"value_names":["CROPS"]},{"action":"Set","dir":"out","help":"Directory for the images (default: a temp directory)","long":"out","name":"out","short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["keep","crops","out"],"multiple":true,"name":"Annotations","required":false}],"contract":{"output_mode":"json"},"name":"annotations","path":"pane annotations","runs":"remote"},{"about":"The steps the person recorded in a running viewer (Record steps): each tap with the element it hit and a selector, swipes, typing and keys. Write a UI test from them","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"steps","path":"pane steps","runs":"remote"}]},{"about":"List, boot and shut down Android emulators (AVDs)","contract":{"output_mode":"json"},"name":"emulator","path":"emulator","runs":"remote","subcommands":[{"about":"List the AVDs on this machine, and which are running (as which serial)","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"list","path":"emulator list","runs":"remote"},{"about":"Boot an AVD and wait until it has finished starting (returns at once when it's already running)","args":[{"action":"Set","help":"AVD name, as `emulator list` shows it","name":"avd","positional":true,"required":true,"takes_value":true,"value_names":["AVD"]},{"action":"SetTrue","help":"Run without the emulator's own window (watch it with `olef pane`)","long":"no-window","name":"no_window","possible_values":["true","false"],"value_names":["NO_WINDOW"]},{"action":"SetTrue","help":"Cold boot: ignore the saved snapshot","long":"cold","name":"cold","possible_values":["true","false"],"value_names":["COLD"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["avd","no_window","cold"],"multiple":true,"name":"Boot","required":false}],"contract":{"output_mode":"json"},"name":"boot","path":"emulator boot","runs":"remote"},{"about":"Shut down a running emulator","args":[{"action":"Set","help":"AVD name or adb serial (`emulator-5554`)","name":"avd","positional":true,"required":true,"takes_value":true,"value_names":["AVD"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"kill","path":"emulator kill","runs":"remote"}]},{"about":"Agent-first debug snapshots, timelines, replays, and debugger control","args":[],"argument_groups":[{"args":["engine","debug_backend"],"multiple":true,"name":"DebugArgs","required":false}],"contract":{"output_mode":"json"},"name":"debug","path":"debug","runs":"remote","subcommands":[{"about":"Start an app, attach the debugger, and return a snapshot","args":[{"action":"Set","help":"App alias, package, or installed app name. Defaults to config, then foreground app","name":"app_target","positional":true,"takes_value":true,"value_names":["TARGET"]},{"action":"Set","help":"App alias or installed app name. Useful when the target would be parsed as an option","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","help":"Exact package/process name. Overrides target and --app","long":"package","name":"package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Engines to attach: java (default), native, or mixed (both)","long":"mode","name":"mode","possible_values":["auto","java","native","mixed"],"takes_value":true,"value_names":["MODE"]},{"action":"SetTrue","help":"Do not launch the app before attaching/snapshotting","long":"no-start","name":"no_start","possible_values":["true","false"],"value_names":["NO_START"]},{"action":"SetTrue","help":"Do not attach the debugger; only resolve, launch, and snapshot","long":"no-attach","name":"no_attach","possible_values":["true","false"],"value_names":["NO_ATTACH"]},{"action":"SetTrue","conflicts_with":["no_start"],"help":"Start the app under the debugger so breakpoints catch startup code","long":"from-start","name":"from_start","possible_values":["true","false"],"value_names":["FROM_START"]},{"action":"Append","dir":"in","help":"Line breakpoint set at attach, as FILE:LINE (repeatable)","long":"break","name":"break_at","takes_value":true,"value_names":["FILE:LINE"]},{"action":"Append","help":"Exception breakpoint set at attach (repeatable)","long":"break-exception","name":"break_exception","takes_value":true,"value_names":["CLASS"]},{"action":"Set","help":"Activity to start with --from-start when the app has several launcher activities (`.Main` or a class name)","long":"launch-activity","name":"launch_activity","requires":["from_start"],"takes_value":true,"value_names":["ACTIVITY"]},{"action":"Set","default_values":["20000"],"help":"App foreground wait timeout after launch","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"Set","default_values":["200"],"help":"Number of recent logcat lines to include","long":"logs","name":"logs","takes_value":true,"value_names":["LOGS"]},{"action":"Set","default_values":["1"],"help":"Include expanded top-frame variables when the debugger is suspended","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"Set","dir":"out","help":"Directory for screenshot artifacts","long":"screenshot-dir","name":"screenshot_dir","takes_value":true,"value_hint":"AnyPath","value_names":["SCREENSHOT_DIR"]},{"action":"SetTrue","help":"Skip screenshot capture","long":"no-screenshot","name":"no_screenshot","possible_values":["true","false"],"value_names":["NO_SCREENSHOT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app_target","app","package","mode","no_start","no_attach","from_start","break_at","break_exception","launch_activity","timeout_ms","logs","depth","screenshot_dir","no_screenshot"],"multiple":true,"name":"AutoArgs","required":false}],"contract":{"output_mode":"json"},"name":"auto","path":"debug auto","runs":"remote"},{"about":"Capture one bounded debug state object for an agent","args":[{"action":"Set","aliases":["package"],"help":"App package used for log/debugger filtering where possible","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","dir":"out","help":"Write the snapshot JSON to a file instead of stdout","long":"out","name":"out","short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"Set","dir":"out","help":"Directory for screenshot artifacts","long":"screenshot-dir","name":"screenshot_dir","takes_value":true,"value_hint":"AnyPath","value_names":["SCREENSHOT_DIR"]},{"action":"SetTrue","help":"Skip screenshot capture","long":"no-screenshot","name":"no_screenshot","possible_values":["true","false"],"value_names":["NO_SCREENSHOT"]},{"action":"Set","default_values":["200"],"help":"Number of recent logcat lines to include","long":"logs","name":"logs","takes_value":true,"value_names":["LOGS"]},{"action":"Set","default_values":["1"],"help":"Include expanded top-frame variables when the debugger is suspended","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","out","screenshot_dir","no_screenshot","logs","depth"],"multiple":true,"name":"SnapshotArgs","required":false}],"contract":{"output_mode":"json"},"name":"snapshot","path":"debug snapshot","runs":"remote"},{"about":"Record a JSONL debug timeline: screen/app/logcat/debugger/screenshot events","args":[{"action":"Set","dir":"out","help":"JSONL timeline path","long":"out","name":"out","required":true,"short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"Set","help":"Stop automatically after this many milliseconds. Omit to record until Ctrl-C","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"Set","default_values":["500"],"help":"Poll interval for screen/debugger snapshots","long":"poll-ms","name":"poll_ms","takes_value":true,"value_names":["POLL_MS"]},{"action":"Set","aliases":["package"],"help":"App package used for annotations and debugger filtering where possible","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","dir":"out","help":"Directory for screenshot artifacts. Defaults beside --out","long":"screenshot-dir","name":"screenshot_dir","takes_value":true,"value_hint":"AnyPath","value_names":["SCREENSHOT_DIR"]},{"action":"SetTrue","help":"Skip screenshot capture on screen changes","long":"no-screenshots","name":"no_screenshots","possible_values":["true","false"],"value_names":["NO_SCREENSHOTS"]},{"action":"Set","default_values":["1"],"help":"Include expanded top-frame variables in debugger timeline events","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["out","duration_ms","poll_ms","app","screenshot_dir","no_screenshots","depth"],"multiple":true,"name":"RecordArgs","required":false}],"contract":{"output_mode":"json"},"name":"record","path":"debug record","runs":"remote"},{"about":"Replay action events from a JSONL timeline","args":[{"action":"Set","dir":"in","help":"JSONL timeline path","name":"file","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"SetTrue","help":"Print replayable actions without performing them","long":"dry-run","name":"dry_run","possible_values":["true","false"],"value_names":["DRY_RUN"]},{"action":"Set","default_values":["0"],"help":"Fixed delay between replayed actions","long":"delay-ms","name":"delay_ms","takes_value":true,"value_names":["DELAY_MS"]},{"action":"SetTrue","help":"Stop at the first unsupported or failed action","long":"stop-on-error","name":"stop_on_error","possible_values":["true","false"],"value_names":["STOP_ON_ERROR"]},{"action":"Set","default_values":["1"],"help":"Replay the whole timeline this many times back-to-back — a flake hunter","long":"repeat","name":"repeat","takes_value":true,"value_names":["REPEAT"]},{"action":"SetTrue","help":"After each action capture the post-action screen_hash and report run-to-run divergence — surfaces non-determinism in the underlying flow before it becomes a flaky test","long":"diff","name":"diff","possible_values":["true","false"],"value_names":["DIFF"]},{"action":"Set","default_values":["0"],"help":"Settle delay before capturing screen_hash when --diff is set","long":"settle-ms","name":"settle_ms","takes_value":true,"value_names":["SETTLE_MS"]}],"argument_groups":[{"args":["file","dry_run","delay_ms","stop_on_error","repeat","diff","settle_ms"],"multiple":true,"name":"ReplayArgs","required":false}],"contract":{"output_mode":"jsonl"},"name":"replay","path":"debug replay","runs":"remote"},{"about":"Show the debugger daemons and their sessions","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"status","path":"debug status","runs":"remote"},{"about":"List attached debug sessions","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"sessions","path":"debug sessions","runs":"remote"},{"about":"List debuggable processes on the device and the sessions attached to them","args":[{"action":"Set","aliases":["app"],"help":"Filter by app package/process","long":"package","name":"package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Filter by process id","long":"pid","name":"pid","takes_value":true,"value_names":["PID"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["package","pid"],"multiple":true,"name":"AndroidClientArgs","required":false}],"contract":{"output_mode":"json"},"name":"clients","path":"debug clients","runs":"remote"},{"about":"Attach the standalone debugger to a running app, or start it under the debugger","args":[{"action":"Set","aliases":["app"],"help":"App package/process to attach to","long":"package","name":"package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Process id to attach to","long":"pid","name":"pid","takes_value":true,"value_names":["PID"]},{"action":"Set","help":"Engines to attach: java (default), native, or mixed (both)","long":"mode","name":"mode","possible_values":["auto","java","native","mixed"],"takes_value":true,"value_names":["MODE"]},{"action":"SetTrue","help":"Restart the app under `am set-debug-app -w` and attach before its code runs","long":"wait-for-launch","name":"wait_for_launch","possible_values":["true","false"],"value_names":["WAIT_FOR_LAUNCH"]},{"action":"SetTrue","help":"Restart an already running app under the debugger, carrying over the session's line and exception breakpoints: long stops then raise no ANR. Resets the app's state (force-stop)","long":"relaunch","name":"relaunch","possible_values":["true","false"],"value_names":["RELAUNCH"]},{"action":"Append","dir":"in","help":"Line breakpoint set at attach, as FILE:LINE (repeatable)","long":"break","name":"break_at","takes_value":true,"value_names":["FILE:LINE"]},{"action":"Append","help":"Exception breakpoint set at attach (repeatable)","long":"break-exception","name":"break_exception","takes_value":true,"value_names":["CLASS"]},{"action":"Append","help":"Native function breakpoint set at attach (repeatable; native/mixed mode)","long":"break-function","name":"break_function","takes_value":true,"value_names":["NAME"]},{"action":"Set","default_values":["20000"],"help":"How long to wait for the launched process","long":"launch-timeout-ms","name":"launch_timeout_ms","takes_value":true,"value_names":["LAUNCH_TIMEOUT_MS"]},{"action":"Set","help":"Activity to start with --wait-for-launch (`.Main`, `pkg/.Main`, or a class name). Default: the only launcher activity, else the root of the app's most recent task, else the first launcher in manifest order","long":"launch-activity","name":"launch_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"Append","dir":"in","help":"Unstripped libraries for native symbols: a directory of `.so` files, a directory with `<abi>/` subdirectories, or one file (repeatable). Gradle outputs under the project root are found automatically","long":"symbols","name":"symbols","takes_value":true,"value_hint":"AnyPath","value_names":["PATH"]},{"action":"Set","default_values":["smart"],"help":"`smart` (default) hands every signal to the app untouched (ART uses SIGSEGV and SIGBUS itself) and stops on real crashes at the faulting frame: a SIGSEGV ART does not own (at ART's `art_sigsegv_fault` hook), and SIGABRT, SIGILL, SIGFPE and SIGSYS; `stop` also stops on every SIGSEGV as it is raised, which can disturb ART (diagnosis only)","long":"signal-policy","name":"signal_policy","possible_values":["smart","stop"],"takes_value":true,"value_names":["SIGNAL_POLICY"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["wait_for_launch","relaunch","break_at","break_exception","break_function","launch_timeout_ms","launch_activity"],"multiple":true,"name":"LaunchArgs","required":false},{"args":["symbols","signal_policy"],"multiple":true,"name":"NativeAttachArgs","required":false}],"contract":{"output_mode":"json"},"name":"attach","path":"debug attach","runs":"remote"},{"about":"Breakpoint commands","contract":{"output_mode":"json"},"name":"break","path":"debug break","runs":"remote","subcommands":[{"about":"Add a line breakpoint: Kotlin/Java, or C/C++ (`.c`, `.cpp`, `.h`, …) in a native or mixed session","args":[{"action":"Set","dir":"in","help":"Source file: a path, or a file name or path suffix found under the project root","long":"file","name":"file","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"Set","help":"One-based source line number","long":"line","name":"line","required":true,"takes_value":true,"value_names":["LINE"]},{"action":"SetTrue","help":"Create the breakpoint disabled","long":"disabled","name":"disabled","possible_values":["true","false"],"value_names":["DISABLED"]},{"action":"SetTrue","help":"Create a temporary breakpoint","long":"temporary","name":"temporary","possible_values":["true","false"],"value_names":["TEMPORARY"]},{"action":"Set","conflicts_with":["clear_condition"],"help":"Breakpoint condition; the breakpoint stops only when it is true","long":"condition","name":"condition","takes_value":true,"value_names":["CONDITION"]},{"action":"SetTrue","help":"Clear any condition on an existing breakpoint at this file/line","long":"clear-condition","name":"clear_condition","possible_values":["true","false"],"value_names":["CLEAR_CONDITION"]},{"action":"SetTrue","help":"Set the condition even if it does not parse (it then fails at each hit)","long":"force","name":"force","possible_values":["true","false"],"requires":["condition"],"value_names":["FORCE"]},{"action":"SetTrue","help":"Let the condition call app methods (runs app code)","long":"invoke","name":"invoke","possible_values":["true","false"],"value_names":["INVOKE"]},{"action":"Set","help":"Locations on the line: all (default), outer method, or innermost lambda","long":"variant","name":"variant","possible_values":["all","outer","lambda"],"takes_value":true,"value_names":["VARIANT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["file","line","disabled","temporary","condition","clear_condition","force","invoke","variant"],"multiple":true,"name":"Line","required":false}],"contract":{"output_mode":"json"},"name":"line","path":"debug break line","runs":"remote"},{"about":"Add a Java exception breakpoint","args":[{"action":"Set","help":"Fully-qualified exception class, e.g. java.lang.IllegalStateException","name":"exception","positional":true,"required":true,"takes_value":true,"value_names":["EXCEPTION"]},{"action":"SetTrue","help":"Create the breakpoint disabled","long":"disabled","name":"disabled","possible_values":["true","false"],"value_names":["DISABLED"]},{"action":"Set","default_values":["true"],"help":"Break on caught exceptions","long":"caught","name":"caught","possible_values":["true","false"],"takes_value":true,"value_names":["CAUGHT"]},{"action":"Set","default_values":["true"],"help":"Break on uncaught exceptions","long":"uncaught","name":"uncaught","possible_values":["true","false"],"takes_value":true,"value_names":["UNCAUGHT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["exception","disabled","caught","uncaught"],"multiple":true,"name":"Exception","required":false}],"contract":{"output_mode":"json"},"name":"exception","path":"debug break exception","runs":"remote"},{"about":"Add a native function breakpoint (C/C++ name, `ns::fn`, or a regex)","args":[{"action":"Set","help":"Function name: `checksum`, `fieldlab::checksum`, `Java_..._compute`","long":"name","name":"name","required":true,"takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"Treat --name as a regular expression","long":"regex","name":"regex","possible_values":["true","false"],"value_names":["REGEX"]},{"action":"Set","help":"Only in this library, e.g. `libfieldlab_native.so`","long":"module","name":"module","takes_value":true,"value_names":["MODULE"]},{"action":"SetTrue","help":"Create the breakpoint disabled","long":"disabled","name":"disabled","possible_values":["true","false"],"value_names":["DISABLED"]},{"action":"SetTrue","help":"Remove the breakpoint after its first hit","long":"temporary","name":"temporary","possible_values":["true","false"],"value_names":["TEMPORARY"]},{"action":"Set","help":"C/C++ condition; the breakpoint stops only when it is true","long":"condition","name":"condition","takes_value":true,"value_names":["CONDITION"]},{"action":"Set","help":"Skip this many hits before stopping","long":"pass-count","name":"pass_count","takes_value":true,"value_names":["PASS_COUNT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["disabled","temporary","condition","pass_count"],"multiple":true,"name":"NativeBreakOptions","required":false}],"contract":{"output_mode":"json"},"name":"function","path":"debug break function","runs":"remote"},{"about":"Add a native breakpoint at a code address","args":[{"action":"Set","help":"Address (hex `0x…` or decimal)","long":"address","name":"address","required":true,"takes_value":true,"value_names":["ADDRESS"]},{"action":"SetTrue","help":"Create the breakpoint disabled","long":"disabled","name":"disabled","possible_values":["true","false"],"value_names":["DISABLED"]},{"action":"SetTrue","help":"Remove the breakpoint after its first hit","long":"temporary","name":"temporary","possible_values":["true","false"],"value_names":["TEMPORARY"]},{"action":"Set","help":"C/C++ condition; the breakpoint stops only when it is true","long":"condition","name":"condition","takes_value":true,"value_names":["CONDITION"]},{"action":"Set","help":"Skip this many hits before stopping","long":"pass-count","name":"pass_count","takes_value":true,"value_names":["PASS_COUNT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["disabled","temporary","condition","pass_count"],"multiple":true,"name":"NativeBreakOptions","required":false}],"contract":{"output_mode":"json"},"name":"address","path":"debug break address","runs":"remote"},{"about":"Add a native data watchpoint: stop when memory is written (or read)","args":[{"action":"Set","help":"Variable in scope at the current stop, or a global, e.g. `g_counter`","long":"expression","name":"expression","takes_value":true,"value_names":["EXPRESSION"]},{"action":"Set","conflicts_with":["expression"],"help":"Watch this address instead of an expression's storage","long":"address","name":"address","takes_value":true,"value_names":["ADDRESS"]},{"action":"Set","help":"Bytes to watch (default: the expression's size; at most 8)","long":"size","name":"size","requires":["expression"],"takes_value":true,"value_names":["SIZE"]},{"action":"Set","default_values":["write"],"help":"Access that stops: write (default), read, or read-write","long":"access","name":"access","possible_values":["write","read","read-write"],"requires":["expression"],"takes_value":true,"value_names":["ACCESS"]},{"action":"SetTrue","help":"Create the breakpoint disabled","long":"disabled","name":"disabled","possible_values":["true","false"],"requires":["expression"],"value_names":["DISABLED"]},{"action":"SetTrue","help":"Remove the breakpoint after its first hit","long":"temporary","name":"temporary","possible_values":["true","false"],"requires":["expression"],"value_names":["TEMPORARY"]},{"action":"Set","help":"C/C++ condition; the breakpoint stops only when it is true","long":"condition","name":"condition","requires":["expression"],"takes_value":true,"value_names":["CONDITION"]},{"action":"Set","help":"Skip this many hits before stopping","long":"pass-count","name":"pass_count","requires":["expression"],"takes_value":true,"value_names":["PASS_COUNT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility","requires":["expression"]}],"argument_groups":[{"args":["disabled","temporary","condition","pass_count"],"multiple":true,"name":"NativeBreakOptions","required":false}],"contract":{"output_mode":"json"},"name":"data","path":"debug break data","runs":"remote"},{"about":"Add a Java/Kotlin wildcard method breakpoint","args":[{"action":"Set","help":"Class name or pattern","long":"class","name":"class","required":true,"takes_value":true,"value_names":["CLASS"]},{"action":"Set","help":"Method name","long":"method","name":"method","required":true,"takes_value":true,"value_names":["METHOD"]},{"action":"SetTrue","help":"Create the breakpoint disabled","long":"disabled","name":"disabled","possible_values":["true","false"],"value_names":["DISABLED"]},{"action":"Set","default_values":["true"],"help":"Break on method entry","long":"entry","name":"entry","possible_values":["true","false"],"takes_value":true,"value_names":["ENTRY"]},{"action":"SetTrue","help":"Break on method exit","long":"exit","name":"exit","possible_values":["true","false"],"value_names":["EXIT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["class","method","disabled","entry","exit"],"multiple":true,"name":"Method","required":false}],"contract":{"output_mode":"json"},"name":"method","path":"debug break method","runs":"remote"},{"about":"Add a Java/Kotlin field watchpoint at a source location","args":[{"action":"Set","dir":"in","help":"Source file containing the field (unused: the field is found by class and name)","long":"file","name":"file","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"Set","help":"One-based source line number","long":"line","name":"line","required":true,"takes_value":true,"value_names":["LINE"]},{"action":"Set","help":"Declaring class name","long":"class","name":"class","required":true,"takes_value":true,"value_names":["CLASS"]},{"action":"Set","help":"Field name","long":"field","name":"field","required":true,"takes_value":true,"value_names":["FIELD"]},{"action":"SetTrue","help":"Create the breakpoint disabled","long":"disabled","name":"disabled","possible_values":["true","false"],"value_names":["DISABLED"]},{"action":"SetTrue","help":"Create a temporary breakpoint","long":"temporary","name":"temporary","possible_values":["true","false"],"value_names":["TEMPORARY"]},{"action":"SetTrue","help":"Break on field access","long":"access","name":"access","possible_values":["true","false"],"value_names":["ACCESS"]},{"action":"Set","default_values":["true"],"help":"Break on field modification","long":"modification","name":"modification","possible_values":["true","false"],"takes_value":true,"value_names":["MODIFICATION"]},{"action":"SetTrue","help":"Use a real field watch, which slows the whole app","long":"accept-slowdown","name":"accept_slowdown","possible_values":["true","false"],"value_names":["ACCEPT_SLOWDOWN"]},{"action":"Set","default_values":["60000"],"help":"Auto-clear a field watch after this long","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["file","line","class","field","disabled","temporary","access","modification","accept_slowdown","duration_ms"],"multiple":true,"name":"Field","required":false}],"contract":{"output_mode":"json"},"name":"field","path":"debug break field","runs":"remote"},{"about":"Update a breakpoint by stable id. Native ids (nbp_...) support enabled, temporary, condition, clear-condition and pass-count; use `logpoint add` to create native logging breakpoints","args":[{"action":"Set","help":"Breakpoint id from `debug breakpoints`","long":"id","name":"id","required":true,"takes_value":true,"value_names":["ID"]},{"action":"Set","help":"Enable or disable the breakpoint","long":"enabled","name":"enabled","possible_values":["true","false"],"takes_value":true,"value_names":["ENABLED"]},{"action":"Set","help":"Mark breakpoint temporary or persistent","long":"temporary","name":"temporary","possible_values":["true","false"],"takes_value":true,"value_names":["TEMPORARY"]},{"action":"Set","conflicts_with":["clear_condition"],"help":"Breakpoint condition; the breakpoint stops only when it is true","long":"condition","name":"condition","takes_value":true,"value_names":["CONDITION"]},{"action":"SetTrue","help":"Clear any breakpoint condition","long":"clear-condition","name":"clear_condition","possible_values":["true","false"],"value_names":["CLEAR_CONDITION"]},{"action":"Set","conflicts_with":["clear_log_expression"],"help":"Log expression without stopping when suspend policy is `none`","long":"log-expression","name":"log_expression","takes_value":true,"value_names":["LOG_EXPRESSION"]},{"action":"SetTrue","help":"Clear the log expression","long":"clear-log-expression","name":"clear_log_expression","possible_values":["true","false"],"value_names":["CLEAR_LOG_EXPRESSION"]},{"action":"Set","help":"Toggle the default \"breakpoint hit\" log message","long":"log-message","name":"log_message","possible_values":["true","false"],"takes_value":true,"value_names":["LOG_MESSAGE"]},{"action":"Set","help":"Toggle stack trace logging","long":"log-stack","name":"log_stack","possible_values":["true","false"],"takes_value":true,"value_names":["LOG_STACK"]},{"action":"Set","help":"Suspend policy: all, thread, or none","long":"suspend","name":"suspend","possible_values":["all","thread","none"],"takes_value":true,"value_names":["SUSPEND"]},{"action":"Set","help":"Pass count. Use 0 to disable pass-count filtering","long":"pass-count","name":"pass_count","takes_value":true,"value_names":["PASS_COUNT"]},{"action":"SetTrue","help":"Set expressions even if they do not parse (they then fail at each hit)","long":"force","name":"force","possible_values":["true","false"],"value_names":["FORCE"]},{"action":"SetTrue","help":"Let the condition and log expression call app methods (runs app code)","long":"invoke","name":"invoke","possible_values":["true","false"],"value_names":["INVOKE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["id","enabled","temporary","condition","clear_condition","log_expression","clear_log_expression","log_message","log_stack","suspend","pass_count","force","invoke"],"multiple":true,"name":"BreakpointUpdateArgs","required":false}],"contract":{"output_mode":"json"},"name":"update","path":"debug break update","runs":"remote"},{"about":"Remove a breakpoint by stable id","args":[{"action":"Set","help":"Breakpoint id from `debug breakpoints`","long":"id","name":"id","required":true,"takes_value":true,"value_names":["ID"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"remove","path":"debug break remove","runs":"remote"}]},{"about":"Non-suspending debugger logpoints and their structured hit stream","contract":{"output_mode":"json"},"name":"logpoint","path":"debug logpoint","runs":"remote","subcommands":[{"about":"Configure a non-suspending line logpoint (Kotlin/Java or C/C++)","args":[{"action":"Set","dir":"in","help":"Source file: a path, or a file name or path suffix found under the project root","long":"file","name":"file","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"Set","help":"One-based source line number","long":"line","name":"line","required":true,"takes_value":true,"value_names":["LINE"]},{"action":"SetTrue","help":"Create the logpoint disabled","long":"disabled","name":"disabled","possible_values":["true","false"],"requires":["expression","log_message","log_stack"],"value_names":["DISABLED"]},{"action":"SetTrue","help":"Remove the logpoint after its first hit","long":"temporary","name":"temporary","possible_values":["true","false"],"requires":["expression","log_message","log_stack"],"value_names":["TEMPORARY"]},{"action":"Set","help":"Expression whose rendered value is logged at each matching hit","long":"expression","name":"expression","takes_value":true,"value_names":["EXPRESSION"]},{"action":"SetTrue","help":"Include the default breakpoint-hit message (location and thread)","long":"log-message","name":"log_message","possible_values":["true","false"],"value_names":["LOG_MESSAGE"]},{"action":"SetTrue","help":"Include a stack trace in the logged message","long":"log-stack","name":"log_stack","possible_values":["true","false"],"value_names":["LOG_STACK"]},{"action":"Set","help":"Boolean condition evaluated before logging","long":"condition","name":"condition","requires":["expression","log_message","log_stack"],"takes_value":true,"value_names":["CONDITION"]},{"action":"Set","help":"Log only after this many matching passes. Use 0 to disable filtering","long":"pass-count","name":"pass_count","requires":["expression","log_message","log_stack"],"takes_value":true,"value_names":["PASS_COUNT"]},{"action":"SetTrue","help":"Set expressions even if they do not parse (they then fail at each hit)","long":"force","name":"force","possible_values":["true","false"],"requires":["expression","log_message","log_stack"],"value_names":["FORCE"]},{"action":"Set","default_values":["olef"],"help":"Ownership label used for safe remove/clear operations","long":"owner","name":"owner","requires":["expression","log_message","log_stack"],"takes_value":true,"value_names":["OWNER"]},{"action":"Set","help":"Maximum structured events captured per second for this logpoint","long":"max-events-per-second","name":"max_events_per_second","requires":["expression","log_message","log_stack"],"takes_value":true,"value_names":["MAX_EVENTS_PER_SECOND"]},{"action":"Set","help":"Maximum rendered-message characters retained per structured event","long":"max-message-chars","name":"max_message_chars","takes_value":true,"value_names":["MAX_MESSAGE_CHARS"]},{"action":"SetTrue","help":"Let the expression and condition call app methods (runs app code)","long":"invoke","name":"invoke","possible_values":["true","false"],"requires":["expression","log_message","log_stack"],"value_names":["INVOKE"]},{"action":"Set","help":"Locations on the line: all (default), outer method, or innermost lambda","long":"variant","name":"variant","possible_values":["all","outer","lambda"],"requires":["expression","log_message","log_stack"],"takes_value":true,"value_names":["VARIANT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility","requires":["expression","log_message","log_stack"]}],"argument_groups":[{"args":["file","line","disabled","temporary","expression","log_message","log_stack","condition","pass_count","force","owner","max_events_per_second","max_message_chars","invoke","variant"],"multiple":true,"name":"LogpointAddArgs","required":false},{"args":["expression","log_message","log_stack"],"multiple":true,"name":"logpoint_output","required":true}],"contract":{"output_mode":"json"},"name":"add","path":"debug logpoint add","runs":"remote"},{"about":"List configured logpoints","args":[{"action":"Set","help":"Stable debugger session id","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Stable logpoint/breakpoint id","long":"id","name":"breakpoint_id","takes_value":true,"value_names":["BREAKPOINT_ID"]},{"action":"Set","help":"Ownership label to filter by","long":"owner","name":"owner","takes_value":true,"value_names":["OWNER"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","breakpoint_id","owner"],"multiple":true,"name":"LogpointFilterArgs","required":false}],"contract":{"output_mode":"json"},"name":"list","path":"debug logpoint list","runs":"remote"},{"about":"Read a bounded page of structured logpoint-hit events","args":[{"action":"Set","help":"Return events strictly newer than this cursor","long":"after","name":"after","requires":["stream_id"],"takes_value":true,"value_names":["AFTER"]},{"action":"Set","help":"Event-stream id that issued --after; both options must be supplied together","long":"stream-id","name":"stream_id","requires":["after"],"takes_value":true,"value_names":["STREAM_ID"]},{"action":"Set","default_values":["100"],"help":"Maximum number of events to return","long":"limit","name":"limit","takes_value":true,"value_names":["LIMIT"]},{"action":"Set","help":"Stable debugger session id","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Stable logpoint/breakpoint id","long":"id","name":"breakpoint_id","takes_value":true,"value_names":["BREAKPOINT_ID"]},{"action":"Set","help":"Ownership label to filter by","long":"owner","name":"owner","takes_value":true,"value_names":["OWNER"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","breakpoint_id","owner"],"multiple":true,"name":"LogpointFilterArgs","required":false}],"contract":{"output_mode":"json"},"name":"events","path":"debug logpoint events","runs":"remote"},{"about":"Follow structured logpoint-hit events as JSONL","args":[{"action":"Set","conflicts_with":["replay_existing"],"help":"Resume strictly after this cursor instead of starting at the live tail","long":"after","name":"after","requires":["stream_id"],"takes_value":true,"value_names":["AFTER"]},{"action":"Set","help":"Event-stream id that issued --after; both options must be supplied together","long":"stream-id","name":"stream_id","requires":["after"],"takes_value":true,"value_names":["STREAM_ID"]},{"action":"Set","default_values":["100"],"help":"Maximum events requested from the daemon in one page","long":"limit","name":"limit","takes_value":true,"value_names":["LIMIT"]},{"action":"Set","default_values":["1000"],"help":"Maximum daemon long-poll wait in milliseconds","long":"poll-ms","name":"poll_ms","takes_value":true,"value_names":["POLL_MS"]},{"action":"Set","help":"Stop after this many milliseconds. Omit to follow until Ctrl-C","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"Set","help":"Stop after emitting this many logpoint events","long":"max-events","name":"max_events","takes_value":true,"value_names":["MAX_EVENTS"]},{"action":"SetTrue","help":"Emit the current bounded event history before following new hits","long":"replay-existing","name":"replay_existing","possible_values":["true","false"],"value_names":["REPLAY_EXISTING"]},{"action":"Set","help":"Stable debugger session id","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Stable logpoint/breakpoint id","long":"id","name":"breakpoint_id","takes_value":true,"value_names":["BREAKPOINT_ID"]},{"action":"Set","help":"Ownership label to filter by","long":"owner","name":"owner","takes_value":true,"value_names":["OWNER"]}],"argument_groups":[{"args":["session","breakpoint_id","owner"],"multiple":true,"name":"LogpointFilterArgs","required":false}],"contract":{"output_mode":"jsonl"},"name":"follow","path":"debug logpoint follow","runs":"remote"},{"about":"Remove one Olef-owned logpoint by stable id","args":[{"action":"Set","help":"Stable id from `debug logpoint list` or `debug logpoint add`","long":"id","name":"id","required":true,"takes_value":true,"value_names":["ID"]},{"action":"Set","default_values":["olef"],"help":"Ownership label that must match the logpoint","long":"owner","name":"owner","takes_value":true,"value_names":["OWNER"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["id","owner"],"multiple":true,"name":"LogpointRemoveArgs","required":false}],"contract":{"output_mode":"json"},"name":"remove","path":"debug logpoint remove","runs":"remote"},{"about":"Remove Olef-owned logpoints matching the supplied scope","args":[{"action":"Set","default_values":["olef"],"help":"Remove only logpoints with this ownership label","long":"owner","name":"owner","takes_value":true,"value_names":["OWNER"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"clear","path":"debug logpoint clear","runs":"remote"}]},{"about":"List the session's breakpoints","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"breakpoints","path":"debug breakpoints","runs":"remote"},{"about":"Pause the selected debug session","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"pause","path":"debug pause","runs":"remote"},{"about":"Resume the selected debug session","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"resume","path":"debug resume","runs":"remote"},{"about":"Step into from the selected suspended session","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"step-in","path":"debug step-in","runs":"remote"},{"about":"Step over from the selected suspended session","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"step-over","path":"debug step-over","runs":"remote"},{"about":"Step out from the selected suspended session","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"step-out","path":"debug step-out","runs":"remote"},{"about":"Detach the debugger and resume the app (same as detach)","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"stop","path":"debug stop","runs":"remote"},{"about":"Detach the debugger and resume the app","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"detach","path":"debug detach","runs":"remote"},{"about":"Print stack frames for the selected suspended session","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","default_values":["64"],"help":"Maximum number of frames per stack","long":"limit","name":"limit","takes_value":true,"value_names":["LIMIT"]},{"action":"Set","default_values":["2500"],"help":"Debugger manager request timeout","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","limit","timeout_ms"],"multiple":true,"name":"StackArgs","required":false}],"contract":{"output_mode":"json"},"name":"stack","path":"debug stack","runs":"remote"},{"about":"Print debugger threads and their stack frames","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","default_values":["64"],"help":"Maximum number of frames per stack","long":"limit","name":"limit","takes_value":true,"value_names":["LIMIT"]},{"action":"Set","default_values":["2500"],"help":"Debugger manager request timeout","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","limit","timeout_ms"],"multiple":true,"name":"StackArgs","required":false}],"contract":{"output_mode":"json"},"name":"threads","path":"debug threads","runs":"remote"},{"about":"Print visible variables for the selected suspended frame","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Execution stack/thread index from `debug threads`","long":"thread","name":"thread","takes_value":true,"value_names":["THREAD"]},{"action":"Set","help":"Frame index within the selected thread","long":"frame","name":"frame","takes_value":true,"value_names":["FRAME"]},{"action":"Set","default_values":["0"],"help":"Object expansion depth. 0 prints only local values, 1 prints direct fields","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"Set","default_values":["64"],"help":"Maximum instance fields to include per object","long":"max-fields","name":"max_fields","takes_value":true,"value_names":["MAX_FIELDS"]},{"action":"Set","default_values":["32"],"help":"Maximum array/list items to include per array","long":"max-array-items","name":"max_array_items","takes_value":true,"value_names":["MAX_ARRAY_ITEMS"]},{"action":"Set","default_values":["2500"],"help":"Debugger manager request timeout","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","thread","frame","depth","max_fields","max_array_items","timeout_ms"],"multiple":true,"name":"VariablesArgs","required":false}],"contract":{"output_mode":"json"},"name":"variables","path":"debug variables","runs":"remote"},{"about":"Evaluate an expression in the selected frame","args":[{"action":"Set","help":"Deterministic expression path: `this`, a local name, fields, and array indexes","name":"expression","positional":true,"required":true,"takes_value":true,"value_names":["EXPRESSION"]},{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Execution stack/thread index from `debug threads`","long":"thread","name":"thread","takes_value":true,"value_names":["THREAD"]},{"action":"Set","help":"Frame index within the selected thread","long":"frame","name":"frame","takes_value":true,"value_names":["FRAME"]},{"action":"Set","default_values":["1"],"help":"Object expansion depth. 0 prints only the result value","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"Set","default_values":["64"],"help":"Maximum instance fields to include per object","long":"max-fields","name":"max_fields","takes_value":true,"value_names":["MAX_FIELDS"]},{"action":"Set","default_values":["32"],"help":"Maximum array/list items to include per array","long":"max-array-items","name":"max_array_items","takes_value":true,"value_names":["MAX_ARRAY_ITEMS"]},{"action":"Set","default_values":["5000"],"help":"Evaluation request timeout (bounds each method call with --invoke)","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Allow method calls and `toString()` rendering (runs app code)","long":"invoke","name":"invoke","possible_values":["true","false"],"value_names":["INVOKE"]},{"action":"Set","default_values":["4096"],"help":"Maximum characters of string values and rendered `toString()` text","long":"max-message-chars","name":"max_message_chars","takes_value":true,"value_names":["MAX_MESSAGE_CHARS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["expression","session","thread","frame","depth","max_fields","max_array_items","timeout_ms","invoke","max_message_chars"],"multiple":true,"name":"EvalArgs","required":false}],"contract":{"output_mode":"json"},"name":"eval","path":"debug eval","runs":"remote"},{"about":"Inspect an expression or a previously returned object handle","args":[{"action":"Set","conflicts_with":["handle"],"help":"Deterministic expression path: `this`, a local name, fields, and array indexes","name":"expression","positional":true,"takes_value":true,"value_names":["EXPRESSION"]},{"action":"Set","help":"Object handle returned by `debug variables`, `debug eval`, or `debug inspect`","long":"handle","name":"handle","takes_value":true,"value_names":["HANDLE"]},{"action":"Set","help":"Relative path from --handle, e.g. `.field[0]`","long":"path","name":"path","takes_value":true,"value_names":["PATH"]},{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Execution stack/thread index from `debug threads`","long":"thread","name":"thread","takes_value":true,"value_names":["THREAD"]},{"action":"Set","help":"Frame index within the selected thread","long":"frame","name":"frame","takes_value":true,"value_names":["FRAME"]},{"action":"Set","default_values":["1"],"help":"Object expansion depth. 0 prints only the result value","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"Set","default_values":["64"],"help":"Maximum instance fields to include per object","long":"max-fields","name":"max_fields","takes_value":true,"value_names":["MAX_FIELDS"]},{"action":"Set","default_values":["32"],"help":"Maximum array/list items to include per array","long":"max-array-items","name":"max_array_items","takes_value":true,"value_names":["MAX_ARRAY_ITEMS"]},{"action":"Set","default_values":["5000"],"help":"Inspection request timeout (bounds each method call with --invoke)","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Allow method calls and `toString()` rendering (runs app code)","long":"invoke","name":"invoke","possible_values":["true","false"],"value_names":["INVOKE"]},{"action":"Set","default_values":["4096"],"help":"Maximum characters of string values and rendered `toString()` text","long":"max-message-chars","name":"max_message_chars","takes_value":true,"value_names":["MAX_MESSAGE_CHARS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["expression","handle","path","session","thread","frame","depth","max_fields","max_array_items","timeout_ms","invoke","max_message_chars"],"multiple":true,"name":"InspectArgs","required":false}],"contract":{"output_mode":"json"},"name":"inspect","path":"debug inspect","runs":"remote"},{"about":"Coroutine and async-state inspection for suspended sessions","contract":{"output_mode":"json"},"name":"coroutines","path":"debug coroutines","runs":"remote","subcommands":[{"about":"Snapshot coroutine-like state reachable from suspended Java/Kotlin frames","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","default_values":["64"],"help":"Maximum threads/frames/continuations to include","long":"limit","name":"limit","takes_value":true,"value_names":["LIMIT"]},{"action":"Set","default_values":["1"],"help":"Object expansion depth for spilled locals","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"SetTrue","help":"Read each continuation's source line by calling its getStackTraceElement() (runs app code; needs a breakpoint or step stop)","long":"invoke","name":"invoke","possible_values":["true","false"],"value_names":["INVOKE"]},{"action":"Set","default_values":["2500"],"help":"Debugger manager request timeout","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","limit","depth","invoke","timeout_ms"],"multiple":true,"name":"CoroutineSnapshotArgs","required":false}],"contract":{"output_mode":"json"},"name":"snapshot","path":"debug coroutines snapshot","runs":"remote"},{"about":"Print debugger threads with dispatcher hints","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","default_values":["32"],"help":"Maximum threads to include","long":"limit","name":"limit","takes_value":true,"value_names":["LIMIT"]},{"action":"Set","default_values":["2500"],"help":"Debugger manager request timeout","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","limit","timeout_ms"],"multiple":true,"name":"CoroutineThreadsArgs","required":false}],"contract":{"output_mode":"json"},"name":"threads","path":"debug coroutines threads","runs":"remote"},{"about":"Inspect continuation-like objects in the selected frame","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Execution stack/thread index from `debug threads`","long":"thread","name":"thread","takes_value":true,"value_names":["THREAD"]},{"action":"Set","help":"Frame index within the selected thread","long":"frame","name":"frame","takes_value":true,"value_names":["FRAME"]},{"action":"Set","default_values":["2"],"help":"Object expansion depth for spilled locals","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"Set","default_values":["2500"],"help":"Debugger manager request timeout","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","thread","frame","depth","timeout_ms"],"multiple":true,"name":"CoroutineContinuationArgs","required":false}],"contract":{"output_mode":"json"},"name":"continuation","path":"debug coroutines continuation","runs":"remote"},{"about":"Inspect a Flow/StateFlow-like expression without collecting or invoking methods","args":[{"action":"Set","help":"Deterministic expression path to a Flow/StateFlow-like object","long":"expr","name":"expr","required":true,"takes_value":true,"value_names":["EXPR"]},{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Execution stack/thread index from `debug threads`","long":"thread","name":"thread","takes_value":true,"value_names":["THREAD"]},{"action":"Set","help":"Frame index within the selected thread","long":"frame","name":"frame","takes_value":true,"value_names":["FRAME"]},{"action":"Set","default_values":["2"],"help":"Object expansion depth","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"Set","default_values":["2500"],"help":"Debugger manager request timeout","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["expr","session","thread","frame","depth","timeout_ms"],"multiple":true,"name":"CoroutineFlowArgs","required":false}],"contract":{"output_mode":"json"},"name":"flow","path":"debug coroutines flow","runs":"remote"}]},{"about":"Resume until a source location (and optional condition) is reached","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","dir":"in","help":"Source file path to match against the top frame. Unless a breakpoint already exists at --file:--line, a temporary one is set there for the run and removed afterwards","long":"file","name":"file","requires":["line"],"takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"Set","help":"One-based source line to match against the top frame","long":"line","name":"line","requires":["file"],"takes_value":true,"value_names":["LINE"]},{"action":"Set","help":"Deterministic JDI path expression that must evaluate to true/non-null/non-zero","long":"condition","name":"condition","takes_value":true,"value_names":["CONDITION"]},{"action":"Set","default_values":["10000"],"help":"Stop waiting after this many milliseconds","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"Set","default_values":["100"],"help":"Poll interval while waiting","long":"poll-ms","name":"poll_ms","takes_value":true,"value_names":["POLL_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","file","line","condition","timeout_ms","poll_ms"],"multiple":true,"name":"ContinueUntilArgs","required":false}],"contract":{"output_mode":"json"},"name":"continue-until","path":"debug continue-until","runs":"remote"},{"about":"Watch expression commands","contract":{"output_mode":"json"},"name":"watch","path":"debug watch","runs":"remote","subcommands":[{"about":"Add or replace a watch expression","args":[{"action":"Set","name":"expression","positional":true,"required":true,"takes_value":true,"value_names":["EXPRESSION"]},{"action":"Set","help":"Optional stable name. Defaults to the expression text","long":"name","name":"name","takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"Allow method calls in the watch (runs app code on every breakpoint or step stop)","long":"invoke","name":"invoke","possible_values":["true","false"],"value_names":["INVOKE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["expression","name","invoke"],"multiple":true,"name":"Add","required":false}],"contract":{"output_mode":"json"},"name":"add","path":"debug watch add","runs":"remote"},{"about":"List watches and evaluate them if a session is suspended","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","default_values":["1"],"help":"Object expansion depth for evaluated watch values","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"Set","default_values":["64"],"help":"Maximum instance fields to include per object","long":"max-fields","name":"max_fields","takes_value":true,"value_names":["MAX_FIELDS"]},{"action":"Set","default_values":["32"],"help":"Maximum array/list items to include per array","long":"max-array-items","name":"max_array_items","takes_value":true,"value_names":["MAX_ARRAY_ITEMS"]},{"action":"Set","default_values":["2500"],"help":"Debugger manager request timeout","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","depth","max_fields","max_array_items","timeout_ms"],"multiple":true,"name":"WatchListArgs","required":false}],"contract":{"output_mode":"json"},"name":"list","path":"debug watch list","runs":"remote"},{"about":"Remove a watch by id","args":[{"action":"Set","help":"Id of the watch to remove (from `debug watch list`)","long":"id","name":"id","required":true,"takes_value":true,"value_names":["ID"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"remove","path":"debug watch remove","runs":"remote"},{"about":"Remove all watches","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"clear","path":"debug watch clear","runs":"remote"}]},{"about":"Native (C/C++) debugging: readiness, registers, memory, disassembly, modules, symbols, and instruction stepping","contract":{"output_mode":"json"},"name":"native","path":"debug native","runs":"remote","subcommands":[{"about":"What native debugging of an app needs (NDK, lldb-server for its ABI, debuggability, local symbols) and the native artifacts on the device","args":[{"action":"Set","help":"App alias or package. Defaults to config","name":"app_target","positional":true,"takes_value":true,"value_names":["TARGET"]},{"action":"Set","help":"App alias or installed package","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","help":"Exact package/process name. Overrides target and --app","long":"package","name":"package","takes_value":true,"value_names":["PACKAGE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app_target","app","package"],"multiple":true,"name":"NativeStatusArgs","required":false}],"contract":{"output_mode":"json"},"name":"status","path":"debug native status","runs":"remote"},{"about":"Registers of the selected frame (general purpose by default)","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Thread index, tid, or name from `debug threads`","long":"thread","name":"thread","takes_value":true,"value_names":["THREAD"]},{"action":"Set","help":"Frame index within the selected thread","long":"frame","name":"frame","takes_value":true,"value_names":["FRAME"]},{"action":"Set","help":"Register set name (substring), e.g. `floating`; default general purpose","long":"set","name":"set","takes_value":true,"value_names":["SET"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","thread","frame"],"multiple":true,"name":"NativeFrameArgs","required":false}],"contract":{"output_mode":"json"},"name":"registers","path":"debug native registers","runs":"remote"},{"about":"Read memory as a hex/ASCII dump","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","requires":["address","expression"],"takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Thread index, tid, or name from `debug threads`","long":"thread","name":"thread","requires":["address","expression"],"takes_value":true,"value_names":["THREAD"]},{"action":"Set","help":"Frame index within the selected thread","long":"frame","name":"frame","requires":["address","expression"],"takes_value":true,"value_names":["FRAME"]},{"action":"Set","help":"Start address (hex `0x…` or decimal)","long":"address","name":"address","takes_value":true,"value_names":["ADDRESS"]},{"action":"Set","help":"Pointer or register value (e.g. '$pc') to read from; for a non-pointer variable, read the object's storage. Cast integer addresses to void*","long":"expression","name":"expression","takes_value":true,"value_names":["EXPRESSION"]},{"action":"Set","default_values":["64"],"help":"Bytes to read (at most 4096)","long":"count","name":"count","requires":["address","expression"],"takes_value":true,"value_names":["COUNT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility","requires":["address","expression"]}],"argument_groups":[{"args":["session","thread","frame"],"multiple":true,"name":"NativeFrameArgs","required":false},{"args":["address","expression"],"multiple":false,"name":"memory_at","required":true}],"contract":{"output_mode":"json"},"name":"memory","path":"debug native memory","runs":"remote"},{"about":"Disassemble around the current pc, a function, or an address","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Thread index, tid, or name from `debug threads`","long":"thread","name":"thread","takes_value":true,"value_names":["THREAD"]},{"action":"Set","help":"Frame index within the selected thread","long":"frame","name":"frame","takes_value":true,"value_names":["FRAME"]},{"action":"Set","conflicts_with":["address"],"help":"Disassemble this function instead of the current frame","long":"function","name":"function","takes_value":true,"value_names":["FUNCTION"]},{"action":"Set","help":"Disassemble from this address instead of the current frame","long":"address","name":"address","takes_value":true,"value_names":["ADDRESS"]},{"action":"Set","default_values":["32"],"help":"Instructions to show (at most 512)","long":"count","name":"count","takes_value":true,"value_names":["COUNT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","thread","frame"],"multiple":true,"name":"NativeFrameArgs","required":false}],"contract":{"output_mode":"json"},"name":"disassemble","path":"debug native disassemble","runs":"remote"},{"about":"Loaded libraries: load address, build-id, and whether symbols are loaded","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"SetTrue","help":"Include system libraries, not only the app's","long":"all","name":"all","possible_values":["true","false"],"value_names":["ALL"]},{"action":"Set","help":"Only modules whose name contains this text","long":"filter","name":"filter","takes_value":true,"value_names":["FILTER"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","all","filter"],"multiple":true,"name":"NativeModulesArgs","required":false}],"contract":{"output_mode":"json"},"name":"modules","path":"debug native modules","runs":"remote"},{"about":"Load symbols from an unstripped library into the session","args":[{"action":"Set","dir":"in","help":"Unstripped library to load symbols from","name":"path","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["PATH"]},{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["path","session"],"multiple":true,"name":"NativeSymbolsArgs","required":false}],"contract":{"output_mode":"json"},"name":"symbols","path":"debug native symbols","runs":"remote"},{"about":"Step one machine instruction (`--over` steps over calls)","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Thread index, tid, or name","long":"thread","name":"thread","takes_value":true,"value_names":["THREAD"]},{"action":"SetTrue","help":"Step over calls instead of into them","long":"over","name":"over","possible_values":["true","false"],"value_names":["OVER"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","thread","over"],"multiple":true,"name":"NativeStepInstructionArgs","required":false}],"contract":{"output_mode":"json"},"name":"step-instruction","path":"debug native step-instruction","runs":"remote"}]},{"about":"Step over until the screen hash changes, then return a final snapshot","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","default_values":["10000"],"help":"Stop waiting after this many milliseconds","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"Set","default_values":["100"],"help":"Poll interval while waiting","long":"poll-ms","name":"poll_ms","takes_value":true,"value_names":["POLL_MS"]},{"action":"Set","aliases":["package"],"help":"App package used for the final snapshot","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","default_values":["1"],"help":"Include expanded top-frame variables in the final snapshot","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","timeout_ms","poll_ms","app","depth"],"multiple":true,"name":"StepWaitArgs","required":false}],"contract":{"output_mode":"json"},"name":"step-until-screen-change","path":"debug step-until-screen-change","runs":"remote"},{"about":"Step over until logcat emits a matching line, then return a final snapshot","args":[{"action":"Set","help":"Substring that must appear in a logcat line","long":"pattern","name":"pattern","required":true,"takes_value":true,"value_names":["PATTERN"]},{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","default_values":["10000"],"help":"Stop waiting after this many milliseconds","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"Set","default_values":["100"],"help":"Poll interval while waiting","long":"poll-ms","name":"poll_ms","takes_value":true,"value_names":["POLL_MS"]},{"action":"Set","aliases":["package"],"help":"App package used for the final snapshot","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","default_values":["1"],"help":"Include expanded top-frame variables in the final snapshot","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","timeout_ms","poll_ms","app","depth"],"multiple":true,"name":"StepWaitArgs","required":false}],"contract":{"output_mode":"json"},"name":"step-until-log","path":"debug step-until-log","runs":"remote"},{"about":"Resume and wait for a Java/native crash or ANR, then return a final snapshot. The device is released while waiting, so other commands can trigger it","args":[{"action":"Set","help":"Stable session id (preferred) or current index from `debug sessions`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","default_values":["30000"],"help":"Stop waiting after this many milliseconds","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"Set","aliases":["package"],"help":"App package used for the final snapshot","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","default_values":["120"],"help":"Number of recent logcat lines to include in the final snapshot/bundle","long":"logs","name":"logs","takes_value":true,"value_names":["LOGS"]},{"action":"Set","default_values":["1"],"help":"Include expanded top-frame variables in the final snapshot","long":"depth","name":"depth","takes_value":true,"value_names":["DEPTH"]},{"action":"Set","dir":"out","help":"Write the result JSON to a file instead of stdout","long":"out","name":"out","short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"Set","dir":"out","help":"Also write a local crash bundle to this directory","long":"bundle","name":"bundle","takes_value":true,"value_hint":"AnyPath","value_names":["BUNDLE"]},{"action":"SetTrue","help":"Collect best-effort ANR/tombstone artifacts when available","long":"native-artifacts","name":"native_artifacts","possible_values":["true","false"],"value_names":["NATIVE_ARTIFACTS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","timeout_ms","app","logs","depth","out","bundle","native_artifacts"],"multiple":true,"name":"RunUntilCrashArgs","required":false}],"contract":{"output_mode":"json"},"name":"run-until-crash","path":"debug run-until-crash","runs":"remote"},{"about":"List or pull native tombstone files from the device","contract":{"output_mode":"json"},"name":"tombstones","path":"debug tombstones","runs":"remote","subcommands":[{"about":"List recent native tombstone files visible through adb","args":[{"action":"Set","aliases":["package"],"help":"App alias/package label for output context","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"list","path":"debug tombstones list","runs":"remote"},{"about":"Pull recent native tombstone files into a local directory","args":[{"action":"Set","dir":"out","help":"Output directory","long":"out","name":"out","required":true,"short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"Set","aliases":["package"],"help":"App alias/package label for output context","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["out","app"],"multiple":true,"name":"TombstonePullArgs","required":false}],"contract":{"output_mode":"json"},"name":"pull","path":"debug tombstones pull","runs":"remote"}]}]},{"about":"Attach and manage the in-process runtime in debuggable apps","contract":{"output_mode":"json"},"examples":["--device emulator-5554 runtime attach --app io.github.andriyo.shadowdroid.sample","runtime attach --app <package> --startup --restart"],"name":"runtime","path":"runtime","runs":"remote","subcommands":[{"about":"Attach the runtime to a debuggable app, without the server APK","args":[{"action":"Set","aliases":["package"],"help":"App package","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","help":"App process id","long":"pid","name":"pid","takes_value":true,"value_names":["PID"]},{"action":"SetTrue","help":"Load on future app starts (API 29+), until runtime detach","long":"startup","name":"startup","possible_values":["true","false"],"value_names":["STARTUP"]},{"action":"SetTrue","conflicts_with":["pid"],"help":"Force-stop and relaunch the app, discarding its in-memory state","long":"restart","name":"restart","possible_values":["true","false"],"value_names":["RESTART"]},{"action":"Set","default_values":["20000"],"help":"Maximum wait for the host daemon to become ready after deployment","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Track coroutines with kotlinx DebugProbes from the moment the runtime starts (with --startup: from process start) for `runtime coroutines`","long":"coroutine-probes","name":"coroutine_probes","possible_values":["true","false"],"value_names":["COROUTINE_PROBES"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","pid"],"multiple":true,"name":"Selector","required":false}],"contract":{"output_mode":"json"},"examples":["--device emulator-5554 runtime attach --app io.github.andriyo.shadowdroid.sample","runtime attach --app <package> --startup --restart"],"name":"attach","path":"runtime attach","runs":"remote"},{"about":"List live runtime sessions (read-only on the device)","args":[{"action":"Set","aliases":["package"],"help":"App package","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","help":"App process id","long":"pid","name":"pid","takes_value":true,"value_names":["PID"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","pid"],"multiple":true,"name":"Selector","required":false}],"contract":{"output_mode":"json"},"name":"status","path":"runtime status","runs":"remote"},{"about":"Detach and remove the app's startup runtime agent","args":[{"action":"Set","aliases":["package"],"help":"App package","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","help":"App process id","long":"pid","name":"pid","takes_value":true,"value_names":["PID"]},{"action":"SetTrue","conflicts_with":["app","pid"],"help":"Detach every session and remove known startup agents on the selected device","long":"all","name":"all","possible_values":["true","false"],"value_names":["ALL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","pid"],"multiple":true,"name":"Selector","required":false}],"contract":{"output_mode":"json"},"name":"detach","path":"runtime detach","runs":"remote"},{"about":"Dump the app's live coroutines (state, context, stacks) via kotlinx DebugProbes, with no build changes; attaches the runtime if needed","args":[{"action":"Set","aliases":["package"],"help":"App package","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","help":"App process id","long":"pid","name":"pid","takes_value":true,"value_names":["PID"]},{"action":"SetTrue","help":"Include the full DebugProbes text dump (job hierarchy + stack traces)","long":"dump","name":"dump","possible_values":["true","false"],"value_names":["DUMP"]},{"action":"Set","default_values":["6"],"help":"Stack frames to show per coroutine in the structured list (0 = none)","long":"frames","name":"frames","takes_value":true,"value_names":["FRAMES"]},{"action":"Set","default_values":["200"],"help":"Cap the structured coroutine list (state counts are always complete)","long":"limit","name":"limit","takes_value":true,"value_names":["LIMIT"]},{"action":"Set","dir":"out","help":"Write the full text dump to this file (implies the dump is collected)","long":"out","name":"out","short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"SetTrue","help":"Emit a single JSON object instead of human-readable text","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]}],"argument_groups":[{"args":["app","pid"],"multiple":true,"name":"Selector","required":false}],"contract":{"output_mode":"human_or_json"},"name":"coroutines","path":"runtime coroutines","runs":"remote"}]},{"about":"Screen-record a device into a timestamped, crash-safe evidence bundle","contract":{"output_mode":"json"},"name":"video","path":"video","runs":"remote","subcommands":[{"about":"Record in the foreground until --duration elapses or Ctrl-C is pressed","args":[{"action":"Set","dir":"out","help":"New session-bundle directory. Existing paths are never overwritten","long":"out","name":"out","required":true,"short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["DIR"]},{"action":"Set","help":"Stop automatically after this duration (minimum 1s; for example 30s or 2m). Without it, record until Ctrl-C","long":"duration","name":"duration","takes_value":true,"value_names":["DURATION"]},{"action":"Set","default_values":["auto"],"help":"Recording backend. `auto` currently selects Android screenrecord","long":"backend","name":"backend","possible_values":["auto","screenrecord"],"takes_value":true,"value_names":["BACKEND"]},{"action":"Set","help":"Video dimensions as WIDTHxHEIGHT. Omit to use the device display size","long":"size","name":"size","takes_value":true,"value_names":["WIDTHxHEIGHT"]},{"action":"Set","help":"Encoder bit rate in bits per second","long":"bit-rate","name":"bit_rate","takes_value":true,"value_names":["BPS"]},{"action":"Set","help":"Android logical display id (only on screenrecord versions that support it)","long":"display-id","name":"display_id","takes_value":true,"value_names":["ID"]},{"action":"SetTrue","help":"Add Android's diagnostic screenrecord overlay","long":"bugreport","name":"bugreport","possible_values":["true","false"],"value_names":["BUGREPORT"]},{"action":"Set","default_values":["170"],"help":"Maximum length of each crash-safe MP4 segment","long":"segment-seconds","name":"segment_seconds","takes_value":true,"value_names":["SECONDS"]},{"action":"SetTrue","help":"Keep one segment across device rotation instead of splitting at rotation","long":"no-split-on-rotation","name":"no_split_on_rotation","possible_values":["true","false"],"value_names":["NO_SPLIT_ON_ROTATION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["backend","size","bit_rate","display_id","bugreport","segment_seconds","no_split_on_rotation"],"multiple":true,"name":"CaptureArgs","required":false}],"contract":{"output_mode":"json"},"name":"record","path":"video record","runs":"remote"},{"about":"Start a detached per-device recording session","args":[{"action":"Set","dir":"out","help":"New session-bundle directory. Existing paths are never overwritten","long":"out","name":"out","required":true,"short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["DIR"]},{"action":"Set","default_values":["auto"],"help":"Recording backend. `auto` currently selects Android screenrecord","long":"backend","name":"backend","possible_values":["auto","screenrecord"],"takes_value":true,"value_names":["BACKEND"]},{"action":"Set","help":"Video dimensions as WIDTHxHEIGHT. Omit to use the device display size","long":"size","name":"size","takes_value":true,"value_names":["WIDTHxHEIGHT"]},{"action":"Set","help":"Encoder bit rate in bits per second","long":"bit-rate","name":"bit_rate","takes_value":true,"value_names":["BPS"]},{"action":"Set","help":"Android logical display id (only on screenrecord versions that support it)","long":"display-id","name":"display_id","takes_value":true,"value_names":["ID"]},{"action":"SetTrue","help":"Add Android's diagnostic screenrecord overlay","long":"bugreport","name":"bugreport","possible_values":["true","false"],"value_names":["BUGREPORT"]},{"action":"Set","default_values":["170"],"help":"Maximum length of each crash-safe MP4 segment","long":"segment-seconds","name":"segment_seconds","takes_value":true,"value_names":["SECONDS"]},{"action":"SetTrue","help":"Keep one segment across device rotation instead of splitting at rotation","long":"no-split-on-rotation","name":"no_split_on_rotation","possible_values":["true","false"],"value_names":["NO_SPLIT_ON_ROTATION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["backend","size","bit_rate","display_id","bugreport","segment_seconds","no_split_on_rotation"],"multiple":true,"name":"CaptureArgs","required":false}],"contract":{"output_mode":"json"},"name":"start","path":"video start","runs":"remote"},{"about":"Report the active recorder, or running:false when this device is idle","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"status","path":"video status","runs":"remote"},{"about":"Read encoded coverage, gaps, and marker ranges from an existing bundle (no device required)","args":[{"action":"Set","dir":"in","name":"bundle","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["BUNDLE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"coverage","path":"video coverage","runs":"remote"},{"about":"Add a timestamped label to the active recording timeline","args":[{"action":"Set","help":"Searchable marker text, for example \"before checkout\"","name":"label","positional":true,"required":true,"takes_value":true,"value_names":["LABEL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"mark","path":"video mark","runs":"remote"},{"about":"Gracefully finalize and pull the active recording. Idempotent when idle","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"stop","path":"video stop","runs":"remote"}]},{"about":"Watch the app timeline: UI changes, crashes, toasts, watchers, and network events when available","args":[{"action":"Set","aliases":["package"],"help":"Only emit app-scoped events for this package. Permission dialogs are still allowed","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","default_values":["1000"],"help":"Safety-net poll interval (ms). Catches in-screen changes that emit no logcat transition — a counter ticking, async content loading — by re-dumping on this cadence. Navigation changes are caught immediately via logcat, independent of this; lower = notice silent changes sooner at the cost of more dumps","long":"poll-ms","name":"poll_ms","takes_value":true,"value_names":["POLL_MS"]},{"action":"Set","default_values":["80"],"help":"Settle delay (ms) after a logcat transition before dumping, so a burst of transition events (an animation, a multi-step navigation) collapses into one dump of the final screen instead of every intermediate frame. Not applied to poll ticks or post-command refreshes","long":"debounce-ms","name":"debounce_ms","takes_value":true,"value_names":["DEBOUNCE_MS"]},{"action":"SetTrue","help":"Don't read interactive commands from stdin; only stream events","long":"no-stdin","name":"no_stdin","possible_values":["true","false"],"value_names":["NO_STDIN"]},{"action":"SetTrue","help":"Don't parse logcat for crashes/ANRs (skip the crash watcher)","long":"no-crash-detect","name":"no_crash_detect","possible_values":["true","false"],"value_names":["NO_CRASH_DETECT"]},{"action":"SetTrue","help":"Emit the full element set (bounds + every UIAutomator flag) instead of the compact agent shape — the same flag as `ui dump --full`","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"Set","default_values":["ignore"],"help":"Built-in Android permission dialog policy","long":"permission-dialogs","name":"permission_dialogs","possible_values":["ignore","allow","deny"],"takes_value":true,"value_names":["PERMISSION_DIALOGS"]},{"action":"Append","dir":"in","help":"Load a JSON watcher-rules file (declarative popup auto-handlers). Repeatable to stack multiple rule files","long":"watcher-file","name":"watcher_file","takes_value":true,"value_names":["WATCHER_FILE"]},{"action":"SetTrue","help":"Do not try to attach live HTTP events from a running `net` proxy daemon","long":"no-net","name":"no_net","possible_values":["true","false"],"value_names":["NO_NET"]},{"action":"SetTrue","help":"Do not stream logpoint hits from an attached debug session","long":"no-logpoints","name":"no_logpoints","possible_values":["true","false"],"value_names":["NO_LOGPOINTS"]},{"action":"Set","default_values":["15000"],"help":"Emit `{\"type\":\"heartbeat\",…}` after this long without any other line, so a reader can tell an idle stream from a dead one. 0 turns heartbeats off","long":"heartbeat-ms","name":"heartbeat_ms","takes_value":true,"value_names":["HEARTBEAT_MS"]}],"argument_groups":[{"args":["app","poll_ms","debounce_ms","no_stdin","no_crash_detect","full","permission_dialogs","watcher_file","no_net","no_logpoints","heartbeat_ms"],"multiple":true,"name":"Watch","required":false}],"contract":{"output_mode":"jsonl"},"name":"watch","path":"watch","runs":"remote"},{"about":"Application lifecycle, info, and install rituals","contract":{"output_mode":"json"},"name":"app","path":"app","runs":"remote","subcommands":[{"about":"Launch the app's default activity, or an explicit activity with --activity","aliases":["launch"],"args":[{"action":"Set","help":"App package, app alias from config, or installed package name","name":"package","positional":true,"takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Explicit activity class to launch, e.g. .MainActivity or com.example.MainActivity","long":"activity","name":"activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"Set","help":"How long to wait for the activity to reach the foreground (default 15000; raise it for slow devices or apps with heavy startup)","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["package","activity","timeout_ms"],"multiple":true,"name":"Start","required":false}],"contract":{"output_mode":"json"},"examples":["app start com.example.app --activity .MainActivity"],"name":"start","path":"app start","runs":"remote"},{"about":"Force-stop the app","args":[{"action":"Set","help":"App package, app alias from config, or installed package name","name":"package","positional":true,"takes_value":true,"value_names":["PACKAGE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"stop","path":"app stop","runs":"remote"},{"about":"Install an APK and run the app-under-test setup ritual (clear/grant/launch/wait)","args":[{"action":"Set","dir":"in","help":"Path to the APK to install","name":"app_apk","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["APK"]},{"action":"Set","help":"Override the package name (otherwise read from the APK via aapt2)","long":"package","name":"package","takes_value":true,"value_names":["PACKAGE"]},{"action":"SetTrue","help":"Wipe app data after installing","long":"clear","name":"clear","possible_values":["true","false"],"value_names":["CLEAR"]},{"action":"SetTrue","help":"Grant every runtime permission the app declares","long":"grant-all","name":"grant_all","possible_values":["true","false"],"value_names":["GRANT_ALL"]},{"action":"Append","help":"Grant a specific runtime permission (repeatable)","long":"grant","name":"grant","takes_value":true,"value_names":["GRANT"]},{"action":"SetTrue","help":"Launch the app after installing","long":"launch","name":"launch","possible_values":["true","false"],"value_names":["LAUNCH"]},{"action":"SetTrue","help":"Launch and wait for the app to reach the foreground (implies --launch)","long":"wait-front","name":"wait_front","possible_values":["true","false"],"value_names":["WAIT_FRONT"]},{"action":"Set","default_values":["20000"],"help":"Timeout for --wait-front, in milliseconds","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app_apk","package","clear","grant_all","grant","launch","wait_front","timeout_ms"],"multiple":true,"name":"AppInstallArgs","required":false}],"contract":{"output_mode":"json"},"name":"install","path":"app install","runs":"remote"},{"about":"Build and get the current source onto the device the cheapest correct way: redefine + recompose in place, restart the activity, or reinstall; reports what it did, when the change takes effect and why","args":[{"action":"Set","help":"Gradle application module (`app`, or a nested path like `apps:phone`). Default: `module` in the config, else `app`","long":"module","name":"module","takes_value":true,"value_names":["MODULE"]},{"action":"Set","help":"Build variant. Default: `variant` in the config, else `debug`","long":"variant","name":"variant","takes_value":true,"value_names":["VARIANT"]},{"action":"Set","default_values":["auto"],"help":"`auto` applies in place when possible; `reinstall` always reinstalls","long":"mode","name":"mode","possible_values":["auto","reinstall"],"takes_value":true,"value_names":["MODE"]},{"action":"Set","help":"Apply at least this strongly, e.g. `restart-activity` when a value is cached somewhere the analysis cannot see","long":"at-least","name":"at_least","possible_values":["hot","restart-activity","reinstall"],"takes_value":true,"value_names":["AT_LEAST"]},{"action":"Set","default_values":["1800000"],"help":"Cooperative apply budget, including Gradle and reads. Dispatched app mutations finish and record their baseline even if the budget expires","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Leave out `screen` (what changed in the UI structure after the change: app, texts that appeared or went away), which costs two UI reads","long":"no-screen","name":"no_screen","possible_values":["true","false"],"value_names":["NO_SCREEN"]},{"action":"SetTrue","help":"Restart the activity with its ViewModels cleared, so what they computed is computed again (implies `--at-least restart-activity`). For a value a ViewModel cached, which a plain restart keeps","long":"fresh-viewmodels","name":"fresh_viewmodels","possible_values":["true","false"],"value_names":["FRESH_VIEWMODELS"]},{"action":"SetTrue","help":"Build what the next apply builds, without the device, so its Gradle and Kotlin daemons, configuration cache entry and D8 are warm: a cloud session runs it while the emulator boots. Changes nothing on the device","long":"prepare","name":"prepare","possible_values":["true","false"],"value_names":["PREPARE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["module","variant","mode","at_least","timeout_ms","no_screen","fresh_viewmodels","prepare"],"multiple":true,"name":"ApplyArgs","required":false}],"contract":{"output_mode":"json"},"name":"apply","path":"app apply","runs":"remote"},{"about":"Like `install`, but uninstall any existing copy first","args":[{"action":"Set","dir":"in","help":"Path to the APK to install","name":"app_apk","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["APK"]},{"action":"Set","help":"Override the package name (otherwise read from the APK via aapt2)","long":"package","name":"package","takes_value":true,"value_names":["PACKAGE"]},{"action":"SetTrue","help":"Wipe app data after installing","long":"clear","name":"clear","possible_values":["true","false"],"value_names":["CLEAR"]},{"action":"SetTrue","help":"Grant every runtime permission the app declares","long":"grant-all","name":"grant_all","possible_values":["true","false"],"value_names":["GRANT_ALL"]},{"action":"Append","help":"Grant a specific runtime permission (repeatable)","long":"grant","name":"grant","takes_value":true,"value_names":["GRANT"]},{"action":"SetTrue","help":"Launch the app after installing","long":"launch","name":"launch","possible_values":["true","false"],"value_names":["LAUNCH"]},{"action":"SetTrue","help":"Launch and wait for the app to reach the foreground (implies --launch)","long":"wait-front","name":"wait_front","possible_values":["true","false"],"value_names":["WAIT_FRONT"]},{"action":"Set","default_values":["20000"],"help":"Timeout for --wait-front, in milliseconds","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app_apk","package","clear","grant_all","grant","launch","wait_front","timeout_ms"],"multiple":true,"name":"AppInstallArgs","required":false}],"contract":{"output_mode":"json"},"name":"reinstall","path":"app reinstall","runs":"remote"},{"about":"Snapshot, restore, recover, and clean up private debuggable-app state","contract":{"output_mode":"json"},"name":"state","path":"app state","runs":"remote","subcommands":[{"about":"Snapshot selected private debuggable-app paths into a protected host directory","args":[{"action":"Set","aliases":["package"],"help":"App package or configured app alias. Defaults through normal app resolution","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","dir":"out","help":"New snapshot directory. Existing paths are refused","long":"out","name":"out","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"Append","help":"Private relative file/directory to include; repeat for multiple roots","long":"include","name":"include","required":true,"takes_value":true,"value_names":["INCLUDE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","out","include"],"multiple":true,"name":"Snapshot","required":false}],"contract":{"output_mode":"json"},"name":"snapshot","path":"app state snapshot","runs":"remote"},{"about":"Restore a snapshot transactionally, retaining private rollback data until verification","args":[{"action":"Set","aliases":["package"],"help":"Target app package or configured app alias. Defaults to the manifest package","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","dir":"in","help":"Snapshot directory containing manifest.json and data/","long":"from","name":"from","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["FROM"]},{"action":"SetTrue","help":"Override package/signature compatibility refusal. This is unsafe and explicit","long":"allow-incompatible","name":"allow_incompatible","possible_values":["true","false"],"value_names":["ALLOW_INCOMPATIBLE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","from","allow_incompatible"],"multiple":true,"name":"Restore","required":false}],"contract":{"output_mode":"json"},"name":"restore","path":"app state restore","runs":"remote"},{"about":"Resolve an interrupted restore by rolling back unverified state or finalizing verified state","args":[{"action":"Set","aliases":["package"],"help":"App package or configured app alias. Defaults through normal app resolution","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"recover","path":"app state recover","runs":"remote"},{"about":"Best-effort overwrite and delete of a protected host snapshot directory","args":[{"action":"Set","dir":"dir","help":"Snapshot directory to securely clean up","long":"from","name":"from","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["FROM"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"cleanup","path":"app state cleanup","runs":"remote"}]},{"about":"Clear the app's data","args":[{"action":"Set","help":"App package, app alias from config, or installed package name","name":"package","positional":true,"takes_value":true,"value_names":["PACKAGE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"clear","path":"app clear","runs":"remote"},{"about":"Version name/code + label","args":[{"action":"Set","help":"App package, app alias from config, or installed package name","name":"package","positional":true,"takes_value":true,"value_names":["PACKAGE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"info","path":"app info","runs":"remote"},{"about":"Wait for the app to launch (or, with --front, reach the foreground)","args":[{"action":"Set","help":"App package, app alias from config, or installed package name","name":"package","positional":true,"takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","default_values":["20000"],"help":"Give up after this many milliseconds","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"Set","conflicts_with":["timeout_ms"],"help":"Give up after this long, with a unit: `30s`, `500ms`, `2m`","long":"timeout","name":"timeout","takes_value":true,"value_names":["DURATION"]},{"action":"SetTrue","help":"Wait until the app reaches the foreground, not just until it launches","long":"front","name":"front","possible_values":["true","false"],"value_names":["FRONT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["package","timeout_ms","timeout","front"],"multiple":true,"name":"Wait","required":false}],"contract":{"output_mode":"json"},"name":"wait","path":"app wait","runs":"remote"},{"about":"Print the current foreground app (package / activity / pid)","args":[{"action":"SetTrue","help":"Accepted for consistency with other subcommands; output is always JSON","long":"json","name":"json","possible_values":["true","false"],"value_names":["JSON"]}],"contract":{"output_mode":"json"},"name":"current","path":"app current","runs":"remote"}]},{"about":"Runtime permission grants","contract":{"output_mode":"json"},"name":"perm","path":"perm","runs":"remote","subcommands":[{"about":"Grant one or more runtime permissions (verify-by-readback)","args":[{"action":"Set","name":"package","positional":true,"required":true,"takes_value":true,"value_names":["PACKAGE"]},{"action":"Append","help":"Permissions to grant (e.g. android.permission.CAMERA); one or more","name":"perms","num_args":"1..","positional":true,"required":true,"takes_value":true,"value_names":["PERMS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["package","perms"],"multiple":true,"name":"Grant","required":false}],"contract":{"output_mode":"json"},"name":"grant","path":"perm grant","runs":"remote"},{"about":"Revoke one or more runtime permissions","args":[{"action":"Set","name":"package","positional":true,"required":true,"takes_value":true,"value_names":["PACKAGE"]},{"action":"Append","help":"Permissions to revoke (e.g. android.permission.CAMERA); one or more","name":"perms","num_args":"1..","positional":true,"required":true,"takes_value":true,"value_names":["PERMS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["package","perms"],"multiple":true,"name":"Revoke","required":false}],"contract":{"output_mode":"json"},"name":"revoke","path":"perm revoke","runs":"remote"},{"about":"List a package's runtime permission grant states","args":[{"action":"Set","name":"package","positional":true,"required":true,"takes_value":true,"value_names":["PACKAGE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"list","path":"perm list","runs":"remote"},{"about":"Revoke all granted runtime permissions (fresh-install prompt state)","args":[{"action":"Set","name":"package","positional":true,"required":true,"takes_value":true,"value_names":["PACKAGE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"reset","path":"perm reset","runs":"remote"},{"about":"Answer the runtime-permission dialog on screen: `allow-foreground` (\"While using the app\", or \"Allow\" where that is the only grant), `allow-once` (\"Only this time\") or `deny` (\"Don't allow\"). Waits for the dialog, taps the answer whatever its id on this Android version, and waits for the dialog to close or the next one to replace it","args":[{"action":"Set","name":"choice","positional":true,"possible_values":["allow-foreground","allow-once","deny"],"required":true,"takes_value":true,"value_names":["CHOICE"]},{"action":"Set","default_values":["5000"],"help":"How long to wait for a permission dialog to appear, in milliseconds","long":"wait-ms","name":"wait_ms","takes_value":true,"value_names":["WAIT_MS"]},{"action":"Set","default_values":["5000"],"help":"How long to wait for the dialog to close after the tap, in milliseconds","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["choice","wait_ms","timeout_ms"],"multiple":true,"name":"Dialog","required":false}],"contract":{"output_mode":"json"},"name":"dialog","path":"perm dialog","runs":"remote"}]},{"about":"App-ops (allow|deny|ignore|default|… per operation)","contract":{"output_mode":"json"},"name":"appops","path":"appops","runs":"remote","subcommands":[{"about":"Get appop mode(s), preserving UID/package scopes and effective precedence","args":[{"action":"Set","name":"package","positional":true,"required":true,"takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","name":"op","positional":true,"takes_value":true,"value_names":["OP"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["package","op"],"multiple":true,"name":"Get","required":false}],"contract":{"output_mode":"json"},"name":"get","path":"appops get","runs":"remote"},{"about":"Set and verify an appop mode at an explicit UID or package scope","args":[{"action":"Set","name":"package","positional":true,"required":true,"takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","name":"op","positional":true,"required":true,"takes_value":true,"value_names":["OP"]},{"action":"Set","name":"mode","positional":true,"required":true,"takes_value":true,"value_names":["MODE"]},{"action":"Set","help":"Android policy scope. UID modes govern package modes when both exist","long":"scope","name":"scope","possible_values":["uid","package"],"required":true,"takes_value":true,"value_names":["SCOPE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["package","op","mode","scope"],"multiple":true,"name":"Set","required":false}],"contract":{"output_mode":"json"},"name":"set","path":"appops set","runs":"remote"}]},{"about":"Device display profile (animations, font, density, size, rotation)","contract":{"output_mode":"json"},"name":"profile","path":"profile","runs":"remote","subcommands":[{"about":"Capture the display profile as JSON, optionally to a file","args":[{"action":"Set","dir":"out","help":"Write the snapshot to this file instead of stdout","long":"out","name":"out","short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"snapshot","path":"profile snapshot","runs":"remote"},{"about":"Apply a preset (`automation`), a snapshot file, or individual flags","args":[{"action":"Set","help":"Named preset. `automation` zeroes the three animation scales","long":"preset","name":"preset","takes_value":true,"value_names":["PRESET"]},{"action":"Set","conflicts_with":["animations","density","font_scale","preset","rotation","size"],"dir":"in","help":"Apply a profile previously written by `profile-snapshot -o`","long":"file","name":"file","takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"Set","help":"Set all three animation scales to this value (e.g. 0 or 1)","long":"animations","name":"animations","takes_value":true,"value_names":["ANIMATIONS"]},{"action":"Set","help":"Set the font scale","long":"font-scale","name":"font_scale","takes_value":true,"value_names":["FONT_SCALE"]},{"action":"Set","help":"Set the display density (dpi)","long":"density","name":"density","takes_value":true,"value_names":["DENSITY"]},{"action":"Set","help":"Set the display size as WxH (e.g. 1080x2400)","long":"size","name":"size","takes_value":true,"value_names":["SIZE"]},{"action":"Set","help":"Pin rotation 0..3 (disables auto-rotate)","long":"rotation","name":"rotation","takes_value":true,"value_names":["ROTATION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["preset","file","animations","font_scale","density","size","rotation"],"multiple":true,"name":"ProfileApplyArgs","required":false}],"contract":{"output_mode":"json"},"name":"apply","path":"profile apply","runs":"remote"},{"about":"Reset the display profile to stock defaults","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"reset","path":"profile reset","runs":"remote"}]},{"about":"Device & system controls (info, shell, power, orientation, clipboard, …)","contract":{"output_mode":"json"},"name":"device","path":"device","runs":"remote","subcommands":[{"about":"Detailed device info (model, fingerprint, locale, density)","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"info","path":"device info","runs":"remote"},{"about":"Run a shell command on the device","args":[{"action":"Set","name":"cmd","positional":true,"required":true,"takes_value":true,"value_names":["CMD"]},{"action":"Set","default_values":["30000"],"help":"Kill the command and fail if it runs longer than this (milliseconds)","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["cmd","timeout_ms"],"multiple":true,"name":"Shell","required":false}],"contract":{"output_mode":"json"},"name":"shell","path":"device shell","runs":"remote"},{"about":"Wake the screen / turn the display on","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"wake","path":"device wake","runs":"remote"},{"about":"Put the display to sleep","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"sleep","path":"device sleep","runs":"remote"},{"about":"Wake and dismiss the keyguard","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"unlock","path":"device unlock","runs":"remote"},{"about":"Get (no value) or set the screen orientation","args":[{"action":"Set","name":"value","positional":true,"takes_value":true,"value_names":["VALUE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"orientation","path":"device orientation","runs":"remote"},{"about":"Get (no value) or set the clipboard","args":[{"action":"Set","name":"value","positional":true,"takes_value":true,"value_names":["VALUE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"clipboard","path":"device clipboard","runs":"remote"},{"about":"Open the notification shade","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"notifications","path":"device notifications","runs":"remote"},{"about":"Open quick settings","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"quick-settings","path":"device quick-settings","runs":"remote"},{"about":"Open a URL via an ACTION_VIEW intent","args":[{"action":"Set","name":"url","positional":true,"required":true,"takes_value":true,"value_names":["URL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"open-url","path":"device open-url","runs":"remote"}]},{"about":"On-device file operations","contract":{"output_mode":"json"},"name":"files","path":"files","runs":"remote","subcommands":[{"about":"List a directory on the device","args":[{"action":"Set","aliases":["package"],"help":"Resolve the path inside this debuggable app's private data directory","long":"app","name":"app","requires":["run_as"],"takes_value":true,"value_names":["APP"]},{"action":"SetTrue","help":"Access the path through Android run-as instead of shared/server storage","long":"run-as","name":"run_as","possible_values":["true","false"],"value_names":["RUN_AS"]},{"action":"Set","help":"Device path. An absolute path is that path on the device (shared storage through the Olef server, anything else through adb as the shell user); a relative path is inside Olef's own app storage. With --run-as, a path inside the app's data directory","name":"remote","positional":true,"required":true,"takes_value":true,"value_names":["REMOTE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","run_as","remote"],"multiple":true,"name":"Ls","required":false}],"contract":{"output_mode":"json"},"name":"ls","path":"files ls","runs":"remote"},{"about":"Push a local file to the device","args":[{"action":"Set","aliases":["package"],"help":"Resolve the destination inside this debuggable app's private data directory","long":"app","name":"app","requires":["run_as"],"takes_value":true,"value_names":["APP"]},{"action":"SetTrue","help":"Access the destination through Android run-as","long":"run-as","name":"run_as","possible_values":["true","false"],"value_names":["RUN_AS"]},{"action":"Set","dir":"in","name":"local","positional":true,"required":true,"takes_value":true,"value_names":["LOCAL"]},{"action":"Set","help":"Device path. An absolute path is that path on the device (shared storage through the Olef server, anything else through adb as the shell user); a relative path is inside Olef's own app storage. With --run-as, a path inside the app's data directory","name":"remote","positional":true,"required":true,"takes_value":true,"value_names":["REMOTE"]},{"action":"Set","help":"Require Unix permission bits after the push (octal, e.g. 644). Omit on shared/FUSE storage where Android controls the effective mode","long":"mode","name":"mode","takes_value":true,"value_names":["MODE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","run_as","local","remote","mode"],"multiple":true,"name":"Push","required":false}],"contract":{"output_mode":"json"},"name":"push","path":"files push","runs":"remote"},{"about":"Pull a device file to the host","args":[{"action":"Set","aliases":["package"],"help":"Resolve the source inside this debuggable app's private data directory","long":"app","name":"app","requires":["run_as"],"takes_value":true,"value_names":["APP"]},{"action":"SetTrue","help":"Access the source through Android run-as","long":"run-as","name":"run_as","possible_values":["true","false"],"value_names":["RUN_AS"]},{"action":"Set","help":"Device path. An absolute path is that path on the device (shared storage through the Olef server, anything else through adb as the shell user); a relative path is inside Olef's own app storage. With --run-as, a path inside the app's data directory","name":"remote","positional":true,"required":true,"takes_value":true,"value_names":["REMOTE"]},{"action":"Set","dir":"out","name":"local","positional":true,"required":true,"takes_value":true,"value_names":["LOCAL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","run_as","remote","local"],"multiple":true,"name":"Pull","required":false}],"contract":{"output_mode":"json"},"name":"pull","path":"files pull","runs":"remote"}]},{"about":"Network MITM proxy: enable, inspect, intercept, and modify HTTP(S) traffic","contract":{"output_mode":"json"},"name":"net","path":"net","runs":"remote","subcommands":[{"about":"Verdict: is this app interceptable (debuggable, NSC trusts user CA, engine proxy-aware)?","args":[{"action":"Set","help":"App package, app alias from config, or installed package name","name":"package","positional":true,"takes_value":true,"value_names":["PACKAGE"]},{"action":"SetTrue","help":"Launch a package-scoped HTTPS canary and wait for its exact decrypted request. The app must handle the canary VIEW intent and issue that URL itself","long":"probe","name":"probe","possible_values":["true","false"],"value_names":["PROBE"]},{"action":"Set","default_values":["10000"],"help":"How long to wait for the canary request, in milliseconds","long":"probe-timeout-ms","name":"probe_timeout_ms","takes_value":true,"value_names":["PROBE_TIMEOUT_MS"]},{"action":"SetTrue","help":"Ignore `proxy.ca_trusted` and the verify-once cache; probe the device","long":"fresh","name":"fresh","possible_values":["true","false"],"value_names":["FRESH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["package","probe","probe_timeout_ms","fresh"],"multiple":true,"name":"Check","required":false}],"contract":{"output_mode":"json"},"name":"check","path":"net check","runs":"remote"},{"about":"Install / trust the Olef CA on the device","args":[{"action":"SetTrue","help":"Choose the best available install path for this device (default)","long":"auto","name":"auto","possible_values":["true","false"],"value_names":["AUTO"]},{"action":"SetTrue","help":"Push into the system trust store (emulator/root)","long":"system","name":"system","possible_values":["true","false"],"value_names":["SYSTEM"]},{"action":"SetTrue","help":"Stage the CA in Downloads and open Settings for manual installation. A device screen-lock credential is required to finish the install","long":"push","name":"push","possible_values":["true","false"],"value_names":["PUSH"]},{"action":"SetTrue","conflicts_with":["push"],"help":"Legacy alias for --push. This does not automate certificate install","long":"ui","name":"ui","possible_values":["true","false"],"value_names":["UI"]},{"action":"SetTrue","help":"Ignore `proxy.ca_trusted` and the verify-once cache; install/verify against the device for real","long":"fresh","name":"fresh","possible_values":["true","false"],"value_names":["FRESH"]},{"action":"SetTrue","help":"Never restart adbd as root. By default a debuggable build (an emulator's google_apis image) is switched to a root adbd so the CA can go into the system store; that briefly drops adb forwards","long":"no-adb-root","name":"no_adb_root","possible_values":["true","false"],"value_names":["NO_ADB_ROOT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["auto","system","push","ui","fresh","no_adb_root"],"multiple":true,"name":"Trust","required":false}],"contract":{"output_mode":"json"},"name":"trust","path":"net trust","runs":"remote"},{"about":"Manage the proxy's signing CA (use your own, inspect it, or regenerate)","contract":{"output_mode":"json"},"name":"ca","path":"net ca","runs":"remote","subcommands":[{"about":"Install a user-provided CA as the proxy's signing CA (replaces the auto-generated one). Everything downstream — `net trust`, `net check`, leaf signing — then uses your CA. Re-run `net trust` after importing so the device trusts the new CA, and restart the proxy if it's running","args":[{"action":"Set","dir":"in","help":"PEM certificate file (your root/intermediate CA). May also contain the private key (a combined PEM like mitmproxy's `mitmproxy-ca.pem`)","long":"cert","name":"cert","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["PATH"]},{"action":"Set","dir":"in","help":"PEM private key file. Omit if the key is in the --cert file. PKCS#1 / SEC1 keys are converted to PKCS#8 via openssl automatically","long":"key","name":"key","takes_value":true,"value_hint":"AnyPath","value_names":["PATH"]},{"action":"SetTrue","conflicts_with":["global"],"help":"Operate on the per-project CA (`<project>/.olef/ca.*`)","long":"project","name":"project","possible_values":["true","false"],"value_names":["PROJECT"]},{"action":"SetTrue","conflicts_with":["project"],"help":"Operate on the global CA (`~/.olef/net/ca.*`)","long":"global","name":"global","possible_values":["true","false"],"value_names":["GLOBAL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["project","global"],"multiple":true,"name":"CaScopeArgs","required":false}],"contract":{"output_mode":"json"},"examples":["net ca import --cert mitmproxy-ca.pem","net ca import --cert corp-ca.crt --key corp-ca.key"],"name":"import","path":"net ca import","runs":"remote"},{"about":"Show the current signing CA: source, subject, validity, key type, and the Android trust-store hash","args":[{"action":"SetTrue","conflicts_with":["global"],"help":"Operate on the per-project CA (`<project>/.olef/ca.*`)","long":"project","name":"project","possible_values":["true","false"],"value_names":["PROJECT"]},{"action":"SetTrue","conflicts_with":["project"],"help":"Operate on the global CA (`~/.olef/net/ca.*`)","long":"global","name":"global","possible_values":["true","false"],"value_names":["GLOBAL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["project","global"],"multiple":true,"name":"CaScopeArgs","required":false}],"contract":{"output_mode":"json"},"name":"info","path":"net ca info","runs":"remote"},{"about":"Discard the current CA (backed up to `.bak`) and generate a fresh Olef CA — the way back after an import, and how a per-project CA is first minted (`--project`)","args":[{"action":"SetTrue","conflicts_with":["global"],"help":"Operate on the per-project CA (`<project>/.olef/ca.*`)","long":"project","name":"project","possible_values":["true","false"],"value_names":["PROJECT"]},{"action":"SetTrue","conflicts_with":["project"],"help":"Operate on the global CA (`~/.olef/net/ca.*`)","long":"global","name":"global","possible_values":["true","false"],"value_names":["GLOBAL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["project","global"],"multiple":true,"name":"CaScopeArgs","required":false}],"contract":{"output_mode":"json"},"name":"reset","path":"net ca reset","runs":"remote"}]},{"about":"Start the MITM proxy: spawn the daemon, `adb reverse`, set `http_proxy`","args":[{"action":"Set","default_values":["8080"],"help":"Proxy listen port (wired to the device via `adb reverse`)","long":"port","name":"port","takes_value":true,"value_names":["PORT"]},{"action":"Append","help":"Limit capture/MITM to domains or leading '*.' patterns (repeatable). Both example.com and '*.example.com' include the apex and subdomains; a bare fragment matches substrings. Other wildcards are rejected. Omit --host and proxy.hosts to capture all hosts","long":"host","name":"host","takes_value":true,"value_names":["HOST"]},{"action":"SetTrue","help":"Run the proxy in the foreground instead of detaching a daemon","long":"foreground","name":"foreground","possible_values":["true","false"],"value_names":["FOREGROUND"]},{"action":"SetTrue","help":"Strip cache-validation request headers (force fresh responses)","long":"anticache","name":"anticache","possible_values":["true","false"],"value_names":["ANTICACHE"]},{"action":"SetTrue","help":"Strip Accept-Encoding (force uncompressed responses)","long":"anticomp","name":"anticomp","possible_values":["true","false"],"value_names":["ANTICOMP"]},{"action":"SetTrue","conflicts_with":["verify_upstream"],"help":"Accept upstream TLS certificates that fail validation (self-signed, expired, wrong host). Upstream certificates are verified by default, so a tampered network cannot hide behind the Olef CA; use this only for a self-signed dev/staging backend you trust","long":"insecure-upstream","name":"insecure_upstream","possible_values":["true","false"],"value_names":["INSECURE_UPSTREAM"]},{"action":"SetTrue","help":"Deprecated no-op: upstream TLS is verified by default","long":"verify-upstream","name":"verify_upstream","possible_values":["true","false"],"value_names":["VERIFY_UPSTREAM"]},{"action":"Append","help":"Refuse connections to this destination (repeatable): a host ('example.com', '*.corp.example', or a bare substring), an IP address, or a CIDR range ('10.0.0.0/8', 'fd00::/8'). Names are resolved when ranges are listed; any blocked address refuses them. Refusals return 403 and appear as `blocked` events","long":"block-host","name":"block_host","takes_value":true,"value_names":["HOST|CIDR"]},{"action":"SetTrue","help":"Refuse the host's loopback, link-local and private (RFC 1918, IPv6 ULA) ranges and `localhost` names. Off by default so dev servers on localhost keep working; adb and the proxy's own ports are always refused","long":"block-local","name":"block_local","possible_values":["true","false"],"value_names":["BLOCK_LOCAL"]},{"action":"Append","help":"Relay this host's TLS without interception (repeatable; same forms as --host), for apps that pin certificates. Its connections appear as connection-level flows (`passthrough: true`, byte counts, no bodies). Change the list later with `net passthrough`","long":"passthrough-host","name":"passthrough_host","takes_value":true,"value_names":["HOST"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["port","host","foreground","anticache","anticomp","insecure_upstream","verify_upstream","block_host","block_local","passthrough_host"],"multiple":true,"name":"Start","required":false}],"contract":{"output_mode":"json"},"examples":["net start --host api.example.com","net start --block-local","net start --block-host 10.0.0.0/8 --block-host '*.corp.example'","net start --passthrough-host pinned.example.com"],"name":"start","path":"net start","runs":"remote"},{"about":"Stop the proxy and tear down device wiring","args":[{"action":"SetTrue","help":"Also remove the Olef CA from the device trust store","long":"revoke-ca","name":"revoke_ca","possible_values":["true","false"],"value_names":["REVOKE_CA"]},{"action":"Set","default_values":["example.com"],"env":"OLEF_NET_CANARY_HOST","help":"Neutral hostname used to verify DNS after teardown","long":"canary-host","name":"canary_host","takes_value":true,"value_names":["CANARY_HOST"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["revoke_ca","canary_host"],"multiple":true,"name":"Stop","required":false}],"contract":{"output_mode":"json"},"name":"stop","path":"net stop","runs":"remote"},{"about":"Proxy + device-wiring status (daemon, http_proxy, and adb reverse)","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"status","path":"net status","runs":"remote"},{"about":"Recall past flows from the session log","args":[{"action":"Set","conflicts_with":["after_checkpoint","after_id","host","limit","method","path","rule_id","session","since","status"],"help":"Clear queryable capture history while preserving a running proxy and its rules","name":"action","positional":true,"possible_values":["clear"],"takes_value":true,"value_names":["ACTION"]},{"action":"Set","help":"Filter by host (substring), e.g. api.example.com","long":"host","name":"host","takes_value":true,"value_names":["HOST"]},{"action":"Set","help":"Filter by URL path (substring)","long":"path","name":"path","takes_value":true,"value_names":["PATH"]},{"action":"Set","help":"Filter by HTTP method (GET, POST, …)","long":"method","name":"method","takes_value":true,"value_names":["METHOD"]},{"action":"Set","help":"Filter by response status code","long":"status","name":"status","takes_value":true,"value_names":["STATUS"]},{"action":"Set","default_values":["50"],"help":"Return at most this many flows: the most recent ones, listed oldest first","long":"limit","name":"limit","short":"n","takes_value":true,"value_names":["LIMIT"]},{"action":"Set","help":"Restrict results to one capture session id returned by `net start`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Restrict results to a recent duration, e.g. 500ms, 2m, 1h","long":"since","name":"since","takes_value":true,"value_names":["DURATION"]},{"action":"Set","conflicts_with":["after_checkpoint"],"help":"Exclude this flow id and every older flow in its capture session","long":"after-id","name":"after_id","takes_value":true,"value_names":["FLOW_ID"]},{"action":"Set","conflicts_with":["after_id"],"help":"Exclude events at or before a durable capture checkpoint","long":"after-checkpoint","name":"after_checkpoint","takes_value":true,"value_names":["CHECKPOINT"]},{"action":"Set","help":"Restrict results to flows modified by this rule id","long":"rule-id","name":"rule_id","takes_value":true,"value_names":["RULE_ID"]},{"action":"Set","conflicts_with":["action"],"help":"Which protocols to show. Default: HTTP + WebSocket lifecycle (no per-message frames). `websocket` shows WS messages too; `http` hides WebSockets; `all` shows everything","long":"protocol","name":"protocol","possible_values":["http","websocket","all"],"takes_value":true,"value_names":["PROTOCOL"]}],"argument_groups":[{"args":["action","host","path","method","status","limit","session","since","after_id","after_checkpoint","rule_id","protocol"],"multiple":true,"name":"Log","required":false}],"contract":{"output_mode":"jsonl"},"name":"log","path":"net log","runs":"remote"},{"about":"Mark the current capture boundary without stopping the proxy","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"checkpoint","path":"net checkpoint","runs":"remote"},{"about":"Full headers + bodies for one flow (or one WebSocket session/message)","args":[{"action":"Set","name":"id","positional":true,"required":true,"takes_value":true,"value_names":["ID"]},{"action":"SetTrue","help":"Include request/response bodies (not just headers)","long":"body","name":"body","possible_values":["true","false"],"value_names":["BODY"]},{"action":"Set","dir":"out","help":"Write the full response body to this file (avoids inline-JSON truncation for large responses) instead of printing the flow","long":"body-file","name":"body_file","takes_value":true,"value_hint":"AnyPath","value_names":["PATH"]},{"action":"SetTrue","conflicts_with":["body_file"],"help":"Emit the flow as a single-entry HAR object","long":"har","name":"har","possible_values":["true","false"],"value_names":["HAR"]},{"action":"Set","help":"Render a WebSocket message payload decoded: `hex`, `json` (pretty), or `protobuf` (schemaless field dump)","long":"format","name":"format","possible_values":["hex","json","protobuf"],"takes_value":true,"value_names":["FORMAT"]},{"action":"SetTrue","help":"Show the per-frame breakdown of a fragmented WebSocket message","long":"frames","name":"frames","possible_values":["true","false"],"value_names":["FRAMES"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["id","body","body_file","har","format","frames"],"multiple":true,"name":"Show","required":false}],"contract":{"output_mode":"json"},"name":"show","path":"net show","runs":"remote"},{"about":"Export flows for interop: `har`, `curl`, or `fixtures` (a versioned, content-addressed replay bundle with exact request keys). Fixture export skips redacted, truncated, streamed, errored, or body-incomplete flows and lists them in `skipped`; naming one flow id rejects it instead","args":[{"action":"Set","help":"Export format: har, curl, fixtures, or jsonl (durable line-per-record stream; the machine-readable format for WebSocket messages)","name":"format","positional":true,"possible_values":["har","curl","fixtures","jsonl"],"required":true,"takes_value":true,"value_names":["FORMAT"]},{"action":"Set","name":"id","positional":true,"takes_value":true,"value_names":["ID"]},{"action":"Set","dir":"out","help":"Output path: directory for `fixtures`, file for `jsonl` (stdout if omitted for `jsonl`)","long":"out","name":"out","short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"Set","help":"jsonl only (refused for other formats): which protocol to export (http | websocket | all). Default: all","long":"protocol","name":"protocol","possible_values":["http","websocket","all"],"takes_value":true,"value_names":["PROTOCOL"]},{"action":"Set","help":"jsonl only (refused for other formats): restrict to one capture session id","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["format","id","out","protocol","session"],"multiple":true,"name":"Export","required":false}],"contract":{"output_mode":"json_action_with_artifact"},"name":"export","path":"net export","runs":"remote"},{"about":"Inspect captured WebSocket traffic: sessions, then messages. Cheapest first — bare `net ws` lists sessions; `net ws <id>` lists that session's messages; `net show <message-id>` reveals a full payload","args":[{"action":"Set","help":"A session id (e.g. `w1`) to list its messages; omit to list sessions","name":"id","positional":true,"takes_value":true,"value_names":["SESSION_ID"]},{"action":"Set","help":"Filter by host (substring)","long":"host","name":"host","takes_value":true,"value_names":["HOST"]},{"action":"Set","help":"Only one direction: `c2s` (app→server) or `s2c` (server→app)","long":"dir","name":"dir","possible_values":["c2s","s2c"],"takes_value":true,"value_names":["DIR"]},{"action":"Set","help":"Only this frame type","long":"opcode","name":"opcode","possible_values":["text","binary","ping","pong","close"],"takes_value":true,"value_names":["OPCODE"]},{"action":"Set","help":"Only messages whose text/preview contains this (substring)","long":"grep","name":"grep","takes_value":true,"value_names":["GREP"]},{"action":"Set","help":"Restrict to one capture session id from `net start`","long":"session","name":"session","takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Restrict to a recent duration, e.g. 500ms, 2m, 1h","long":"since","name":"since","takes_value":true,"value_names":["DURATION"]},{"action":"SetTrue","help":"Summarize a session (opcode histogram, per-direction bytes, compression ratio, rate) instead of listing messages; needs a session id","long":"stats","name":"stats","possible_values":["true","false"],"value_names":["STATS"]},{"action":"Set","default_values":["50"],"help":"Return at most this many rows: the most recent ones, listed oldest first","long":"limit","name":"limit","short":"n","takes_value":true,"value_names":["LIMIT"]}],"argument_groups":[{"args":["id","host","dir","opcode","grep","session","since","stats","limit"],"multiple":true,"name":"Ws","required":false}],"contract":{"output_mode":"jsonl"},"name":"ws","path":"net ws","runs":"remote"},{"about":"Inject a WebSocket frame into a live captured session (see `net ws`). Uncompressed and safe even under permessage-deflate. Pick exactly one of --text/--binary/--ping/--pong/--close","args":[{"action":"Set","help":"Session id from `net ws` (e.g. `w1`)","name":"session","positional":true,"required":true,"takes_value":true,"value_names":["SESSION"]},{"action":"Set","help":"Direction: `s2c` (to the app, simulate a server push) or `c2s` (to the server, as if from the app)","long":"dir","name":"dir","possible_values":["c2s","s2c"],"required":true,"takes_value":true,"value_names":["DIR"]},{"action":"Set","conflicts_with":["binary","close","ping","pong"],"help":"Send a text frame with this payload","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","conflicts_with":["close","ping","pong","text"],"help":"Send a binary frame (base64-encoded payload)","long":"binary","name":"binary","takes_value":true,"value_names":["BINARY"]},{"action":"SetTrue","conflicts_with":["binary","close","pong","text"],"help":"Send a ping frame","long":"ping","name":"ping","possible_values":["true","false"],"value_names":["PING"]},{"action":"SetTrue","conflicts_with":["binary","close","ping","text"],"help":"Send a pong frame","long":"pong","name":"pong","possible_values":["true","false"],"value_names":["PONG"]},{"action":"SetTrue","conflicts_with":["binary","ping","pong","text"],"help":"Send a close frame","long":"close","name":"close","possible_values":["true","false"],"value_names":["CLOSE"]},{"action":"Set","help":"Close code (with --close), e.g. 1000","long":"code","name":"code","requires":["close"],"takes_value":true,"value_names":["CODE"]},{"action":"Set","help":"Close reason (with --close)","long":"reason","name":"reason","requires":["close"],"takes_value":true,"value_names":["REASON"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["session","dir","text","binary","ping","pong","close","code","reason"],"multiple":true,"name":"Inject","required":false}],"contract":{"output_mode":"json"},"name":"inject","path":"net inject","runs":"remote"},{"about":"Pause matching flows (or WebSocket frames, with --dir) for agent-in-the-loop editing","args":[{"action":"Set","help":"Only intercept flows/frames whose host contains this (substring)","long":"host","name":"host","takes_value":true,"value_names":["HOST"]},{"action":"Set","conflicts_with":["dir"],"help":"Only intercept flows whose URL path contains this (substring)","long":"path","name":"path","takes_value":true,"value_names":["PATH"]},{"action":"Set","conflicts_with":["dir"],"help":"Only intercept flows with this HTTP method","long":"method","name":"method","takes_value":true,"value_names":["METHOD"]},{"action":"Set","conflicts_with":["dir"],"help":"Only intercept flows with this response status (response phase; refused with `--at request`, where no status exists yet)","long":"status","name":"status","takes_value":true,"value_names":["STATUS"]},{"action":"Set","help":"Intercept WebSocket frames in this direction instead of HTTP flows: `s2c` (from the server) or `c2s` (from the app)","long":"dir","name":"dir","possible_values":["c2s","s2c"],"takes_value":true,"value_names":["DIR"]},{"action":"Set","help":"With --dir: only intercept frames of this opcode","long":"opcode","name":"opcode","possible_values":["text","binary","ping","pong","close"],"requires":["dir"],"takes_value":true,"value_names":["OPCODE"]},{"action":"SetTrue","help":"Disarm HTTP interception, or WebSocket interception with --dir. Already-held flows/frames keep their existing release/deadline lifecycle","long":"clear","name":"clear","possible_values":["true","false"],"value_names":["CLEAR"]},{"action":"Set","default_values":["response"],"help":"Hold at the request phase, response phase, or both (HTTP only)","long":"at","name":"at","possible_values":["request","response","both"],"takes_value":true,"value_names":["AT"]},{"action":"Set","default_values":["30000"],"help":"Auto-act after this long if the agent doesn't (apps time out their own client)","long":"hold-ms","name":"hold_ms","takes_value":true,"value_names":["HOLD_MS"]},{"action":"Set","default_values":["resume"],"help":"What to do when the hold deadline passes (fail-open by default)","long":"on-timeout","name":"on_timeout","possible_values":["resume","drop"],"takes_value":true,"value_names":["ON_TIMEOUT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["host","path","method","status","dir","opcode","clear","at","hold_ms","on_timeout"],"multiple":true,"name":"Intercept","required":false}],"contract":{"output_mode":"json"},"name":"intercept","path":"net intercept","runs":"remote"},{"about":"Release a held flow (optionally mutated) or a held WebSocket frame","args":[{"action":"Set","name":"id","positional":true,"required":true,"takes_value":true,"value_names":["ID"]},{"action":"Set","conflicts_with":["binary","body","set_header","set_status"],"help":"Held WebSocket frame: replace its payload with this text before forwarding","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","conflicts_with":["body","set_header","set_status","text"],"help":"Held WebSocket frame: replace its payload with this base64 binary","long":"binary","name":"binary","takes_value":true,"value_names":["BINARY"]},{"action":"Set","help":"Override the response status code","long":"set-status","name":"set_status","takes_value":true,"value_names":["SET_STATUS"]},{"action":"Append","help":"Set (or replace) a header; repeatable","long":"set-header","name":"set_header","takes_value":true,"value_names":["NAME=VALUE"]},{"action":"Append","help":"Remove a header; repeatable","long":"remove-header","name":"remove_header","takes_value":true,"value_names":["NAME"]},{"action":"Set","conflicts_with":["body_file"],"help":"Replace the body with this literal string","long":"body","name":"body","takes_value":true,"value_names":["BODY"]},{"action":"Set","conflicts_with":["body"],"dir":"in","help":"Replace the body with the contents of this file","long":"body-file","name":"body_file","takes_value":true,"value_hint":"AnyPath","value_names":["BODY_FILE"]},{"action":"Append","help":"Regex-replace within the body: --replace <REGEX> <REPL>","long":"replace","name":"replace","num_args":"2","takes_value":true,"value_names":["REGEX","REPL"]},{"action":"Set","help":"Delay the release by this many milliseconds (simulate latency)","long":"delay-ms","name":"delay_ms","takes_value":true,"value_names":["DELAY_MS"]},{"action":"Set","help":"Rewrite the request URL before forwarding (request phase). The captured flow then describes the forwarded URL and keeps the app's URL in `original_url`","long":"set-url","name":"set_url","takes_value":true,"value_names":["SET_URL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["id","text","binary","set_status","set_header","remove_header","body","body_file","replace","delay_ms","set_url"],"multiple":true,"name":"Resume","required":false}],"contract":{"output_mode":"json"},"name":"resume","path":"net resume","runs":"remote"},{"about":"Drop a held flow (HTTP 502 by default), or abort its transport explicitly","args":[{"action":"Set","name":"id","positional":true,"required":true,"takes_value":true,"value_names":["ID"]},{"action":"Set","help":"Return this HTTP status instead of the default 502","long":"set-status","name":"set_status","takes_value":true,"value_names":["SET_STATUS"]},{"action":"SetTrue","conflicts_with":["set_status"],"help":"Abort the HTTP connection/stream without sending a response status or body","long":"transport","name":"transport","possible_values":["true","false"],"value_names":["TRANSPORT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["id","set_status","transport"],"multiple":true,"name":"Drop","required":false}],"contract":{"output_mode":"json"},"name":"drop","path":"net drop","runs":"remote"},{"about":"Short-circuit a held request with a canned response (never hits the server)","args":[{"action":"Set","name":"id","positional":true,"required":true,"takes_value":true,"value_names":["ID"]},{"action":"Set","default_values":["200"],"help":"Status code of the canned response","long":"set-status","name":"set_status","takes_value":true,"value_names":["SET_STATUS"]},{"action":"Set","conflicts_with":["body_file"],"help":"Response body as a literal string","long":"body","name":"body","takes_value":true,"value_names":["BODY"]},{"action":"Set","conflicts_with":["body"],"dir":"in","help":"Response body from this file","long":"body-file","name":"body_file","takes_value":true,"value_hint":"AnyPath","value_names":["BODY_FILE"]},{"action":"Append","help":"Set a response header; repeatable","long":"set-header","name":"set_header","takes_value":true,"value_names":["NAME=VALUE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["id","set_status","body","body_file","set_header"],"multiple":true,"name":"Respond","required":false}],"contract":{"output_mode":"json"},"name":"respond","path":"net respond","runs":"remote"},{"about":"Relay certificate-pinned hosts' TLS without interception (runtime list)","contract":{"output_mode":"json"},"name":"passthrough","path":"net passthrough","runs":"remote","subcommands":[{"about":"Relay new CONNECT tunnels to these hosts still encrypted: no MITM, no rules, intercepts, or bodies; each connection is recorded as a connection-level flow. Connections already open stay as they are","args":[{"action":"Append","help":"Host to pass through: example.com or '*.example.com' (domain and subdomains) or a bare substring (repeatable)","long":"host","name":"host","required":true,"takes_value":true,"value_names":["HOST"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"examples":["net passthrough add --host pinned.example.com","net passthrough add --host '*.bank.example' --host api.payments.example"],"name":"add","path":"net passthrough add","runs":"remote"},{"about":"Intercept these hosts again (exact patterns as listed; repeatable)","args":[{"action":"Append","long":"host","name":"host","required":true,"takes_value":true,"value_names":["HOST"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"remove","path":"net passthrough remove","runs":"remote"},{"about":"List the hosts currently passed through","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"list","path":"net passthrough list","runs":"remote"}]},{"about":"Declarative response/request rules","contract":{"output_mode":"json"},"name":"rule","path":"net rule","runs":"remote","subcommands":[{"about":"Add a rule. Request-phase kinds: block, delay, map-local, map-remote, respond, set-request-header. Response-phase kinds: set-status, set-response-header, replace","args":[{"action":"Set","help":"block | delay | map-local | map-remote | respond | set-request-header | set-status | set-response-header | replace | set-json | ws-drop | ws-set-text","name":"kind","positional":true,"required":true,"takes_value":true,"value_names":["KIND"]},{"action":"Set","help":"Match flows whose host contains this (substring)","long":"host","name":"host","takes_value":true,"value_names":["HOST"]},{"action":"Set","help":"Match flows whose URL path contains this (substring)","long":"path","name":"path","takes_value":true,"value_names":["PATH"]},{"action":"Set","help":"Match flows with this HTTP method","long":"method","name":"method","takes_value":true,"value_names":["METHOD"]},{"action":"Set","help":"`ws-*` rules: restrict to a direction, `c2s` or `s2c`","long":"dir","name":"dir","possible_values":["c2s","s2c"],"takes_value":true,"value_names":["DIR"]},{"action":"Set","help":"`ws-*` rules: restrict to a frame opcode","long":"opcode","name":"opcode","possible_values":["text","binary","ping","pong","close"],"takes_value":true,"value_names":["OPCODE"]},{"action":"Set","help":"Match flows with this response content-type (substring)","long":"content-type","name":"content_type","takes_value":true,"value_names":["CONTENT_TYPE"]},{"action":"Set","help":"Match a GraphQL operationName in the URL query or JSON request body (HTTP rules)","long":"operation-name","name":"operation_name","takes_value":true,"value_names":["NAME"]},{"action":"Set","help":"Synthetic response status (respond only; default 200)","long":"status","name":"status","takes_value":true,"value_names":["CODE"]},{"action":"Append","help":"Synthetic response header as NAME=VALUE; repeatable (respond only)","long":"header","name":"header","takes_value":true,"value_names":["NAME=VALUE"]},{"action":"Set","conflicts_with":["body_file"],"help":"Synthetic response body literal (respond only)","long":"body","name":"body","takes_value":true,"value_names":["BODY"]},{"action":"Set","conflicts_with":["body"],"dir":"in","help":"Read the synthetic response body from a file (respond only)","long":"body-file","name":"body_file","takes_value":true,"value_hint":"AnyPath","value_names":["PATH"]},{"action":"Append","help":"Kind-specific positionals: block [status], delay <ms>, map-local <file>, map-remote <host:port>, respond (use flags), set-request-header <name> <value>, set-response-header <name> <value>, set-status <code>, replace <regex> <repl>, set-json <pointer> <expected-json> <value-json> [max-applications=1]","name":"args","num_args":"1..","positional":true,"takes_value":true,"value_names":["ARGS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["kind","host","path","method","dir","opcode","content_type","operation_name","status","header","body","body_file","args"],"multiple":true,"name":"NetRuleAddArgs","required":false}],"contract":{"output_mode":"json"},"examples":["net rule add map-local response.json --host api.example.com --path /v1/dict","net rule add set-status 503 --host api.example.com","net rule add respond --host api.example.com --method POST --operation-name currentSession --status 401 --header content-type=application/json --body '{\"errors\":[{\"message\":\"Unauthorized\"}]}'","net rule add set-request-header x-debug 1 --host api.example.com","net rule add set-response-header cache-control no-store --host api.example.com"],"name":"add","path":"net rule add","runs":"remote"},{"about":"List active rules","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"list","path":"net rule list","runs":"remote"},{"about":"Remove a rule by id","args":[{"action":"Set","name":"id","positional":true,"required":true,"takes_value":true,"value_names":["ID"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"rm","path":"net rule rm","runs":"remote"},{"about":"Remove all rules","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"clear","path":"net rule clear","runs":"remote"},{"about":"Validate a rules file without requiring a device or running proxy","args":[{"action":"Set","dir":"in","name":"file","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"lint","path":"net rule lint","runs":"remote"},{"about":"Explain which rules match one concrete flow and why","args":[{"action":"Set","dir":"in","help":"JSON array or legacy JSONL rules file","name":"file","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"Set","help":"Observed request/WebSocket host","long":"host","name":"host","required":true,"takes_value":true,"value_names":["HOST"]},{"action":"Set","default_values":["/"],"help":"Observed request path and query","long":"path","name":"path","takes_value":true,"value_names":["PATH"]},{"action":"Set","default_values":["GET"],"help":"Observed HTTP method","long":"method","name":"method","takes_value":true,"value_names":["METHOD"]},{"action":"Set","conflicts_with":["dir","opcode"],"help":"Response status; selects response-phase explanation","long":"status","name":"status","takes_value":true,"value_names":["STATUS"]},{"action":"Set","conflicts_with":["dir","opcode"],"help":"Response content type; selects response-phase explanation","long":"content-type","name":"content_type","takes_value":true,"value_names":["CONTENT_TYPE"]},{"action":"Set","default_values":[""],"help":"Request body used by GraphQL operation matchers","long":"body","name":"body","takes_value":true,"value_names":["BODY"]},{"action":"Set","help":"WebSocket direction; selects WebSocket-phase explanation","long":"dir","name":"dir","possible_values":["c2s","s2c"],"requires":["opcode"],"takes_value":true,"value_names":["DIR"]},{"action":"Set","help":"WebSocket opcode; selects WebSocket-phase explanation","long":"opcode","name":"opcode","possible_values":["text","binary","ping","pong","close"],"requires":["dir"],"takes_value":true,"value_names":["OPCODE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["file","host","path","method","status","content_type","body","dir","opcode"],"multiple":true,"name":"NetRuleExplainArgs","required":false}],"contract":{"output_mode":"json"},"name":"explain","path":"net rule explain","runs":"remote"}]},{"about":"Convenience: map URL-matching requests to a local response file","args":[{"action":"Set","help":"URL glob to match, e.g. https://api.example.com/v1/dict*","long":"url","name":"url","required":true,"takes_value":true,"value_names":["GLOB"]},{"action":"Set","dir":"in","help":"Local file to serve as the response body","long":"file","name":"file","required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["PATH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["url","file"],"multiple":true,"name":"Override","required":false}],"contract":{"output_mode":"json"},"examples":["net override --url 'https://api.example.com/v1/dict*' --file response.json"],"name":"override","path":"net override","runs":"remote"},{"about":"Atomically replace active rules from a validated JSON array/JSONL file","args":[{"action":"Set","dir":"in","name":"file","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"rules","path":"net rules","runs":"remote"},{"about":"Atomically serve a validated fixtures bundle without a backend","args":[{"action":"Set","dir":"in","help":"Directory (or manifest.json) produced by `net export fixtures`. Historical raw FlowRecord JSONL remains supported with strict parsing","long":"from","name":"from","takes_value":true,"value_hint":"AnyPath","value_names":["FROM"]},{"action":"Set","conflicts_with":["clear"],"help":"Select this exact canonical host from a multi-host bundle","long":"host","name":"host","requires":["from"],"takes_value":true,"value_names":["HOST"]},{"action":"SetTrue","conflicts_with":["from"],"help":"Stop serving the active replay set; requests reach their servers again","long":"clear","name":"clear","possible_values":["true","false"],"value_names":["CLEAR"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility","requires":["from"]}],"argument_groups":[{"args":["from","host","clear"],"multiple":true,"name":"Replay","required":false}],"contract":{"output_mode":"json"},"name":"replay","path":"net replay","runs":"remote"}]},{"about":"Live UI automation: dump, find, tap, type, and wait for screen state","contract":{"output_mode":"json"},"name":"ui","path":"ui","runs":"remote","subcommands":[{"about":"Dump the current UI as a flat element list","args":[{"action":"SetTrue","help":"Emit the full element set (bounds + every UIAutomator flag). Default is the compact agent shape: selector fields + tap, false flags omitted","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Ask the runtime's Compose inspector for semantics/layout nodes that are missing from the accessibility tree (attaches the runtime)","long":"deep","name":"deep","possible_values":["true","false"],"value_names":["DEEP"]},{"action":"Set","default_values":["8000"],"help":"Budget for --deep's Compose semantics read, in milliseconds","long":"deep-timeout-ms","name":"deep_timeout_ms","takes_value":true,"value_names":["DEEP_TIMEOUT_MS"]},{"action":"Set","help":"A `screen_hash` from an earlier read: report only what changed since that screen (`unchanged: true` when nothing did). Falls back to the full element list when that screen is no longer remembered","long":"since","name":"since","takes_value":true,"value_names":["SCREEN_HASH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["full","deep","deep_timeout_ms","since"],"multiple":true,"name":"Dump","required":false}],"contract":{"output_mode":"json"},"name":"dump","path":"ui dump","runs":"remote"},{"about":"Audit the current screen for interactive elements lacking a stable selector (resource-id / Compose testTag) — the ones that force a test to match on localized text or element index. Helps before writing a test. With --a11y, audit accessibility instead","args":[{"action":"SetTrue","help":"Check accessibility instead of selectors: unlabeled controls, touch targets under 48dp, low text contrast, duplicate names, stacked clickables and role words in descriptions. Takes one screenshot","long":"a11y","name":"a11y","possible_values":["true","false"],"value_names":["A11Y"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"audit","path":"ui audit","runs":"remote"},{"about":"Generate a starting-point Kotlin Screen Object from the current screen, with stable selectors filled in and un-tagged elements listed as TODOs","args":[{"action":"Set","default_values":["Generated"],"help":"Class-name prefix; the generated class is `<name>Screen`","long":"name","name":"name","takes_value":true,"value_names":["NAME"]}],"contract":{"output_mode":"source_text"},"name":"gen","path":"ui gen","runs":"remote"},{"about":"Capture a screenshot to a file","args":[{"action":"Set","dir":"out","name":"path","positional":true,"takes_value":true,"value_names":["PATH"]},{"action":"Set","help":"Image format: png (default) or jpeg","long":"format","name":"format","takes_value":true,"value_names":["FORMAT"]},{"action":"Set","help":"Server-side downscale factor, e.g. 0.5","long":"scale","name":"scale","takes_value":true,"value_names":["SCALE"]},{"action":"Set","help":"JPEG quality 1..100 (format=jpeg only)","long":"quality","name":"quality","takes_value":true,"value_names":["QUALITY"]},{"action":"SetTrue","help":"With global --redact enabled, black out accessibility bounds whose text matches the active policy. PNG only; pixels remain potentially sensitive because Android may not expose every rendered glyph","long":"redact-pixels","name":"redact_pixels","possible_values":["true","false"],"value_names":["REDACT_PIXELS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["path","format","scale","quality","redact_pixels"],"multiple":true,"name":"Screenshot","required":false}],"contract":{"output_mode":"json"},"name":"screenshot","path":"ui screenshot","runs":"remote"},{"about":"Find elements by selector (--text/--rid/--desc/--xpath); does not tap","args":[{"action":"Set","help":"Match by visible text (normalized, case-insensitive substring; add --exact for a full match)","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Match by resource-id (substring)","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Match by content-description (normalized substring)","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"Set","help":"Match by xpath, e.g. //*[@text='Foo'] or //*[contains(@text,'Foo')]","long":"xpath","name":"xpath","takes_value":true,"value_names":["XPATH"]},{"action":"SetTrue","help":"Return all matches instead of the first","long":"all","name":"all","possible_values":["true","false"],"value_names":["ALL"]},{"action":"SetTrue","help":"Match selector values exactly instead of as a substring","long":"exact","name":"exact","possible_values":["true","false"],"value_names":["EXACT"]},{"action":"SetTrue","help":"Only match clickable elements (skips labels/containers with the same text)","long":"clickable","name":"clickable","possible_values":["true","false"],"value_names":["CLICKABLE"]},{"action":"SetTrue","help":"Emit the full element set instead of the compact agent shape","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["text","rid","desc","xpath","all","exact","clickable","full"],"multiple":true,"name":"Find","required":false}],"contract":{"output_mode":"json"},"name":"find","path":"ui find","runs":"remote"},{"about":"Tap by element id, coordinates, or a selector (--text/--rid/--desc/--xpath)","args":[{"action":"Set","help":"Screen-bound handle from a fresh `ui dump` (i:.../e:...)","long":"handle","name":"handle","takes_value":true,"value_names":["HANDLE"]},{"action":"Set","help":"Element id from a fresh `ui dump`. Equivalent to positional `ui tap <id>`","long":"id","name":"id","takes_value":true,"value_names":["ID"]},{"action":"Set","help":"Compose fallback id (cs:<draw-id> or cl:<draw-id>) from a fresh `ui dump --deep`. High-confidence cs: targets may be tapped directly; cl: targets require --coordinate-fallback and --if-screen","long":"fallback-id","name":"fallback_id","takes_value":true,"value_names":["FALLBACK_ID"]},{"action":"Set","help":"Element id (from `ui dump`) or X coordinate","name":"a","positional":true,"takes_value":true,"value_names":["A"]},{"action":"Set","help":"Y coordinate (with X for a coordinate tap)","name":"b","positional":true,"takes_value":true,"value_names":["B"]},{"action":"Set","help":"Tap the element matching this visible text (normalized substring; --exact for full)","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Tap the element matching this resource-id (substring)","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Tap the element matching this content-description (substring)","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"Set","help":"Tap the element matching this xpath","long":"xpath","name":"xpath","takes_value":true,"value_names":["XPATH"]},{"action":"SetTrue","help":"Match selector values exactly instead of as a substring. Avoids tapping a label whose text merely contains the target (e.g. \"Allow notifications…\" vs \"Allow\")","long":"exact","name":"exact","possible_values":["true","false"],"value_names":["EXACT"]},{"action":"SetTrue","help":"Require the matched node itself to be clickable instead of resolving its nearest enabled clickable ancestor","long":"clickable","name":"clickable","possible_values":["true","false"],"value_names":["CLICKABLE"]},{"action":"SetTrue","help":"Explicitly allow center-coordinate injection when no enabled clickable target can perform ACTION_CLICK. Selector taps otherwise fail safely","long":"coordinate-fallback","name":"coordinate_fallback","possible_values":["true","false"],"value_names":["COORDINATE_FALLBACK"]},{"action":"SetTrue","help":"Tap even when the target is covered by the keyboard, a dialog, a system bar or an element drawn on top. Id and selector taps are otherwise refused with `element_occluded`, because a user's finger would land on the cover instead","long":"allow-occluded","name":"allow_occluded","possible_values":["true","false"],"value_names":["ALLOW_OCCLUDED"]},{"action":"Set","default_values":["8000"],"help":"Budget for --fallback-id's Compose semantics read, in milliseconds","long":"deep-timeout-ms","name":"deep_timeout_ms","takes_value":true,"value_names":["DEEP_TIMEOUT_MS"]},{"action":"Set","help":"How the tap reaches an element: `accessibility` (default: a click on its clickable node) or `touch` (a real finger tap at its visible point, for views that react to touches but not to clicks)","long":"via","name":"via","possible_values":["accessibility","touch"],"takes_value":true,"value_names":["HOW"]},{"action":"Set","help":"Wait up to this long for the target to be on screen, unique, enabled and uncovered before acting, re-reading the screen until it is. Nothing is injected while waiting. Default: one attempt","long":"wait-ms","name":"wait_ms","takes_value":true,"value_names":["MS"]},{"action":"SetTrue","help":"Bring the target into view first: wait for the screen to settle, hide the keyboard when it hides or covers the target, then scroll the nearest list (down, then up) until the target shows. Needs --text, --rid or --desc","long":"reveal","name":"reveal","possible_values":["true","false"],"value_names":["REVEAL"]},{"action":"Set","help":"Require the target to be checked afterwards (`false`: unchecked), read back on a stable screen. Switches, checkboxes, and Compose chips and toggles. Needs --text, --rid or --desc","long":"expect-checked","name":"expect_checked","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"Require the target to be selected afterwards (`false`: not selected). Tabs and list items; Compose reports selectable chips as checked","long":"expect-selected","name":"expect_selected","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"Require the target to be enabled afterwards (`false`: disabled)","long":"expect-enabled","name":"expect_enabled","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"SetTrue","help":"In a session with --app: this step acts outside the app under test on purpose (share sheet, browser, settings), so skip the foreground guard","long":"allow-other-app","name":"allow_other_app","possible_values":["true","false"],"value_names":["ALLOW_OTHER_APP"]},{"action":"SetTrue","help":"In a session with --app: a crash or ANR of an app process during this step does not fail it","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"In a session with --app: when system UI (notification shade, heads-up) covers the app, collapse it and retry once instead of failing. Recorded as a flake signal","long":"dismiss-system-ui","name":"dismiss_system_ui","possible_values":["true","false"],"value_names":["DISMISS_SYSTEM_UI"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash (from your last `ui dump`/`ui wait`). On mismatch the command fails with code=screen_changed and the fresh compact screen in `detail` — use that instead of re-dumping","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash. Unlike --if-screen, volatile display content is ignored","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Include the post-action compact screen in this same response (saves the follow-up `ui dump` round-trip)","long":"observe","name":"observe","possible_values":["true","false"],"value_names":["OBSERVE"]},{"action":"Set","default_values":["500"],"help":"Required accessibility-event quiet period before the observed screen is considered stable, in milliseconds","long":"observe-delay-ms","name":"observe_delay_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["3000"],"help":"Overall deadline for stable observation and any --expect-* postcondition","long":"timeout-ms","name":"observe_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Require a stable destination containing this visible text","long":"expect-text","name":"expect_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Require a stable destination containing this content description","long":"expect-desc","name":"expect_desc","takes_value":true,"value_names":["DESCRIPTION"]},{"action":"Set","help":"Require a stable destination containing this resource id","long":"expect-rid","name":"expect_rid","takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"Set","help":"Require this foreground package after the action","long":"expect-package","name":"expect_package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Require this foreground activity after the action","long":"expect-activity","name":"expect_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"SetTrue","help":"Match the --expect-* value exactly (case-insensitive) instead of as a substring","long":"expect-exact","name":"expect_exact","possible_values":["true","false"],"value_names":["EXPECT_EXACT"]},{"action":"SetTrue","help":"With a satisfied --expect-* postcondition, return the whole post-action screen instead of its summary (hashes, foreground app, top texts)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["wait_ms","reveal","expect_checked","expect_selected","expect_enabled"],"multiple":true,"name":"TargetArgs","required":false},{"args":["allow_other_app","allow_crash","dismiss_system_ui"],"multiple":true,"name":"GuardArgs","required":false}],"contract":{"output_mode":"json"},"name":"tap","path":"ui tap","runs":"remote"},{"about":"Set a slider/range control through Android accessibility and verify readback","args":[{"action":"Set","help":"Screen-bound handle from a fresh `ui dump` (i:.../e:...)","long":"handle","name":"handle","takes_value":true,"value_names":["HANDLE"]},{"action":"Set","help":"Element id from a fresh `ui dump`","long":"id","name":"id","takes_value":true,"value_names":["ID"]},{"action":"Set","help":"Match by exact/normalized visible text","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Match by resource id or Compose test tag","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Match by content description","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"Set","help":"Match by supported xpath","long":"xpath","name":"xpath","takes_value":true,"value_names":["XPATH"]},{"action":"SetTrue","help":"Match selector values exactly instead of as a substring","long":"exact","name":"exact","possible_values":["true","false"],"value_names":["EXACT"]},{"action":"Set","allow_hyphen_values":true,"help":"Absolute value in the control's exposed min..max range","long":"value","name":"value","takes_value":true,"value_names":["VALUE"]},{"action":"Set","allow_hyphen_values":true,"help":"Position from 0 to 100 within the exposed range","long":"percent","name":"percent","takes_value":true,"value_names":["PERCENT"]},{"action":"SetTrue","help":"Clamp an out-of-range value/percent instead of rejecting it","long":"clamp","name":"clamp","possible_values":["true","false"],"value_names":["CLAMP"]},{"action":"SetTrue","help":"Explicitly permit an approximate coordinate track click when semantic mutation is unavailable","long":"coordinate-fallback","name":"coordinate_fallback","possible_values":["true","false"],"value_names":["COORDINATE_FALLBACK"]},{"action":"Set","help":"Wait up to this long for the target to be on screen, unique, enabled and uncovered before acting, re-reading the screen until it is. Nothing is injected while waiting. Default: one attempt","long":"wait-ms","name":"wait_ms","takes_value":true,"value_names":["MS"]},{"action":"SetTrue","help":"Bring the target into view first: wait for the screen to settle, hide the keyboard when it hides or covers the target, then scroll the nearest list (down, then up) until the target shows. Needs --text, --rid or --desc","long":"reveal","name":"reveal","possible_values":["true","false"],"value_names":["REVEAL"]},{"action":"Set","help":"Require the target to be checked afterwards (`false`: unchecked), read back on a stable screen. Switches, checkboxes, and Compose chips and toggles. Needs --text, --rid or --desc","long":"expect-checked","name":"expect_checked","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"Require the target to be selected afterwards (`false`: not selected). Tabs and list items; Compose reports selectable chips as checked","long":"expect-selected","name":"expect_selected","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"Require the target to be enabled afterwards (`false`: disabled)","long":"expect-enabled","name":"expect_enabled","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"SetTrue","help":"In a session with --app: this step acts outside the app under test on purpose (share sheet, browser, settings), so skip the foreground guard","long":"allow-other-app","name":"allow_other_app","possible_values":["true","false"],"value_names":["ALLOW_OTHER_APP"]},{"action":"SetTrue","help":"In a session with --app: a crash or ANR of an app process during this step does not fail it","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"In a session with --app: when system UI (notification shade, heads-up) covers the app, collapse it and retry once instead of failing. Recorded as a flake signal","long":"dismiss-system-ui","name":"dismiss_system_ui","possible_values":["true","false"],"value_names":["DISMISS_SYSTEM_UI"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash (from your last `ui dump`/`ui wait`). On mismatch the command fails with code=screen_changed and the fresh compact screen in `detail` — use that instead of re-dumping","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash. Unlike --if-screen, volatile display content is ignored","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Include the post-action compact screen in this same response (saves the follow-up `ui dump` round-trip)","long":"observe","name":"observe","possible_values":["true","false"],"value_names":["OBSERVE"]},{"action":"Set","default_values":["500"],"help":"Required accessibility-event quiet period before the observed screen is considered stable, in milliseconds","long":"observe-delay-ms","name":"observe_delay_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["3000"],"help":"Overall deadline for stable observation and any --expect-* postcondition","long":"timeout-ms","name":"observe_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Require a stable destination containing this visible text","long":"expect-text","name":"expect_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Require a stable destination containing this content description","long":"expect-desc","name":"expect_desc","takes_value":true,"value_names":["DESCRIPTION"]},{"action":"Set","help":"Require a stable destination containing this resource id","long":"expect-rid","name":"expect_rid","takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"Set","help":"Require this foreground package after the action","long":"expect-package","name":"expect_package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Require this foreground activity after the action","long":"expect-activity","name":"expect_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"SetTrue","help":"Match the --expect-* value exactly (case-insensitive) instead of as a substring","long":"expect-exact","name":"expect_exact","possible_values":["true","false"],"value_names":["EXPECT_EXACT"]},{"action":"SetTrue","help":"With a satisfied --expect-* postcondition, return the whole post-action screen instead of its summary (hashes, foreground app, top texts)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["wait_ms","reveal","expect_checked","expect_selected","expect_enabled"],"multiple":true,"name":"TargetArgs","required":false},{"args":["allow_other_app","allow_crash","dismiss_system_ui"],"multiple":true,"name":"GuardArgs","required":false}],"contract":{"output_mode":"json"},"name":"set-progress","path":"ui set-progress","runs":"remote"},{"about":"Double-tap an element (--rid/--text/--desc/--xpath/--id/--handle) or <x> <y> coordinates. An element is checked first: unique, enabled and not covered","args":[{"action":"Set","help":"X coordinate, for a coordinate double-tap","name":"x","positional":true,"takes_value":true,"value_names":["X"]},{"action":"Set","help":"Y coordinate, for a coordinate double-tap","name":"y","positional":true,"takes_value":true,"value_names":["Y"]},{"action":"Set","help":"Screen-bound handle from a fresh `ui dump` (i:.../e:...)","long":"handle","name":"handle","takes_value":true,"value_names":["HANDLE"]},{"action":"Set","help":"Element id from a fresh `ui dump`","long":"id","name":"id","takes_value":true,"value_names":["ID"]},{"action":"Set","help":"Match the element by visible text (normalized substring; --exact for full)","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Match the element by resource-id or Compose test tag (substring)","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Match the element by content-description (substring)","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"Set","help":"Match the element by xpath","long":"xpath","name":"xpath","takes_value":true,"value_names":["XPATH"]},{"action":"SetTrue","help":"Match selector values exactly instead of as a substring","long":"exact","name":"exact","possible_values":["true","false"],"value_names":["EXACT"]},{"action":"SetTrue","help":"Act even when the element is covered by the keyboard, a dialog, a system bar or an element drawn on top (refused with `element_occluded` otherwise)","long":"allow-occluded","name":"allow_occluded","possible_values":["true","false"],"value_names":["ALLOW_OCCLUDED"]},{"action":"Set","help":"Wait up to this long for the target to be on screen, unique, enabled and uncovered before acting, re-reading the screen until it is. Nothing is injected while waiting. Default: one attempt","long":"wait-ms","name":"wait_ms","takes_value":true,"value_names":["MS"]},{"action":"SetTrue","help":"Bring the target into view first: wait for the screen to settle, hide the keyboard when it hides or covers the target, then scroll the nearest list (down, then up) until the target shows. Needs --text, --rid or --desc","long":"reveal","name":"reveal","possible_values":["true","false"],"value_names":["REVEAL"]},{"action":"Set","help":"Require the target to be checked afterwards (`false`: unchecked), read back on a stable screen. Switches, checkboxes, and Compose chips and toggles. Needs --text, --rid or --desc","long":"expect-checked","name":"expect_checked","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"Require the target to be selected afterwards (`false`: not selected). Tabs and list items; Compose reports selectable chips as checked","long":"expect-selected","name":"expect_selected","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"Require the target to be enabled afterwards (`false`: disabled)","long":"expect-enabled","name":"expect_enabled","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"SetTrue","help":"In a session with --app: this step acts outside the app under test on purpose (share sheet, browser, settings), so skip the foreground guard","long":"allow-other-app","name":"allow_other_app","possible_values":["true","false"],"value_names":["ALLOW_OTHER_APP"]},{"action":"SetTrue","help":"In a session with --app: a crash or ANR of an app process during this step does not fail it","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"In a session with --app: when system UI (notification shade, heads-up) covers the app, collapse it and retry once instead of failing. Recorded as a flake signal","long":"dismiss-system-ui","name":"dismiss_system_ui","possible_values":["true","false"],"value_names":["DISMISS_SYSTEM_UI"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash (from your last `ui dump`/`ui wait`). On mismatch the command fails with code=screen_changed and the fresh compact screen in `detail` — use that instead of re-dumping","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash. Unlike --if-screen, volatile display content is ignored","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Include the post-action compact screen in this same response (saves the follow-up `ui dump` round-trip)","long":"observe","name":"observe","possible_values":["true","false"],"value_names":["OBSERVE"]},{"action":"Set","default_values":["500"],"help":"Required accessibility-event quiet period before the observed screen is considered stable, in milliseconds","long":"observe-delay-ms","name":"observe_delay_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["3000"],"help":"Overall deadline for stable observation and any --expect-* postcondition","long":"timeout-ms","name":"observe_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Require a stable destination containing this visible text","long":"expect-text","name":"expect_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Require a stable destination containing this content description","long":"expect-desc","name":"expect_desc","takes_value":true,"value_names":["DESCRIPTION"]},{"action":"Set","help":"Require a stable destination containing this resource id","long":"expect-rid","name":"expect_rid","takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"Set","help":"Require this foreground package after the action","long":"expect-package","name":"expect_package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Require this foreground activity after the action","long":"expect-activity","name":"expect_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"SetTrue","help":"Match the --expect-* value exactly (case-insensitive) instead of as a substring","long":"expect-exact","name":"expect_exact","possible_values":["true","false"],"value_names":["EXPECT_EXACT"]},{"action":"SetTrue","help":"With a satisfied --expect-* postcondition, return the whole post-action screen instead of its summary (hashes, foreground app, top texts)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["handle","id","text","rid","desc","xpath","exact","allow_occluded"],"multiple":true,"name":"GestureTargetArgs","required":false},{"args":["wait_ms","reveal","expect_checked","expect_selected","expect_enabled"],"multiple":true,"name":"TargetArgs","required":false},{"args":["allow_other_app","allow_crash","dismiss_system_ui"],"multiple":true,"name":"GuardArgs","required":false}],"contract":{"output_mode":"json"},"name":"double-tap","path":"ui double-tap","runs":"remote"},{"about":"Long-press an element (--rid/--text/--desc/--xpath/--id/--handle) or <x> <y> coordinates, holding for --duration-ms. An element is checked first: unique, enabled and not covered","args":[{"action":"Set","help":"X coordinate, for a coordinate long-press","name":"x","positional":true,"takes_value":true,"value_names":["X"]},{"action":"Set","help":"Y coordinate, for a coordinate long-press","name":"y","positional":true,"takes_value":true,"value_names":["Y"]},{"action":"Set","help":"Screen-bound handle from a fresh `ui dump` (i:.../e:...)","long":"handle","name":"handle","takes_value":true,"value_names":["HANDLE"]},{"action":"Set","help":"Element id from a fresh `ui dump`","long":"id","name":"id","takes_value":true,"value_names":["ID"]},{"action":"Set","help":"Match the element by visible text (normalized substring; --exact for full)","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Match the element by resource-id or Compose test tag (substring)","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Match the element by content-description (substring)","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"Set","help":"Match the element by xpath","long":"xpath","name":"xpath","takes_value":true,"value_names":["XPATH"]},{"action":"SetTrue","help":"Match selector values exactly instead of as a substring","long":"exact","name":"exact","possible_values":["true","false"],"value_names":["EXACT"]},{"action":"SetTrue","help":"Act even when the element is covered by the keyboard, a dialog, a system bar or an element drawn on top (refused with `element_occluded` otherwise)","long":"allow-occluded","name":"allow_occluded","possible_values":["true","false"],"value_names":["ALLOW_OCCLUDED"]},{"action":"Set","default_values":["600"],"help":"How long to hold the press, in milliseconds","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"Set","help":"Wait up to this long for the target to be on screen, unique, enabled and uncovered before acting, re-reading the screen until it is. Nothing is injected while waiting. Default: one attempt","long":"wait-ms","name":"wait_ms","takes_value":true,"value_names":["MS"]},{"action":"SetTrue","help":"Bring the target into view first: wait for the screen to settle, hide the keyboard when it hides or covers the target, then scroll the nearest list (down, then up) until the target shows. Needs --text, --rid or --desc","long":"reveal","name":"reveal","possible_values":["true","false"],"value_names":["REVEAL"]},{"action":"Set","help":"Require the target to be checked afterwards (`false`: unchecked), read back on a stable screen. Switches, checkboxes, and Compose chips and toggles. Needs --text, --rid or --desc","long":"expect-checked","name":"expect_checked","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"Require the target to be selected afterwards (`false`: not selected). Tabs and list items; Compose reports selectable chips as checked","long":"expect-selected","name":"expect_selected","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"Require the target to be enabled afterwards (`false`: disabled)","long":"expect-enabled","name":"expect_enabled","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"SetTrue","help":"In a session with --app: this step acts outside the app under test on purpose (share sheet, browser, settings), so skip the foreground guard","long":"allow-other-app","name":"allow_other_app","possible_values":["true","false"],"value_names":["ALLOW_OTHER_APP"]},{"action":"SetTrue","help":"In a session with --app: a crash or ANR of an app process during this step does not fail it","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"In a session with --app: when system UI (notification shade, heads-up) covers the app, collapse it and retry once instead of failing. Recorded as a flake signal","long":"dismiss-system-ui","name":"dismiss_system_ui","possible_values":["true","false"],"value_names":["DISMISS_SYSTEM_UI"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash (from your last `ui dump`/`ui wait`). On mismatch the command fails with code=screen_changed and the fresh compact screen in `detail` — use that instead of re-dumping","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash. Unlike --if-screen, volatile display content is ignored","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Include the post-action compact screen in this same response (saves the follow-up `ui dump` round-trip)","long":"observe","name":"observe","possible_values":["true","false"],"value_names":["OBSERVE"]},{"action":"Set","default_values":["500"],"help":"Required accessibility-event quiet period before the observed screen is considered stable, in milliseconds","long":"observe-delay-ms","name":"observe_delay_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["3000"],"help":"Overall deadline for stable observation and any --expect-* postcondition","long":"timeout-ms","name":"observe_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Require a stable destination containing this visible text","long":"expect-text","name":"expect_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Require a stable destination containing this content description","long":"expect-desc","name":"expect_desc","takes_value":true,"value_names":["DESCRIPTION"]},{"action":"Set","help":"Require a stable destination containing this resource id","long":"expect-rid","name":"expect_rid","takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"Set","help":"Require this foreground package after the action","long":"expect-package","name":"expect_package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Require this foreground activity after the action","long":"expect-activity","name":"expect_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"SetTrue","help":"Match the --expect-* value exactly (case-insensitive) instead of as a substring","long":"expect-exact","name":"expect_exact","possible_values":["true","false"],"value_names":["EXPECT_EXACT"]},{"action":"SetTrue","help":"With a satisfied --expect-* postcondition, return the whole post-action screen instead of its summary (hashes, foreground app, top texts)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["handle","id","text","rid","desc","xpath","exact","allow_occluded"],"multiple":true,"name":"GestureTargetArgs","required":false},{"args":["wait_ms","reveal","expect_checked","expect_selected","expect_enabled"],"multiple":true,"name":"TargetArgs","required":false},{"args":["allow_other_app","allow_crash","dismiss_system_ui"],"multiple":true,"name":"GuardArgs","required":false}],"contract":{"output_mode":"json"},"name":"long-tap","path":"ui long-tap","runs":"remote"},{"about":"Swipe from (x1,y1) to (x2,y2), or across an element (--rid/--text/--desc/--xpath/--id/--handle) in --direction: a carousel, a pager, a swipe-to-dismiss row","args":[{"action":"Set","help":"Start X, for a coordinate swipe","name":"x1","positional":true,"takes_value":true,"value_names":["X1"]},{"action":"Set","help":"Start Y, for a coordinate swipe","name":"y1","positional":true,"takes_value":true,"value_names":["Y1"]},{"action":"Set","help":"End X, for a coordinate swipe","name":"x2","positional":true,"takes_value":true,"value_names":["X2"]},{"action":"Set","help":"End Y, for a coordinate swipe","name":"y2","positional":true,"takes_value":true,"value_names":["Y2"]},{"action":"Set","help":"Screen-bound handle from a fresh `ui dump` (i:.../e:...)","long":"handle","name":"handle","takes_value":true,"value_names":["HANDLE"]},{"action":"Set","help":"Element id from a fresh `ui dump`","long":"id","name":"id","takes_value":true,"value_names":["ID"]},{"action":"Set","help":"Match the element by visible text (normalized substring; --exact for full)","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Match the element by resource-id or Compose test tag (substring)","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Match the element by content-description (substring)","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"Set","help":"Match the element by xpath","long":"xpath","name":"xpath","takes_value":true,"value_names":["XPATH"]},{"action":"SetTrue","help":"Match selector values exactly instead of as a substring","long":"exact","name":"exact","possible_values":["true","false"],"value_names":["EXACT"]},{"action":"SetTrue","help":"Act even when the element is covered by the keyboard, a dialog, a system bar or an element drawn on top (refused with `element_occluded` otherwise)","long":"allow-occluded","name":"allow_occluded","possible_values":["true","false"],"value_names":["ALLOW_OCCLUDED"]},{"action":"Set","help":"Finger direction of an element swipe: the finger moves up, down, left or right through the middle of the element","long":"direction","name":"direction","possible_values":["up","down","left","right"],"takes_value":true,"value_names":["DIRECTION"]},{"action":"Set","help":"Fraction of the element's height or width an element swipe travels, 0.1–0.95 (default 0.6)","long":"scale","name":"scale","takes_value":true,"value_names":["FRACTION"]},{"action":"Set","default_values":["200"],"help":"Swipe duration in milliseconds (longer = slower, more deliberate)","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"Set","help":"Wait up to this long for the target to be on screen, unique, enabled and uncovered before acting, re-reading the screen until it is. Nothing is injected while waiting. Default: one attempt","long":"wait-ms","name":"wait_ms","takes_value":true,"value_names":["MS"]},{"action":"SetTrue","help":"Bring the target into view first: wait for the screen to settle, hide the keyboard when it hides or covers the target, then scroll the nearest list (down, then up) until the target shows. Needs --text, --rid or --desc","long":"reveal","name":"reveal","possible_values":["true","false"],"value_names":["REVEAL"]},{"action":"Set","help":"Require the target to be checked afterwards (`false`: unchecked), read back on a stable screen. Switches, checkboxes, and Compose chips and toggles. Needs --text, --rid or --desc","long":"expect-checked","name":"expect_checked","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"Require the target to be selected afterwards (`false`: not selected). Tabs and list items; Compose reports selectable chips as checked","long":"expect-selected","name":"expect_selected","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"Require the target to be enabled afterwards (`false`: disabled)","long":"expect-enabled","name":"expect_enabled","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"SetTrue","help":"In a session with --app: this step acts outside the app under test on purpose (share sheet, browser, settings), so skip the foreground guard","long":"allow-other-app","name":"allow_other_app","possible_values":["true","false"],"value_names":["ALLOW_OTHER_APP"]},{"action":"SetTrue","help":"In a session with --app: a crash or ANR of an app process during this step does not fail it","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"In a session with --app: when system UI (notification shade, heads-up) covers the app, collapse it and retry once instead of failing. Recorded as a flake signal","long":"dismiss-system-ui","name":"dismiss_system_ui","possible_values":["true","false"],"value_names":["DISMISS_SYSTEM_UI"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash (from your last `ui dump`/`ui wait`). On mismatch the command fails with code=screen_changed and the fresh compact screen in `detail` — use that instead of re-dumping","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash. Unlike --if-screen, volatile display content is ignored","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Include the post-action compact screen in this same response (saves the follow-up `ui dump` round-trip)","long":"observe","name":"observe","possible_values":["true","false"],"value_names":["OBSERVE"]},{"action":"Set","default_values":["500"],"help":"Required accessibility-event quiet period before the observed screen is considered stable, in milliseconds","long":"observe-delay-ms","name":"observe_delay_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["3000"],"help":"Overall deadline for stable observation and any --expect-* postcondition","long":"timeout-ms","name":"observe_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Require a stable destination containing this visible text","long":"expect-text","name":"expect_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Require a stable destination containing this content description","long":"expect-desc","name":"expect_desc","takes_value":true,"value_names":["DESCRIPTION"]},{"action":"Set","help":"Require a stable destination containing this resource id","long":"expect-rid","name":"expect_rid","takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"Set","help":"Require this foreground package after the action","long":"expect-package","name":"expect_package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Require this foreground activity after the action","long":"expect-activity","name":"expect_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"SetTrue","help":"Match the --expect-* value exactly (case-insensitive) instead of as a substring","long":"expect-exact","name":"expect_exact","possible_values":["true","false"],"value_names":["EXPECT_EXACT"]},{"action":"SetTrue","help":"With a satisfied --expect-* postcondition, return the whole post-action screen instead of its summary (hashes, foreground app, top texts)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["handle","id","text","rid","desc","xpath","exact","allow_occluded"],"multiple":true,"name":"GestureTargetArgs","required":false},{"args":["wait_ms","reveal","expect_checked","expect_selected","expect_enabled"],"multiple":true,"name":"TargetArgs","required":false},{"args":["allow_other_app","allow_crash","dismiss_system_ui"],"multiple":true,"name":"GuardArgs","required":false}],"contract":{"output_mode":"json"},"name":"swipe","path":"ui swipe","runs":"remote"},{"about":"Drag from (x1,y1) to (x2,y2) — slower than swipe, for drag-and-drop / reorder","args":[{"action":"Set","name":"x1","positional":true,"required":true,"takes_value":true,"value_names":["X1"]},{"action":"Set","name":"y1","positional":true,"required":true,"takes_value":true,"value_names":["Y1"]},{"action":"Set","name":"x2","positional":true,"required":true,"takes_value":true,"value_names":["X2"]},{"action":"Set","name":"y2","positional":true,"required":true,"takes_value":true,"value_names":["Y2"]},{"action":"Set","default_values":["500"],"help":"Drag duration in milliseconds (longer = slower, for drag-and-drop)","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"In a session with --app: this step acts outside the app under test on purpose (share sheet, browser, settings), so skip the foreground guard","long":"allow-other-app","name":"allow_other_app","possible_values":["true","false"],"value_names":["ALLOW_OTHER_APP"]},{"action":"SetTrue","help":"In a session with --app: a crash or ANR of an app process during this step does not fail it","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"In a session with --app: when system UI (notification shade, heads-up) covers the app, collapse it and retry once instead of failing. Recorded as a flake signal","long":"dismiss-system-ui","name":"dismiss_system_ui","possible_values":["true","false"],"value_names":["DISMISS_SYSTEM_UI"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash (from your last `ui dump`/`ui wait`). On mismatch the command fails with code=screen_changed and the fresh compact screen in `detail` — use that instead of re-dumping","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash. Unlike --if-screen, volatile display content is ignored","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Include the post-action compact screen in this same response (saves the follow-up `ui dump` round-trip)","long":"observe","name":"observe","possible_values":["true","false"],"value_names":["OBSERVE"]},{"action":"Set","default_values":["500"],"help":"Required accessibility-event quiet period before the observed screen is considered stable, in milliseconds","long":"observe-delay-ms","name":"observe_delay_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["3000"],"help":"Overall deadline for stable observation and any --expect-* postcondition","long":"timeout-ms","name":"observe_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Require a stable destination containing this visible text","long":"expect-text","name":"expect_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Require a stable destination containing this content description","long":"expect-desc","name":"expect_desc","takes_value":true,"value_names":["DESCRIPTION"]},{"action":"Set","help":"Require a stable destination containing this resource id","long":"expect-rid","name":"expect_rid","takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"Set","help":"Require this foreground package after the action","long":"expect-package","name":"expect_package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Require this foreground activity after the action","long":"expect-activity","name":"expect_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"SetTrue","help":"Match the --expect-* value exactly (case-insensitive) instead of as a substring","long":"expect-exact","name":"expect_exact","possible_values":["true","false"],"value_names":["EXPECT_EXACT"]},{"action":"SetTrue","help":"With a satisfied --expect-* postcondition, return the whole post-action screen instead of its summary (hashes, foreground app, top texts)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["allow_other_app","allow_crash","dismiss_system_ui"],"multiple":true,"name":"GuardArgs","required":false}],"contract":{"output_mode":"json"},"name":"drag","path":"ui drag","runs":"remote"},{"about":"Swipe a fraction (--scale) of the screen in a direction (up/down/left/right)","args":[{"action":"Set","help":"Direction to swipe","name":"direction","positional":true,"possible_values":["up","down","left","right"],"required":true,"takes_value":true,"value_names":["DIRECTION"]},{"action":"Set","default_values":["0.9"],"help":"Fraction of the screen to travel, 0.0–1.0","long":"scale","name":"scale","takes_value":true,"value_names":["SCALE"]},{"action":"Set","default_values":["200"],"help":"Swipe duration in milliseconds","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"In a session with --app: this step acts outside the app under test on purpose (share sheet, browser, settings), so skip the foreground guard","long":"allow-other-app","name":"allow_other_app","possible_values":["true","false"],"value_names":["ALLOW_OTHER_APP"]},{"action":"SetTrue","help":"In a session with --app: a crash or ANR of an app process during this step does not fail it","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"In a session with --app: when system UI (notification shade, heads-up) covers the app, collapse it and retry once instead of failing. Recorded as a flake signal","long":"dismiss-system-ui","name":"dismiss_system_ui","possible_values":["true","false"],"value_names":["DISMISS_SYSTEM_UI"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash (from your last `ui dump`/`ui wait`). On mismatch the command fails with code=screen_changed and the fresh compact screen in `detail` — use that instead of re-dumping","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash. Unlike --if-screen, volatile display content is ignored","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Include the post-action compact screen in this same response (saves the follow-up `ui dump` round-trip)","long":"observe","name":"observe","possible_values":["true","false"],"value_names":["OBSERVE"]},{"action":"Set","default_values":["500"],"help":"Required accessibility-event quiet period before the observed screen is considered stable, in milliseconds","long":"observe-delay-ms","name":"observe_delay_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["3000"],"help":"Overall deadline for stable observation and any --expect-* postcondition","long":"timeout-ms","name":"observe_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Require a stable destination containing this visible text","long":"expect-text","name":"expect_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Require a stable destination containing this content description","long":"expect-desc","name":"expect_desc","takes_value":true,"value_names":["DESCRIPTION"]},{"action":"Set","help":"Require a stable destination containing this resource id","long":"expect-rid","name":"expect_rid","takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"Set","help":"Require this foreground package after the action","long":"expect-package","name":"expect_package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Require this foreground activity after the action","long":"expect-activity","name":"expect_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"SetTrue","help":"Match the --expect-* value exactly (case-insensitive) instead of as a substring","long":"expect-exact","name":"expect_exact","possible_values":["true","false"],"value_names":["EXPECT_EXACT"]},{"action":"SetTrue","help":"With a satisfied --expect-* postcondition, return the whole post-action screen instead of its summary (hashes, foreground app, top texts)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["allow_other_app","allow_crash","dismiss_system_ui"],"multiple":true,"name":"GuardArgs","required":false}],"contract":{"output_mode":"json"},"name":"swipe-ext","path":"ui swipe-ext","runs":"remote"},{"about":"Move one finger (or two, with `--fingers 2`) along timed points, for gestures `swipe`/`drag` can't make: curves, long-press-then-drag, pinch, rotate. Points are pixels: `x,y[,delay_ms]`, or `x1,y1,x2,y2[,delay_ms]` with two fingers; the delay comes before the point (default 16). The first point is touch-down, the last touch-up. Two fingers need an emulator","args":[{"action":"Append","allow_hyphen_values":true,"help":"The points, e.g. `500,1500 500,1200 500,800,100`","name":"points","num_args":"1..","positional":true,"required":true,"takes_value":true,"value_names":["POINTS"]},{"action":"Set","default_values":["1"],"help":"1 or 2","long":"fingers","name":"fingers","takes_value":true,"value_names":["FINGERS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["points","fingers"],"multiple":true,"name":"Path","required":false}],"contract":{"output_mode":"json"},"name":"path","path":"ui path","runs":"remote"},{"about":"Pinch in (zoom out) or out (zoom in) on the element matched by a selector","args":[{"action":"Set","help":"Pinch `in` (zoom out) or `out` (zoom in)","name":"direction","positional":true,"possible_values":["in","out"],"required":true,"takes_value":true,"value_names":["DIRECTION"]},{"action":"Set","help":"Match the target element by resource-id (substring)","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Match the target element by visible text (substring)","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Match the target element by content-description (substring)","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"Set","default_values":["50"],"help":"Pinch distance as a percent of the element's size (1–100)","long":"percent","name":"percent","takes_value":true,"value_names":["PERCENT"]},{"action":"SetTrue","help":"In a session with --app: this step acts outside the app under test on purpose (share sheet, browser, settings), so skip the foreground guard","long":"allow-other-app","name":"allow_other_app","possible_values":["true","false"],"value_names":["ALLOW_OTHER_APP"]},{"action":"SetTrue","help":"In a session with --app: a crash or ANR of an app process during this step does not fail it","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"In a session with --app: when system UI (notification shade, heads-up) covers the app, collapse it and retry once instead of failing. Recorded as a flake signal","long":"dismiss-system-ui","name":"dismiss_system_ui","possible_values":["true","false"],"value_names":["DISMISS_SYSTEM_UI"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash (from your last `ui dump`/`ui wait`). On mismatch the command fails with code=screen_changed and the fresh compact screen in `detail` — use that instead of re-dumping","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash. Unlike --if-screen, volatile display content is ignored","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Include the post-action compact screen in this same response (saves the follow-up `ui dump` round-trip)","long":"observe","name":"observe","possible_values":["true","false"],"value_names":["OBSERVE"]},{"action":"Set","default_values":["500"],"help":"Required accessibility-event quiet period before the observed screen is considered stable, in milliseconds","long":"observe-delay-ms","name":"observe_delay_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["3000"],"help":"Overall deadline for stable observation and any --expect-* postcondition","long":"timeout-ms","name":"observe_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Require a stable destination containing this visible text","long":"expect-text","name":"expect_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Require a stable destination containing this content description","long":"expect-desc","name":"expect_desc","takes_value":true,"value_names":["DESCRIPTION"]},{"action":"Set","help":"Require a stable destination containing this resource id","long":"expect-rid","name":"expect_rid","takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"Set","help":"Require this foreground package after the action","long":"expect-package","name":"expect_package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Require this foreground activity after the action","long":"expect-activity","name":"expect_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"SetTrue","help":"Match the --expect-* value exactly (case-insensitive) instead of as a substring","long":"expect-exact","name":"expect_exact","possible_values":["true","false"],"value_names":["EXPECT_EXACT"]},{"action":"SetTrue","help":"With a satisfied --expect-* postcondition, return the whole post-action screen instead of its summary (hashes, foreground app, top texts)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["allow_other_app","allow_crash","dismiss_system_ui"],"multiple":true,"name":"GuardArgs","required":false}],"contract":{"output_mode":"json"},"name":"pinch","path":"ui pinch","runs":"remote"},{"about":"Scroll a list until a selector is visible, then optionally tap it","args":[{"action":"Set","help":"Match text by case-insensitive substring. Single-target actions prefer a unique full-text match; multiple remaining matches are ambiguous","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Match by resource-id substring; actions prefer a unique exact match","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Match by content-description substring; actions prefer a unique exact match","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"Set","default_values":["down"],"help":"Content scroll direction: down (default) reveals items further down","long":"direction","name":"direction","possible_values":["up","down","left","right"],"takes_value":true,"value_names":["DIRECTION"]},{"action":"Set","default_values":["12"],"help":"Maximum number of swipes before giving up","long":"max-swipes","name":"max_swipes","takes_value":true,"value_names":["MAX_SWIPES"]},{"action":"Set","help":"Restrict swiping to the bounds of the scrollable with this resource-id","long":"container-rid","name":"container_rid","takes_value":true,"value_names":["CONTAINER_RID"]},{"action":"SetTrue","help":"Tap the element once found","long":"tap","name":"tap","possible_values":["true","false"],"value_names":["TAP"]},{"action":"SetTrue","help":"Require the selector field to match the complete value","long":"exact","name":"exact","possible_values":["true","false"],"value_names":["EXACT"]},{"action":"SetTrue","help":"With --tap, tap even when the found element is covered (by the keyboard, a dialog, a bottom bar drawn on top); refused otherwise","long":"allow-occluded","name":"allow_occluded","possible_values":["true","false"],"requires":["tap"],"value_names":["ALLOW_OCCLUDED"]},{"action":"Set","default_values":["250"],"help":"Swipe duration in milliseconds","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["text","rid","desc"],"multiple":true,"name":"SelectorArgs","required":false}],"contract":{"output_mode":"json"},"name":"scroll-to","path":"ui scroll-to","runs":"remote"},{"about":"Move D-pad focus to a selector (TV/leanback), then optionally activate it (--center)","args":[{"action":"Set","help":"Match text by case-insensitive substring. Single-target actions prefer a unique full-text match; multiple remaining matches are ambiguous","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Match by resource-id substring; actions prefer a unique exact match","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Match by content-description substring; actions prefer a unique exact match","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"SetTrue","help":"Press DPAD_CENTER once the target is focused (activate it)","long":"center","name":"center","possible_values":["true","false"],"value_names":["CENTER"]},{"action":"SetTrue","help":"Match the selector value exactly instead of as a case-insensitive substring. Use it to disambiguate when several elements match","long":"exact","name":"exact","possible_values":["true","false"],"value_names":["EXACT"]},{"action":"Set","default_values":["30"],"help":"Maximum D-pad presses before giving up","long":"max-steps","name":"max_steps","takes_value":true,"value_names":["MAX_STEPS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["text","rid","desc"],"multiple":true,"name":"SelectorArgs","required":false}],"contract":{"output_mode":"json"},"name":"focus","path":"ui focus","runs":"remote"},{"about":"Type into the focused field, or into an element matched by --id/--text/--rid/--desc/--xpath","aliases":["type"],"args":[{"action":"Set","help":"The text to type. Use --value-env instead for secrets","name":"value","positional":true,"takes_value":true,"value_names":["VALUE"]},{"action":"Set","conflicts_with":["value"],"help":"Type the value of this environment variable, never echoing it: output names the variable, and the value is scrubbed from anything printed. For passwords and tokens (`--value-env LOGIN_PASSWORD`)","long":"value-env","name":"value_env","takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"Clear the field's existing contents before typing","long":"clear","name":"clear","possible_values":["true","false"],"value_names":["CLEAR"]},{"action":"Set","help":"Screen-bound handle from a fresh `ui dump` (i:.../e:...)","long":"handle","name":"handle","takes_value":true,"value_names":["HANDLE"]},{"action":"Set","help":"Element id from a fresh `ui dump` to receive text","long":"id","name":"id","takes_value":true,"value_names":["ID"]},{"action":"Set","help":"Match a text-bearing/editable element to receive text","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Match by resource-id substring","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Match by content-description substring","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"Set","help":"Match by xpath","long":"xpath","name":"xpath","takes_value":true,"value_names":["XPATH"]},{"action":"SetTrue","help":"Use exact selector matching instead of substring matching","long":"exact","name":"exact","possible_values":["true","false"],"value_names":["EXACT"]},{"action":"Set","help":"Wait up to this long for the target to be on screen, unique, enabled and uncovered before acting, re-reading the screen until it is. Nothing is injected while waiting. Default: one attempt","long":"wait-ms","name":"wait_ms","takes_value":true,"value_names":["MS"]},{"action":"SetTrue","help":"Bring the target into view first: wait for the screen to settle, hide the keyboard when it hides or covers the target, then scroll the nearest list (down, then up) until the target shows. Needs --text, --rid or --desc","long":"reveal","name":"reveal","possible_values":["true","false"],"value_names":["REVEAL"]},{"action":"Set","help":"Require the target to be checked afterwards (`false`: unchecked), read back on a stable screen. Switches, checkboxes, and Compose chips and toggles. Needs --text, --rid or --desc","long":"expect-checked","name":"expect_checked","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"Require the target to be selected afterwards (`false`: not selected). Tabs and list items; Compose reports selectable chips as checked","long":"expect-selected","name":"expect_selected","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"Require the target to be enabled afterwards (`false`: disabled)","long":"expect-enabled","name":"expect_enabled","num_args":"0..=1","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"SetTrue","help":"In a session with --app: this step acts outside the app under test on purpose (share sheet, browser, settings), so skip the foreground guard","long":"allow-other-app","name":"allow_other_app","possible_values":["true","false"],"value_names":["ALLOW_OTHER_APP"]},{"action":"SetTrue","help":"In a session with --app: a crash or ANR of an app process during this step does not fail it","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"In a session with --app: when system UI (notification shade, heads-up) covers the app, collapse it and retry once instead of failing. Recorded as a flake signal","long":"dismiss-system-ui","name":"dismiss_system_ui","possible_values":["true","false"],"value_names":["DISMISS_SYSTEM_UI"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash (from your last `ui dump`/`ui wait`). On mismatch the command fails with code=screen_changed and the fresh compact screen in `detail` — use that instead of re-dumping","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash. Unlike --if-screen, volatile display content is ignored","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Include the post-action compact screen in this same response (saves the follow-up `ui dump` round-trip)","long":"observe","name":"observe","possible_values":["true","false"],"value_names":["OBSERVE"]},{"action":"Set","default_values":["500"],"help":"Required accessibility-event quiet period before the observed screen is considered stable, in milliseconds","long":"observe-delay-ms","name":"observe_delay_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["3000"],"help":"Overall deadline for stable observation and any --expect-* postcondition","long":"timeout-ms","name":"observe_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Require a stable destination containing this visible text","long":"expect-text","name":"expect_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Require a stable destination containing this content description","long":"expect-desc","name":"expect_desc","takes_value":true,"value_names":["DESCRIPTION"]},{"action":"Set","help":"Require a stable destination containing this resource id","long":"expect-rid","name":"expect_rid","takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"Set","help":"Require this foreground package after the action","long":"expect-package","name":"expect_package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Require this foreground activity after the action","long":"expect-activity","name":"expect_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"SetTrue","help":"Match the --expect-* value exactly (case-insensitive) instead of as a substring","long":"expect-exact","name":"expect_exact","possible_values":["true","false"],"value_names":["EXPECT_EXACT"]},{"action":"SetTrue","help":"With a satisfied --expect-* postcondition, return the whole post-action screen instead of its summary (hashes, foreground app, top texts)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["wait_ms","reveal","expect_checked","expect_selected","expect_enabled"],"multiple":true,"name":"TargetArgs","required":false},{"args":["allow_other_app","allow_crash","dismiss_system_ui"],"multiple":true,"name":"GuardArgs","required":false}],"contract":{"output_mode":"json"},"name":"text","path":"ui text","runs":"remote"},{"about":"Enter a numeric PIN through visible keypad buttons without echoing it in JSON output","args":[{"action":"Set","help":"Numeric PIN to enter. The value is never included in command output or diagnostics","name":"digits","positional":true,"required":true,"takes_value":true,"value_names":["DIGITS"]},{"action":"SetTrue","help":"Enter the digits without pressing Enter afterward","long":"no-submit","name":"no_submit","possible_values":["true","false"],"value_names":["NO_SUBMIT"]},{"action":"SetTrue","help":"Explicitly allow center-coordinate injection when a digit label has no clickable ancestor","long":"coordinate-fallback","name":"coordinate_fallback","possible_values":["true","false"],"value_names":["COORDINATE_FALLBACK"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["digits","no_submit","coordinate_fallback","if_screen","if_interaction"],"multiple":true,"name":"Pin","required":false}],"contract":{"output_mode":"json"},"name":"pin","path":"ui pin","runs":"remote"},{"about":"Press a named key or keycode","args":[{"action":"Set","name":"name","positional":true,"required":true,"takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"In a session with --app: this step acts outside the app under test on purpose (share sheet, browser, settings), so skip the foreground guard","long":"allow-other-app","name":"allow_other_app","possible_values":["true","false"],"value_names":["ALLOW_OTHER_APP"]},{"action":"SetTrue","help":"In a session with --app: a crash or ANR of an app process during this step does not fail it","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"In a session with --app: when system UI (notification shade, heads-up) covers the app, collapse it and retry once instead of failing. Recorded as a flake signal","long":"dismiss-system-ui","name":"dismiss_system_ui","possible_values":["true","false"],"value_names":["DISMISS_SYSTEM_UI"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash (from your last `ui dump`/`ui wait`). On mismatch the command fails with code=screen_changed and the fresh compact screen in `detail` — use that instead of re-dumping","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash. Unlike --if-screen, volatile display content is ignored","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Include the post-action compact screen in this same response (saves the follow-up `ui dump` round-trip)","long":"observe","name":"observe","possible_values":["true","false"],"value_names":["OBSERVE"]},{"action":"Set","default_values":["500"],"help":"Required accessibility-event quiet period before the observed screen is considered stable, in milliseconds","long":"observe-delay-ms","name":"observe_delay_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["3000"],"help":"Overall deadline for stable observation and any --expect-* postcondition","long":"timeout-ms","name":"observe_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Require a stable destination containing this visible text","long":"expect-text","name":"expect_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Require a stable destination containing this content description","long":"expect-desc","name":"expect_desc","takes_value":true,"value_names":["DESCRIPTION"]},{"action":"Set","help":"Require a stable destination containing this resource id","long":"expect-rid","name":"expect_rid","takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"Set","help":"Require this foreground package after the action","long":"expect-package","name":"expect_package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Require this foreground activity after the action","long":"expect-activity","name":"expect_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"SetTrue","help":"Match the --expect-* value exactly (case-insensitive) instead of as a substring","long":"expect-exact","name":"expect_exact","possible_values":["true","false"],"value_names":["EXPECT_EXACT"]},{"action":"SetTrue","help":"With a satisfied --expect-* postcondition, return the whole post-action screen instead of its summary (hashes, foreground app, top texts)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["allow_other_app","allow_crash","dismiss_system_ui"],"multiple":true,"name":"GuardArgs","required":false}],"contract":{"output_mode":"json"},"name":"key","path":"ui key","runs":"remote"},{"about":"Hide the soft keyboard if Olef sees it; no-op when already hidden","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"hide-keyboard","path":"ui hide-keyboard","runs":"remote"},{"about":"Press the Back button","args":[{"action":"SetTrue","help":"In a session with --app: this step acts outside the app under test on purpose (share sheet, browser, settings), so skip the foreground guard","long":"allow-other-app","name":"allow_other_app","possible_values":["true","false"],"value_names":["ALLOW_OTHER_APP"]},{"action":"SetTrue","help":"In a session with --app: a crash or ANR of an app process during this step does not fail it","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"In a session with --app: when system UI (notification shade, heads-up) covers the app, collapse it and retry once instead of failing. Recorded as a flake signal","long":"dismiss-system-ui","name":"dismiss_system_ui","possible_values":["true","false"],"value_names":["DISMISS_SYSTEM_UI"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash (from your last `ui dump`/`ui wait`). On mismatch the command fails with code=screen_changed and the fresh compact screen in `detail` — use that instead of re-dumping","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash. Unlike --if-screen, volatile display content is ignored","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Include the post-action compact screen in this same response (saves the follow-up `ui dump` round-trip)","long":"observe","name":"observe","possible_values":["true","false"],"value_names":["OBSERVE"]},{"action":"Set","default_values":["500"],"help":"Required accessibility-event quiet period before the observed screen is considered stable, in milliseconds","long":"observe-delay-ms","name":"observe_delay_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["3000"],"help":"Overall deadline for stable observation and any --expect-* postcondition","long":"timeout-ms","name":"observe_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Require a stable destination containing this visible text","long":"expect-text","name":"expect_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Require a stable destination containing this content description","long":"expect-desc","name":"expect_desc","takes_value":true,"value_names":["DESCRIPTION"]},{"action":"Set","help":"Require a stable destination containing this resource id","long":"expect-rid","name":"expect_rid","takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"Set","help":"Require this foreground package after the action","long":"expect-package","name":"expect_package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Require this foreground activity after the action","long":"expect-activity","name":"expect_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"SetTrue","help":"Match the --expect-* value exactly (case-insensitive) instead of as a substring","long":"expect-exact","name":"expect_exact","possible_values":["true","false"],"value_names":["EXPECT_EXACT"]},{"action":"SetTrue","help":"With a satisfied --expect-* postcondition, return the whole post-action screen instead of its summary (hashes, foreground app, top texts)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["allow_other_app","allow_crash","dismiss_system_ui"],"multiple":true,"name":"GuardArgs","required":false}],"contract":{"output_mode":"json"},"name":"back","path":"ui back","runs":"remote"},{"about":"Press the Home button","args":[{"action":"SetTrue","help":"In a session with --app: this step acts outside the app under test on purpose (share sheet, browser, settings), so skip the foreground guard","long":"allow-other-app","name":"allow_other_app","possible_values":["true","false"],"value_names":["ALLOW_OTHER_APP"]},{"action":"SetTrue","help":"In a session with --app: a crash or ANR of an app process during this step does not fail it","long":"allow-crash","name":"allow_crash","possible_values":["true","false"],"value_names":["ALLOW_CRASH"]},{"action":"SetTrue","help":"In a session with --app: when system UI (notification shade, heads-up) covers the app, collapse it and retry once instead of failing. Recorded as a flake signal","long":"dismiss-system-ui","name":"dismiss_system_ui","possible_values":["true","false"],"value_names":["DISMISS_SYSTEM_UI"]},{"action":"Set","help":"Only act if the screen still matches this screen_hash (from your last `ui dump`/`ui wait`). On mismatch the command fails with code=screen_changed and the fresh compact screen in `detail` — use that instead of re-dumping","long":"if-screen","name":"if_screen","takes_value":true,"value_names":["HASH"]},{"action":"Set","help":"Only act if the actionable structure still matches this interaction hash. Unlike --if-screen, volatile display content is ignored","long":"if-interaction","name":"if_interaction","takes_value":true,"value_names":["INTERACTION_HASH"]},{"action":"SetTrue","help":"Include the post-action compact screen in this same response (saves the follow-up `ui dump` round-trip)","long":"observe","name":"observe","possible_values":["true","false"],"value_names":["OBSERVE"]},{"action":"Set","default_values":["500"],"help":"Required accessibility-event quiet period before the observed screen is considered stable, in milliseconds","long":"observe-delay-ms","name":"observe_delay_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","default_values":["3000"],"help":"Overall deadline for stable observation and any --expect-* postcondition","long":"timeout-ms","name":"observe_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"Set","help":"Require a stable destination containing this visible text","long":"expect-text","name":"expect_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Require a stable destination containing this content description","long":"expect-desc","name":"expect_desc","takes_value":true,"value_names":["DESCRIPTION"]},{"action":"Set","help":"Require a stable destination containing this resource id","long":"expect-rid","name":"expect_rid","takes_value":true,"value_names":["RESOURCE_ID"]},{"action":"Set","help":"Require this foreground package after the action","long":"expect-package","name":"expect_package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","help":"Require this foreground activity after the action","long":"expect-activity","name":"expect_activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"SetTrue","help":"Match the --expect-* value exactly (case-insensitive) instead of as a substring","long":"expect-exact","name":"expect_exact","possible_values":["true","false"],"value_names":["EXPECT_EXACT"]},{"action":"SetTrue","help":"With a satisfied --expect-* postcondition, return the whole post-action screen instead of its summary (hashes, foreground app, top texts)","long":"full","name":"full","possible_values":["true","false"],"value_names":["FULL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["allow_other_app","allow_crash","dismiss_system_ui"],"multiple":true,"name":"GuardArgs","required":false}],"contract":{"output_mode":"json"},"name":"home","path":"ui home","runs":"remote"},{"about":"Wait for an element / activity / package to appear (or be --gone)","args":[{"action":"Set","help":"Wait for an element whose visible text matches (substring; --exact for full)","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Wait for an element whose resource-id matches (substring)","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Wait for an element whose content-description matches (substring)","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"Set","help":"Wait for an element whose class name matches (substring)","long":"klass","name":"klass","takes_value":true,"value_names":["KLASS"]},{"action":"Set","help":"Wait until the foreground activity name contains this (substring)","long":"activity","name":"activity","takes_value":true,"value_names":["ACTIVITY"]},{"action":"Set","aliases":["pkg"],"help":"Wait until the foreground app's package contains this (e.g. `chrome`)","long":"package","name":"package","takes_value":true,"value_names":["PACKAGE"]},{"action":"Set","aliases":["pkg-not"],"help":"Wait until the foreground app's package does NOT contain this — i.e. the screen left this app (a browser/dialer/share-sheet opened, or you navigated back out)","long":"package-not","name":"package_not","takes_value":true,"value_names":["PACKAGE_NOT"]},{"action":"SetTrue","help":"Match selector values (--text/--rid/--desc/--klass) exactly instead of as a case-insensitive substring","long":"exact","name":"exact","possible_values":["true","false"],"value_names":["EXACT"]},{"action":"SetTrue","help":"Invert: wait until the matched element is *gone* instead of present","long":"gone","name":"gone","possible_values":["true","false"],"value_names":["GONE"]},{"action":"Set","help":"With a selector: wait until the element is checked (`true`) or unchecked (`false`). A switch, checkbox, or Compose chip/toggle","long":"checked","name":"checked","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"With a selector: wait until the element is selected (`true`) or not","long":"selected","name":"selected","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","help":"With a selector: wait until the element is enabled (`true`) or disabled","long":"enabled","name":"enabled","possible_values":["true","false"],"takes_value":true,"value_names":["BOOL"]},{"action":"Set","allow_hyphen_values":true,"help":"With a selector: wait until the element's range value (a slider or progress bar) is N, within half a step","long":"value","name":"value","takes_value":true,"value_names":["N"]},{"action":"Set","help":"With a selector: wait until the element's own text contains this (normalized, case-insensitive). On timeout the error shows the text it had","long":"has-text","name":"has_text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","default_values":["10000"],"help":"Give up after this many milliseconds","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"Set","conflicts_with":["timeout_ms"],"help":"Give up after this long, with a unit: `30s`, `500ms`, `2m`","long":"timeout","name":"timeout","takes_value":true,"value_names":["DURATION"]},{"action":"Set","default_values":["200"],"help":"How often to re-check, in milliseconds","long":"poll-ms","name":"poll_ms","takes_value":true,"value_names":["POLL_MS"]},{"action":"SetTrue","help":"Wait until the screen stops changing: no accessibility events for --stable-ms, then the same tree (bounds included) one quiet period later. Alone it waits out animations and loading; with a selector it waits for the element, then for the screen around it to settle","long":"stable","name":"stable","possible_values":["true","false"],"value_names":["STABLE"]},{"action":"Set","default_values":["400"],"help":"Quiet period --stable requires, in milliseconds (50–2000)","long":"stable-ms","name":"stable_ms","takes_value":true,"value_names":["STABLE_MS"]},{"action":"SetTrue","help":"With --stable, also require the pixels to hold still, which catches canvas, Lottie and video motion the accessibility tree does not show","long":"pixels","name":"pixels","possible_values":["true","false"],"requires":["stable"],"value_names":["PIXELS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["text","rid","desc","klass","activity","package","package_not","exact","gone","checked","selected","enabled","value","has_text","timeout_ms","timeout","poll_ms","stable","stable_ms","pixels"],"multiple":true,"name":"Wait","required":false}],"contract":{"output_mode":"json"},"name":"wait","path":"ui wait","runs":"remote"},{"about":"Capture recent toast messages: those shown in the last 30 s (including one raised by your previous action), else the first shown within --wait-ms. Each reports `age_ms`","args":[{"action":"Set","default_values":["5000"],"help":"How long to wait for a toast when none was shown recently, in milliseconds","long":"wait-ms","name":"wait_ms","takes_value":true,"value_names":["WAIT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"toast","path":"ui toast","runs":"remote"}]},{"about":"Put the device or app into a failure condition on purpose — process death, no network, full storage, a moved clock, failing backend calls — and undo it reliably. Start with `fault kinds`","contract":{"output_mode":"json"},"name":"fault","path":"fault","runs":"remote","subcommands":[{"about":"List every fault kind: what it does, whether it is a one-off action or a state `fault clear` undoes, and what it needs. No device required","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"kinds","path":"fault kinds","runs":"remote"},{"about":"Inject a fault. A state fault stays until `fault clear` or `--duration-ms`; an action fault happens once. Replies with the fault record, including its id and how it will be undone","contract":{"output_mode":"json"},"name":"inject","path":"fault inject","runs":"remote","subcommands":[{"about":"Background the app and kill its process as Android does under memory pressure; its task stays in recents so reopening restores saved state","args":[{"action":"Set","aliases":["package"],"help":"App package. Defaults to the configured app","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"SetTrue","help":"Reopen the app afterwards like tapping its icon, then report the new pid","long":"relaunch","name":"relaunch","possible_values":["true","false"],"value_names":["RELAUNCH"]},{"action":"Set","default_values":["10000"],"help":"How long to wait for Android to let the backgrounded process be killed","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"process-death","path":"fault inject process-death","runs":"remote"},{"about":"Destroy activities as soon as the user leaves them","args":[{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"dont-keep-activities","path":"fault inject dont-keep-activities","runs":"remote"},{"about":"Deliver an onTrimMemory level to the app","args":[{"action":"Set","aliases":["package"],"help":"App package. Defaults to the configured app","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","default_values":["running-critical"],"help":"running-* levels need the app in the foreground; the others in the background","long":"level","name":"level","possible_values":["running-moderate","running-low","running-critical","ui-hidden","background","moderate","complete"],"takes_value":true,"value_names":["LEVEL"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"low-memory","path":"fault inject low-memory","runs":"remote"},{"about":"Revoke a granted runtime permission (Android kills the app)","args":[{"action":"Set","aliases":["package"],"help":"App package. Defaults to the configured app","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","help":"Permission name, e.g. android.permission.CAMERA","long":"permission","name":"permission","required":true,"takes_value":true,"value_names":["PERMISSION"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"revoke-permission","path":"fault inject revoke-permission","runs":"remote"},{"about":"Lock the screen rotation","args":[{"action":"Set","long":"rotation","name":"rotation","possible_values":["0","90","180","270"],"required":true,"takes_value":true,"value_names":["ROTATION"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"orientation","path":"fault inject orientation","runs":"remote"},{"about":"Switch the system dark theme","args":[{"action":"Set","default_values":["on"],"long":"mode","name":"mode","possible_values":["on","off"],"takes_value":true,"value_names":["MODE"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"night-mode","path":"fault inject night-mode","runs":"remote"},{"about":"Change the system font scale","args":[{"action":"Set","help":"Font scale, 0.5-3.0 (1.0 is the default size)","long":"scale","name":"scale","required":true,"takes_value":true,"value_names":["SCALE"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"font-scale","path":"fault inject font-scale","runs":"remote"},{"about":"Override the display size and/or density","args":[{"action":"Set","help":"Size as WIDTHxHEIGHT pixels, e.g. 1080x1200","long":"size","name":"size","takes_value":true,"value_names":["SIZE"]},{"action":"Set","help":"Density in dpi, e.g. 320","long":"density","name":"density","takes_value":true,"value_names":["DENSITY"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility","requires":["size"]}],"contract":{"output_mode":"json"},"name":"display-size","path":"fault inject display-size","runs":"remote"},{"about":"Set the app's own locale (per-app language)","args":[{"action":"Set","aliases":["package"],"help":"App package. Defaults to the configured app","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","help":"Language tags separated by commas, e.g. ar-EG or he,en-US","long":"locales","name":"locales","required":true,"takes_value":true,"value_names":["LOCALES"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"app-locale","path":"fault inject app-locale","runs":"remote"},{"about":"Shrink the app's task to part of the screen, as split screen does","args":[{"action":"Set","aliases":["package"],"help":"App package. Defaults to the configured app","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","default_values":["50"],"help":"Share of the screen height the app keeps, 20-80","long":"percent","name":"percent","takes_value":true,"value_names":["PERCENT"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"split-screen","path":"fault inject split-screen","runs":"remote"},{"about":"Leave the app (HOME) so it can enter picture-in-picture; reports whether it did","args":[{"action":"Set","aliases":["package"],"help":"App package. Defaults to the configured app","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"pip","path":"fault inject pip","runs":"remote"},{"about":"Force the device into deep Doze","args":[{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"doze","path":"fault inject doze","runs":"remote"},{"about":"Move the app to an App Standby bucket","args":[{"action":"Set","aliases":["package"],"help":"App package. Defaults to the configured app","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","long":"bucket","name":"bucket","possible_values":["active","working-set","frequent","rare","restricted"],"required":true,"takes_value":true,"value_names":["BUCKET"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"standby-bucket","path":"fault inject standby-bucket","runs":"remote"},{"about":"Report the battery as unplugged, optionally low and with Battery Saver","args":[{"action":"Set","help":"Battery level percent, 0-100 (default: keep the current level)","long":"level","name":"level","takes_value":true,"value_names":["LEVEL"]},{"action":"SetTrue","help":"Also turn Battery Saver on","long":"saver","name":"saver","possible_values":["true","false"],"value_names":["SAVER"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"battery","path":"fault inject battery","runs":"remote"},{"about":"Report a thermal (overheating) status","args":[{"action":"Set","long":"status","name":"status","possible_values":["light","moderate","severe","critical","emergency","shutdown"],"required":true,"takes_value":true,"value_names":["STATUS"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"thermal","path":"fault inject thermal","runs":"remote"},{"about":"Fill the data partition until only --free-mb remains","args":[{"action":"Set","default_values":["50"],"help":"Space left free, in MiB","long":"free-mb","name":"free_mb","takes_value":true,"value_names":["FREE_MB"]},{"action":"SetTrue","help":"Allow this on a physical device (other apps run out of space too)","long":"allow-physical","name":"allow_physical","possible_values":["true","false"],"value_names":["ALLOW_PHYSICAL"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"storage-full","path":"fault inject storage-full","runs":"remote"},{"about":"Move the system clock","args":[{"action":"Set","allow_hyphen_values":true,"help":"Milliseconds to move the clock; negative moves it back","long":"offset-ms","name":"offset_ms","required":true,"takes_value":true,"value_names":["OFFSET_MS"]},{"action":"SetTrue","help":"Allow this on a physical device (turns automatic time off until clear)","long":"allow-physical","name":"allow_physical","possible_values":["true","false"],"value_names":["ALLOW_PHYSICAL"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"clock","path":"fault inject clock","runs":"remote"},{"about":"Change the system time zone","args":[{"action":"Set","help":"Olson time zone id, e.g. Asia/Tokyo","long":"tz","name":"tz","required":true,"takes_value":true,"value_names":["TZ"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"timezone","path":"fault inject timezone","runs":"remote"},{"about":"Keep CPU cores busy","args":[{"action":"Set","help":"Busy loops to run (default: one per CPU core)","long":"threads","name":"threads","takes_value":true,"value_names":["THREADS"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"cpu-load","path":"fault inject cpu-load","runs":"remote"},{"about":"Turn airplane mode on","args":[{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"airplane-mode","path":"fault inject airplane-mode","runs":"remote"},{"about":"Turn Wi-Fi off","args":[{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"wifi-off","path":"fault inject wifi-off","runs":"remote"},{"about":"Turn mobile data off","args":[{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"mobile-data-off","path":"fault inject mobile-data-off","runs":"remote"},{"about":"Toggle airplane mode on and off repeatedly","args":[{"action":"Set","default_values":["5000"],"help":"Time spent in each state, in milliseconds","long":"period-ms","name":"period_ms","takes_value":true,"value_names":["PERIOD_MS"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"network-flap","path":"fault inject network-flap","runs":"remote"},{"about":"Make every DNS lookup fail","args":[{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"dns-failure","path":"fault inject dns-failure","runs":"remote"},{"about":"Throttle the emulator link to a cellular speed (emulator only)","args":[{"action":"Set","long":"profile","name":"profile","possible_values":["gsm","gprs","edge","umts","hsdpa","lte"],"required":true,"takes_value":true,"value_names":["PROFILE"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"network-speed","path":"fault inject network-speed","runs":"remote"},{"about":"Add cellular latency to the emulator link (emulator only)","args":[{"action":"Set","long":"profile","name":"profile","possible_values":["gprs","edge","umts"],"required":true,"takes_value":true,"value_names":["PROFILE"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"network-latency","path":"fault inject network-latency","runs":"remote"},{"about":"Answer matching proxied requests with an HTTP error (needs `net start`)","args":[{"action":"Set","help":"Only requests whose host contains this text","long":"host","name":"host","takes_value":true,"value_names":["HOST"]},{"action":"Set","help":"Only requests whose path contains this text","long":"path","name":"path","takes_value":true,"value_names":["PATH"]},{"action":"Set","default_values":["100"],"help":"Share of matching requests hit, 1-100","long":"percent","name":"percent","takes_value":true,"value_names":["PERCENT"]},{"action":"Set","default_values":["0"],"help":"Seed for which requests are hit when --percent is below 100: the same seed hits the same requests in the same order","long":"seed","name":"seed","takes_value":true,"value_names":["SEED"]},{"action":"Set","default_values":["503"],"help":"HTTP status to answer with","long":"status","name":"status","takes_value":true,"value_names":["STATUS"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["host","path","percent","seed"],"multiple":true,"name":"ProxyScope","required":false}],"contract":{"output_mode":"json"},"name":"http-errors","path":"fault inject http-errors","runs":"remote"},{"about":"Delay matching proxied requests (needs `net start`)","args":[{"action":"Set","help":"Only requests whose host contains this text","long":"host","name":"host","takes_value":true,"value_names":["HOST"]},{"action":"Set","help":"Only requests whose path contains this text","long":"path","name":"path","takes_value":true,"value_names":["PATH"]},{"action":"Set","default_values":["100"],"help":"Share of matching requests hit, 1-100","long":"percent","name":"percent","takes_value":true,"value_names":["PERCENT"]},{"action":"Set","default_values":["0"],"help":"Seed for which requests are hit when --percent is below 100: the same seed hits the same requests in the same order","long":"seed","name":"seed","takes_value":true,"value_names":["SEED"]},{"action":"Set","help":"Delay in milliseconds","long":"delay-ms","name":"delay_ms","required":true,"takes_value":true,"value_names":["DELAY_MS"]},{"action":"Set","default_values":["0"],"help":"Extra random delay up to this many milliseconds (seeded by --seed)","long":"jitter-ms","name":"jitter_ms","takes_value":true,"value_names":["JITTER_MS"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["host","path","percent","seed"],"multiple":true,"name":"ProxyScope","required":false}],"contract":{"output_mode":"json"},"name":"http-latency","path":"fault inject http-latency","runs":"remote"},{"about":"Stream matching proxied responses at a limited rate (needs `net start`)","args":[{"action":"Set","help":"Only requests whose host contains this text","long":"host","name":"host","takes_value":true,"value_names":["HOST"]},{"action":"Set","help":"Only requests whose path contains this text","long":"path","name":"path","takes_value":true,"value_names":["PATH"]},{"action":"Set","default_values":["100"],"help":"Share of matching requests hit, 1-100","long":"percent","name":"percent","takes_value":true,"value_names":["PERCENT"]},{"action":"Set","default_values":["0"],"help":"Seed for which requests are hit when --percent is below 100: the same seed hits the same requests in the same order","long":"seed","name":"seed","takes_value":true,"value_names":["SEED"]},{"action":"Set","help":"Bytes per second delivered to the app","long":"bytes-per-sec","name":"bytes_per_sec","required":true,"takes_value":true,"value_names":["BYTES_PER_SEC"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["host","path","percent","seed"],"multiple":true,"name":"ProxyScope","required":false}],"contract":{"output_mode":"json"},"name":"bandwidth","path":"fault inject bandwidth","runs":"remote"},{"about":"Break matching proxied responses partway through (needs `net start`)","args":[{"action":"Set","help":"Only requests whose host contains this text","long":"host","name":"host","takes_value":true,"value_names":["HOST"]},{"action":"Set","help":"Only requests whose path contains this text","long":"path","name":"path","takes_value":true,"value_names":["PATH"]},{"action":"Set","default_values":["100"],"help":"Share of matching requests hit, 1-100","long":"percent","name":"percent","takes_value":true,"value_names":["PERCENT"]},{"action":"Set","default_values":["0"],"help":"Seed for which requests are hit when --percent is below 100: the same seed hits the same requests in the same order","long":"seed","name":"seed","takes_value":true,"value_names":["SEED"]},{"action":"Set","default_values":["0"],"help":"Response body bytes delivered before the connection breaks","long":"after-bytes","name":"after_bytes","takes_value":true,"value_names":["AFTER_BYTES"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["host","path","percent","seed"],"multiple":true,"name":"ProxyScope","required":false}],"contract":{"output_mode":"json"},"name":"connection-reset","path":"fault inject connection-reset","runs":"remote"},{"about":"Deliver only the start of matching proxied response bodies as if complete (needs `net start`)","args":[{"action":"Set","help":"Only requests whose host contains this text","long":"host","name":"host","takes_value":true,"value_names":["HOST"]},{"action":"Set","help":"Only requests whose path contains this text","long":"path","name":"path","takes_value":true,"value_names":["PATH"]},{"action":"Set","default_values":["100"],"help":"Share of matching requests hit, 1-100","long":"percent","name":"percent","takes_value":true,"value_names":["PERCENT"]},{"action":"Set","default_values":["0"],"help":"Seed for which requests are hit when --percent is below 100: the same seed hits the same requests in the same order","long":"seed","name":"seed","takes_value":true,"value_names":["SEED"]},{"action":"Set","default_values":["16"],"help":"Response body bytes kept","long":"keep-bytes","name":"keep_bytes","takes_value":true,"value_names":["KEEP_BYTES"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["host","path","percent","seed"],"multiple":true,"name":"ProxyScope","required":false}],"contract":{"output_mode":"json"},"name":"truncated-response","path":"fault inject truncated-response","runs":"remote"},{"about":"Fail the TLS handshake for matching HTTPS hosts (needs `net start`)","args":[{"action":"Set","help":"Hosts containing this text fail their TLS handshake","long":"host","name":"host","required":true,"takes_value":true,"value_names":["HOST"]},{"action":"Set","default_values":["100"],"help":"Share of connections that fail, 1-100","long":"percent","name":"percent","takes_value":true,"value_names":["PERCENT"]},{"action":"Set","default_values":["0"],"help":"Seed for which connections fail when --percent is below 100","long":"seed","name":"seed","takes_value":true,"value_names":["SEED"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"tls-failure","path":"fault inject tls-failure","runs":"remote"},{"about":"Ring an incoming phone call (emulator only)","args":[{"action":"Set","default_values":["5551234"],"help":"Caller number","long":"number","name":"number","takes_value":true,"value_names":["NUMBER"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"incoming-call","path":"fault inject incoming-call","runs":"remote"},{"about":"Deliver an incoming SMS (emulator only)","args":[{"action":"Set","default_values":["5551234"],"help":"Sender number","long":"from","name":"from","takes_value":true,"value_names":["FROM"]},{"action":"Set","help":"Message text","long":"text","name":"text","required":true,"takes_value":true,"value_names":["TEXT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["from","text"],"multiple":true,"name":"Sms","required":false}],"contract":{"output_mode":"json"},"name":"sms","path":"fault inject sms","runs":"remote"},{"about":"Turn the screen off","args":[{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"screen-off","path":"fault inject screen-off","runs":"remote"},{"about":"Pull the notification shade or quick settings down over the app","args":[{"action":"Set","default_values":["notifications"],"long":"panel","name":"panel","possible_values":["notifications","quick-settings"],"takes_value":true,"value_names":["PANEL"]},{"action":"Set","help":"Clear the fault automatically after this many milliseconds. Without it the fault stays until `fault clear`","long":"duration-ms","name":"duration_ms","takes_value":true,"value_names":["DURATION_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"notification-shade","path":"fault inject notification-shade","runs":"remote"},{"about":"Crash the emulator (emulator only)","args":[{"action":"SetTrue","help":"Boot the emulator again afterwards","long":"relaunch","name":"relaunch","possible_values":["true","false"],"value_names":["RELAUNCH"]},{"action":"SetTrue","help":"With --relaunch, cold boot instead of loading the quick-boot snapshot","long":"cold-boot","name":"cold_boot","possible_values":["true","false"],"requires":["relaunch"],"value_names":["COLD_BOOT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["relaunch","cold_boot"],"multiple":true,"name":"EmulatorCrash","required":false}],"contract":{"output_mode":"json"},"name":"emulator-crash","path":"fault inject emulator-crash","runs":"remote"}]},{"about":"List the faults active on the device, oldest first","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"list","path":"fault list","runs":"remote"},{"about":"Undo faults and verify each restore. Newest first with --all","args":[{"action":"Append","help":"Fault ids from `fault inject` or `fault list`","name":"ids","num_args":"1..","positional":true,"takes_value":true,"value_names":["IDS"]},{"action":"SetTrue","help":"Clear every fault active on the device","long":"all","name":"all","possible_values":["true","false"],"value_names":["ALL"]},{"action":"SetTrue","help":"Set by the --duration-ms timer: an id that is already gone is not an error","long":"expired","name":"expired","possible_values":["true","false"],"requires":["all"],"value_names":["EXPIRED"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility","requires":["all"]}],"argument_groups":[{"args":["ids","all","expired"],"multiple":true,"name":"ClearArgs","required":false},{"args":["ids","all"],"multiple":false,"name":"which","required":true}],"contract":{"output_mode":"json"},"name":"clear","path":"fault clear","runs":"remote"},{"about":"Emulator snapshots: save a known state before a fault run, load it back after","contract":{"output_mode":"json"},"name":"snapshot","path":"fault snapshot","runs":"remote","subcommands":[{"about":"Save the emulator's current state under a name","args":[{"action":"Set","name":"name","positional":true,"required":true,"takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"save","path":"fault snapshot save","runs":"remote"},{"about":"Load a saved state (the app and Olef server restart with it)","args":[{"action":"Set","name":"name","positional":true,"required":true,"takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"load","path":"fault snapshot load","runs":"remote"},{"about":"List saved snapshots","args":[{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"list","path":"fault snapshot list","runs":"remote"},{"about":"Delete a saved snapshot","args":[{"action":"Set","name":"name","positional":true,"required":true,"takes_value":true,"value_names":["NAME"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"contract":{"output_mode":"json"},"name":"delete","path":"fault snapshot delete","runs":"remote"}]},{"about":"Run a JSON scenario: a sequence of Olef commands, faults, waits and checks. Every fault it injected is cleared at the end, pass or fail","args":[{"action":"Set","dir":"in","help":"Scenario JSON file (see `commands --guide faults`)","name":"file","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["FILE"]},{"action":"Set","help":"Seed for `pick` steps and proxy faults without their own --seed; the same seed replays the same choices. Overrides the file's `seed`","long":"seed","name":"seed","takes_value":true,"value_names":["SEED"]},{"action":"Set","default_values":["600000"],"help":"Stop a step that runs longer than this; the step fails and the scenario's faults are still cleared","long":"step-timeout-ms","name":"step_timeout_ms","takes_value":true,"value_names":["MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["file","seed","step_timeout_ms"],"multiple":true,"name":"RunArgs","required":false}],"contract":{"output_mode":"json"},"name":"run","path":"fault run","runs":"remote"}]},{"about":"Agent-first layout snapshots and diffs","contract":{"output_mode":"json"},"name":"layout","path":"layout","runs":"remote","subcommands":[{"about":"Capture a layout snapshot from the current UI tree","args":[{"action":"Set","dir":"out","help":"Write JSON to a file instead of stdout","long":"out","name":"out","short":"o","takes_value":true,"value_hint":"AnyPath","value_names":["OUT"]},{"action":"SetTrue","help":"Add Compose nodes (runtime Compose inspector)","long":"compose","name":"compose","possible_values":["true","false"],"value_names":["COMPOSE"]},{"action":"SetTrue","help":"Add Compose semantics and text (slower: reads every parameter)","long":"semantics","name":"semantics","possible_values":["true","false"],"value_names":["SEMANTICS"]},{"action":"SetTrue","help":"Map nodes and elements to project source files","long":"source-map","name":"source_map","possible_values":["true","false"],"value_names":["SOURCE_MAP"]},{"action":"SetTrue","help":"Include a screenshot artifact next to the snapshot","long":"screenshot","name":"screenshot","possible_values":["true","false"],"value_names":["SCREENSHOT"]},{"action":"Set","aliases":["package"],"help":"App package to inspect instead of the foreground app","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","help":"Process id to inspect instead of the foreground app's","long":"pid","name":"pid","takes_value":true,"value_names":["PID"]},{"action":"Set","default_values":["8000"],"help":"Budget for Compose parameters and semantics, in milliseconds","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","pid","timeout_ms"],"multiple":true,"name":"LayoutTargetArgs","required":false}],"contract":{"output_mode":"json"},"name":"snapshot","path":"layout snapshot","runs":"remote"},{"about":"Diff two layout snapshot JSON files","args":[{"action":"Set","dir":"in","name":"before","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["BEFORE"]},{"action":"Set","dir":"in","name":"after","positional":true,"required":true,"takes_value":true,"value_hint":"AnyPath","value_names":["AFTER"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["before","after"],"multiple":true,"name":"LayoutDiffArgs","required":false}],"contract":{"output_mode":"json"},"name":"diff","path":"layout diff","runs":"remote"},{"about":"Compose recomposition counters from the runtime's Compose inspector","args":[{"action":"SetTrue","help":"Reset the counters after reading them","long":"reset","name":"reset","possible_values":["true","false"],"value_names":["RESET"]},{"action":"Set","aliases":["package"],"help":"App package to inspect instead of the foreground app","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","help":"Process id to inspect instead of the foreground app's","long":"pid","name":"pid","takes_value":true,"value_names":["PID"]},{"action":"Set","default_values":["8000"],"help":"Budget for Compose parameters and semantics, in milliseconds","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"Set","default_values":["0"],"help":"Only return nodes recomposed at least this many times (the full tree of a real screen is hundreds of nodes; `--min-count 1` keeps what changed)","long":"min-count","name":"min_count","takes_value":true,"value_names":["MIN_COUNT"]},{"action":"Set","help":"Return at most this many nodes, most recomposed first","long":"limit","name":"limit","takes_value":true,"value_names":["LIMIT"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["app","pid","timeout_ms"],"multiple":true,"name":"LayoutTargetArgs","required":false}],"contract":{"output_mode":"json"},"name":"recompositions","path":"layout recompositions","runs":"remote"},{"about":"Resolve a current UI node and map it to source when source mapping is available","args":[{"action":"Set","help":"Element id from `screen` or `layout snapshot`","long":"id","name":"id","takes_value":true,"value_names":["ID"]},{"action":"Set","help":"Layout node draw id from `layout snapshot`","long":"draw-id","name":"draw_id","takes_value":true,"value_names":["DRAW_ID"]},{"action":"Set","help":"Match text by case-insensitive substring. Single-target actions prefer a unique full-text match; multiple remaining matches are ambiguous","long":"text","name":"text","takes_value":true,"value_names":["TEXT"]},{"action":"Set","help":"Match by resource-id substring; actions prefer a unique exact match","long":"rid","name":"rid","takes_value":true,"value_names":["RID"]},{"action":"Set","help":"Match by content-description substring; actions prefer a unique exact match","long":"desc","name":"desc","takes_value":true,"value_names":["DESC"]},{"action":"Set","aliases":["package"],"help":"App package to inspect instead of the foreground app","long":"app","name":"app","takes_value":true,"value_names":["APP"]},{"action":"Set","help":"Process id to inspect instead of the foreground app's","long":"pid","name":"pid","takes_value":true,"value_names":["PID"]},{"action":"Set","default_values":["8000"],"help":"Budget for Compose parameters and semantics, in milliseconds","long":"timeout-ms","name":"timeout_ms","takes_value":true,"value_names":["TIMEOUT_MS"]},{"action":"SetTrue","help":"Accepted for compatibility; output is always JSON.","long":"json","name":"json_compatibility"}],"argument_groups":[{"args":["text","rid","desc"],"multiple":true,"name":"SelectorArgs","required":false},{"args":["app","pid","timeout_ms"],"multiple":true,"name":"LayoutTargetArgs","required":false}],"contract":{"output_mode":"json"},"name":"source","path":"layout source","runs":"remote"}]}],"name":"olef","next_actions":["olef commands --json --depth 1","olef commands --json --describe 'ui tap'","olef commands --guide net --json","olef config schema --json"],"projection":{"cli_version":"3.0.2","contract_defaults":{"hints":"every JSON error contains a hints array of prose advice (what to change); read it instead of msg, whose repeated advice goes away next release","next_actions":"every terminal JSON success/error contains a non-empty next_actions array; streaming events omit it until their terminal summary","success_condition":"process exit code 0; action envelopes also contain ok=true"},"effect_contract":"listed commands omit it and contract_defaults; `olef commands <path> --json` or --full shows both","name":"lean","omitted_argument_values":[false,null,[],"Unknown"],"schema_version":4,"shared_metadata":"olef commands --json --depth 0","version":1},"schema_version":4,"version":"3.0.2"}