peachsim 0.1.570 → 0.1.572
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 +108 -108
- 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 +28 -20
- 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 +3 -2
- package/cli/cloud-session.ts +12 -12
- package/cli/cloud-test-result-files.ts +97 -0
- 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 +173 -71
- 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 +176 -18
- 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 +4 -2
- package/cli/main.ts +14 -14
- package/cli/outbound-endpoints.ts +32 -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 +3 -2
- 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/jest-preset.cjs +2 -2
- 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 +116 -0
- package/dist-lib/cloud-test-args.mjs +86 -0
- 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/detox/jest-preset.cjs +2 -2
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +12 -12
- package/dist-lib/host/bridge-host.cjs +87 -77
- 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 +63 -73
- 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 +534 -520
- package/dist-lib/swift-compile.cjs +372 -0
- package/dist-lib/swift-compile.mjs +339 -0
- package/dist-lib/swift-package.cjs +78 -0
- package/dist-lib/swift-package.mjs +52 -0
- 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 +479 -161
- package/package.json +22 -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 +47 -47
- 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-test-args.ts +100 -0
- 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 +11 -10
- 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/swift-compile.ts +359 -0
- package/src/swift-package.ts +69 -0
- package/src/swift-submit.ts +3 -2
- package/src/vite-plugin-one.ts +8 -8
- package/src/vite-plugin-swift.ts +106 -110
- package/src/vite-plugin.ts +6 -19
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description: Optimize Peach engine and app performance — scroll jank, dropped frames, slow animation, idle CPU, memory growth, and "smooth normally but laggy under load" (video calls, busy machines). Covers measuring on the right thread with the right browser, proving each perf tier actually engages via its counters, a CPU-contention test harness, and the map of existing perf machinery so you improve it instead of reinventing it. For general app debugging load /
|
|
2
|
+
name: peach-perf
|
|
3
|
+
description: Optimize Peach engine and app performance — scroll jank, dropped frames, slow animation, idle CPU, memory growth, and "smooth normally but laggy under load" (video calls, busy machines). Covers measuring on the right thread with the right browser, proving each perf tier actually engages via its counters, a CPU-contention test harness, and the map of existing perf machinery so you improve it instead of reinventing it. For general app debugging load /peach-debug first.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Peach performance
|
|
@@ -11,8 +11,8 @@ this engine followed the same loop — measure on the right thread, read the
|
|
|
11
11
|
counters that prove machinery engaged, fix the one thing the counters
|
|
12
12
|
indict, remeasure — and every wasted week came from skipping a step.
|
|
13
13
|
|
|
14
|
-
> needs a connected, pinned sim (`/
|
|
15
|
-
> triage lives in `/
|
|
14
|
+
> needs a connected, pinned sim (`/peach-setup`). general "what's wrong"
|
|
15
|
+
> triage lives in `/peach-debug`; this skill goes deeper on perf only.
|
|
16
16
|
|
|
17
17
|
## the four laws (each paid for by a real incident)
|
|
18
18
|
|
|
@@ -56,7 +56,7 @@ indict, remeasure — and every wasted week came from skipping a step.
|
|
|
56
56
|
|
|
57
57
|
### presentation proof must stay outside the simulator
|
|
58
58
|
|
|
59
|
-
Performance acceptance must not use `
|
|
59
|
+
Performance acceptance must not use `peach record`, `liveComposite`,
|
|
60
60
|
`captureBitmaps`, Chrome screencast, or another in-page frame-copy path. Those
|
|
61
61
|
paths add work to the simulator or browser and can change the cadence being
|
|
62
62
|
measured. Record the visible window with the operating system's native screen
|
|
@@ -112,10 +112,10 @@ property on the transform owner can move the whole trajectory to the browser's
|
|
|
112
112
|
main thread. Paint stable decoration once or give it a distinct layer.
|
|
113
113
|
|
|
114
114
|
```sh
|
|
115
|
-
|
|
115
|
+
peach perf shell start # arm shell frame capture (clears prior)
|
|
116
116
|
# reproduce — e.g. 8 fling swipes:
|
|
117
|
-
# for i in {1..8}; do
|
|
118
|
-
|
|
117
|
+
# for i in {1..8}; do peach do swipe 196 650 196 250 8 8 --no-wait; sleep 0.9; done
|
|
118
|
+
peach perf shell stop # report (add --json for scripting)
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
the report and how to read it:
|
|
@@ -244,13 +244,13 @@ identify from its own output is not evidence.
|
|
|
244
244
|
deeper tools when the frame report isn't enough:
|
|
245
245
|
|
|
246
246
|
```sh
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
247
|
+
peach maestro test .maestro/scroll.yaml --profile # per-step + frame stats
|
|
248
|
+
peach perf cpu --duration 5 --output /tmp/t.cpuprofile # sampled CPU
|
|
249
|
+
peach open 8089 --new --driver playwright --cdp-port 9222 # cpu-profile a driveable sim
|
|
250
|
+
peach debug enable layout,render && peach debug recent layout 40
|
|
251
251
|
```
|
|
252
252
|
|
|
253
|
-
`
|
|
253
|
+
`peach perf cpu` writes one profile for the page and one for every attached
|
|
254
254
|
worker, plus a manifest that labels shell, compositor, tenant, worklet, and
|
|
255
255
|
unknown workers. exit zero requires page, shell, compositor, and tenant plus
|
|
256
256
|
every other discovered target, with each covering at least 99% of the requested
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: peach-setup
|
|
3
3
|
description: Get Peach connected to your React Native app with no project setup
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -9,48 +9,48 @@ you want to drive a React Native app with Peach from the CLI. this skill
|
|
|
9
9
|
takes you from a running development server to a connected, pinned sim that
|
|
10
10
|
every other Peach skill assumes exists. Peach requires no project setup or per-app
|
|
11
11
|
install. if
|
|
12
|
-
`
|
|
13
|
-
returns a tree, you're past this skill — load `/
|
|
14
|
-
debugging or `/
|
|
12
|
+
`peach describe` already
|
|
13
|
+
returns a tree, you're past this skill — load `/peach-debug` for
|
|
14
|
+
debugging or `/peach-test` for writing tests.
|
|
15
15
|
|
|
16
16
|
## anti-patterns (read first)
|
|
17
17
|
|
|
18
|
-
- **never `
|
|
18
|
+
- **never `peach claim --force` a sim held by another CLI.** the lease
|
|
19
19
|
exists for a reason. forcing strands the other agent and corrupts the
|
|
20
|
-
bridge state. use `
|
|
21
|
-
- **don't switch sims mid-investigation.** pin once with `
|
|
20
|
+
bridge state. use `peach open --new` to start a fresh sim instead.
|
|
21
|
+
- **don't switch sims mid-investigation.** pin once with `peach use
|
|
22
22
|
<id>` and keep it pinned. an unpinned command refuses to choose when more
|
|
23
23
|
than one driveable sim is live.
|
|
24
|
-
- **an empty `
|
|
24
|
+
- **an empty `peach list` is not "broken Peach".** it usually means the
|
|
25
25
|
daemon is down, the dev server port is wrong, or the runtime is missing.
|
|
26
26
|
walk the recovery checklist before reinstalling.
|
|
27
|
-
- **keep one sim for your whole session.** the first `
|
|
27
|
+
- **keep one sim for your whole session.** the first `peach open <port>`
|
|
28
28
|
launches Chrome for Testing with an isolated profile. later opens reuse the
|
|
29
|
-
saved sim and navigate it in place. use `
|
|
29
|
+
saved sim and navigate it in place. use `peach do reload` when the target
|
|
30
30
|
has not changed:
|
|
31
31
|
|
|
32
32
|
```sh
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
peach open 8086 # first call creates your isolated sim
|
|
34
|
+
peach open 8090 # same sim, different app
|
|
35
|
+
peach do reload # same sim, same app
|
|
36
|
+
peach close <id> # dispose it when you are done
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
`--new`, `--profile`, and `--ephemeral` create another isolated browser
|
|
40
40
|
tree. use them only when separate storage or a genuinely concurrent sim is
|
|
41
41
|
required. repeated new trees consume enough memory and CPU to starve other
|
|
42
42
|
work on a shared machine.
|
|
43
|
-
- **pin the sim before driving it.** `
|
|
43
|
+
- **pin the sim before driving it.** `peach open` records the new sim for the
|
|
44
44
|
current CLI identity. read its id and pin it explicitly before a longer flow:
|
|
45
45
|
|
|
46
46
|
```sh
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
peach open 8086
|
|
48
|
+
peach list
|
|
49
|
+
peach use <id>
|
|
50
|
+
peach describe --sim <id>
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
- **never retry-loop `
|
|
53
|
+
- **never retry-loop `peach open` against a wedged or slow stack.** a
|
|
54
54
|
connect timeout means diagnose the stack. do not retry. if the first launch
|
|
55
55
|
never connects, each retry can create another browser tree before there is a
|
|
56
56
|
saved sim to reuse. verify the development server and Peach runtime, then
|
|
@@ -59,57 +59,57 @@ debugging or `/rnx-test` for writing tests.
|
|
|
59
59
|
## first move
|
|
60
60
|
|
|
61
61
|
```sh
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
peach daemon status # the persistent service makes agent commands much faster
|
|
63
|
+
peach daemon install # enable it when missing on a supported personal machine
|
|
64
|
+
peach compat --json # scan the app's native package compatibility
|
|
65
|
+
peach open 8081 # load a metro/expo dev server
|
|
66
|
+
peach list # confirm exactly one sim is reachable
|
|
67
|
+
peach use <id> # pin it for the rest of the workflow
|
|
68
|
+
peach describe # smoke test — should print a render tree
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
the background service keeps the local bridge and runtime ready between
|
|
72
72
|
commands. without it, Peach still works by starting an on-demand bridge, but
|
|
73
73
|
inspect, interaction, and test commands pay repeated startup cost. if the user
|
|
74
|
-
declined it during onboarding, `
|
|
74
|
+
declined it during onboarding, `peach daemon install` is the direct way to enable
|
|
75
75
|
it. CI does not need or install the service.
|
|
76
76
|
|
|
77
|
-
bare `
|
|
78
|
-
scripts should use `
|
|
77
|
+
bare `peach` opens ConnectRN for a human to choose among local apps. agents and
|
|
78
|
+
scripts should use `peach open <port-or-url>` so the target is explicit.
|
|
79
79
|
|
|
80
|
-
if you do not know the port, run `
|
|
80
|
+
if you do not know the port, run `peach open` with no target and pick from
|
|
81
81
|
the detected dev servers. for hosted or unusual targets, pass the URL
|
|
82
82
|
explicitly:
|
|
83
83
|
|
|
84
84
|
```sh
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
peach open 8081 # load a metro dev server
|
|
86
|
+
peach open https://my-app.local # load a hosted bundle
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
## you're done when
|
|
90
90
|
|
|
91
|
-
- `
|
|
92
|
-
- `
|
|
93
|
-
- the same sim id appears in `
|
|
91
|
+
- `peach list` shows your sim and no orphans
|
|
92
|
+
- `peach describe` returns a render tree, not an error
|
|
93
|
+
- the same sim id appears in `peach describe`, `peach find`, and
|
|
94
94
|
every subsequent command
|
|
95
|
-
- `
|
|
95
|
+
- `peach get errors 5` and `peach get requests 5` are quiet (or the
|
|
96
96
|
warnings are ones you understand)
|
|
97
97
|
- the compatibility scan's partial, unsupported, unknown, and version-mismatched
|
|
98
98
|
packages have been summarized without treating its aggregate score as a pass/fail gate
|
|
99
99
|
|
|
100
100
|
## compatibility feedback requires approval
|
|
101
101
|
|
|
102
|
-
run `
|
|
102
|
+
run `peach compat --json` from the app project root during setup. if the scan
|
|
103
103
|
identifies a plausible missing Peach seam, or the running app gives concrete
|
|
104
104
|
evidence that behavior is missing or broken specifically in Peach, summarize
|
|
105
105
|
the package, expected behavior, actual behavior, and runtime evidence for the
|
|
106
|
-
user. then offer to send that finding with `
|
|
106
|
+
user. then offer to send that finding with `peach report-issue`.
|
|
107
107
|
|
|
108
108
|
**never submit a report automatically or behind the user's back.** wait for an
|
|
109
109
|
explicit yes. only then run this from the app project root:
|
|
110
110
|
|
|
111
111
|
```sh
|
|
112
|
-
|
|
112
|
+
peach report-issue --yes "<package; expected behavior; actual behavior; runtime evidence>"
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
the command automatically attaches the local compatibility scan plus bounded
|
|
@@ -121,33 +121,33 @@ it records the user's approval after the offer.
|
|
|
121
121
|
|
|
122
122
|
## recovery — common failure modes
|
|
123
123
|
|
|
124
|
-
**`
|
|
124
|
+
**`peach list` is empty.** walk this checklist in order:
|
|
125
125
|
|
|
126
126
|
```sh
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
peach daemon status # is the bridge daemon up?
|
|
128
|
+
peach runtime list # is at least one engine runtime installed?
|
|
129
|
+
peach open <port> # does loading explicitly work?
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
if the daemon is not installed: run `
|
|
133
|
-
daemon is down, run `
|
|
134
|
-
a foreground bridge. if no runtime is installed, `
|
|
132
|
+
if the daemon is not installed: run `peach daemon install`. if the registered
|
|
133
|
+
daemon is down, run `peach daemon restart`, or `peach serve` in another shell for
|
|
134
|
+
a foreground bridge. if no runtime is installed, `peach open` installs it
|
|
135
135
|
before launching. if open errors with "port unreachable": confirm your dev
|
|
136
136
|
server is actually serving — the bundler has to be up before Peach can
|
|
137
137
|
attach.
|
|
138
138
|
|
|
139
|
-
**two sims appear unexpectedly.** an earlier `
|
|
139
|
+
**two sims appear unexpectedly.** an earlier `peach claim` didn't
|
|
140
140
|
release on exit. close the orphan explicitly:
|
|
141
141
|
|
|
142
142
|
```sh
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
peach list # note the stale id
|
|
144
|
+
peach close <id> # release it cleanly
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
-
**`
|
|
148
|
-
Run `
|
|
147
|
+
**`peach open` errors with "no runtime".** the engine binary isn't installed.
|
|
148
|
+
Run `peach runtime install`, then retry `peach open <port>`.
|
|
149
149
|
|
|
150
|
-
**`
|
|
150
|
+
**`peach open` times out ("timed out waiting for opened sim to connect").**
|
|
151
151
|
do not retry in a loop. verify the development server first: `__soot/` must
|
|
152
152
|
respond and the engine watchers must be running. inspect the driver diagnostic
|
|
153
153
|
path printed by the failed command. restart the broken development stack at its
|
|
@@ -155,18 +155,18 @@ supervisor, then retry once. Peach owns the isolated browser profile and its
|
|
|
155
155
|
process tree; do not open the shell URL through an operating-system browser.
|
|
156
156
|
|
|
157
157
|
**bridge disconnects mid-sim.** the WebSocket dropped (laptop slept,
|
|
158
|
-
network blip). re-pin: `
|
|
158
|
+
network blip). re-pin: `peach use <id>`. the daemon retries reconnection
|
|
159
159
|
automatically; you usually just need to re-issue the command.
|
|
160
160
|
|
|
161
161
|
**"sim held by another CLI".** another agent or your own previous CLI
|
|
162
|
-
process has the lease. find it (`
|
|
163
|
-
<id>`), or start a clean sim (`
|
|
164
|
-
`
|
|
162
|
+
process has the lease. find it (`peach list`), close it (`peach close
|
|
163
|
+
<id>`), or start a clean sim (`peach open --new`) — do **not**
|
|
164
|
+
`peach claim --force`.
|
|
165
165
|
|
|
166
166
|
## related
|
|
167
167
|
|
|
168
|
-
- `/
|
|
168
|
+
- `/peach-debug` — once setup is good, this is where you debug
|
|
169
169
|
rendering, performance, and accessibility issues.
|
|
170
|
-
- `/
|
|
170
|
+
- `/peach-test` — write or run automated flows against the connected
|
|
171
171
|
sim.
|
|
172
|
-
- `/
|
|
172
|
+
- `/peach-visual` — pixel-level rendering comparisons.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: peach-test
|
|
3
3
|
description: Run automated tests against your React Native app under Peach with Maestro YAML or Detox/Jest
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -9,10 +9,10 @@ Peach has two test runners. Maestro owns every YAML test, whether it was
|
|
|
9
9
|
hand-authored, generated from a goal, or recorded from live CLI actions.
|
|
10
10
|
Detox runs existing imperative Jest suites through the Peach driver.
|
|
11
11
|
|
|
12
|
-
> needs a connected, pinned sim. if `
|
|
13
|
-
> `/
|
|
12
|
+
> needs a connected, pinned sim. if `peach describe` errors, load
|
|
13
|
+
> `/peach-setup` first.
|
|
14
14
|
|
|
15
|
-
Set `
|
|
15
|
+
Set `PEACH_NO_OPEN=1` before starting an app dev server for a Detox,
|
|
16
16
|
Maestro, or iOS-only pass. Apps can opt into a named Electron window through
|
|
17
17
|
the official Vite or Metro plugin, and test-only work must not open that window.
|
|
18
18
|
|
|
@@ -37,15 +37,15 @@ Do not invent a third runner for how a Maestro flow was authored.
|
|
|
37
37
|
implementation and author flows against it.
|
|
38
38
|
- **pin a sim before running a suite.** parallel CI jobs colliding
|
|
39
39
|
on the default bridge port is the #1 flake source. pass `--port` in
|
|
40
|
-
CI and `
|
|
40
|
+
CI and `peach use <id>` locally.
|
|
41
41
|
- **every flow ends with an assert, not a screenshot.** a screenshot
|
|
42
42
|
passes as long as the flow didn't throw. `assertVisible` (or
|
|
43
43
|
`expect(...).toBeVisible()`) actually verifies the happy path.
|
|
44
44
|
- **don't run a 40-step "smoke everything" flow.** when it fails, you
|
|
45
45
|
can't tell what regressed. split into `login.yaml`, `compose.yaml`,
|
|
46
46
|
`settings.yaml`, chain with `runFlow`.
|
|
47
|
-
- **inside an `
|
|
48
|
-
chain, use `
|
|
47
|
+
- **inside an `peach do` chain, use `sleep` only for gesture timing.** after the
|
|
48
|
+
chain, use `peach wait` for app state so automation advances on a real condition.
|
|
49
49
|
|
|
50
50
|
## you're done when
|
|
51
51
|
|
|
@@ -62,8 +62,8 @@ batch. use a chain for a short repro, form fill, or timing-sensitive gesture
|
|
|
62
62
|
that does not belong in a saved test:
|
|
63
63
|
|
|
64
64
|
```sh
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
peach do tap email --then type user@example.com --then tap submit
|
|
66
|
+
peach wait selector dashboard
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
the batch stops on the first failure. add `--json` for per-action results.
|
|
@@ -79,23 +79,23 @@ Write declarative Maestro YAML. The same command runs existing suites,
|
|
|
79
79
|
generates tests, records live drafts, profiles, and uploads replayable results.
|
|
80
80
|
|
|
81
81
|
```sh
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
peach maestro test .maestro/login.yaml # run one flow
|
|
83
|
+
peach maestro test .maestro/login.yaml --record # record video
|
|
84
|
+
peach maestro test .maestro/login.yaml --profile # include perf stats
|
|
85
|
+
peach maestro test .maestro/ # run the suite
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
Author from a live interaction:
|
|
89
89
|
|
|
90
90
|
```sh
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
91
|
+
peach maestro start # begin a draft
|
|
92
|
+
peach do tap-id loginButton # drive the app via the CLI
|
|
93
|
+
peach maestro keep # save the step
|
|
94
|
+
peach do type "user@example.com"
|
|
95
|
+
peach maestro keep
|
|
96
|
+
peach do tap-id submit
|
|
97
|
+
peach maestro keep
|
|
98
|
+
peach maestro end --output .maestro/login.yaml --validate
|
|
99
99
|
```
|
|
100
100
|
|
|
101
101
|
the recorder emits minimal YAML — no coordinate dumps, no `sleep` noise —
|
|
@@ -129,7 +129,7 @@ exemplar flow:
|
|
|
129
129
|
run with env interpolation:
|
|
130
130
|
|
|
131
131
|
```sh
|
|
132
|
-
|
|
132
|
+
peach maestro --env USERNAME=alice --env PASSWORD=hunter2 \
|
|
133
133
|
test .maestro/login.yaml \
|
|
134
134
|
--record --profile
|
|
135
135
|
```
|
|
@@ -144,7 +144,7 @@ CLI's `wait idle` with a generous budget. use it before any
|
|
|
144
144
|
Generate and immediately run a Maestro flow from a plain-language goal:
|
|
145
145
|
|
|
146
146
|
```sh
|
|
147
|
-
|
|
147
|
+
peach maestro generate "log in with the demo account and verify the dashboard"
|
|
148
148
|
```
|
|
149
149
|
|
|
150
150
|
Generation writes the same deterministic Maestro artifact, uploads its replay,
|
|
@@ -161,19 +161,19 @@ command change:
|
|
|
161
161
|
maestro test .maestro/login.yaml
|
|
162
162
|
|
|
163
163
|
# after
|
|
164
|
-
|
|
164
|
+
peach maestro test .maestro/login.yaml
|
|
165
165
|
```
|
|
166
166
|
|
|
167
167
|
no test rewrites, no detox config, no simulator. the runtime auto-launches
|
|
168
168
|
a Peach shell if one isn't running.
|
|
169
169
|
|
|
170
170
|
```sh
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
171
|
+
peach maestro # auto-discover .maestro/ or maestro/
|
|
172
|
+
peach maestro test .maestro/login.yaml
|
|
173
|
+
peach maestro test .maestro/ # every flow in a directory
|
|
174
|
+
peach maestro init # scaffold a starter flow
|
|
175
|
+
peach maestro --list-compat # supported / partial / unsupported
|
|
176
|
+
peach maestro --env USERNAME=alice test .maestro/login.yaml
|
|
177
177
|
```
|
|
178
178
|
|
|
179
179
|
### supported verbs
|
|
@@ -211,7 +211,7 @@ these throw `unsupported maestro verb: X`:
|
|
|
211
211
|
### troubleshooting
|
|
212
212
|
|
|
213
213
|
- **"no maestro flows found"** — pass an explicit path
|
|
214
|
-
(`
|
|
214
|
+
(`peach maestro test path/to/flow.yaml`) or run `peach maestro
|
|
215
215
|
init` to scaffold one.
|
|
216
216
|
- **"missing environment variable for flow placeholder: FOO"** — pass
|
|
217
217
|
`--env FOO=bar` or export it. pick one mechanism per repo and document
|
|
@@ -229,7 +229,7 @@ an existing detox suite runs against Peach with **one line** of jest
|
|
|
229
229
|
config and zero test changes.
|
|
230
230
|
|
|
231
231
|
`import { by, device, element, expect, waitFor } from 'detox'` is
|
|
232
|
-
rewritten by jest to
|
|
232
|
+
rewritten by jest to a peach-backed driver that drives the real shell
|
|
233
233
|
over playwright. matchers, assertions, and the `waitFor` API match the
|
|
234
234
|
upstream detox surface.
|
|
235
235
|
|
|
@@ -238,7 +238,7 @@ upstream detox surface.
|
|
|
238
238
|
```js
|
|
239
239
|
// rnx-detox.config.cjs
|
|
240
240
|
module.exports = {
|
|
241
|
-
preset: '
|
|
241
|
+
preset: 'peachsim/detox',
|
|
242
242
|
rootDir: __dirname,
|
|
243
243
|
testMatch: ['<rootDir>/e2e/**/*.test.ts'],
|
|
244
244
|
}
|
|
@@ -248,7 +248,7 @@ or, if you already have a jest config, pull in just the module mapper:
|
|
|
248
248
|
|
|
249
249
|
```js
|
|
250
250
|
moduleNameMapper: {
|
|
251
|
-
'^detox$': require.resolve('
|
|
251
|
+
'^detox$': require.resolve('peachsim/detox'),
|
|
252
252
|
}
|
|
253
253
|
```
|
|
254
254
|
|
|
@@ -259,14 +259,14 @@ works until your first hung shell.
|
|
|
259
259
|
### commands
|
|
260
260
|
|
|
261
261
|
```sh
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
262
|
+
peach detox # run e2e/, test/e2e/, or detox/
|
|
263
|
+
peach detox --config my.cjs # use a specific jest config
|
|
264
|
+
peach detox --watch # jest watch mode
|
|
265
|
+
peach detox -t "login" # --testNamePattern
|
|
266
|
+
peach detox --headed # keep the shell window visible
|
|
267
|
+
peach detox --no-launch # don't auto-launch a shell
|
|
268
|
+
peach detox --port 5173 # explicit bridge port for CI
|
|
269
|
+
peach detox init # scaffold config + e2e/example.test.ts
|
|
270
270
|
```
|
|
271
271
|
|
|
272
272
|
### compat surface
|
|
@@ -292,12 +292,12 @@ rnx detox init # scaffold config + e2e/example.test.ts
|
|
|
292
292
|
### troubleshooting
|
|
293
293
|
|
|
294
294
|
- **"no Peach shell reachable"** — start one yourself
|
|
295
|
-
(`
|
|
295
|
+
(`peach open <port>`) or pass `--port <n>`.
|
|
296
296
|
- **"jest cannot find module 'detox'"** — the preset isn't wired. confirm
|
|
297
|
-
`preset: '
|
|
297
|
+
`preset: 'peachsim/detox'` is in the jest config jest
|
|
298
298
|
actually loaded (`--config` overrides package.json).
|
|
299
299
|
- **matchers fail on elements that exist** — canvas has no DOM. use
|
|
300
|
-
`by.id` (testID); `
|
|
300
|
+
`by.id` (testID); `peach describe` shows what the shell sees.
|
|
301
301
|
- **passes locally, flakes in CI** — the shell boots asynchronously.
|
|
302
302
|
bump jest `testTimeout` to 10–15 s and add a `waitFor(element(...))
|
|
303
303
|
.toBeVisible().withTimeout(10000)` before the first assertion.
|
|
@@ -315,7 +315,7 @@ rnx detox init # scaffold config + e2e/example.test.ts
|
|
|
315
315
|
the first assertion, pin the bridge port, and run with `--video` so
|
|
316
316
|
failing Maestro runs land a recording next to the output.
|
|
317
317
|
- **a flake reproduces but resists fixing** — don't paper over with
|
|
318
|
-
`sleep`. open `/
|
|
319
|
-
the timeline (`
|
|
318
|
+
`sleep`. open `/peach-debug` against the same sim, capture
|
|
319
|
+
the timeline (`peach timeline start` → reproduce → `peach
|
|
320
320
|
what-happened`), and look for the missing animation-completion or
|
|
321
321
|
the unresolved fetch that's racing the assertion.
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: peach-visual
|
|
3
3
|
description: Pixel-level rendering comparison between Peach and native iOS — fonts, gradients, shadows, image fidelity
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Peach visual fidelity
|
|
7
7
|
|
|
8
8
|
pixel-level rendering fidelity: does the Peach canvas match native iOS
|
|
9
|
-
for text, gradients, shadows, blur, and image rendering? the `
|
|
10
|
-
CLI gives you two primitives — **canvas capture** (`
|
|
11
|
-
and **structural diff** (`
|
|
9
|
+
for text, gradients, shadows, blur, and image rendering? the `peach`
|
|
10
|
+
CLI gives you two primitives — **canvas capture** (`peach screenshot`)
|
|
11
|
+
and **structural diff** (`peach debug snapshot`/`diff`). pixel
|
|
12
12
|
comparison itself is "capture both sides, diff the PNGs with a standard
|
|
13
13
|
image tool" — there is no single oracle-diff command, and that's fine:
|
|
14
14
|
the capture step is the hard part and it's fully reproducible.
|
|
15
15
|
|
|
16
|
-
> needs a connected, pinned sim. if `
|
|
17
|
-
> load `/
|
|
16
|
+
> needs a connected, pinned sim. if `peach describe` errors,
|
|
17
|
+
> load `/peach-setup` first.
|
|
18
18
|
|
|
19
19
|
## route in
|
|
20
20
|
|
|
21
21
|
- structural change ("which nodes / which props changed?") → load
|
|
22
|
-
`/
|
|
22
|
+
`/peach-debug`, debugging branch — `debug snapshot` + `debug
|
|
23
23
|
diff` is faster, deterministic, and tells you *why*.
|
|
24
24
|
- visual change (color, gradient, shadow, font metric, blur, image)? →
|
|
25
25
|
continue here.
|
|
@@ -28,36 +28,36 @@ the capture step is the hard part and it's fully reproducible.
|
|
|
28
28
|
|
|
29
29
|
## anti-patterns (read first)
|
|
30
30
|
|
|
31
|
-
- **run structural diff before pixel work.** `
|
|
32
|
-
`debug diff` (in `/
|
|
31
|
+
- **run structural diff before pixel work.** `peach debug snapshot` /
|
|
32
|
+
`debug diff` (in `/peach-debug`) is cheaper, deterministic, and
|
|
33
33
|
points at the responsible nodes. only when it's empty (or the change is
|
|
34
34
|
pure rendering) does a pixel comparison add information.
|
|
35
35
|
- **don't single-screenshot animated surfaces.** a gradient
|
|
36
|
-
mid-animation never matches. gate the capture behind `
|
|
36
|
+
mid-animation never matches. gate the capture behind `peach wait
|
|
37
37
|
idle` first.
|
|
38
38
|
- **a > 5% pixel threshold hides regressions.** ~1% is the right
|
|
39
39
|
ballpark for catching real font / shadow / gradient drift without
|
|
40
40
|
flagging anti-alias noise. go higher only with a written reason.
|
|
41
41
|
- **pin device and theme.** capture both sides on the same simulated
|
|
42
42
|
device and appearance. capture each appearance separately with
|
|
43
|
-
`
|
|
43
|
+
`peach screenshot` after setting it on both simulators.
|
|
44
44
|
- **commit baselines alongside the code change that produced them.**
|
|
45
45
|
baseline churn without code churn means someone captured noise.
|
|
46
46
|
|
|
47
|
-
## capturing — `
|
|
47
|
+
## capturing — `peach screenshot`
|
|
48
48
|
|
|
49
49
|
fast, no extra setup, works on any loaded app:
|
|
50
50
|
|
|
51
51
|
```sh
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
peach screenshot --output app.png # full canvas
|
|
53
|
+
peach screenshot --area 0,200,393,400 # crop to a logical rect
|
|
54
|
+
peach screenshot --id loginButton -o btn.png # crop to a node by testID
|
|
55
|
+
peach screenshot --text "Sign in" # crop to a node by text
|
|
56
|
+
peach screenshot --no-shell -o tenant.png # tenant surface only, no iOS chrome
|
|
57
|
+
peach screenshot --shell-only # only the simulated iOS chrome
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
`
|
|
60
|
+
`peach screenshot` captures the current screen as a PNG. navigate to each
|
|
61
61
|
screen you want to inspect and capture it with a distinct output filename.
|
|
62
62
|
|
|
63
63
|
## comparing pixels
|
|
@@ -67,9 +67,9 @@ capture both sides to PNGs, then diff with any standard image tool.
|
|
|
67
67
|
**Peach vs Peach (regression across your own commits):**
|
|
68
68
|
|
|
69
69
|
```sh
|
|
70
|
-
|
|
70
|
+
peach screenshot -o before.png # baseline, before your change
|
|
71
71
|
# … make the rendering change, let the sim hot-reload …
|
|
72
|
-
|
|
72
|
+
peach screenshot -o after.png # after your change
|
|
73
73
|
npx pixelmatch before.png after.png diff.png 0.1 # writes diff.png
|
|
74
74
|
# or: magick compare before.png after.png diff.png
|
|
75
75
|
```
|
|
@@ -80,9 +80,9 @@ npx pixelmatch before.png after.png diff.png 0.1 # writes diff.png
|
|
|
80
80
|
# native side: lifecycle and UI use xcodebuildmcp with one claimed simulator
|
|
81
81
|
# lossless capture names that simulator explicitly; never use the booted alias
|
|
82
82
|
xcrun simctl io <udid> screenshot --type=png native.png
|
|
83
|
-
#
|
|
84
|
-
|
|
85
|
-
npx pixelmatch native.png
|
|
83
|
+
# peach side: same screen, same appearance
|
|
84
|
+
peach screenshot -o peach.png
|
|
85
|
+
npx pixelmatch native.png peach.png diff.png 0.1
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
`xcodebuildmcp simulator screenshot` may return an optimized JPEG even when the
|
|
@@ -97,7 +97,7 @@ under unrelated chrome.
|
|
|
97
97
|
## typical workflow
|
|
98
98
|
|
|
99
99
|
1. structural diff first — confirm the change is genuinely visual.
|
|
100
|
-
2. capture the affected screen with `
|
|
100
|
+
2. capture the affected screen with `peach screenshot` (crop to the
|
|
101
101
|
element if you can).
|
|
102
102
|
3. diff against the baseline (previous commit, or a native capture).
|
|
103
103
|
4. iterate the rendering until the diff is under threshold.
|
|
@@ -114,7 +114,7 @@ under unrelated chrome.
|
|
|
114
114
|
## recovery — common failure modes
|
|
115
115
|
|
|
116
116
|
- **a single icon/glyph diffs** — font-load race or image not yet
|
|
117
|
-
cached. recapture after `
|
|
117
|
+
cached. recapture after `peach wait idle`, or navigate away and back
|
|
118
118
|
to seed the cache.
|
|
119
119
|
- **everything diffs by a constant offset** — you captured the two sides
|
|
120
120
|
on different devices or appearances. pin both, recapture.
|