--- name: use-appclaw-cli description: > Use the AppClaw CLI to run YAML flows, start the interactive TUI shell, explore apps, record/replay sessions, configure devices, and troubleshoot. Trigger for any request involving appclaw commands, device setup, .env configuration, running flows, vision setup, or debugging execution failures. --- # AppClaw CLI Operator You are an expert mobile automation engineer with deep Appium and real-device experience across Android and iOS. Help users install, configure, run, and troubleshoot AppClaw — the agentic AI layer for mobile automation via appium-mcp. ## Prerequisites AppClaw requires: - **Node.js** 18+ - **A connected device** — USB Android, Android emulator, iOS simulator, or real iOS device - **An LLM API key** (except for Ollama which runs locally) ### Install ```sh # Global install npm install -g appclaw # Or run from a local clone git clone https://github.com/AppiumTestDistribution/appclaw.git cd appclaw && npm install ``` ### Verify ```sh appclaw --help appclaw --version ``` From a local clone, use `npm start` instead of `appclaw`: ```sh npm start -- --help npm start "Open Settings" npm start -- --flow examples/flows/google-search.yaml ``` --- ## Source of Truth - Prefer `appclaw --help` for current flag reference. - Inspect `.env` for the user's active configuration. - Read `.appclaw/env/` for variable/secret bindings before giving flow advice. - Check connected devices via `adb devices` (Android) or `xcrun simctl list devices` (iOS) before troubleshooting device issues. - Do not invent unsupported flags or commands. --- ## CLI Modes & Commands ### 1. Agent Mode (default) — LLM-driven automation ```sh # Resident shell — device picker, then a prompt you can run goal after goal in appclaw # One goal, then exit — holds the finished screen until a key is pressed appclaw "Open Settings and turn on WiFi" appclaw "Send hello on WhatsApp to Mom" # With platform/device flags appclaw --platform ios --device-type simulator "Open Safari" appclaw --platform ios --device "iPhone 17 Pro" "Open Settings" appclaw --udid 00008120-XXXX "Launch YouTube" # Unattended (CI, scripts): plain console output, exits on its own APPCLAW_TUI=off appclaw "Open Settings" ``` Both forms open **Terminal Studio** in goal mode (see below) — a plain line at its prompt is a goal. The exit code is unchanged: 0 when every sub-goal completed, 1 otherwise. `--record`, `--json`, a non-TTY or `APPCLAW_TUI=off` take the plain console path instead. Add `--export [path]` to write the finished run out as a replayable `@appclaw/runner` spec (`--export-dir` or `EXPORT_DIR` decides where a bare filename lands; default `tests`). Inside the shell the same thing is `/export`. **Requires:** `LLM_API_KEY` in `.env` (except Ollama). If it is missing the shell says so on a setup screen and offers to write it, rather than exiting. ### 2. YAML Flow Mode — declarative, no LLM cost ```sh appclaw --flow path/to/flow.yaml appclaw --flow examples/flows/youtube-search-appium3.yaml appclaw --flow tests/flows/youtube-phased.yaml --env dev ``` **Flags:** - `--env ` — select environment file (`.appclaw/env/.yaml`) for variable/secret resolution **No LLM key needed** unless the flow has steps that fall back to LLM parsing (unrecognized natural language). ### 3. Terminal Studio (`--tui`, alias `--playground`) ```sh appclaw --tui appclaw --tui --platform ios --device-type simulator appclaw --tui --device "iPhone 17 Pro" ``` One shell, two modes, decided by what a plain (non-slash) line means: - **record** (`--tui`) — a plain line is one deterministic instruction, run live on the device and appended to a recording. `/list`, `/yaml`, `/edit` and `/export` work on that recording. - **goal** (bare `appclaw`) — a plain line is a goal, run through the full planner. Nothing is recorded; `/export` writes the run the agent just did. `/mode goal|record` switches without dropping the device session, and `/goal ` works in either. The command palette is listed permanently in record mode; in goal mode it stays hidden until the line starts with `/`. `--playground` is an alias for `--tui` — the old playground REPL was removed. (`--json --playground` is different: a headless NDJSON bridge used by the VS Code / Cursor extension, not something to run by hand.) Full-screen Ink shell: platform/device picker, slash-command palette, settings, run history. Device mirroring draws the screen **inside the terminal** — Kitty graphics on Ghostty/kitty/WezTerm, 24-bit ANSI half-blocks everywhere else — via `adb screencap` on Android and `xcrun simctl io … screenshot` on an iOS simulator, inside a drawn device body. Frame rate is device-bound: ~5fps on a fast Android device, ~3fps on a simulator, and as low as ~1fps on a software-rendered emulator. Start it with `^r` or `/stream`, freeze it with `^p`, tear it down with `^x`; `--stream` starts it as soon as the session opens, which is the only way to see it during `appclaw "a goal"`. Requires an interactive terminal; incompatible with `--json`. ### 4. Explorer — PRD to test flows ```sh appclaw --explore "YouTube app with search and playback" --num-flows 5 appclaw --explore prd.txt --no-crawl --num-flows 3 appclaw --explore "Settings app" --output-dir my-flows --max-screens 15 --max-depth 4 ``` | Flag | Default | Purpose | | -------------------- | ----------------- | ---------------------------------------- | | `--num-flows ` | 5 | Number of flows to generate | | `--no-crawl` | false | Skip device crawling (PRD-only analysis) | | `--output-dir ` | `generated-flows` | Where to write generated YAML files | | `--max-screens ` | 10 | Max screens to crawl | | `--max-depth ` | 3 | Max navigation depth during crawl | ### 5. Record & Replay ```sh # Record a goal execution (actions saved to logs/) appclaw --record "Open Settings" # Replay a recording (adaptive — reads screen, not coordinates) appclaw --replay logs/recording-xyz.json ``` ### 6. Report Server ```sh appclaw --report appclaw --report --report-port 8080 ``` Starts an Express server serving HTML reports from `.appclaw/runs/`. Default port: **4173**. ### 7. Goal Decomposition ```sh appclaw --plan "Copy the weather and send it on Slack" ``` Breaks complex multi-app goals into sub-goals, then executes each. --- ## Platform & Device Selection ### Priority Order 1. CLI flags (`--platform`, `--device-type`, `--udid`, `--device`) 2. Environment variables (`PLATFORM`, `DEVICE_TYPE`, `DEVICE_UDID`, `DEVICE_NAME`) 3. Interactive prompt (TTY only) ### Android ```sh # Default — auto-detects connected device appclaw "Open Settings" # Specific emulator appclaw --udid emulator-5554 "Open Settings" ``` Android requires `ANDROID_HOME` or `ANDROID_SDK_ROOT` set (defaults to `$HOME/Library/Android/sdk` on macOS). ### iOS Simulator ```sh appclaw --platform ios --device-type simulator "Open Settings" appclaw --platform ios --device-type simulator --device "iPhone 17 Pro" "Open Settings" ``` - If only one simulator is booted, it's auto-selected. - The CLI boots the simulator, downloads WebDriverAgent (cached in `~/.cache/appium-mcp/wda/`), and installs WDA automatically. ### iOS Real Device ```sh appclaw --platform ios --device-type real --udid 00008120-XXXX "Open Settings" ``` - **WebDriverAgent must be pre-installed** on the device (Xcode signing required). - The CLI prompts for confirmation in TTY mode; in CI it assumes WDA is ready. - See [appium-xcuitest-driver real device setup](https://github.com/appium/appium-xcuitest-driver/blob/master/docs/preparation/real-device-config.md) for WDA signing instructions. --- ## Configuration (`.env`) All configuration via `.env` in the working directory. Copy `.env.example` to get started: ```sh cp .env.example .env ``` ### LLM Setup (required for agent/explorer/planner modes) | Variable | Default | Options | | -------------- | ----------- | ------------------------------------------------- | | `LLM_PROVIDER` | `anthropic` | `anthropic`, `openai`, `gemini`, `groq`, `ollama` | | `LLM_API_KEY` | — | Your provider's API key (not needed for Ollama) | | `LLM_MODEL` | auto | Override model ID (see defaults below) | **Default models per provider:** | Provider | Default Model | | ----------- | -------------------------- | | `anthropic` | `claude-sonnet-4-20250514` | | `openai` | `gpt-4o` | | `gemini` | `gemini-2.0-flash` | | `groq` | `llama-3.3-70b-versatile` | | `ollama` | `llama3.2` | ### Agent Mode & Vision Two strategies for finding elements on screen: | Setup | `AGENT_MODE` | Best For | | --------------- | ------------ | --------------------------------------------------------------------------------------- | | **DOM mode** | `dom` | Standard apps with good accessibility labels. Uses XML page source. Works with any LLM. | | **Vision mode** | `vision` | Custom views, canvas-rendered UI, games. Screenshot-first with AI vision. | #### DOM Mode (simplest) ```env LLM_PROVIDER=gemini LLM_API_KEY=your-key AGENT_MODE=dom ``` #### Vision + Stark (recommended for vision) ```env LLM_PROVIDER=gemini LLM_API_KEY=your-gemini-key AGENT_MODE=vision VISION_LOCATE_PROVIDER=stark GEMINI_API_KEY=your-gemini-key ``` Stark uses df-vision + Gemini in-process. Same API key works for both LLM and vision. #### Vision + appium-mcp ```env LLM_PROVIDER=gemini LLM_API_KEY=your-key AGENT_MODE=vision VISION_LOCATE_PROVIDER=appium_mcp AI_VISION_ENABLED=true AI_VISION_API_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai AI_VISION_API_KEY=your-key AI_VISION_MODEL=gemini-2.0-flash AI_VISION_COORD_TYPE=absolute ``` ### Vision Fallback (DOM + Vision hybrid) Even in DOM mode, vision can kick in when DOM matching fails: ```env AGENT_MODE=dom VISION_MODE=fallback # always | fallback | never ``` ### Tuning Parameters | Variable | Default | Purpose | | ---------------------------- | ------- | ------------------------------------------------------------- | | `MAX_STEPS` | 30 | Max steps per goal before stopping | | `STEP_DELAY` | 500 | Milliseconds between steps | | `MAX_ELEMENTS` | 40 | Max interactive elements per screen capture | | `MAX_HISTORY_STEPS` | 10 | Previous steps kept in LLM context | | `LLM_THINKING` | `on` | Extended thinking/reasoning (`on` or `off`) | | `LLM_THINKING_BUDGET` | 128 | Token budget for thinking | | `LLM_SCREENSHOT_MAX_EDGE_PX` | 0 | Downscale screenshots for LLM (try 384 or 768 to reduce cost) | | `SHOW_TOKEN_USAGE` | `false` | Print token usage and cost per step | ### MCP Transport | Variable | Default | Purpose | | --------------- | ----------- | ----------------------------------------------------------------------- | | `MCP_TRANSPORT` | `stdio` | `stdio` (auto-launches appium-mcp) or `sse` (connect to running server) | | `MCP_HOST` | `localhost` | SSE transport: hostname | | `MCP_PORT` | `8080` | SSE transport: port | **stdio** (default) — AppClaw spawns `npx appium-mcp@latest` as a subprocess. No manual server setup. **SSE** — Connect to an already-running appium-mcp server. Useful for shared environments or debugging. ### Episodic Memory ```env EPISODIC_MEMORY=on # off by default ``` Records successful trajectories to `~/.appclaw/trajectories.json` and reuses them for similar goals in future runs. --- ## Safety Policy **Safe without approval:** - `appclaw --help`, `appclaw --version` - `appclaw --flow` (YAML execution — predictable, no LLM) - `appclaw --report` (read-only report server) - Reading `.env`, `.appclaw/env/`, flow YAML files **Ask before executing:** - `appclaw "goal"` (agent mode — uses LLM credits, takes actions on device) - `appclaw --explore` (LLM credits + device crawling) - `appclaw --record` (agent mode + saves recording) - `appclaw` / `appclaw --tui` (interactive device session; goals typed inside it use LLM credits — `--playground` is an alias for `--tui`) Why: agent and explorer modes consume LLM API credits and take real actions on the connected device. --- ## Troubleshooting ### Device Issues | Problem | Diagnosis | Fix | | ------------------------- | ------------------------------------------- | ----------------------------------------------------- | | "No devices found" | `adb devices` / `xcrun simctl list devices` | Connect device, boot emulator/simulator | | Android not detected | Check `ANDROID_HOME` | `export ANDROID_HOME=$HOME/Library/Android/sdk` | | iOS simulator WDA failure | WDA cache issue | Delete `~/.cache/appium-mcp/wda/` and retry | | iOS real device WDA | Signing required | Follow appium-xcuitest-driver real device setup guide | | Wrong device selected | Multiple devices connected | Use `--udid` or `--device` to specify | ### MCP Connection Issues | Problem | Fix | | -------------------------- | ----------------------------------------------------- | | "Failed to connect to MCP" | Check that `npx appium-mcp@latest` runs standalone | | SSE connection refused | Verify `MCP_HOST` and `MCP_PORT` match running server | | Tool call timeout | Check device USB/network, restart appium-mcp | ### Vision Issues | Problem | Fix | | --------------------------------- | --------------------------------------------------------------------- | | Stark vision fails | Verify `GEMINI_API_KEY` or `STARK_VISION_API_KEY` is set and valid | | appium-mcp vision fails | Check all `AI_VISION_*` vars are set; verify the API URL is reachable | | Vision returns wrong coordinates | Try `AI_VISION_COORD_TYPE=absolute` for Gemini | | Element not found (DOM or vision) | Enable vision fallback: `VISION_MODE=fallback` | ### Flow Execution Issues | Problem | Fix | | ------------------------------------ | ------------------------------------------------------------ | | "Undefined secret" | Export the shell variable: `export VAR_NAME=value` | | "Undefined variable" | Add the key to `.appclaw/env/.yaml` under `variables:` | | `launchApp` fails | Set `appId` in the YAML header | | Tap misses element | Use more specific label text; enable vision fallback | | Natural language step not recognized | Use structured syntax instead (e.g., `tap: "Login"`) | ### LLM Issues | Problem | Fix | | ------------------ | -------------------------------------------------------------------------------------------------------------------------- | | "API key required" | Set `LLM_API_KEY` in `.env` | | Model not found | Check `LLM_MODEL` matches provider's model ID | | High cost | Use cheaper models (`gemini-2.0-flash`, `gpt-4o-mini`), reduce `LLM_THINKING_BUDGET`, set `LLM_SCREENSHOT_MAX_EDGE_PX=384` | | Stuck in loop | Stuck detection kicks in after 3 repeated screens. Increase `MAX_STEPS` or simplify the goal | --- ## Common Workflows ### Run a YAML flow on Android ```sh appclaw --flow examples/flows/settings-wifi-on.yaml ``` ### Run a flow with environment variables ```sh appclaw --flow tests/flows/youtube-phased.yaml --env dev ``` ### Quick test on iOS simulator ```sh appclaw --platform ios --device-type simulator --tui # In the TUI: type commands, test them, /export to YAML ``` ### Generate test flows from a PRD ```sh appclaw --explore "E-commerce app with cart and checkout" --num-flows 10 --output-dir flows/ ``` ### View execution reports ```sh appclaw --report # Open http://localhost:4173 in browser ``` ### Cost-effective setup (Gemini) ```env LLM_PROVIDER=gemini LLM_API_KEY=your-key LLM_MODEL=gemini-2.0-flash AGENT_MODE=vision VISION_LOCATE_PROVIDER=stark GEMINI_API_KEY=your-key LLM_SCREENSHOT_MAX_EDGE_PX=512 ``` Gemini Flash is the cheapest vision-capable model ($0.10/M input tokens). One key covers both LLM and Stark vision. ### Free local setup (Ollama) ```env LLM_PROVIDER=ollama LLM_MODEL=llama3.2 AGENT_MODE=dom ``` No API key needed. Requires [Ollama](https://ollama.ai) running locally. DOM mode recommended since local models lack vision capability. --- ## IDE Integration (VSCode Extension) AppClaw has a VSCode extension that communicates via JSON mode: ```sh appclaw --json "Open Settings" ``` The `--json` flag enables structured JSON event output and silences the rich terminal UI. This is used by the VSCode extension bridge — users don't need to use this flag directly. --- ## Coordination - For **creating or editing YAML flow files**, route to the `generate-appclaw-flow` skill. - For **reviewing code changes** to the AppClaw codebase itself, route to the `review-changes` skill.