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
package/cli/commands/control.ts
CHANGED
|
@@ -6,6 +6,8 @@ import path from 'node:path'
|
|
|
6
6
|
import { encodeAppCatalogWire } from 'peach-engine/engine/app-catalog-wire'
|
|
7
7
|
import {
|
|
8
8
|
devices,
|
|
9
|
+
getRuntimePlatform,
|
|
10
|
+
isDeviceModel,
|
|
9
11
|
listSelectableDeviceModels,
|
|
10
12
|
resolveDeviceFitBox,
|
|
11
13
|
type DeviceModel,
|
|
@@ -13,12 +15,13 @@ import {
|
|
|
13
15
|
import { WebSocket } from 'ws'
|
|
14
16
|
import { probePort } from '../../scripts/dev-server-scanner'
|
|
15
17
|
import { isAppDeepLinkTarget, openAppUrl } from '../../src/app-url'
|
|
16
|
-
import { isLoopbackHost } from '../../src/backend-origin'
|
|
18
|
+
import { isLoopbackHost, loopbackOriginOf } from '../../src/backend-origin'
|
|
17
19
|
import { resolveSootsimShellBaseUrlForBridgePort } from '../../src/bridge-constants'
|
|
18
20
|
import {
|
|
19
21
|
applyPeachConfigToUrl,
|
|
20
22
|
mergePeachConfig,
|
|
21
23
|
PEACH_CONFIG_QUERY_PARAM,
|
|
24
|
+
readPeachConfigFromSearchParams,
|
|
22
25
|
type PeachConfig,
|
|
23
26
|
} from '../../src/config'
|
|
24
27
|
import {
|
|
@@ -80,7 +83,7 @@ import {
|
|
|
80
83
|
import { getDriver } from '../drivers/registry'
|
|
81
84
|
import { isTeamMachineSession, openUrl as openUrlInBrowser } from '../open-url'
|
|
82
85
|
import { diagnosticsAllowedForCurrentProcess } from '../privacy'
|
|
83
|
-
import { rethrowIfExit,
|
|
86
|
+
import { rethrowIfExit, peachExit } from '../run-rnx'
|
|
84
87
|
import { collectRuntimeDiagnostics } from '../runtime-diagnostics'
|
|
85
88
|
import { rnxSelfInvocation } from '../self-invocation'
|
|
86
89
|
import {
|
|
@@ -95,6 +98,7 @@ import {
|
|
|
95
98
|
worldForBridgePort,
|
|
96
99
|
type BridgeSimInfo,
|
|
97
100
|
} from '../ws-bridge'
|
|
101
|
+
import { readNativeProjectRenderer } from './detect'
|
|
98
102
|
import { inspectDescribe, inspectReadySnapshot, waitReadyReason } from './inspect/core'
|
|
99
103
|
import { isAgentEnv } from './inspect/env'
|
|
100
104
|
import { hasInstalledPeachSkills } from './skills'
|
|
@@ -425,14 +429,14 @@ function looksLikeSootsimUrl(target: string): boolean {
|
|
|
425
429
|
url.pathname.includes(PEACH_SIMULATOR_SHELL_FILE) ||
|
|
426
430
|
isPeachSimulatorDocumentPath(pathname) ||
|
|
427
431
|
pathname === '/sootsim' ||
|
|
428
|
-
url.pathname === '/
|
|
429
|
-
url.pathname === '/
|
|
432
|
+
url.pathname === '/__peachsim' ||
|
|
433
|
+
url.pathname === '/__peachsim/' ||
|
|
430
434
|
pathname === '/rn' ||
|
|
431
435
|
/^\/rn\/[^/]+$/i.test(pathname) ||
|
|
432
436
|
/^\/app\/[^/]+$/i.test(pathname) ||
|
|
433
|
-
pathname === '/
|
|
434
|
-
/^\/
|
|
435
|
-
/^\/
|
|
437
|
+
pathname === '/__peachsim/rn' ||
|
|
438
|
+
/^\/__peachsim\/rn\/[^/]+$/i.test(pathname) ||
|
|
439
|
+
/^\/__peachsim\/app\/[^/]+$/i.test(pathname)
|
|
436
440
|
)
|
|
437
441
|
} catch {
|
|
438
442
|
return false
|
|
@@ -448,9 +452,9 @@ function looksLikeShellPathTarget(target: string): boolean {
|
|
|
448
452
|
pathname === '/rn' ||
|
|
449
453
|
/^\/rn\/[^/]+$/i.test(pathname) ||
|
|
450
454
|
/^\/app\/[^/]+$/i.test(pathname) ||
|
|
451
|
-
pathname === '/
|
|
452
|
-
/^\/
|
|
453
|
-
/^\/
|
|
455
|
+
pathname === '/__peachsim/rn' ||
|
|
456
|
+
/^\/__peachsim\/rn\/[^/]+$/i.test(pathname) ||
|
|
457
|
+
/^\/__peachsim\/app\/[^/]+$/i.test(pathname)
|
|
454
458
|
)
|
|
455
459
|
} catch {
|
|
456
460
|
return false
|
|
@@ -461,8 +465,8 @@ function buildShellPathOpenUrl(target: string, baseUrl: string): string {
|
|
|
461
465
|
const targetUrl = new URL(target, 'http://sootsim.local')
|
|
462
466
|
const url = new URL(baseUrl)
|
|
463
467
|
const prefix = getShellRoutePrefix(url.pathname)
|
|
464
|
-
const routePath = targetUrl.pathname.startsWith('/
|
|
465
|
-
? targetUrl.pathname.slice('/
|
|
468
|
+
const routePath = targetUrl.pathname.startsWith('/__peachsim/')
|
|
469
|
+
? targetUrl.pathname.slice('/__peachsim'.length)
|
|
466
470
|
: targetUrl.pathname
|
|
467
471
|
|
|
468
472
|
url.pathname = `${prefix}${routePath}`
|
|
@@ -558,8 +562,8 @@ async function resolveConnectionInputForCli(target: string): Promise<ResolvedDev
|
|
|
558
562
|
|
|
559
563
|
function getShellRoutePrefix(pathname: string): string {
|
|
560
564
|
const normalized = pathname.replace(/\/+$/, '') || '/'
|
|
561
|
-
if (normalized === '/
|
|
562
|
-
return '/
|
|
565
|
+
if (normalized === '/__peachsim' || normalized.startsWith('/__peachsim/')) {
|
|
566
|
+
return '/__peachsim'
|
|
563
567
|
}
|
|
564
568
|
return ''
|
|
565
569
|
}
|
|
@@ -636,18 +640,18 @@ function parseOpenRuntimeConfig(args: string[]): PeachConfig | undefined {
|
|
|
636
640
|
const raw = args[i + 1]
|
|
637
641
|
if (!raw) {
|
|
638
642
|
console.error(' peach open: --replace expects <module>=<file>')
|
|
639
|
-
|
|
643
|
+
peachExit(1)
|
|
640
644
|
}
|
|
641
645
|
const eqIndex = raw.indexOf('=')
|
|
642
646
|
if (eqIndex <= 0 || eqIndex === raw.length - 1) {
|
|
643
647
|
console.error(' peach open: --replace expects <module>=<file>')
|
|
644
|
-
|
|
648
|
+
peachExit(1)
|
|
645
649
|
}
|
|
646
650
|
const moduleName = raw.slice(0, eqIndex).trim()
|
|
647
651
|
const filePath = normalizeReplacementPath(raw.slice(eqIndex + 1).trim())
|
|
648
652
|
if (!fs.existsSync(filePath)) {
|
|
649
653
|
console.error(` peach open: replacement file not found: ${filePath}`)
|
|
650
|
-
|
|
654
|
+
peachExit(1)
|
|
651
655
|
}
|
|
652
656
|
modules[moduleName] = { file: filePath }
|
|
653
657
|
i++
|
|
@@ -661,7 +665,7 @@ function parseOpenRuntimeConfig(args: string[]): PeachConfig | undefined {
|
|
|
661
665
|
const eqIndex = raw ? raw.indexOf('=') : -1
|
|
662
666
|
if (!raw || eqIndex <= 0 || eqIndex === raw.length - 1) {
|
|
663
667
|
console.error(' peach open: --remap expects <host:port>=<host:port>')
|
|
664
|
-
|
|
668
|
+
peachExit(1)
|
|
665
669
|
}
|
|
666
670
|
remap[raw.slice(0, eqIndex).trim()] = raw.slice(eqIndex + 1).trim()
|
|
667
671
|
i++
|
|
@@ -876,14 +880,15 @@ async function stampAppSplash(
|
|
|
876
880
|
}
|
|
877
881
|
|
|
878
882
|
// stamp the engine page url with `?appCatalog=` so an app's asset-catalog
|
|
879
|
-
// colors and its declared accent reach the tenant, which applies
|
|
880
|
-
// bundle this url opens. the catalog lives in the native binary,
|
|
881
|
-
// the js bundle, so only the app's ios project on disk has it.
|
|
883
|
+
// colors and images and its declared accent reach the tenant, which applies
|
|
884
|
+
// them to the bundle this url opens. the catalog lives in the native binary,
|
|
885
|
+
// never in the js bundle, so only the app's ios project on disk has it.
|
|
882
886
|
function stampAppCatalog(urlStr: string, project?: ResolvedAppProject | null): string {
|
|
883
887
|
try {
|
|
884
888
|
const url = new URL(urlStr)
|
|
885
|
-
|
|
886
|
-
|
|
889
|
+
const metroOrigin = loopbackOriginOf(url.searchParams.get('bundle') ?? '')
|
|
890
|
+
if (!metroOrigin || !project) return urlStr
|
|
891
|
+
const catalog = discoverAppCatalog(project.appDir, metroOrigin)
|
|
887
892
|
if (!catalog) return urlStr
|
|
888
893
|
url.searchParams.set('appCatalog', encodeAppCatalogWire(catalog))
|
|
889
894
|
return url.toString()
|
|
@@ -953,12 +958,20 @@ export interface BuildShellUrlOptions {
|
|
|
953
958
|
// screen holding a focused text field never reaches three identical idle
|
|
954
959
|
// frames, so the screenshot guard burns all 12 attempts and then fails.
|
|
955
960
|
proof?: boolean
|
|
961
|
+
// a temporary storage profile, stamped as ?ephemeral=1. the shell then
|
|
962
|
+
// neither reads nor writes the machine-wide settings in
|
|
963
|
+
// ~/.peach/config.json, so a preference another sim saved (bold text,
|
|
964
|
+
// reduce motion, appearance) cannot steer this boot.
|
|
965
|
+
ephemeral?: boolean
|
|
956
966
|
// launch-time environment variables, stamped as repeated ?env=KEY%3DVALUE.
|
|
957
967
|
// see the --env flag above.
|
|
958
968
|
env?: string[]
|
|
959
969
|
// the project's env file as react-native-config's iOS build compiles it,
|
|
960
970
|
// stamped as ?dotEnv=<json>. set by `peach open --load-env` only.
|
|
961
971
|
dotEnv?: Record<string, string>
|
|
972
|
+
// the bridge an explicit --port names; the expo swift compile endpoint
|
|
973
|
+
// stamped onto the URL uses it instead of the discovered world's bridge.
|
|
974
|
+
bridgePort?: number
|
|
962
975
|
}
|
|
963
976
|
|
|
964
977
|
function readProjectNativeFirebaseConfig(
|
|
@@ -1005,6 +1018,29 @@ export async function buildShellUrl(
|
|
|
1005
1018
|
project,
|
|
1006
1019
|
)
|
|
1007
1020
|
const expoStamped = new URL(stamped)
|
|
1021
|
+
if (project) {
|
|
1022
|
+
const device = opts.device ?? expoStamped.searchParams.get('device')
|
|
1023
|
+
const bundle = bundleUrlOf(resolved)
|
|
1024
|
+
const platform =
|
|
1025
|
+
device && isDeviceModel(device)
|
|
1026
|
+
? getRuntimePlatform(device)
|
|
1027
|
+
: bundle && new URL(bundle).searchParams.get('platform') === 'android'
|
|
1028
|
+
? 'android'
|
|
1029
|
+
: 'ios'
|
|
1030
|
+
const nativeRenderer = readNativeProjectRenderer(project.appDir, platform)
|
|
1031
|
+
if (nativeRenderer !== undefined) {
|
|
1032
|
+
const config = readPeachConfigFromSearchParams(expoStamped.searchParams)
|
|
1033
|
+
if (
|
|
1034
|
+
config?.nativeRenderer !== undefined &&
|
|
1035
|
+
config.nativeRenderer !== nativeRenderer
|
|
1036
|
+
)
|
|
1037
|
+
throw new Error('peach config contradicts native project renderer')
|
|
1038
|
+
expoStamped.searchParams.set(
|
|
1039
|
+
PEACH_CONFIG_QUERY_PARAM,
|
|
1040
|
+
JSON.stringify(mergePeachConfig(config, { nativeRenderer })),
|
|
1041
|
+
)
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1008
1044
|
// a plain Metro has no native Firebase config endpoint, so the CLI reads it
|
|
1009
1045
|
// from the project whose Expo config it can evaluate. a project without its
|
|
1010
1046
|
// own `@expo/config` (a dependency-free recorder) leaves it to the Peach
|
|
@@ -1020,18 +1056,24 @@ export async function buildShellUrl(
|
|
|
1020
1056
|
const world = resolveBridgeWorld()
|
|
1021
1057
|
const port = resolveBridgePortForPin({
|
|
1022
1058
|
baseUrl,
|
|
1023
|
-
wsPort: world.bridgePort,
|
|
1024
|
-
explicitPort:
|
|
1059
|
+
wsPort: opts.bridgePort ?? world.bridgePort,
|
|
1060
|
+
explicitPort: opts.bridgePort !== undefined,
|
|
1025
1061
|
})
|
|
1026
1062
|
if (port.error) throw new Error(port.error)
|
|
1027
1063
|
expoStamped.searchParams.set(
|
|
1028
1064
|
'expoSwift',
|
|
1029
1065
|
`http://localhost:${port.port}/__peach/expo-swift?root=${encodeURIComponent(expoRoot)}`,
|
|
1030
1066
|
)
|
|
1067
|
+
// the engine fetches only its device platform's build
|
|
1068
|
+
expoStamped.searchParams.set(
|
|
1069
|
+
'expoKotlin',
|
|
1070
|
+
`http://localhost:${port.port}/__peach/expo-kotlin?root=${encodeURIComponent(expoRoot)}`,
|
|
1071
|
+
)
|
|
1031
1072
|
}
|
|
1032
1073
|
if (
|
|
1033
1074
|
!opts.device &&
|
|
1034
1075
|
!opts.proof &&
|
|
1076
|
+
!opts.ephemeral &&
|
|
1035
1077
|
!opts.posture &&
|
|
1036
1078
|
!opts.orientation &&
|
|
1037
1079
|
!opts.osVersion &&
|
|
@@ -1048,6 +1090,7 @@ export async function buildShellUrl(
|
|
|
1048
1090
|
if (opts.osVersion) url.searchParams.set('osVersion', opts.osVersion)
|
|
1049
1091
|
if (opts.theme) url.searchParams.set('theme', opts.theme)
|
|
1050
1092
|
if (opts.proof) url.searchParams.set('proof', '1')
|
|
1093
|
+
if (opts.ephemeral) url.searchParams.set('ephemeral', '1')
|
|
1051
1094
|
for (const entry of opts.env ?? []) url.searchParams.append('env', entry)
|
|
1052
1095
|
return url.toString()
|
|
1053
1096
|
}
|
|
@@ -1079,6 +1122,7 @@ function deriveCurrentSimBaseUrl(
|
|
|
1079
1122
|
url.searchParams.delete('appCatalog')
|
|
1080
1123
|
url.searchParams.delete('nativeFirebase')
|
|
1081
1124
|
url.searchParams.delete('expoSwift')
|
|
1125
|
+
url.searchParams.delete('expoKotlin')
|
|
1082
1126
|
return url.toString()
|
|
1083
1127
|
} catch {
|
|
1084
1128
|
return fallback
|
|
@@ -1289,7 +1333,7 @@ function readUnservedUrl(result: DriverLaunchResult): string | null {
|
|
|
1289
1333
|
}
|
|
1290
1334
|
}
|
|
1291
1335
|
|
|
1292
|
-
function printDriverDiagnosticLogTail(result: DriverLaunchResult) {
|
|
1336
|
+
export function printDriverDiagnosticLogTail(result: DriverLaunchResult) {
|
|
1293
1337
|
if (!result.diagnosticLogPath) return
|
|
1294
1338
|
try {
|
|
1295
1339
|
const detail = fs.readFileSync(result.diagnosticLogPath, 'utf8').trim()
|
|
@@ -1563,7 +1607,7 @@ export async function runLinkCommand(args: string[], opts: ControlCommandOptions
|
|
|
1563
1607
|
if (parsed.positional.length !== 1) {
|
|
1564
1608
|
console.error(' peach open: expected exactly one <url-or-route>')
|
|
1565
1609
|
console.error(' examples: peach open /settings | peach open myapp://settings')
|
|
1566
|
-
|
|
1610
|
+
peachExit(1)
|
|
1567
1611
|
}
|
|
1568
1612
|
|
|
1569
1613
|
const bridge = createBridgeFromParsed(parsed)
|
|
@@ -1578,7 +1622,7 @@ export async function runLinkCommand(args: string[], opts: ControlCommandOptions
|
|
|
1578
1622
|
warningsCommand: `peach get warnings 5${simHint}`,
|
|
1579
1623
|
requestsCommand: `peach get requests 5${simHint}`,
|
|
1580
1624
|
})
|
|
1581
|
-
|
|
1625
|
+
peachExit(1)
|
|
1582
1626
|
} finally {
|
|
1583
1627
|
bridge.close()
|
|
1584
1628
|
}
|
|
@@ -1636,11 +1680,11 @@ export async function runOpenCommand(
|
|
|
1636
1680
|
console.error(
|
|
1637
1681
|
` peach open: --cdp-port must be a positive port number, got "${cdpPortArg}"`,
|
|
1638
1682
|
)
|
|
1639
|
-
|
|
1683
|
+
peachExit(1)
|
|
1640
1684
|
}
|
|
1641
1685
|
if (requestedProfileId && ephemeralProfile) {
|
|
1642
1686
|
console.error(' peach open: --profile cannot be combined with --ephemeral')
|
|
1643
|
-
|
|
1687
|
+
peachExit(1)
|
|
1644
1688
|
}
|
|
1645
1689
|
const profileId = requestedProfileId ? ensureProfile(requestedProfileId).id : undefined
|
|
1646
1690
|
const openInNewSim = args.includes('--new') || !!profileId || ephemeralProfile
|
|
@@ -1649,7 +1693,7 @@ export async function runOpenCommand(
|
|
|
1649
1693
|
console.error(
|
|
1650
1694
|
' peach open: --new, --profile, and --ephemeral cannot be combined with --sim',
|
|
1651
1695
|
)
|
|
1652
|
-
|
|
1696
|
+
peachExit(1)
|
|
1653
1697
|
}
|
|
1654
1698
|
const target = parsed.positional[0] || ''
|
|
1655
1699
|
|
|
@@ -1663,7 +1707,7 @@ export async function runOpenCommand(
|
|
|
1663
1707
|
console.error(
|
|
1664
1708
|
` peach open: --port is the WS bridge port, not the app port. to open the app on ${portValue}, pass it positionally: \`peach open ${portValue}\``,
|
|
1665
1709
|
)
|
|
1666
|
-
|
|
1710
|
+
peachExit(1)
|
|
1667
1711
|
}
|
|
1668
1712
|
|
|
1669
1713
|
// -t / --theme <light|dark|auto> seeds the appearance for the opened sim,
|
|
@@ -1676,7 +1720,7 @@ export async function runOpenCommand(
|
|
|
1676
1720
|
const themeArg = themeFlagIndex === -1 ? undefined : args[themeFlagIndex + 1]
|
|
1677
1721
|
if (themeFlagIndex !== -1 && themeArg === undefined) {
|
|
1678
1722
|
console.error(' peach open: --theme expects light, dark, or auto')
|
|
1679
|
-
|
|
1723
|
+
peachExit(1)
|
|
1680
1724
|
}
|
|
1681
1725
|
if (
|
|
1682
1726
|
themeArg !== undefined &&
|
|
@@ -1685,7 +1729,7 @@ export async function runOpenCommand(
|
|
|
1685
1729
|
themeArg !== 'auto'
|
|
1686
1730
|
) {
|
|
1687
1731
|
console.error(` peach open: --theme must be light, dark, or auto, got "${themeArg}"`)
|
|
1688
|
-
|
|
1732
|
+
peachExit(1)
|
|
1689
1733
|
}
|
|
1690
1734
|
|
|
1691
1735
|
if (isAppDeepLinkTarget(target)) {
|
|
@@ -1693,7 +1737,7 @@ export async function runOpenCommand(
|
|
|
1693
1737
|
console.error(
|
|
1694
1738
|
' peach open: deep links target the current app; remove --new, --profile, or --ephemeral',
|
|
1695
1739
|
)
|
|
1696
|
-
|
|
1740
|
+
peachExit(1)
|
|
1697
1741
|
}
|
|
1698
1742
|
await runLinkCommand(args, opts)
|
|
1699
1743
|
return
|
|
@@ -1721,7 +1765,7 @@ export async function runOpenCommand(
|
|
|
1721
1765
|
` could not launch a browser: ${err instanceof Error ? err.message : String(err)}`,
|
|
1722
1766
|
)
|
|
1723
1767
|
console.error(` open it yourself: ${target}`)
|
|
1724
|
-
|
|
1768
|
+
peachExit(1)
|
|
1725
1769
|
}
|
|
1726
1770
|
console.log(
|
|
1727
1771
|
isLocal
|
|
@@ -1738,7 +1782,7 @@ export async function runOpenCommand(
|
|
|
1738
1782
|
const projectRoot = projectRootIndex < 0 ? undefined : args[projectRootIndex + 1]
|
|
1739
1783
|
if (projectRootIndex >= 0 && (!projectRoot || projectRoot.startsWith('--'))) {
|
|
1740
1784
|
console.error(' peach open: --project-root expects a local app directory')
|
|
1741
|
-
|
|
1785
|
+
peachExit(1)
|
|
1742
1786
|
}
|
|
1743
1787
|
const project = await resolveAppProjectForBundleUrl(
|
|
1744
1788
|
resolvedBundle?.bundleUrl,
|
|
@@ -1772,7 +1816,7 @@ export async function runOpenCommand(
|
|
|
1772
1816
|
})
|
|
1773
1817
|
if (pinned.error !== undefined) {
|
|
1774
1818
|
console.error(` error: ${pinned.error}`)
|
|
1775
|
-
|
|
1819
|
+
peachExit(1)
|
|
1776
1820
|
} else {
|
|
1777
1821
|
parsed.wsPort = pinned.port
|
|
1778
1822
|
}
|
|
@@ -1796,10 +1840,12 @@ export async function runOpenCommand(
|
|
|
1796
1840
|
console.error(
|
|
1797
1841
|
` unknown driver "${requestedDriverId}" — run \`peach list --drivers\``,
|
|
1798
1842
|
)
|
|
1799
|
-
|
|
1843
|
+
peachExit(1)
|
|
1800
1844
|
}
|
|
1801
1845
|
const driverId: DriverId = isDriverId(requestedDriverId)
|
|
1802
|
-
? requestedDriverId
|
|
1846
|
+
? requestedDriverId === 'electron' && process.platform !== 'win32'
|
|
1847
|
+
? 'desktop'
|
|
1848
|
+
: requestedDriverId
|
|
1803
1849
|
: process.env.CI === '1' ||
|
|
1804
1850
|
process.env.CI === 'true' ||
|
|
1805
1851
|
process.env.GITHUB_ACTIONS === 'true' ||
|
|
@@ -1807,11 +1853,17 @@ export async function runOpenCommand(
|
|
|
1807
1853
|
isAgentEnv() ||
|
|
1808
1854
|
!process.stdin.isTTY
|
|
1809
1855
|
? 'playwright'
|
|
1810
|
-
: readSimulatorDriverPreference()
|
|
1856
|
+
: readSimulatorDriverPreference() === 'electron' && process.platform !== 'win32'
|
|
1857
|
+
? 'desktop'
|
|
1858
|
+
: readSimulatorDriverPreference() || 'playwright'
|
|
1859
|
+
if (requestedDriverId === 'electron' && driverId === 'desktop')
|
|
1860
|
+
console.error(
|
|
1861
|
+
' Electron is Windows-only; using the native desktop app (peach install-desktop).',
|
|
1862
|
+
)
|
|
1811
1863
|
const driverHeadless = resolveDriverHeadless(args, driverId)
|
|
1812
1864
|
if (cdpPort && driverId !== 'playwright') {
|
|
1813
1865
|
console.error(' peach open: --cdp-port is only honored by the playwright driver')
|
|
1814
|
-
|
|
1866
|
+
peachExit(1)
|
|
1815
1867
|
}
|
|
1816
1868
|
|
|
1817
1869
|
// metro HMR mode. interactive opens default to hot=true so edits hot-apply
|
|
@@ -1825,7 +1877,7 @@ export async function runOpenCommand(
|
|
|
1825
1877
|
const noHmrFlag = args.includes('--no-hmr')
|
|
1826
1878
|
if (hotFlag && noHmrFlag) {
|
|
1827
1879
|
console.error(' peach open: --hot and --no-hmr cannot be combined')
|
|
1828
|
-
|
|
1880
|
+
peachExit(1)
|
|
1829
1881
|
}
|
|
1830
1882
|
const hotMode = hotFlag ? true : noHmrFlag ? false : driverId !== 'playwright'
|
|
1831
1883
|
|
|
@@ -1837,7 +1889,7 @@ export async function runOpenCommand(
|
|
|
1837
1889
|
if (deviceArg && !(deviceArg in devices)) {
|
|
1838
1890
|
console.error(` peach open: unknown device "${deviceArg}"`)
|
|
1839
1891
|
console.error(` known devices: ${listSelectableDeviceModels().join(', ')}`)
|
|
1840
|
-
|
|
1892
|
+
peachExit(1)
|
|
1841
1893
|
}
|
|
1842
1894
|
|
|
1843
1895
|
// --posture <open|closed> seeds the fold posture for the opened sim,
|
|
@@ -1847,7 +1899,7 @@ export async function runOpenCommand(
|
|
|
1847
1899
|
const postureArg = args.find((_, i) => args[i - 1] === '--posture')
|
|
1848
1900
|
if (postureArg && postureArg !== 'open' && postureArg !== 'closed') {
|
|
1849
1901
|
console.error(` peach open: --posture must be open or closed, got "${postureArg}"`)
|
|
1850
|
-
|
|
1902
|
+
peachExit(1)
|
|
1851
1903
|
}
|
|
1852
1904
|
const orientationFlag = args.find((_, i) => args[i - 1] === '--orientation')
|
|
1853
1905
|
const orientationArg =
|
|
@@ -1858,7 +1910,7 @@ export async function runOpenCommand(
|
|
|
1858
1910
|
console.error(
|
|
1859
1911
|
` peach open: --orientation must be portrait or landscape, got "${orientationFlag}"`,
|
|
1860
1912
|
)
|
|
1861
|
-
|
|
1913
|
+
peachExit(1)
|
|
1862
1914
|
}
|
|
1863
1915
|
// the window fits the box the browser stage fits the device into, which for
|
|
1864
1916
|
// a foldable spans both postures, so the device draws at its natural size in
|
|
@@ -1878,7 +1930,7 @@ export async function runOpenCommand(
|
|
|
1878
1930
|
console.error(
|
|
1879
1931
|
` peach open: --os-version must be <major>.<minor>, got "${osVersionArg}"`,
|
|
1880
1932
|
)
|
|
1881
|
-
|
|
1933
|
+
peachExit(1)
|
|
1882
1934
|
}
|
|
1883
1935
|
|
|
1884
1936
|
// --env <KEY=VALUE> (repeatable) sets a launch-time environment variable,
|
|
@@ -1894,7 +1946,7 @@ export async function runOpenCommand(
|
|
|
1894
1946
|
const eqIndex = raw ? raw.indexOf('=') : -1
|
|
1895
1947
|
if (!raw || eqIndex <= 0) {
|
|
1896
1948
|
console.error(` peach open: --env expects KEY=VALUE, got "${raw ?? ''}"`)
|
|
1897
|
-
|
|
1949
|
+
peachExit(1)
|
|
1898
1950
|
}
|
|
1899
1951
|
envArgs.push(raw)
|
|
1900
1952
|
}
|
|
@@ -1909,7 +1961,7 @@ export async function runOpenCommand(
|
|
|
1909
1961
|
console.error(
|
|
1910
1962
|
` peach open: --viewport must be <width>x<height>, got "${viewportArg}"`,
|
|
1911
1963
|
)
|
|
1912
|
-
|
|
1964
|
+
peachExit(1)
|
|
1913
1965
|
}
|
|
1914
1966
|
const explicitViewport = viewportMatch
|
|
1915
1967
|
? { width: Number(viewportMatch[1]), height: Number(viewportMatch[2]) }
|
|
@@ -1925,7 +1977,7 @@ export async function runOpenCommand(
|
|
|
1925
1977
|
console.error(
|
|
1926
1978
|
' peach open: --load-env needs a local app project to read the env file from',
|
|
1927
1979
|
)
|
|
1928
|
-
|
|
1980
|
+
peachExit(1)
|
|
1929
1981
|
}
|
|
1930
1982
|
try {
|
|
1931
1983
|
const result = readProjectDotEnv(project.appDir)
|
|
@@ -1935,7 +1987,7 @@ export async function runOpenCommand(
|
|
|
1935
1987
|
console.error(
|
|
1936
1988
|
` peach open: ${error instanceof Error ? error.message : String(error)}`,
|
|
1937
1989
|
)
|
|
1938
|
-
|
|
1990
|
+
peachExit(1)
|
|
1939
1991
|
}
|
|
1940
1992
|
}
|
|
1941
1993
|
|
|
@@ -1951,8 +2003,10 @@ export async function runOpenCommand(
|
|
|
1951
2003
|
resolvedBundle,
|
|
1952
2004
|
project,
|
|
1953
2005
|
proof: args.includes('--proof'),
|
|
2006
|
+
ephemeral: ephemeralProfile,
|
|
1954
2007
|
env: envArgs.length ? envArgs : undefined,
|
|
1955
2008
|
dotEnv,
|
|
2009
|
+
bridgePort: parsed.explicitPort ? parsed.wsPort : undefined,
|
|
1956
2010
|
}
|
|
1957
2011
|
|
|
1958
2012
|
// resolve the shell base URL from the bridge port we settled on, so the page
|
|
@@ -2069,7 +2123,7 @@ export async function runOpenCommand(
|
|
|
2069
2123
|
warningsCommand: `peach get warnings 5${simHint}`,
|
|
2070
2124
|
requestsCommand: `peach get requests 5${simHint}`,
|
|
2071
2125
|
})
|
|
2072
|
-
|
|
2126
|
+
peachExit(1)
|
|
2073
2127
|
}
|
|
2074
2128
|
|
|
2075
2129
|
if (!fallBackToNewSim && targetSim && navigatedShellUrl) {
|
|
@@ -2093,7 +2147,7 @@ export async function runOpenCommand(
|
|
|
2093
2147
|
warningsCommand: `peach get warnings 5${simHint}`,
|
|
2094
2148
|
requestsCommand: `peach get requests 5${simHint}`,
|
|
2095
2149
|
})
|
|
2096
|
-
|
|
2150
|
+
peachExit(1)
|
|
2097
2151
|
}
|
|
2098
2152
|
targetSim = navigatedSim
|
|
2099
2153
|
const ready = await waitForSimReady(
|
|
@@ -2110,7 +2164,7 @@ export async function runOpenCommand(
|
|
|
2110
2164
|
warningsCommand: `peach get warnings 5${simHint}`,
|
|
2111
2165
|
requestsCommand: `peach get requests 5${simHint}`,
|
|
2112
2166
|
})
|
|
2113
|
-
|
|
2167
|
+
peachExit(1)
|
|
2114
2168
|
}
|
|
2115
2169
|
ready.bridge.close()
|
|
2116
2170
|
saveCurrentSimId(targetSim.id)
|
|
@@ -2136,12 +2190,12 @@ export async function runOpenCommand(
|
|
|
2136
2190
|
console.error(
|
|
2137
2191
|
' could not resolve a stable owning process; refusing unsupervised sim host',
|
|
2138
2192
|
)
|
|
2139
|
-
|
|
2193
|
+
peachExit(1)
|
|
2140
2194
|
}
|
|
2141
2195
|
const driver = getDriver(driverId)
|
|
2142
2196
|
if (!driver) {
|
|
2143
2197
|
console.error(` unknown driver "${driverId}" — run \`peach list --drivers\``)
|
|
2144
|
-
|
|
2198
|
+
peachExit(1)
|
|
2145
2199
|
}
|
|
2146
2200
|
const connectWait = resolveDriverConnectWaitOptions()
|
|
2147
2201
|
opts.signal?.throwIfAborted()
|
|
@@ -2171,7 +2225,7 @@ export async function runOpenCommand(
|
|
|
2171
2225
|
opts.signal?.throwIfAborted()
|
|
2172
2226
|
if (!result.launched) {
|
|
2173
2227
|
console.error(` ${driver.name} driver: ${result.message}`)
|
|
2174
|
-
|
|
2228
|
+
peachExit(1)
|
|
2175
2229
|
}
|
|
2176
2230
|
const outcome = await waitForSimMatchOrHostExit(
|
|
2177
2231
|
parsed.wsPort,
|
|
@@ -2194,7 +2248,7 @@ export async function runOpenCommand(
|
|
|
2194
2248
|
} else {
|
|
2195
2249
|
console.error(` ${driver.name} host crashed — sim is no longer attached`)
|
|
2196
2250
|
}
|
|
2197
|
-
|
|
2251
|
+
peachExit(1)
|
|
2198
2252
|
}
|
|
2199
2253
|
if (outcome.kind === 'timeout') {
|
|
2200
2254
|
if (result.pid) {
|
|
@@ -2207,7 +2261,7 @@ export async function runOpenCommand(
|
|
|
2207
2261
|
console.error(
|
|
2208
2262
|
` timed out after ${connectWait.timeoutMs}ms waiting for opened sim to connect`,
|
|
2209
2263
|
)
|
|
2210
|
-
|
|
2264
|
+
peachExit(1)
|
|
2211
2265
|
}
|
|
2212
2266
|
const match = outcome.sim
|
|
2213
2267
|
if (opts.resources) opts.resources.simId = match.id
|
|
@@ -2237,7 +2291,7 @@ export async function runOpenCommand(
|
|
|
2237
2291
|
requestsCommand: `peach get requests 5${hint}`,
|
|
2238
2292
|
})
|
|
2239
2293
|
bridge.close()
|
|
2240
|
-
|
|
2294
|
+
peachExit(1)
|
|
2241
2295
|
}
|
|
2242
2296
|
ready.bridge.close()
|
|
2243
2297
|
printOpenedSim(openUrl, match, `${driver.name} driver`, quiet)
|
|
@@ -2280,7 +2334,7 @@ async function runUseLikeCommand(args: string[], opts: ControlCommandOptions = {
|
|
|
2280
2334
|
` refused: ${target.id} is locked by the active user (${secs}s) — that's a live human tab`,
|
|
2281
2335
|
)
|
|
2282
2336
|
console.error(` run \`peach open --new\` for a fresh investigation sim`)
|
|
2283
|
-
|
|
2337
|
+
peachExit(1)
|
|
2284
2338
|
}
|
|
2285
2339
|
if (!force) {
|
|
2286
2340
|
// another CLI agent leases it. don't hijack its target silently;
|
|
@@ -2292,7 +2346,7 @@ async function runUseLikeCommand(args: string[], opts: ControlCommandOptions = {
|
|
|
2292
2346
|
console.error(
|
|
2293
2347
|
` \`peach use ${target.id} --force\` to take it, or \`peach open --new\` for a fresh sim`,
|
|
2294
2348
|
)
|
|
2295
|
-
|
|
2349
|
+
peachExit(1)
|
|
2296
2350
|
}
|
|
2297
2351
|
}
|
|
2298
2352
|
await bridge.focusSim(target.id)
|
|
@@ -2306,7 +2360,7 @@ async function runUseLikeCommand(args: string[], opts: ControlCommandOptions = {
|
|
|
2306
2360
|
warningsCommand: `peach get warnings 5${simHint}`,
|
|
2307
2361
|
requestsCommand: `peach get requests 5${simHint}`,
|
|
2308
2362
|
})
|
|
2309
|
-
|
|
2363
|
+
peachExit(1)
|
|
2310
2364
|
}
|
|
2311
2365
|
} finally {
|
|
2312
2366
|
bridge.close()
|
|
@@ -2350,10 +2404,10 @@ export async function runClaimCommand(args: string[], opts: ControlCommandOption
|
|
|
2350
2404
|
const secs = Math.max(0, Math.round(err.lock.expiresInMs / 1000))
|
|
2351
2405
|
console.error(` claim failed: locked by ${err.lock.by} for ${secs}s more`)
|
|
2352
2406
|
console.error(` use --force to take it, or \`peach open --new\` for a fresh sim`)
|
|
2353
|
-
|
|
2407
|
+
peachExit(1)
|
|
2354
2408
|
}
|
|
2355
2409
|
console.error(` claim failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
2356
|
-
|
|
2410
|
+
peachExit(1)
|
|
2357
2411
|
}
|
|
2358
2412
|
} finally {
|
|
2359
2413
|
bridge.close()
|
|
@@ -2545,7 +2599,7 @@ export async function runCloseCommand(args: string[], opts: ControlCommandOption
|
|
|
2545
2599
|
console.error(
|
|
2546
2600
|
` close failed: keep sim ${plan.missingExplicitKeepId} is not connected; not closing other sims`,
|
|
2547
2601
|
)
|
|
2548
|
-
|
|
2602
|
+
peachExit(1)
|
|
2549
2603
|
}
|
|
2550
2604
|
if (plan.targets.length === 0) {
|
|
2551
2605
|
console.log(
|
|
@@ -2578,12 +2632,12 @@ export async function runCloseCommand(args: string[], opts: ControlCommandOption
|
|
|
2578
2632
|
console.log(summary)
|
|
2579
2633
|
if (result.remaining.length > 0) {
|
|
2580
2634
|
console.error(` close failed: still connected: ${result.remaining.join(', ')}`)
|
|
2581
|
-
|
|
2635
|
+
peachExit(1)
|
|
2582
2636
|
}
|
|
2583
2637
|
} catch (err) {
|
|
2584
2638
|
rethrowIfExit(err)
|
|
2585
2639
|
console.error(` close failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
2586
|
-
|
|
2640
|
+
peachExit(1)
|
|
2587
2641
|
} finally {
|
|
2588
2642
|
bridge.close()
|
|
2589
2643
|
}
|
|
@@ -2606,7 +2660,7 @@ export async function runCloseCommand(args: string[], opts: ControlCommandOption
|
|
|
2606
2660
|
if (!closed) {
|
|
2607
2661
|
await terminatePlaywrightHostsForSims(sims, [target.id])
|
|
2608
2662
|
console.error(` close failed: ${target.id} is still connected`)
|
|
2609
|
-
|
|
2663
|
+
peachExit(1)
|
|
2610
2664
|
}
|
|
2611
2665
|
await terminatePlaywrightHostsForSims(sims, [target.id])
|
|
2612
2666
|
if (readCurrentSimId() === target.id) {
|
|
@@ -2623,14 +2677,14 @@ export async function runCloseCommand(args: string[], opts: ControlCommandOption
|
|
|
2623
2677
|
console.error(
|
|
2624
2678
|
` to close ${word === 'all' ? 'every' : 'every other'} sim: peach close --${word}`,
|
|
2625
2679
|
)
|
|
2626
|
-
|
|
2680
|
+
peachExit(1)
|
|
2627
2681
|
}
|
|
2628
2682
|
await printBridgeFailureDiagnostics(bridge, {
|
|
2629
2683
|
errorsCommand: `peach get errors 5${simHint}`,
|
|
2630
2684
|
warningsCommand: `peach get warnings 5${simHint}`,
|
|
2631
2685
|
requestsCommand: `peach get requests 5${simHint}`,
|
|
2632
2686
|
})
|
|
2633
|
-
|
|
2687
|
+
peachExit(1)
|
|
2634
2688
|
}
|
|
2635
2689
|
} finally {
|
|
2636
2690
|
bridge.close()
|