peachsim 0.1.939 → 0.1.1399
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/README.md +28 -22
- package/cli/app-catalog.ts +29 -14
- package/cli/app-fonts.ts +5 -3
- package/cli/bridge-flow-runner.ts +40 -29
- package/cli/cloud-client.ts +57 -21
- package/cli/cloud-test-tunnel.ts +12 -18
- package/cli/commands/agent.ts +1 -1
- package/cli/commands/app-fonts.ts +3 -3
- package/cli/commands/assert.ts +8 -8
- package/cli/commands/auth.ts +8 -3
- package/cli/commands/box/bundle-plane.ts +13 -1
- package/cli/commands/box.ts +16 -5
- package/cli/commands/compat.ts +1 -1
- package/cli/commands/config.ts +2 -2
- package/cli/commands/control.ts +125 -71
- package/cli/commands/cpu-profile.ts +45 -1
- package/cli/commands/daemon.ts +131 -33
- package/cli/commands/debug.ts +24 -17
- package/cli/commands/desktop.ts +7 -1
- package/cli/commands/detect.ts +101 -0
- package/cli/commands/detox.ts +6 -6
- package/cli/commands/device.ts +12 -12
- package/cli/commands/electron.ts +32 -14
- package/cli/commands/flow.ts +49 -41
- package/cli/commands/guest-host.ts +39 -1
- package/cli/commands/inspect/core.ts +14 -8
- package/cli/commands/inspect/list.ts +1 -1
- package/cli/commands/inspect/settle.ts +5 -3
- package/cli/commands/inspect/settling.ts +229 -44
- package/cli/commands/inspect/wait-idle.ts +3 -2
- package/cli/commands/inspect.ts +105 -93
- package/cli/commands/install-cli.ts +36 -15
- package/cli/commands/install-desktop.ts +68 -195
- package/cli/commands/kotlin.ts +6 -5
- package/cli/commands/login.ts +5 -5
- package/cli/commands/maestro-compare.ts +554 -0
- package/cli/commands/maestro-generate.ts +6 -3
- package/cli/commands/maestro.ts +22 -0
- package/cli/commands/mode.ts +2 -2
- package/cli/commands/no-bridge-hint.ts +6 -2
- package/cli/commands/platform.ts +35 -6
- package/cli/commands/preview.ts +6 -0
- package/cli/commands/project-report.ts +10 -12
- package/cli/commands/record.ts +37 -37
- package/cli/commands/runtime.ts +9 -9
- package/cli/commands/screenshot-layers.ts +4 -4
- package/cli/commands/screenshot-mode.ts +2 -2
- package/cli/commands/screenshot.ts +8 -8
- package/cli/commands/screenshots-capture.ts +2 -2
- package/cli/commands/serve.ts +9 -12
- package/cli/commands/setup.ts +29 -14
- package/cli/commands/shell-boolean-mode.ts +2 -2
- package/cli/commands/show-touches-mode.ts +2 -2
- package/cli/commands/skills.ts +11 -11
- package/cli/commands/swift.ts +29 -11
- package/cli/commands/telemetry.ts +2 -2
- package/cli/commands/test.ts +5 -0
- package/cli/commands/three-mode.ts +3 -3
- package/cli/commands/timeline.ts +4 -4
- package/cli/commands/upgrade.ts +2 -2
- package/cli/commands/upload.ts +15 -15
- package/cli/commands/what-happened.ts +2 -2
- package/cli/current-sim.ts +6 -3
- package/cli/desktop-companion.ts +55 -149
- package/cli/dev-build-freshness.ts +2 -2
- package/cli/drivers/desktop.ts +17 -9
- package/cli/drivers/electron.ts +1 -2
- package/cli/drivers/playwright-sim-host.ts +11 -2
- package/cli/drivers/playwright.ts +35 -2
- package/cli/drivers/types.ts +8 -0
- package/cli/maestro-compare.ts +670 -0
- package/cli/outbound-endpoints.ts +46 -8
- package/cli/recording-access.ts +6 -6
- package/cli/run-registry.ts +1 -1
- package/cli/runtime-compat.ts +5 -1
- package/cli/send-to-box.ts +3 -3
- package/cli/shell-init.ts +2 -1
- package/cli/ws-bridge.ts +9 -5
- package/detox/element-types.ts +1 -0
- package/detox/gestures.ts +3 -3
- package/detox/index.ts +67 -38
- package/detox/navigation-lifecycle.ts +9 -6
- package/detox/proof-frame.cjs +6 -4
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- 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 +1 -1
- package/dist-lib/bridge-contract-input.cjs +42 -17
- package/dist-lib/bridge-contract-input.mjs +41 -16
- package/dist-lib/bridge-contract.cjs +1 -4
- package/dist-lib/bridge-contract.mjs +1 -3
- package/dist-lib/bundle-channel.cjs +2918 -550
- package/dist-lib/capture-contract.cjs +65 -24
- package/dist-lib/capture-contract.mjs +63 -24
- package/dist-lib/cloud-contract.cjs +2 -2
- package/dist-lib/cloud-contract.mjs +2 -2
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +3 -3
- package/dist-lib/cloud.mjs +3 -3
- package/dist-lib/config.cjs +15 -5
- package/dist-lib/config.mjs +154 -0
- package/dist-lib/detox/index.cjs +495 -139
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +1168 -238
- package/dist-lib/expo-swift-metadata.cjs +34 -23
- package/dist-lib/expo-swift-metadata.mjs +32 -23
- package/dist-lib/home-paths.cjs +2 -2
- package/dist-lib/host/bridge-host.cjs +2938 -654
- package/dist-lib/host/fetch-proxy-handler.cjs +14 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +7 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +5 -1
- package/dist-lib/host/replacement-module-handler.cjs +2 -2
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +999 -353
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/kotlin-host.cjs +332 -19
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- 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 +7 -7
- package/dist-lib/metro-production-bundle.mjs +5 -5
- package/dist-lib/metro.cjs +688 -250
- package/dist-lib/native-app-identity-project.cjs +2647 -0
- package/dist-lib/native-app-identity-project.mjs +1257 -0
- package/dist-lib/native-app-identity.cjs +325 -25
- package/dist-lib/native-app-identity.mjs +323 -25
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.mjs +1 -1
- package/dist-lib/plist.cjs +1 -1
- package/dist-lib/plist.mjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +5 -1
- package/dist-lib/react-native-host-modules.mjs +5 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +57 -32
- package/dist-lib/sdk.cjs +231 -51
- package/dist-lib/sdk.mjs +231 -51
- package/dist-lib/skills.cjs +4107 -1374
- package/dist-lib/swift-compile.cjs +290 -30
- package/dist-lib/swift-compile.mjs +290 -30
- package/dist-lib/swift-package.cjs +143 -12
- package/dist-lib/swift-package.mjs +137 -11
- package/dist-lib/swift-submit.cjs +47 -5
- package/dist-lib/swift-submit.mjs +42 -5
- package/dist-lib/swift-toolchain.cjs +7 -2
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +1392 -458
- package/dist-lib/vite.cjs +13 -17
- package/dist-lib/worklet-executable.cjs +248 -33
- package/dist-lib/worklet-executable.mjs +248 -33
- package/install.sh +10 -1
- package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Resources.kt +9 -9
- package/kotlin/AndroidViewSources/android/graphics/Canvas.kt +20 -0
- package/kotlin/AndroidViewSources/android/view/View.kt +211 -0
- package/kotlin/AndroidViewSources/android/widget/FrameLayout.kt +61 -0
- package/kotlin/AndroidViewSources/android/widget/LinearLayout.kt +49 -0
- package/kotlin/AppSources/android/view/Window.kt +36 -0
- package/kotlin/AppSources/android/view/WindowInsets.kt +9 -0
- package/kotlin/AppSources/android/view/WindowInsetsController.kt +5 -0
- package/kotlin/AppSources/android/window/OnBackInvokedDispatcher.kt +48 -0
- package/kotlin/AppSources/androidx/activity/OnBackPressedDispatcher.kt +20 -5
- package/kotlin/AppSources/androidx/compose/foundation/layout/WindowInsets.kt +15 -0
- package/kotlin/AppSources/androidx/compose/ui/platform/ComposeView.kt +2 -1
- package/kotlin/AppSources/dev/peach/app/PeachApp.kt +42 -50
- package/kotlin/ComposeSources/PeachComposeHost.kt +200 -84
- package/kotlin/ExpoComposeSources/PeachAndroidView.kt +87 -0
- package/kotlin/ExpoComposeSources/PeachExpoViewMount.kt +24 -0
- package/kotlin/ExpoComposeSources/dev/peach/expo/PeachExpoCompose.kt +28 -0
- package/kotlin/ExpoComposeSources/expo/modules/kotlin/views/ExpoComposeView.kt +70 -0
- package/kotlin/ExpoSources/dev/peach/expo/PeachExpoRuntime.kt +513 -0
- package/kotlin/ExpoSources/dev/peach/expo/PeachExpoTypes.kt +173 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/AppContext.kt +20 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/Promise.kt +19 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +198 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/exception/CodedException.kt +126 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/functions/Functions.kt +132 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/jni/JavaScriptTypedArray.kt +81 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/modules/Module.kt +98 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +236 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/records/Record.kt +12 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/runtime/Runtime.kt +9 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObject.kt +50 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +57 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedRef.kt +19 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/ConcreteTypedArrays.kt +158 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/GenericTypedArray.kt +8 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArray.kt +29 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArrayIterator.kt +9 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/types/AnyType.kt +155 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/types/Either.kt +91 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/types/Enumerable.kt +6 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/viewevent/ViewEvent.kt +54 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/views/ExpoView.kt +23 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +71 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewProps.kt +35 -0
- package/kotlin/README.md +13 -3
- package/kotlin/Sources/android/os/Build.kt +17 -0
- package/kotlin/Sources/android/os/Handler.kt +35 -0
- package/kotlin/Sources/android/os/Looper.kt +17 -0
- package/kotlin/Sources/android/os/MessageQueue.kt +56 -0
- package/kotlin/Sources/android/os/SystemClock.kt +14 -0
- package/kotlin/Sources/android/util/Log.kt +64 -0
- package/kotlin/Sources/java/security/MessageDigest.kt +114 -0
- package/kotlin/Sources/kotlin/text/StringFormat.kt +9 -0
- package/kotlin/Sources/org/json/JSON.kt +44 -0
- package/kotlin/fixtures/counter/Counter.d.kt.ts +1 -0
- package/kotlin/fixtures/counter/Counter.kt +10 -3
- package/kotlin/fixtures/counter/CounterApp.native.tsx +1 -1
- package/kotlin/fixtures/counter/vite.config.ts +2 -2
- package/kotlin/fixtures/headless-counter/Headless.kt +7 -6
- package/kotlin/fixtures/import-animation/Animation.d.kt.ts +7 -0
- package/kotlin/fixtures/import-animation/Animation.kt +80 -0
- package/kotlin/fixtures/import-animation/ImportAnimation.native.tsx +13 -0
- package/kotlin/fixtures/import-animation/README.md +24 -0
- package/kotlin/fixtures/import-animation/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-animation/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-animation/app/routes.d.ts +18 -0
- package/kotlin/fixtures/import-animation/package.json +23 -0
- package/kotlin/fixtures/import-animation/tsconfig.json +20 -0
- package/kotlin/fixtures/import-animation/vite.config.ts +20 -0
- package/kotlin/fixtures/import-editor/Editor.d.kt.ts +7 -0
- package/kotlin/fixtures/import-editor/Editor.kt +59 -0
- package/kotlin/fixtures/import-editor/ImportEditor.native.tsx +23 -0
- package/kotlin/fixtures/import-editor/README.md +27 -0
- package/kotlin/fixtures/import-editor/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-editor/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-editor/package.json +23 -0
- package/kotlin/fixtures/import-editor/tsconfig.json +20 -0
- package/kotlin/fixtures/import-editor/vite.config.ts +20 -0
- package/kotlin/fixtures/import-effects/Effects.d.kt.ts +7 -0
- package/kotlin/fixtures/import-effects/Effects.kt +87 -0
- package/kotlin/fixtures/import-effects/ImportEffects.native.tsx +13 -0
- package/kotlin/fixtures/import-effects/README.md +19 -0
- package/kotlin/fixtures/import-effects/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-effects/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-effects/package.json +23 -0
- package/kotlin/fixtures/import-effects/tsconfig.json +20 -0
- package/kotlin/fixtures/import-effects/vite.config.ts +20 -0
- package/kotlin/fixtures/import-layout/ImportLayout.native.tsx +13 -0
- package/kotlin/fixtures/import-layout/Layout.d.kt.ts +7 -0
- package/kotlin/fixtures/import-layout/Layout.kt +72 -0
- package/kotlin/fixtures/import-layout/README.md +24 -0
- package/kotlin/fixtures/import-layout/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-layout/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-layout/package.json +23 -0
- package/kotlin/fixtures/import-layout/tsconfig.json +20 -0
- package/kotlin/fixtures/import-layout/vite.config.ts +20 -0
- package/kotlin/fixtures/import-navigation/ImportNavigation.native.tsx +18 -0
- package/kotlin/fixtures/import-navigation/Navigation.d.kt.ts +7 -0
- package/kotlin/fixtures/import-navigation/Navigation.kt +104 -0
- package/kotlin/fixtures/import-navigation/README.md +31 -0
- package/kotlin/fixtures/import-navigation/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-navigation/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-navigation/package.json +23 -0
- package/kotlin/fixtures/import-navigation/tsconfig.json +20 -0
- package/kotlin/fixtures/import-navigation/vite.config.ts +20 -0
- package/kotlin/fixtures/import-overlays/ImportOverlays.native.tsx +29 -0
- package/kotlin/fixtures/import-overlays/Overlays.d.kt.ts +7 -0
- package/kotlin/fixtures/import-overlays/Overlays.kt +93 -0
- package/kotlin/fixtures/import-overlays/README.md +34 -0
- package/kotlin/fixtures/import-overlays/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-overlays/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-overlays/package.json +23 -0
- package/kotlin/fixtures/import-overlays/tsconfig.json +20 -0
- package/kotlin/fixtures/import-overlays/vite.config.ts +20 -0
- package/kotlin/fixtures/import-scroll/ImportScroll.native.tsx +13 -0
- package/kotlin/fixtures/import-scroll/README.md +23 -0
- package/kotlin/fixtures/import-scroll/Scroll.d.kt.ts +7 -0
- package/kotlin/fixtures/import-scroll/Scroll.kt +91 -0
- package/kotlin/fixtures/import-scroll/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-scroll/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-scroll/package.json +23 -0
- package/kotlin/fixtures/import-scroll/tsconfig.json +20 -0
- package/kotlin/fixtures/import-scroll/vite.config.ts +20 -0
- package/kotlin/fixtures/import-selection/ImportSelection.native.tsx +44 -0
- package/kotlin/fixtures/import-selection/README.md +32 -0
- package/kotlin/fixtures/import-selection/Selection.d.kt.ts +8 -0
- package/kotlin/fixtures/import-selection/Selection.kt +78 -0
- package/kotlin/fixtures/import-selection/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-selection/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-selection/package.json +23 -0
- package/kotlin/fixtures/import-selection/tsconfig.json +20 -0
- package/kotlin/fixtures/import-selection/vite.config.ts +20 -0
- package/kotlin/fixtures/import-surfaces/ImportSurfaces.native.tsx +13 -0
- package/kotlin/fixtures/import-surfaces/README.md +22 -0
- package/kotlin/fixtures/import-surfaces/Surfaces.d.kt.ts +7 -0
- package/kotlin/fixtures/import-surfaces/Surfaces.kt +64 -0
- package/kotlin/fixtures/import-surfaces/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-surfaces/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-surfaces/package.json +23 -0
- package/kotlin/fixtures/import-surfaces/tsconfig.json +20 -0
- package/kotlin/fixtures/import-surfaces/vite.config.ts +20 -0
- package/kotlin/fixtures/import-values/ImportValues.native.tsx +35 -0
- package/kotlin/fixtures/import-values/README.md +23 -0
- package/kotlin/fixtures/import-values/Values.d.kt.ts +11 -0
- package/kotlin/fixtures/import-values/Values.kt +66 -0
- package/kotlin/fixtures/import-values/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-values/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-values/package.json +23 -0
- package/kotlin/fixtures/import-values/tsconfig.json +20 -0
- package/kotlin/fixtures/import-values/vite.config.ts +20 -0
- package/kotlin/fixtures/kotlin-app-variants/BarBehavior.kt +38 -0
- package/kotlin/fixtures/kotlin-app-variants/BarVisibility.kt +36 -0
- package/kotlin/fixtures/kotlin-app-variants/Ime.kt +3 -1
- package/kotlin/fixtures/kotlin-app-variants/TransientInsets.kt +50 -0
- package/kotlin/fork/NOTICE +6 -1
- package/kotlin/fork/README.md +15 -7
- package/kotlin/fork/build.sh +2 -0
- package/kotlin/fork/compose-worker-globals.patch +186 -4
- package/kotlin/fork/fork.json +2 -2
- package/kotlin/fork/skiko-worker-clock.patch +12 -0
- package/kotlin/toolchain.json +12 -12
- package/kotlin/tools/expo-types.main.kts +115 -0
- package/package.json +17 -23
- package/scripts/dev-server-scanner.ts +92 -66
- package/skills/contrast/SKILL.md +2 -2
- package/skills/peach-debug/SKILL.md +1 -1
- package/skills/peach-perf/SKILL.md +1 -1
- package/skills/peach-setup/SKILL.md +2 -1
- package/skills/peach-test/SKILL.md +8 -0
- package/src/assetCatalogContract.ts +43 -1
- package/src/bridge-contract-input.ts +46 -19
- package/src/bridge-contract.ts +0 -1
- package/src/bundle-channel.mjs +197 -84
- package/src/bundleGlobalFooter.ts +38 -0
- package/src/capture-contract.ts +107 -33
- package/src/cloud-contract.ts +5 -1
- package/src/cloud.ts +5 -2
- package/src/config.ts +22 -3
- package/src/configured-bundle-producer.ts +1 -1
- package/src/desktop-host-delivery.ts +95 -1
- package/src/expo-kotlin-bundle.ts +29 -0
- package/src/expo-kotlin-host.ts +201 -0
- package/src/expo-swift-host.ts +96 -76
- package/src/expoKotlinContract.ts +70 -0
- package/src/expoSwiftContract.ts +4 -25
- package/src/home-paths.ts +7 -4
- package/src/host/bridge-host.ts +23 -3
- package/src/host/fetch-proxy-handler.ts +13 -0
- package/src/host/fetch-proxy-overrides.ts +11 -0
- package/src/host/replacement-module-handler.ts +5 -2
- package/src/index.ts +3 -1
- package/src/kotlin-host.ts +463 -19
- package/src/metro-plugin.ts +56 -28
- package/src/metro-production-bundle.ts +2 -2
- package/src/native-app-identity-project.ts +190 -0
- package/src/native-app-identity.ts +398 -34
- package/src/native-firebase-config.ts +69 -15
- package/src/native-seam-manifest.ts +6 -0
- package/src/one-widget-discovery.ts +2 -1
- package/src/openstep-plist.ts +107 -0
- package/src/react-native-host-modules.ts +4 -0
- package/src/runtime-assets.ts +2 -2
- package/src/sim-client.ts +2 -2
- package/src/swift-binary-modules.ts +3 -1
- package/src/swift-compile.ts +286 -38
- package/src/swift-distribution-contract.ts +4 -0
- package/src/swift-distribution.lock.json +123 -12
- package/src/swift-distribution.ts +7 -3
- package/src/swift-host.ts +298 -83
- package/src/swift-package-manifest.ts +29 -2
- package/src/swift-package.ts +180 -10
- package/src/swift-packages.ts +4 -0
- package/src/swift-standin-emit.ts +4 -1
- package/src/swift-standins.ts +274 -15
- package/src/swift-submit.ts +62 -7
- package/src/swift-toolchain.ts +6 -1
- package/src/swiftContract.ts +126 -3
- package/src/vite-plugin-one.ts +13 -16
- package/src/vite-plugin-swift.ts +4 -5
- package/src/vite-plugin.ts +360 -144
- package/src/vite.d.ts +1 -1
- package/src/worker-system-chunks.ts +221 -0
- package/src/worklet-executable.ts +348 -38
- package/src/worklets-babel.ts +1 -1
- package/src/xcode-project.ts +243 -127
- package/dist-lib/agent-identity.cjs +0 -39
- package/dist-lib/agent-sessions.cjs +0 -760
- package/dist-lib/cli-constants.cjs +0 -32
- package/dist-lib/render-mode.cjs +0 -44
- package/kotlin/AppSources/android/view/View.kt +0 -74
- package/kotlin/AppSources/android/widget/FrameLayout.kt +0 -6
- package/src/render-mode.ts +0 -15
- /package/kotlin/{AppSources → AndroidViewSources}/android/content/Context.kt +0 -0
- /package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Configuration.kt +0 -0
- /package/kotlin/{AppSources → AndroidViewSources}/android/graphics/Color.kt +0 -0
- /package/kotlin/{AppSources → AndroidViewSources}/android/util/DisplayMetrics.kt +0 -0
- /package/kotlin/{AppSources → AndroidViewSources}/dev/peach/app/JavaFormat.kt +0 -0
- /package/kotlin/{AppSources → Sources}/java/lang/Runnable.kt +0 -0
|
@@ -410,7 +410,13 @@ export const DECLARED_OUTBOUND_CALLS: Record<string, OutboundCallDeclaration> =
|
|
|
410
410
|
category: 'local_development',
|
|
411
411
|
count: 1,
|
|
412
412
|
},
|
|
413
|
-
|
|
413
|
+
// a Live Activity or widget surface compiles One's extension from the
|
|
414
|
+
// package URL the app's own dev server advertised in its widget scan.
|
|
415
|
+
'packages/peach-engine/src/ios/one-widget-entry.ts :: fetch :: widget.packageUrl': {
|
|
416
|
+
category: 'local_development',
|
|
417
|
+
count: 1,
|
|
418
|
+
},
|
|
419
|
+
"packages/peachsim/src/one-widget-discovery.ts :: fetch-alias :: new URL('/__server-scan', bundleUrl).href":
|
|
414
420
|
{
|
|
415
421
|
category: 'local_development',
|
|
416
422
|
count: 1,
|
|
@@ -458,9 +464,9 @@ export const DECLARED_OUTBOUND_CALLS: Record<string, OutboundCallDeclaration> =
|
|
|
458
464
|
category: 'guest_app_network',
|
|
459
465
|
count: 2,
|
|
460
466
|
},
|
|
461
|
-
'packages/peach-engine/src/
|
|
467
|
+
'packages/peach-engine/src/bundle-fetch.ts :: fetch :: buildBrowserAssetProxyUrl(devServerUrl)':
|
|
462
468
|
{ category: 'guest_app_network', count: 1 },
|
|
463
|
-
'packages/peach-engine/src/
|
|
469
|
+
'packages/peach-engine/src/bundle-fetch.ts :: fetch :: requestUrl': {
|
|
464
470
|
category: 'guest_app_network',
|
|
465
471
|
count: 1,
|
|
466
472
|
},
|
|
@@ -468,6 +474,23 @@ export const DECLARED_OUTBOUND_CALLS: Record<string, OutboundCallDeclaration> =
|
|
|
468
474
|
category: 'same_origin_runtime',
|
|
469
475
|
count: 1,
|
|
470
476
|
},
|
|
477
|
+
'packages/peach-engine/src/engine/metal-air-compiler.ts :: fetch :: url': {
|
|
478
|
+
category: 'same_origin_runtime',
|
|
479
|
+
count: 1,
|
|
480
|
+
},
|
|
481
|
+
'packages/peach-engine/src/engine/metal-source-compiler.ts :: fetch :: url': {
|
|
482
|
+
category: 'same_origin_runtime',
|
|
483
|
+
count: 1,
|
|
484
|
+
},
|
|
485
|
+
'packages/peach-engine/src/engine/metal-shader-sources.ts :: fetch :: url': {
|
|
486
|
+
category: 'guest_app_network',
|
|
487
|
+
count: 1,
|
|
488
|
+
},
|
|
489
|
+
'packages/peach-engine/src/render-worker/compositor-runtime/metal-effects.ts :: fetch :: uri':
|
|
490
|
+
{
|
|
491
|
+
category: 'guest_app_network',
|
|
492
|
+
count: 1,
|
|
493
|
+
},
|
|
471
494
|
'packages/peach-engine/src-electron/tray.ts :: client.get :: parsed': {
|
|
472
495
|
category: 'guest_app_network',
|
|
473
496
|
count: 1,
|
|
@@ -535,6 +558,16 @@ export const DECLARED_OUTBOUND_CALLS: Record<string, OutboundCallDeclaration> =
|
|
|
535
558
|
},
|
|
536
559
|
'packages/peach-engine/src/render-worker/app-in-worker.tsx :: fetch :: new URL(file, listUrl)':
|
|
537
560
|
{ category: 'same_origin_runtime', count: 1 },
|
|
561
|
+
// the rive runtime's system fallback font, the engine's own SF Pro asset.
|
|
562
|
+
'packages/peach-engine/src/render-worker/rive-host.ts :: fetch :: url': {
|
|
563
|
+
category: 'same_origin_runtime',
|
|
564
|
+
count: 1,
|
|
565
|
+
},
|
|
566
|
+
// CDN assets a guest rive file names, fetched as the rive runtime's CDN loader does.
|
|
567
|
+
'packages/peach-engine/src/render-worker/rive-host.ts :: fetch :: cdnUrl': {
|
|
568
|
+
category: 'guest_app_network',
|
|
569
|
+
count: 1,
|
|
570
|
+
},
|
|
538
571
|
'packages/peach-engine/src/render-worker/host.ts :: fetch :: msg.fallbackUrl': {
|
|
539
572
|
category: 'guest_app_network',
|
|
540
573
|
count: 1,
|
|
@@ -561,10 +594,11 @@ export const DECLARED_OUTBOUND_CALLS: Record<string, OutboundCallDeclaration> =
|
|
|
561
594
|
{ category: 'contrast_user_action', count: 1 },
|
|
562
595
|
'packages/peach-engine/src/screenshots/capture-store.ts :: fetch :: captureApiUrl(ref)':
|
|
563
596
|
{ category: 'contrast_user_action', count: 1 },
|
|
564
|
-
"packages/peach-engine/src/server-discovery.ts :: fetch :: '/__server-scan'":
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
597
|
+
"packages/peach-engine/src/server-discovery.ts :: fetch :: requireSootSimRuntimeLocation().origin + '/__server-scan'":
|
|
598
|
+
{
|
|
599
|
+
category: 'local_development',
|
|
600
|
+
count: 1,
|
|
601
|
+
},
|
|
568
602
|
'packages/peach-engine/src/server-discovery.ts :: fetch :: `${gatewayOrigin}/__scan`': {
|
|
569
603
|
category: 'local_development',
|
|
570
604
|
count: 1,
|
|
@@ -708,7 +742,11 @@ export const DECLARED_OUTBOUND_CALLS: Record<string, OutboundCallDeclaration> =
|
|
|
708
742
|
{ category: 'local_development', count: 1 },
|
|
709
743
|
'packages/peach-engine/src/engine/text-hyphenation-en-us.ts :: xml-http-request :: <none>':
|
|
710
744
|
{ category: 'same_origin_runtime', count: 1 },
|
|
711
|
-
'packages/peach-engine/src/expo-
|
|
745
|
+
'packages/peach-engine/src/expo-kotlin-compilation.ts :: fetch :: address': {
|
|
746
|
+
category: 'local_development',
|
|
747
|
+
count: 1,
|
|
748
|
+
},
|
|
749
|
+
'packages/peach-engine/src/expo-native-modules.tsx :: fetch :: address': {
|
|
712
750
|
category: 'local_development',
|
|
713
751
|
count: 1,
|
|
714
752
|
},
|
package/cli/recording-access.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readSharedDesktopAuthSession } from '../src/auth/shared-session'
|
|
2
2
|
import { authHeaderValue, resolveCliAuth, type CliAuth } from './auth'
|
|
3
3
|
import { resolveDefaultUploadOrigin } from './commands/upload'
|
|
4
|
-
import {
|
|
4
|
+
import { peachExit } from './run-rnx'
|
|
5
5
|
|
|
6
6
|
type BillingSubscriptionSnapshot = {
|
|
7
7
|
plan?: 'free' | 'personal' | 'team'
|
|
@@ -59,7 +59,7 @@ export async function ensureCliRecordingEntitlement(
|
|
|
59
59
|
` • run \`peach login\`\n` +
|
|
60
60
|
` • set PEACH_API_KEY=sk_rnx_... (recommended for CI)\n\n`,
|
|
61
61
|
)
|
|
62
|
-
|
|
62
|
+
peachExit(1)
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
if (auth.kind === 'github' && opts.allowGitHubAuth) return
|
|
@@ -75,7 +75,7 @@ export async function ensureCliRecordingEntitlement(
|
|
|
75
75
|
`\n peach ${commandLabel} couldn't verify recording access.\n` +
|
|
76
76
|
` ${error instanceof Error ? error.message : String(error)}\n\n`,
|
|
77
77
|
)
|
|
78
|
-
|
|
78
|
+
peachExit(1)
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
if (res.status === 401) {
|
|
@@ -83,7 +83,7 @@ export async function ensureCliRecordingEntitlement(
|
|
|
83
83
|
`\n peach ${commandLabel} couldn't verify recording access with the current auth against ${billingOrigin}.\n` +
|
|
84
84
|
` sign in again for that origin, or provide a valid PEACH_API_KEY.\n\n`,
|
|
85
85
|
)
|
|
86
|
-
|
|
86
|
+
peachExit(1)
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
if (!res.ok) {
|
|
@@ -92,7 +92,7 @@ export async function ensureCliRecordingEntitlement(
|
|
|
92
92
|
`\n peach ${commandLabel} couldn't verify recording access (${res.status}).\n` +
|
|
93
93
|
` ${text || 'unexpected billing response'}\n\n`,
|
|
94
94
|
)
|
|
95
|
-
|
|
95
|
+
peachExit(1)
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
const data = (await res.json()) as BillingSubscriptionSnapshot
|
|
@@ -104,5 +104,5 @@ export async function ensureCliRecordingEntitlement(
|
|
|
104
104
|
` current plan: ${plan}.\n` +
|
|
105
105
|
` free keeps basic 3d mode; the trial unlocks the full Personal surface.\n\n`,
|
|
106
106
|
)
|
|
107
|
-
|
|
107
|
+
peachExit(1)
|
|
108
108
|
}
|
package/cli/run-registry.ts
CHANGED
|
@@ -175,7 +175,7 @@ export async function registerRun(args: RegisterRunArgs): Promise<RegisteredRun
|
|
|
175
175
|
// drivers through this choke: fail exactly like a dead endpoint,
|
|
176
176
|
// without touching the network. downstream (warn shape, null return,
|
|
177
177
|
// require-registration exit) is byte-identical to a real failure.
|
|
178
|
-
if (process.env.
|
|
178
|
+
if (process.env.PEACH_INJECT_REGISTRATION_FAILURE === '1') {
|
|
179
179
|
console.warn(' warn: run registration failed: injected failure')
|
|
180
180
|
return null
|
|
181
181
|
}
|
package/cli/runtime-compat.ts
CHANGED
|
@@ -116,7 +116,11 @@ export function readRuntimeCompatibility(runtimeVersion = readActiveRuntime()):
|
|
|
116
116
|
reason: 'runtime compatibility snapshot is invalid or belongs to another runtime',
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
|
-
return {
|
|
119
|
+
return {
|
|
120
|
+
runtimeVersion,
|
|
121
|
+
data: snapshot.data,
|
|
122
|
+
reason: null,
|
|
123
|
+
}
|
|
120
124
|
} catch {
|
|
121
125
|
return {
|
|
122
126
|
runtimeVersion,
|
package/cli/send-to-box.ts
CHANGED
|
@@ -11,12 +11,12 @@ import {
|
|
|
11
11
|
getRuntimePlatform,
|
|
12
12
|
listDeviceModels,
|
|
13
13
|
} from '../../peach-engine/src/settings/devices.ts'
|
|
14
|
-
import {
|
|
14
|
+
import { isRecord } from '../src/is-record'
|
|
15
|
+
import { toPeachProductionBundleUrl } from '../src/metro-production-bundle.ts'
|
|
15
16
|
import { createCloudBox } from './cloud-client.ts'
|
|
16
17
|
import type { StorageSnapshot } from '../../peach-engine/src/preview/storage-snapshot-contract.ts'
|
|
17
18
|
import type { DeviceModel } from '../../peach-engine/src/settings/devices.ts'
|
|
18
19
|
import type { BridgeCommandType } from '../src/bridge-contract.ts'
|
|
19
|
-
import { isRecord } from '../src/is-record'
|
|
20
20
|
|
|
21
21
|
export interface SendToBoxOptions {
|
|
22
22
|
/** runs one bridge command against the sim running the app. */
|
|
@@ -79,7 +79,7 @@ export async function sendToBox(options: SendToBoxOptions): Promise<SendToBoxRes
|
|
|
79
79
|
}
|
|
80
80
|
const storage: StorageSnapshot = dumped
|
|
81
81
|
const created = await createCloudBox({
|
|
82
|
-
bundlePath:
|
|
82
|
+
bundlePath: toPeachProductionBundleUrl(bundleUrl),
|
|
83
83
|
device:
|
|
84
84
|
options.device ??
|
|
85
85
|
cloudDevice(isRecord(captured.deviceSpec) ? captured.deviceSpec.model : null),
|
package/cli/shell-init.ts
CHANGED
|
@@ -52,7 +52,8 @@ export function renderRnxShellInit(shell: string): string {
|
|
|
52
52
|
;;
|
|
53
53
|
ios)
|
|
54
54
|
for _peach_shell_session in "$@"; do
|
|
55
|
-
if [ "$_peach_shell_session" = '--remote' ]
|
|
55
|
+
if [ "$_peach_shell_session" = '--remote' ] ||
|
|
56
|
+
[ "$_peach_shell_session" = '--nano' ]; then
|
|
56
57
|
_peach_shell_create=1
|
|
57
58
|
break
|
|
58
59
|
fi
|
package/cli/ws-bridge.ts
CHANGED
|
@@ -114,11 +114,11 @@ function resolveDefaultDevBridgeLockfile(): DevBridgeLockfile | null {
|
|
|
114
114
|
if (lockfiles.length === 0) return null
|
|
115
115
|
|
|
116
116
|
if (
|
|
117
|
-
process.env.
|
|
117
|
+
process.env.PEACH_BRIDGE_PORT !== undefined ||
|
|
118
118
|
process.env.PORT_OFFSET !== undefined
|
|
119
119
|
) {
|
|
120
120
|
const requestedPort = resolveSootsimBridgePort({
|
|
121
|
-
explicitPort: process.env.
|
|
121
|
+
explicitPort: process.env.PEACH_BRIDGE_PORT,
|
|
122
122
|
portOffset: process.env.PORT_OFFSET,
|
|
123
123
|
})
|
|
124
124
|
return lockfiles.find((lockfile) => lockfile.bridgePort === requestedPort) ?? null
|
|
@@ -175,11 +175,11 @@ function resolveBridgeWorldFresh(): BridgeWorld {
|
|
|
175
175
|
}
|
|
176
176
|
const lock = readDaemonLockfile()
|
|
177
177
|
const requestedPort = resolveSootsimBridgePort({
|
|
178
|
-
explicitPort: process.env.
|
|
178
|
+
explicitPort: process.env.PEACH_BRIDGE_PORT,
|
|
179
179
|
portOffset: process.env.PORT_OFFSET,
|
|
180
180
|
})
|
|
181
181
|
const explicitWorld =
|
|
182
|
-
process.env.
|
|
182
|
+
process.env.PEACH_BRIDGE_PORT !== undefined || process.env.PORT_OFFSET !== undefined
|
|
183
183
|
if (
|
|
184
184
|
lock &&
|
|
185
185
|
isDaemonLockfileFresh(lock) &&
|
|
@@ -680,7 +680,11 @@ export function createBridge(wsPort: number, opts: WsBridgeOptions = {}): WsBrid
|
|
|
680
680
|
// used by scripts that prefer clean stdout.
|
|
681
681
|
function maybeNoticeTarget(cmdType: string, simId: string | undefined) {
|
|
682
682
|
if (noticedTarget) return
|
|
683
|
-
if (
|
|
683
|
+
if (
|
|
684
|
+
process.env.PEACH_QUIET_TARGET_NOTICE === '1' ||
|
|
685
|
+
process.env.SOOTSIM_QUIET_TARGET_NOTICE === '1'
|
|
686
|
+
)
|
|
687
|
+
return
|
|
684
688
|
if (cmdType.startsWith('bridge:') || cmdType === 'focus' || cmdType === 'close')
|
|
685
689
|
return
|
|
686
690
|
noticedTarget = true
|
package/detox/element-types.ts
CHANGED
package/detox/gestures.ts
CHANGED
|
@@ -339,9 +339,9 @@ export async function dragScrollNode(
|
|
|
339
339
|
let recognitionSootSimY = startSootSimY
|
|
340
340
|
let endSootSimX = startSootSimX
|
|
341
341
|
let endSootSimY = startSootSimY
|
|
342
|
-
//
|
|
343
|
-
// the
|
|
344
|
-
const slop =
|
|
342
|
+
// recognition consumes only axis slop. compensate that distance once so
|
|
343
|
+
// excess travel on the first move remains part of the requested scroll.
|
|
344
|
+
const slop = scrollTouchSlop(DETOX_PLATFORM, 1)
|
|
345
345
|
const travel = pixels + slop
|
|
346
346
|
|
|
347
347
|
switch (direction) {
|
package/detox/index.ts
CHANGED
|
@@ -62,8 +62,8 @@ export type { SootSimElement } from './element-types'
|
|
|
62
62
|
declare global {
|
|
63
63
|
interface Window {
|
|
64
64
|
// installed by takeScreenshotStagesFast; each input action calls it with
|
|
65
|
-
// its capture token
|
|
66
|
-
// only that capture's stages anchor at
|
|
65
|
+
// its capture token immediately before invoking the input bridge so
|
|
66
|
+
// only that capture's stages anchor at dispatch, before input completes.
|
|
67
67
|
__sootsimAnchorTimedInput?: (token: string) => void
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -71,7 +71,7 @@ declare global {
|
|
|
71
71
|
const BASE_URL = process.env.PEACH_URL || 'http://localhost:5173'
|
|
72
72
|
const SCREENSHOT_DIR =
|
|
73
73
|
process.env.PEACH_SCREENSHOT_DIR ||
|
|
74
|
-
path.join(process.cwd(), 'test', 'detox-driver', 'screenshots')
|
|
74
|
+
path.join(process.cwd(), 'test', 'detox-driver', 'screenshots', String(process.pid))
|
|
75
75
|
|
|
76
76
|
// shared state -- playwright page and browser
|
|
77
77
|
let _browser: Browser | null = null
|
|
@@ -560,7 +560,10 @@ export async function waitForSootsimIdle(
|
|
|
560
560
|
layoutDirty = stats?.layoutDirty === true && stats?.renderRequested === true
|
|
561
561
|
} catch {}
|
|
562
562
|
}
|
|
563
|
+
let webViewStarting = false
|
|
563
564
|
if (root) {
|
|
565
|
+
const PREVIEW_PROGRESS_REGEX =
|
|
566
|
+
/^(creating webview|loading html|fetching bundle|waiting for first render|starting preview|loading simulator|fetching app code|waiting for native preview|starting design|loading canvas|fetching screens|painting the canvas|waiting for webview|waiting for preview|waiting for canvas|preview stalled)/i
|
|
564
567
|
const walk = (node: any) => {
|
|
565
568
|
if (node.layout && node.layout.width > 0) {
|
|
566
569
|
layout.push(
|
|
@@ -570,16 +573,39 @@ export async function waitForSootsimIdle(
|
|
|
570
573
|
Math.round(node.layout.height),
|
|
571
574
|
)
|
|
572
575
|
}
|
|
576
|
+
const tid = node.testID || node.props?.testID || node.props?.testId
|
|
577
|
+
if (
|
|
578
|
+
typeof tid === 'string' &&
|
|
579
|
+
(tid === 'web-preview-progress' || tid.endsWith('-preview-progress'))
|
|
580
|
+
) {
|
|
581
|
+
webViewStarting = true
|
|
582
|
+
}
|
|
583
|
+
const text =
|
|
584
|
+
node.textContent ||
|
|
585
|
+
(typeof node.props?.children === 'string' ? node.props.children : '')
|
|
586
|
+
if (typeof text === 'string' && PREVIEW_PROGRESS_REGEX.test(text.trim())) {
|
|
587
|
+
webViewStarting = true
|
|
588
|
+
}
|
|
573
589
|
for (const child of node.children || []) walk(child)
|
|
574
590
|
}
|
|
575
591
|
walk(root)
|
|
576
592
|
}
|
|
593
|
+
if (!webViewStarting && typeof document !== 'undefined') {
|
|
594
|
+
if (
|
|
595
|
+
document.querySelector(
|
|
596
|
+
'[data-testid$="-preview-progress"], [data-testid="web-preview-progress"], [data-testid="ios-preview-progress"], [data-testid="design-preview-progress"], [data-sootsim-webview-loading="true"], [data-sootsim-webview-mode="placeholder"]',
|
|
597
|
+
)
|
|
598
|
+
) {
|
|
599
|
+
webViewStarting = true
|
|
600
|
+
}
|
|
601
|
+
}
|
|
577
602
|
return {
|
|
578
603
|
animating,
|
|
579
604
|
auxSurfaceDebug,
|
|
580
605
|
layout,
|
|
581
606
|
layoutDirty,
|
|
582
607
|
renderStatsAvailable,
|
|
608
|
+
webViewStarting,
|
|
583
609
|
}
|
|
584
610
|
}
|
|
585
611
|
|
|
@@ -593,6 +619,7 @@ export async function waitForSootsimIdle(
|
|
|
593
619
|
(!strict || snapshot.renderStatsAvailable) &&
|
|
594
620
|
!snapshot.animating &&
|
|
595
621
|
!snapshot.layoutDirty &&
|
|
622
|
+
!snapshot.webViewStarting &&
|
|
596
623
|
isLayoutStable(stableLayout, snapshot.layout)
|
|
597
624
|
) {
|
|
598
625
|
stable++
|
|
@@ -613,7 +640,7 @@ export async function waitForSootsimIdle(
|
|
|
613
640
|
: !lastSnapshot
|
|
614
641
|
? 'deadline spent before the first idle poll'
|
|
615
642
|
: strict
|
|
616
|
-
? `strict idle state unavailable: renderStats=${lastSnapshot?.renderStatsAvailable === true} animating=${lastSnapshot?.animating === true} layoutDirty=${lastSnapshot?.layoutDirty === true} layoutNodes=${(lastSnapshot?.layout.length ?? 0) / 4} aux=${JSON.stringify(lastSnapshot?.auxSurfaceDebug)}`
|
|
643
|
+
? `strict idle state unavailable: renderStats=${lastSnapshot?.renderStatsAvailable === true} animating=${lastSnapshot?.animating === true} layoutDirty=${lastSnapshot?.layoutDirty === true} webViewStarting=${lastSnapshot?.webViewStarting === true} layoutNodes=${(lastSnapshot?.layout.length ?? 0) / 4} aux=${JSON.stringify(lastSnapshot?.auxSurfaceDebug)}`
|
|
617
644
|
: 'layout fallback',
|
|
618
645
|
}
|
|
619
646
|
},
|
|
@@ -761,9 +788,9 @@ async function dispatchTapAtSootsimPoint(
|
|
|
761
788
|
async ({ x, y, token }) => {
|
|
762
789
|
const interactTap = window.SootSim?.bridges?.interact?.tap
|
|
763
790
|
if (typeof interactTap === 'function') {
|
|
791
|
+
if (token) window.__sootsimAnchorTimedInput?.(token)
|
|
764
792
|
const result = await interactTap(x, y)
|
|
765
793
|
if (result && (typeof result !== 'object' || result.hit !== false)) {
|
|
766
|
-
if (token) window.__sootsimAnchorTimedInput?.(token)
|
|
767
794
|
return
|
|
768
795
|
}
|
|
769
796
|
}
|
|
@@ -771,8 +798,8 @@ async function dispatchTapAtSootsimPoint(
|
|
|
771
798
|
if (typeof tap !== 'function') {
|
|
772
799
|
throw new Error('sootsim tap bridge is not installed')
|
|
773
800
|
}
|
|
774
|
-
await tap(x, y)
|
|
775
801
|
if (token) window.__sootsimAnchorTimedInput?.(token)
|
|
802
|
+
await tap(x, y)
|
|
776
803
|
},
|
|
777
804
|
{ x, y, token },
|
|
778
805
|
)
|
|
@@ -1171,8 +1198,8 @@ function createSootSimElement(matcher: Matcher): SootSimElement {
|
|
|
1171
1198
|
if (typeof longPress !== 'function') {
|
|
1172
1199
|
throw new Error('sootsim longPress bridge is not installed')
|
|
1173
1200
|
}
|
|
1174
|
-
await longPress(x, y, duration)
|
|
1175
1201
|
if (token) window.__sootsimAnchorTimedInput?.(token)
|
|
1202
|
+
await longPress(x, y, duration)
|
|
1176
1203
|
},
|
|
1177
1204
|
{ duration, x: target.x, y: target.y, token: captureToken },
|
|
1178
1205
|
)
|
|
@@ -1254,6 +1281,12 @@ function createSootSimElement(matcher: Matcher): SootSimElement {
|
|
|
1254
1281
|
await page.keyboard.type(text)
|
|
1255
1282
|
},
|
|
1256
1283
|
|
|
1284
|
+
async tapReturnKey() {
|
|
1285
|
+
const page = getPage()
|
|
1286
|
+
await focusElementForTextEntry(el)
|
|
1287
|
+
await page.keyboard.press('Enter')
|
|
1288
|
+
},
|
|
1289
|
+
|
|
1257
1290
|
async replaceText(text: string) {
|
|
1258
1291
|
const page = getPage()
|
|
1259
1292
|
const node = await findNodeByMatcher(matcher)
|
|
@@ -1449,8 +1482,8 @@ function createSootSimElement(matcher: Matcher): SootSimElement {
|
|
|
1449
1482
|
if (typeof drag !== 'function') {
|
|
1450
1483
|
throw new Error('sootsim interact bridge is not installed')
|
|
1451
1484
|
}
|
|
1452
|
-
await drag(fromX, fromY, toX, toY, steps, stepMs)
|
|
1453
1485
|
if (token) window.__sootsimAnchorTimedInput?.(token)
|
|
1486
|
+
await drag(fromX, fromY, toX, toY, steps, stepMs)
|
|
1454
1487
|
},
|
|
1455
1488
|
{
|
|
1456
1489
|
fromX: startSootSimX,
|
|
@@ -2168,8 +2201,10 @@ export const device = {
|
|
|
2168
2201
|
|
|
2169
2202
|
// park every render clock before the interaction, detect the first changed
|
|
2170
2203
|
// stepped frame inside the named component, then advance exact 60fps frames
|
|
2171
|
-
// to each requested offset. native extraction
|
|
2172
|
-
//
|
|
2204
|
+
// to each requested offset from that frame. native extraction anchors at
|
|
2205
|
+
// its detection frame's pts, so both legs zero at the first painted change
|
|
2206
|
+
// and native also chooses the first frame at or after an offset, which is
|
|
2207
|
+
// the same rounding convention from the same zero.
|
|
2173
2208
|
async takeScreenshotStagesFromVisibleChangeFast(
|
|
2174
2209
|
namePrefix: string,
|
|
2175
2210
|
stages: Array<{
|
|
@@ -2473,9 +2508,8 @@ export const device = {
|
|
|
2473
2508
|
controller.initialFrame.virtualTimestampMs + input.hold.durationMs,
|
|
2474
2509
|
)
|
|
2475
2510
|
}
|
|
2476
|
-
// an anchor is
|
|
2477
|
-
//
|
|
2478
|
-
// capture the anchor frame itself.
|
|
2511
|
+
// an anchor is its visible-change frame; its bitmap is kept so a 0ms
|
|
2512
|
+
// stage can still capture the anchor frame itself.
|
|
2479
2513
|
const keptFrames = new Map<number, ImageBitmap>()
|
|
2480
2514
|
try {
|
|
2481
2515
|
const baselineBitmap = await captureBitmap()
|
|
@@ -2503,7 +2537,6 @@ export const device = {
|
|
|
2503
2537
|
|
|
2504
2538
|
let visibleStart: FrameReceipt | null = null
|
|
2505
2539
|
let detectedMeasurement: MotionChangeMeasurement | null = null
|
|
2506
|
-
let previousReceipt: FrameReceipt | null = null
|
|
2507
2540
|
let previousBitmap: ImageBitmap | null = null
|
|
2508
2541
|
// android can publish mount layout at p=0 before a clock step.
|
|
2509
2542
|
if (input.platform === 'android') {
|
|
@@ -2541,30 +2574,27 @@ export const device = {
|
|
|
2541
2574
|
width: bounds.width,
|
|
2542
2575
|
})
|
|
2543
2576
|
if (measurement.passedMinimum) {
|
|
2544
|
-
|
|
2577
|
+
previousBitmap?.close()
|
|
2578
|
+
previousBitmap = null
|
|
2545
2579
|
visibleStart = receipt
|
|
2546
2580
|
detectedMeasurement = measurement
|
|
2581
|
+
keptFrames.set(receipt.frameIndex, candidateBitmap)
|
|
2547
2582
|
break
|
|
2548
2583
|
}
|
|
2549
2584
|
previousBitmap?.close()
|
|
2550
2585
|
previousBitmap = candidateBitmap
|
|
2551
|
-
previousReceipt = receipt
|
|
2552
|
-
}
|
|
2553
|
-
if (previousReceipt && previousBitmap) {
|
|
2554
|
-
keptFrames.set(previousReceipt.frameIndex, previousBitmap)
|
|
2555
2586
|
}
|
|
2556
2587
|
if (!visibleStart || !detectedMeasurement) {
|
|
2588
|
+
previousBitmap?.close()
|
|
2557
2589
|
throw new Error(
|
|
2558
2590
|
`peach motion had no visible change before ${input.detectionTimeoutMs}ms`,
|
|
2559
2591
|
)
|
|
2560
2592
|
}
|
|
2561
|
-
//
|
|
2562
|
-
//
|
|
2563
|
-
//
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
? visibleStart
|
|
2567
|
-
: (previousReceipt ?? visibleStart)
|
|
2593
|
+
// stages on every platform measure from the first frame that
|
|
2594
|
+
// differs from baseline: native extraction anchors at its
|
|
2595
|
+
// detection frame's pts, so the drive starts here too. the
|
|
2596
|
+
// preceding tick is still baseline on both legs.
|
|
2597
|
+
const driveStart = visibleStart
|
|
2568
2598
|
let currentReceipt = visibleStart
|
|
2569
2599
|
const resolvedAnchors = new Map<string, FrameReceipt>()
|
|
2570
2600
|
const anchorRecords: Array<{
|
|
@@ -2575,9 +2605,8 @@ export const device = {
|
|
|
2575
2605
|
virtualTimestampMs: number
|
|
2576
2606
|
}> = []
|
|
2577
2607
|
// a second drive (the pop after a swipe's pan) re-detects from the
|
|
2578
|
-
// search start: the
|
|
2579
|
-
//
|
|
2580
|
-
// first consecutive pair past the gate, mirroring the drive rule.
|
|
2608
|
+
// search start: the new drive is the passing frame itself, the
|
|
2609
|
+
// frame native reports as the onset atSec, mirroring the drive rule.
|
|
2581
2610
|
const resolveAnchor = async (stage: {
|
|
2582
2611
|
label: string
|
|
2583
2612
|
anchor?: { id: string; notBeforeMs: number; onsetThresholdPercent?: number }
|
|
@@ -2647,14 +2676,14 @@ export const device = {
|
|
|
2647
2676
|
} else {
|
|
2648
2677
|
latePeakPercent = Math.max(latePeakPercent, measurement.changePercent)
|
|
2649
2678
|
}
|
|
2650
|
-
|
|
2651
|
-
candidateBitmap.close()
|
|
2652
|
-
onsetMeasurement = measurement
|
|
2653
|
-
break
|
|
2654
|
-
}
|
|
2679
|
+
const passed = measurement.passedMinimum
|
|
2655
2680
|
anchorBitmap.close()
|
|
2656
2681
|
anchorBitmap = candidateBitmap
|
|
2657
2682
|
anchorReceipt = receipt
|
|
2683
|
+
if (passed) {
|
|
2684
|
+
onsetMeasurement = measurement
|
|
2685
|
+
break
|
|
2686
|
+
}
|
|
2658
2687
|
}
|
|
2659
2688
|
if (!onsetMeasurement) {
|
|
2660
2689
|
anchorBitmap.close()
|
|
@@ -3230,7 +3259,7 @@ export const device = {
|
|
|
3230
3259
|
const simId = await page.evaluate(() => window.SootSim?.state.simId)
|
|
3231
3260
|
if (!simId) throw new Error('peach location requires a registered harness sim')
|
|
3232
3261
|
const port = resolveSootsimBridgePortForHttpPort({
|
|
3233
|
-
explicitPort: process.env.
|
|
3262
|
+
explicitPort: process.env.PEACH_BRIDGE_PORT,
|
|
3234
3263
|
httpPort: new URL(page.url()).port,
|
|
3235
3264
|
baseHttpPort: 5173,
|
|
3236
3265
|
})
|
|
@@ -3320,9 +3349,9 @@ export const device = {
|
|
|
3320
3349
|
async ({ x: tx, y: ty, token }) => {
|
|
3321
3350
|
const interactTap = window.SootSim?.bridges?.interact?.tap
|
|
3322
3351
|
if (typeof interactTap === 'function') {
|
|
3352
|
+
if (token) window.__sootsimAnchorTimedInput?.(token)
|
|
3323
3353
|
const result = await interactTap(tx, ty)
|
|
3324
3354
|
if (result && (typeof result !== 'object' || result.hit !== false)) {
|
|
3325
|
-
if (token) window.__sootsimAnchorTimedInput?.(token)
|
|
3326
3355
|
return
|
|
3327
3356
|
}
|
|
3328
3357
|
}
|
|
@@ -3330,8 +3359,8 @@ export const device = {
|
|
|
3330
3359
|
if (typeof tap !== 'function') {
|
|
3331
3360
|
throw new Error('sootsim tap bridge is not installed')
|
|
3332
3361
|
}
|
|
3333
|
-
await tap(tx, ty)
|
|
3334
3362
|
if (token) window.__sootsimAnchorTimedInput?.(token)
|
|
3363
|
+
await tap(tx, ty)
|
|
3335
3364
|
},
|
|
3336
3365
|
{ x, y, token: captureToken },
|
|
3337
3366
|
)
|
|
@@ -3353,11 +3382,11 @@ export const device = {
|
|
|
3353
3382
|
if (typeof longPress !== 'function') {
|
|
3354
3383
|
throw new Error('sootsim longPress bridge is not installed')
|
|
3355
3384
|
}
|
|
3385
|
+
if (token) window.__sootsimAnchorTimedInput?.(token)
|
|
3356
3386
|
const hit = await longPress(px, py, ms)
|
|
3357
3387
|
if (!hit) {
|
|
3358
3388
|
throw new Error(`sootsim longPress missed at ${px},${py}`)
|
|
3359
3389
|
}
|
|
3360
|
-
if (token) window.__sootsimAnchorTimedInput?.(token)
|
|
3361
3390
|
},
|
|
3362
3391
|
{ x, y, ms: durationMs, token: captureToken },
|
|
3363
3392
|
)
|
|
@@ -91,12 +91,15 @@ function recordPageDiagnostic(page: Page, diagnostic: PageDiagnostic, persist =
|
|
|
91
91
|
if (persist) writeAttemptEvent(diagnostic)
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
function isTopLevelDocumentRequest(page: Page, request: Request) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
94
|
+
export function isTopLevelDocumentRequest(page: Page, request: Request) {
|
|
95
|
+
if (!request.isNavigationRequest() || request.resourceType() !== 'document') {
|
|
96
|
+
return false
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
return request.frame() === page.mainFrame()
|
|
100
|
+
} catch {
|
|
101
|
+
return false
|
|
102
|
+
}
|
|
100
103
|
}
|
|
101
104
|
|
|
102
105
|
function recordNavigationMilestoneFor(
|
package/detox/proof-frame.cjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const { abs, max } = Math
|
|
2
|
+
|
|
1
3
|
// proof captures reserve the top and bottom of a device frame for platform
|
|
2
4
|
// chrome. those pixels can be fully opaque while the app surface is blank or
|
|
3
5
|
// still fading in, so evidence density is measured only in the content band.
|
|
@@ -71,10 +73,10 @@ function measureProofFrameContent(input) {
|
|
|
71
73
|
for (let x = 0; x < width; x++) {
|
|
72
74
|
const offset = (y * width + x) * 4
|
|
73
75
|
if (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
max(
|
|
77
|
+
abs(data[offset] - dominant.red),
|
|
78
|
+
abs(data[offset + 1] - dominant.green),
|
|
79
|
+
abs(data[offset + 2] - dominant.blue),
|
|
78
80
|
) >= PROOF_CONTENT_DEFINITION.channelThreshold
|
|
79
81
|
) {
|
|
80
82
|
contentPixels++
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*!
|
|
1
|
+
/*! peach v0.1.1399 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*!
|
|
1
|
+
/*! peach v0.1.1399 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*!
|
|
1
|
+
/*! peach v0.1.1399 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*!
|
|
1
|
+
/*! peach v0.1.1399 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*!
|
|
1
|
+
/*! peach v0.1.1399 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/beta.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*!
|
|
1
|
+
/*! peach v0.1.1399 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/beta.mjs
CHANGED