npm.io
0.1.18 • Published 17h agoCLI

@ramarivera/chofi

Licence
MIT
Version
0.1.18
Deps
1
Size
234 kB
Vulns
0
Weekly
841

chofi

chofi mascot

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: plan commands 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, and maestro via typed subprocess calls — no native framework linking

Installation

npm install -g @ramarivera/chofi
# or
pnpm add -g @ramarivera/chofi
# or
npx @ramarivera/chofi context --json

Quick 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 --json

Command 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 launch <udid> <bundleId> --json -- <args...> Launch app with app arguments and report verified argv
chofi app launch <udid> <bundleId> --stability-recheck-ms 3500 --json Require the launched PID to survive a longer post-launch settle window
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
Logs
Command Description
chofi logs <udid> --json --timeout <ms> Stream simulator/device logs
chofi logs <udid> --json --timeout <ms> --bundle-id <bundleId> Stream app-focused logs
chofi logs <udid> --json --timeout <ms> --predicate <predicate> Stream logs matching an explicit NSPredicate
Build & Test
Command Description
chofi build --scheme <scheme> --json Build via xcodebuild
chofi build --scheme <scheme> --progress --json Streaming build output
chofi build --scheme <scheme> --derived-data-path <path> --json Build with an explicit DerivedData path
chofi build --scheme <scheme> --json -- CODE_SIGNING_ALLOWED=NO Forward extra xcodebuild settings/args
chofi test --scheme <scheme> --json Run tests
chofi test --scheme <scheme> --only <test> --json Run specific tests
chofi test --scheme <scheme> --skip <test> --json Skip specific tests
chofi test --scheme <scheme> --retry --json Retry failed tests
chofi test --scheme <scheme> --progress --json Real-time test progress
chofi test --scheme <scheme> --result-bundle-path <path> --json Preserve an explicit .xcresult bundle path in failure JSON
chofi test --scheme <scheme> --json -- CODE_SIGNING_ALLOWED=NO -quiet Forward extra xcodebuild settings/args after --
chofi test discover --scheme <scheme> --json Discover available tests
chofi clean --scheme <scheme> --json Clean build artifacts
chofi clean --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 tests

Safety 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 --json

Publishing

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

Keywords