Thanks for your interest in contributing to agent-device.
Requirements:
- Node.js 22+
- pnpm
- Android SDK tools (
adb) for Android support - Xcode (
simctl/devicectl) for iOS support
Setup:
pnpm installBuild all CLIs and Xcode projects:
pnpm build:allApple XCTest builds now share a common helper script. pnpm build:xcuitest:ios and
pnpm build:xcuitest:tvos keep their existing cleanup behavior, while
pnpm build:xcuitest:macos reuses the existing DerivedData by default for faster local
iteration. Set AGENT_DEVICE_IOS_CLEAN_DERIVED=1 when you need a clean macOS runner rebuild.
Run tests:
pnpm testTargeted checks:
pnpm check:quick
pnpm check:unit
pnpm exec vitest run src/compat/maestro/__tests__/replay-flow.test.ts src/compat/__tests__/replay-input.test.tsCode quality (fallow): CI runs pnpm check:fallow --base "$FALLOW_BASE", a diff-based
audit of dead code, duplication, and complexity in the files your PR changes, compared
against the grandfathered baselines in fallow-baselines/. Locally, pnpm fallow runs
the same kind of audit against origin/main and is expected to pass on a clean tree;
pnpm fallow:all shows the full-project picture, including known legacy findings that
the baselines grandfather, so it reporting issues is normal. CRAP scores depend on
estimated test coverage, so a finding can occasionally be exposed — not introduced — by
your change. Run pnpm fallow:baseline to regenerate the baselines only when you are
intentionally accepting a finding.
pnpm fallow— diff-based audit vsorigin/main(what CI runs, with CI picking the PR base)pnpm fallow:all— full-tree summary, includes grandfathered legacy findingspnpm fallow:baseline— regenerate baselines (only to intentionally accept a finding)
Optional device selectors for tests:
ANDROID_DEVICE=Pixel_9_Pro_XLorANDROID_SERIAL=emulator-5554IOS_DEVICE="iPhone 17 Pro"orIOS_UDID=<udid>
The Expo test app lives in examples/test-app. Install its dependencies once:
pnpm test-app:installFor Maestro compatibility, we currently have 15 parser/compat unit tests and one
top-level test-app Maestro flow, examples/test-app/maestro/checkout-form.yaml,
which includes examples/test-app/maestro/helpers/open-checkout-form.yaml.
Run only the parser/compat tests:
pnpm exec vitest run src/compat/maestro/__tests__/replay-flow.test.ts src/compat/__tests__/replay-input.test.tsRun the Expo test-app flow on iOS:
pnpm test-app:start
pnpm ad --session test-app-maestro open "Expo Go" exp://127.0.0.1:8081 --platform ios --device "iPhone 17 Pro"
pnpm ad --session test-app-maestro wait "Agent Device Tester" 30000 --platform ios --device "iPhone 17 Pro"
pnpm test-app:maestro:ios -- --session test-app-maestro -- --device "iPhone 17 Pro"Use pnpm test-app:maestro:android for Android, passing the same extra
agent-device flags after --.
- Keep dependencies minimal.
- Preserve the CLI’s agent-friendly JSON output.
- Ensure tests open and close sessions explicitly.
- Add/adjust integration tests when introducing new commands.
- Prefer built-in Node APIs over new packages.
Issue labels describe workflow state, not who will do the work. See
docs/agents/triage-labels.md for the label meanings and state flow.
Please include:
- OS and Node version
- Xcode/Android SDK versions (if relevant)
- Exact command and output
Thanks for helping improve agent-device.