peachsim 0.1.527
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 +22 -0
- package/README.md +640 -0
- package/cli/app-config.ts +82 -0
- package/cli/app-fonts.ts +388 -0
- package/cli/app-project.ts +59 -0
- package/cli/app-splash.ts +171 -0
- package/cli/app-state-reset.ts +26 -0
- package/cli/auth.ts +184 -0
- package/cli/bin.ts +59 -0
- package/cli/bridge-diagnostics.ts +226 -0
- package/cli/bridge-flow-runner.ts +2806 -0
- package/cli/browser-backend.ts +44 -0
- package/cli/browser-evals.ts +96 -0
- package/cli/cli-update.ts +261 -0
- package/cli/cloud-client.ts +1530 -0
- package/cli/cloud-dispatch.ts +206 -0
- package/cli/cloud-session.ts +227 -0
- package/cli/command-contract.ts +221 -0
- package/cli/command-registry.ts +304 -0
- package/cli/commands/agent-wrapper.ts +1048 -0
- package/cli/commands/agent.ts +439 -0
- package/cli/commands/app-fonts.ts +99 -0
- package/cli/commands/assert.ts +542 -0
- package/cli/commands/auth.ts +71 -0
- package/cli/commands/box/bundle-plane.ts +71 -0
- package/cli/commands/box/checkout-plane.ts +256 -0
- package/cli/commands/box/plane-share.ts +208 -0
- package/cli/commands/box/rnx-command.ts +60 -0
- package/cli/commands/box/search-command.ts +157 -0
- package/cli/commands/box.ts +925 -0
- package/cli/commands/camera.ts +266 -0
- package/cli/commands/cleanup.ts +169 -0
- package/cli/commands/compat.ts +176 -0
- package/cli/commands/config.ts +34 -0
- package/cli/commands/control.ts +2154 -0
- package/cli/commands/cpu-profile.ts +941 -0
- package/cli/commands/daemon-mac-app.ts +165 -0
- package/cli/commands/daemon.ts +800 -0
- package/cli/commands/debug.ts +751 -0
- package/cli/commands/desktop.ts +39 -0
- package/cli/commands/detect.ts +201 -0
- package/cli/commands/detox.ts +481 -0
- package/cli/commands/device.ts +134 -0
- package/cli/commands/diagnose.ts +589 -0
- package/cli/commands/do-chain.ts +408 -0
- package/cli/commands/electron.ts +94 -0
- package/cli/commands/film.ts +379 -0
- package/cli/commands/flow.ts +1240 -0
- package/cli/commands/inspect/actions.ts +516 -0
- package/cli/commands/inspect/core.ts +2086 -0
- package/cli/commands/inspect/count.ts +17 -0
- package/cli/commands/inspect/describe.ts +119 -0
- package/cli/commands/inspect/env.ts +25 -0
- package/cli/commands/inspect/find.ts +169 -0
- package/cli/commands/inspect/get-layout.ts +53 -0
- package/cli/commands/inspect/keyboard.ts +54 -0
- package/cli/commands/inspect/list.ts +175 -0
- package/cli/commands/inspect/memory.ts +215 -0
- package/cli/commands/inspect/redaction.ts +39 -0
- package/cli/commands/inspect/resolve-target.ts +77 -0
- package/cli/commands/inspect/screens.ts +78 -0
- package/cli/commands/inspect/settle.ts +32 -0
- package/cli/commands/inspect/settling.ts +197 -0
- package/cli/commands/inspect/shared.ts +259 -0
- package/cli/commands/inspect/sleep.ts +15 -0
- package/cli/commands/inspect/tree.ts +23 -0
- package/cli/commands/inspect/url.ts +17 -0
- package/cli/commands/inspect/wait-event.ts +211 -0
- package/cli/commands/inspect/wait-idle.ts +25 -0
- package/cli/commands/inspect/wait-ready.ts +87 -0
- package/cli/commands/inspect/wait-selector.ts +59 -0
- package/cli/commands/inspect/wait.ts +32 -0
- package/cli/commands/inspect.ts +4738 -0
- package/cli/commands/install-cli.ts +275 -0
- package/cli/commands/install-desktop.ts +385 -0
- package/cli/commands/login.ts +357 -0
- package/cli/commands/logout.ts +24 -0
- package/cli/commands/maestro-generate.ts +375 -0
- package/cli/commands/maestro.ts +536 -0
- package/cli/commands/mode.ts +58 -0
- package/cli/commands/no-bridge-hint.ts +80 -0
- package/cli/commands/perf.ts +67 -0
- package/cli/commands/permissions.ts +203 -0
- package/cli/commands/platform.ts +410 -0
- package/cli/commands/preview.ts +103 -0
- package/cli/commands/profile.ts +106 -0
- package/cli/commands/react.ts +353 -0
- package/cli/commands/record.ts +1435 -0
- package/cli/commands/report-issue.ts +305 -0
- package/cli/commands/reset.ts +89 -0
- package/cli/commands/runtime.ts +348 -0
- package/cli/commands/screenshot-command.ts +106 -0
- package/cli/commands/screenshot-layers.ts +144 -0
- package/cli/commands/screenshot-mode.ts +38 -0
- package/cli/commands/screenshot.ts +492 -0
- package/cli/commands/screenshots-capture.ts +608 -0
- package/cli/commands/screenshots.ts +127 -0
- package/cli/commands/serve.ts +139 -0
- package/cli/commands/setup.ts +416 -0
- package/cli/commands/shell-boolean-mode.ts +82 -0
- package/cli/commands/skills.ts +468 -0
- package/cli/commands/slides.ts +357 -0
- package/cli/commands/state.ts +94 -0
- package/cli/commands/storage.ts +58 -0
- package/cli/commands/telemetry.ts +55 -0
- package/cli/commands/test.ts +535 -0
- package/cli/commands/three-mode.ts +771 -0
- package/cli/commands/timeline.ts +121 -0
- package/cli/commands/upgrade.ts +167 -0
- package/cli/commands/upload.ts +1203 -0
- package/cli/commands/version.ts +63 -0
- package/cli/commands/welcome.ts +17 -0
- package/cli/commands/what-happened.ts +328 -0
- package/cli/current-sim.ts +217 -0
- package/cli/desktop-companion.ts +315 -0
- package/cli/drivers/electron.ts +70 -0
- package/cli/drivers/index.ts +20 -0
- package/cli/drivers/playwright-provisioning.ts +184 -0
- package/cli/drivers/playwright-sim-host.ts +537 -0
- package/cli/drivers/playwright.ts +209 -0
- package/cli/drivers/registry.ts +65 -0
- package/cli/drivers/types.ts +102 -0
- package/cli/flow-export.ts +55 -0
- package/cli/flow-file.ts +142 -0
- package/cli/flow-live-status.ts +126 -0
- package/cli/flow-session.ts +140 -0
- package/cli/help-core.ts +143 -0
- package/cli/help.ts +44 -0
- package/cli/hidden-runtime-alias.ts +19 -0
- package/cli/hints.ts +214 -0
- package/cli/inspect-notice-state.ts +114 -0
- package/cli/internal-child.ts +176 -0
- package/cli/maestro-js.ts +323 -0
- package/cli/main.ts +704 -0
- package/cli/open-url.ts +8 -0
- package/cli/outbound-endpoints.ts +830 -0
- package/cli/parent-pid.ts +204 -0
- package/cli/parse-args.ts +189 -0
- package/cli/privacy.ts +53 -0
- package/cli/prompt.ts +56 -0
- package/cli/recording-access.ts +108 -0
- package/cli/registry.ts +2 -0
- package/cli/resolve-assets.ts +63 -0
- package/cli/rnx-in-process.ts +98 -0
- package/cli/run-registry.ts +226 -0
- package/cli/run-rnx-core.ts +148 -0
- package/cli/run-rnx.ts +137 -0
- package/cli/runtime-notes.ts +66 -0
- package/cli/runtime-summary.ts +25 -0
- package/cli/secure-file.ts +31 -0
- package/cli/self-invocation.ts +58 -0
- package/cli/send-to-box.ts +109 -0
- package/cli/setup-repository.ts +191 -0
- package/cli/shell-init.ts +98 -0
- package/cli/standalone.ts +4 -0
- package/cli/telemetry.ts +84 -0
- package/cli/ui.ts +68 -0
- package/cli/ws-bridge.ts +1020 -0
- package/detox/attempt-events.cjs +23 -0
- package/detox/colors.ts +54 -0
- package/detox/config-loader.ts +135 -0
- package/detox/element-types.ts +48 -0
- package/detox/expectations.ts +534 -0
- package/detox/gestures.ts +501 -0
- package/detox/index.ts +2694 -0
- package/detox/jest-preset.cjs +29 -0
- package/detox/jest-setup-after-env.cjs +22 -0
- package/detox/matchers.ts +30 -0
- package/detox/motion-change.cjs +109 -0
- package/detox/motion-change.d.cts +35 -0
- package/detox/navigation-lifecycle.ts +290 -0
- package/detox/navigation.ts +43 -0
- package/detox/proof-frame.cjs +114 -0
- package/detox/record-block-execution.cjs +78 -0
- package/detox/screenshots/animated-color-test-rest-norngh.png +0 -0
- package/detox/screenshots/color-test-after-drag-norngh.png +0 -0
- package/detox/screenshots/color-test-rest-norngh.png +0 -0
- package/detox/screenshots/theme-blue-toggle.png +0 -0
- package/detox/screenshots/theme-blue.png +0 -0
- package/detox/screenshots/theme-red-toggle.png +0 -0
- package/detox/screenshots/theme-red.png +0 -0
- package/dist-lib/agent-daemon-client.cjs +502 -0
- package/dist-lib/agent-events.cjs +48 -0
- package/dist-lib/agent-identity.cjs +53 -0
- package/dist-lib/agent-sessions.cjs +759 -0
- package/dist-lib/attached-projects.cjs +526 -0
- package/dist-lib/auth/shared-session.cjs +208 -0
- package/dist-lib/backend-origin.cjs +88 -0
- package/dist-lib/beta.cjs +41 -0
- package/dist-lib/beta.mjs +13 -0
- package/dist-lib/bridge-constants.cjs +161 -0
- package/dist-lib/bridge-contract-input.cjs +451 -0
- package/dist-lib/bridge-contract-input.mjs +414 -0
- package/dist-lib/bridge-contract.cjs +130 -0
- package/dist-lib/bridge-contract.mjs +94 -0
- package/dist-lib/capture-contract.cjs +220 -0
- package/dist-lib/capture-contract.mjs +190 -0
- package/dist-lib/cli-constants.cjs +32 -0
- package/dist-lib/cloud-contract.cjs +194 -0
- package/dist-lib/cloud-contract.mjs +145 -0
- package/dist-lib/cloud.cjs +670 -0
- package/dist-lib/cloud.mjs +639 -0
- package/dist-lib/config.cjs +96 -0
- package/dist-lib/detox/index.cjs +3789 -0
- package/dist-lib/detox/jest-preset.cjs +29 -0
- package/dist-lib/dev-bundle-resolution.cjs +290 -0
- package/dist-lib/home-paths.cjs +638 -0
- package/dist-lib/host/bridge-host.cjs +10903 -0
- package/dist-lib/host/fetch-proxy-handler.cjs +421 -0
- package/dist-lib/host/fetch-proxy-overrides.cjs +63 -0
- package/dist-lib/host/fetch-proxy-overrides.mjs +37 -0
- package/dist-lib/host/replacement-module-handler.cjs +469 -0
- package/dist-lib/host/websocket-proxy.cjs +298 -0
- package/dist-lib/index.cjs +4268 -0
- package/dist-lib/jump-to-source-babel.cjs +93 -0
- package/dist-lib/jump-to-source-native.cjs +112 -0
- package/dist-lib/menu.cjs +646 -0
- package/dist-lib/menu.mjs +604 -0
- package/dist-lib/metro-fingerprint-registry.cjs +186 -0
- package/dist-lib/metro-fingerprint-registry.mjs +156 -0
- package/dist-lib/metro-production-bundle.cjs +329 -0
- package/dist-lib/metro-production-bundle.mjs +295 -0
- package/dist-lib/metro.cjs +904 -0
- package/dist-lib/profiles.cjs +246 -0
- package/dist-lib/public-brand.cjs +39 -0
- package/dist-lib/react-native-host-modules.cjs +51 -0
- package/dist-lib/react-native-host-modules.mjs +25 -0
- package/dist-lib/render-mode.cjs +54 -0
- package/dist-lib/scripts/dev-server-scanner.cjs +1232 -0
- package/dist-lib/sdk.cjs +2433 -0
- package/dist-lib/sdk.mjs +2336 -0
- package/dist-lib/skills.cjs +39132 -0
- package/dist-lib/swift-submit.cjs +92 -0
- package/dist-lib/swift-submit.mjs +65 -0
- package/dist-lib/swift.cjs +1646 -0
- package/dist-lib/vite.cjs +1591 -0
- package/package.json +290 -0
- package/scripts/dev-server-scanner.ts +1291 -0
- package/scripts/optional-demo-registry.ts +113 -0
- package/skills/contrast/SKILL.md +165 -0
- package/skills/rnx-debug/SKILL.md +433 -0
- package/skills/rnx-perf/SKILL.md +399 -0
- package/skills/rnx-setup/SKILL.md +172 -0
- package/skills/rnx-test/SKILL.md +321 -0
- package/skills/rnx-visual/SKILL.md +126 -0
- package/src/agent-daemon-client.ts +410 -0
- package/src/agent-events.ts +71 -0
- package/src/agent-identity.ts +23 -0
- package/src/agent-prompt.ts +71 -0
- package/src/agent-sessions.ts +580 -0
- package/src/app-url.ts +39 -0
- package/src/attached-projects.ts +539 -0
- package/src/auth/shared-session.ts +235 -0
- package/src/backend-origin.ts +70 -0
- package/src/beta.ts +19 -0
- package/src/bridge-constants.ts +175 -0
- package/src/bridge-contract-input.ts +502 -0
- package/src/bridge-contract.ts +558 -0
- package/src/browser-cache.ts +16 -0
- package/src/capture-contract.ts +587 -0
- package/src/cli-constants.ts +1 -0
- package/src/cli-version.ts +40 -0
- package/src/cloud-contract.ts +274 -0
- package/src/cloud.ts +762 -0
- package/src/codex-client.ts +234 -0
- package/src/config.ts +132 -0
- package/src/connect.ts +101 -0
- package/src/dev-bundle-resolution.ts +346 -0
- package/src/dev-server-open.ts +198 -0
- package/src/disk-cleanup.ts +540 -0
- package/src/flow-timeout-scale.ts +15 -0
- package/src/home-paths.ts +806 -0
- package/src/host/agent-host.ts +666 -0
- package/src/host/bridge-host.ts +2788 -0
- package/src/host/fetch-proxy-handler.ts +449 -0
- package/src/host/fetch-proxy-overrides.ts +51 -0
- package/src/host/open-url.ts +89 -0
- package/src/host/plane-host.ts +203 -0
- package/src/host/replacement-module-handler.ts +158 -0
- package/src/host/websocket-proxy.ts +315 -0
- package/src/index.ts +71 -0
- package/src/jump-to-source-babel.ts +135 -0
- package/src/jump-to-source-native.ts +102 -0
- package/src/menu.ts +777 -0
- package/src/metro-fingerprint-registry.ts +302 -0
- package/src/metro-plugin.ts +341 -0
- package/src/metro-production-bundle.ts +471 -0
- package/src/native-dev-bundle-url.ts +118 -0
- package/src/native-seam-manifest.ts +341 -0
- package/src/playwright-host-log.ts +16 -0
- package/src/plist.ts +27 -0
- package/src/poll-until.ts +123 -0
- package/src/profiles.ts +179 -0
- package/src/public-brand.ts +9 -0
- package/src/react-native-host-modules.ts +26 -0
- package/src/render-mode.ts +27 -0
- package/src/rolldown-plugin-swift.ts +240 -0
- package/src/runtime-assets.ts +233 -0
- package/src/runtime-delivery.ts +54 -0
- package/src/screenshots/compose.ts +422 -0
- package/src/screenshots/frame-compose.ts +514 -0
- package/src/screenshots/orchestrate.ts +256 -0
- package/src/screenshots/org-deck.ts +91 -0
- package/src/screenshots/registry.ts +58 -0
- package/src/screenshots/schema.ts +364 -0
- package/src/sdk.ts +15 -0
- package/src/settings-bundle.ts +418 -0
- package/src/shell-bridge-identity.ts +15 -0
- package/src/sim-client.ts +697 -0
- package/src/skills/builtin/a11y-review.ts +132 -0
- package/src/skills/builtin/compat-check.ts +71 -0
- package/src/skills/builtin/maestro-test.ts +121 -0
- package/src/skills/builtin/perf-profile.ts +90 -0
- package/src/skills/builtin/screenshot-all.ts +52 -0
- package/src/skills/builtin/visual-diff.ts +100 -0
- package/src/skills/registry.ts +107 -0
- package/src/skills/types.ts +41 -0
- package/src/swift-submit.ts +185 -0
- package/src/swift.ts +7 -0
- package/src/team-machine-prompt.ts +73 -0
- package/src/vite-plugin-one.ts +264 -0
- package/src/vite-plugin-swift.ts +620 -0
- package/src/vite-plugin.ts +1946 -0
- package/src/worklets-babel.ts +250 -0
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
// the wire contract for the sootsim ws bridge. the engine implements it in
|
|
2
|
+
// sootsim-engine/src/mcp/ws-bridge.ts; the rnxsim cli client, the SimClient
|
|
3
|
+
// sdk, and the flow runner speak it. it is the single owner of these shapes,
|
|
4
|
+
// and neither side redeclares them.
|
|
5
|
+
//
|
|
6
|
+
// it lives in rnxsim rather than the engine because rnxsim is published and
|
|
7
|
+
// sootsim-engine is `private: true`. the engine already depends on rnxsim
|
|
8
|
+
// (see its `rnxsim` dependency and its `rnxsim/bridge-constants` import), so
|
|
9
|
+
// this is the direction that ships.
|
|
10
|
+
|
|
11
|
+
import type {
|
|
12
|
+
SootSimAgentActionDetail,
|
|
13
|
+
SootSimCaptureFilter,
|
|
14
|
+
SootSimExternalAppLifecycleOptions,
|
|
15
|
+
SootSimStorageResetStrategy,
|
|
16
|
+
} from '@rnx/globals'
|
|
17
|
+
|
|
18
|
+
export type BridgeCommandType =
|
|
19
|
+
| 'evaluate'
|
|
20
|
+
| 'call'
|
|
21
|
+
| 'screenshot'
|
|
22
|
+
| 'capture'
|
|
23
|
+
| 'captureRegions'
|
|
24
|
+
| 'settle'
|
|
25
|
+
| 'setAppearance'
|
|
26
|
+
| 'openUrl'
|
|
27
|
+
| 'memory'
|
|
28
|
+
| 'tap'
|
|
29
|
+
| 'longPress'
|
|
30
|
+
| 'keyboard'
|
|
31
|
+
| 'tree'
|
|
32
|
+
| 'focus'
|
|
33
|
+
| 'close'
|
|
34
|
+
| 'flowStatus'
|
|
35
|
+
| 'perform'
|
|
36
|
+
| 'waitFor'
|
|
37
|
+
| 'state'
|
|
38
|
+
| 'query'
|
|
39
|
+
| 'resolve'
|
|
40
|
+
| 'reset'
|
|
41
|
+
| 'camera'
|
|
42
|
+
| 'diagnostics'
|
|
43
|
+
| 'storageSnapshot'
|
|
44
|
+
|
|
45
|
+
export interface WsCommand {
|
|
46
|
+
id: string | number
|
|
47
|
+
type: BridgeCommandType
|
|
48
|
+
// local daemon routing; cloud transport strips it before execution.
|
|
49
|
+
simId?: string
|
|
50
|
+
// flowStatus — live flow-runner progress payload (see flow-run-store)
|
|
51
|
+
status?: Record<string, unknown>
|
|
52
|
+
code?: string
|
|
53
|
+
path?: string
|
|
54
|
+
args?: unknown[]
|
|
55
|
+
x?: number
|
|
56
|
+
y?: number
|
|
57
|
+
durationMs?: number
|
|
58
|
+
maxFrames?: number
|
|
59
|
+
target?: SootSimAgentActionDetail['target']
|
|
60
|
+
action?: string
|
|
61
|
+
text?: string
|
|
62
|
+
appearance?: 'light' | 'dark'
|
|
63
|
+
url?: string
|
|
64
|
+
includeVisual?: boolean
|
|
65
|
+
includeFonts?: boolean
|
|
66
|
+
includeRasterAtlas?: boolean
|
|
67
|
+
regions?: import('./capture-contract').RnxCaptureRegionRequest[]
|
|
68
|
+
depth?: number
|
|
69
|
+
// screenshot — which canvas layers to composite. omit for full (today's
|
|
70
|
+
// default: everything including iOS chrome). 'tenant' excludes the shell
|
|
71
|
+
// overlay for a clean app capture.
|
|
72
|
+
layers?: 'full' | 'tenant' | 'shell'
|
|
73
|
+
// screenshot — engine-side layer isolation (hide subtrees / solo one
|
|
74
|
+
// subtree on transparency). see SootSimCaptureOptions.captureFilter.
|
|
75
|
+
captureFilter?: SootSimCaptureFilter
|
|
76
|
+
// screenshot — optional crop rect in logical sootsim coords. the capture
|
|
77
|
+
// module scales x/y/w/h by device pixel ratio before cropping.
|
|
78
|
+
crop?: { x: number; y: number; w: number; h: number }
|
|
79
|
+
// perform — ordered batch executed inside the page, no round trips
|
|
80
|
+
steps?: PerformStep[]
|
|
81
|
+
performOptions?: PerformOptions
|
|
82
|
+
// waitFor — one engine-side polling loop and one transport round trip
|
|
83
|
+
waitForOptions?: SemanticWaitOptions
|
|
84
|
+
// state — compound screenshot + tree + route + errors
|
|
85
|
+
stateOptions?: SimStateOptions
|
|
86
|
+
// query / resolve — structured visible-tree reads and selector geometry
|
|
87
|
+
query?: SimSemanticQuery
|
|
88
|
+
selector?: SimSemanticResolveSelector
|
|
89
|
+
// reset — two-tier app state wipe
|
|
90
|
+
resetOptions?: ResetOptions
|
|
91
|
+
// camera — fixture injection into the host camera pipeline
|
|
92
|
+
camera?: CameraCommand
|
|
93
|
+
// diagnostics — read-only engine debug state: channel recording, the sheet /
|
|
94
|
+
// portal / boundary finders, and the recent event ring.
|
|
95
|
+
diagnostics?: DiagnosticsOptions
|
|
96
|
+
// storageSnapshot — the running app's own storage and route, as
|
|
97
|
+
// `StorageSnapshot` from the engine's preview/storage-snapshot module. the
|
|
98
|
+
// default result is share-safe; `includeCredentials` carries the signed-in
|
|
99
|
+
// session and belongs only to a send to the owner's own box.
|
|
100
|
+
storageSnapshotOptions?: { includeCredentials?: boolean }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// perform — batched input
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
// every step maps onto a primitive that already exists on
|
|
108
|
+
// SootSim.bridges.interact / .keyboard / .test. the batch runs entirely inside
|
|
109
|
+
// the page so gesture timing is real wall-clock timing, not ws round-trips.
|
|
110
|
+
//
|
|
111
|
+
// deliberately absent: text-based tap resolution. matching by visible text is
|
|
112
|
+
// fuzzy, needs ranking and failure diagnostics, and lives once in the cli's
|
|
113
|
+
// tapByText. the sdk resolves text to coordinates before it builds a batch.
|
|
114
|
+
// testID lookup is exact, so tapId resolves in-engine.
|
|
115
|
+
export type PerformStep =
|
|
116
|
+
// raw pointer steps — full control over gesture physics
|
|
117
|
+
| { type: 'touchDown'; x: number; y: number; pointerId?: number }
|
|
118
|
+
| { type: 'touchMove'; x: number; y: number; pointerId?: number }
|
|
119
|
+
| { type: 'touchUp'; x: number; y: number; pointerId?: number }
|
|
120
|
+
| { type: 'touchCancel'; pointerId?: number }
|
|
121
|
+
// semantic steps
|
|
122
|
+
| { type: 'tap'; x: number; y: number; target?: SootSimAgentActionDetail['target'] }
|
|
123
|
+
| { type: 'tapId'; id: string }
|
|
124
|
+
| { type: 'doubleTap'; x: number; y: number; gapMs?: number }
|
|
125
|
+
| {
|
|
126
|
+
type: 'longPress'
|
|
127
|
+
x: number
|
|
128
|
+
y: number
|
|
129
|
+
durationMs?: number
|
|
130
|
+
target?: SootSimAgentActionDetail['target']
|
|
131
|
+
}
|
|
132
|
+
| {
|
|
133
|
+
type: 'drag'
|
|
134
|
+
fromX: number
|
|
135
|
+
fromY: number
|
|
136
|
+
toX: number
|
|
137
|
+
toY: number
|
|
138
|
+
steps?: number
|
|
139
|
+
stepMs?: number
|
|
140
|
+
}
|
|
141
|
+
| {
|
|
142
|
+
type: 'pinch'
|
|
143
|
+
fromX1: number
|
|
144
|
+
fromY1: number
|
|
145
|
+
fromX2: number
|
|
146
|
+
fromY2: number
|
|
147
|
+
toX1: number
|
|
148
|
+
toY1: number
|
|
149
|
+
toX2: number
|
|
150
|
+
toY2: number
|
|
151
|
+
steps?: number
|
|
152
|
+
stepMs?: number
|
|
153
|
+
}
|
|
154
|
+
| { type: 'scroll'; id: string; x?: number; y?: number; animated?: boolean }
|
|
155
|
+
| { type: 'type'; text: string }
|
|
156
|
+
| { type: 'key'; key: string }
|
|
157
|
+
| { type: 'dismissKeyboard' }
|
|
158
|
+
| { type: 'wait'; ms: number }
|
|
159
|
+
| {
|
|
160
|
+
type: 'waitFor'
|
|
161
|
+
testID?: string
|
|
162
|
+
id?: string
|
|
163
|
+
condition?: 'present' | 'mounted' | 'absent'
|
|
164
|
+
timeoutMs?: number
|
|
165
|
+
}
|
|
166
|
+
// limrun parity steps. each maps onto an engine primitive and reports
|
|
167
|
+
// per step; the refused ones below parse but never run.
|
|
168
|
+
| { type: 'setElementValue'; id: string; text: string; submit?: boolean }
|
|
169
|
+
| { type: 'toggleKeyboard' }
|
|
170
|
+
| { type: 'openUrl'; url: string }
|
|
171
|
+
| { type: 'keyDown'; key: string }
|
|
172
|
+
| { type: 'keyUp'; key: string }
|
|
173
|
+
| { type: 'setOrientation'; orientation: 'portrait' | 'landscape' }
|
|
174
|
+
| { type: 'deviceInfo' }
|
|
175
|
+
// refused with a named reason, never emulated: no hardware-button model,
|
|
176
|
+
// no storekit simulation, no stepper primitive, and key/orientation state
|
|
177
|
+
// the engine does not hold.
|
|
178
|
+
| { type: 'buttonDown'; button?: string }
|
|
179
|
+
| { type: 'buttonUp'; button?: string }
|
|
180
|
+
| { type: 'incrementElement'; id: string }
|
|
181
|
+
| { type: 'decrementElement'; id: string }
|
|
182
|
+
| { type: 'discoverStoreKitConfig' }
|
|
183
|
+
| { type: 'clearStoreKitConfig' }
|
|
184
|
+
|
|
185
|
+
export interface PerformOptions {
|
|
186
|
+
// stop the batch at the first failing step. default true — a gesture whose
|
|
187
|
+
// touchDown missed should not keep dragging.
|
|
188
|
+
stopOnError?: boolean
|
|
189
|
+
// ceiling on batch PROGRESS, checked between steps: once it passes, the
|
|
190
|
+
// batch starts no further steps and reports which one it reached. a step
|
|
191
|
+
// already running is always awaited to completion, never abandoned, because
|
|
192
|
+
// a gesture that keeps dispatching pointer events after the caller has been
|
|
193
|
+
// told the batch failed is worse than a late reply. every step is bounded on
|
|
194
|
+
// its own (drag and pinch by steps * stepMs, wait by ms, waitFor by its own
|
|
195
|
+
// timeout), and a wedged worker is caught by the CLI client's per-command
|
|
196
|
+
// timeout one layer up. default 30000.
|
|
197
|
+
timeoutMs?: number
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// observed device identity for the `deviceInfo` step: the live device spec
|
|
201
|
+
// in both runtimes, so every field is measured, never a default.
|
|
202
|
+
export interface PerformDeviceInfo {
|
|
203
|
+
platform: string
|
|
204
|
+
model?: string
|
|
205
|
+
width: number
|
|
206
|
+
height: number
|
|
207
|
+
scale: number
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// steps that parse but never run. one owner for the refusal vocabulary so
|
|
211
|
+
// the browser page and the cpu runtime refuse with the same named reason and
|
|
212
|
+
// neither plane emulates what the engine cannot do.
|
|
213
|
+
export const REFUSED_PERFORM_STEP_TYPES = [
|
|
214
|
+
'keyDown',
|
|
215
|
+
'keyUp',
|
|
216
|
+
'setOrientation',
|
|
217
|
+
'buttonDown',
|
|
218
|
+
'buttonUp',
|
|
219
|
+
'incrementElement',
|
|
220
|
+
'decrementElement',
|
|
221
|
+
'discoverStoreKitConfig',
|
|
222
|
+
'clearStoreKitConfig',
|
|
223
|
+
] as const
|
|
224
|
+
|
|
225
|
+
export type RefusedPerformStepType = (typeof REFUSED_PERFORM_STEP_TYPES)[number]
|
|
226
|
+
|
|
227
|
+
export function refusedPerformStepReason(type: RefusedPerformStepType): string {
|
|
228
|
+
switch (type) {
|
|
229
|
+
case 'keyDown':
|
|
230
|
+
case 'keyUp':
|
|
231
|
+
return `${type} is not supported: keys dispatch atomically; use the key step`
|
|
232
|
+
case 'setOrientation':
|
|
233
|
+
return 'setOrientation is not supported: the simulator viewport is fixed at boot'
|
|
234
|
+
case 'buttonDown':
|
|
235
|
+
case 'buttonUp':
|
|
236
|
+
return `${type} is not supported: the simulator has no hardware buttons`
|
|
237
|
+
case 'incrementElement':
|
|
238
|
+
case 'decrementElement':
|
|
239
|
+
return `${type} is not supported: steppers have no engine primitive; drive them with tapId`
|
|
240
|
+
case 'discoverStoreKitConfig':
|
|
241
|
+
case 'clearStoreKitConfig':
|
|
242
|
+
return `${type} is not supported: storekit has no simulator model`
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// returns the refusal for a refused step, null when the step is runnable.
|
|
247
|
+
// every variant is listed so adding a step forces its classification here;
|
|
248
|
+
// the executors mirror the refused cases in their own switches.
|
|
249
|
+
export function performStepRefusal(type: PerformStep['type']): string | null {
|
|
250
|
+
switch (type) {
|
|
251
|
+
case 'keyDown':
|
|
252
|
+
case 'keyUp':
|
|
253
|
+
case 'setOrientation':
|
|
254
|
+
case 'buttonDown':
|
|
255
|
+
case 'buttonUp':
|
|
256
|
+
case 'incrementElement':
|
|
257
|
+
case 'decrementElement':
|
|
258
|
+
case 'discoverStoreKitConfig':
|
|
259
|
+
case 'clearStoreKitConfig':
|
|
260
|
+
return refusedPerformStepReason(type)
|
|
261
|
+
case 'touchDown':
|
|
262
|
+
case 'touchMove':
|
|
263
|
+
case 'touchUp':
|
|
264
|
+
case 'touchCancel':
|
|
265
|
+
case 'tap':
|
|
266
|
+
case 'tapId':
|
|
267
|
+
case 'doubleTap':
|
|
268
|
+
case 'longPress':
|
|
269
|
+
case 'drag':
|
|
270
|
+
case 'pinch':
|
|
271
|
+
case 'scroll':
|
|
272
|
+
case 'type':
|
|
273
|
+
case 'key':
|
|
274
|
+
case 'dismissKeyboard':
|
|
275
|
+
case 'setElementValue':
|
|
276
|
+
case 'toggleKeyboard':
|
|
277
|
+
case 'openUrl':
|
|
278
|
+
case 'deviceInfo':
|
|
279
|
+
case 'wait':
|
|
280
|
+
case 'waitFor':
|
|
281
|
+
return null
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export interface PerformStepResult {
|
|
286
|
+
index: number
|
|
287
|
+
type: PerformStep['type']
|
|
288
|
+
ok: boolean
|
|
289
|
+
// step-specific payload: tap hit info, waitFor match, resolved coordinates
|
|
290
|
+
value?: unknown
|
|
291
|
+
error?: string
|
|
292
|
+
// wall-clock ms this step took inside the page
|
|
293
|
+
durationMs: number
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export interface PerformResult {
|
|
297
|
+
ok: boolean
|
|
298
|
+
steps: PerformStepResult[]
|
|
299
|
+
// number of steps that ran. less than steps.length when the batch aborted.
|
|
300
|
+
completed: number
|
|
301
|
+
durationMs: number
|
|
302
|
+
error?: string
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// ---------------------------------------------------------------------------
|
|
306
|
+
// waitFor — engine-side semantic condition polling
|
|
307
|
+
// ---------------------------------------------------------------------------
|
|
308
|
+
|
|
309
|
+
// `present` is what a person can see: the node must survive the occlusion pass,
|
|
310
|
+
// so a button behind a sheet does not count. `mounted` asks only whether the
|
|
311
|
+
// node exists and is laid out, which is the right question for a marker the app
|
|
312
|
+
// renders as proof of something (a build id, a launch phase) rather than as
|
|
313
|
+
// something to look at — those are 1x1 and painted under the whole app, so they
|
|
314
|
+
// are permanently occluded and `present` can never match one.
|
|
315
|
+
export type SemanticWaitCondition =
|
|
316
|
+
| { type: 'ready' }
|
|
317
|
+
| { type: 'present'; selector: SimSemanticResolveSelector }
|
|
318
|
+
| { type: 'mounted'; selector: SimSemanticResolveSelector }
|
|
319
|
+
| { type: 'absent'; selector: SimSemanticResolveSelector }
|
|
320
|
+
|
|
321
|
+
export interface SemanticWaitOptions {
|
|
322
|
+
condition: SemanticWaitCondition
|
|
323
|
+
timeoutMs?: number
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export interface SemanticReadyProbe {
|
|
327
|
+
flag: unknown
|
|
328
|
+
at: number
|
|
329
|
+
nodes: number
|
|
330
|
+
targets: number
|
|
331
|
+
liveFrameActive: boolean
|
|
332
|
+
liveFrameChannels: number
|
|
333
|
+
liveFramePublishes: number
|
|
334
|
+
errors: number
|
|
335
|
+
loadingText: string
|
|
336
|
+
externalReady: boolean | null
|
|
337
|
+
externalStatus: string
|
|
338
|
+
externalError: string
|
|
339
|
+
suppressedEntryError: string
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// react native's own Pressable/Touchable delayLongPress default, and the
|
|
343
|
+
// ceiling any transport accepts for a press-and-hold. a driver that holds
|
|
344
|
+
// longer than this is describing a drag, not a long press.
|
|
345
|
+
export const SIM_LONG_PRESS_DEFAULT_MS = 500
|
|
346
|
+
export const SIM_LONG_PRESS_MAX_MS = 5_000
|
|
347
|
+
|
|
348
|
+
export const SEMANTIC_READY_CONTENT_NODE_FLOOR = 100
|
|
349
|
+
export const SEMANTIC_READY_NODE_STABLE_MS = 750
|
|
350
|
+
export const SEMANTIC_READY_POLL_MS = 150
|
|
351
|
+
|
|
352
|
+
export const PUBLIC_NO_NETWORK_MARKER = 'public RNX Cloud simulators have no network'
|
|
353
|
+
export const HEADLESS_TENANT_FETCH_HUNG_MARKER = 'headless tenant fetch hung'
|
|
354
|
+
|
|
355
|
+
export function readyProbeHasContent(
|
|
356
|
+
probe: Pick<SemanticReadyProbe, 'nodes' | 'targets'> &
|
|
357
|
+
Partial<Pick<SemanticReadyProbe, 'liveFrameActive'>>,
|
|
358
|
+
): boolean {
|
|
359
|
+
return (
|
|
360
|
+
probe.liveFrameActive ||
|
|
361
|
+
probe.targets > 0 ||
|
|
362
|
+
probe.nodes >= SEMANTIC_READY_CONTENT_NODE_FLOOR
|
|
363
|
+
)
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export function readyProbeHasTargetContent(
|
|
367
|
+
probe: Pick<SemanticReadyProbe, 'targets'> &
|
|
368
|
+
Partial<Pick<SemanticReadyProbe, 'liveFrameActive'>>,
|
|
369
|
+
): boolean {
|
|
370
|
+
return probe.liveFrameActive || probe.targets > 0
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export interface SemanticWaitResult {
|
|
374
|
+
matched: boolean
|
|
375
|
+
elapsedMs: number
|
|
376
|
+
polls: number
|
|
377
|
+
probe?: SemanticReadyProbe
|
|
378
|
+
node?: SimSemanticNode
|
|
379
|
+
error?: string
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// ---------------------------------------------------------------------------
|
|
383
|
+
// state — one round-trip situational awareness
|
|
384
|
+
// ---------------------------------------------------------------------------
|
|
385
|
+
|
|
386
|
+
export interface DiagnosticsOptions {
|
|
387
|
+
// debug channels to record from this point on. omitted leaves recording as
|
|
388
|
+
// it is; an empty list stops recording.
|
|
389
|
+
channels?: readonly string[]
|
|
390
|
+
find?: 'sheets' | 'portals' | 'boundaries'
|
|
391
|
+
recentChannel?: string
|
|
392
|
+
recentLimit?: number
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export interface DiagnosticsResult {
|
|
396
|
+
channels: string[]
|
|
397
|
+
runtime: unknown
|
|
398
|
+
found: unknown[] | null
|
|
399
|
+
events: unknown[]
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export interface SimStateOptions {
|
|
403
|
+
// omit a section an agent does not need this turn
|
|
404
|
+
screenshot?: boolean
|
|
405
|
+
tree?: boolean
|
|
406
|
+
route?: boolean
|
|
407
|
+
errors?: boolean
|
|
408
|
+
// include the bounded guest console tail. omitted by the ordinary state
|
|
409
|
+
// command so one-shot state remains compact; `rnx logs` requests it.
|
|
410
|
+
logs?: boolean
|
|
411
|
+
// tree depth, matching the standalone `tree` command. default 5.
|
|
412
|
+
depth?: number
|
|
413
|
+
layers?: WsCommand['layers']
|
|
414
|
+
// cap on recentErrors entries. default 20.
|
|
415
|
+
errorLimit?: number
|
|
416
|
+
// cap on recentLogs entries. default and maximum 100.
|
|
417
|
+
logLimit?: number
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
export interface SimStateLogEntry {
|
|
421
|
+
level: string
|
|
422
|
+
text: string
|
|
423
|
+
at?: number
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
export interface SimStateResult {
|
|
427
|
+
// png data uri, same encoding the `screenshot` command returns
|
|
428
|
+
screenshot?: unknown
|
|
429
|
+
tree?: SimSemanticNode[]
|
|
430
|
+
route?: { url?: string; screen?: string | null; stack?: string[] } | null
|
|
431
|
+
recentErrors?: SimStateLogEntry[]
|
|
432
|
+
recentLogs?: SimStateLogEntry[]
|
|
433
|
+
keyboard?: { visible: boolean; mode?: string | null }
|
|
434
|
+
capturedAt: number
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// ---------------------------------------------------------------------------
|
|
438
|
+
// semantic tree — pruned visible structure shared by local and cloud runtimes
|
|
439
|
+
// ---------------------------------------------------------------------------
|
|
440
|
+
|
|
441
|
+
export interface SimSemanticGeometry {
|
|
442
|
+
x: number
|
|
443
|
+
y: number
|
|
444
|
+
width: number
|
|
445
|
+
height: number
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
export interface SimSemanticNode {
|
|
449
|
+
nodeId: number
|
|
450
|
+
type: string
|
|
451
|
+
testID?: string
|
|
452
|
+
text?: string
|
|
453
|
+
role?: string
|
|
454
|
+
label?: string
|
|
455
|
+
pressable?: true
|
|
456
|
+
geometry: SimSemanticGeometry
|
|
457
|
+
children?: SimSemanticNode[]
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
export type SimSemanticSelector =
|
|
461
|
+
| { testID: string }
|
|
462
|
+
| { text: string }
|
|
463
|
+
| { role: string }
|
|
464
|
+
| { type: string }
|
|
465
|
+
| { pressable: true }
|
|
466
|
+
| { visible: true }
|
|
467
|
+
|
|
468
|
+
export type SimSemanticQuery =
|
|
469
|
+
| { kind: 'tree'; depth?: number }
|
|
470
|
+
| { kind: 'find'; selector: SimSemanticSelector }
|
|
471
|
+
| { kind: 'count' }
|
|
472
|
+
|
|
473
|
+
export interface SimSemanticQueryResult {
|
|
474
|
+
nodes: SimSemanticNode[]
|
|
475
|
+
total: number
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
export type SimSemanticResolveSelector = { testID: string } | { text: string }
|
|
479
|
+
|
|
480
|
+
export interface SimSemanticResolveResult {
|
|
481
|
+
match: SimSemanticNode
|
|
482
|
+
target: SimSemanticNode
|
|
483
|
+
point: { x: number; y: number }
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// ---------------------------------------------------------------------------
|
|
487
|
+
// reset — two-tier app state wipe
|
|
488
|
+
// ---------------------------------------------------------------------------
|
|
489
|
+
|
|
490
|
+
// 'data' clears what a user could clear from inside the app: async storage,
|
|
491
|
+
// MMKV, sqlite, cache dirs. 'full' also clears what only a fresh install would:
|
|
492
|
+
// simulated keychain, user defaults, granted permissions.
|
|
493
|
+
//
|
|
494
|
+
// reset replaces the tenant worker before clearing storage, so background app
|
|
495
|
+
// work cannot refill a store between its clear and verification.
|
|
496
|
+
export type ResetStrategy = SootSimStorageResetStrategy
|
|
497
|
+
|
|
498
|
+
export interface ResetOptions extends Pick<
|
|
499
|
+
SootSimExternalAppLifecycleOptions,
|
|
500
|
+
'initialUrl' | 'launchArguments'
|
|
501
|
+
> {
|
|
502
|
+
strategy?: ResetStrategy
|
|
503
|
+
// relaunch the app after wiping. default true.
|
|
504
|
+
relaunch?: boolean
|
|
505
|
+
// boot the wiped simulator on a live copy of another simulator's storage
|
|
506
|
+
// instead of empty stores: the cheap clean-but-not-cold seam. the id names
|
|
507
|
+
// a simulator on the same account; runtimes that cannot reach another
|
|
508
|
+
// simulator's storage refuse it by name rather than wiping without forking.
|
|
509
|
+
from?: string
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
export interface ResetResult {
|
|
513
|
+
ok: boolean
|
|
514
|
+
strategy: ResetStrategy
|
|
515
|
+
// stores verified empty after the wipe, read back rather than assumed
|
|
516
|
+
cleared: string[]
|
|
517
|
+
// stores this strategy deliberately did NOT clear, each with the reason.
|
|
518
|
+
// a named gap is not a failure, so this leaves `ok` true and stays out of
|
|
519
|
+
// `error`; a caller that cares can branch on it.
|
|
520
|
+
skipped?: Array<{ store: string; reason: string }>
|
|
521
|
+
relaunched: boolean
|
|
522
|
+
// true when reset had to restart the tenant worker instead of doing an
|
|
523
|
+
// in-worker cold remount. a restart is correct but slow, so a caller running
|
|
524
|
+
// reset between tests needs to see which path it got.
|
|
525
|
+
workerReloaded?: boolean
|
|
526
|
+
error?: string
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// ---------------------------------------------------------------------------
|
|
530
|
+
// camera — fixture injection
|
|
531
|
+
// ---------------------------------------------------------------------------
|
|
532
|
+
|
|
533
|
+
// the host thread owns the camera pipeline (hidden <video> -> <canvas> ->
|
|
534
|
+
// ImageBitmap -> worker). injection replaces the source of that <video>, so
|
|
535
|
+
// every downstream consumer — expo-camera's live frame texture and the
|
|
536
|
+
// BarcodeDetector scan loop — sees the fixture with no seam of its own.
|
|
537
|
+
export interface CameraPlayOptions {
|
|
538
|
+
// url the host can fetch. the cli serves the local file from the daemon.
|
|
539
|
+
url: string
|
|
540
|
+
loop?: boolean
|
|
541
|
+
// playback rate, for making a slow fixture scan faster in ci
|
|
542
|
+
rate?: number
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
export type CameraCommand =
|
|
546
|
+
| ({ action: 'play' } & CameraPlayOptions)
|
|
547
|
+
| { action: 'stop' }
|
|
548
|
+
| { action: 'status' }
|
|
549
|
+
|
|
550
|
+
export interface CameraResult {
|
|
551
|
+
ok: boolean
|
|
552
|
+
// 'live' = real getUserMedia, 'fixture' = injected video, 'idle' = no session
|
|
553
|
+
source: 'live' | 'fixture' | 'idle'
|
|
554
|
+
url?: string
|
|
555
|
+
loop?: boolean
|
|
556
|
+
rate?: number
|
|
557
|
+
error?: string
|
|
558
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const DISPOSABLE_BROWSER_CACHE_DIR_NAMES = [
|
|
2
|
+
'Cache',
|
|
3
|
+
'Code Cache',
|
|
4
|
+
'DawnCache',
|
|
5
|
+
'DawnGraphiteCache',
|
|
6
|
+
'DawnWebGPUCache',
|
|
7
|
+
'GPUCache',
|
|
8
|
+
'GrShaderCache',
|
|
9
|
+
'ShaderCache',
|
|
10
|
+
] as const
|
|
11
|
+
|
|
12
|
+
const disposableBrowserCacheDirs = new Set<string>(DISPOSABLE_BROWSER_CACHE_DIR_NAMES)
|
|
13
|
+
|
|
14
|
+
export function isDisposableBrowserCacheDir(name: string): boolean {
|
|
15
|
+
return disposableBrowserCacheDirs.has(name)
|
|
16
|
+
}
|