@ramarivera/chofi 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +257 -0
  2. package/dist/cli.d.ts +18 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +1326 -0
  5. package/dist/config.d.ts +10 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +20 -0
  8. package/dist/discovery.d.ts +44 -0
  9. package/dist/discovery.d.ts.map +1 -0
  10. package/dist/discovery.js +151 -0
  11. package/dist/drivers/apple.d.ts +68 -0
  12. package/dist/drivers/apple.d.ts.map +1 -0
  13. package/dist/drivers/apple.js +360 -0
  14. package/dist/drivers/expo.d.ts +14 -0
  15. package/dist/drivers/expo.d.ts.map +1 -0
  16. package/dist/drivers/expo.js +42 -0
  17. package/dist/drivers/idb.d.ts +38 -0
  18. package/dist/drivers/idb.d.ts.map +1 -0
  19. package/dist/drivers/idb.js +52 -0
  20. package/dist/drivers/maestro.d.ts +37 -0
  21. package/dist/drivers/maestro.d.ts.map +1 -0
  22. package/dist/drivers/maestro.js +64 -0
  23. package/dist/drivers/types.d.ts +23 -0
  24. package/dist/drivers/types.d.ts.map +1 -0
  25. package/dist/drivers/types.js +1 -0
  26. package/dist/errors.d.ts +31 -0
  27. package/dist/errors.d.ts.map +1 -0
  28. package/dist/errors.js +59 -0
  29. package/dist/events.d.ts +33 -0
  30. package/dist/events.d.ts.map +1 -0
  31. package/dist/events.js +26 -0
  32. package/dist/executor.d.ts +11 -0
  33. package/dist/executor.d.ts.map +1 -0
  34. package/dist/executor.js +17 -0
  35. package/dist/index.d.ts +14 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +13 -0
  38. package/dist/planning.d.ts +18 -0
  39. package/dist/planning.d.ts.map +1 -0
  40. package/dist/planning.js +75 -0
  41. package/dist/runtime.d.ts +157 -0
  42. package/dist/runtime.d.ts.map +1 -0
  43. package/dist/runtime.js +650 -0
  44. package/dist/safety.d.ts +8 -0
  45. package/dist/safety.d.ts.map +1 -0
  46. package/dist/safety.js +84 -0
  47. package/dist/spawn.d.ts +30 -0
  48. package/dist/spawn.d.ts.map +1 -0
  49. package/dist/spawn.js +178 -0
  50. package/dist/tsconfig.tsbuildinfo +1 -0
  51. package/package.json +64 -0
  52. package/sophy.png +0 -0
package/README.md ADDED
@@ -0,0 +1,257 @@
1
+ # chofi
2
+
3
+ <img src="sophy.png" alt="chofi mascot" width="200" />
4
+
5
+ **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.
6
+
7
+ ## Philosophy
8
+
9
+ - **JSON-first**: Every command emits NDJSON events for both humans and machines
10
+ - **Planning before execution**: `plan` commands show what *would* happen; execution requires explicit confirmation
11
+ - **Clean-room**: Inspired by public CLI patterns, but owned code with no proprietary dependencies
12
+ - **Maestro-native**: UI automation flows through Maestro's open-source local runner
13
+ - **Subprocess-based**: Uses `xcrun`, `simctl`, `devicectl`, and `maestro` via typed subprocess calls — no native framework linking
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install -g @ramarivera/chofi
19
+ # or
20
+ pnpm add -g @ramarivera/chofi
21
+ # or
22
+ npx @ramarivera/chofi context --json
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ```bash
28
+ # Discover your project
29
+ chofi context --json
30
+
31
+ # Boot a simulator
32
+ chofi sim boot "iPhone 17 Pro" --json
33
+
34
+ # Take a screenshot
35
+ chofi sim screenshot "iPhone 17 Pro" --output ./shot.png --json
36
+
37
+ # Run Maestro flow
38
+ chofi maestro run flows/smoke.yaml --json
39
+ ```
40
+
41
+ ## Command Reference
42
+
43
+ ### Context & Discovery
44
+
45
+ | Command | Description |
46
+ |---------|-------------|
47
+ | `chofi context --json` | Project metadata, detected platforms, tool availability |
48
+ | `chofi doctor --json` | Health checks (Xcode, simctl, node, pnpm, typecheck) |
49
+ | `chofi plan run ios --json` | Show what an iOS run would do |
50
+ | `chofi plan run maestro --json` | Show what Maestro flows would run |
51
+
52
+ ### Simulator
53
+
54
+ | Command | Description |
55
+ |---------|-------------|
56
+ | `chofi sim list --json` | List all simulators |
57
+ | `chofi sim runtime --json` | List available runtimes |
58
+ | `chofi sim device-types --json` | List available device types |
59
+ | `chofi sim boot <target> --json` | Boot simulator (fuzzy match) |
60
+ | `chofi sim shutdown <target> --json` | Shutdown simulator |
61
+ | `chofi sim open <target> --json` | Open Simulator.app GUI |
62
+ | `chofi sim screenshot <target> --output <path> --json` | Screenshot (PNG) |
63
+ | `chofi sim screenshot <target> --output <path> --format jpeg --json` | Screenshot (JPEG) |
64
+ | `chofi sim erase <target> --confirm --json` | **Erase simulator data** |
65
+ | `chofi sim create <name> <deviceType> <runtime> --json` | Create simulator |
66
+ | `chofi sim clone <target> <newName> --json` | Clone simulator |
67
+ | `chofi sim delete <target> --confirm --json` | **Delete simulator** |
68
+ | `chofi sim prune --confirm --json` | **Remove unavailable simulators** |
69
+ | `chofi sim set-appearance <target> <dark\|light> --json` | Set appearance |
70
+ | `chofi sim clear-cache <target> --json` | Clear simulator cache |
71
+ | `chofi sim add-media <target> <paths...> --json` | Add photos/videos to Photos |
72
+ | `chofi sim record start <target> <path> --json` | Start video recording |
73
+ | `chofi sim record stop <target> --json` | Stop video recording |
74
+
75
+ ### Physical Devices
76
+
77
+ | Command | Description |
78
+ |---------|-------------|
79
+ | `chofi device list --json` | List connected devices |
80
+ | `chofi device list --platform connected --json` | Filter by status |
81
+
82
+ ### App Lifecycle
83
+
84
+ | Command | Description |
85
+ |---------|-------------|
86
+ | `chofi app install <udid> <path> --json` | Install .app bundle |
87
+ | `chofi app launch <udid> <bundleId> --json` | Launch app |
88
+ | `chofi app terminate <udid> <bundleId> --json` | Terminate app |
89
+ | `chofi app terminate <udid> <bundleId> --force --json` | Force kill (SIGKILL) |
90
+ | `chofi app terminate-all <udid> --force --json` | Kill ALL apps |
91
+ | `chofi app uninstall <udid> <bundleId> --json` | Uninstall app |
92
+ | `chofi apps list <udid> --json` | List running apps |
93
+ | `chofi apps prune <udid> --json` | Remove stale registry entries |
94
+
95
+ ### Build & Test
96
+
97
+ | Command | Description |
98
+ |---------|-------------|
99
+ | `chofi build ios --scheme <scheme> --json` | Build via xcodebuild |
100
+ | `chofi build ios --scheme <scheme> --progress --json` | Streaming build output |
101
+ | `chofi test ios --scheme <scheme> --json` | Run tests |
102
+ | `chofi test ios --scheme <scheme> --only <test> --json` | Run specific tests |
103
+ | `chofi test ios --scheme <scheme> --skip <test> --json` | Skip specific tests |
104
+ | `chofi test ios --scheme <scheme> --retry --json` | Retry failed tests |
105
+ | `chofi test ios --scheme <scheme> --progress --json` | Real-time test progress |
106
+ | `chofi test discover ios --scheme <scheme> --json` | Discover available tests |
107
+ | `chofi clean ios --scheme <scheme> --json` | Clean build artifacts |
108
+ | `chofi clean ios --scheme <scheme> --derived-data --json` | Clean derived data |
109
+
110
+ ### Run
111
+
112
+ | Command | Description |
113
+ |---------|-------------|
114
+ | `chofi run ios --json` | Build and run on iOS simulator |
115
+ | `chofi run ios --no-build --json` | Skip build, just run |
116
+ | `chofi run ios --launch-env KEY=value --json` | Pass launch env vars |
117
+ | `chofi run android --confirm --json` | Build and run on Android |
118
+
119
+ ### Maestro
120
+
121
+ | Command | Description |
122
+ |---------|-------------|
123
+ | `chofi maestro check --json` | Check Maestro installation |
124
+ | `chofi maestro run <flow> --json` | Run a Maestro flow |
125
+ | `chofi maestro continuous <flow> --json` | Run in continuous mode |
126
+ | `chofi maestro hierarchy --json` | Dump UI hierarchy |
127
+ | `chofi maestro record <flow> --json` | Record a test session |
128
+ | `chofi maestro driver-setup --json` | Setup Maestro driver |
129
+ | `chofi maestro start-device --platform ios --json` | Start Maestro device |
130
+
131
+ ### Project Introspection
132
+
133
+ | Command | Description |
134
+ |---------|-------------|
135
+ | `chofi project build-config --json` | List build configurations |
136
+ | `chofi project schemes --json` | Auto-detect schemes |
137
+
138
+ ### Configuration
139
+
140
+ | Command | Description |
141
+ |---------|-------------|
142
+ | `chofi config get <key> --json` | Get config value |
143
+ | `chofi config set <key> <value> --json` | Set config value |
144
+ | `chofi config reset --confirm --json` | **Reset config** |
145
+
146
+ ## JSON Event Format
147
+
148
+ Every command emits newline-delimited JSON events:
149
+
150
+ ```json
151
+ {"schemaVersion":"0.1.0","tool":"chofi","event":"command_started","phase":"sim.boot","timestamp":"2026-05-03T00:00:00.000Z","data":{"target":"iPhone 17 Pro"}}
152
+ {"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"}}
153
+ {"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"}}
154
+ ```
155
+
156
+ ### Event Types
157
+
158
+ | Event | Description |
159
+ |-------|-------------|
160
+ | `command_started` | Command began execution |
161
+ | `command_completed` | Success — contains result data |
162
+ | `command_failed` | Failure — contains `message` and `recoverySuggestion` |
163
+ | `summary` | Final event (always emitted) |
164
+ | `tool_checked` | Tool availability report |
165
+ | `plan` | Execution plan (non-executing) |
166
+ | `progress` | Build/test progress stream |
167
+
168
+ ## Architecture
169
+
170
+ ```
171
+ chofi
172
+ ├── src/
173
+ │ ├── cli.ts # Commander.js CLI parsing & routing
174
+ │ ├── runtime.ts # Execution orchestrator (20+ operations)
175
+ │ ├── drivers/
176
+ │ │ ├── apple.ts # simctl, xcrun, devicectl, xcodebuild
177
+ │ │ ├── maestro.ts # Maestro CLI wrapper
178
+ │ │ └── expo.ts # Expo CLI wrapper
179
+ │ ├── spawn.ts # ProcessSpawner abstraction (testable)
180
+ │ ├── events.ts # NDJSON event envelope
181
+ │ ├── discovery.ts # Workspace & tool discovery
182
+ │ ├── planning.ts # Non-executing command plans
183
+ │ ├── safety.ts # Explicit confirmation gates
184
+ │ ├── config.ts # .chofi.json persistence
185
+ │ └── errors.ts # Structured error hierarchy
186
+ └── test/
187
+ ├── drivers/ # Driver unit tests
188
+ ├── e2e.test.ts # End-to-end CLI tests
189
+ ├── integration.test.ts # Live tests (CHOFI_LIVE=1)
190
+ └── *.test.ts # Unit tests
191
+ ```
192
+
193
+ ## Safety Gates
194
+
195
+ Dangerous operations require explicit confirmation:
196
+
197
+ | Command | Gate |
198
+ |---------|------|
199
+ | `sim erase` | `--confirm` |
200
+ | `sim delete` | `--confirm` |
201
+ | `sim prune` | `--confirm` |
202
+ | `run ios` (device) | `--confirm` |
203
+ | `run android` | `--confirm` |
204
+ | `config reset` | `--confirm` |
205
+
206
+ ## Configuration
207
+
208
+ Create `.chofi.json` in the project root:
209
+
210
+ ```json
211
+ {
212
+ "scheme": "MyApp",
213
+ "workspace": "MyApp.xcworkspace",
214
+ "destination": "platform=iOS Simulator,name=iPhone 17 Pro"
215
+ }
216
+ ```
217
+
218
+ Or use environment variables:
219
+
220
+ | Variable | Purpose |
221
+ |----------|---------|
222
+ | `CHOFI_SCHEME` | Default Xcode scheme |
223
+ | `CHOFI_WORKSPACE` | Default Xcode workspace |
224
+ | `CHOFI_PROJECT` | Default Xcode project |
225
+ | `CHOFI_DESTINATION` | Default build destination |
226
+
227
+ ## Environment Variables
228
+
229
+ | Variable | Purpose |
230
+ |----------|---------|
231
+ | `CHOFI_LIVE` | Set to `1` to enable live integration tests |
232
+
233
+ ## Development
234
+
235
+ ```bash
236
+ # Install dependencies
237
+ pnpm install
238
+
239
+ # Run all tests
240
+ pnpm test
241
+
242
+ # Run live integration tests
243
+ CHOFI_LIVE=1 pnpm test:live
244
+
245
+ # Typecheck
246
+ pnpm typecheck
247
+
248
+ # Build
249
+ pnpm build
250
+
251
+ # Run locally
252
+ node dist/cli.js context --json
253
+ ```
254
+
255
+ ## License
256
+
257
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { type Clock, type EventWriter } from "./events.js";
3
+ import { type ToolChecker } from "./discovery.js";
4
+ import { type CommandRunner } from "./executor.js";
5
+ import { RuntimeController } from "./runtime.js";
6
+ import type { ProcessSpawner } from "./spawn.js";
7
+ export interface CliDependencies {
8
+ readonly clock?: Clock | undefined;
9
+ readonly cwd?: string | undefined;
10
+ readonly pathEnv?: string | undefined;
11
+ readonly runner?: CommandRunner | undefined;
12
+ readonly runtime?: RuntimeController | undefined;
13
+ readonly spawner?: ProcessSpawner | undefined;
14
+ readonly toolChecker?: ToolChecker | undefined;
15
+ readonly writer?: EventWriter | undefined;
16
+ }
17
+ export declare function runChofiCli(argv: readonly string[], dependencies?: CliDependencies): Promise<number>;
18
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAGL,KAAK,KAAK,EACV,KAAK,WAAW,EACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,eAAe,CAAC;AAQvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAC3C;AA0pCD,wBAAsB,WAAW,CAC/B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,YAAY,GAAE,eAAoB,GACjC,OAAO,CAAC,MAAM,CAAC,CA2DjB"}