@ramarivera/chofi
v0.1.1
Published
JSON-first CLI for iOS, Android, Expo, simulator, device, build, test, screenshot, logs, and Maestro workflows
Downloads
72
Maintainers
Readme
chofi
chofi is a JSON-first CLI for iOS, Android, Expo, and React Native workflows — simulator management, builds, tests, screenshots, device operations, and Maestro UI automation.
Philosophy
- JSON-first: Every command emits NDJSON events for both humans and machines
- Planning before execution:
plancommands show what would happen; execution requires explicit confirmation - Clean-room: Inspired by public CLI patterns, but owned code with no proprietary dependencies
- Maestro-native: UI automation flows through Maestro's open-source local runner
- Subprocess-based: Uses
xcrun,simctl,devicectl, andmaestrovia typed subprocess calls — no native framework linking
Installation
npm install -g @ramarivera/chofi
# or
pnpm add -g @ramarivera/chofi
# or
npx @ramarivera/chofi context --jsonQuick Start
# Discover your project
chofi context --json
# Boot a simulator
chofi sim boot "iPhone 17 Pro" --json
# Take a screenshot
chofi sim screenshot "iPhone 17 Pro" --output ./shot.png --json
# Run Maestro flow
chofi maestro run flows/smoke.yaml --jsonCommand Reference
Context & Discovery
| Command | Description |
|---------|-------------|
| chofi context --json | Project metadata, detected platforms, tool availability |
| chofi doctor --json | Health checks (Xcode, simctl, node, pnpm, typecheck) |
| chofi plan run ios --json | Show what an iOS run would do |
| chofi plan run maestro --json | Show what Maestro flows would run |
Simulator
| Command | Description |
|---------|-------------|
| chofi sim list --json | List all simulators |
| chofi sim runtime --json | List available runtimes |
| chofi sim device-types --json | List available device types |
| chofi sim boot <target> --json | Boot simulator (fuzzy match) |
| chofi sim shutdown <target> --json | Shutdown simulator |
| chofi sim open <target> --json | Open Simulator.app GUI |
| chofi sim screenshot <target> --output <path> --json | Screenshot (PNG) |
| chofi sim screenshot <target> --output <path> --format jpeg --json | Screenshot (JPEG) |
| chofi sim erase <target> --confirm --json | Erase simulator data |
| chofi sim create <name> <deviceType> <runtime> --json | Create simulator |
| chofi sim clone <target> <newName> --json | Clone simulator |
| chofi sim delete <target> --confirm --json | Delete simulator |
| chofi sim prune --confirm --json | Remove unavailable simulators |
| chofi sim set-appearance <target> <dark\|light> --json | Set appearance |
| chofi sim clear-cache <target> --json | Clear simulator cache |
| chofi sim add-media <target> <paths...> --json | Add photos/videos to Photos |
| chofi sim record start <target> <path> --json | Start video recording |
| chofi sim record stop <target> --json | Stop video recording |
Physical Devices
| Command | Description |
|---------|-------------|
| chofi device list --json | List connected devices |
| chofi device list --platform connected --json | Filter by status |
App Lifecycle
| Command | Description |
|---------|-------------|
| chofi app install <udid> <path> --json | Install .app bundle |
| chofi app launch <udid> <bundleId> --json | Launch app |
| chofi app terminate <udid> <bundleId> --json | Terminate app |
| chofi app terminate <udid> <bundleId> --force --json | Force kill (SIGKILL) |
| chofi app terminate-all <udid> --force --json | Kill ALL apps |
| chofi app uninstall <udid> <bundleId> --json | Uninstall app |
| chofi apps list <udid> --json | List running apps |
| chofi apps prune <udid> --json | Remove stale registry entries |
Build & Test
| Command | Description |
|---------|-------------|
| chofi build ios --scheme <scheme> --json | Build via xcodebuild |
| chofi build ios --scheme <scheme> --progress --json | Streaming build output |
| chofi test ios --scheme <scheme> --json | Run tests |
| chofi test ios --scheme <scheme> --only <test> --json | Run specific tests |
| chofi test ios --scheme <scheme> --skip <test> --json | Skip specific tests |
| chofi test ios --scheme <scheme> --retry --json | Retry failed tests |
| chofi test ios --scheme <scheme> --progress --json | Real-time test progress |
| chofi test discover ios --scheme <scheme> --json | Discover available tests |
| chofi clean ios --scheme <scheme> --json | Clean build artifacts |
| chofi clean ios --scheme <scheme> --derived-data --json | Clean derived data |
Run
| Command | Description |
|---------|-------------|
| chofi run ios --json | Build and run on iOS simulator |
| chofi run ios --no-build --json | Skip build, just run |
| chofi run ios --launch-env KEY=value --json | Pass launch env vars |
| chofi run android --confirm --json | Build and run on Android |
Maestro
| Command | Description |
|---------|-------------|
| chofi maestro check --json | Check Maestro installation |
| chofi maestro run <flow> --json | Run a Maestro flow |
| chofi maestro continuous <flow> --json | Run in continuous mode |
| chofi maestro hierarchy --json | Dump UI hierarchy |
| chofi maestro record <flow> --json | Record a test session |
| chofi maestro driver-setup --json | Setup Maestro driver |
| chofi maestro start-device --platform ios --json | Start Maestro device |
Project Introspection
| Command | Description |
|---------|-------------|
| chofi project build-config --json | List build configurations |
| chofi project schemes --json | Auto-detect schemes |
Configuration
| Command | Description |
|---------|-------------|
| chofi config get <key> --json | Get config value |
| chofi config set <key> <value> --json | Set config value |
| chofi config reset --confirm --json | Reset config |
JSON Event Format
Every command emits newline-delimited JSON events:
{"schemaVersion":"0.1.0","tool":"chofi","event":"command_started","phase":"sim.boot","timestamp":"2026-05-03T00:00:00.000Z","data":{"target":"iPhone 17 Pro"}}
{"schemaVersion":"0.1.0","tool":"chofi","event":"command_completed","phase":"sim.boot","status":"passed","timestamp":"2026-05-03T00:00:02.000Z","data":{"target":"iPhone 17 Pro"}}
{"schemaVersion":"0.1.0","tool":"chofi","event":"summary","phase":"sim.boot","status":"passed","timestamp":"2026-05-03T00:00:02.000Z","data":{"target":"iPhone 17 Pro"}}Event Types
| Event | Description |
|-------|-------------|
| command_started | Command began execution |
| command_completed | Success — contains result data |
| command_failed | Failure — contains message and recoverySuggestion |
| summary | Final event (always emitted) |
| tool_checked | Tool availability report |
| plan | Execution plan (non-executing) |
| progress | Build/test progress stream |
Architecture
chofi
├── src/
│ ├── cli.ts # Commander.js CLI parsing & routing
│ ├── runtime.ts # Execution orchestrator (20+ operations)
│ ├── drivers/
│ │ ├── apple.ts # simctl, xcrun, devicectl, xcodebuild
│ │ ├── maestro.ts # Maestro CLI wrapper
│ │ └── expo.ts # Expo CLI wrapper
│ ├── spawn.ts # ProcessSpawner abstraction (testable)
│ ├── events.ts # NDJSON event envelope
│ ├── discovery.ts # Workspace & tool discovery
│ ├── planning.ts # Non-executing command plans
│ ├── safety.ts # Explicit confirmation gates
│ ├── config.ts # .chofi.json persistence
│ └── errors.ts # Structured error hierarchy
└── test/
├── drivers/ # Driver unit tests
├── e2e.test.ts # End-to-end CLI tests
├── integration.test.ts # Live tests (CHOFI_LIVE=1)
└── *.test.ts # Unit testsSafety Gates
Dangerous operations require explicit confirmation:
| Command | Gate |
|---------|------|
| sim erase | --confirm |
| sim delete | --confirm |
| sim prune | --confirm |
| run ios (device) | --confirm |
| run android | --confirm |
| config reset | --confirm |
Configuration
Create .chofi.json in the project root:
{
"scheme": "MyApp",
"workspace": "MyApp.xcworkspace",
"destination": "platform=iOS Simulator,name=iPhone 17 Pro"
}Or use environment variables:
| Variable | Purpose |
|----------|---------|
| CHOFI_SCHEME | Default Xcode scheme |
| CHOFI_WORKSPACE | Default Xcode workspace |
| CHOFI_PROJECT | Default Xcode project |
| CHOFI_DESTINATION | Default build destination |
Environment Variables
| Variable | Purpose |
|----------|---------|
| CHOFI_LIVE | Set to 1 to enable live integration tests |
Development
# Install dependencies
pnpm install
# Run all tests
pnpm test
# Run live integration tests
CHOFI_LIVE=1 pnpm test:live
# Typecheck
pnpm typecheck
# Build
pnpm build
# Run locally
node dist/cli.js context --jsonPublishing
This package publishes through GitHub Actions trusted publishing from .github/workflows/publish.yml.
To publish a new release, bump package.json, commit, and push to master. The workflow uses Node 24 with npm 11+, installs dependencies with pnpm, runs typecheck/tests, builds dist/, performs an npm pack dry-run, skips already-published versions, and publishes unpublished versions to npm.
The npm trusted publisher should be configured for:
- Package:
@ramarivera/chofi - Repository:
ramarivera/chofi - Workflow:
.github/workflows/publish.yml - Environment: blank unless the workflow is changed to require one
License
MIT
