run-agent-device
Use if testing or debugging an iOS app via agent-device CLI — simulator flows, evidence, bug triage.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use if testing or debugging an iOS app via agent-device CLI — simulator flows, evidence, bug triage.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use skill if you are exhaustively testing or release-gating martool CLI commands in a source checkout or deployed Coolify container over SSH, without local Docker or provider spend.
Use if driving agent-browser for Chrome/CDP automation, @ref snapshots, tabs, or verification.
Use if supervising Jean agents through MCP and Computer Use for monitoring, recovery, or closure.
Use if auditing or designing a CLI for agent/LLM use — JSON output, exit codes, non-interactive.
Use if auditing or designing an MCP server for agent-readiness — framework, security, context.
Use if verifying claimed-done work or auditing session/plan/branch completion with evidence.
| name | run-agent-device |
| description | Use if testing or debugging an iOS app via agent-device CLI — simulator flows, evidence, bug triage. |
| allowed-tools | Bash(agent-device:*) |
Drive the installed agent-device CLI as a serial REPL against an iOS simulator or device: run one command, read its full output, decide the next command from what it actually said. You are testing a product, not just a screen — most "UI bugs" you will find live in another layer (dev server, app code, backend, environment), and this skill's job is to keep you from fixing the wrong one.
Not this skill: Android-first device control (use mobilerun-control), web/browser automation (use run-agent-browser), authoring XCTest/unit tests, or App Store release operations. agent-device can drive Android and web, but this skill's guidance is iOS-product-testing shaped.
agent-device ships version-matched instructions. When syntax or behavior is uncertain, ask the tool, not your memory:
agent-device --help # command list + agent quickstart
agent-device help workflow # full operating reference (the big one)
agent-device <command> --help # exact flags for one command
agent-device --version
Route by task before starting:
| Task smells like | Read first |
|---|---|
| Follow a written test script / acceptance checklist | agent-device help manual-qa |
| Explore the app and report issues with evidence | agent-device help dogfood |
| Prove a code change / perf fix / regression on-device | agent-device help validate |
| Logs, network, alerts, traces, crashes, flaky failures | agent-device help debugging |
| App is React Native / Expo / dev client | agent-device help react-native + references/dev-loop-react-native.md |
| Component props/state/renders/rerenders | agent-device help react-devtools |
| JS heap growth / leak proof | agent-device help cdp |
| Physical iPhone/iPad, signing setup | agent-device help physical-device |
If this file ever conflicts with the installed CLI's current help, the CLI wins; fix this skill afterward.
Full annotated command surface (all 65 subcommands, grouped, with when-to-use): references/command-map.md. Read it once per session instead of running --help per command.
agent-device devices --platform ios # pick target; --device "iPhone 17 Pro" only if several
agent-device open <AppName-or-bundle-id> --platform ios
agent-device snapshot -i # interactive refs for the first action
open without --relaunch foregrounds an already-running app without restarting it. Use --relaunch when the test needs fresh process state ("start from the home screen").agent-device apps, then open the discovered id. Never invent bundle ids or open artifact paths.doctor only when something fails or the user asks for setup diagnostics — it is not routine prep.--session <name> on every command in that flow.close when done. The iOS XCTest runner stays warm ~5 min after close, so consecutive opens are cheap.snapshot -i → refs like @e12, plus [off-screen below] scroll hints.press / fill / click / longpress <@ref|selector|x y> --settle on every mutating action that supports it.wait stable or another snapshot when the diff already shows the next target. If it prints not settled, follow its hint before the next ref-based action.wait text "…" / wait <selector> / is / get / find — a bare screenshot or snapshot is not verification of a named expectation.open/--relaunch invalidates all of them. After a mutation, prefer a known selector (press 'label="Send"') or refresh with snapshot -i (scope with -s "Container" when possible).Targets: @e12 refs from the latest snapshot/settle output, or selectors — id="submit", label="Search", text="…", role=button label="Follow". Never CSS selectors, never placeholder refs like @eN in a plan. Ambiguous selectors auto-resolve (deepest node, then smallest area) — add id= or longer text to force a different match. Labels containing apostrophes are shell-quoting hazards; prefer the @ref.
Text entry: fill <target> <text> --settle replaces; type <text> appends to the focused field (autoFocused fields are already focused — fill there replaces the whole value, which is usually what you want). fill <target> "" is not a supported clear — use a visible clear control or report the gap. Keyboard on screen usually does not block taps: press the next target directly; only keyboard dismiss when hiding it is the actual goal.
Coordinates are last resort: after refs/selectors fail or accessibility omits the target, get rects with snapshot -i --json, press the center, verify with diff snapshot -i, and say why you used coordinates. Avoid screen edges, tab bars, and the home-indicator zone — they trigger system navigation.
Waits: wait text "…" [timeoutMs] polls every 300 ms (default timeout 10 s) and fails loudly on timeout — that failure is signal, not noise. Network-backed results can land after the settle window; follow the settled action with an explicit wait text/wait <selector> for server-loaded content.
When the task is "test the app / features end to end, fix what breaks":
snapshot -i + screenshot <path> on entry.network dump, logs path, exact repro commands), then root-cause before writing any fix — see the triage table below and references/bug-triage.md.Rules that keep this loop honest:
Empty screens, wrong data, and dead buttons are usually not screen bugs. Probe cheapest-first:
| Symptom | First probe | Likely layer |
|---|---|---|
| Empty list/feed/dashboard, spinner forever | network dump --include headers — did the request fire? status? body? | Backend or auth, not UI |
| Tap "succeeds" but nothing changes | settled diff / diff snapshot -i; check response for targetHittable: false; snapshot -i for overlays sitting on top | Overlay interception or wrong target |
| Fix applied but behavior identical | Prove the running app contains the new code (below) | Stale runtime |
| Data appears but is wrong/stale | network dump --include body, then query the backend directly (curl/DB) with the current user's identity | Backend logic or wrong-user assumption |
| Works once, fails on repeat | Server-side state from the earlier run (idempotency keys, created records) | Test-state pollution |
| Crash / hang / RN red screen | logs clear --restart → repro → logs path; react-native dismiss-overlay for LogBox; debug symbols for crash artifacts | App code |
| Permission sheet blocks flow | alert get → `alert accept | dismiss; if "no alert" but sheet visible, it's app-owned UI: snapshot -i` + press by label |
| Snapshot sparse / AX unavailable | screenshot as visual truth, coordinate-nav off the bad screen, retry snapshot -i | Screen-specific AX gap |
Full playbook with backend-probe patterns, current-user identification, and async-job polling: references/bug-triage.md.
"My fix didn't work" is, more often than not, "the running app never executed my fix." Before debugging logic, prove freshness:
agent-device metro reload — but first confirm which Metro serves this app: which project root, which worktree, which port. A dev client happily loads JS from a different checkout than the one you edited. agent-device doctor reports dev-server reachability; lsof -iTCP:8081 -sTCP:LISTEN + the process cwd tells you whose Metro it is. Editing repo A while Metro serves repo B burns hours.open --relaunch.RN/Expo specifics (Metro truth, Expo Go vs dev client opens, reload-vs-relaunch-vs-rebuild): references/dev-loop-react-native.md.
"Fresh" has independent levels — pick deliberately per retest; onboarding/auth flows usually need all of them:
| Level | Command | Resets |
|---|---|---|
| Foreground | open <app> | Nothing (idempotent foreground) |
| Process | open <app> --relaunch | In-memory state only |
| Local storage | settings clear-app-state [app-id] | Keychain-adjacent app data, caches, onboarding-done flags |
| Server account | In-app sign-out, or a new (anonymous) account | Server-side user state |
| Permissions | settings permission reset <service> | Prior grant/deny decisions |
Watch-out: repeated fresh-account runs create many server-side users. When probing the backend, identify the current run's user from evidence (newest created_at, device id, a value you just typed) — never assume the record you're looking at belongs to the run you're testing.
screenshot ./out/issue-001.png; add --overlay-refs when showing the tappable target matters.logs clear --restart → logs mark "before X" → repro → logs path. Never cat a full stale log into context.network dump --include headers (or body/all) — this is the request/response evidence, better than log spelunking.record start ./out/issue.mp4 … record stop; --hide-touches for gesture-heavy captures.perf metrics --json first pass; perf frames --json for jank; artifacts (heap, traces, profiles) stay on disk — report path + size, never paste raw dumps.grep/jq/head or add 2>/dev/null — raw output carries refs, warnings, and hints your next step needs.| Do this | Not that |
|---|---|
| Prove the running app contains your fix before retesting the symptom | Assume edit + reload reached the device (wrong Metro/worktree/port is silent) |
Drag blocking floating overlays away: gesture pan <x> <y> <dx> <dy> <ms> (dev-menu bubbles, FABs) | Keep tapping "through" an overlay that is eating your presses |
network dump before touching UI code for any empty/wrong-data screen | "Fix" the screen that faithfully renders bad data |
| Re-read the actual error on every retry — second failures often have new causes | Retry harder on the assumption it's the same bug |
| Retest auth/onboarding from a truly new account + cleared storage | Trust a retest that silently reused server-side state |
| Identify the current test user in backend probes by fresh evidence | Query "the user" and reason from someone else's rows |
Verify async product results with wait text "…" <generous-ms>; poll backend jobs on the backend side | Spam snapshots at the UI waiting for a server job |
Use --settle and read the settled diff as the next observation | Sandwich every action between full snapshots |
Escalate stuck iOS waits to screenshot visual truth (AX can be screen-specifically broken) | Retry snapshot forever on an AX-unavailable screen |
In shell probe loops around the CLI: avoid naming a variable status (readonly in zsh) and remember zsh does not word-split unquoted vars | Lose a polling loop to a shell quirk and misread it as a device problem |
| Background long polls (job status, CI, deploys) and keep testing | Block the session foreground-sleeping on a slow backend |
press/fill/open/close against one session.snapshot -i.snapshot -i --json and a stated reason.| File | Load when |
|---|---|
| references/command-map.md | Once per session for the full command surface, or when unsure which command owns a job |
| references/bug-triage.md | A bug is found and needs root-causing across layers, or a fix didn't hold |
| references/dev-loop-react-native.md | The app is React Native / Expo / a dev client |