[ Documentation ]
CLI Reference

CLI Reference

The peach CLI is the operational surface for booting shells, opening sims, driving automation, and exposing the bridge host to agents.

terminal
peach [command] [options]

Commands

commanddescription
maestroauthor, generate, and run Maestro YAML flows against peach
detoxrun existing Detox suites against peach on headless Chromium
cleanupinspect and reclaim local peach disk usage
recordcapture the live sim as webm/mp4/gif, or sample N png frames (—frames)
filmrecord a flow on the flat canvas, play it back on the 3d device stage under a camera cinematic, save a clip
storagemanage guest app storage and launch profiles
permissionsinspect and change simulated operating-system permissions
perfCPU, React render, shell frame, and scroll-layer profiling
describecurated human-readable UI summary (default inspection tool)
findlocate nodes by text / testID / role / type / predicate
assertrun any read verb and convert its output into an exit code
screenshotcapture PNGs and manage App Store screenshot assets
getread runtime state (tree, a11y, layout, url, count, errors, …)
dodrive the app (tap, type, scroll, swipe, key, reload, …)
waitblock until the runtime reaches a known state
shelldrive shell state and simulator chrome
modetoggle screenshot and 3D display modes
deviceinspect or change the live device preset for a sim
networkinspect live network traffic from the running peach worker
logsinspect live console output from the running peach worker
debugdrive __sootsimDebug: channels, snapshots, and inspectors
what-happenedshow recent semantic events: toasts, keyboards, screens, alerts, fetches, errors
timelinecontrol the semantic event timeline (enable opt-in kinds, clear, dump)
iosstart an iOS simulator
androidstart an Android simulator
openload a target into the current sim or open a new one
listlist connected sims or available launch drivers
useselect a connected sim
skillinstall and inspect bundled peach agent skills
claimtake an exclusive lease on a sim
agentinspect messages, attached projects, and local agent sessions
closeclose a connected sim
setupconfigure optional local conveniences
compatcheck package compatibility
report-issuesend an explicitly approved compatibility report
desktoplaunch or install the desktop companion
daemonmanage the recommended background bridge service
versionshow the CLI + engine runtime versions you are running
upgradeupdate the peach CLI and engine runtime to the latest
serverun the peach bridge in the foreground
runtimemanage engine runtimes under ~/.peach/runtimes/
authinspect active CLI auth
loginsign in for preview uploads
logoutclear the local desktop auth session
configmanage local CLI preferences

Global Flags

flagdescription
-h, --helpshow help
-V, --versionshow version
-v, --verboseverbose output
-p, --port <number>bridge port, depending on command
-d, --device <model>override the simulated device model
-t, --theme <scheme>override light, dark, or auto color scheme
--headlessrun browser automation without a visible window where supported

What The CLI Covers

The CLI is split across four jobs:

  • +
    booting a simulator shell around a local React Native bundler
  • +
    opening, listing, and targeting live sims over the shared bridge host
  • +
    automating those sims for Maestro/Detox tests, screenshots, and recordings
  • +
    exposing the same bridge-backed runtime to CLI automation and generated docs

If you only remember one rule, use the highest-level command that matches the task. Reach for peach open before pasting shell URLs, and peach describe before debugging with screenshots.

Command Groups

The command set is intentionally shaped around workflow instead of implementation detail.

  • +
    setup and development: setup, open, desktop
  • +
    agent onboarding: skill install installs the bundled peach workflow skills
  • +
    storage: storage
  • +
    automation: maestro, detox, record, screenshot
  • +
    live control: open, list, use, claim, close
  • +
    runtime reads: describe, find, and the get <noun> family (get tree, get a11y, get layout --styling, get url, get count, get errors, get requests, …)
  • +
    runtime actions: the do <action> family (do tap, do type, do scroll, do swipe, do key, …), plus shell <action> for simulator chrome
  • +
    instrumentation: perf for profiling and debug for raw runtime dumps, channels, snapshots, diffs, and events
  • +
    compatibility: compat, plus the explicitly approved report-issue feedback path

That grouping is what the website docs and terminal help now share from the same package source.

Bridge Model

The bridge host is the control plane behind top-level verbs like describe and do tap, plus debug, open, list, use, claim, and close.

  • +
    default bridge port: 7668
  • +
    default shell URL: http://localhost:7668/
  • +
    every connected sim gets a stable hex id like a1, a2, …, af, b0
  • +
    browser sims use isolated Playwright Chrome for Testing profiles; the desktop companion uses Electron
  • +
    peach open reuses the saved sim by default. --new, --profile, and --ephemeral explicitly request a separate sim
  • +
    the first CLI to send a command to a sim holds a 60s lease on it. other agents are rejected until the lease expires or, last-resort, taken with peach claim --force (which interrupts whoever’s mid-flow; prefer peach open --new to get a fresh sim instead). the lease refreshes on every command from the owner

This means you can open a sim one way and still inspect or debug it later from the CLI. The CLI also remembers the last sim you opened or selected, so one common pattern is:

terminal
peach open 8081
peach describe
peach do tap-text "Sign in"

Local Setup And CI

Start the app’s Metro, Expo, React Native, or One development server with its existing command. peach does not start or replace that server. Run peach open <port> from the app project root when possible. That directory is the fallback for custom-font, splash-screen, and project-configuration discovery when the development server does not advertise its root.

The local bridge is a lightweight HTTP and WebSocket server at http://localhost:7668/ by default. The background service keeps that bridge and the runtime ready between commands. It is strongly recommended for local agent work because inspect, interaction, and test commands start much faster. It remains optional: enable it any time with peach daemon install. CI can install the standalone CLI with curl -fsSL https://peachsim.com/install.sh | PEACH_NO_MODIFY_PATH=1 sh and run peach open <port> --driver playwright --headless; the command starts the bridge for the job without registering an operating-system service. The peach installer itself does not require Node.js, npm, or Bun.

Coding agents should run peach skill install once, then restart their session so they load the bundled setup, debugging, testing, visual, and performance workflows.

Common Flows

terminal
# load a local port into the current sim
peach open 8081
# open a second sim only when it must run concurrently
peach open --new 8085
# see what is connected and target one sim explicitly
peach list
peach describe --sim a3
# capture state around a bug
peach debug snapshot before
peach debug snapshot after
peach debug diff before after
# isolate app storage in Electron or Playwright
peach storage profile create qa
peach open 8081 --profile qa
# run a single Maestro flow
peach maestro test .maestro/login.yaml --record

Multiple Sims

When more than one sim is connected, run peach list first and pass --sim to the command you care about. The CLI remembers the last sim you opened or used, so explicit --sim matters most when you are juggling more than one target and want deterministic automation.

Passing --sim <sim> also skips the CLI’s identity lookup entirely. If you need a stable identity without pinning a sim on every call, export PEACH_CLI_IDENTITY=<any-stable-string> once for your shell or agent run.

Auto-Settle After Writes

Every peach do <write> command (tap, tap-id, type, scroll, drag, swipe, etc.) briefly waits for layout to stabilize before returning: capped at 200ms (400ms when an agent environment is detected), bailing on 2 consecutive stable frames. This keeps the next CLI call from capturing mid-animation state, which is the single most common source of agent confusion (do tap then describe showing a half-slid screen). When the auto-wait hits its cap without stabilizing, it warns that the next command may see mid-animation state and points at peach do settle for a longer wait, so agents know what happened.

Opt out with --no-wait on the command, or PEACH_NO_AUTO_WAIT=1 for the sim. For longer waits (e.g. screens that animate slowly), chain an explicit peach do settle <seconds> or peach wait idle after the write.

Agent detection is automatic: CLAUDECODE, CLAUDE_CODE_ENTRYPOINT, CODEX_THREAD_ID, CURSOR_TRACE_ID, AIDER_MODEL, or explicit PEACH_AGENT=1 enables agent-friendly defaults. Set PEACH_AGENT=0 to force interactive defaults.

Explicit Waits

peach wait <kind> gives you bounded, loud synchronization primitives instead of sleep guessing:

  • +
    peach wait ready blocks until the guest app bundle is loaded and painted. A persistent runtime readiness flag is cleared on bundle reload and reset by full page reload, avoiding node-count heuristics that can mistake the connection screen for a loaded app. It is idempotent and returns immediately when the app is already ready. The default timeout is 20 seconds; pass --max-ms 30000 for slow cold bundles. CLI-side polling has no bridge timeout ceiling. Run it after opening a new sim or after debug js "window.location.reload()"; no sleep is needed.
  • +
    peach wait idle blocks until animations, rAF queue, and layout all stop moving. Same signal as do settle but discoverable under the wait grouping.
  • +
    peach wait selector <testid> blocks until a node with that testID is present and laid out. Playwright-style. When peach find --testid foo returns no result, the CLI prints this as a hint.

All wait subverbs accept --max-ms <ms> and exit non-zero on timeout, so scripts fail loudly.

peach do <tap|double-tap|long-press> also accept --testid <id> or --text <text> to resolve a node center at call time, equivalent to do tap-id / do tap-text but consistent with find --testid. A missing node prints the wait selector hint.

Flow Drafting

When peach maestro start is active, successful write commands like tap, tap-id, type, scroll, and swipe update the pending flow candidate. They do not automatically become part of the draft. Use peach maestro keep only after the last action proved itself.