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.
- package/LICENSE +1 -1
- package/README.md +106 -106
- package/cli/app-config.ts +1 -1
- package/cli/app-fonts.ts +4 -4
- package/cli/auth.ts +11 -11
- package/cli/bin.ts +4 -4
- package/cli/bridge-flow-runner.ts +13 -13
- package/cli/browser-evals.ts +2 -2
- package/cli/cli-update.ts +6 -6
- package/cli/cloud-client.ts +16 -16
- package/cli/cloud-dispatch.ts +2 -2
- package/cli/cloud-session.ts +12 -12
- package/cli/cloud-test-tunnel.ts +4 -4
- package/cli/command-registry.ts +7 -7
- package/cli/commands/agent-wrapper.ts +7 -7
- package/cli/commands/agent.ts +16 -16
- package/cli/commands/app-fonts.ts +3 -3
- package/cli/commands/assert.ts +10 -10
- package/cli/commands/auth.ts +5 -5
- package/cli/commands/box/checkout-plane.ts +1 -1
- package/cli/commands/box/plane-share.ts +2 -2
- package/cli/commands/box/rnx-command.ts +5 -5
- package/cli/commands/box.ts +38 -38
- package/cli/commands/camera.ts +13 -13
- package/cli/commands/cleanup.ts +13 -13
- package/cli/commands/compat.ts +7 -7
- package/cli/commands/config.ts +5 -5
- package/cli/commands/control.ts +63 -63
- package/cli/commands/cpu-profile.ts +11 -11
- package/cli/commands/daemon-mac-app.ts +10 -10
- package/cli/commands/daemon.ts +29 -27
- package/cli/commands/debug.ts +35 -35
- package/cli/commands/desktop.ts +3 -3
- package/cli/commands/detox.ts +33 -33
- package/cli/commands/device.ts +9 -9
- package/cli/commands/diagnose.ts +17 -17
- package/cli/commands/do-chain.ts +4 -4
- package/cli/commands/electron.ts +9 -9
- package/cli/commands/film.ts +9 -9
- package/cli/commands/flow.ts +49 -49
- package/cli/commands/inspect/core.ts +12 -12
- package/cli/commands/inspect/count.ts +1 -1
- package/cli/commands/inspect/describe.ts +1 -1
- package/cli/commands/inspect/env.ts +2 -2
- package/cli/commands/inspect/find.ts +2 -2
- package/cli/commands/inspect/get-layout.ts +2 -2
- package/cli/commands/inspect/keyboard.ts +1 -1
- package/cli/commands/inspect/list.ts +4 -4
- package/cli/commands/inspect/memory.ts +1 -1
- package/cli/commands/inspect/resolve-target.ts +1 -1
- package/cli/commands/inspect/screens.ts +1 -1
- package/cli/commands/inspect/shared.ts +1 -1
- package/cli/commands/inspect/tree.ts +1 -1
- package/cli/commands/inspect/url.ts +1 -1
- package/cli/commands/inspect/wait-event.ts +5 -5
- package/cli/commands/inspect.ts +82 -82
- package/cli/commands/install-cli.ts +16 -16
- package/cli/commands/install-desktop.ts +26 -26
- package/cli/commands/login.ts +11 -11
- package/cli/commands/maestro-generate.ts +10 -10
- package/cli/commands/maestro.ts +77 -67
- package/cli/commands/mode.ts +4 -4
- package/cli/commands/no-bridge-hint.ts +12 -12
- package/cli/commands/perf.ts +11 -11
- package/cli/commands/permissions.ts +5 -5
- package/cli/commands/platform.ts +21 -21
- package/cli/commands/preview.ts +5 -5
- package/cli/commands/profile.ts +12 -12
- package/cli/commands/react.ts +15 -15
- package/cli/commands/record.ts +31 -31
- package/cli/commands/report-issue.ts +4 -4
- package/cli/commands/reset.ts +2 -2
- package/cli/commands/runtime.ts +23 -23
- package/cli/commands/screenshot-command.ts +2 -2
- package/cli/commands/screenshot-layers.ts +5 -5
- package/cli/commands/screenshot-mode.ts +7 -7
- package/cli/commands/screenshot.ts +24 -24
- package/cli/commands/screenshots-capture.ts +13 -13
- package/cli/commands/screenshots.ts +6 -6
- package/cli/commands/serve.ts +12 -12
- package/cli/commands/setup.ts +25 -25
- package/cli/commands/skills.ts +30 -23
- package/cli/commands/slides.ts +20 -20
- package/cli/commands/state.ts +2 -2
- package/cli/commands/storage.ts +3 -3
- package/cli/commands/telemetry.ts +2 -2
- package/cli/commands/test.ts +15 -15
- package/cli/commands/three-mode.ts +17 -17
- package/cli/commands/timeline.ts +12 -12
- package/cli/commands/upgrade.ts +11 -11
- package/cli/commands/upload.ts +26 -26
- package/cli/commands/version.ts +7 -7
- package/cli/commands/what-happened.ts +20 -20
- package/cli/current-sim.ts +3 -3
- package/cli/desktop-companion.ts +16 -16
- package/cli/drivers/electron.ts +4 -4
- package/cli/drivers/playwright-sim-host.ts +7 -7
- package/cli/drivers/playwright.ts +4 -4
- package/cli/drivers/registry.ts +1 -1
- package/cli/drivers/types.ts +5 -5
- package/cli/flow-export.ts +1 -1
- package/cli/flow-file.ts +5 -5
- package/cli/flow-session.ts +1 -1
- package/cli/help-core.ts +13 -13
- package/cli/hints.ts +14 -14
- package/cli/inspect-notice-state.ts +1 -1
- package/cli/internal-child.ts +2 -2
- package/cli/maestro-js.ts +4 -4
- package/cli/maestro-report.ts +1 -1
- package/cli/main.ts +14 -14
- package/cli/outbound-endpoints.ts +30 -30
- package/cli/parse-args.ts +7 -7
- package/cli/privacy.ts +1 -1
- package/cli/recording-access.ts +10 -10
- package/cli/resolve-assets.ts +2 -2
- package/cli/rnx-in-process.ts +5 -5
- package/cli/run-registry.ts +1 -1
- package/cli/run-rnx-core.ts +3 -3
- package/cli/run-rnx.ts +1 -1
- package/cli/runtime-notes.ts +1 -1
- package/cli/self-invocation.ts +1 -1
- package/cli/send-to-box.ts +1 -1
- package/cli/shell-init.ts +40 -40
- package/cli/ui.ts +1 -1
- package/cli/ws-bridge.ts +22 -22
- package/detox/config-loader.ts +1 -1
- package/detox/index.ts +28 -28
- package/detox/navigation.ts +2 -2
- package/dist-lib/agent-daemon-client.cjs +12 -12
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +2 -2
- package/dist-lib/agent-sessions.cjs +12 -12
- package/dist-lib/attached-projects.cjs +4 -4
- package/dist-lib/auth/shared-session.cjs +4 -4
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +4 -4
- package/dist-lib/bridge-contract-input.cjs +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +2 -2
- package/dist-lib/bridge-contract.mjs +2 -2
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +42 -42
- package/dist-lib/cloud.mjs +42 -42
- package/dist-lib/config.cjs +2 -2
- package/dist-lib/detox/index.cjs +29 -29
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +12 -12
- package/dist-lib/host/bridge-host.cjs +72 -71
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +6 -6
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +48 -48
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/menu.cjs +5 -5
- package/dist-lib/menu.mjs +5 -5
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +15 -15
- package/dist-lib/profiles.cjs +4 -4
- package/dist-lib/public-brand.cjs +3 -3
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +2 -1
- package/dist-lib/sdk.cjs +9 -9
- package/dist-lib/sdk.mjs +9 -9
- package/dist-lib/skills.cjs +416 -415
- package/dist-lib/swift-compile.cjs +1 -1
- package/dist-lib/swift-compile.mjs +1 -1
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite.cjs +24 -24
- package/package.json +1 -1
- package/scripts/dev-server-scanner.ts +4 -3
- package/skills/contrast/SKILL.md +75 -75
- package/skills/{rnx-debug → peach-debug}/SKILL.md +90 -90
- package/skills/{rnx-perf → peach-perf}/SKILL.md +13 -13
- package/skills/{rnx-setup → peach-setup}/SKILL.md +60 -60
- package/skills/{rnx-test → peach-test}/SKILL.md +44 -44
- package/skills/{rnx-visual → peach-visual}/SKILL.md +26 -26
- package/src/agent-daemon-client.ts +5 -5
- package/src/agent-events.ts +1 -1
- package/src/agent-identity.ts +1 -1
- package/src/agent-sessions.ts +13 -13
- package/src/attached-projects.ts +1 -1
- package/src/auth/shared-session.ts +1 -1
- package/src/bridge-constants.ts +3 -3
- package/src/bridge-contract-input.ts +1 -1
- package/src/bridge-contract.ts +3 -3
- package/src/cli-version.ts +6 -6
- package/src/cloud.ts +40 -40
- package/src/config.ts +1 -1
- package/src/connect.ts +6 -6
- package/src/dev-server-open.ts +8 -8
- package/src/disk-cleanup.ts +3 -3
- package/src/home-paths.ts +26 -26
- package/src/host/agent-host.ts +3 -3
- package/src/host/bridge-host.ts +33 -33
- package/src/host/fetch-proxy-handler.ts +1 -1
- package/src/host/plane-host.ts +2 -2
- package/src/host/replacement-module-handler.ts +2 -2
- package/src/menu.ts +2 -2
- package/src/metro-plugin.ts +7 -7
- package/src/metro-production-bundle.ts +2 -2
- package/src/native-dev-bundle-url.ts +2 -2
- package/src/playwright-host-log.ts +1 -1
- package/src/public-brand.ts +2 -2
- package/src/react-native-host-modules.ts +1 -1
- package/src/rolldown-plugin-swift.ts +3 -3
- package/src/runtime-assets.ts +11 -11
- package/src/runtime-delivery.ts +6 -6
- package/src/screenshots/orchestrate.ts +1 -1
- package/src/screenshots/org-deck.ts +1 -1
- package/src/screenshots/schema.ts +2 -2
- package/src/sim-client.ts +1 -1
- package/src/skills/builtin/compat-check.ts +2 -2
- package/src/vite-plugin-one.ts +8 -8
- package/src/vite-plugin-swift.ts +3 -3
- package/src/vite-plugin.ts +6 -19
package/LICENSE
CHANGED
|
@@ -2,7 +2,7 @@ Proprietary Software License
|
|
|
2
2
|
|
|
3
3
|
Copyright (c) Tamagui LLC. All rights reserved.
|
|
4
4
|
|
|
5
|
-
This package (
|
|
5
|
+
This package (peachsim) is proprietary software of Tamagui LLC, licensed under
|
|
6
6
|
the rnx Software License Agreement: https://rnxsim.com/legal/license
|
|
7
7
|
|
|
8
8
|
In summary (the agreement governs): personal, non-commercial use is free;
|
package/README.md
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
# Peach
|
|
2
2
|
|
|
3
|
-
The source owner for the standalone `
|
|
3
|
+
The source owner for the standalone `peach` executable and the public `peachsim`
|
|
4
4
|
integration library used to drive a browser-native React Native simulator.
|
|
5
5
|
|
|
6
6
|
## Overview
|
|
7
7
|
|
|
8
8
|
The CLI and library are separate public artifacts. The recommended installer
|
|
9
|
-
downloads one Bun-compiled `
|
|
10
|
-
installation. The `
|
|
9
|
+
downloads one Bun-compiled `peach` executable that needs no Node.js, npm, or Bun
|
|
10
|
+
installation. The `peachsim` npm package contains bundler plugins, testing
|
|
11
11
|
drivers, and library exports, with no command-line binary.
|
|
12
12
|
|
|
13
|
-
The executable updates itself with `
|
|
13
|
+
The executable updates itself with `peach upgrade`. Successful interactive human
|
|
14
14
|
commands refresh a cached stable CLI version in a detached process at most once
|
|
15
15
|
every 20 hours. A newer version produces one short notice on stderr, once per
|
|
16
16
|
version and no more than weekly. CI, agents, JSON output, pipes, and
|
|
17
|
-
noninteractive commands stay silent. Set `
|
|
18
|
-
check and notice; `
|
|
17
|
+
noninteractive commands stay silent. Set `PEACH_UPDATE_CHECK=off` to disable the
|
|
18
|
+
check and notice; `peach version` checks explicitly, while `peach --version` remains
|
|
19
19
|
offline.
|
|
20
20
|
|
|
21
21
|
Neither artifact contains rendering code. The canvas engine (CanvasKit
|
|
22
22
|
renderer, Yoga layout, iOS/Android shell chrome, Electron shell) lives in the
|
|
23
23
|
private `sootsim-engine` workspace package and is shipped at runtime as a
|
|
24
|
-
versioned tarball, fetched from the contrast.dev CDN and unpacked into `~/.
|
|
24
|
+
versioned tarball, fetched from the contrast.dev CDN and unpacked into `~/.peach`.
|
|
25
25
|
|
|
26
26
|
What this workspace gives you:
|
|
27
27
|
|
|
28
|
-
- the standalone `
|
|
28
|
+
- the standalone `peach` CLI source and binary build, which provides the primary
|
|
29
29
|
debugging and automation surface (inspect the UI tree, tap elements, capture
|
|
30
30
|
flows, screenshot, record, run agents)
|
|
31
|
-
- `
|
|
31
|
+
- `peachsim/vite` and `peachsim/metro` — bundler plugins that serve the installed
|
|
32
32
|
engine runtime from your own dev server
|
|
33
|
-
- `
|
|
33
|
+
- `peachsim/jump-to-source-babel` — an optional Babel plugin that annotates JSX
|
|
34
34
|
with source locations so inspect mode can open the selected element in your
|
|
35
35
|
editor
|
|
36
36
|
- `peachsim/detox` — a drop-in Detox driver + jest preset
|
|
37
|
-
- `
|
|
38
|
-
- `
|
|
37
|
+
- `peachsim/sdk` — the inspect/interact verbs as a programmatic API
|
|
38
|
+
- `peachsim/bridge-contract-input` — parsers turning untrusted JSON into
|
|
39
39
|
bridge-contract arguments
|
|
40
|
-
- `
|
|
40
|
+
- `peachsim/skills` — a registry of Contrast-flavored automation skills
|
|
41
41
|
|
|
42
42
|
Platform status: iOS is the parity baseline. Android is bootstrapped and usable
|
|
43
43
|
for focused conformance slices (bundle/runtime identity, device profiles, shell
|
|
@@ -47,7 +47,7 @@ repo plan pass.
|
|
|
47
47
|
|
|
48
48
|
## What's in each distribution
|
|
49
49
|
|
|
50
|
-
| standalone `
|
|
50
|
+
| standalone `peach` executable | `peachsim` npm package | private engine runtime |
|
|
51
51
|
| --- | --- | --- |
|
|
52
52
|
| CLI commands and bridge client | Vite and Metro plugins | CanvasKit renderer and Yoga layout |
|
|
53
53
|
| bridge daemon host | SDK and bridge contracts | iOS/Android shell chrome, home grid, app switcher |
|
|
@@ -66,7 +66,7 @@ internally splits into shell, compositor, and tenant workers.
|
|
|
66
66
|
|
|
67
67
|
```mermaid
|
|
68
68
|
graph TD
|
|
69
|
-
subgraph cli["
|
|
69
|
+
subgraph cli["peach CLI process (short-lived, cli/)"]
|
|
70
70
|
BIN["bin.ts (dispatcher + privacy choice)"]
|
|
71
71
|
SETUP["commands/setup.ts (guided daemon setup)"]
|
|
72
72
|
RUNTIMECMD["commands/runtime.ts (runtime install/use)"]
|
|
@@ -92,14 +92,14 @@ graph TD
|
|
|
92
92
|
TENANTW["tenant worker (guest RN app tree)"]
|
|
93
93
|
end
|
|
94
94
|
subgraph build["build-time plugins (src/)"]
|
|
95
|
-
VITEONE["
|
|
95
|
+
VITEONE["peachsim/vite = vite-plugin-one.ts (serve runtime at /__soot/)"]
|
|
96
96
|
VITERN["sootsim() = vite-plugin.ts (RN resolver + native stubs)"]
|
|
97
|
-
METRO["
|
|
97
|
+
METRO["peachsim/metro = metro-plugin.ts"]
|
|
98
98
|
COMPAT["@sootsim/compat stub-manifest (native seams)"]
|
|
99
99
|
ENGINESHIM["sootsim-engine react-native shim"]
|
|
100
100
|
end
|
|
101
|
-
SKILLS["
|
|
102
|
-
subgraph fs["~/.
|
|
101
|
+
SKILLS["peachsim/skills registry.ts (builtin skills)"]
|
|
102
|
+
subgraph fs["~/.peach (home-paths.ts)"]
|
|
103
103
|
RTDIR["runtimes/<version>/ (engine assets)"]
|
|
104
104
|
LOCK["daemon.json lockfile"]
|
|
105
105
|
CFG["config.json"]
|
|
@@ -146,22 +146,22 @@ graph TD
|
|
|
146
146
|
```
|
|
147
147
|
|
|
148
148
|
**The CLI process** (`cli/bin.ts` routes, `cli/main.ts` parses argv) lazy-imports
|
|
149
|
-
exactly one command module per run. Bare `
|
|
149
|
+
exactly one command module per run. Bare `peach` opens ConnectRN, whose simulator UI discovers
|
|
150
150
|
running React Native development servers. The first human run offers the
|
|
151
151
|
recommended background service and optional Desktop app, then opens the simulator
|
|
152
|
-
before asking about private diagnostics or an optional repository install. `
|
|
152
|
+
before asking about private diagnostics or an optional repository install. `peach open`
|
|
153
153
|
ensures the engine runtime exists and starts a local foreground bridge when no
|
|
154
154
|
daemon is reachable, then opens a `WsBridge` (`cli/ws-bridge.ts`) on **port
|
|
155
155
|
7668** and sends JSON commands. Inspection/interaction verbs live in
|
|
156
|
-
`cli/commands/inspect/*` and are re-exported as the programmatic `
|
|
156
|
+
`cli/commands/inspect/*` and are re-exported as the programmatic `peachsim/sdk`;
|
|
157
157
|
the Maestro runner is `cli/bridge-flow-runner.ts`; the Detox compat driver
|
|
158
158
|
is in `detox/`. Test and screenshot paths additionally use `cli/drivers/*`.
|
|
159
159
|
Browser sims launch in an isolated Playwright Chrome for Testing profile;
|
|
160
160
|
Electron is the native desktop surface.
|
|
161
161
|
|
|
162
162
|
**The daemon is one process** — `SootSimBridgeHost` (`src/host/bridge-host.ts`).
|
|
163
|
-
`
|
|
164
|
-
process* wrapped with autostart and the `~/.
|
|
163
|
+
`peach serve` runs it in the foreground; the background daemon is the *same
|
|
164
|
+
process* wrapped with autostart and the `~/.peach/daemon.json` lockfile. It is
|
|
165
165
|
an HTTP+WS hub: sims register over WS, CLI clients connect to drive them, and
|
|
166
166
|
the host forwards each command to the targeted sim and relays the reply back. It
|
|
167
167
|
also serves the engine runtime over HTTP (with a self-update route), exposes
|
|
@@ -171,11 +171,11 @@ localhost. The `AgentHost` extension owns one FIFO reader per agent session and
|
|
|
171
171
|
fans agent events out to every subscriber.
|
|
172
172
|
|
|
173
173
|
During source development, each Vite bridge owns one
|
|
174
|
-
`~/.
|
|
174
|
+
`~/.peach/dev-bridges/<port>.json` heartbeat record. CLI defaults select the
|
|
175
175
|
current `PORT_OFFSET`, then the current checkout, then the canonical `:7668`
|
|
176
176
|
bridge, so concurrent worktrees cannot replace or delete one another's address.
|
|
177
177
|
Each Vite shell also publishes its exact bridge at `/__sootsim/bridge`, so a
|
|
178
|
-
launcher that reuses a shell from another isolated `
|
|
178
|
+
launcher that reuses a shell from another isolated `PEACH_HOME` stays in that
|
|
179
179
|
shell's bridge world without reading the other process's lockfile directory.
|
|
180
180
|
|
|
181
181
|
**The sim** is a browser/Electron *page* launched by a CLI driver. Inside that
|
|
@@ -186,17 +186,17 @@ bridge always addresses the **shell worker**, never an undifferentiated sim.
|
|
|
186
186
|
|
|
187
187
|
**Two distinct plugin families** round it out, and they must not be conflated:
|
|
188
188
|
|
|
189
|
-
- The published **`
|
|
190
|
-
and **`
|
|
189
|
+
- The published **`peachsim/vite`** (`src/vite-plugin-one.ts`, `rnxPlugin`)
|
|
190
|
+
and **`peachsim/metro`** plugins do one thing: serve the installed runtime at
|
|
191
191
|
`/__soot/` so an app's own dev server can host the sim shell. The Vite plugin accepts an
|
|
192
192
|
opt-in `open` option that launches a named Electron window when the dev server
|
|
193
|
-
starts (skipped when `CI` or `
|
|
193
|
+
starts (skipped when `CI` or `PEACH_NO_OPEN` is set).
|
|
194
194
|
- The internal **`sootsim()`** plugin (`src/vite-plugin.ts`) is a separate, much
|
|
195
195
|
larger RN-resolution / native-stub plugin: it aliases `react-native` to the
|
|
196
196
|
engine shim and native packages to `@sootsim/compat` stubs, applies worklets
|
|
197
197
|
transforms, and is the one that instantiates `SootSimBridgeHost` inside its
|
|
198
198
|
own dev server. It is used to build the engine/shell and to load external RN
|
|
199
|
-
apps — it is **not** the published `
|
|
199
|
+
apps — it is **not** the published `peachsim/vite` export.
|
|
200
200
|
|
|
201
201
|
## Key components
|
|
202
202
|
|
|
@@ -204,60 +204,60 @@ bridge always addresses the **shell worker**, never an undifferentiated sim.
|
|
|
204
204
|
| --- | --- | --- |
|
|
205
205
|
| Peach CLI (bin + dispatcher) | Short-lived terminal entry point. Parses argv, owns the private-by-default one-time choice, lazy-imports one command per run, and routes direct open/runtime/inspection flows. | `cli/bin.ts`, `cli/main.ts`, `cli/privacy.ts`, `cli/parse-args.ts`, `cli/help.ts`, `cli/commands/setup.ts`, `cli/commands/control.ts` |
|
|
206
206
|
| WsBridge client | Client side of the CLI→daemon link. Resolves the daemon port from the lockfile, opens a WS to `:7668`, sends JSON commands and awaits `{id,result}`/`{id,error}`. Used by every interactive command. | `cli/ws-bridge.ts`, `src/bridge-constants.ts`, `cli/current-sim.ts` |
|
|
207
|
-
| inspect / SDK command surface | Runtime inspection + interaction verbs (describe, find, do tap, get errors, wait, layout, settle). Re-exported as `
|
|
207
|
+
| inspect / SDK command surface | Runtime inspection + interaction verbs (describe, find, do tap, get errors, wait, layout, settle). Re-exported as `peachsim/sdk` so programmatic callers drive a sim the same way the CLI does. | `cli/commands/inspect/core.ts`, `cli/commands/inspect/actions.ts`, `cli/commands/inspect.ts`, `src/sdk.ts` |
|
|
208
208
|
| bridge-contract input parsers | Turn untrusted JSON into typed bridge-contract arguments, so a transport in front of a sim validates request bodies once instead of writing a second reader. | `src/bridge-contract-input.ts`, `src/bridge-contract.ts` |
|
|
209
209
|
| Maestro / Detox runners | Drop-in test compatibility. `bridge-flow-runner.ts` runs Maestro YAML and recorded flows over the bridge; `detox/` provides a `by`/`element`/`expect`/`device` driver + jest preset so existing Detox suites run unchanged. | `cli/bridge-flow-runner.ts`, `cli/commands/maestro.ts`, `cli/commands/detox.ts`, `detox/index.ts`, `detox/jest-preset.cjs` |
|
|
210
210
|
| sim drivers | Launch or attach the actual sim page. Playwright owns isolated browser profiles; Electron owns the native desktop surface. The current sim is reused unless `--new`, `--profile`, or `--ephemeral` requests a separate one. | `cli/drivers/index.ts`, `cli/drivers/registry.ts`, `cli/drivers/electron.ts`, `cli/drivers/playwright.ts` |
|
|
211
|
-
| SootSimBridgeHost (serve/daemon) | The bridge process (`
|
|
211
|
+
| SootSimBridgeHost (serve/daemon) | The bridge process (`peach serve`, or autostarted as the daemon via launchd/systemd). HTTP+WS hub on `:7668`: relays commands between CLI clients and registered sims; also serves runtime HTTP, `/__server-scan`, and fetch/WS proxies. | `src/host/bridge-host.ts`, `cli/commands/serve.ts`, `cli/commands/daemon.ts`, `src/home-paths.ts` |
|
|
212
212
|
| AgentHost + sessions | Agent-routing extension of the host: owns the single FIFO reader per agent session and fans `agent:event`/`session-status` pushes to every WS subscriber. Backed by agent-sessions + attached-projects stores. | `src/host/agent-host.ts`, `src/agent-sessions.ts`, `src/attached-projects.ts`, `src/agent-daemon-client.ts` |
|
|
213
213
|
| host proxies + dev-server scan | Host-side helpers so a cross-origin tenant worker can reach local dev servers and same-origin APIs: `/__server-scan` discovers running metro/expo/vxrn/one servers; fetch + websocket proxies relay guest-app network through the daemon. | `src/host/fetch-proxy-handler.ts`, `src/host/websocket-proxy.ts`, `scripts/dev-server-scanner.ts`, `src/dev-bundle-resolution.ts` |
|
|
214
|
-
| runtime delivery + Peach home | Versioned engine runtime management. The shared machinery owns manifest fetch, sha256 verification, channels, and auto-update. Peach binds it to `https://contrast.dev` and `~/.
|
|
214
|
+
| runtime delivery + Peach home | Versioned engine runtime management. The shared machinery owns manifest fetch, sha256 verification, channels, and auto-update. Peach binds it to `https://contrast.dev` and `~/.peach/runtimes/<version>`. A repo can select `runtimeVersion` without changing the machine default. | `src/runtime-delivery.ts`, `packages/contrast-runtime-delivery/`, `src/home-paths.ts`, `src/runtime-assets.ts` |
|
|
215
215
|
| standalone CLI delivery | Cached stable-version checks, bounded interactive notices, and verified atomic executable replacement. | `cli/cli-update.ts`, `cli/commands/upgrade.ts`, `cli/commands/version.ts`, `src/cli-version.ts` |
|
|
216
|
-
| `
|
|
217
|
-
| `sootsim()` vite resolver plugin (internal) | The large RN-resolution / native-stub vite plugin: aliases `react-native` to the engine shim, native packages to `@sootsim/compat` stubs, applies worklets/babel transforms, and instantiates `SootSimBridgeHost` in its dev server. Distinct from the published `
|
|
218
|
-
| skills registry | Peach agent skills (`rnx-setup`, `rnx-debug`, `rnx-test`, `rnx-visual`, and the generated `contrast` index) installable with `
|
|
216
|
+
| `peachsim/vite` + `peachsim/metro` (runtime serving) | Published bundler plugins. Both serve the installed engine runtime at `/__soot/` from `~/.peach/runtimes/<version>` so an app's own dev server can host the sim shell; the Vite plugin can opt into a named Electron window. | `src/vite-plugin-one.ts`, `src/metro-plugin.ts`, `src/runtime-assets.ts` |
|
|
217
|
+
| `sootsim()` vite resolver plugin (internal) | The large RN-resolution / native-stub vite plugin: aliases `react-native` to the engine shim, native packages to `@sootsim/compat` stubs, applies worklets/babel transforms, and instantiates `SootSimBridgeHost` in its dev server. Distinct from the published `peachsim/vite` export. | `src/vite-plugin.ts`, `src/worklets-babel.ts`, `packages/peach-compat/src/stub-manifest.ts` |
|
|
218
|
+
| skills registry | Peach agent skills (`rnx-setup`, `rnx-debug`, `rnx-test`, `rnx-visual`, and the generated `contrast` index) installable with `peach skill`. | `skills/*.md`, `src/skills/registry.ts`, `src/skills/types.ts` |
|
|
219
219
|
|
|
220
220
|
## Getting started
|
|
221
221
|
|
|
222
222
|
```sh
|
|
223
223
|
curl -fsSL https://rnxsim.com/install.sh | sh
|
|
224
|
-
|
|
225
|
-
|
|
224
|
+
peach # open ConnectRN and choose a running app in the simulator
|
|
225
|
+
peach open /settings # dispatch a React Native deep link into that app
|
|
226
226
|
```
|
|
227
227
|
|
|
228
228
|
Start Metro, Expo, One, or another supported React Native development server
|
|
229
|
-
the way you normally do, then run `
|
|
229
|
+
the way you normally do, then run `peach` from any directory. The simulator
|
|
230
230
|
opens ConnectRN, which shows the available local apps and lets you connect one.
|
|
231
|
-
Pass a target to `
|
|
231
|
+
Pass a target to `peach open <port-or-url>` when a script or agent needs an explicit
|
|
232
232
|
selection.
|
|
233
233
|
|
|
234
|
-
The first `
|
|
234
|
+
The first `peach open` launches an isolated Chrome for Testing sim. The CLI
|
|
235
235
|
resolves Playwright from the app or CLI install, asks that exact package for
|
|
236
236
|
its required browser executable, and runs that package's installer once when
|
|
237
237
|
the executable is absent. It never substitutes another revision found in the
|
|
238
238
|
shared Playwright cache. Later opens reuse that sim and reload it at the
|
|
239
|
-
requested target. Use `
|
|
239
|
+
requested target. Use `peach do reload` when the target has not changed.
|
|
240
240
|
Reserve `--new` for a genuinely concurrent sim; repeated new browser trees
|
|
241
241
|
consume memory and CPU on shared machines.
|
|
242
242
|
|
|
243
|
-
The public installer places one standalone `
|
|
244
|
-
The `
|
|
243
|
+
The public installer places one standalone `peach` executable in `~/.local/bin`.
|
|
244
|
+
The `peachsim` npm package contains bundler plugins and library exports, not a CLI
|
|
245
245
|
binary. Start your Metro, Expo, or One dev server the way you already do, then
|
|
246
246
|
open it from the CLI. There is no iOS native build in the inner loop; Metro alone is
|
|
247
247
|
enough. The manifest bundle path and query remain authoritative. When both the
|
|
248
248
|
discovery request and manifest target are loopback addresses, Peach keeps the
|
|
249
249
|
loopback host that answered discovery so an IPv6-only listener is not reopened
|
|
250
|
-
through an unreachable IPv4 address. `
|
|
250
|
+
through an unreachable IPv4 address. `peach open` starts a local bridge when no
|
|
251
251
|
daemon is reachable. The background service is strongly recommended for local
|
|
252
252
|
agent work because inspect, interaction, and test commands reuse one ready bridge
|
|
253
|
-
and runtime. Enable it at any time with `
|
|
253
|
+
and runtime. Enable it at any time with `peach daemon install`; it is never required
|
|
254
254
|
in CI. The packaged Desktop app is optional and available through first-run
|
|
255
|
-
onboarding or `
|
|
255
|
+
onboarding or `peach desktop install`. A downloaded app starts its own bundled
|
|
256
256
|
daemon on first launch, then offers **Install the Peach command** over the running
|
|
257
|
-
simulator. That action installs `~/.local/bin/
|
|
257
|
+
simulator. That action installs `~/.local/bin/peach`, updates shell startup, and
|
|
258
258
|
hands the daemon to launchd or systemd without reloading the window. Windows
|
|
259
|
-
keeps the desktop-owned daemon because it has no daemon service yet. Native Electron windows created by `
|
|
260
|
-
session and close when the session exits; `
|
|
259
|
+
keeps the desktop-owned daemon because it has no daemon service yet. Native Electron windows created by `peach open` belong to that CLI
|
|
260
|
+
session and close when the session exits; `peach desktop` keeps the persistent
|
|
261
261
|
desktop-app lifecycle. In Electron, `File > New Window`
|
|
262
262
|
duplicates the focused simulator, while `File > New Simulator >` opens a new
|
|
263
263
|
window for a selected device (same device list as the `Window >` menu).
|
|
@@ -268,7 +268,7 @@ Peach sends no analytics, crash report, command event, app data, project data, o
|
|
|
268
268
|
identity by default. An unsigned-in interactive run may request the runtime it
|
|
269
269
|
is about to execute and the stable standalone CLI version document. The latter
|
|
270
270
|
runs after the command in a detached process at most once every 20 hours and can
|
|
271
|
-
be disabled with `
|
|
271
|
+
be disabled with `PEACH_UPDATE_CHECK=off`. The first human run asks once about
|
|
272
272
|
bounded diagnostics, defaults to no, and never prompts in a non-TTY shell, CI,
|
|
273
273
|
or an agent. An automated first run is declined for that process without
|
|
274
274
|
consuming the later human choice. Legacy browser and Electron telemetry senders
|
|
@@ -281,13 +281,13 @@ login, upload, billing, issue reporting, generated flows, and screenshot decks
|
|
|
281
281
|
contact their documented service only when explicitly invoked. The complete
|
|
282
282
|
enforced network contract is in [`specs/rnx-privacy.md`](../../specs/rnx-privacy.md).
|
|
283
283
|
|
|
284
|
-
`
|
|
284
|
+
`peach daemon uninstall` removes the machine daemon: it stops current and legacy
|
|
285
285
|
launchd / systemd services and removes their logs, launcher, and generated
|
|
286
|
-
`.app` wrapper. `~/.
|
|
286
|
+
`.app` wrapper. `~/.peach/` survives, because runtimes, device profiles and their
|
|
287
287
|
app storage, and live dev-bridge records belong to simulators the user may
|
|
288
|
-
still be running. `
|
|
288
|
+
still be running. `peach daemon uninstall --purge` deletes `~/.peach/` as well.
|
|
289
289
|
Neither form removes the optional `/Applications/rnx.app` desktop bundle or the
|
|
290
|
-
macOS preference plist. To inspect existing disk usage first, run `
|
|
290
|
+
macOS preference plist. To inspect existing disk usage first, run `peach cleanup`;
|
|
291
291
|
add `--apply` only after reviewing the preview.
|
|
292
292
|
|
|
293
293
|
## Jump to source in inspect mode
|
|
@@ -299,7 +299,7 @@ Metro/Babel config:
|
|
|
299
299
|
```js
|
|
300
300
|
plugins: [
|
|
301
301
|
[
|
|
302
|
-
'
|
|
302
|
+
'peachsim/jump-to-source-babel',
|
|
303
303
|
{
|
|
304
304
|
include: [__dirname],
|
|
305
305
|
},
|
|
@@ -340,46 +340,46 @@ inspection, interaction, animation debugging, shell tracing, screenshots, and
|
|
|
340
340
|
flow capture, not just as a test runner.
|
|
341
341
|
|
|
342
342
|
```sh
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
343
|
+
peach list # connected tabs
|
|
344
|
+
peach open 8081 # load a running metro/expo dev server
|
|
345
|
+
peach open /settings # route via React Native Linking
|
|
346
|
+
peach describe # dump UI tree
|
|
347
|
+
peach get errors 5 # recent runtime failures
|
|
348
|
+
peach compat # scan native package compatibility
|
|
349
|
+
peach report-issue "…" # preview an opt-in compatibility report
|
|
350
|
+
peach find --testid cta # inspect one node deeply
|
|
351
|
+
peach debug enable animated,layout
|
|
352
|
+
peach debug trace shell on 240
|
|
353
|
+
peach do tap-text "..." # interact
|
|
354
|
+
peach do tap email --then type user@example.com --then tap submit
|
|
355
|
+
peach debug snapshot before
|
|
356
|
+
peach debug snapshot after
|
|
357
|
+
peach debug diff before after
|
|
358
|
+
peach maestro start # begin a Maestro draft
|
|
359
|
+
peach maestro keep # persist the last action
|
|
360
|
+
peach maestro end --output .maestro/login.yaml --validate
|
|
361
|
+
peach detox # run Detox/Jest suites against rnx
|
|
362
362
|
```
|
|
363
363
|
|
|
364
|
-
See the full command reference via `
|
|
364
|
+
See the full command reference via `peach --help` or at
|
|
365
365
|
`src/features/site/docs/rnx/cli/` in the Contrast repo.
|
|
366
366
|
|
|
367
367
|
Sim-scoped commands use the primary fallback only when one driveable sim is
|
|
368
368
|
connected. With multiple driveable sims, the bridge lists their ids and refuses
|
|
369
|
-
to choose. Run `
|
|
369
|
+
to choose. Run `peach use <id>` to pin later commands, or pass `--sim <id>` to
|
|
370
370
|
target one command.
|
|
371
371
|
|
|
372
|
-
Use an inline `
|
|
372
|
+
Use an inline `peach do` chain for a short action sequence that should execute as
|
|
373
373
|
one engine batch. Repeat `--then` before each additional action. Each phrase
|
|
374
374
|
uses the same positional grammar as its standalone `do` command. Touch timing
|
|
375
375
|
stays inside the sim, the batch stops at the first failure, and `--json` prints
|
|
376
376
|
the complete per-step result. Reusable file-based flows stay in Maestro YAML.
|
|
377
377
|
|
|
378
378
|
```sh
|
|
379
|
-
|
|
379
|
+
peach do tap email --then type user@example.com --then tap submit
|
|
380
380
|
```
|
|
381
381
|
|
|
382
|
-
## Bundler plugins (`
|
|
382
|
+
## Bundler plugins (`peachsim/vite` and `peachsim/metro`)
|
|
383
383
|
|
|
384
384
|
The Vite plugin serves the installed Peach runtime from your existing dev server.
|
|
385
385
|
|
|
@@ -451,8 +451,8 @@ no code changes — just add one line to your jest config:
|
|
|
451
451
|
Or use the CLI directly:
|
|
452
452
|
|
|
453
453
|
```sh
|
|
454
|
-
|
|
455
|
-
|
|
454
|
+
peach detox # auto-discovers e2e/ tests and launches a shell
|
|
455
|
+
peach detox init # scaffold a config + sample test
|
|
456
456
|
```
|
|
457
457
|
|
|
458
458
|
See `../../docs/migrating-from-detox.md` for details.
|
|
@@ -463,10 +463,10 @@ Maestro is Peach's single YAML test surface. Point it at your existing
|
|
|
463
463
|
`.maestro/` directory, generate a test, or author one from live actions:
|
|
464
464
|
|
|
465
465
|
```sh
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
466
|
+
peach maestro # discover .maestro/ and run all flows
|
|
467
|
+
peach maestro test .maestro/ # explicit
|
|
468
|
+
peach maestro generate "verify login"
|
|
469
|
+
peach maestro --list-compat # see the verb support matrix
|
|
470
470
|
```
|
|
471
471
|
|
|
472
472
|
Most Maestro verbs work out of the box (`tapOn`, `assertVisible`, `inputText`,
|
|
@@ -479,22 +479,22 @@ need real device hardware (GPS, radio, photo library) throw a clear error. See
|
|
|
479
479
|
For animation-heavy debugging, the useful path is usually:
|
|
480
480
|
|
|
481
481
|
```sh
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
482
|
+
peach debug enable animated
|
|
483
|
+
peach debug trace shell on 240
|
|
484
|
+
peach debug snapshot before
|
|
485
485
|
# reproduce the transition
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
486
|
+
peach debug snapshot after
|
|
487
|
+
peach debug diff before after
|
|
488
|
+
peach screenshot --with-frame --output /tmp/rnx-framed.png
|
|
489
|
+
peach record --duration 5 --output /tmp/rnx-anim.mp4
|
|
490
490
|
```
|
|
491
491
|
|
|
492
|
-
`
|
|
492
|
+
`peach screenshot --with-frame` composes the real Peach shell device chrome
|
|
493
493
|
around the raw screen bitmap (reusing the shell bezel/button geometry, excluding
|
|
494
494
|
the Electron top bar, rail gutter, and other window chrome). Flows can request
|
|
495
495
|
the framed export inline without changing Maestro syntax:
|
|
496
496
|
|
|
497
|
-
`
|
|
497
|
+
`peach wait ready` and the screenshot readiness guard accept inspectable
|
|
498
498
|
native content, a populated node tree, or a live-frame channel whose publish
|
|
499
499
|
count advances across probes. Canvas-only GL, WebGPU, and video surfaces can
|
|
500
500
|
therefore prove that they are painting without weakening the boot-card guard.
|
|
@@ -506,7 +506,7 @@ therefore prove that they are painting without weakening the boot-card guard.
|
|
|
506
506
|
withFrame: true
|
|
507
507
|
```
|
|
508
508
|
|
|
509
|
-
For plan-driven app-store exports, use `
|
|
509
|
+
For plan-driven app-store exports, use `peach screenshot appstore`:
|
|
510
510
|
|
|
511
511
|
```yaml
|
|
512
512
|
app: 8081
|
|
@@ -529,14 +529,14 @@ compose:
|
|
|
529
529
|
```
|
|
530
530
|
|
|
531
531
|
```sh
|
|
532
|
-
|
|
532
|
+
peach screenshot appstore --plan .peach/app-store.yaml
|
|
533
533
|
```
|
|
534
534
|
|
|
535
535
|
The plan runner can reuse a visible sim for capture (`--sim a9`), stop after
|
|
536
536
|
raw/framed intermediates (`--capture-only`), or rerender final marketing
|
|
537
537
|
canvases from an existing raw directory (`--compose-only`). If your flow already
|
|
538
538
|
writes screenshots to explicit project paths, set `from:` + `pathMode: flow` so
|
|
539
|
-
`
|
|
539
|
+
`peach screenshot appstore` respects the flow's own `takeScreenshot` paths
|
|
540
540
|
instead of prepending `--screenshots <rawDir>`:
|
|
541
541
|
|
|
542
542
|
```yaml
|
|
@@ -553,7 +553,7 @@ frame for quick art-direction passes.
|
|
|
553
553
|
|
|
554
554
|
## Skills registry
|
|
555
555
|
|
|
556
|
-
`
|
|
556
|
+
`peach skill install` installs Peach agent skills in the standard
|
|
557
557
|
`<skill-name>/SKILL.md` layout used by Codex and Claude Code. The bundled
|
|
558
558
|
skills cover setup, debugging/perf/accessibility, testing, visual review, and
|
|
559
559
|
the generated `contrast` command index. The published CLI registry and generated
|
|
@@ -576,10 +576,10 @@ Peach's CDN origin (default `https://contrast.dev`, overridable in
|
|
|
576
576
|
them to the shared delivery machinery in `@contrast/runtime-delivery` — an
|
|
577
577
|
internal workspace package the CLI bundles, so a published install has it
|
|
578
578
|
inlined. That machinery fetches `runtimes/manifest.json` + the runtime tarball,
|
|
579
|
-
verifies its sha256, and unpacks it under `~/.
|
|
579
|
+
verifies its sha256, and unpacks it under `~/.peach`:
|
|
580
580
|
|
|
581
581
|
```
|
|
582
|
-
~/.
|
|
582
|
+
~/.peach/
|
|
583
583
|
├── runtimes/
|
|
584
584
|
│ ├── <active>/ unpacked engine assets (served at /__soot/)
|
|
585
585
|
│ └── <rollback>/ previous version for rollback
|
|
@@ -593,7 +593,7 @@ verifies its sha256, and unpacks it under `~/.rnx`:
|
|
|
593
593
|
```
|
|
594
594
|
|
|
595
595
|
The bridge daemon serves these assets over HTTP and exposes a self-update route;
|
|
596
|
-
`
|
|
596
|
+
`peach upgrade` / `peach runtime` drive explicit version changes from the
|
|
597
597
|
CLI side. Installation retains the active runtime plus one rollback and removes
|
|
598
598
|
the downloaded archive after extraction. Disposable Playwright caches live in a
|
|
599
599
|
bounded per-session temporary directory; Electron's persistent HTTP cache is
|
|
@@ -601,11 +601,11 @@ disabled for simulator profiles and globally capped for app chrome. Cookies,
|
|
|
601
601
|
localStorage, IndexedDB, service workers, recordings, and captured frames are
|
|
602
602
|
user-owned data and are not removed by the default cleanup command.
|
|
603
603
|
|
|
604
|
-
Per-repo configuration is optional. Every installed-runtime `
|
|
604
|
+
Per-repo configuration is optional. Every installed-runtime `peach open`
|
|
605
605
|
serves its selected version from a version-specific localhost origin, so a
|
|
606
606
|
background activation cannot mix an already loaded shell with chunks from the
|
|
607
607
|
next runtime. Without config, each new open selects the active stable version.
|
|
608
|
-
When `rnx.config.ts` sets `runtimeVersion`, `
|
|
608
|
+
When `rnx.config.ts` sets `runtimeVersion`, `peach open` installs that
|
|
609
609
|
version without changing the machine default. App config, native-linked fonts,
|
|
610
610
|
and splash assets all resolve from the project root advertised by the selected
|
|
611
611
|
development server. Bare Metro, which has no Expo manifest project root, uses
|
|
@@ -620,7 +620,7 @@ maintenance process. The app and terminal command are usable before the legacy
|
|
|
620
620
|
filesystem scan begins. The worker prints the reclaimed size to stderr, records
|
|
621
621
|
completion, and does not run the scan again. Open browser profiles and a runtime
|
|
622
622
|
served by a live daemon or development bridge are left untouched. The automatic
|
|
623
|
-
pass retries on a later command after they close. The explicit `
|
|
623
|
+
pass retries on a later command after they close. The explicit `peach cleanup --aggressive`
|
|
624
624
|
command remains the only path that removes the rollback runtime or user-created
|
|
625
625
|
recordings.
|
|
626
626
|
|
|
@@ -633,7 +633,7 @@ for the current platform:
|
|
|
633
633
|
bun run build:cli-binary
|
|
634
634
|
```
|
|
635
635
|
|
|
636
|
-
The output is `dist-bin/
|
|
636
|
+
The output is `dist-bin/peach-<platform>-<arch>`. `dist-cli/bin.js` remains a
|
|
637
637
|
repository build artifact for tests and internal tooling and is not published
|
|
638
638
|
as an npm executable. Library exports build to `dist-lib/` (consumed via the
|
|
639
639
|
`exports` map: `.`, `./vite`, `./metro`, `./sdk`, `./skills`, `./detox`, and the
|
package/cli/app-config.ts
CHANGED
|
@@ -65,7 +65,7 @@ export async function loadRNXAppConfig(
|
|
|
65
65
|
})
|
|
66
66
|
const loaded: unknown = await jiti.import(project.configPath, { default: true })
|
|
67
67
|
if (!isRNXConfig(loaded)) {
|
|
68
|
-
throw new Error('the default export must be
|
|
68
|
+
throw new Error('the default export must be a peach config object')
|
|
69
69
|
}
|
|
70
70
|
return resolveConfigReplacementFiles(loaded, project.configPath)
|
|
71
71
|
} catch (error) {
|
package/cli/app-fonts.ts
CHANGED
|
@@ -124,7 +124,7 @@ export function discoverNativeLinkedAppFonts(opts: {
|
|
|
124
124
|
|
|
125
125
|
// @react-native-vector-icons links fonts from its configured local font
|
|
126
126
|
// directory and each installed icon package into the native app. those files
|
|
127
|
-
// never enter the metro module graph, so
|
|
127
|
+
// never enter the metro module graph, so peach must stage them through the
|
|
128
128
|
// same native-linked font wire as expo-font config-plugin assets. Font Awesome
|
|
129
129
|
// Pro installs its licensed faces under the local directory rather than
|
|
130
130
|
// publishing them in the npm package.
|
|
@@ -260,9 +260,9 @@ export function discoverNativeLinkedAppFonts(opts: {
|
|
|
260
260
|
|
|
261
261
|
// resolve a metro dev server's project root. expo serves a manifest at the
|
|
262
262
|
// server origin carrying `extra.expoClient._internal.projectRoot` — the absolute
|
|
263
|
-
// dir of the app being served. the local `
|
|
263
|
+
// dir of the app being served. the local `peach open <port>` path runs from the
|
|
264
264
|
// CLI's cwd, which almost never owns the bundle being opened (e.g.
|
|
265
|
-
// `
|
|
265
|
+
// `peach open 8081` run from ~/soot against a 3pc metro), so scanning cwd for
|
|
266
266
|
// font declarations finds nothing.
|
|
267
267
|
//
|
|
268
268
|
// a bare react-native packager serves no such manifest, so the same resolver
|
|
@@ -355,7 +355,7 @@ export type FetchedAppFont = {
|
|
|
355
355
|
// fetch every config-plugin font declared on an engine `?appFonts=` wire.
|
|
356
356
|
// these typefaces live in the native binary, never in the metro bundle's
|
|
357
357
|
// __packager_asset graph, so neither asset capture nor recorded fetches see
|
|
358
|
-
// them — both the preview (`
|
|
358
|
+
// them — both the preview (`peach record upload`) and build (`peach app-fonts
|
|
359
359
|
// stage`) paths backfill by re-fetching the declared urls off the still-live
|
|
360
360
|
// metro. one implementation so both pipelines store identical bytes + keys.
|
|
361
361
|
export async function fetchAppFontFiles(
|
package/cli/auth.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
//
|
|
1
|
+
// peach cli auth resolution for cloud-hitting commands.
|
|
2
2
|
//
|
|
3
3
|
// priority order (first match wins):
|
|
4
|
-
// 1.
|
|
4
|
+
// 1. PEACH_API_KEY — ci path
|
|
5
5
|
// 2. CONTRAST_INSTALLATION_TOKEN/GITHUB_TOKEN + repo env — github action
|
|
6
6
|
// preview uploads from the Contrast runner, no extra secret
|
|
7
|
-
// 3. desktop session token from shared desktop auth (`
|
|
7
|
+
// 3. desktop session token from shared desktop auth (`peach login`)
|
|
8
8
|
//
|
|
9
9
|
// callers wanting an auth header: `authHeaderOrExit('upload')`.
|
|
10
10
|
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
} from '../src/auth/shared-session.ts'
|
|
15
15
|
import { rnxExit } from './run-rnx.ts'
|
|
16
16
|
|
|
17
|
-
export type CliApiKeyEnvName = '
|
|
17
|
+
export type CliApiKeyEnvName = 'PEACH_API_KEY'
|
|
18
18
|
|
|
19
19
|
export type CliAuth =
|
|
20
20
|
| { kind: 'api-key'; secret: string; source: 'env'; envName: CliApiKeyEnvName }
|
|
@@ -35,7 +35,7 @@ export type CliAuth =
|
|
|
35
35
|
token: string
|
|
36
36
|
origin: string
|
|
37
37
|
// the account this sign-in bills cloud sessions to. null when the person
|
|
38
|
-
// belongs to several accounts and has not chosen one with `
|
|
38
|
+
// belongs to several accounts and has not chosen one with `peach login
|
|
39
39
|
// --account`; a person with exactly one account never has to choose.
|
|
40
40
|
accountId: string | null
|
|
41
41
|
}
|
|
@@ -58,7 +58,7 @@ function looksLikeGitHubToken(token: string | undefined): boolean {
|
|
|
58
58
|
// in src/github/token.ts. the length floor + prefix is only a cheap typo
|
|
59
59
|
// guard before the cloud endpoints verify real repo access. an upper cap
|
|
60
60
|
// here silently rejects the long actions token, so resolveCliAuth() returns
|
|
61
|
-
// null and every CI `record start` dies with "set
|
|
61
|
+
// null and every CI `record start` dies with "set PEACH_API_KEY".
|
|
62
62
|
return Boolean(
|
|
63
63
|
token &&
|
|
64
64
|
token.length >= 20 &&
|
|
@@ -108,7 +108,7 @@ function isCliApiKeySecret(secret: string): boolean {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
function readApiKeyFromEnv(): { secret: string; envName: CliApiKeyEnvName } | null {
|
|
111
|
-
const envName = '
|
|
111
|
+
const envName = 'PEACH_API_KEY'
|
|
112
112
|
const secret = process.env[envName]?.trim()
|
|
113
113
|
return secret && isCliApiKeySecret(secret) ? { secret, envName } : null
|
|
114
114
|
}
|
|
@@ -140,7 +140,7 @@ export function resolveCliAuth(): CliAuth | null {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
export const CHOOSE_ACCOUNT_HINT =
|
|
143
|
-
'this sign-in belongs to several accounts; run `
|
|
143
|
+
'this sign-in belongs to several accounts; run `peach login --account <name>` to choose the one to bill'
|
|
144
144
|
|
|
145
145
|
// the account a request that opens a paid cloud session names. an api key
|
|
146
146
|
// names its own account, so it sends none; a session token has to say.
|
|
@@ -175,10 +175,10 @@ export function authHeaderOrExit(commandLabel: string): {
|
|
|
175
175
|
if (auth) return { auth, header: authHeaderValue(auth) }
|
|
176
176
|
|
|
177
177
|
process.stderr.write(
|
|
178
|
-
`\n
|
|
178
|
+
`\n peach needs to be authenticated.\n\n` +
|
|
179
179
|
` pick one:\n` +
|
|
180
|
-
` • run \`
|
|
181
|
-
` • set
|
|
180
|
+
` • run \`peach login\` to sign in with your GH account\n` +
|
|
181
|
+
` • set PEACH_API_KEY=sk_rnx_... (recommended for CI)\n\n`,
|
|
182
182
|
)
|
|
183
183
|
rnxExit(1)
|
|
184
184
|
}
|