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.
Inspect
Section titled “Inspect”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. |
vk log in detail
Section titled “vk log in detail”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. |
launch restarts by default
Section titled “launch restarts by default”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-restartopts out and brings the existing instance forward.--clearinstead wipes data viapm clear, which already force-stops.
Device state
Section titled “Device state”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. |
ai flags
Section titled “ai flags”| 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 |
suite flags
Section titled “suite flags”| 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 |
Remote
Section titled “Remote”| 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. |
Environment
Section titled “Environment”| 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.
Test runs
Section titled “Test runs”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.
Global flags
Section titled “Global flags”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.