peachsim 0.1.571 → 0.1.573

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 (235) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +106 -106
  3. package/cli/app-config.ts +1 -1
  4. package/cli/app-fonts.ts +4 -4
  5. package/cli/auth.ts +11 -11
  6. package/cli/bin.ts +4 -4
  7. package/cli/bridge-flow-runner.ts +13 -13
  8. package/cli/browser-evals.ts +2 -2
  9. package/cli/cli-update.ts +6 -6
  10. package/cli/cloud-client.ts +16 -16
  11. package/cli/cloud-dispatch.ts +2 -2
  12. package/cli/cloud-session.ts +12 -12
  13. package/cli/cloud-test-tunnel.ts +4 -4
  14. package/cli/command-registry.ts +7 -7
  15. package/cli/commands/agent-wrapper.ts +7 -7
  16. package/cli/commands/agent.ts +16 -16
  17. package/cli/commands/app-fonts.ts +3 -3
  18. package/cli/commands/assert.ts +10 -10
  19. package/cli/commands/auth.ts +5 -5
  20. package/cli/commands/box/checkout-plane.ts +1 -1
  21. package/cli/commands/box/plane-share.ts +2 -2
  22. package/cli/commands/box/rnx-command.ts +5 -5
  23. package/cli/commands/box.ts +38 -38
  24. package/cli/commands/camera.ts +13 -13
  25. package/cli/commands/cleanup.ts +13 -13
  26. package/cli/commands/compat.ts +7 -7
  27. package/cli/commands/config.ts +5 -5
  28. package/cli/commands/control.ts +63 -63
  29. package/cli/commands/cpu-profile.ts +11 -11
  30. package/cli/commands/daemon-mac-app.ts +10 -10
  31. package/cli/commands/daemon.ts +29 -27
  32. package/cli/commands/debug.ts +35 -35
  33. package/cli/commands/desktop.ts +3 -3
  34. package/cli/commands/detox.ts +33 -33
  35. package/cli/commands/device.ts +9 -9
  36. package/cli/commands/diagnose.ts +17 -17
  37. package/cli/commands/do-chain.ts +4 -4
  38. package/cli/commands/electron.ts +9 -9
  39. package/cli/commands/film.ts +9 -9
  40. package/cli/commands/flow.ts +49 -49
  41. package/cli/commands/inspect/core.ts +12 -12
  42. package/cli/commands/inspect/count.ts +1 -1
  43. package/cli/commands/inspect/describe.ts +1 -1
  44. package/cli/commands/inspect/env.ts +2 -2
  45. package/cli/commands/inspect/find.ts +2 -2
  46. package/cli/commands/inspect/get-layout.ts +2 -2
  47. package/cli/commands/inspect/keyboard.ts +1 -1
  48. package/cli/commands/inspect/list.ts +4 -4
  49. package/cli/commands/inspect/memory.ts +1 -1
  50. package/cli/commands/inspect/resolve-target.ts +1 -1
  51. package/cli/commands/inspect/screens.ts +1 -1
  52. package/cli/commands/inspect/shared.ts +1 -1
  53. package/cli/commands/inspect/tree.ts +1 -1
  54. package/cli/commands/inspect/url.ts +1 -1
  55. package/cli/commands/inspect/wait-event.ts +5 -5
  56. package/cli/commands/inspect.ts +82 -82
  57. package/cli/commands/install-cli.ts +16 -16
  58. package/cli/commands/install-desktop.ts +26 -26
  59. package/cli/commands/login.ts +11 -11
  60. package/cli/commands/maestro-generate.ts +10 -10
  61. package/cli/commands/maestro.ts +77 -67
  62. package/cli/commands/mode.ts +4 -4
  63. package/cli/commands/no-bridge-hint.ts +12 -12
  64. package/cli/commands/perf.ts +11 -11
  65. package/cli/commands/permissions.ts +5 -5
  66. package/cli/commands/platform.ts +21 -21
  67. package/cli/commands/preview.ts +5 -5
  68. package/cli/commands/profile.ts +12 -12
  69. package/cli/commands/react.ts +15 -15
  70. package/cli/commands/record.ts +31 -31
  71. package/cli/commands/report-issue.ts +4 -4
  72. package/cli/commands/reset.ts +2 -2
  73. package/cli/commands/runtime.ts +23 -23
  74. package/cli/commands/screenshot-command.ts +2 -2
  75. package/cli/commands/screenshot-layers.ts +5 -5
  76. package/cli/commands/screenshot-mode.ts +7 -7
  77. package/cli/commands/screenshot.ts +24 -24
  78. package/cli/commands/screenshots-capture.ts +13 -13
  79. package/cli/commands/screenshots.ts +6 -6
  80. package/cli/commands/serve.ts +12 -12
  81. package/cli/commands/setup.ts +25 -25
  82. package/cli/commands/skills.ts +30 -23
  83. package/cli/commands/slides.ts +20 -20
  84. package/cli/commands/state.ts +2 -2
  85. package/cli/commands/storage.ts +3 -3
  86. package/cli/commands/telemetry.ts +2 -2
  87. package/cli/commands/test.ts +15 -15
  88. package/cli/commands/three-mode.ts +17 -17
  89. package/cli/commands/timeline.ts +12 -12
  90. package/cli/commands/upgrade.ts +11 -11
  91. package/cli/commands/upload.ts +26 -26
  92. package/cli/commands/version.ts +7 -7
  93. package/cli/commands/what-happened.ts +20 -20
  94. package/cli/current-sim.ts +3 -3
  95. package/cli/desktop-companion.ts +16 -16
  96. package/cli/drivers/electron.ts +4 -4
  97. package/cli/drivers/playwright-sim-host.ts +7 -7
  98. package/cli/drivers/playwright.ts +4 -4
  99. package/cli/drivers/registry.ts +1 -1
  100. package/cli/drivers/types.ts +5 -5
  101. package/cli/flow-export.ts +1 -1
  102. package/cli/flow-file.ts +5 -5
  103. package/cli/flow-session.ts +1 -1
  104. package/cli/help-core.ts +13 -13
  105. package/cli/hints.ts +14 -14
  106. package/cli/inspect-notice-state.ts +1 -1
  107. package/cli/internal-child.ts +2 -2
  108. package/cli/maestro-js.ts +4 -4
  109. package/cli/maestro-report.ts +1 -1
  110. package/cli/main.ts +14 -14
  111. package/cli/outbound-endpoints.ts +30 -30
  112. package/cli/parse-args.ts +7 -7
  113. package/cli/privacy.ts +1 -1
  114. package/cli/recording-access.ts +10 -10
  115. package/cli/resolve-assets.ts +2 -2
  116. package/cli/rnx-in-process.ts +5 -5
  117. package/cli/run-registry.ts +1 -1
  118. package/cli/run-rnx-core.ts +3 -3
  119. package/cli/run-rnx.ts +1 -1
  120. package/cli/runtime-notes.ts +1 -1
  121. package/cli/self-invocation.ts +1 -1
  122. package/cli/send-to-box.ts +1 -1
  123. package/cli/shell-init.ts +40 -40
  124. package/cli/ui.ts +1 -1
  125. package/cli/ws-bridge.ts +22 -22
  126. package/detox/config-loader.ts +1 -1
  127. package/detox/index.ts +28 -28
  128. package/detox/navigation.ts +2 -2
  129. package/dist-lib/agent-daemon-client.cjs +12 -12
  130. package/dist-lib/agent-events.cjs +1 -1
  131. package/dist-lib/agent-identity.cjs +2 -2
  132. package/dist-lib/agent-sessions.cjs +12 -12
  133. package/dist-lib/attached-projects.cjs +4 -4
  134. package/dist-lib/auth/shared-session.cjs +4 -4
  135. package/dist-lib/backend-origin.cjs +1 -1
  136. package/dist-lib/beta.cjs +1 -1
  137. package/dist-lib/beta.mjs +1 -1
  138. package/dist-lib/bridge-constants.cjs +4 -4
  139. package/dist-lib/bridge-contract-input.cjs +1 -1
  140. package/dist-lib/bridge-contract-input.mjs +1 -1
  141. package/dist-lib/bridge-contract.cjs +2 -2
  142. package/dist-lib/bridge-contract.mjs +2 -2
  143. package/dist-lib/capture-contract.cjs +1 -1
  144. package/dist-lib/capture-contract.mjs +1 -1
  145. package/dist-lib/cli-constants.cjs +1 -1
  146. package/dist-lib/cloud-contract.cjs +1 -1
  147. package/dist-lib/cloud-contract.mjs +1 -1
  148. package/dist-lib/cloud-test-args.cjs +1 -1
  149. package/dist-lib/cloud-test-args.mjs +1 -1
  150. package/dist-lib/cloud.cjs +42 -42
  151. package/dist-lib/cloud.mjs +42 -42
  152. package/dist-lib/config.cjs +2 -2
  153. package/dist-lib/detox/index.cjs +29 -29
  154. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  155. package/dist-lib/home-paths.cjs +12 -12
  156. package/dist-lib/host/bridge-host.cjs +72 -71
  157. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  158. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  159. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  160. package/dist-lib/host/replacement-module-handler.cjs +6 -6
  161. package/dist-lib/host/websocket-proxy.cjs +1 -1
  162. package/dist-lib/index.cjs +48 -48
  163. package/dist-lib/jump-to-source-babel.cjs +1 -1
  164. package/dist-lib/jump-to-source-native.cjs +1 -1
  165. package/dist-lib/menu.cjs +5 -5
  166. package/dist-lib/menu.mjs +5 -5
  167. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  168. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  169. package/dist-lib/metro-production-bundle.cjs +1 -1
  170. package/dist-lib/metro-production-bundle.mjs +1 -1
  171. package/dist-lib/metro.cjs +15 -15
  172. package/dist-lib/profiles.cjs +4 -4
  173. package/dist-lib/public-brand.cjs +3 -3
  174. package/dist-lib/react-native-host-modules.cjs +1 -1
  175. package/dist-lib/react-native-host-modules.mjs +1 -1
  176. package/dist-lib/render-mode.cjs +1 -1
  177. package/dist-lib/scripts/dev-server-scanner.cjs +2 -1
  178. package/dist-lib/sdk.cjs +9 -9
  179. package/dist-lib/sdk.mjs +9 -9
  180. package/dist-lib/skills.cjs +416 -415
  181. package/dist-lib/swift-compile.cjs +1 -1
  182. package/dist-lib/swift-compile.mjs +1 -1
  183. package/dist-lib/swift-package.cjs +1 -1
  184. package/dist-lib/swift-package.mjs +1 -1
  185. package/dist-lib/swift-submit.cjs +1 -1
  186. package/dist-lib/swift-submit.mjs +1 -1
  187. package/dist-lib/swift.cjs +1 -1
  188. package/dist-lib/vite.cjs +24 -24
  189. package/package.json +1 -1
  190. package/scripts/dev-server-scanner.ts +4 -3
  191. package/skills/contrast/SKILL.md +75 -75
  192. package/skills/{rnx-debug → peach-debug}/SKILL.md +90 -90
  193. package/skills/{rnx-perf → peach-perf}/SKILL.md +13 -13
  194. package/skills/{rnx-setup → peach-setup}/SKILL.md +60 -60
  195. package/skills/{rnx-test → peach-test}/SKILL.md +44 -44
  196. package/skills/{rnx-visual → peach-visual}/SKILL.md +26 -26
  197. package/src/agent-daemon-client.ts +5 -5
  198. package/src/agent-events.ts +1 -1
  199. package/src/agent-identity.ts +1 -1
  200. package/src/agent-sessions.ts +13 -13
  201. package/src/attached-projects.ts +1 -1
  202. package/src/auth/shared-session.ts +1 -1
  203. package/src/bridge-constants.ts +3 -3
  204. package/src/bridge-contract-input.ts +1 -1
  205. package/src/bridge-contract.ts +3 -3
  206. package/src/cli-version.ts +6 -6
  207. package/src/cloud.ts +40 -40
  208. package/src/config.ts +1 -1
  209. package/src/connect.ts +6 -6
  210. package/src/dev-server-open.ts +8 -8
  211. package/src/disk-cleanup.ts +3 -3
  212. package/src/home-paths.ts +26 -26
  213. package/src/host/agent-host.ts +3 -3
  214. package/src/host/bridge-host.ts +33 -33
  215. package/src/host/fetch-proxy-handler.ts +1 -1
  216. package/src/host/plane-host.ts +2 -2
  217. package/src/host/replacement-module-handler.ts +2 -2
  218. package/src/menu.ts +2 -2
  219. package/src/metro-plugin.ts +7 -7
  220. package/src/metro-production-bundle.ts +2 -2
  221. package/src/native-dev-bundle-url.ts +2 -2
  222. package/src/playwright-host-log.ts +1 -1
  223. package/src/public-brand.ts +2 -2
  224. package/src/react-native-host-modules.ts +1 -1
  225. package/src/rolldown-plugin-swift.ts +3 -3
  226. package/src/runtime-assets.ts +11 -11
  227. package/src/runtime-delivery.ts +6 -6
  228. package/src/screenshots/orchestrate.ts +1 -1
  229. package/src/screenshots/org-deck.ts +1 -1
  230. package/src/screenshots/schema.ts +2 -2
  231. package/src/sim-client.ts +1 -1
  232. package/src/skills/builtin/compat-check.ts +2 -2
  233. package/src/vite-plugin-one.ts +8 -8
  234. package/src/vite-plugin-swift.ts +3 -3
  235. package/src/vite-plugin.ts +6 -19
@@ -1,8 +1,8 @@
1
- // rnx maestro — drop-in replacement for the real `maestro` cli.
1
+ // peach maestro — drop-in replacement for the real `maestro` cli.
2
2
  //
3
3
  // users with an existing `.maestro/` directory can swap `maestro test`
4
- // for `rnx maestro test` and have their flows execute against
5
- // rnx's in-browser engine. the heavy lifting lives in `flow.ts` +
4
+ // for `peach maestro test` and have their flows execute against
5
+ // peach's in-browser engine. the heavy lifting lives in `flow.ts` +
6
6
  // `bridge-flow-runner.ts`; this file just re-maps the maestro argv shape
7
7
  // onto the existing flow runner and handles directory iteration + init.
8
8
 
@@ -43,23 +43,23 @@ const MAESTRO_DIRS = ['.maestro', 'maestro']
43
43
 
44
44
  function printHelp() {
45
45
  console.log(`
46
- rnx maestro — author and run Maestro YAML flows against rnx
46
+ peach maestro — author and run Maestro YAML flows against peach
47
47
 
48
48
  usage:
49
- rnx maestro # discover .maestro/ or maestro/ in cwd, run all
50
- rnx maestro test <flow-or-dir> # mirrors "maestro test"
51
- rnx maestro load <flow> # load flow into runner without running (--dry-run)
52
- rnx maestro test .maestro/ # every *.yaml / *.yml in a directory
53
- rnx maestro generate "<goal>" # generate, run, and upload a Maestro flow
54
- rnx maestro start|keep|end # author a flow from live CLI actions
55
- rnx maestro validate <flow> # validate a Maestro YAML file
56
- rnx maestro init # scaffold .maestro/login.yaml
57
- rnx maestro --list-compat # print supported/unsupported verbs
49
+ peach maestro # discover .maestro/ or maestro/ in cwd, run all
50
+ peach maestro test <flow-or-dir> # mirrors "maestro test"
51
+ peach maestro load <flow> # load flow into runner without running (--dry-run)
52
+ peach maestro test .maestro/ # every *.yaml / *.yml in a directory
53
+ peach maestro generate "<goal>" # generate, run, and upload a Maestro flow
54
+ peach maestro start|keep|end # author a flow from live CLI actions
55
+ peach maestro validate <flow> # validate a Maestro YAML file
56
+ peach maestro init # scaffold .maestro/login.yaml
57
+ peach maestro --list-compat # print supported/unsupported verbs
58
58
 
59
59
  options:
60
60
  --dry-run, --no-run load flow into runner idle without auto-running
61
61
  --env KEY=VALUE set env vars for \${KEY} interpolation (repeatable)
62
- --continuous accepted for maestro cli compat; rnx runs the flow once
62
+ --continuous accepted for maestro cli compat; peach runs the flow once
63
63
  --include-tags <a,b> run only flows carrying one of these tags (comma-
64
64
  separated; CLI wins over config.yaml includeTags)
65
65
  --exclude-tags <a,b> skip flows carrying any of these tags
@@ -72,16 +72,16 @@ options:
72
72
  per-flow screenshots, commands.json, and logs/maestro.log
73
73
  (config key testOutputDir:; CLI wins over config)
74
74
  --debug-output <dir> write a session maestro.log there
75
- --flatten-debug-output accepted; rnx output is already flat
75
+ --flatten-debug-output accepted; peach output is already flat
76
76
  --test-suite-name <n> junit testsuite name (default "Test Suite")
77
- --platform ios accepted; any other platform is refused (rnx is iOS-only)
78
- (-p stays the rnx bridge-port short)
79
- --no-ansi accepted; rnx output is already plain text
80
- --udid <id> warned; rnx manages its own sim (pin one with --sim)
81
- -s, --shards <n> warned; rnx runs the full selection on one sim
77
+ --platform ios accepted; any other platform is refused (peach is iOS-only)
78
+ (-p stays the peach bridge-port short)
79
+ --no-ansi accepted; peach output is already plain text
80
+ --udid <id> warned; peach manages its own sim (pin one with --sim)
81
+ -s, --shards <n> warned; peach runs the full selection on one sim
82
82
  --shard-all, --shard-split <spec>
83
- warned; rnx runs the full selection on one sim
84
- -c warned; --continuous runs once under rnx
83
+ warned; peach runs the full selection on one sim
84
+ -c warned; --continuous runs once under peach
85
85
  --device <model> override the flow frontmatter device for this run
86
86
  --new force a fresh browser window for this run
87
87
  --headed force a fresh, VISIBLE window (implies --new,
@@ -95,19 +95,19 @@ options:
95
95
  --slow <ms> delay between steps for natural pacing
96
96
 
97
97
  examples:
98
- rnx maestro test .maestro/login.yaml
99
- rnx maestro test .maestro/
100
- rnx maestro generate "log in and verify the welcome screen"
101
- rnx maestro start
102
- rnx maestro end --output .maestro/login.yaml --validate
103
- rnx maestro --env USERNAME=alice test .maestro/login.yaml
104
- rnx maestro init
98
+ peach maestro test .maestro/login.yaml
99
+ peach maestro test .maestro/
100
+ peach maestro generate "log in and verify the welcome screen"
101
+ peach maestro start
102
+ peach maestro end --output .maestro/login.yaml --validate
103
+ peach maestro --env USERNAME=alice test .maestro/login.yaml
104
+ peach maestro init
105
105
  `)
106
106
  }
107
107
 
108
108
  function printCompatMatrix() {
109
109
  console.log(`
110
- rnx maestro — compatibility matrix
110
+ peach maestro — compatibility matrix
111
111
 
112
112
  supported verbs:
113
113
  launchApp (including arguments), stopApp, clearState, clearKeychain (warn-only),
@@ -135,7 +135,7 @@ cli flags (maestro test parity):
135
135
  CLI wins over config.yaml), --config <path>, --format junit with
136
136
  --output (default report.xml; flow name:/properties: shape the
137
137
  testcase), --test-output-dir (config key testOutputDir:, CLI wins),
138
- --debug-output, --platform ios (others refused), --no-ansi (rnx
138
+ --debug-output, --platform ios (others refused), --no-ansi (peach
139
139
  output is already plain), -d for --device, -e for --env.
140
140
  --continuous warns and runs once; --format html warns and runs
141
141
  without a report.
@@ -147,14 +147,14 @@ launch behavior:
147
147
  openLink: replaces the guest, then delivers the URL to the new tenant.
148
148
 
149
149
  partial:
150
- clearKeychain — warn-only, rnx has no keychain surface.
151
- when.platform — rnx reports iOS for this runner.
150
+ clearKeychain — warn-only, peach has no keychain surface.
151
+ when.platform — peach reports iOS for this runner.
152
152
  openLink: app routing works; no OS-level Safari fallback.
153
- launchApp.resetRuntime — rnx-only extension for recorded benchmarks:
153
+ launchApp.resetRuntime — peach-only extension for recorded benchmarks:
154
154
  keep tenant storage/auth, but soft-reload the guest app inside launchApp.
155
- takeScreenshot — maestro string form works unchanged; rnx also accepts
155
+ takeScreenshot — maestro string form works unchanged; peach also accepts
156
156
  { path, withFrame } for framed export.
157
- env — rnx seeds the JS env from the full shell environment, not just
157
+ env — peach seeds the JS env from the full shell environment, not just
158
158
  MAESTRO_* (so \${SOOTSIM_*} credentials resolve); a bare \${NAME} that is
159
159
  undefined fails the step loudly instead of typing "undefined".
160
160
 
@@ -195,7 +195,7 @@ export function applyEnvFlags(args: string[]): string[] {
195
195
  }
196
196
 
197
197
  // maestro-cli flags this command consumes itself, accepted so an existing
198
- // script can swap `maestro test` for `rnx maestro test` unedited. each one
198
+ // script can swap `maestro test` for `peach maestro test` unedited. each one
199
199
  // either takes effect below or says out loud that it does not: an option
200
200
  // that is quietly dropped is how a run reports success while doing something
201
201
  // other than what was asked. `--origin` is consumed here because only this
@@ -303,13 +303,13 @@ export function extractMaestroCompatFlags(args: string[]): {
303
303
  break
304
304
  case '--platform':
305
305
  if (value.toLowerCase() !== 'ios') {
306
- throw new Error(`rnx emulates iOS only; --platform ${value} is not supported`)
306
+ throw new Error(`peach emulates iOS only; --platform ${value} is not supported`)
307
307
  }
308
308
  compat.platform = value
309
309
  break
310
310
  case '--udid':
311
311
  console.warn(
312
- ' warn: --udid selects a Maestro simulator; rnx manages its own sim — pin one with --sim instead',
312
+ ' warn: --udid selects a Maestro simulator; peach manages its own sim — pin one with --sim instead',
313
313
  )
314
314
  break
315
315
  case '--test-suite-name':
@@ -319,15 +319,15 @@ export function extractMaestroCompatFlags(args: string[]): {
319
319
  case '--shard-all':
320
320
  case '--shard-split':
321
321
  console.warn(
322
- ` warn: ${head} shards across Maestro devices; rnx runs the full selection on one sim`,
322
+ ` warn: ${head} shards across Maestro devices; peach runs the full selection on one sim`,
323
323
  )
324
324
  break
325
325
  case '--api-key':
326
326
  case '--api-url':
327
- console.warn(` warn: ${head} is Maestro beta AI analysis; rnx ignores it`)
327
+ console.warn(` warn: ${head} is Maestro beta AI analysis; peach ignores it`)
328
328
  break
329
329
  case '--screen-size':
330
- console.warn(' warn: --screen-size is web-only; rnx ignores it')
330
+ console.warn(' warn: --screen-size is web-only; peach ignores it')
331
331
  break
332
332
  }
333
333
  continue
@@ -339,30 +339,30 @@ export function extractMaestroCompatFlags(args: string[]): {
339
339
  continue
340
340
  }
341
341
  if (a === '-d') {
342
- // maestro's short form for --device. rnx's device flag names a device
342
+ // maestro's short form for --device. peach's device flag names a device
343
343
  // model, and the flow runner reads it under the long spelling only.
344
344
  rest.push('--device')
345
345
  continue
346
346
  }
347
347
  if (a === '--no-ansi' || a === '--no-color') {
348
- // trivially satisfied: rnx prints no ANSI escapes anywhere on this path.
348
+ // trivially satisfied: peach prints no ANSI escapes anywhere on this path.
349
349
  continue
350
350
  }
351
351
  if (a === '--ansi' || a === '--color') {
352
- console.warn(' warn: rnx prints no ANSI escapes; colored output is unavailable')
352
+ console.warn(' warn: peach prints no ANSI escapes; colored output is unavailable')
353
353
  continue
354
354
  }
355
355
  if (a === '--continuous' || a === '-c') {
356
- console.warn(' warn: --continuous is not implemented in rnx — running once')
356
+ console.warn(' warn: --continuous is not implemented in peach — running once')
357
357
  continue
358
358
  }
359
359
  if (a === '--flatten-debug-output') {
360
- // rnx writes one <dir>/maestro.log with no per-run subfolders or
360
+ // peach writes one <dir>/maestro.log with no per-run subfolders or
361
361
  // timestamps, so the maestro layout flag is already satisfied.
362
362
  continue
363
363
  }
364
364
  if (a === '--analyze') {
365
- console.warn(' warn: --analyze is Maestro beta AI analysis; rnx ignores it')
365
+ console.warn(' warn: --analyze is Maestro beta AI analysis; peach ignores it')
366
366
  continue
367
367
  }
368
368
  if (a === '-s') {
@@ -370,18 +370,18 @@ export function extractMaestroCompatFlags(args: string[]): {
370
370
  if (!count || count.startsWith('-')) throw new Error('-s expects a value')
371
371
  i += 1
372
372
  console.warn(
373
- ' warn: -s shards across Maestro devices; rnx runs the full selection on one sim',
373
+ ' warn: -s shards across Maestro devices; peach runs the full selection on one sim',
374
374
  )
375
375
  continue
376
376
  }
377
377
  if (head === '-p') {
378
- // -p is the rnx bridge-port short, not maestro's --platform short. a
378
+ // -p is the peach bridge-port short, not maestro's --platform short. a
379
379
  // non-numeric value is a pasted maestro command line; fail loud with
380
380
  // the mapping instead of pinning the bridge to a NaN port.
381
381
  const value = eq > 0 ? a.slice(eq + 1) : args[i + 1]
382
382
  if (value !== undefined && !value.startsWith('-') && !/^\d+$/.test(value)) {
383
383
  throw new Error(
384
- `-p is the rnx bridge-port short; use --platform for the Maestro platform (got ${JSON.stringify(value)})`,
384
+ `-p is the peach bridge-port short; use --platform for the Maestro platform (got ${JSON.stringify(value)})`,
385
385
  )
386
386
  }
387
387
  rest.push(a)
@@ -393,11 +393,11 @@ export function extractMaestroCompatFlags(args: string[]): {
393
393
  compat.format !== null &&
394
394
  !['junit', 'html', 'html-detailed', 'noop'].includes(compat.format)
395
395
  ) {
396
- throw new Error(`unsupported --format: ${compat.format} (rnx writes junit reports)`)
396
+ throw new Error(`unsupported --format: ${compat.format} (peach writes junit reports)`)
397
397
  }
398
398
  if (compat.format === 'html' || compat.format === 'html-detailed') {
399
399
  console.warn(
400
- ' warn: --format html is not implemented in rnx — running without a report',
400
+ ' warn: --format html is not implemented in peach — running without a report',
401
401
  )
402
402
  }
403
403
  return { rest, compat }
@@ -560,8 +560,8 @@ async function runInit(cwd: string): Promise<number> {
560
560
  console.error(` error: ${outPath} already exists`)
561
561
  return 1
562
562
  }
563
- const starter = `# rnx maestro starter flow — drop-in compatible with the maestro cli.
564
- # run: rnx maestro test .maestro/login.yaml
563
+ const starter = `# peach maestro starter flow — drop-in compatible with the maestro cli.
564
+ # run: peach maestro test .maestro/login.yaml
565
565
  appId: com.example.app
566
566
  ---
567
567
  - launchApp
@@ -576,7 +576,7 @@ appId: com.example.app
576
576
  `
577
577
  fs.writeFileSync(outPath, starter, 'utf8')
578
578
  console.log(` + wrote ${outPath}`)
579
- console.log(` next: rnx maestro test .maestro/login.yaml`)
579
+ console.log(` next: peach maestro test .maestro/login.yaml`)
580
580
  return 0
581
581
  }
582
582
 
@@ -651,7 +651,7 @@ export async function runMaestro(
651
651
  }
652
652
  if (compat.format === 'html' || compat.format === 'html-detailed') {
653
653
  console.warn(
654
- ` warn: --format ${compat.format} reports are not implemented in rnx — running without writing a report`,
654
+ ` warn: --format ${compat.format} reports are not implemented in peach — running without writing a report`,
655
655
  )
656
656
  }
657
657
  if (compat.output && compat.format !== 'junit') {
@@ -663,7 +663,7 @@ export async function runMaestro(
663
663
  let forwardArgs: string[]
664
664
 
665
665
  if (sub === 'test') {
666
- // `rnx maestro test <flow-or-dir> [flags...]`. the flow path is the first
666
+ // `peach maestro test <flow-or-dir> [flags...]`. the flow path is the first
667
667
  // token that is neither a flag nor the value of one — without the second
668
668
  // half, `test --sim a2 login.yaml` takes `a2` as the flow file. remove it
669
669
  // by index, since a path can equal a flag value elsewhere in the argv.
@@ -677,7 +677,7 @@ export async function runMaestro(
677
677
  forwardArgs = rest.filter((_, i) => i !== positionalIndex)
678
678
  } else if (compat.configPath) {
679
679
  // no positional with an explicit workspace config: run the directory
680
- // the config lives in, like `rnx test --config` does.
680
+ // the config lives in, like `peach test --config` does.
681
681
  target = path.resolve(cwd, path.dirname(compat.configPath))
682
682
  forwardArgs = rest
683
683
  } else {
@@ -685,7 +685,7 @@ export async function runMaestro(
685
685
  forwardArgs = rest
686
686
  }
687
687
  } else if (sub && !looksLikeFlag(sub)) {
688
- // `rnx maestro <flow-or-dir>` — tolerate the shorthand.
688
+ // `peach maestro <flow-or-dir>` — tolerate the shorthand.
689
689
  target = path.resolve(cwd, sub)
690
690
  forwardArgs = remaining.slice(1)
691
691
  } else {
@@ -703,7 +703,7 @@ export async function runMaestro(
703
703
  for (const problem of unexpected) {
704
704
  console.error(` error: ${problem.message}`)
705
705
  }
706
- console.error('\n run `rnx maestro --help` for the flags this command accepts')
706
+ console.error('\n run `peach maestro --help` for the flags this command accepts')
707
707
  return 1
708
708
  }
709
709
 
@@ -711,8 +711,8 @@ export async function runMaestro(
711
711
  console.error(`
712
712
  error: no maestro flows found.
713
713
  expected one of: ${MAESTRO_DIRS.map((d) => `./${d}/`).join(', ')}
714
- or pass a flow explicitly: rnx maestro test path/to/flow.yaml
715
- or scaffold a starter flow: rnx maestro init
714
+ or pass a flow explicitly: peach maestro test path/to/flow.yaml
715
+ or scaffold a starter flow: peach maestro init
716
716
  `)
717
717
  return 1
718
718
  }
@@ -751,7 +751,7 @@ export async function runMaestro(
751
751
  }
752
752
 
753
753
  // maestro's priority rule: CLI flag, then config.yaml, then the default
754
- // (which for rnx is no test-output routing at all). a config-relative dir
754
+ // (which for peach is no test-output routing at all). a config-relative dir
755
755
  // resolves against the config file, a CLI dir against the invocation cwd.
756
756
  const testOutputRoot = compat.testOutputDir
757
757
  ? path.resolve(cwd, compat.testOutputDir)
@@ -760,7 +760,7 @@ export async function runMaestro(
760
760
  : null
761
761
 
762
762
  console.log(`
763
- rnx maestro — ${files.length} flow${files.length === 1 ? '' : 's'}
763
+ peach maestro — ${files.length} flow${files.length === 1 ? '' : 's'}
764
764
  root: ${path.relative(cwd, target) || '.'}
765
765
  `)
766
766
 
@@ -815,7 +815,7 @@ export async function runMaestro(
815
815
  // one. sending it on as `--url` made it an app target instead, which left
816
816
  // the playback bridge on whichever world resolveBridgeWorld picks by
817
817
  // default (a live Vite dev shell selected from the development registry).
818
- // so `rnx --port <installed daemon> maestro …` silently ran the flow
818
+ // so `peach --port <installed daemon> maestro …` silently ran the flow
819
819
  // against the dev engine, then failed trying to resolve a bundle at the
820
820
  // bridge port. an explicit command-level `--port` still wins, since
821
821
  // parseBridgeCliArgs takes the last occurrence.
@@ -910,7 +910,17 @@ export async function runMaestro(
910
910
  })
911
911
  if (run) {
912
912
  console.log(` run: ${run.id}${run.traceUrl ? ` · replay: ${run.traceUrl}` : ''}`)
913
- } else if (process.env.RNX_REQUIRE_REGISTRATION === 'true') {
913
+ try {
914
+ fs.writeFileSync(
915
+ path.join(cwd, 'test-result.json'),
916
+ JSON.stringify({
917
+ runId: run.id,
918
+ previewUrl: run.previewUrl,
919
+ traceUrl: run.traceUrl,
920
+ }),
921
+ )
922
+ } catch {}
923
+ } else if (process.env.PEACH_REQUIRE_REGISTRATION === 'true') {
914
924
  console.error(' error: required hosted run registration failed')
915
925
  if (exit === 0) exit = 1
916
926
  if (worstExit === 0) worstExit = 1
@@ -28,12 +28,12 @@ function withoutSubcommand(args: string[], index: number): string[] {
28
28
 
29
29
  function printHelp(): void {
30
30
  console.log(`
31
- rnx mode — toggle live display modes
31
+ peach mode — toggle live display modes
32
32
 
33
33
  usage:
34
- rnx mode screenshot [on|off|toggle]
35
- rnx mode three [on|off|toggle]
36
- rnx mode three configure [options]
34
+ peach mode screenshot [on|off|toggle]
35
+ peach mode three [on|off|toggle]
36
+ peach mode three configure [options]
37
37
  `)
38
38
  }
39
39
 
@@ -4,39 +4,39 @@ import { findDesktopCompanion } from '../desktop-companion'
4
4
  import type { BridgeSimInfo } from '../ws-bridge'
5
5
 
6
6
  export function printMissingCompanionHint() {
7
- console.error(' no rnx desktop companion found.')
7
+ console.error(' no peach desktop companion found.')
8
8
  console.error('')
9
9
  console.error(' install the desktop app:')
10
- console.error(' rnx desktop install')
10
+ console.error(' peach desktop install')
11
11
  console.error('')
12
12
  console.error(' or install the recommended background service:')
13
- console.error(' rnx daemon install')
13
+ console.error(' peach daemon install')
14
14
  console.error('')
15
15
  }
16
16
 
17
17
  export function printMissingBridgeHint(port: number) {
18
18
  const companion = findDesktopCompanion()
19
- console.log(` note: no rnx bridge detected on port ${port}`)
19
+ console.log(` note: no peach bridge detected on port ${port}`)
20
20
  if (companion) {
21
21
  console.log(` launch the installed companion with:`)
22
- console.log(` rnx desktop`)
22
+ console.log(` peach desktop`)
23
23
  return
24
24
  }
25
25
  console.log('')
26
- console.log(' run `rnx daemon install` to enable the faster background service,')
27
- console.log(' or run `rnx serve` in another shell for a foreground bridge.')
26
+ console.log(' run `peach daemon install` to enable the faster background service,')
27
+ console.log(' or run `peach serve` in another shell for a foreground bridge.')
28
28
  }
29
29
 
30
30
  export function printMissingSimHint(port: number) {
31
31
  console.error('')
32
- console.error(` no sim is connected to the rnx bridge on port ${port}.`)
32
+ console.error(` no sim is connected to the peach bridge on port ${port}.`)
33
33
  console.error('')
34
- console.error(' start your app dev server, then open it in rnx:')
34
+ console.error(' start your app dev server, then open it in peach:')
35
35
  console.error(' npx expo start --localhost --port 8081')
36
- console.error(' rnx open 8081')
36
+ console.error(' peach open 8081')
37
37
  console.error('')
38
38
  console.error(' then inspect the live app:')
39
- console.error(' rnx describe')
39
+ console.error(' peach describe')
40
40
  }
41
41
 
42
42
  // printed when a command targeted a specific `--sim <id>` that the bridge
@@ -76,5 +76,5 @@ export async function printUnknownSimHint(
76
76
  console.error(` ${sim.id} (${flags})`)
77
77
  }
78
78
  console.error('')
79
- console.error(' pass a valid --sim id, or run `rnx list` to see all sessions.')
79
+ console.error(' pass a valid --sim id, or run `peach list` to see all sessions.')
80
80
  }
@@ -28,22 +28,22 @@ function withoutSubcommand(args: string[], index: number): string[] {
28
28
 
29
29
  function printHelp(): void {
30
30
  console.log(`
31
- rnx perf — performance profiling tools
31
+ peach perf — performance profiling tools
32
32
 
33
33
  usage:
34
- rnx perf cpu [options]
35
- rnx perf react <subcommand> [options]
36
- rnx perf shell <start|stop|transition> [options]
37
- rnx perf scroll <start|stop> [options]
34
+ peach perf cpu [options]
35
+ peach perf react <subcommand> [options]
36
+ peach perf shell <start|stop|transition> [options]
37
+ peach perf scroll <start|stop> [options]
38
38
 
39
39
  examples:
40
- rnx perf cpu --duration 5 --output /tmp/trace.cpuprofile
40
+ peach perf cpu --duration 5 --output /tmp/trace.cpuprofile
41
41
  # writes page + every worker profile and a role-labelled manifest
42
- rnx perf react summary --limit 10
43
- rnx perf shell start
44
- rnx perf shell stop --json
45
- rnx perf scroll start
46
- rnx perf scroll stop --json
42
+ peach perf react summary --limit 10
43
+ peach perf shell start
44
+ peach perf shell stop --json
45
+ peach perf scroll start
46
+ peach perf scroll stop --json
47
47
  `)
48
48
  }
49
49
 
@@ -51,13 +51,13 @@ const KINDS: readonly SystemPermissionKind[] = [
51
51
 
52
52
  function printHelp(): void {
53
53
  console.log(`
54
- rnx permissions — inspect and change simulated operating-system permissions
54
+ peach permissions — inspect and change simulated operating-system permissions
55
55
 
56
56
  usage:
57
- rnx permissions list [--json]
58
- rnx permissions get <app-id> [--json]
59
- rnx permissions set <app-id> <kind> <status> [--once] [--accuracy full|reduced] [--json]
60
- rnx permissions reset <app-id> [kind] [--json]
57
+ peach permissions list [--json]
58
+ peach permissions get <app-id> [--json]
59
+ peach permissions set <app-id> <kind> <status> [--once] [--accuracy full|reduced] [--json]
60
+ peach permissions reset <app-id> [kind] [--json]
61
61
  `)
62
62
  }
63
63
 
@@ -1,7 +1,7 @@
1
- // `rnx ios` and `rnx android` — start a simulator on that platform.
1
+ // `peach ios` and `peach android` — start a simulator on that platform.
2
2
  //
3
3
  // the platform picks the device; the command context picks where the sim runs
4
- // (this machine, a local box, or the `rnx remote` namespace). this file resolves
4
+ // (this machine, a local box, or the `peach remote` namespace). this file resolves
5
5
  // the device and hands the rest to the normal open path.
6
6
 
7
7
  import { createHash } from 'node:crypto'
@@ -49,7 +49,7 @@ function remoteInputFromArgs(
49
49
  }
50
50
  if (REMOTE_VALUE_FLAGS.has(arg)) {
51
51
  const value = args[++index] ?? null
52
- if (!value) throw new Error(`rnx remote ${platform} ${arg} requires a value`)
52
+ if (!value) throw new Error(`peach remote ${platform} ${arg} requires a value`)
53
53
  if (arg === '--name') name = value
54
54
  continue
55
55
  }
@@ -57,7 +57,7 @@ function remoteInputFromArgs(
57
57
  if (assigned && REMOTE_VALUE_FLAGS.has(assigned[1] ?? '')) {
58
58
  const value = assigned[2] ?? ''
59
59
  if (!value)
60
- throw new Error(`rnx remote ${platform} ${assigned[1]} requires a value`)
60
+ throw new Error(`peach remote ${platform} ${assigned[1]} requires a value`)
61
61
  if (assigned[1] === '--name') name = value
62
62
  continue
63
63
  }
@@ -70,23 +70,23 @@ function remoteInputFromArgs(
70
70
  arg.startsWith('--tab=')
71
71
  ) {
72
72
  throw new Error(
73
- `rnx remote ${platform} creates a new simulator and cannot target --sim`,
73
+ `peach remote ${platform} creates a new simulator and cannot target --sim`,
74
74
  )
75
75
  }
76
76
  if (arg.startsWith('-')) {
77
- throw new Error(`rnx remote ${platform} does not support ${arg}`)
77
+ throw new Error(`peach remote ${platform} does not support ${arg}`)
78
78
  }
79
79
  positional.push(arg)
80
80
  }
81
81
  if (positional.length !== 1 || !positional[0]) {
82
82
  throw new Error(
83
- `usage: rnx remote ${platform} <local bundle.js|https://bundle-url> [--device <model>] [--reuse|--new]`,
83
+ `usage: peach remote ${platform} <local bundle.js|https://bundle-url> [--device <model>] [--reuse|--new]`,
84
84
  )
85
85
  }
86
86
  const reuse = args.includes('--reuse')
87
87
  const fresh = args.includes('--new')
88
88
  if (reuse && fresh) {
89
- throw new Error(`rnx remote ${platform} cannot combine --reuse and --new`)
89
+ throw new Error(`peach remote ${platform} cannot combine --reuse and --new`)
90
90
  }
91
91
  return { bundlePath: positional[0], name, reuse, fresh }
92
92
  }
@@ -105,7 +105,7 @@ function boxNameForBundle(bundlePath: string): string {
105
105
  .toLowerCase()
106
106
  .replace(/[^a-z0-9]+/g, '-')
107
107
  .replace(/^-+|-+$/g, '')
108
- if (!name) throw new Error(`rnx remote could not name a box after ${bundlePath}`)
108
+ if (!name) throw new Error(`peach remote could not name a box after ${bundlePath}`)
109
109
  return name
110
110
  }
111
111
 
@@ -143,7 +143,7 @@ export async function runPlatformCommand(
143
143
  selectedDevice = explicitDevice
144
144
  } else {
145
145
  // keep the user's own device when it already belongs to the platform they
146
- // asked for, so `rnx ios` after `rnx device set iphone-16` does not
146
+ // asked for, so `peach ios` after `peach device set iphone-16` does not
147
147
  // silently snap back to the default model.
148
148
  const current = settingsStore.get('deviceModel')
149
149
  if (getRuntimePlatform(current) !== platform) {
@@ -231,7 +231,7 @@ const REMOTE_COMMANDS_HELP =
231
231
  ' commands: describe, find, get tree|node|count|memory, wait ready|selector, do, reset, logs, state, screenshot'
232
232
 
233
233
  /**
234
- * `rnx remote ios|android <bundle>` on the one customer plane: one typed
234
+ * `peach remote ios|android <bundle>` on the one customer plane: one typed
235
235
  * create through the instance API for both platforms, and a reattach to the
236
236
  * shell's own simulator when it already runs this bundle. the box stays the
237
237
  * host behind the API and is never created or addressed here.
@@ -352,9 +352,9 @@ async function runRemoteCreate(
352
352
  }
353
353
 
354
354
  /**
355
- * `rnx ios --remote` and `rnx android --remote` — the app runs in a micro box.
355
+ * `peach ios --remote` and `peach android --remote` — the app runs in a micro box.
356
356
  *
357
- * the bundle is prepared by the box plane's own producer, the one `rnx box
357
+ * the bundle is prepared by the box plane's own producer, the one `peach box
358
358
  * create --bundle` uses: assets embedded, nothing minified and no module
359
359
  * identity rewritten. the nano producer's artifact is built for the nano
360
360
  * runner, which imports it as a module; a box page evaluates the bytes with
@@ -384,7 +384,7 @@ async function runRemoteBox(
384
384
  publishCloudSessionToShell,
385
385
  readCloudSession,
386
386
  serializeCloudSession,
387
- RNX_CLOUD_SESSION_ENV,
387
+ PEACH_CLOUD_SESSION_ENV,
388
388
  },
389
389
  ] = await Promise.all([
390
390
  import('../cloud-client'),
@@ -447,7 +447,7 @@ async function runRemoteBox(
447
447
  try {
448
448
  publishCloudSessionToShell(null)
449
449
  } catch {
450
- // no shell update channel is required outside an interactive rnx shell
450
+ // no shell update channel is required outside an interactive peach shell
451
451
  }
452
452
  } else if (existingSession) {
453
453
  await closeCloudSession(existingSession)
@@ -482,7 +482,7 @@ async function runRemoteBox(
482
482
  } catch {
483
483
  // shell update fd not configured
484
484
  }
485
- process.env[RNX_CLOUD_SESSION_ENV] = serializeCloudSession(session)
485
+ process.env[PEACH_CLOUD_SESSION_ENV] = serializeCloudSession(session)
486
486
 
487
487
  console.log(` box: ${created.id} (${artifact.bytes.length} bytes)`)
488
488
  console.log(` platform: ${platform}`)
@@ -504,7 +504,7 @@ async function runRemoteBox(
504
504
  return openInBrowser(watchUrl)
505
505
  }
506
506
 
507
- /** `rnx remote list`: the simulators this account runs that `rnx remote` made. */
507
+ /** `peach remote list`: the simulators this account runs that `peach remote` made. */
508
508
  export async function runRemoteList(args: string[]): Promise<number> {
509
509
  try {
510
510
  let json = false
@@ -513,7 +513,7 @@ export async function runRemoteList(args: string[]): Promise<number> {
513
513
  json = true
514
514
  continue
515
515
  }
516
- throw new Error(`usage: rnx remote list [--json]`)
516
+ throw new Error(`usage: peach remote list [--json]`)
517
517
  }
518
518
  const [{ authHeaderOrExit, cloudAccountIdOrExit }, { listRemoteSims }] =
519
519
  await Promise.all([import('../auth'), import('../cloud-client')])
@@ -529,7 +529,7 @@ export async function runRemoteList(args: string[]): Promise<number> {
529
529
  return 0
530
530
  }
531
531
  for (const sim of sims) {
532
- const platformLabel = sim.labels['rnx.platform'] ?? 'unknown'
532
+ const platformLabel = sim.labels['peach.platform'] ?? 'unknown'
533
533
  console.log(
534
534
  ` ${sim.simId} ${sim.status} ${platformLabel} sha256:${sim.artifact.sha256.slice(0, 12)}`,
535
535
  )
@@ -546,7 +546,7 @@ export async function runRemoteList(args: string[]): Promise<number> {
546
546
  }
547
547
  }
548
548
 
549
- /** `rnx remote stop <id>`: delete one remote simulator by id. */
549
+ /** `peach remote stop <id>`: delete one remote simulator by id. */
550
550
  export async function runRemoteStop(args: string[]): Promise<number> {
551
551
  try {
552
552
  const positional = args.filter((arg) => !arg.startsWith('-'))
@@ -555,7 +555,7 @@ export async function runRemoteStop(args: string[]): Promise<number> {
555
555
  positional.length !== 1 ||
556
556
  !positional[0]
557
557
  ) {
558
- throw new Error(`usage: rnx remote stop <sim-id>`)
558
+ throw new Error(`usage: peach remote stop <sim-id>`)
559
559
  }
560
560
  const simId = positional[0]
561
561
  const [