Skip to content

Commands

vk help prints this same list from the CLI itself. Aliases are noted where they exist.

Not every command works everywhere — Platform support is the matrix of what runs on Android and iOS, on physical hardware and on an emulator or simulator. The flags shared across commands — --device, --json, --server — are under Global flags at the end.

The semantic hierarchy is the core feature. These commands never change the screen and never scroll.

Command Description
ui [--all] [--tree] [--json]
alias: dump
Compact list of interactive/labeled elements. --all keeps layout nodes; --tree indents by nesting; --json is structured.
find <selector> [--json] [--wait <dur>|--no-wait] Print elements matching a selector. Auto-waits up to 5s; exit 1 if still none.
assert <selector> [--text S] [--gone] [--contains] [--wait <dur>|--no-wait] Assertion for tests. Auto-waits until it passes. Exit 0 pass / 1 fail.
wait <selector> [--timeout ms] [--interval ms] [--gone] Poll the hierarchy until match (or absence). Exit 1 on timeout. Explicit polling — distinct from the --wait flag.
current Best-effort foreground app/activity. Returns (unknown) on iOS.
log [package] [-n lines] [--since t] [--out path] [--full] [--json]
alias: logs
Recent device logs (Android logcat snapshot; simulator-only on iOS). See below.

Prints to stdout; --out saves to a file, --json is structured.

Inside a run it defaults to logs since the run started, so pre-session logs are excluded. -n caps to the last N lines instead, --since <MM-DD HH:MM:SS.mmm> sets an explicit start, and --full dumps everything. Precedence: --since > -n > --full > session window > last-N.

A package scopes logs to that app’s process, falling back to system-wide when the app is not running (for example because it crashed) so the crash trace is still captured.

Unlike other inspection commands it is recorded, so its output lands in the archived report.

Command Description
tap <selector|index> / tap --at x,y
alias: click
Tap an element (or raw coordinates). Selector taps auto-wait and auto-scroll; a bare integer taps [index] from the latest ui and never waits.
text <selector> <text…> [--clear] [--enter] Focus a field and type. --clear deletes existing text first. The field lookup auto-waits. Punctuation and symbols are escaped for the device shell and type verbatim — quote the value in your shell.
type <text…> [--enter] Type into the currently focused field.
key <name|code> / back / home / enter Send a key event, by name or as a raw Android keycode. Names: enter, back, home, tab, space, del/delete/backspace, forward_del, escape/esc, menu, search, up/down/left/right/center (also dpad_*), power, sleep, wakeup, app_switch/recents, volume_up, volume_down, mute, move_home, move_end, page_up, page_down. power is a toggle — use sleep/wakeup when you mean a direction. iOS accepts a different set; see Platform support.
swipe <up|down|left|right> [--on <selector>] [--distance f] [--duration ms]
alias: scroll
Directional swipe over the screen, or within an element via --on (whose lookup auto-waits). --distance is a fraction of the region, default 0.6.
swipe --from x,y --to x,y [--duration ms] Explicit swipe between two points.
screenshot [--out path] [--more] [--max px] [--full] [--json]
alias: shot
Save a PNG (default ./.verikun/screen.png) and print the path. Downscaled to a 700px longest edge by default.
launch <app> [--clear] [--no-restart]
alias: open
Start an app by package id (Android) or bundle id (iOS). Restarts by default — see below.
stop <app> Force-stop the app.
clear <app> Wipe the app’s locally stored data — login/session, preferences, caches — resetting it to just-installed state (Android pm clear, which also force-stops). iOS unsupported: there is no per-app data reset.
install <app.apk|.ipa> [--server url] Install a build (adb install -r -d / idb install). With --server, the file is uploaded to a remote vk server started with --allow-install (single-file .apk/.ipa, sha256-verified). Android: if the device holds a build of the same package signed by a different key, that build is removed and the install retried — its app data is lost, and a note says so on stderr. -d allows a build with a lower version code than what’s already on the device to install by default, when the build is debuggable — a release-signed downgrade still fails. Same-key installs (including a downgrade) keep their data as before. On a pooled server the build goes to every device; any that cannot take it are dropped from the pool and listed as skipped, still exit 0. Only a build that fails on every device is an error.

Re-issuing a launch intent to an app that is already running only resurfaces its current, often mid-flow, screen, so launch force-stops the app first and you start from a cold screen every time.

  • --no-restart opts out and brings the existing instance forward.
  • --clear instead wipes data via pm clear, which already force-stops.

Change the device the app runs on, then put it back. Full detail: Device state.

Command Description
device set <key>=<value> … Apply settings, snapshotting each original first. Keys: animations, airplane, dark, font-scale, rotation, stay-awake, screen-timeout, dnd, doze. Every change is verified by reading it back. Refuses airplane=on over wireless adb; --allow-wireless overrides.
device get [key] [--json]
alias: device status
Current values; n/a where the platform cannot answer.
device reset [key …] Restore what this run changed. batch, ai and suite also do this automatically when the flow ends or fails.
device prep [--dry-run] [--json]
device prep --revert
Prepare a test device once: animations=off, stay-awake=off, screen-timeout=1m, dnd=on, doze=off. Unlike device set this is sticky — it survives the run and is undone only by --revert. A physical device must be named with --device, so prep can never land on a personal phone. --no-sleep-when-idle selects the other display policy — stay-awake=on, screen-timeout=max, so it never turns off. See Device state.
device caps [--json] What the active platform supports, and the manual equivalent where it does not.
device release [serial] [--json] Hand a claimed device back to the pool. Claims expire on their own; this is for when you do not want to wait. Releases another job’s claim too. See Device claims.
Command Description
batch [--file <path>] [--quiet] Run newline-separated commands — from --file, else piped stdin — each exactly as its own command (same auto-wait, recording, exit codes). Streams each result to stdout and stops on the first non-zero exit, propagating that code. Blank lines and # comments are skipped; --quiet hides per-line progress. See Writing test cases.
Command Description
ai <file> [--model m] [--max-cost-usd n] [--timeout dur] [--cost-override in/out] [--effort e] [--package pkg] [--app-build id] [--reset-app id] [--server url] [--show-plan] [--recompile] [--json] Run a plain-English test: compile to a deterministic plan once, replay model-free, self-heal failures via the model. @include <path> on its own line splices in another file’s prose (relative to the including file). Needs ANTHROPIC_API_KEY or OPENAI_API_KEY per model, or no key with --model codex-cli / cursor-cli. See Natural-language tests.
suite <dir> [--app <id>] [--name n] [--retries n] [--server url] [--json]
[--devices a,b] [--servers u1,u2] [--concurrency n] [--max-suite-cost-usd n]
(+ all ai flags)
Run every *.md in <dir> as one suite with an overview report and a non-zero exit on failure — the CI gate. README.md and _-prefixed @include fragments are not tests and are skipped. --devices/--servers spread the tests across a pool (next free device takes the next test), and a plain --server sizes itself from a pooled server’s capacity. See Suites.
Flag Default Effect
--model <m> claude-sonnet-4-6 Model and provider — see Models
--max-cost-usd <n> 3 Abort if the cost estimate crosses this — per test, see Cost & budget
--timeout <dur> 15m Abort on wall clock
--cost-override <in/out> — Override the bundled per-1M price table if it drifts
--effort <e> — Reasoning effort, where the provider supports it. Bills through the output rate.
--package <pkg> inferred App id, used as part of the plan-cache key
--app-build <id> — Build identity; a change invalidates the cached plan
--server <url> VERIKUN_SERVER Run device I/O against a remote vk server
--reset-app <id> — Clear (iOS: force-stop) that app before the first step, on this run’s own device
--show-plan — Print the compiled IR and exit without running
--recompile (alias --no-cache) — Ignore the cache
Flag Default Effect
--app <id> — Reset this app’s data between tests (iOS: force-stop)
--retries <n> 0 Re-run a failed test up to N times; a later pass recovers the suite with a warning
--devices <a,b|all|all-android|all-ios> — Run across these local devices, next free device takes the next test. Same spelling as vk server --devices; cannot be combined with --server
--servers <u1,u2> — Same, across several vk server hosts — one lane per device each of them serves. A plain --server at a pooled server needs neither
--concurrency <n> pool size Cap how many devices run at once
--max-suite-cost-usd <n> — Stop the suite once total model spend crosses this (exit 1). Off by default; the per-test --max-cost-usd still applies
--name <n> directory name Suite name in the manifest and the overview page
Command Description
server [--bind addr] [--port n] [--auth-key k] [--devices all|all-android|all-ios|a,b] [--allow-install] [--allow-device-control[=names]] [--allow-failover[=serials]|--no-failover] [--allow-unsafe-anonymous] [--log-file path|off] Expose this machine’s connected device(s) to remote verikun clients (ai / suite / install --server). Auth is mandatory unless explicitly disabled; only verikun’s validated command grammar is executable. --devices serves a whole pool from one address, leasing one device per run; a device that fails but is still attached is demoted (dealt last) rather than dropped, one that has gone leaves the pool, and one that comes back is re-adopted. Logs to ~/.verikun/logs/server-<port>.log unless --log-file off. Binds 127.0.0.1:8391 by default. See Remote devices & CI.

Clients pass --server <url> (or VERIKUN_SERVER) plus --auth-key (or VERIKUN_SERVER_AUTH_KEY) to ai, suite and install. The server’s device and platform apply — no flag on an exec request can repoint them. With --allow-device-control a client may restart/stop the server’s own device, and with --allow-device-control=<names> also start one of those targets; the device lifecycle commands below all accept --server <url>. The server may also move itself off a device that fails — see When the bound device fails.

Flag Effect
(none) Failover is on when the server auto-selected its device, and off when --device (or VERIKUN_DEVICE / ANDROID_SERIAL) pinned it.
--allow-failover Turn it on even for a pinned server; it may move to any attached, running, unclaimed device.
--allow-failover=<a,b> As above, but bounded to those serials or AVD/simulator names.
--no-failover Off outright. Same as VERIKUN_NO_FAILOVER=1, which wins over every flag.
Command Description
devices [--all] [--json] List attached devices and simulators. Probes both backends. A USED BY column appears when another job holds one — see Device claims. --all also lists startable (not-yet-booted) AVDs and simulators.
devices start <name> [--wipe] [--timeout dur] [--no-wait] Boot an Android AVD or iOS simulator, waiting until it is genuinely drivable; prints the resolved serial on stdout. Already running = a no-op.
devices stop <name|serial> Shut a running emulator or simulator down.
devices restart <name> [--wipe] Stop then boot — the fix for a wedged or flaky device.
doctor [--fix] Diagnose adb + device, and report the CLI/plugin versions plus whether the device has been prepared and whether it has a screen lock. Read-only without --fix; --fix is an alias for device prep and inherits its gate, so on a physical device it refuses unless the serial was named. --ios checks the idb toolchain. Version staleness and a screen lock are reported as warnings and do not affect the exit code — only a genuinely unusable setup gives 3.
companion <status|stop> [--json] Inspect or stop the on-device hierarchy reader (Android only). stop hands back the device’s single UiAutomation connection so Appium or Layout Inspector can use it. See Companion.

vk devices stop powers a device off; vk stop <appId> force-stops an app, and vk device set (singular) changes settings on the device you are driving.

Physical devices are never power-cycled — start/stop/restart refuse them with exit 2. An ambiguous name (simulator names repeat across iOS runtimes) is exit 2 with the candidates listed; pass the UDID instead. A boot that times out is exit 1 (retryable — the device is left running); a missing toolchain is exit 3. Set VERIKUN_EMULATOR if the SDK’s emulator binary is not on PATH or under $ANDROID_HOME.

--wipe (emulator -wipe-data / simctl erase) is the only destructive path: start and restart only, never a physical device, and never against an already-running target — use restart --wipe.

Actions are recorded automatically; a run auto-starts on the first action. Full detail: Reports & test runs.

Command Description
run start [name] [--force] Begin a named run. One auto-starts on the first action if you do not. Refuses to clobber a non-empty active run without --force.
run status Show the active run, its device and session, and its recorded steps. This is the default when run is given no subcommand.
run archive [name] [--no-logs]
aliases: finish, save
Write JUnit + HTML report to ./.verikun/runs/<id>/. Exits non-zero if any step failed. Captures artifacts/logcat.txt by default.
run clear
aliases: stop, discard
Discard the active run without a report.
Command Description
help / --help Print usage. Exit 0.
version / --version Print the version. Exit 0.

An unrecognised command exits 2.

Every command accepts these; the environment-variable forms are listed in Environment variables.

Flag Meaning
-d, --device <serial> Target a specific device. Resolution order: --device, then VERIKUN_DEVICE, then ANDROID_SERIAL (Android only). With none set, verikun picks a device no other job is driving and says which on stderr; naming a device another job holds, or every device being claimed, is exit 2 — see Device claims. VERIKUN_NO_CLAIM=1 turns claims off: one attached device auto-resolves, more than one exits 2.
-p, --platform <android|ios> Platform, default android. --ios / --android are shortcuts.
-j, --json Machine-readable output — also serializes errors as {error, exitCode, errorKind} with the exit code unchanged, so one parser handles both outcomes. errorKind is the error’s class (SelectorNotFoundError, AmbiguousSelectorError, NoWindowError, CliError, Error), so a caller can tell “the app has not drawn yet” from “the device is gone” although both are exit 3.
--server <url> For ai / suite / install: run against a remote vk server (or VERIKUN_SERVER). The server’s device and platform apply.
--auth-key <k> Key for --server (or VERIKUN_SERVER_AUTH_KEY, which keeps it out of ps).
-- End flag parsing, so text may start with -: vk type -- "-50% off".

Globals passed to a batch call carry into every line unless a line overrides them — --device, --platform / --ios / --android, and --json — so vk batch --ios --file login.flow runs the whole flow against the simulator.