Operate VMOS Edge CLI
Overview
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.
When to Use
- Creating, starting, stopping, or deleting Android virtual devices on edge hosts
- Automating the VMOS Edge Desktop Electron UI via CDP
- Writing YAML playbooks or batch JSON for device workflows
- Recovering from
vmos-edge-cli error codes
- Installing or verifying the
vmos-edge-cli tool
Not for: raw ADB commands, Appium, Android Studio emulators, or any non-VMOS Android tooling.
Preflight
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.
Critical Rules
- ALWAYS
ui state to inspect, NEVER screenshot — state is free and structured. screenshot costs vision tokens. Only screenshot when user asks to save an image.
- ALWAYS
ui click/type to interact, NEVER eval to click/type — eval bypasses scroll and CDP fallback, fails on off-screen elements.
- ALWAYS
ui state after page changes — after click, goto, back. Never reuse stale indices.
- ALWAYS batch consecutive safe actions — if each step is safe regardless of others' results, batch them. Never run them as separate calls.
- NEVER mix mutating commands in one batch —
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.
- ALWAYS
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.
- Every
device/image command needs --host <ip> — host commands take <ip> as positional arg.
Core Workflow
The app stays running between commands — no need to app start every time.
- Preflight → see Preflight section above. Must pass before continuing.
- Inspect →
ui state, device list, host info, etc.
- Act → direct for single/mutating, batch for consecutive safe actions, run for reusable flows
- Parse → success: read
data. Failure: branch on code (see error-recovery.md)
- Verify →
ui state after page changes, ui form-state after typing, device info after mutations
Quick Reference
| 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.
Reference Map
Use the Read tool on these files when the condition applies — do not work from memory.
- references/page-map.md — read first when navigating the desktop UI: page routes, hidden features, how to reveal menus/panels/dialogs
- references/command-patterns.md — three invocation modes (direct / batch / run), full command reference
- references/ui-automation.md — element selection, action list, cost guide
- references/error-recovery.md — error codes and deterministic recovery
- references/invocation-preflight.md — automated helper script, platform paths, install edge cases
Common Pitfalls
| 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 |
1---2name: operate-vmos-edge-cli3description: 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.4---56# Operate VMOS Edge CLI78## Overview910CLI 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.1112## When to Use1314- Creating, starting, stopping, or deleting Android virtual devices on edge hosts15- Automating the VMOS Edge Desktop Electron UI via CDP16- Writing YAML playbooks or batch JSON for device workflows17- Recovering from `vmos-edge-cli` error codes18- Installing or verifying the `vmos-edge-cli` tool1920**Not for:** raw ADB commands, Appium, Android Studio emulators, or any non-VMOS Android tooling.2122## Preflight2324**GATE — complete before any other command. Do not skip.**2526```bash27# 1. Node.js 18+ required28node --version2930# 2. Check CLI31vmos-edge-cli --version3233# 3. If CLI missing → install34npm i -g @vmosedge/cli3536# 4. Verify37vmos-edge-cli schema38```3940| Check fails | Action |41|-------------|--------|42| `node` not found | **Stop.** Tell user to install Node.js 18+. |43| `npm` not found | **Stop.** Tell user to install npm (bundled with Node.js). |44| `vmos-edge-cli` not found | Run `npm i -g @vmosedge/cli`, then verify with `schema`. |45| `schema` fails after install | Report error and **stop**. Do not improvise fallbacks. |4647Do not substitute `node dist/main.js`, `pnpm build`, or `pnpm link`. The only supported install path is `npm i -g @vmosedge/cli`.4849The manual steps above and the automated script (`scripts/ensure-installed.mjs`) run the same flow — use either. See [invocation-preflight.md](references/invocation-preflight.md) for platform paths and edge cases.5051## Critical Rules52531. **ALWAYS `ui state` to inspect, NEVER `screenshot`** — `state` is free and structured. `screenshot` costs vision tokens. Only screenshot when user asks to save an image.542. **ALWAYS `ui click`/`type` to interact, NEVER `eval` to click/type** — `eval` bypasses scroll and CDP fallback, fails on off-screen elements.553. **ALWAYS `ui state` after page changes** — after `click`, `goto`, `back`. Never reuse stale indices.564. **ALWAYS batch consecutive safe actions** — if each step is safe regardless of others' results, batch them. Never run them as separate calls.575. **NEVER mix mutating commands in one batch** — `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.586. **ALWAYS `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.597. **Every `device`/`image` command needs `--host <ip>`** — `host` commands take `<ip>` as positional arg.6061## Core Workflow6263The app stays running between commands — no need to `app start` every time.64651. **Preflight** → see Preflight section above. Must pass before continuing.662. **Inspect** → `ui state`, `device list`, `host info`, etc.673. **Act** → direct for single/mutating, batch for consecutive safe actions, run for reusable flows684. **Parse** → success: read `data`. Failure: branch on `code` (see [error-recovery.md](references/error-recovery.md))695. **Verify** → `ui state` after page changes, `ui form-state` after typing, `device info` after mutations7071## Quick Reference7273| Context | Format | Example |74|---------|--------|---------|75| Terminal | `vmos-edge-cli <domain> <method>` | `vmos-edge-cli ui eval "1+1"` |76| YAML `action:` | `domain.method` | `action: ui.eval` |77| `batch` JSON | `domain.method` | `{"action":"ui.eval"}` |78| YAML variable | `${{ expr }}` | `${{ devices[0].id }}` |79| `batch` variable | `$expr` | `$devices[0].id` |8081Terminal uses spaces. YAML and batch use dots. Variable syntax is not interchangeable.8283## Reference Map8485Use the Read tool on these files when the condition applies — do not work from memory.8687- [references/page-map.md](references/page-map.md) — **read first** when navigating the desktop UI: page routes, hidden features, how to reveal menus/panels/dialogs88- [references/command-patterns.md](references/command-patterns.md) — three invocation modes (direct / batch / run), full command reference89- [references/ui-automation.md](references/ui-automation.md) — element selection, action list, cost guide90- [references/error-recovery.md](references/error-recovery.md) — error codes and deterministic recovery91- [references/invocation-preflight.md](references/invocation-preflight.md) — automated helper script, platform paths, install edge cases9293## Common Pitfalls9495| Mistake | Fix |96|---------|-----|97| `ui screenshot` to inspect page | Use `ui state` — free, structured, has `[N]` indices |98| `ui eval "el.click()"` | Use `ui click <N>` — handles scroll + CDP fallback |99| Reuse indices after page navigation | Run `ui state` again to get fresh indices |100| `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 |101| Guess batch/YAML param names from CLI syntax | Positional args have different names. Run `schema <domain>` first |102| `device create` then `device start` in one batch | Never — different mutating commands must be separate calls |103| Type into field without verifying | `ui form-state` after typing to confirm value |104| `app start` on every command | App persists — check `app status` first |105| `ui state` output too long on complex page | `ui state --interactive-only`, or batch with `interactiveOnly: true` |106| Skip preflight, run CLI commands directly | CLI may not be installed. **Always** run Preflight gate first |