Use when a task involves VMOS Edge Desktop — creating or controlling Android virtual devices on edge hosts, interacting with the Electron desktop UI via CDP, automating device workflows with YAML playbooks or batch JSON, or recovering from CLI error codes.
CLI tool for controlling the VMOS Edge Desktop Electron app — manage Android virtual devices on edge hosts, automate the desktop UI via CDP, and orchestrate device workflows.
vmos-edge-cli error codesvmos-edge-cli toolNot for: raw ADB commands, Appium, Android Studio emulators, or any non-VMOS Android tooling.
GATE — complete before any other command. Do not skip.
# 1. Node.js 18+ required
node --version
# 2. Check CLI
vmos-edge-cli --version
# 3. If CLI missing → install
npm i -g @vmosedge/cli
# 4. Verify
vmos-edge-cli schema
| Check fails | Action |
|---|---|
node not found | Stop. Tell user to install Node.js 18+. |
npm not found | Stop. Tell user to install npm (bundled with Node.js). |
vmos-edge-cli not found | Run npm i -g @vmosedge/cli, then verify with schema. |
schema fails after install | Report error and stop. Do not improvise fallbacks. |
Do not substitute node dist/main.js, pnpm build, or pnpm link. The only supported install path is npm i -g @vmosedge/cli.
The manual steps above and the automated script (scripts/ensure-installed.mjs) run the same flow — use either. See invocation-preflight.md for platform paths and edge cases.
ui state to inspect, NEVER screenshot — state is free and structured. screenshot costs vision tokens. Only screenshot when user asks to save an image.ui click/type to interact, NEVER eval to click/type — eval bypasses scroll and CDP fallback, fails on off-screen elements.ui state after page changes — after click, goto, back. Never reuse stale indices.create, delete, start, stop, reset each as a separate direct call. Check result before issuing the next command. One command may target multiple items (device start id1 id2, --count 5) — the boundary is between commands, not between targets.schema before writing batch/YAML — never guess param names. Positional CLI args have different names in batch/YAML that are not guessable. Run schema <domain> to discover exact names and types.device/image command needs --host <ip> — host commands take <ip> as positional arg.The app stays running between commands — no need to app start every time.
ui state, device list, host info, etc.data. Failure: branch on code (see error-recovery.md)ui state after page changes, ui form-state after typing, device info after mutations| Context | Format | Example |
|---|---|---|
| Terminal | vmos-edge-cli <domain> <method> | vmos-edge-cli ui eval "1+1" |
YAML action: | domain.method | action: ui.eval |
batch JSON | domain.method | {"action":"ui.eval"} |
| YAML variable | ${{ expr }} | ${{ devices[0].id }} |
batch variable | $expr | $devices[0].id |
Terminal uses spaces. YAML and batch use dots. Variable syntax is not interchangeable.
Use the Read tool on these files when the condition applies — do not work from memory.
| Mistake | Fix |
|---|---|
ui screenshot to inspect page | Use ui state — free, structured, has [N] indices |
ui eval "el.click()" | Use ui click <N> — handles scroll + CDP fallback |
| Reuse indices after page navigation | Run ui state again to get fresh indices |
host check 10.0.0.5 then host info 10.0.0.5 as 2 calls | Batch them: one call, both safe to run unconditionally |
| Guess batch/YAML param names from CLI syntax | Positional args have different names. Run schema <domain> first |
device create then device start in one batch | Never — different mutating commands must be separate calls |
| Type into field without verifying | ui form-state after typing to confirm value |
app start on every command | App persists — check app status first |
ui state output too long on complex page | ui state --interactive-only, or batch with interactiveOnly: true |
| Skip preflight, run CLI commands directly | CLI may not be installed. Always run Preflight gate first |