CLI · Open source · MIT

v0.20.0

Conductor

Give Claude hands. Let it drive your app.

A token-efficient CLI for mobile and web UI testing, built for AI agents. A TypeScript reimplementation and partial fork of Maestro that bundles its own native drivers — no external CLI, no setup friction, no nonsense.

Install

npm install -g @houwert/conductor

That's it. Conductor is a pure CLI — no Claude Code plugin or skill is registered. Wire it into your agent through a custom CLAUDE.md, a project skill, or a slash command.

Highlights
🎯

Built for agents

Output is short and human-readable by default; opt into --json when you need machine-parseable results. Designed to be cheap on tokens.

📱

iOS, Android, and web

Drive iOS simulators, Android emulators, and Playwright-controlled browsers through one CLI. Same commands, three platforms.

👀

Inspect and assert

Read the live view hierarchy with accessibility metadata, take screenshots, and assert visibility — all without writing flow YAML.

🧵

Multi-device parallel testing

Run flows on every booted device at once with run-parallel, or hand each agent its own device through a shared pool with file-based locking.

📦

Drivers bundled

No Maestro CLI, no extra setup. Native iOS, Android, and web drivers are downloaded on first use into ~/.conductor/drivers — and Argus ships its own copy out of the box.

🪵

Logs out of the box

Stream React Native Metro logs, native simctl/logcat output, or browser console events with a single conductor logs command.

  1. v0.20.0

    Highlights

    • Wire `network logs`, `network request`, and `debug evaluate` to the web (Playwright) driver.
    • Support canvas-rendered webtv apps (Lightning/WPE/RDK) in the web driver.

    Fixes

    • `capture-ui` now rejects a non-`.json` `--output` path. The command always emits a JSON bundle (the screenshot is embedded as base64), so passing an image path like `--output foo.png` previously produced an image-named file full of JSON. It now fails fast with a clear message pointing to `take-screenshot` for actual image files. Extensionless and `.json` paths are unchanged.
    • Auto-start the daemon when reading logs without one running. `conductor logs` (both `--recent` and streaming) previously relied on `getDriver()` to bring the daemon up, but `getDriver()` only spawns the daemon when the driver _port_ is closed. After the daemon idle-times-out while leaving the driver alive (e.g. tvOS deliberately keeps its runner up across daemon restarts), the port stays open but the daemon socket — which hosts the log collector — is gone, so log reads failed with "Daemon … is not responding". The command now explicitly ensures the daemon socket is up via the idempotent `startDaemon()` before connecting.
  2. v0.19.1

    Fixes

    • Fix `take-screenshot --id/--text/<query>` cropping the wrong region on retina iOS and 4K tvOS. The crop pipeline derived its AX→pixel scale from the synthetic root `axElement.frame`, which is always zero, so bounds in logical points were applied as pixel coordinates and the crop landed in the top-left quadrant. Scale is now sourced from `deviceInfo`, and `--margin` is interpreted in the same logical units as the bounds it pads. Also adds the missing `-o` shorthand for `--output`.
  3. v0.19.0

    Highlights

    • `screenshot` can now target a single element via `--selector` (or a positional selector argument), cropping the capture to that element's bounds. Adds a new `png-crop` helper for in-process PNG cropping, so no external image tooling is required.
    • Restore app focus on tvOS via a new `RestoreFocusHandler` in the iOS driver, wired through the daemon and bootstrap so tvOS sessions can recover focus after backgrounding or navigation.

    Fixes

    • Make the blast radius of `launch-app --clear-state` and `--clear-keychain` explicit: clarified `--help` text, updated `docs/commands.md`, and added a one-line stderr warning when either flag is used. These flags drop the app's keychain items (signing the user out) and are easy to reach for as a debugging shortcut — the new messaging spells that out. No behavior change.