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
@@ -21,10 +21,10 @@ function takeValue(args: string[], flag: string): string | null {
21
21
  export async function runPreview(args: string[]): Promise<number> {
22
22
  if (args.includes('--help') || args.includes('-h')) {
23
23
  console.log(`
24
- rnx preview — publish a prebuilt React Native bundle as a standalone share
24
+ peach preview — publish a prebuilt React Native bundle as a standalone share
25
25
 
26
26
  usage:
27
- rnx preview <bundle.js|https://bundle-url> [--platform ios|android] [--open]
27
+ peach preview <bundle.js|https://bundle-url> [--platform ios|android] [--open]
28
28
 
29
29
  The share contains the immutable build and its automatically discovered Metro assets. It is not a recorded replay.
30
30
  `)
@@ -47,10 +47,10 @@ The share contains the immutable build and its automatically discovered Metro as
47
47
  throw new Error('--platform must be ios or android')
48
48
  }
49
49
  if (input.length !== 1 || input[0]?.startsWith('-')) {
50
- throw new Error('usage: rnx preview <bundle.js|https://bundle-url>')
50
+ throw new Error('usage: peach preview <bundle.js|https://bundle-url>')
51
51
  }
52
52
  const auth = resolveCliAuth()
53
- if (!auth) throw new Error('rnx preview needs `rnx login` or RNX_API_KEY')
53
+ if (!auth) throw new Error('peach preview needs `peach login` or PEACH_API_KEY')
54
54
  const accountId = cloudAccountIdOrExit(auth)
55
55
 
56
56
  const artifact = await producePreviewArtifact(input[0])
@@ -96,7 +96,7 @@ The share contains the immutable build and its automatically discovered Metro as
96
96
  return 0
97
97
  } catch (error) {
98
98
  console.error(
99
- ` rnx preview failed: ${error instanceof Error ? error.message : String(error)}`,
99
+ ` peach preview failed: ${error instanceof Error ? error.message : String(error)}`,
100
100
  )
101
101
  return 1
102
102
  }
@@ -1,4 +1,4 @@
1
- // rnx storage profile — manage isolated app storage profiles.
1
+ // peach storage profile — manage isolated app storage profiles.
2
2
 
3
3
  import {
4
4
  clearProfileStorage,
@@ -15,25 +15,25 @@ interface ProfileOptions {
15
15
 
16
16
  function printHelp() {
17
17
  console.log(`
18
- rnx storage profile — manage isolated storage profiles
18
+ peach storage profile — manage isolated storage profiles
19
19
 
20
20
  usage:
21
- rnx storage profile list
22
- rnx storage profile create <id>
23
- rnx storage profile clear <id>
24
- rnx storage profile delete <id>
21
+ peach storage profile list
22
+ peach storage profile create <id>
23
+ peach storage profile clear <id>
24
+ peach storage profile delete <id>
25
25
 
26
26
  profiles isolate cookies, localStorage, IndexedDB, cache, permissions, and
27
27
  service workers in Electron and Playwright launches. Plain browser-tab launches
28
28
  cannot honor profiles and will fail clearly if a profile is requested.
29
29
 
30
30
  examples:
31
- rnx storage profile list
32
- rnx storage profile create qa
33
- rnx open 8081 --profile qa
34
- rnx open 8081 --profile qa --driver playwright
35
- rnx storage profile clear qa
36
- rnx storage profile delete qa
31
+ peach storage profile list
32
+ peach storage profile create qa
33
+ peach open 8081 --profile qa
34
+ peach open 8081 --profile qa --driver playwright
35
+ peach storage profile clear qa
36
+ peach storage profile delete qa
37
37
  `)
38
38
  }
39
39
 
@@ -36,16 +36,16 @@ interface TreeRow {
36
36
 
37
37
  function printHelp() {
38
38
  console.log(`
39
- rnx perf react — inspect React component render cost in the tenant worker
39
+ peach perf react — inspect React component render cost in the tenant worker
40
40
 
41
41
  usage:
42
- rnx perf react profile start [--include-props] [--max-commits N]
43
- rnx perf react profile stop
44
- rnx perf react summary [--limit 10] [--json]
45
- rnx perf react slow [--limit 5] [--json]
46
- rnx perf react rerenders [--limit 5] [--json]
47
- rnx perf react tree [--depth 3] [--find <name>] [--json]
48
- rnx perf react why <fiber-id> [--json]
42
+ peach perf react profile start [--include-props] [--max-commits N]
43
+ peach perf react profile stop
44
+ peach perf react summary [--limit 10] [--json]
45
+ peach perf react slow [--limit 5] [--json]
46
+ peach perf react rerenders [--limit 5] [--json]
47
+ peach perf react tree [--depth 3] [--find <name>] [--json]
48
+ peach perf react why <fiber-id> [--json]
49
49
 
50
50
  \`react summary\` is the demo-friendly shortcut: it runs both slow and
51
51
  rerenders in one round-trip, prints them as a single table per side,
@@ -53,12 +53,12 @@ and surfaces the duration-zero warning prominently when the bundle is
53
53
  running without React profiler timers.
54
54
 
55
55
  examples:
56
- rnx perf react profile start
57
- rnx do tap-text Inbox
58
- rnx perf react profile stop
59
- rnx perf react summary --limit 10
60
- rnx perf react slow --limit 10
61
- rnx perf react rerenders --json
56
+ peach perf react profile start
57
+ peach do tap-text Inbox
58
+ peach perf react profile stop
59
+ peach perf react summary --limit 10
60
+ peach perf react slow --limit 10
61
+ peach perf react rerenders --json
62
62
  `)
63
63
  }
64
64
 
@@ -332,7 +332,7 @@ export async function runReact(args: string[], opts: ReactOptions): Promise<numb
332
332
  if (first === 'why') {
333
333
  const fiberId = Number(second)
334
334
  if (!Number.isFinite(fiberId) || fiberId <= 0) {
335
- console.error(' usage: rnx perf react why <fiber-id>')
335
+ console.error(' usage: peach perf react why <fiber-id>')
336
336
  return 1
337
337
  }
338
338
  const result = (await callInBridge(
@@ -1,6 +1,6 @@
1
- // rnx record — drives the engine's built-in canvas recorder over
1
+ // peach record — drives the engine's built-in canvas recorder over
2
2
  // the WS bridge. no playwright, no ffmpeg. encoding happens in the
3
- // running rnx page (webm via MediaRecorder, mp4 via WebCodecs, gif
3
+ // running peach page (webm via MediaRecorder, mp4 via WebCodecs, gif
4
4
  // via gifenc, raw png frames via a shared bitmap sampler).
5
5
 
6
6
  import {
@@ -85,7 +85,7 @@ async function evalCaptureStep<T>(
85
85
  ` ${step} stalled — the render host did not finish within ` +
86
86
  `${Math.round(timeoutMs / 1000)}s; it is likely contended or wedged.\n` +
87
87
  ` the capture lock auto-releases, so simply retry the recording.\n` +
88
- ` if it persists, recover the sim with \`rnx close --sim <id>\`.`,
88
+ ` if it persists, recover the sim with \`peach close --sim <id>\`.`,
89
89
  )
90
90
  rnxExit(1)
91
91
  }
@@ -106,7 +106,7 @@ async function evalCaptureStep<T>(
106
106
  ` releasing. the lock self-heals in ~${Math.round(
107
107
  (durationMs + 20_000) / 1000,
108
108
  )}s — retry then, or recover now with\n` +
109
- ` \`rnx close --sim <id>\` and reopen the sim.`,
109
+ ` \`peach close --sim <id>\` and reopen the sim.`,
110
110
  )
111
111
  rnxExit(1)
112
112
  }
@@ -319,7 +319,7 @@ export async function runRecord(args: string[], opts: RecordOptions) {
319
319
  // only the upload-bearing modes touch the cloud, so gate the recording
320
320
  // entitlement here, not on local-file video/gif/png capture (F19).
321
321
  // allowGitHubAuth mirrors preview flow recording: the github pr-preview
322
- // runner authenticates with an installation token, not RNX_API_KEY
322
+ // runner authenticates with an installation token, not PEACH_API_KEY
323
323
  // (zero-secrets design). the bypass only fires when auth.kind ===
324
324
  // 'github' (ci/preview); local paid users have session/
325
325
  // api-key auth and still go through the billing entitlement check.
@@ -375,7 +375,7 @@ export async function runRecord(args: string[], opts: RecordOptions) {
375
375
 
376
376
  if (format === 'png') {
377
377
  const count = framesCount ?? 10
378
- const outDir = resolveRecordingOutput(outputArg, `rnx-frames-${stamp()}`)
378
+ const outDir = resolveRecordingOutput(outputArg, `peach-frames-${stamp()}`)
379
379
  // --frames writes one png PER frame, so --output names a directory, not
380
380
  // a file. a caller passing `--output shot.png` gets a directory literally
381
381
  // named `shot.png` — flag the likely mistake rather than silently doing it.
@@ -445,7 +445,7 @@ export async function runRecord(args: string[], opts: RecordOptions) {
445
445
 
446
446
  if (format === 'gif') {
447
447
  const count = framesCount ?? Math.max(10, Math.round((durationSec * fps) / 3))
448
- const out = resolveRecordingOutput(outputArg, `rnx-${stamp()}.gif`)
448
+ const out = resolveRecordingOutput(outputArg, `peach-${stamp()}.gif`)
449
449
  mkdirSync(dirname(out), { recursive: true })
450
450
  console.log(` encoding gif: ${count} frames over ${durationSec}s → ${out}`)
451
451
  const result: { data: string; size: number } | null = await evalCaptureStep(
@@ -466,7 +466,7 @@ export async function runRecord(args: string[], opts: RecordOptions) {
466
466
  }
467
467
 
468
468
  // video path: webm or mp4
469
- const out = resolveRecordingOutput(outputArg, `rnx-${stamp()}.${format}`)
469
+ const out = resolveRecordingOutput(outputArg, `peach-${stamp()}.${format}`)
470
470
  mkdirSync(dirname(out), { recursive: true })
471
471
 
472
472
  const startOpts: {
@@ -501,7 +501,7 @@ export async function runRecord(args: string[], opts: RecordOptions) {
501
501
  console.error(
502
502
  ' a prior recording was abandoned and its capture is still\n' +
503
503
  ' releasing. retry in ~20s, or recover now with\n' +
504
- ' `rnx close --sim <id>` then reopen the sim.',
504
+ ' `peach close --sim <id>` then reopen the sim.',
505
505
  )
506
506
  }
507
507
  rnxExit(1)
@@ -562,7 +562,7 @@ async function probeSim(bridge: WsBridge, code: string): Promise<boolean> {
562
562
  if (/^command timed out after \d+s$/.test(msg)) {
563
563
  console.error(
564
564
  ' sim did not respond — it is connected to the bridge but has not\n' +
565
- ' loaded an app (or its page is unresponsive). run `rnx list`\n' +
565
+ ' loaded an app (or its page is unresponsive). run `peach list`\n' +
566
566
  ' and target a sim with a loaded app via --sim <id>.',
567
567
  )
568
568
  rnxExit(1)
@@ -575,7 +575,7 @@ async function assertRecorderAvailable(bridge: WsBridge) {
575
575
  const ok = await probeSim(bridge, 'typeof window.__sootsimRecorder !== "undefined"')
576
576
  if (!ok) {
577
577
  console.error(
578
- ' window.__sootsimRecorder missing — is rnx engine running in this sim?',
578
+ ' window.__sootsimRecorder missing — is peach engine running in this sim?',
579
579
  )
580
580
  rnxExit(1)
581
581
  }
@@ -583,7 +583,7 @@ async function assertRecorderAvailable(bridge: WsBridge) {
583
583
 
584
584
  // frame-capturing recordings (video / gif / png / combined) drive their
585
585
  // encoder off requestAnimationFrame and throttled timers, which browsers
586
- // clamp to ~1fps when the rnx tab is hidden (backgrounded, or its chrome
586
+ // clamp to ~1fps when the peach tab is hidden (backgrounded, or its chrome
587
587
  // window minimized). that silently produced a frozen-looking file and is
588
588
  // exactly why agents started pre-checking `document.hidden` by hand. refuse
589
589
  // up front with an actionable message instead. checkSimHealth already emits
@@ -594,7 +594,7 @@ async function assertTabVisibleForCapture(bridge: WsBridge) {
594
594
  const { hidden } = await checkSimHealth(bridge)
595
595
  if (hidden) {
596
596
  console.error(
597
- ' refusing to record: the rnx tab is hidden, so frame capture\n' +
597
+ ' refusing to record: the peach tab is hidden, so frame capture\n' +
598
598
  ' would be throttled to ~1fps and produce a frozen-looking file.\n' +
599
599
  ' bring the chrome window to the foreground (un-minimize / switch to\n' +
600
600
  ' its tab) or run the recording in headless playwright, then retry.',
@@ -658,10 +658,10 @@ function stamp(): string {
658
658
 
659
659
  // default home for recordings when --output is omitted. writing into the
660
660
  // process cwd litters whatever directory the CLI was invoked from (the repo
661
- // root, most often) with rnx-*.mp4 / rnx-frames-*/ — F11-2. an
661
+ // root, most often) with peach-*.mp4 / peach-frames-*/ — F11-2. an
662
662
  // explicit --output still resolves relative to cwd as the caller expects.
663
663
  function recordingsDir(): string {
664
- const dir = join(homedir(), '.rnx', 'recordings')
664
+ const dir = join(homedir(), '.peach', 'recordings')
665
665
  mkdirSync(dir, { recursive: true })
666
666
  return dir
667
667
  }
@@ -698,7 +698,7 @@ function parseMode(raw: string | undefined): RecordMode {
698
698
  }
699
699
 
700
700
  function recordingStatePath(): string {
701
- return join(tmpdir(), `rnx-recording-${getCliIdentityKey()}.json`)
701
+ return join(tmpdir(), `peach-recording-${getCliIdentityKey()}.json`)
702
702
  }
703
703
 
704
704
  function readRecordingState(): RecordingState | null {
@@ -744,7 +744,7 @@ async function recordStart(args: string[], opts: RecordOptions) {
744
744
  const existing = readRecordingState()
745
745
  if (existing) {
746
746
  console.error(
747
- ` recording already in progress (started ${existing.startedAt}, sim ${existing.simId ?? '?'}). run \`rnx record stop\` first, or \`rnx record cancel\` to discard.`,
747
+ ` recording already in progress (started ${existing.startedAt}, sim ${existing.simId ?? '?'}). run \`peach record stop\` first, or \`peach record cancel\` to discard.`,
748
748
  )
749
749
  rnxExit(1)
750
750
  }
@@ -772,7 +772,7 @@ async function recordStart(args: string[], opts: RecordOptions) {
772
772
  const format = formatArg === 'mp4' ? 'mp4' : 'webm'
773
773
  if (formatArg && format !== formatArg) {
774
774
  console.error(
775
- ` record start only supports webm or mp4 (got: ${formatArg}). for gif/png use atomic mode: rnx record --format ${formatArg} --duration <s>`,
775
+ ` record start only supports webm or mp4 (got: ${formatArg}). for gif/png use atomic mode: peach record --format ${formatArg} --duration <s>`,
776
776
  )
777
777
  rnxExit(1)
778
778
  }
@@ -797,7 +797,7 @@ async function recordStart(args: string[], opts: RecordOptions) {
797
797
  // entitlement here, not on local-file webm/mp4 capture (F19).
798
798
  // allowGitHubAuth: the PR-preview runner (`record start --mode
799
799
  // combined`) authenticates with a GitHub installation token, not
800
- // RNX_API_KEY — the whole pipeline is zero-secrets by design.
800
+ // PEACH_API_KEY — the whole pipeline is zero-secrets by design.
801
801
  // mirrors `flow --record`. the bypass only triggers for github-kind
802
802
  // auth (CI); local paid users still hit the billing check.
803
803
  await ensureCliRecordingEntitlement('record', {
@@ -855,11 +855,11 @@ async function recordStart(args: string[], opts: RecordOptions) {
855
855
  })
856
856
  if (mode === 'video') {
857
857
  console.log(
858
- ` recording ${format} @ ${fps}fps${layers ? ` (${layers})` : ''} — run \`rnx record stop --output <path>\` when done`,
858
+ ` recording ${format} @ ${fps}fps${layers ? ` (${layers})` : ''} — run \`peach record stop --output <path>\` when done`,
859
859
  )
860
860
  } else {
861
861
  console.log(
862
- ` recording ${mode} — run \`rnx record stop\` when done (add --open to launch the preview URL)`,
862
+ ` recording ${mode} — run \`peach record stop\` when done (add --open to launch the preview URL)`,
863
863
  )
864
864
  }
865
865
  } finally {
@@ -871,7 +871,7 @@ async function recordPreludeStart(args: string[], opts: RecordOptions) {
871
871
  const existing = readRecordingState()
872
872
  if (existing) {
873
873
  console.error(
874
- ` recording already in progress (started ${existing.startedAt}, sim ${existing.simId ?? '?'}). run \`rnx record stop\` first, or \`rnx record cancel\` to discard.`,
874
+ ` recording already in progress (started ${existing.startedAt}, sim ${existing.simId ?? '?'}). run \`peach record stop\` first, or \`peach record cancel\` to discard.`,
875
875
  )
876
876
  rnxExit(1)
877
877
  }
@@ -911,7 +911,7 @@ async function recordPreludeStart(args: string[], opts: RecordOptions) {
911
911
  rnxExit(1)
912
912
  }
913
913
  console.log(
914
- ' recording preview prelude — run `rnx record start --mode combined` when the visible proof segment is ready',
914
+ ' recording preview prelude — run `peach record start --mode combined` when the visible proof segment is ready',
915
915
  )
916
916
  } finally {
917
917
  bridge.close()
@@ -1027,8 +1027,8 @@ async function recordStatus(args: string[], opts: RecordOptions) {
1027
1027
  console.log(
1028
1028
  ' a recording preview prelude is active. hidden setup is being\n' +
1029
1029
  ' captured for the next live/combined preview recording. finish\n' +
1030
- ' it with `rnx record start --mode combined`, or discard it\n' +
1031
- ' with `rnx record cancel`.',
1030
+ ' it with `peach record start --mode combined`, or discard it\n' +
1031
+ ' with `peach record cancel`.',
1032
1032
  )
1033
1033
  return
1034
1034
  }
@@ -1040,7 +1040,7 @@ async function recordStatus(args: string[], opts: RecordOptions) {
1040
1040
  ' (atomic `--mode video/gif/png` writes a local file from that\n' +
1041
1041
  ' process; live/combined upload to /preview/<id>). if the run was\n' +
1042
1042
  ' killed, the recording is abandoned and will NOT finish — reclaim\n' +
1043
- ' it now with `rnx record cancel`, or it auto-reclaims when the\n' +
1043
+ ' it now with `peach record cancel`, or it auto-reclaims when the\n' +
1044
1044
  " abandoned capture's deadline lapses.",
1045
1045
  )
1046
1046
  } else {
@@ -1133,7 +1133,7 @@ async function recordCancel(args: string[], opts: RecordOptions) {
1133
1133
  async function recordStop(args: string[], opts: RecordOptions) {
1134
1134
  const state = readRecordingState()
1135
1135
  if (!state) {
1136
- console.error(' no recording in progress. start one with `rnx record start`.')
1136
+ console.error(' no recording in progress. start one with `peach record start`.')
1137
1137
  rnxExit(1)
1138
1138
  }
1139
1139
 
@@ -1165,7 +1165,7 @@ async function recordStop(args: string[], opts: RecordOptions) {
1165
1165
  }
1166
1166
 
1167
1167
  const outputArg = valueOf(args, '--output')
1168
- const out = resolveRecordingOutput(outputArg, `rnx-${stamp()}.${state.format}`)
1168
+ const out = resolveRecordingOutput(outputArg, `peach-${stamp()}.${state.format}`)
1169
1169
  mkdirSync(dirname(out), { recursive: true })
1170
1170
  const stopResult: {
1171
1171
  ok: boolean
@@ -1211,7 +1211,7 @@ async function assertStoreBridgesAvailable(bridge: WsBridge) {
1211
1211
  )
1212
1212
  if (!ok) {
1213
1213
  console.error(
1214
- ' SootSim.bridges.startRecording missing — is rnx engine running in this sim?',
1214
+ ' SootSim.bridges.startRecording missing — is peach engine running in this sim?',
1215
1215
  )
1216
1216
  rnxExit(1)
1217
1217
  }
@@ -1219,7 +1219,7 @@ async function assertStoreBridgesAvailable(bridge: WsBridge) {
1219
1219
 
1220
1220
  // CLI-driven live/combined recording runs in a headless browser that was
1221
1221
  // never logged in, so browser-side upload has no bearer. push the CLI's own
1222
- // auth — the same RNX_API_KEY / `rnx login` / GitHub token
1222
+ // auth — the same PEACH_API_KEY / `peach login` / GitHub token
1223
1223
  // ensureCliRecordingEntitlement just verified — into the page's shared-session
1224
1224
  // store before starting. GitHub PR-preview auth also needs its repo identity
1225
1225
  // in the upload init body so the server treats the bearer as a GitHub upload
@@ -1308,7 +1308,7 @@ async function injectPreviewSessionAuth(
1308
1308
  console.error(
1309
1309
  ' SootSim.bridges.setSession missing — this sim is running an engine\n' +
1310
1310
  ' build without CLI-injected preview auth. reload the sim or open a\n' +
1311
- ' fresh one (`rnx open --new`); if it persists, update rnx.',
1311
+ ' fresh one (`peach open --new`); if it persists, update peach.',
1312
1312
  )
1313
1313
  rnxExit(1)
1314
1314
  }
@@ -1,4 +1,4 @@
1
- // rnx report-issue — submit an explicitly approved compatibility report.
1
+ // peach report-issue — submit an explicitly approved compatibility report.
2
2
 
3
3
  import { existsSync, readFileSync } from 'node:fs'
4
4
  import { resolve } from 'node:path'
@@ -214,7 +214,7 @@ export async function runReportIssue(
214
214
  } catch (error) {
215
215
  dependencies.stderr(
216
216
  ` ${error instanceof Error ? error.message : String(error)}\n` +
217
- ` usage: rnx report-issue [--app <dir>] [--dry-run] [--yes] "<description>"\n`,
217
+ ` usage: peach report-issue [--app <dir>] [--dry-run] [--yes] "<description>"\n`,
218
218
  )
219
219
  return 1
220
220
  }
@@ -237,7 +237,7 @@ export async function runReportIssue(
237
237
  }
238
238
 
239
239
  dependencies.stdout(
240
- `\n rnx issue report preview\n\n` +
240
+ `\n peach issue report preview\n\n` +
241
241
  ` description: ${payload.note}\n` +
242
242
  ` compatibility: ${compatibilitySummary(payload.bundle.compatibility)}\n` +
243
243
  ` environment: CLI ${payload.bundle.cliVersion}, runtime ${
@@ -260,7 +260,7 @@ export async function runReportIssue(
260
260
  return 2
261
261
  }
262
262
  const approved = await dependencies.confirmSubmission(
263
- 'send this compatibility report to the rnx team?',
263
+ 'send this compatibility report to the peach team??',
264
264
  false,
265
265
  )
266
266
  if (!approved) {
@@ -19,10 +19,10 @@ function isResetResult(value: unknown): value is ResetResult {
19
19
 
20
20
  function printHelp(): void {
21
21
  console.log(`
22
- rnx reset - clear the current guest app and relaunch it
22
+ peach reset - clear the current guest app and relaunch it
23
23
 
24
24
  usage:
25
- rnx reset [--full] [--json] [--sim <id>]
25
+ peach reset [--full] [--json] [--sim <id>]
26
26
 
27
27
  options:
28
28
  --full also clear keychain, user defaults, and permissions
@@ -1,14 +1,14 @@
1
- // rnx runtime — manage engine runtimes under ~/.rnx/runtimes/.
1
+ // peach runtime — manage engine runtimes under ~/.peach/runtimes/.
2
2
  //
3
3
  // runtimes are versioned tarballs hosted behind the configured CDN origin
4
4
  // (default https://contrast.dev/runtimes/). each install:
5
5
  // 1. fetches manifest.json to resolve a version (or confirm the literal)
6
6
  // 2. downloads sootsim-runtime-<version>.tar.gz to an operation temp directory
7
7
  // 3. verifies sha256
8
- // 4. extracts to ~/.rnx/runtimes/<version>/
8
+ // 4. extracts to ~/.peach/runtimes/<version>/
9
9
  // 5. (optionally) sets it active + tells the daemon to hot-swap
10
10
  //
11
- // the daemon-side state (active runtime) is mirrored in ~/.rnx/runtimes/active
11
+ // the daemon-side state (active runtime) is mirrored in ~/.peach/runtimes/active
12
12
  // so the CLI can change it even when the daemon isn't running.
13
13
 
14
14
  import fs from 'fs'
@@ -63,15 +63,15 @@ export async function runRuntime(args: string[], opts: RuntimeOptions = {}) {
63
63
 
64
64
  function printHelp() {
65
65
  console.log(`
66
- rnx runtime — manage engine runtimes under ~/.rnx/runtimes/
66
+ peach runtime — manage engine runtimes under ~/.peach/runtimes/
67
67
 
68
68
  usage:
69
- rnx runtime install [version] install a version (default: channel latest)
70
- rnx runtime list show installed + available versions
71
- rnx runtime use <version> switch active runtime
72
- rnx runtime remove <version> delete an installed runtime
73
- rnx runtime which print active runtime version
74
- rnx runtime notes print repo or default engine release notes
69
+ peach runtime install [version] install a version (default: channel latest)
70
+ peach runtime list show installed + available versions
71
+ peach runtime use <version> switch active runtime
72
+ peach runtime remove <version> delete an installed runtime
73
+ peach runtime which print active runtime version
74
+ peach runtime notes print repo or default engine release notes
75
75
 
76
76
  flags:
77
77
  --channel <name> channel to resolve 'latest' from (default: stable)
@@ -79,14 +79,14 @@ flags:
79
79
  --set-active=false do not switch active runtime after install
80
80
 
81
81
  environment:
82
- RNX_CDN_ORIGIN override the CDN base URL (default: ${DEFAULT_RUNTIME_CDN_ORIGIN})
82
+ PEACH_CDN_ORIGIN override the CDN base URL (default: ${DEFAULT_RUNTIME_CDN_ORIGIN})
83
83
 
84
84
  examples:
85
- rnx runtime install
86
- rnx runtime install 1.2.3
87
- rnx runtime install --channel beta
88
- rnx runtime use 1.2.3
89
- rnx runtime notes
85
+ peach runtime install
86
+ peach runtime install 1.2.3
87
+ peach runtime install --channel beta
88
+ peach runtime use 1.2.3
89
+ peach runtime notes
90
90
  `)
91
91
  }
92
92
 
@@ -100,7 +100,7 @@ async function runtimeInstall(args: string[], opts: RuntimeOptions) {
100
100
 
101
101
  ensureRnxHome()
102
102
 
103
- console.log(`rnx runtime install`)
103
+ console.log(`peach runtime install`)
104
104
  console.log(` cdn: ${rnxRuntime.resolveCdnOrigin()}`)
105
105
 
106
106
  try {
@@ -136,7 +136,7 @@ async function activateVersion(version: string) {
136
136
  const notified = await tellDaemonRuntimeChanged(version)
137
137
  if (!notified) {
138
138
  console.log(
139
- ` (no daemon running — next rnx/electron launch will pick up ${version})`,
139
+ ` (no daemon running — next peach/electron launch will pick up ${version})`,
140
140
  )
141
141
  }
142
142
  }
@@ -234,14 +234,14 @@ async function runtimeList(_args: string[]) {
234
234
  async function runtimeUse(args: string[]) {
235
235
  const version = args[0]
236
236
  if (!version) {
237
- console.error(` usage: rnx runtime use <version>`)
237
+ console.error(` usage: peach runtime use <version>`)
238
238
  rnxExit(1)
239
239
  }
240
240
  const installed = rnxRuntime.listInstalled()
241
241
  if (!installed.includes(version)) {
242
242
  console.error(` version ${version} is not installed`)
243
243
  console.error(` installed: ${installed.join(', ') || '(none)'}`)
244
- console.error(` run \`rnx runtime install ${version}\` first`)
244
+ console.error(` run \`peach runtime install ${version}\` first`)
245
245
  rnxExit(1)
246
246
  }
247
247
  await activateVersion(version)
@@ -252,14 +252,14 @@ async function runtimeUse(args: string[]) {
252
252
  async function runtimeRemove(args: string[]) {
253
253
  const version = args[0]
254
254
  if (!version) {
255
- console.error(` usage: rnx runtime remove <version>`)
255
+ console.error(` usage: peach runtime remove <version>`)
256
256
  rnxExit(1)
257
257
  }
258
258
  const active = readActiveRuntime()
259
259
  if (active === version) {
260
260
  console.error(` cannot remove active runtime ${version}`)
261
261
  console.error(
262
- ` switch with \`rnx runtime use <other>\` first, or install another version`,
262
+ ` switch with \`peach runtime use <other>\` first, or install another version`,
263
263
  )
264
264
  rnxExit(1)
265
265
  }
@@ -291,7 +291,7 @@ async function runtimeWhich() {
291
291
 
292
292
  async function runtimeNotes(args: string[]) {
293
293
  if (args.length > 0) {
294
- console.error(` usage: rnx runtime notes`)
294
+ console.error(` usage: peach runtime notes`)
295
295
  rnxExit(1)
296
296
  }
297
297
  const { config } = await resolveRNXAppConfig()
@@ -85,7 +85,7 @@ export async function runScreenshotCommand(
85
85
  // repo-only tooling: screenshots-capture statically imports playwright-core,
86
86
  // which the published CLI never ships (it's external in build-cli.ts). a
87
87
  // static import here would put that bare import at the top of THIS chunk,
88
- // so every published `rnx screenshot` printed ERR_MODULE_NOT_FOUND —
88
+ // so every published `peach screenshot` printed ERR_MODULE_NOT_FOUND —
89
89
  // keep it a runtime dynamic import that only evaluates when capture runs.
90
90
  try {
91
91
  const { runScreenshotsCapture } = await import('./screenshots-capture')
@@ -95,7 +95,7 @@ export async function runScreenshotCommand(
95
95
  } catch (err) {
96
96
  if (err instanceof Error && 'code' in err && err.code === 'ERR_MODULE_NOT_FOUND') {
97
97
  console.error(
98
- 'screenshot appstore capture is repo-only tooling — it needs the rnx workspace (playwright is not shipped with the published CLI).',
98
+ 'screenshot appstore capture is repo-only tooling — it needs the peach workspace (playwright is not shipped with the published CLI).',
99
99
  )
100
100
  return 1
101
101
  }
@@ -1,4 +1,4 @@
1
- // rnx screenshot layers — engine-rendered layer isolation export.
1
+ // peach screenshot layers — engine-rendered layer isolation export.
2
2
  //
3
3
  // captures one screen as a stack the 3d stage can pull apart: `full.png` is
4
4
  // the normal frame, `base.png` re-renders the frame with the target subtrees
@@ -26,14 +26,14 @@ export async function runScreenshotLayers(
26
26
  ): Promise<void> {
27
27
  if (args.includes('--help') || args.includes('-h')) {
28
28
  console.log(`
29
- rnx screenshot layers — export a screen as engine-isolated layers
29
+ peach screenshot layers — export a screen as engine-isolated layers
30
30
 
31
31
  usage:
32
- rnx screenshot layers --ids <testID,testID,...> [--out-dir <dir>]
32
+ peach screenshot layers --ids <testID,testID,...> [--out-dir <dir>]
33
33
 
34
34
  options:
35
35
  --ids <list> comma-separated testIDs of the subtrees to isolate
36
- --out-dir <dir> output directory (default: /tmp/rnx-layers)
36
+ --out-dir <dir> output directory (default: /tmp/peach-layers)
37
37
 
38
38
  output:
39
39
  full.png the normal frame
@@ -58,7 +58,7 @@ output:
58
58
  rnxExit(1)
59
59
  }
60
60
  const outDirArg = args.find((_, i) => args[i - 1] === '--out-dir')
61
- const outDir = resolve(process.cwd(), outDirArg ?? '/tmp/rnx-layers')
61
+ const outDir = resolve(process.cwd(), outDirArg ?? '/tmp/peach-layers')
62
62
 
63
63
  const parsed = parseBridgeCliArgs(args, {
64
64
  port: opts.port,
@@ -1,5 +1,5 @@
1
- // rnx mode screenshot — toggle the "screenshot mode" chrome overlay
2
- // in the running rnx sim. orthogonal to `--no-shell` on the
1
+ // peach mode screenshot — toggle the "screenshot mode" chrome overlay
2
+ // in the running peach sim. orthogonal to `--no-shell` on the
3
3
  // `screenshot` command: this hides the DOM browser chrome (rail, menubar,
4
4
  // window controls) while still rendering the iOS shell inside the canvas.
5
5
  //
@@ -12,10 +12,10 @@ import { runShellBooleanMode, type ShellBooleanModeOptions } from './shell-boole
12
12
  export async function runScreenshotMode(args: string[], opts: ShellBooleanModeOptions) {
13
13
  if (args.includes('--help') || args.includes('-h')) {
14
14
  console.log(`
15
- rnx mode screenshot — toggle the screenshot-mode chrome overlay
15
+ peach mode screenshot — toggle the screenshot-mode chrome overlay
16
16
 
17
17
  usage:
18
- rnx mode screenshot [on|off|toggle]
18
+ peach mode screenshot [on|off|toggle]
19
19
 
20
20
  arguments:
21
21
  on enable screenshot mode (enables showFrame if needed)
@@ -23,9 +23,9 @@ arguments:
23
23
  toggle flip the current state (default)
24
24
 
25
25
  examples:
26
- rnx mode screenshot
27
- rnx mode screenshot on
28
- rnx mode screenshot off
26
+ peach mode screenshot
27
+ peach mode screenshot on
28
+ peach mode screenshot off
29
29
  `)
30
30
  rnxExit(0)
31
31
  }