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,4 +1,4 @@
1
- // rnx what-happened — show recent events from the semantic timeline
1
+ // peach what-happened — show recent events from the semantic timeline
2
2
  //
3
3
  // the agent-facing read verb for the SootSim.bridges.timeline API. by default
4
4
  // shows everything since the previous CLI call from the same agent
@@ -6,13 +6,13 @@
6
6
  // the events it displayed so the next call shows only new events.
7
7
  //
8
8
  // usage:
9
- // rnx what-happened # since last call
10
- // rnx what-happened --summary # one-line counts
11
- // rnx what-happened --all # full ring (no cursor)
12
- // rnx what-happened --since 5s # absolute window
13
- // rnx what-happened --kinds toast,fetch # filter
14
- // rnx what-happened --json # structured
15
- // rnx what-happened --limit 50 # cap (default 200)
9
+ // peach what-happened # since last call
10
+ // peach what-happened --summary # one-line counts
11
+ // peach what-happened --all # full ring (no cursor)
12
+ // peach what-happened --since 5s # absolute window
13
+ // peach what-happened --kinds toast,fetch # filter
14
+ // peach what-happened --json # structured
15
+ // peach what-happened --limit 50 # cap (default 200)
16
16
 
17
17
  import { getCliIdentityKey } from '../current-sim'
18
18
  import { rnxExit } from '../run-rnx'
@@ -157,7 +157,7 @@ export async function runWhatHappened(args: string[], opts: WhatHappenedOptions)
157
157
  '--flow',
158
158
  // by default we hide high-frequency render/layout/scroll noise so
159
159
  // a single tap doesn't get buried under 1000+ rows. enable
160
- // `react-commit` with `rnx timeline start react-commit`, then pass
160
+ // `react-commit` with `peach timeline start react-commit`, then pass
161
161
  // `--noisy` (or an explicit `--kinds react-commit,…` filter) when you
162
162
  // actually want to see them.
163
163
  '--noisy',
@@ -167,21 +167,21 @@ export async function runWhatHappened(args: string[], opts: WhatHappenedOptions)
167
167
 
168
168
  if (args.includes('--help') || args.includes('-h')) {
169
169
  console.log(`
170
- rnx what-happened — show recent events from the semantic timeline
170
+ peach what-happened — show recent events from the semantic timeline
171
171
 
172
172
  usage:
173
- rnx what-happened # since last CLI call
174
- rnx what-happened --summary # one-line counts
175
- rnx what-happened --all # full ring (ignore cursor)
176
- rnx what-happened --since 5s # absolute window
177
- rnx what-happened --kinds toast,fetch
178
- rnx what-happened --noisy # include react-commit/layout/scroll
179
- rnx what-happened --limit 50
180
- rnx what-happened --json
181
- rnx what-happened --no-advance # don't advance cursor after read
173
+ peach what-happened # since last CLI call
174
+ peach what-happened --summary # one-line counts
175
+ peach what-happened --all # full ring (ignore cursor)
176
+ peach what-happened --since 5s # absolute window
177
+ peach what-happened --kinds toast,fetch
178
+ peach what-happened --noisy # include react-commit/layout/scroll
179
+ peach what-happened --limit 50
180
+ peach what-happened --json
181
+ peach what-happened --no-advance # don't advance cursor after read
182
182
 
183
183
  note: react-commit, layout, and scroll are opt-in/noisy events. enable them
184
- with "rnx timeline start <kind>", then pass --noisy or include them in
184
+ with "peach timeline start <kind>", then pass --noisy or include them in
185
185
  --kinds to see them.
186
186
  `)
187
187
  rnxExit(0)
@@ -18,7 +18,7 @@ export interface LocalCurrentTarget {
18
18
  // checked in order — the first one present wins. anything further down is a
19
19
  // progressively weaker signal of "same caller across invocations".
20
20
  const IDENTITY_ENV_VARS = [
21
- 'RNX_CLI_IDENTITY', // explicit override — fastest path, skips all pid lookups
21
+ 'PEACH_CLI_IDENTITY', // explicit override — fastest path, skips all pid lookups
22
22
  'TM_SESSION', // Team Machine session id; routes prompt-bar followups back to this agent
23
23
  'CLAUDE_CODE_SESSION_ID', // claude code, if ever set
24
24
  'CODEX_THREAD_ID', // codex / openai agent thread, stable across tool invocations
@@ -56,7 +56,7 @@ export interface CliIdentity {
56
56
  // pids drift across invocations:
57
57
  // - claude code's bash tool spawns a fresh shell per call, so the
58
58
  // immediate gppid (the shell's parent) can change
59
- // - shell pipelines (`rnx list | grep`) wrap the command in a
59
+ // - shell pipelines (`peach list | grep`) wrap the command in a
60
60
  // subshell, adding an extra ppid layer that shifts gppid down by one
61
61
  // the topmost user process (just below init/launchd) is stable across
62
62
  // all of these — same agent / login shell / terminal across calls.
@@ -147,7 +147,7 @@ export function getCurrentSimPath() {
147
147
  return resolve(process.env[CURRENT_SIM_PATH_ENV])
148
148
  }
149
149
  const key = getCliIdentityKey()
150
- return join(tmpdir(), `rnx-current-sim-${key}.json`)
150
+ return join(tmpdir(), `peach-current-sim-${key}.json`)
151
151
  }
152
152
 
153
153
  function legacyCloudCredentialDirectory(filepath: string): string {
@@ -19,7 +19,7 @@ function getSootsimRoot(): string | null {
19
19
  }
20
20
  return _sootsimRoot
21
21
  }
22
- const SOOTSIM_BUNDLE_ID = 'dev.sootsim.simulator'
22
+ const PEACH_BUNDLE_ID = 'dev.peachsim.simulator'
23
23
 
24
24
  export interface DesktopCompanionInstall {
25
25
  path: string
@@ -38,7 +38,7 @@ export interface DesktopCompanionLaunchResult {
38
38
 
39
39
  // dev-electron: when running from inside the Contrast checkout with sootsim-engine
40
40
  // built and the electron dev dep present, prefer launching the local unpacked
41
- // electron instead of the stale packaged /Applications/rnx.app.
41
+ // electron instead of the stale packaged /Applications/peach.app.
42
42
  //
43
43
  // rationale: in dev we want electron to hit http://localhost:5173
44
44
  // (src-electron/main.ts does this when !app.isPackaged).
@@ -92,9 +92,9 @@ function findElectronBin(startDir: string): string | null {
92
92
  function findMacApp(): DesktopCompanionInstall | null {
93
93
  const root = getSootsimRoot()
94
94
  const candidates = [
95
- '/Applications/rnx.app',
96
- resolve(process.env.HOME || '', 'Applications/rnx.app'),
97
- ...(root ? [resolve(root, 'app/rnx.app')] : []),
95
+ '/Applications/peach.app',
96
+ resolve(process.env.HOME || '', 'Applications/peach.app'),
97
+ ...(root ? [resolve(root, 'app/peach.app')] : []),
98
98
  ]
99
99
 
100
100
  const found = candidates.find((candidate) => existsSync(candidate))
@@ -109,7 +109,7 @@ function findMacApp(): DesktopCompanionInstall | null {
109
109
  try {
110
110
  const result = execFileSync(
111
111
  'mdfind',
112
- [`kMDItemCFBundleIdentifier == "${SOOTSIM_BUNDLE_ID}"`],
112
+ [`kMDItemCFBundleIdentifier == "${PEACH_BUNDLE_ID}"`],
113
113
  { encoding: 'utf8', timeout: 3000 },
114
114
  ).trim()
115
115
  if (result) {
@@ -127,7 +127,7 @@ function findMacApp(): DesktopCompanionInstall | null {
127
127
  function findFirstAppImage(dir: string): string | null {
128
128
  if (!existsSync(dir)) return null
129
129
  const match = readdirSync(dir)
130
- .filter((entry) => entry.startsWith('rnx') && entry.endsWith('.AppImage'))
130
+ .filter((entry) => entry.startsWith('peach') && entry.endsWith('.AppImage'))
131
131
  .sort()
132
132
  .reverse()[0]
133
133
  return match ? join(dir, match) : null
@@ -136,12 +136,12 @@ function findFirstAppImage(dir: string): string | null {
136
136
  function findLinuxInstall(): DesktopCompanionInstall | null {
137
137
  const root = getSootsimRoot()
138
138
  const directCandidates = [
139
- resolve(process.env.HOME || '', 'Applications/rnx.AppImage'),
140
- resolve(process.env.HOME || '', '.local/bin/rnx.AppImage'),
141
- '/opt/rnx/rnx.AppImage',
142
- '/opt/rnx/rnx',
139
+ resolve(process.env.HOME || '', 'Applications/peach.AppImage'),
140
+ resolve(process.env.HOME || '', '.local/bin/peach.AppImage'),
141
+ '/opt/peach/peach.AppImage',
142
+ '/opt/peach/peach',
143
143
  ...(root
144
- ? [resolve(root, 'app/rnx.AppImage'), resolve(root, 'release/linux-unpacked/rnx')]
144
+ ? [resolve(root, 'app/peach.AppImage'), resolve(root, 'release/linux-unpacked/peach')]
145
145
  : []),
146
146
  ]
147
147
 
@@ -173,7 +173,7 @@ function findWindowsInstall(): DesktopCompanionInstall | null {
173
173
  try {
174
174
  const output = execFileSync(
175
175
  'reg',
176
- ['query', `${hive}\\Software\\Classes\\rnx\\shell\\open\\command`, '/ve'],
176
+ ['query', `${hive}\\Software\\Classes\\peach\\shell\\open\\command`, '/ve'],
177
177
  { encoding: 'utf8', timeout: 3000 },
178
178
  )
179
179
  const executable = /"([^"\r\n]+\.exe)"/i.exec(output)?.[1]
@@ -240,8 +240,8 @@ export interface LaunchCompanionOptions {
240
240
  device?: string
241
241
  profileId?: string
242
242
  ephemeralProfile?: boolean
243
- // set by `rnx open`, whose native window belongs to the launching
244
- // session. `rnx desktop` omits it and remains a persistent desktop app.
243
+ // set by `peach open`, whose native window belongs to the launching
244
+ // session. `peach desktop` omits it and remains a persistent desktop app.
245
245
  ownerPid?: number
246
246
  }
247
247
 
@@ -304,7 +304,7 @@ export async function launchDesktopCompanion(
304
304
 
305
305
  function buildMacLaunchUrl(url: string, opts: LaunchCompanionOptions): string {
306
306
  if (!opts.profileId && !opts.ephemeralProfile && !opts.ownerPid) return url
307
- const deepLink = new URL('rnx://dev')
307
+ const deepLink = new URL('peach://dev')
308
308
  deepLink.searchParams.set('url', url)
309
309
  if (opts.profileId) deepLink.searchParams.set('profile', opts.profileId)
310
310
  if (opts.ephemeralProfile) deepLink.searchParams.set('ephemeral', '1')
@@ -1,5 +1,5 @@
1
1
  // electron driver — wraps the existing desktop-companion helper. availability
2
- // is "is the rnx desktop app installed on this machine". launch delegates
2
+ // is "is the peach desktop app installed on this machine". launch delegates
3
3
  // to launchDesktopCompanion, which already handles mac `open -a`, linux
4
4
  // AppImage, and the --device seed.
5
5
 
@@ -16,7 +16,7 @@ function probe(): DriverAvailability {
16
16
  if (!install) {
17
17
  return {
18
18
  available: false,
19
- reason: 'rnx desktop app not installed (run `rnx desktop install`)',
19
+ reason: 'peach desktop app not installed (run `peach desktop install`)',
20
20
  }
21
21
  }
22
22
  return {
@@ -31,7 +31,7 @@ async function launch(opts: DriverLaunchOptions): Promise<DriverLaunchResult> {
31
31
  if (!install) {
32
32
  return {
33
33
  launched: false,
34
- message: 'rnx desktop app not installed',
34
+ message: 'peach desktop app not installed',
35
35
  }
36
36
  }
37
37
  try {
@@ -63,7 +63,7 @@ async function launch(opts: DriverLaunchOptions): Promise<DriverLaunchResult> {
63
63
  export const electronDriver: Driver = {
64
64
  id: 'electron',
65
65
  name: 'electron',
66
- description: 'rnx desktop companion app (native window, menu bar)',
66
+ description: 'peach desktop companion app (native window, menu bar)',
67
67
  kind: 'native',
68
68
  availability: probe,
69
69
  launch,
@@ -34,7 +34,7 @@ const callerUserDataDir = process.env.SOOTSIM_PW_USERDATADIR || '';
34
34
  const ownerPid = Number(process.env.SOOTSIM_PW_OWNER_PID || 0);
35
35
  const ownerPollMs = Number(process.env.SOOTSIM_PW_OWNER_POLL_MS || 5000);
36
36
  // optional CDP port — exposes Chrome's remote-debugging endpoint so a
37
- // bridge-driven sim can also be cpu-profiled (rnx perf cpu --cdp-port).
37
+ // bridge-driven sim can also be cpu-profiled (peach perf cpu --cdp-port).
38
38
  // playwright keeps its own pipe connection; the port is an additional endpoint.
39
39
  const cdpPort = process.env.SOOTSIM_PW_CDP_PORT || '';
40
40
  // extra chromium launch args, space-separated. a linux GPU runner injects
@@ -81,7 +81,7 @@ const resolveBrowserCompositeCdpClip = ${resolveBrowserCompositeCdpClip.toString
81
81
  //
82
82
  // the prior approach was \`pgrep -f ms-playwright/[c]hromium\`. it never matched
83
83
  // system Chrome, so the reaper was a no-op in the common case and every
84
- // aborted/closed \`rnx open\` leaked a renderer + gpu helper burning 100%+
84
+ // aborted/closed \`peach open\` leaked a renderer + gpu helper burning 100%+
85
85
  // CPU until manually killed (multiple incidents 2026-06).
86
86
  //
87
87
  // fix: identify our chrome tree by its UNIQUE user-data-dir. every helper a
@@ -94,13 +94,13 @@ const reapEnabled = process.platform !== 'win32';
94
94
  let profileDir = callerUserDataDir;
95
95
  let ephemeralProfile = false;
96
96
  if (!profileDir) {
97
- profileDir = mkdtempSync(join(tmpdir(), 'rnx-playwright-host-'));
97
+ profileDir = mkdtempSync(join(tmpdir(), 'peach-playwright-host-'));
98
98
  ephemeralProfile = true;
99
99
  }
100
100
  // browser HTTP caches are acceleration data, not profile identity. give each
101
101
  // host a bounded temporary cache so persistent named profiles retain cookies
102
102
  // and storage without multiplying a private cache for every profile.
103
- const diskCacheDir = mkdtempSync(join(tmpdir(), 'rnx-playwright-cache-'));
103
+ const diskCacheDir = mkdtempSync(join(tmpdir(), 'peach-playwright-cache-'));
104
104
  const chromePidsByProfile = () => {
105
105
  if (!reapEnabled) return [];
106
106
  try {
@@ -271,10 +271,10 @@ const cleanupProfile = () => {
271
271
  // through shutdown(); the exit hook (sync sweep) still reaps the tree.
272
272
  process.on('exit', () => { reapChrome(); cleanupProfile(); });
273
273
  // owner-liveness watchdog — the load-bearing fix for leaked Chrome hosts.
274
- // we are spawned detached + unref'd so \`rnx open\` returns immediately,
274
+ // we are spawned detached + unref'd so \`peach open\` returns immediately,
275
275
  // which means nothing in the OS process tree ties Chrome's lifetime to the
276
276
  // session that asked for it. once the sim connects, the connect-timeout
277
- // safety net is cleared, so absent an explicit \`rnx close\` (or the
277
+ // safety net is cleared, so absent an explicit \`peach close\` (or the
278
278
  // daemon's idle reaper closing the sim socket) the host would hold Chrome
279
279
  // open forever after its owner exits. poll the owning session's pid and tear
280
280
  // down when it's gone. ESRCH (kill throws) = owner exited; EPERM = alive but
@@ -300,7 +300,7 @@ const cleanupProfile = () => {
300
300
  // com.google.chrome.for.testing identity cannot intercept open/quit events for
301
301
  // the user's com.google.Chrome browser. CI may use chromium_headless_shell;
302
302
  // local rendering fails closed because that shell has no GPU and silently
303
- // chooses SwiftShader. NOTE: this is NOT enough to make \`rnx perf cpu\`
303
+ // chooses SwiftShader. NOTE: this is NOT enough to make \`peach perf cpu\`
304
304
  // work — that profiles the tenant *worker*, and the JS Self-Profiler API
305
305
  // cannot be constructed in a dedicated worker (see
306
306
  // worker-handlers/cpu-profile.ts). cpu-profile needs a CDP-based profiler
@@ -6,11 +6,11 @@
6
6
  //
7
7
  // the browser runs in a *detached* child process — this CLI re-invoked as
8
8
  // its own `__internal playwright-host` (see cli/internal-child.ts) — rather
9
- // than in this CLI process. that is load-bearing: `rnx open` returns the
9
+ // than in this CLI process. that is load-bearing: `peach open` returns the
10
10
  // moment the sim connects, and playwright tears its browser down when the
11
11
  // launching process exits. an in-process launch would mean the sim vanished
12
12
  // the instant `open` finished. the detached host keeps the test browser alive
13
- // until the sim's page closes (e.g. via `rnx close`).
13
+ // until the sim's page closes (e.g. via `peach close`).
14
14
 
15
15
  import { spawn } from 'child_process'
16
16
  import { closeSync, mkdtempSync, openSync, readFileSync } from 'fs'
@@ -68,7 +68,7 @@ function resolveUserDataDir(opts: DriverLaunchOptions): string {
68
68
  return playwrightProfileUserDataDir(ensureProfile(opts.profileId).id)
69
69
  }
70
70
  if (opts.ephemeralProfile) {
71
- return mkdtempSync(join(tmpdir(), 'rnx-playwright-profile-'))
71
+ return mkdtempSync(join(tmpdir(), 'peach-playwright-profile-'))
72
72
  }
73
73
  return ''
74
74
  }
@@ -107,7 +107,7 @@ async function launch(opts: DriverLaunchOptions): Promise<DriverLaunchResult> {
107
107
  const connectAckFile = `${errLog}.connected`
108
108
  const errFd = openSync(errLog, 'a')
109
109
  try {
110
- // spawn the browser host detached so Chrome outlives `rnx
110
+ // spawn the browser host detached so Chrome outlives `peach
111
111
  // open`. stdout is dropped; stderr is captured to errLog so an early
112
112
  // crash (bad profile dir, missing browser binary) produces a real
113
113
  // message instead of a silent "timed out waiting for sim".
@@ -37,7 +37,7 @@ export function resolveDriver(
37
37
  return null
38
38
  }
39
39
 
40
- // utility for the `rnx list --drivers` view. returns a rich row per
40
+ // utility for the `peach list --drivers` view. returns a rich row per
41
41
  // driver with availability + kind + description, suitable for a table.
42
42
  export interface DriverListRow {
43
43
  id: DriverId
@@ -1,4 +1,4 @@
1
- // driver / runner abstraction for rnx. browser sims run in an isolated
1
+ // driver / runner abstraction for peach. browser sims run in an isolated
2
2
  // playwright-owned profile. electron remains the native desktop surface.
3
3
 
4
4
  export type DriverId = 'electron' | 'playwright'
@@ -29,7 +29,7 @@ export interface DriverLaunchOptions {
29
29
  url?: string
30
30
  // run in headless mode where the driver supports it. ignored by electron.
31
31
  headless?: boolean
32
- // initial device model seed forwarded to the rnx shell. the electron
32
+ // initial device model seed forwarded to the peach shell. the electron
33
33
  // driver forwards it via argv (--device=<model>); browser drivers receive
34
34
  // it already stamped on the URL (?device=<model>) by runOpenCommand.
35
35
  device?: string
@@ -51,7 +51,7 @@ export interface DriverLaunchOptions {
51
51
  // stable pid for the session that owns a CLI-opened host. electron closes
52
52
  // only that session's windows when the owner exits; playwright requires it
53
53
  // so a detached browser can never outlive its session. omitted only for the
54
- // persistent `rnx desktop` app lifecycle.
54
+ // persistent `peach desktop` app lifecycle.
55
55
  ownerPid?: number
56
56
  // expose Chrome's remote-debugging endpoint on this port so a
57
57
  // bridge-driven sim can also be cpu-profiled. only the playwright driver
@@ -60,7 +60,7 @@ export interface DriverLaunchOptions {
60
60
  // maximum time the detached host should wait for the launched sim to
61
61
  // register with the bridge before it tears itself down.
62
62
  connectTimeoutMs?: number
63
- // the rnx WS bridge port the launched sim page should register with,
63
+ // the peach WS bridge port the launched sim page should register with,
64
64
  // injected as window.__sootsimBridgePort. load-bearing when the dev bridge
65
65
  // drifted off the shell-port-implied default (e.g. :7668 taken at the shell's
66
66
  // boot -> bridge on :7669 while the shell kept :5173): the page's own
@@ -85,7 +85,7 @@ export interface DriverLaunchResult {
85
85
 
86
86
  export interface Driver {
87
87
  id: DriverId
88
- // short human name shown in `rnx list --drivers`.
88
+ // short human name shown in `peach list --drivers`.
89
89
  name: string
90
90
  // one-line description. keep under 80 chars so the list command reads
91
91
  // nicely at default terminal width.
@@ -5,7 +5,7 @@
5
5
  // store has to load wherever the CLI's runtime commands load, including inside
6
6
  // a box shell running in workerd, where the `yaml` package does not load at
7
7
  // all. YAML formatting and writing the file are the export step, and only
8
- // `rnx flow` and `rnx maestro` ever reach it.
8
+ // `peach flow` and `peach maestro` ever reach it.
9
9
 
10
10
  import { mkdirSync, writeFileSync } from 'node:fs'
11
11
  import { dirname, resolve } from 'node:path'
package/cli/flow-file.ts CHANGED
@@ -2,14 +2,14 @@ import * as fs from 'fs'
2
2
  import yaml from 'yaml'
3
3
 
4
4
  export interface FlowFrontmatter {
5
- // raw `rnx open` target: port, dev-server URL, bundle URL, or shell URL
5
+ // raw `peach open` target: port, dev-server URL, bundle URL, or shell URL
6
6
  app?: string | number
7
7
  device?: string
8
8
  // pin the sim color scheme for this flow run (screenshot baselines are
9
9
  // theme-sensitive; a dark capture can never match a light baseline)
10
10
  theme?: 'light' | 'dark'
11
11
  electron?: boolean
12
- // maestro-compatible: appId is accepted but not used by rnx (ios bundle id)
12
+ // maestro-compatible: appId is accepted but not used by peach (ios bundle id)
13
13
  appId?: string
14
14
  // maestro-compatible: flow-level env vars, defined into the flow's JS
15
15
  // context before the first step runs
@@ -27,10 +27,10 @@ export interface FlowFrontmatter {
27
27
 
28
28
  // parse flow file. accepts three shapes:
29
29
  // 1. plain yaml array of steps (no frontmatter)
30
- // 2. rnx style: ---\n<fm>\n---\n<steps>
30
+ // 2. peach style: ---\n<fm>\n---\n<steps>
31
31
  // 3. maestro style: <fm>\n---\n<steps> (multi-doc yaml, fm first)
32
32
  // maestro compat matters because real users have real .maestro/*.yaml files
33
- // and shouldn't have to rewrite them to drive rnx.
33
+ // and shouldn't have to rewrite them to drive peach.
34
34
  //
35
35
  // `${...}` templates are NOT resolved here — interpolation happens per-step
36
36
  // at execution time in the flow runner's JS context (matching maestro), so
@@ -123,7 +123,7 @@ export function validateFlowSteps(steps: any[]): string[] {
123
123
  // structural-only validator used by CI runners before uploading the flow
124
124
  // artifact. we only check: file exists, parseable yaml, has at least one
125
125
  // real interaction step. playback validation is a separate concern handled
126
- // by `rnx maestro end --validate` during the authoring session.
126
+ // by `peach maestro end --validate` during the authoring session.
127
127
  export function validateFlowFile(flowPath: string): string[] {
128
128
  if (!fs.existsSync(flowPath)) {
129
129
  return [`file not found: ${flowPath}`]
@@ -23,7 +23,7 @@ const FLOW_SESSION_VERSION = 1 as const
23
23
 
24
24
  export function getFlowSessionPath() {
25
25
  return resolve(
26
- process.env.RNX_FLOW_SESSION_PATH || join(tmpdir(), 'rnx-flow-session.json'),
26
+ process.env.PEACH_FLOW_SESSION_PATH || join(tmpdir(), 'peach-flow-session.json'),
27
27
  )
28
28
  }
29
29
 
package/cli/help-core.ts CHANGED
@@ -38,10 +38,10 @@ function backendLabel(command: string, args: readonly string[]): string {
38
38
  }
39
39
 
40
40
  function renderPreviewHelp(command: 'web' | 'ios' | 'android'): string {
41
- return `rnx ${command} — select or ensure the current branch's existing ${command} preview
41
+ return `peach ${command} — select or ensure the current branch's existing ${command} preview
42
42
 
43
43
  usage:
44
- rnx ${command}
44
+ peach ${command}
45
45
 
46
46
  The browser backend selects the Factory-owned ${command} iframe. It never launches a
47
47
  host process or Cloudflare runtime.`
@@ -51,19 +51,19 @@ function renderFactoryBrowserLeaves(command: string): string | null {
51
51
  switch (command) {
52
52
  case 'do':
53
53
  return `Factory browser leaves:
54
- rnx do navigate /route`
54
+ peach do navigate /route`
55
55
  case 'shell':
56
56
  return `Factory browser leaves:
57
- rnx shell appearance light|dark`
57
+ peach shell appearance light|dark`
58
58
  case 'assert':
59
59
  return `Factory browser leaves:
60
- rnx assert find (--testid <id>|--text <text>|--role <role>) [--exists|--empty] [--contains <text>]`
60
+ peach assert find (--testid <id>|--text <text>|--role <role>) [--exists|--empty] [--contains <text>]`
61
61
  case 'screenshot':
62
62
  return `Factory browser leaves:
63
- rnx screenshot
64
- rnx screenshot ask <question>
65
- rnx screenshot appearance light|dark /route --by <query-kind> --value <target>
66
- rnx screenshot motion <task-id> /route --trigger-by <kind> --trigger-value <target> --result-by <kind> --result-value <target> [--duration-ms <100..2000>]`
63
+ peach screenshot
64
+ peach screenshot ask <question>
65
+ peach screenshot appearance light|dark /route --by <query-kind> --value <target>
66
+ peach screenshot motion <task-id> /route --trigger-by <kind> --trigger-value <target> --result-by <kind> --result-value <target> [--duration-ms <100..2000>]`
67
67
  default:
68
68
  return null
69
69
  }
@@ -90,7 +90,7 @@ function renderRootAvailability(backend: RnxBackendKind): string {
90
90
  available: ${available.join(', ')}
91
91
  unavailable: ${unavailable.join(', ')}
92
92
 
93
- Run \`rnx <command> --help\` for leaf availability and usage.`
93
+ Run \`peach <command> --help\` for leaf availability and usage.`
94
94
  }
95
95
 
96
96
  export function renderRnxHelp(options: RnxHelpOptions): string {
@@ -100,9 +100,9 @@ export function renderRnxHelp(options: RnxHelpOptions): string {
100
100
  return `${renderCliIndexHelp(HELP_CONTEXT, formatFlagHelp()).trimEnd()}
101
101
 
102
102
  browser preview selectors:
103
- rnx web select the existing Factory web preview
104
- rnx ios select the existing Factory iOS preview
105
- rnx android select the existing Factory Android preview
103
+ peach web select the existing Factory web preview
104
+ peach ios select the existing Factory iOS preview
105
+ peach android select the existing Factory Android preview
106
106
 
107
107
  ${renderRootAvailability(options.backend)}`
108
108
  }
package/cli/hints.ts CHANGED
@@ -1,4 +1,4 @@
1
- // configurable, identity-scoped hint registry for the rnx CLI.
1
+ // configurable, identity-scoped hint registry for the peach CLI.
2
2
  //
3
3
  // two problems this solves:
4
4
  // 1. the CLI scatters "hint: ..." console.logs across many command files,
@@ -46,11 +46,11 @@ interface HintStateFile {
46
46
  const STATE_VERSION = 1 as const
47
47
 
48
48
  function identityStatePath(): string {
49
- return join(tmpdir(), `rnx-cli-hints-${getCliIdentityKey()}.json`)
49
+ return join(tmpdir(), `peach-cli-hints-${getCliIdentityKey()}.json`)
50
50
  }
51
51
 
52
52
  function globalStatePath(): string {
53
- return join(tmpdir(), `rnx-cli-hints-global.json`)
53
+ return join(tmpdir(), `peach-cli-hints-global.json`)
54
54
  }
55
55
 
56
56
  function readState(path: string): HintStateFile {
@@ -76,7 +76,7 @@ function writeState(path: string, state: HintStateFile) {
76
76
  }
77
77
 
78
78
  function modeFromEnv(): 'normal' | 'always' | 'off' {
79
- const v = (process.env.RNX_HINTS || '').toLowerCase()
79
+ const v = (process.env.PEACH_HINTS || '').toLowerCase()
80
80
  if (v === 'off' || v === '0' || v === 'false') return 'off'
81
81
  if (v === 'always' || v === 'verbose') return 'always'
82
82
  return 'normal'
@@ -119,7 +119,7 @@ function shouldShow(id: string, frequency: HintFrequency): boolean {
119
119
  export function maybeHint(id: string, ...args: unknown[]): boolean {
120
120
  const spec = registry.get(id)
121
121
  if (!spec) {
122
- if (process.env.RNX_HINTS_DEBUG) {
122
+ if (process.env.PEACH_HINTS_DEBUG) {
123
123
  console.error(` [hints] no hint registered for id "${id}"`)
124
124
  }
125
125
  return false
@@ -158,13 +158,13 @@ defineHint<[number]>('app-still-loading', {
158
158
  // bundle boots — telling the user about it again is useful, not noisy.
159
159
  frequency: { cooldownMs: 60_000 },
160
160
  render: (nodeCount) =>
161
- `app may still be loading (${nodeCount} nodes). run \`rnx wait ready\` first.`,
161
+ `app may still be loading (${nodeCount} nodes). run \`peach wait ready\` first.`,
162
162
  })
163
163
 
164
164
  defineHint<[string]>('wait-selector-for-missing-testid', {
165
165
  // advice is stable; once per CLI identity is enough.
166
166
  frequency: 'once-per-identity',
167
- render: (testId) => `rnx wait selector ${testId}`,
167
+ render: (testId) => `peach wait selector ${testId}`,
168
168
  })
169
169
 
170
170
  defineHint<[string[]]>('prefer-cli-over-eval', {
@@ -181,9 +181,9 @@ defineHint<[]>('describe-use-filters', {
181
181
  frequency: 'once-per-identity',
182
182
  render: () => [
183
183
  `describe output is long. narrow it with:`,
184
- ` rnx describe --only '*Bottom Sheet*'`,
185
- ` rnx describe --testid-like 'swap-*'`,
186
- ` rnx describe --subtree <testID>`,
184
+ ` peach describe --only '*Bottom Sheet*'`,
185
+ ` peach describe --testid-like 'swap-*'`,
186
+ ` peach describe --subtree <testID>`,
187
187
  ],
188
188
  })
189
189
 
@@ -194,21 +194,21 @@ defineHint<[]>('describe-filter-context', {
194
194
  frequency: 'once-per-identity',
195
195
  render: () => [
196
196
  `filtered describe is search output, not current-route proof.`,
197
- `run \`rnx describe\` without filters after navigation; clipped nodes are marked \`(clipped:...)\`.`,
197
+ `run \`peach describe\` without filters after navigation; clipped nodes are marked \`(clipped:...)\`.`,
198
198
  ],
199
199
  })
200
200
 
201
201
  defineHint<[string]>('subtree-root-not-found', {
202
202
  frequency: 'always',
203
203
  render: (id) =>
204
- `no node with testID/id "${id}" — try \`rnx find --testid ${id}\` to discover available ids.`,
204
+ `no node with testID/id "${id}" — try \`peach find --testid ${id}\` to discover available ids.`,
205
205
  })
206
206
 
207
207
  defineHint<[]>('clean-uninstall', {
208
- // shown once on the first `rnx --help` run so users learn the teardown path.
208
+ // shown once on the first `peach --help` run so users learn the teardown path.
209
209
  frequency: 'once-ever',
210
210
  render: () => [
211
- `to remove the background daemon, run \`rnx daemon uninstall\`. it keeps your runtimes and device profiles; add \`--purge\` to delete ~/.rnx too.`,
211
+ `to remove the background daemon, run \`peach daemon uninstall\`. it keeps your runtimes and device profiles; add \`--purge\` to delete ~/.peach too.`,
212
212
  `the optional desktop app and its macOS preference plist are separate from the daemon.`,
213
213
  ],
214
214
  })
@@ -23,7 +23,7 @@ interface InspectNoticeState {
23
23
  export function getInspectNoticeStatePath() {
24
24
  return resolve(
25
25
  process.env[INSPECT_NOTICE_PATH_ENV] ||
26
- join(tmpdir(), 'rnx-inspect-notice-state.json'),
26
+ join(tmpdir(), 'peach-inspect-notice-state.json'),
27
27
  )
28
28
  }
29
29
 
@@ -1,10 +1,10 @@
1
1
  // hidden child-process entry points.
2
2
  //
3
3
  // the CLI needs separate JS processes for a few jobs: a detached browser host
4
- // that outlives `rnx open`, playwright's own installer, and a blocking fetch
4
+ // that outlives `peach open`, playwright's own installer, and a blocking fetch
5
5
  // worker for maestro's synchronous `http` API. each used to run as
6
6
  // `process.execPath -e '<source>'`, which cannot work once the CLI ships as a
7
- // compiled binary: there process.execPath is rnx, and rnx has no -e. a
7
+ // compiled binary: there process.execPath is peach, and peach has no -e. a
8
8
  // shell-installed user has no node and no bun either, so there is nothing else
9
9
  // to reach for. the binary is the JS runtime, and it runs these itself.
10
10
  //
package/cli/maestro-js.ts CHANGED
@@ -14,10 +14,10 @@
14
14
  // time (maestro-orchestra-models util/Env.kt): regex (?<!\\)\$\{([^$]*)},
15
15
  // result stringified, `\${...}` escapes to a literal, blank exprs become ''.
16
16
  //
17
- // divergences (deliberate, rnx-side ergonomics — keep this list short):
17
+ // divergences (deliberate, peach-side ergonomics — keep this list short):
18
18
  // 1. envBinding is seeded from the full process.env, not just MAESTRO_*.
19
- // rnx flows historically resolve `${SOOTSIM_*}` credentials from the
20
- // shell environment and `rnx maestro --env K=V` writes process.env.
19
+ // peach flows historically resolve `${SOOTSIM_*}` credentials from the
20
+ // shell environment and `peach maestro --env K=V` writes process.env.
21
21
  // 2. a *bare identifier* template (`${NAME}`) that evaluates to undefined
22
22
  // throws a loud "missing variable" error instead of interpolating the
23
23
  // literal text "undefined" into a tap target or login form. complex
@@ -45,7 +45,7 @@ function executeSyncHttp(
45
45
  params?: HttpParams,
46
46
  ): { ok: boolean; status: number; body: string; headers: Record<string, string> } {
47
47
  if (params?.multipartForm) {
48
- throw new Error('http: multipartForm is not supported by rnx yet')
48
+ throw new Error('http: multipartForm is not supported by peach yet')
49
49
  }
50
50
  // maestro's `http` API is synchronous (flows do `var res = http.post(...)`)
51
51
  // and there is no synchronous fetch, so each request round-trips through a
@@ -166,7 +166,7 @@ export function buildSessionLog(input: {
166
166
  }): string {
167
167
  const passed = input.flows.filter((flow) => flow.passed).length
168
168
  const lines = [
169
- '# rnx maestro session log',
169
+ '# peach maestro session log',
170
170
  `# started: ${input.startedAtIso}`,
171
171
  `# root: ${input.root}`,
172
172
  `# device: ${input.device}`,