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
@@ -33,7 +33,7 @@ export async function runFindSubcommand(opts: {
33
33
  // ranked-tappable list — same data source as --pressable, but the
34
34
  // output prioritises high-signal targets the agent likely wants to
35
35
  // tap next (visible, has text or testID, has accessibilityLabel),
36
- // and emits a copy-paste `rnx do` command per row so the agent
36
+ // and emits a copy-paste `peach do` command per row so the agent
37
37
  // doesn't have to re-form a tap from raw fields.
38
38
  const interactive = hasFlag('--interactive-targets') || hasFlag('--actions')
39
39
  const bareText =
@@ -71,7 +71,7 @@ export async function runFindSubcommand(opts: {
71
71
  if (jsonOut) {
72
72
  if (mode === 'interactive-targets' && Array.isArray(result)) {
73
73
  // include the `tap` command per row when emitting JSON for agents
74
- // — the human renderer does the same. tooling that drives rnx
74
+ // — the human renderer does the same. tooling that drives peach
75
75
  // can pick the highest-scored entry and execute its `tap` field.
76
76
  printJson(rankInteractive(result).map((n) => ({ ...n, tap: tapCommandForNode(n) })))
77
77
  } else {
@@ -1,4 +1,4 @@
1
- // `rnx get-layout` — bounding boxes for visible meaningful elements on the
1
+ // `peach get-layout` — bounding boxes for visible meaningful elements on the
2
2
  // current screen. focused on the layout numbers a designer checks: on-screen
3
3
  // box (x/y/w/h). pass --styling for computed borderRadius, per-side padding,
4
4
  // fontSize, visual style fields, and native rendered text contrast. pass
@@ -30,7 +30,7 @@ export async function runGetLayoutSubcommand(opts: {
30
30
  if (
31
31
  styling &&
32
32
  error instanceof Error &&
33
- (error.message === 'unsupported RNX Cloud command type: evaluate' ||
33
+ (error.message === 'unsupported Peach Cloud command type: evaluate' ||
34
34
  error.message.includes('requires the debug scope'))
35
35
  ) {
36
36
  throw new Error(
@@ -1,4 +1,4 @@
1
- // `rnx get keyboard` — prints the current iOS keyboard's full state.
1
+ // `peach get keyboard` — prints the current iOS keyboard's full state.
2
2
  //
3
3
  // shows visibility, keyboardType, returnKeyType, autoCapitalize policy,
4
4
  // active QWERTY sub-mode, shift + capsLock, and the mounted accessory bar
@@ -1,4 +1,4 @@
1
- // `rnx list` — connected sims, with the active one marked.
1
+ // `peach list` — connected sims, with the active one marked.
2
2
 
3
3
  import { resolveDevCheckoutRuntimeRoot } from '../../../src/runtime-assets'
4
4
  import { type BridgeSimInfo, formatLockOwner, type WsBridge } from '../../ws-bridge'
@@ -92,7 +92,7 @@ function summarizeSimUrl(url: string | undefined): string | null {
92
92
  parsed.pathname === '/sootsim/' ||
93
93
  parsed.pathname === '/sootsim'
94
94
  ) {
95
- return 'embedded rnx'
95
+ return 'embedded peach'
96
96
  }
97
97
  return null
98
98
  } catch {
@@ -146,8 +146,8 @@ function printConnectedSims(sims: BridgeSimInfo[], selectedId?: string) {
146
146
  }
147
147
 
148
148
  // classify which engine a sim is running so dev-vs-published is never ambiguous
149
- // to agents or humans reading `rnx list`. dev shell serves local source on
150
- // :5173; the Contrast app embeds rnx on :3000; the bridge/daemon and the
149
+ // to agents or humans reading `peach list`. dev shell serves local source on
150
+ // :5173; the Contrast app embeds peach on :3000; the bridge/daemon and the
151
151
  // /__soot plugin serve the active runtime dir — which, inside a dev checkout, is
152
152
  // the fresh dev-stack build (resolveDevCheckoutRuntimeRoot mode boundary), not a
153
153
  // published runtime. keep this label honest so it never says "published" while
@@ -1,4 +1,4 @@
1
- // `rnx get memory` / `rnx debug memory` — per-worker live object
1
+ // `peach get memory` / `peach debug memory` — per-worker live object
2
2
  // counts (nodes registered, pictures, raster images, paragraphs, yoga wasm
3
3
  // nodes), image-loader cache, and JS heaps. one-shot by default; --watch
4
4
  // samples repeatedly and reports per-counter slope, which is the leak-RCA
@@ -5,7 +5,7 @@ import { isSimSemanticTree, type InspectBridge } from './core'
5
5
  //
6
6
  // pass `positional` from a verb whose positionals are x/y coordinates (tap,
7
7
  // double-tap, long-press) and a bare non-numeric first positional reads as a
8
- // testID: `rnx do tap my-button` works like `do tap-id my-button` and like
8
+ // testID: `peach do tap my-button` works like `do tap-id my-button` and like
9
9
  // `do scroll <id>`, instead of failing with a usage line for the one verb an
10
10
  // agent is most likely to reach for. a coordinate is always numeric, so there
11
11
  // is nothing to disambiguate.
@@ -1,4 +1,4 @@
1
- // `rnx get screens` — print the current navigation stack + shell state +
1
+ // `peach get screens` — print the current navigation stack + shell state +
2
2
  // any presented modal + keyboard. answers "what screen am I on?" without
3
3
  // having to dump the whole tree or scrape screen-specific testIDs.
4
4
  //
@@ -224,7 +224,7 @@ export interface ReloadReadyResult {
224
224
  errors: number
225
225
  }
226
226
 
227
- // post-reload readiness is the same engine-owned condition as `rnx wait ready`.
227
+ // post-reload readiness is the same engine-owned condition as `peach wait ready`.
228
228
  // keeping reload on that primitive prevents another polling implementation
229
229
  // from drifting on loading text, live frames, or tree stability.
230
230
  export async function pollForReloadReady(
@@ -1,4 +1,4 @@
1
- // `rnx get tree` — pruned structured semantic tree, default depth 5.
1
+ // `peach get tree` — pruned structured semantic tree, default depth 5.
2
2
 
3
3
  import { formatSemanticTree, inspectTree, isSimSemanticTree } from './core'
4
4
  import { printJson, wantsJson } from './shared'
@@ -1,4 +1,4 @@
1
- // `rnx get url` — prints the current page URL the bridge is attached to.
1
+ // `peach get url` — prints the current page URL the bridge is attached to.
2
2
 
3
3
  import { inspectUrl } from './core'
4
4
  import { printJson, wantsJson } from './shared'
@@ -1,10 +1,10 @@
1
- // rnx wait event — block until a semantic timeline event of the
1
+ // peach wait event — block until a semantic timeline event of the
2
2
  // given kind appears, or timeout.
3
3
  //
4
4
  // usage:
5
- // rnx wait event <kind> [--max-ms 5000] [--since now|cursor]
6
- // rnx wait event fetch [--filter <substring>]
7
- // rnx wait event screen [--equals SignInPage]
5
+ // peach wait event <kind> [--max-ms 5000] [--since now|cursor]
6
+ // peach wait event fetch [--filter <substring>]
7
+ // peach wait event screen [--equals SignInPage]
8
8
  //
9
9
  // the existing wait family is layout-driven: `wait selector` polls
10
10
  // for a testID, `wait idle` polls for rAF + animation settling,
@@ -111,7 +111,7 @@ function eventMatches(
111
111
  export async function runWaitEventSubcommand(opts: WaitEventOptions): Promise<void> {
112
112
  const { bridge, args, positional, inspectUsage } = opts
113
113
  // positional shape after verb-prefix strip and stripBooleanFlags:
114
- // rnx wait event <kind> → ['event', '<kind>']
114
+ // peach wait event <kind> → ['event', '<kind>']
115
115
  // so positional[1] is the kind.
116
116
  const kind = positional[1]
117
117
  if (!kind) {
@@ -1,5 +1,5 @@
1
- // rnx inspect — dump node tree, accessibility info, query nodes
2
- // connects to the rnx WS bridge (no Playwright)
1
+ // peach inspect — dump node tree, accessibility info, query nodes
2
+ // connects to the peach WS bridge (no Playwright)
3
3
 
4
4
  import { getCliInspectVerbMeta } from '@peach/skills/cli'
5
5
  import { renderCliCommandHelp, renderCliGroupHelp } from '@peach/skills/cli/renderers'
@@ -155,8 +155,8 @@ function formatNetworkDuration(ms: number | null): string {
155
155
  function printRecoverHint(): void {
156
156
  process.stderr.write(
157
157
  ` the sim is not responding. recover it with:\n` +
158
- ` rnx close --sim <id> # force-close the wedged sim\n` +
159
- ` rnx list # confirm it's gone\n`,
158
+ ` peach close --sim <id> # force-close the wedged sim\n` +
159
+ ` peach list # confirm it's gone\n`,
160
160
  )
161
161
  }
162
162
 
@@ -495,7 +495,7 @@ function printRenderProfile(worker: string, rp: Record<string, any> | undefined)
495
495
  // pretty-print the shell frame profile payload (__sootsimShellPerf.stop()):
496
496
  // per-painted-frame timing from the shell worker merged with the render
497
497
  // profile counters. numbers arrive pre-rounded from the worker. also used by
498
- // `rnx maestro test --profile`, which records the same payload.
498
+ // `peach maestro test --profile`, which records the same payload.
499
499
  export function printShellPerfReport(result: Record<string, any>) {
500
500
  const fps = result.avgMs > 0 ? (1000 / result.avgMs).toFixed(1) : '?'
501
501
  const jank = result.jank && typeof result.jank === 'object' ? result.jank : null
@@ -862,7 +862,7 @@ async function performCloudKeys(
862
862
  if (result.ok) return
863
863
  const failed = result.steps.find((step) => !step.ok)
864
864
  console.error(
865
- ` ${actionLabel} failed: ${failed?.error ?? result.error ?? 'no text input had focus'}. focus an input first with rnx do tap-id or rnx do type-into.`,
865
+ ` ${actionLabel} failed: ${failed?.error ?? result.error ?? 'no text input had focus'}. focus an input first with peach do tap-id or peach do type-into.`,
866
866
  )
867
867
  rnxExit(1)
868
868
  }
@@ -877,7 +877,7 @@ async function requireVisualKeyboard(bridge: WsBridge, actionLabel: string) {
877
877
  rnxExit(1)
878
878
  }
879
879
  console.error(
880
- ` ${actionLabel} requires the iOS keyboard to be visible. focus an input first with rnx do tap-id/tap-text or rnx do type-into.`,
880
+ ` ${actionLabel} requires the iOS keyboard to be visible. focus an input first with peach do tap-id/tap-text or peach do type-into.`,
881
881
  )
882
882
  rnxExit(1)
883
883
  }
@@ -913,7 +913,7 @@ async function runShellVisualCommand(
913
913
  code: `(async () => {
914
914
  const toggleLock = window.SootSim?.bridges?.mainShell?.toggleLock
915
915
  if (typeof toggleLock !== 'function') {
916
- throw new Error('rnx mainShell.toggleLock bridge unavailable')
916
+ throw new Error('peach mainShell.toggleLock bridge unavailable')
917
917
  }
918
918
  await toggleLock()
919
919
  return { ok: true, action: 'lock' }
@@ -949,9 +949,9 @@ function keyCodeToVisualKey(code: string) {
949
949
  }
950
950
 
951
951
  function getInspectCommandName(subcommand: string, directSubcommand: string | null) {
952
- if (directSubcommand === subcommand) return `rnx ${subcommand}`
952
+ if (directSubcommand === subcommand) return `peach ${subcommand}`
953
953
  const group = getCliInspectVerbMeta(subcommand)?.group
954
- return group ? `rnx ${group} ${subcommand}` : `rnx ${subcommand}`
954
+ return group ? `peach ${group} ${subcommand}` : `peach ${subcommand}`
955
955
  }
956
956
 
957
957
  function getInspectUsage(
@@ -993,7 +993,7 @@ async function recordInspectAction(
993
993
  '`maestro keep` commits one action at a time',
994
994
  )
995
995
  } else {
996
- console.error(' draft: action pending — `rnx maestro keep` to commit')
996
+ console.error(' draft: action pending — `peach maestro keep` to commit')
997
997
  }
998
998
  }
999
999
 
@@ -1056,9 +1056,9 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1056
1056
  // strip a leading grouping verb — `get`, `do`, and (when forwarded from
1057
1057
  // runDebug) `debug`. these are organizational prefixes and shouldn't leak
1058
1058
  // into subcommand dispatch. e.g.:
1059
- // rnx get tree → effectiveArgs = ['tree']
1060
- // rnx do tap 100 200 → effectiveArgs = ['tap', '100', '200']
1061
- // rnx debug state shell → effectiveArgs = ['state', 'shell']
1059
+ // peach get tree → effectiveArgs = ['tree']
1060
+ // peach do tap 100 200 → effectiveArgs = ['tap', '100', '200']
1061
+ // peach debug state shell → effectiveArgs = ['state', 'shell']
1062
1062
  const verbPrefix =
1063
1063
  args[0] === 'get' || args[0] === 'do' || args[0] === 'debug' || args[0] === 'wait'
1064
1064
  ? args[0]
@@ -1133,21 +1133,21 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1133
1133
  const topLevelCommand = isTopLevel ? effectiveArgs[0] : null
1134
1134
  // a usage string has to name something the user can actually type. the
1135
1135
  // registry knows which group each verb belongs to, so an unprefixed
1136
- // invocation still renders `rnx get tree` rather than a bare verb.
1136
+ // invocation still renders `peach get tree` rather than a bare verb.
1137
1137
  const inspectCommand = (name: string) => {
1138
1138
  if (opts.internalPerfCommand && name === 'perf') {
1139
- return `rnx perf ${opts.internalPerfCommand}`
1139
+ return `peach perf ${opts.internalPerfCommand}`
1140
1140
  }
1141
- if (isTopLevel && name === effectiveArgs[0]) return `rnx ${name}`
1141
+ if (isTopLevel && name === effectiveArgs[0]) return `peach ${name}`
1142
1142
  const group = invocationPrefix ?? getCliInspectVerbMeta(name)?.group
1143
- return group ? `rnx ${group} ${name}` : `rnx ${name}`
1143
+ return group ? `peach ${group} ${name}` : `peach ${name}`
1144
1144
  }
1145
1145
  const inspectUsage = (name: string, tail: string) =>
1146
1146
  ` usage: ${inspectCommand(name)}${tail ? ` ${tail}` : ''}`
1147
1147
 
1148
1148
  if (!subcommand || args.includes('--help') || args.includes('-h')) {
1149
1149
  // all help output comes from the registry in packages/peach-skills
1150
- // so `rnx do --help`, `rnx get --help`, the website docs, and
1150
+ // so `peach do --help`, `peach get --help`, the website docs, and
1151
1151
  // the Contrast skill markdown stay in lock-step. a drift check in
1152
1152
  // test/sootsimCliRegistry.test.ts fails CI if a verb lands without a
1153
1153
  // matching registry entry.
@@ -1217,8 +1217,8 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1217
1217
  return
1218
1218
  }
1219
1219
 
1220
- // `rnx list --drivers` — pure local registry view, no bridge needed.
1221
- // short-circuit here so users can discover drivers even when no rnx
1220
+ // `peach list --drivers` — pure local registry view, no bridge needed.
1221
+ // short-circuit here so users can discover drivers even when no peach
1222
1222
  // session is running.
1223
1223
  if (
1224
1224
  subcommand === 'list' &&
@@ -1327,7 +1327,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1327
1327
  // like a settled sim to the next read, and that read then hands out
1328
1328
  // coordinates the screen is still animating away from.
1329
1329
  process.stderr.write(
1330
- ` ⚠ auto-settle failed (${error instanceof Error ? error.message : String(error)}) — next command may see mid-animation state. use \`rnx do settle\` to retry.\n`,
1330
+ ` ⚠ auto-settle failed (${error instanceof Error ? error.message : String(error)}) — next command may see mid-animation state. use \`peach do settle\` to retry.\n`,
1331
1331
  )
1332
1332
  }
1333
1333
  return
@@ -1345,7 +1345,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1345
1345
  })
1346
1346
  if (!settled) {
1347
1347
  process.stderr.write(
1348
- ` ⚠ auto-wait timed out after ${elapsed ?? budgetMs}ms — next command may see mid-animation state. use \`rnx do settle\` for a longer wait.\n`,
1348
+ ` ⚠ auto-wait timed out after ${elapsed ?? budgetMs}ms — next command may see mid-animation state. use \`peach do settle\` for a longer wait.\n`,
1349
1349
  )
1350
1350
  }
1351
1351
  } catch {
@@ -1360,7 +1360,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1360
1360
  ` tap failed: ${label} resolved to (${Math.round(x)},${Math.round(y)}), outside the ${screen?.width}x${screen?.height} screen`,
1361
1361
  )
1362
1362
  console.error(
1363
- ' the node exists but is scrolled out of view — scroll it on-screen first (rnx do scroll / swipe), then tap.',
1363
+ ' the node exists but is scrolled out of view — scroll it on-screen first (peach do scroll / swipe), then tap.',
1364
1364
  )
1365
1365
  return
1366
1366
  }
@@ -1594,7 +1594,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1594
1594
  if (!seen.has(kind) && n) parts.push(`${n} ${kind}${n === 1 ? '' : 's'}`)
1595
1595
  }
1596
1596
  if (parts.length === 0) return
1597
- console.error(`\n since last: ${parts.join(' · ')} — rnx what-happened`)
1597
+ console.error(`\n since last: ${parts.join(' · ')} — peach what-happened`)
1598
1598
  // advance cursor so the next CLI call only sees *new* events.
1599
1599
  if (payload.summary.lastAt) {
1600
1600
  try {
@@ -1660,7 +1660,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1660
1660
  const verboseTransitions =
1661
1661
  (args.includes('--verbose') || args.includes('-v')) && !args.includes('--json')
1662
1662
  if (invocationPrefix === 'do' && subcommand === 'shell') {
1663
- console.error(' `rnx do shell` was removed. use `rnx shell ...` instead.')
1663
+ console.error(' `peach do shell` was removed. use `peach shell ...` instead.')
1664
1664
  rnxExit(1)
1665
1665
  }
1666
1666
  if (writeCommands.has(subcommand)) {
@@ -1797,9 +1797,9 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1797
1797
  }
1798
1798
 
1799
1799
  case 'event': {
1800
- // rnx wait event <kind> — timeline-backed wait. delegates
1800
+ // peach wait event <kind> — timeline-backed wait. delegates
1801
1801
  // matcher + polling to runWaitEventSubcommand so the same
1802
- // logic is reachable from `rnx wait event` regardless of
1802
+ // logic is reachable from `peach wait event` regardless of
1803
1803
  // verb-group prefix (and the same shape is testable on its
1804
1804
  // own).
1805
1805
  await runWaitEventSubcommand({ bridge, args, positional, inspectUsage })
@@ -1808,7 +1808,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1808
1808
 
1809
1809
  case 'layout': {
1810
1810
  const id = positional[1]
1811
- // bare `rnx get layout` (no id) measures visible elements on the
1811
+ // bare `peach get layout` (no id) measures visible elements on the
1812
1812
  // screen by bounding box. --styling opts into box-model/style detail via
1813
1813
  // the shared get-layout kernel the agent's app_get_layout also uses.
1814
1814
  // passing an id keeps the single-node {x, y, width, height} lookup.
@@ -1844,7 +1844,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1844
1844
  case 'capture':
1845
1845
  case 'screenshot': {
1846
1846
  const outputArg = args.find((_, i) => args[i - 1] === '--output')
1847
- const outputPath = outputArg || '/tmp/rnx-inspect.png'
1847
+ const outputPath = outputArg || '/tmp/peach-inspect.png'
1848
1848
  const rect = await resolveSampleRect(args, bridge)
1849
1849
 
1850
1850
  const request: { type: 'screenshot'; crop?: SampleRect } = { type: 'screenshot' }
@@ -1870,7 +1870,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1870
1870
  ),
1871
1871
  )
1872
1872
  console.error(
1873
- ' samples an averaged color from the canvas. coords are logical rnx units.',
1873
+ ' samples an averaged color from the canvas. coords are logical peach units.',
1874
1874
  )
1875
1875
  rnxExit(1)
1876
1876
  }
@@ -2255,7 +2255,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2255
2255
  const payload = outcome.payload
2256
2256
 
2257
2257
  if (payload?.error === 'bridge-not-ready') {
2258
- console.error(' rnx test bridge not ready')
2258
+ console.error(' peach test bridge not ready')
2259
2259
  rnxExit(1)
2260
2260
  }
2261
2261
 
@@ -2366,7 +2366,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2366
2366
  }
2367
2367
 
2368
2368
  case 'tap-best': {
2369
- // rnx do tap-best <query> — try tap-id, then tap-text. the
2369
+ // peach do tap-best <query> — try tap-id, then tap-text. the
2370
2370
  // common agent ergonomic problem: the agent has a label like
2371
2371
  // "Create expense" and doesn't know whether that's a testID
2372
2372
  // or visible text. with tap-text it fails when the only
@@ -2402,7 +2402,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2402
2402
  | null
2403
2403
  if (!payload) {
2404
2404
  console.error(
2405
- ` tap-best: no testID or visible text matched "${query}". try \`rnx find --interactive-targets\` to list candidates.`,
2405
+ ` tap-best: no testID or visible text matched "${query}". try \`peach find --interactive-targets\` to list candidates.`,
2406
2406
  )
2407
2407
  rnxExit(1)
2408
2408
  }
@@ -2412,7 +2412,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2412
2412
  }
2413
2413
  if (payload.strategy === 'none') {
2414
2414
  console.error(
2415
- ` tap-best: no testID or visible text matched "${query}". try \`rnx find --interactive-targets\` to list candidates.`,
2415
+ ` tap-best: no testID or visible text matched "${query}". try \`peach find --interactive-targets\` to list candidates.`,
2416
2416
  )
2417
2417
  rnxExit(1)
2418
2418
  }
@@ -3102,8 +3102,8 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3102
3102
 
3103
3103
  case 'state': {
3104
3104
  const stateCmd = positional[1]
3105
- // `rnx get state` (no sub-arg) → compact runtime dashboard.
3106
- // `rnx debug state <kind>` continues to dispatch the raw dumps.
3105
+ // `peach get state` (no sub-arg) → compact runtime dashboard.
3106
+ // `peach debug state <kind>` continues to dispatch the raw dumps.
3107
3107
  if (verbPrefix === 'get' && !stateCmd) {
3108
3108
  const base = await callTestBridge<Record<string, any>>(
3109
3109
  bridge,
@@ -3512,14 +3512,14 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3512
3512
 
3513
3513
  case 'reload': {
3514
3514
  // a cloud simulator is a headless runtime with no page to reload, and
3515
- // rnx itself runs inside the box's workerd isolate rather than a node
3515
+ // peach itself runs inside the box's workerd isolate rather than a node
3516
3516
  // process, so the full-page branch below cannot work: it reconnects
3517
3517
  // through `waitForBridgeConnected`, whose `createBridge` constructs the
3518
3518
  // `ws` package's WebSocket, and that import has no constructor in
3519
3519
  // workerd.
3520
3520
  if (bridge.plane === 'cloud') {
3521
3521
  const message =
3522
- 'rnx do reload is not available on a cloud simulator; it runs headless with no page to reload. restart the simulator instead.'
3522
+ 'peach do reload is not available on a cloud simulator; it runs headless with no page to reload. restart the simulator instead.'
3523
3523
  if (wantsJson(effectiveArgs)) {
3524
3524
  printJson({ cleared: false, ready: false, error: message })
3525
3525
  } else {
@@ -3744,7 +3744,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3744
3744
  if (!code) {
3745
3745
  console.error(inspectUsage('js', '<javascript>'))
3746
3746
  console.error('')
3747
- console.error(' runs the snippet in the engine realm. rnx is the')
3747
+ console.error(' runs the snippet in the engine realm. peach is the')
3748
3748
  console.error(' canonical state surface — reach into it directly.')
3749
3749
  console.error('')
3750
3750
  console.error(' examples:')
@@ -3794,24 +3794,24 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3794
3794
  const lc = code.toLowerCase()
3795
3795
  const suggestions: string[] = []
3796
3796
  if (lc.includes('sootsim:gohome') || lc.includes('gohome'))
3797
- suggestions.push('rnx shell home')
3797
+ suggestions.push('peach shell home')
3798
3798
  if (lc.includes('sootsim:appswitcher') || lc.includes('appswitcher'))
3799
- suggestions.push('rnx shell switcher')
3799
+ suggestions.push('peach shell switcher')
3800
3800
  if (lc.includes('keyboard.isvisible') || lc.includes('keyboard.getmode'))
3801
- suggestions.push('rnx debug state keyboard')
3802
- if (lc.includes('interact.tap')) suggestions.push('rnx do tap <x> <y>')
3803
- if (lc.includes('keyboard.type')) suggestions.push('rnx do type <text>')
3801
+ suggestions.push('peach debug state keyboard')
3802
+ if (lc.includes('interact.tap')) suggestions.push('peach do tap <x> <y>')
3803
+ if (lc.includes('keyboard.type')) suggestions.push('peach do type <text>')
3804
3804
  if (lc.includes('keyboard.press') || lc.includes('keyboard.dispatchkey'))
3805
- suggestions.push('rnx do key <name>')
3806
- if (lc.includes('keyboard.dismiss')) suggestions.push('rnx do dismiss')
3807
- if (lc.includes('dumptree')) suggestions.push('rnx get tree')
3808
- if (lc.includes('dumpaccessibilitytree')) suggestions.push('rnx get a11y')
3809
- if (lc.includes('getnodecount')) suggestions.push('rnx get count')
3810
- if (lc.includes('findbytext')) suggestions.push('rnx find <text>')
3805
+ suggestions.push('peach do key <name>')
3806
+ if (lc.includes('keyboard.dismiss')) suggestions.push('peach do dismiss')
3807
+ if (lc.includes('dumptree')) suggestions.push('peach get tree')
3808
+ if (lc.includes('dumpaccessibilitytree')) suggestions.push('peach get a11y')
3809
+ if (lc.includes('getnodecount')) suggestions.push('peach get count')
3810
+ if (lc.includes('findbytext')) suggestions.push('peach find <text>')
3811
3811
  if (lc.includes('findbytestid') || lc.includes('findbyid'))
3812
- suggestions.push('rnx find --testid <id>')
3812
+ suggestions.push('peach find --testid <id>')
3813
3813
  if (lc.includes('document.hidden'))
3814
- suggestions.push('rnx debug state keyboard (includes tab health)')
3814
+ suggestions.push('peach debug state keyboard (includes tab health)')
3815
3815
  if (suggestions.length > 0) {
3816
3816
  maybeHint('prefer-cli-over-eval', suggestions)
3817
3817
  }
@@ -3820,7 +3820,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3820
3820
  }
3821
3821
 
3822
3822
  case 'globals': {
3823
- // show all available rnx globals and their methods
3823
+ // show all available peach globals and their methods
3824
3824
  const info = await bridge.send({
3825
3825
  type: 'evaluate',
3826
3826
  code: `(async () => {
@@ -3862,7 +3862,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3862
3862
  return globals
3863
3863
  })()`,
3864
3864
  })
3865
- console.log(' rnx JS API:\n')
3865
+ console.log(' peach JS API:\n')
3866
3866
  for (const [name, methods] of Object.entries(info as Record<string, string[]>)) {
3867
3867
  console.log(` ${name}:`)
3868
3868
  for (const m of methods) {
@@ -3882,7 +3882,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3882
3882
 
3883
3883
  case 'perf': {
3884
3884
  if (invocationPrefix === 'debug' && !opts.internalPerfCommand) {
3885
- console.error(' `rnx debug perf` was removed. use `rnx perf shell ...`.')
3885
+ console.error(' `peach debug perf` was removed. use `peach perf shell ...`.')
3886
3886
  rnxExit(1)
3887
3887
  }
3888
3888
  const perfCmd = positional[1]
@@ -4316,20 +4316,20 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4316
4316
  }
4317
4317
 
4318
4318
  case 'network': {
4319
- // rnx network — live request inspector backed by the shared
4319
+ // peach network — live request inspector backed by the shared
4320
4320
  // observability store (installed at engine boot, fed by worker-side
4321
4321
  // fetch + XHR capture over BroadcastChannel).
4322
4322
  //
4323
4323
  // shapes:
4324
- // rnx network [limit] last N entries (default 20)
4325
- // rnx network --failed only non-2xx / errored
4326
- // rnx network --slow only requests slower than --threshold (default 1000ms)
4327
- // rnx network --threshold <ms> customize slow threshold for --slow
4328
- // rnx network --filter <substring> url substring filter
4329
- // rnx network --json raw json output
4330
- // rnx network tail | -f follow mode (polls)
4331
- // rnx network get <id> detail for one entry
4332
- // rnx network clear drop the buffer
4324
+ // peach network [limit] last N entries (default 20)
4325
+ // peach network --failed only non-2xx / errored
4326
+ // peach network --slow only requests slower than --threshold (default 1000ms)
4327
+ // peach network --threshold <ms> customize slow threshold for --slow
4328
+ // peach network --filter <substring> url substring filter
4329
+ // peach network --json raw json output
4330
+ // peach network tail | -f follow mode (polls)
4331
+ // peach network get <id> detail for one entry
4332
+ // peach network clear drop the buffer
4333
4333
  const sub = positional[1]
4334
4334
 
4335
4335
  // manual flag scan — parseBridgeCliArgs already stripped these
@@ -4373,7 +4373,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4373
4373
  if (sub === 'get') {
4374
4374
  const id = positional[2]
4375
4375
  if (!id) {
4376
- console.error(' usage: rnx network get <id>')
4376
+ console.error(' usage: peach network get <id>')
4377
4377
  rnxExit(1)
4378
4378
  }
4379
4379
  const entry = (await bridge.send({
@@ -4509,17 +4509,17 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4509
4509
  }
4510
4510
 
4511
4511
  case 'logs': {
4512
- // rnx logs — live console inspector backed by the shared
4512
+ // peach logs — live console inspector backed by the shared
4513
4513
  // observability log store (fed by worker-side console capture over
4514
- // BroadcastChannel). mirrors `rnx network`:
4514
+ // BroadcastChannel). mirrors `peach network`:
4515
4515
  //
4516
- // rnx logs [limit] last N entries (default 50)
4517
- // rnx logs --level error,warn filter by level (csv)
4518
- // rnx logs --filter <str> message substring filter
4519
- // rnx logs --internal include engine-internal [sootsim] logs (hidden by default)
4520
- // rnx logs --json raw json output
4521
- // rnx logs tail | -f follow mode (polls)
4522
- // rnx logs clear drop the buffer
4516
+ // peach logs [limit] last N entries (default 50)
4517
+ // peach logs --level error,warn filter by level (csv)
4518
+ // peach logs --filter <str> message substring filter
4519
+ // peach logs --internal include engine-internal [sootsim] logs (hidden by default)
4520
+ // peach logs --json raw json output
4521
+ // peach logs tail | -f follow mode (polls)
4522
+ // peach logs clear drop the buffer
4523
4523
  const sub = positional[1]
4524
4524
 
4525
4525
  let filter: string | null = null
@@ -4638,11 +4638,11 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4638
4638
  // auto-settle after any write command so the next CLI call doesn't see
4639
4639
  // mid-transition state. short deadline — if the app has a perpetual
4640
4640
  // background animation, we bail to layout-only stability via the same
4641
- // logic `do settle` uses. opt-out: --no-wait or RNX_NO_AUTO_WAIT=1.
4641
+ // logic `do settle` uses. opt-out: --no-wait or PEACH_NO_AUTO_WAIT=1.
4642
4642
  if (
4643
4643
  writeCommands.has(subcommand) &&
4644
4644
  !args.includes('--no-wait') &&
4645
- process.env.RNX_NO_AUTO_WAIT !== '1' &&
4645
+ process.env.PEACH_NO_AUTO_WAIT !== '1' &&
4646
4646
  !(await shouldSkipAutoSettleForInspectPick(bridge, subcommand))
4647
4647
  ) {
4648
4648
  await autoSettleAfterWrite(bridge)
@@ -4677,7 +4677,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4677
4677
  } catch (err: any) {
4678
4678
  rethrowIfExit(err)
4679
4679
  const message = err instanceof Error ? err.message : String(err)
4680
- console.error(` ${subcommand ?? 'rnx'} failed: ${message}`)
4680
+ console.error(` ${subcommand ?? 'peach'} failed: ${message}`)
4681
4681
  const unknownSim = /^no sim connected with id ([^;]+)(?:; connected sims: .+)?$/.exec(
4682
4682
  message,
4683
4683
  )
@@ -4710,9 +4710,9 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4710
4710
  process.stderr.write(
4711
4711
  ` the sim is still responsive — '${cmd}' just exceeded the ${timedOut[1]}s command budget.\n` +
4712
4712
  ` the screen's node tree is large; narrow the query or raise the budget:\n` +
4713
- ` rnx ${cmd} --testid <id> # scope to one subtree\n` +
4714
- ` rnx find --testid <id> # targeted single-node lookup\n` +
4715
- ` rnx ${cmd} --timeout 60000 # raise per-command budget (ms)\n`,
4713
+ ` peach --testid <id> # scope to one subtree\n` +
4714
+ ` peach find --testid <id> # targeted single-node lookup\n` +
4715
+ ` peach --timeout 60000 # raise per-command budget (ms)\n`,
4716
4716
  )
4717
4717
  } else {
4718
4718
  printRecoverHint()