Get started
Concepts
Drivers, sessions, devices, the daemon, and how Conductor stays out of the way of your AI agent.
A short tour of the moving parts. Each concept maps to something concrete on disk or in your shell — Conductor is deliberately a thin CLI on top of well-understood platform tooling.
Driver
A driver is the piece of code that runs inside the simulator, emulator, or browser and translates Conductor commands into native actions.
Conductor bundles three of them:
- iOS driver — installed onto the simulator the first time you run a command.
- Android driver — installed via
adbthe first time you target an Android device. - Web driver — uses Playwright. Run
conductor install-webonce to fetch the browser binary.
You don't manage drivers explicitly — Conductor does that. They live
under ~/.conductor/ after first run.
Session
A session is a tiny piece of state on disk that remembers two
things: the device you last targeted (--device) and the last app you
launched (launch-app). It lets every subsequent command run without
re-specifying them.
~/.conductor/
sessions/
default.json ← { "deviceId": "…", "appId": "…" }
backend.json
flow-runner.json
Pass --session <name> to any command to use a session other than
default. This is how concurrent agents work in parallel without
trampling each other's state — give each agent its own session name.
Device
A device is anything Conductor can drive. Today that's:
- An iOS Simulator (any installed runtime).
- An Android emulator (AVD) or a wired-up Android device.
- A Playwright-managed browser instance (
web,web:firefox,web:webkit).
conductor list-devices enumerates booted ones. conductor start-device <name> boots a specific simulator or emulator;
conductor stop-device shuts it down.
Daemon
The driver takes a moment to start. For interactive use that's fine; for an AI agent issuing dozens of commands the cold-start adds up.
The daemon is an optional long-running process per session that keeps the driver warm:
conductor daemon-start --session default
conductor daemon-status
conductor daemon-stop --session default
Subsequent commands skip the cold-start hit. Stop the daemon when
you're done. conductor daemon-stop --all shuts down every session's
daemon at once.
Flow
A flow is a YAML file describing a sequence of Conductor commands. Conductor's flow format is a subset of Maestro's — most existing Maestro flows run unchanged.
appId: com.example.myapp
---
- launchApp
- tapOn: "Sign In"
- inputText: "user@example.com"
- assertVisible: "Dashboard"
conductor run-flow path/to/flow.yaml runs it.
conductor run-flow-inline '<yaml>' accepts the YAML on the command
line. conductor run-parallel --flows-dir tests/ shards a directory
of flows across every booted device round-robin. See
Flows for the full reference.
Element resolution
Most commands take an element — what to tap, what to assert, what to scroll to. Conductor resolves it like Maestro does, in priority order:
- The positional argument is matched against accessibility identifier first, then visible text.
- Disambiguators narrow further:
--id,--text,--index,--below,--above,--left-of,--right-of,--enabled,--checked,--focused,--selected. --timeout <ms>lets the resolver wait for the element to appear.--optional(ontap-onand friends) makes a missing element a no-op instead of an error.
conductor inspect prints the live UI hierarchy so you can see
exactly what identifiers and texts are available right now.
Output modes
Every command prints a one-line success or error message to stdout. Some commands also produce structured data:
conductor inspectandconductor capture-uiprint JSON.--dumponinspectprints the raw driver output.--output <path>on screenshot-y commands writes the artefact to disk.--quietand--jsonflags are honoured where they make sense.
This means agents can pipe Conductor through jq, parse exit codes,
or feed structured snapshots into a model — whichever suits the
workflow.