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
|
@@ -491,6 +491,7 @@ Writes a page profile, worker profiles, and a manifest alongside the output.
|
|
|
491
491
|
const response = await cdp.send('Runtime.evaluate', {
|
|
492
492
|
expression,
|
|
493
493
|
returnByValue: true,
|
|
494
|
+
awaitPromise: true,
|
|
494
495
|
})
|
|
495
496
|
if (response?.exceptionDetails) {
|
|
496
497
|
throw new Error(
|
|
@@ -693,8 +694,33 @@ Writes a page profile, worker profiles, and a manifest alongside the output.
|
|
|
693
694
|
captureStarted = true
|
|
694
695
|
startPromises.push(startTarget(pageTarget))
|
|
695
696
|
for (const target of workers.values()) startPromises.push(startTarget(target))
|
|
697
|
+
// with the native host attached, the engine's workers are realm threads in the host, reached
|
|
698
|
+
// through the page; they record over the same window as the browser targets
|
|
699
|
+
const hostRealms =
|
|
700
|
+
(await evaluatePage(`typeof window.__peachNative?.cpuProfile === 'function'`)) ===
|
|
701
|
+
true
|
|
702
|
+
const hostTargets: AttachedTarget[] = []
|
|
703
|
+
if (hostRealms) {
|
|
704
|
+
const startedAtMs = performance.now()
|
|
705
|
+
const realms = await evaluatePage(
|
|
706
|
+
`window.__peachNative.cpuProfile('start', ${sampleInterval * 1000})`,
|
|
707
|
+
)
|
|
708
|
+
for (const realm of Array.isArray(realms) ? realms : []) {
|
|
709
|
+
hostTargets.push({
|
|
710
|
+
attachedAtMs: startedAtMs,
|
|
711
|
+
detached: false,
|
|
712
|
+
error: realm.error,
|
|
713
|
+
profileStartedAtMs: realm.error ? undefined : performance.now(),
|
|
714
|
+
role: cpuProfileTargetRole(realm.url, realm.name),
|
|
715
|
+
started: !realm.error,
|
|
716
|
+
title: realm.name,
|
|
717
|
+
type: 'host-realm',
|
|
718
|
+
url: realm.url,
|
|
719
|
+
})
|
|
720
|
+
}
|
|
721
|
+
}
|
|
696
722
|
await waitForStableTargetSetup()
|
|
697
|
-
const startedCount = [pageTarget, ...workers.values()].filter(
|
|
723
|
+
const startedCount = [pageTarget, ...workers.values(), ...hostTargets].filter(
|
|
698
724
|
(target) => target.started,
|
|
699
725
|
).length
|
|
700
726
|
if (startedCount === 0) {
|
|
@@ -737,6 +763,23 @@ Writes a page profile, worker profiles, and a manifest alongside the output.
|
|
|
737
763
|
await cdp.send('Profiler.disable', {}, target.sessionId).catch(() => {})
|
|
738
764
|
}),
|
|
739
765
|
)
|
|
766
|
+
if (hostRealms) {
|
|
767
|
+
const stopped = await evaluatePage(`window.__peachNative.cpuProfile('stop', 0)`)
|
|
768
|
+
const stoppedAtMs = performance.now()
|
|
769
|
+
for (const realm of Array.isArray(stopped) ? stopped : []) {
|
|
770
|
+
const target = hostTargets.find(
|
|
771
|
+
(candidate) =>
|
|
772
|
+
candidate.title === realm.name &&
|
|
773
|
+
candidate.url === realm.url &&
|
|
774
|
+
!candidate.profile,
|
|
775
|
+
)
|
|
776
|
+
if (!target) continue
|
|
777
|
+
if (realm.profile) target.profile = realm.profile
|
|
778
|
+
else target.error = realm.error
|
|
779
|
+
target.profileStoppedAtMs = stoppedAtMs
|
|
780
|
+
}
|
|
781
|
+
results.push(...hostTargets)
|
|
782
|
+
}
|
|
740
783
|
// querying the page while five high-frequency profilers are still active
|
|
741
784
|
// can itself time out and lengthen the requested sampling interval. stop
|
|
742
785
|
// first, then read the already-recorded workload completion evidence. a
|
|
@@ -945,6 +988,7 @@ export function cpuProfileTargetRole(url: string, title = ''): string {
|
|
|
945
988
|
return 'compositor'
|
|
946
989
|
}
|
|
947
990
|
if (identity.includes('shell-worker')) return 'shell'
|
|
991
|
+
if (identity.includes('peach-host')) return 'host'
|
|
948
992
|
if (identity.includes('named-worklet')) return 'worklet'
|
|
949
993
|
if (identity.includes('render-worker') || identity.includes('tenant-worker')) {
|
|
950
994
|
return 'tenant'
|
package/cli/commands/daemon.ts
CHANGED
|
@@ -19,7 +19,9 @@ import { spawnSync } from 'child_process'
|
|
|
19
19
|
import {
|
|
20
20
|
existsSync,
|
|
21
21
|
mkdirSync,
|
|
22
|
+
readdirSync,
|
|
22
23
|
readFileSync,
|
|
24
|
+
readlinkSync,
|
|
23
25
|
realpathSync,
|
|
24
26
|
rmSync,
|
|
25
27
|
writeFileSync,
|
|
@@ -27,6 +29,7 @@ import {
|
|
|
27
29
|
import { homedir } from 'os'
|
|
28
30
|
import { dirname, resolve } from 'path'
|
|
29
31
|
import { DEFAULT_SOOTSIM_BRIDGE_PORT } from '../../src/bridge-constants'
|
|
32
|
+
import { unregisterNativeDesktopLinks } from '../../src/desktop-host-delivery'
|
|
30
33
|
import {
|
|
31
34
|
daemonAppDir,
|
|
32
35
|
isDaemonLockfileFresh,
|
|
@@ -37,7 +40,7 @@ import {
|
|
|
37
40
|
import { rnxPublicBrand } from '../../src/public-brand'
|
|
38
41
|
import { printCommandHelp } from '../help'
|
|
39
42
|
import { escapeXml } from '../maestro-report'
|
|
40
|
-
import {
|
|
43
|
+
import { peachExit } from '../run-rnx'
|
|
41
44
|
import { rnxSelfInvocation, type RnxSelfInvocation } from '../self-invocation'
|
|
42
45
|
import { DAEMON_ENVIRONMENT, ensureDaemonApp } from './daemon-mac-app'
|
|
43
46
|
|
|
@@ -84,7 +87,7 @@ export async function runDaemon(args: string[], opts: DaemonOptions = {}) {
|
|
|
84
87
|
default:
|
|
85
88
|
console.error(` unknown daemon subcommand: ${sub}`)
|
|
86
89
|
printHelp()
|
|
87
|
-
|
|
90
|
+
peachExit(1)
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
93
|
|
|
@@ -316,7 +319,7 @@ export async function daemonInstall({ port, force }: { port: number; force: bool
|
|
|
316
319
|
|
|
317
320
|
console.error(` background daemon is not supported on ${process.platform}`)
|
|
318
321
|
console.error(` run 'peach serve' in a persistent shell instead`)
|
|
319
|
-
|
|
322
|
+
peachExit(1)
|
|
320
323
|
}
|
|
321
324
|
|
|
322
325
|
function macServiceTarget(): string {
|
|
@@ -364,9 +367,9 @@ function macBridgeHasListener(pid: number, port: number): boolean {
|
|
|
364
367
|
|
|
365
368
|
export async function stopMacDaemonBridge(
|
|
366
369
|
invocation: RnxSelfInvocation,
|
|
367
|
-
target = macServiceTarget(),
|
|
370
|
+
target: string | null = macServiceTarget(),
|
|
368
371
|
): Promise<void> {
|
|
369
|
-
const service = readMacDaemonState(target)
|
|
372
|
+
const service = target === null ? null : readMacDaemonState(target)
|
|
370
373
|
const lock = readDaemonLockfile()
|
|
371
374
|
if (isDaemonLockfileFresh(lock) && lock.pid !== service?.pid) {
|
|
372
375
|
// a lockfile alone cannot authorize a signal after pid reuse.
|
|
@@ -387,7 +390,7 @@ export async function stopMacDaemonBridge(
|
|
|
387
390
|
}
|
|
388
391
|
process.kill(lock.pid, 'SIGTERM')
|
|
389
392
|
}
|
|
390
|
-
if (service) runLaunchctl(['bootout', target])
|
|
393
|
+
if (service && target !== null) runLaunchctl(['bootout', target])
|
|
391
394
|
if (!lock) return
|
|
392
395
|
const deadline = Date.now() + 4000
|
|
393
396
|
while (Date.now() < deadline) {
|
|
@@ -436,6 +439,102 @@ export async function startMacDaemon(
|
|
|
436
439
|
)
|
|
437
440
|
}
|
|
438
441
|
|
|
442
|
+
// --- linux bridge ownership --------------------------------------------
|
|
443
|
+
|
|
444
|
+
// the linux counterparts to the mac listener and command checks above. both
|
|
445
|
+
// read /proc directly instead of shelling out to lsof, ss or ps, so minimal
|
|
446
|
+
// containers and fresh users get the same ownership proof with no extra
|
|
447
|
+
// binaries installed.
|
|
448
|
+
|
|
449
|
+
function linuxBridgeHasListener(pid: number, port: number): boolean {
|
|
450
|
+
let fds: string[]
|
|
451
|
+
try {
|
|
452
|
+
fds = readdirSync(`/proc/${pid}/fd`)
|
|
453
|
+
} catch {
|
|
454
|
+
return false
|
|
455
|
+
}
|
|
456
|
+
const sockets = new Set<string>()
|
|
457
|
+
for (const fd of fds) {
|
|
458
|
+
try {
|
|
459
|
+
const inode = readlinkSync(`/proc/${pid}/fd/${fd}`).match(/^socket:\[(\d+)\]$/)?.[1]
|
|
460
|
+
if (inode) sockets.add(inode)
|
|
461
|
+
} catch {
|
|
462
|
+
// the fd closed between listing and read; skip it.
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (sockets.size === 0) return false
|
|
466
|
+
const hexPort = port.toString(16).toUpperCase().padStart(4, '0')
|
|
467
|
+
for (const table of ['/proc/net/tcp', '/proc/net/tcp6']) {
|
|
468
|
+
let body: string
|
|
469
|
+
try {
|
|
470
|
+
body = readFileSync(table, 'utf8')
|
|
471
|
+
} catch {
|
|
472
|
+
continue
|
|
473
|
+
}
|
|
474
|
+
const lines = body.split('\n')
|
|
475
|
+
for (let i = 1; i < lines.length; i++) {
|
|
476
|
+
const cols = lines[i].trim().split(/\s+/)
|
|
477
|
+
if (cols.length < 10) continue
|
|
478
|
+
if (cols[3] !== '0A') continue
|
|
479
|
+
if (!cols[1].endsWith(`:${hexPort}`)) continue
|
|
480
|
+
if (sockets.has(cols[9])) return true
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return false
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function readLinuxProcessCommand(pid: number): string | null {
|
|
487
|
+
// /proc cmdline is the argv vector verbatim; joining with spaces matches
|
|
488
|
+
// what `ps -o command=` prints without needing procps installed.
|
|
489
|
+
try {
|
|
490
|
+
const args = readFileSync(`/proc/${pid}/cmdline`, 'utf8')
|
|
491
|
+
.split('\0')
|
|
492
|
+
.filter((part) => part.length > 0)
|
|
493
|
+
return args.length > 0 ? args.join(' ') : null
|
|
494
|
+
} catch {
|
|
495
|
+
return null
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
export async function stopLinuxDaemonBridge(
|
|
500
|
+
invocation: RnxSelfInvocation,
|
|
501
|
+
registered: boolean,
|
|
502
|
+
): Promise<void> {
|
|
503
|
+
if (registered) {
|
|
504
|
+
const res = spawnSync('systemctl', ['--user', 'stop', SERVICE_NAME_LINUX], {
|
|
505
|
+
stdio: 'pipe',
|
|
506
|
+
encoding: 'utf8',
|
|
507
|
+
})
|
|
508
|
+
if (res.status !== 0) {
|
|
509
|
+
console.error(` stop failed: ${res.stderr?.trim()}`)
|
|
510
|
+
peachExit(1)
|
|
511
|
+
}
|
|
512
|
+
return
|
|
513
|
+
}
|
|
514
|
+
const lock = readDaemonLockfile()
|
|
515
|
+
if (!isDaemonLockfileFresh(lock)) return
|
|
516
|
+
// a lockfile alone cannot authorize a signal after pid reuse.
|
|
517
|
+
const ownsListener = linuxBridgeHasListener(lock.pid, lock.bridgePort)
|
|
518
|
+
const runningCommand = readLinuxProcessCommand(lock.pid)
|
|
519
|
+
const command = [invocation.executable, ...invocation.prefixArgs, 'serve'].join(' ')
|
|
520
|
+
if (
|
|
521
|
+
!ownsListener ||
|
|
522
|
+
runningCommand === null ||
|
|
523
|
+
(runningCommand !== command && !runningCommand.startsWith(`${command} `))
|
|
524
|
+
) {
|
|
525
|
+
throw new Error(
|
|
526
|
+
`cannot hand off bridge on port ${lock.bridgePort}: pid ${lock.pid} is not this Peach invocation`,
|
|
527
|
+
)
|
|
528
|
+
}
|
|
529
|
+
process.kill(lock.pid, 'SIGTERM')
|
|
530
|
+
const deadline = Date.now() + 4000
|
|
531
|
+
while (Date.now() < deadline) {
|
|
532
|
+
if (!linuxBridgeHasListener(lock.pid, lock.bridgePort)) return
|
|
533
|
+
await new Promise((resolve) => setTimeout(resolve, 100))
|
|
534
|
+
}
|
|
535
|
+
throw new Error(`bridge pid ${lock.pid} did not release port ${lock.bridgePort}`)
|
|
536
|
+
}
|
|
537
|
+
|
|
439
538
|
// removed-path log (idempotent helpers track what they actually touched so the
|
|
440
539
|
// caller can report a unified "not installed" / "removed N entries" line).
|
|
441
540
|
type TeardownReport = { removed: string[]; missing: boolean }
|
|
@@ -542,6 +641,7 @@ export function teardownDaemonService(): TeardownReport {
|
|
|
542
641
|
export function teardownRnxHome(): TeardownReport {
|
|
543
642
|
const removed: string[] = []
|
|
544
643
|
const home = rnxHomeDir()
|
|
644
|
+
unregisterNativeDesktopLinks()
|
|
545
645
|
if (existsSync(home)) {
|
|
546
646
|
rmSync(home, { recursive: true, force: true })
|
|
547
647
|
removed.push(home)
|
|
@@ -558,7 +658,7 @@ async function daemonUninstall(rest: string[]) {
|
|
|
558
658
|
if (unknown.length > 0) {
|
|
559
659
|
console.error(` unknown daemon uninstall option: ${unknown[0]}`)
|
|
560
660
|
printHelp()
|
|
561
|
-
|
|
661
|
+
peachExit(1)
|
|
562
662
|
return
|
|
563
663
|
}
|
|
564
664
|
const purge = rest.includes('--purge')
|
|
@@ -641,7 +741,7 @@ async function daemonStatus() {
|
|
|
641
741
|
return
|
|
642
742
|
}
|
|
643
743
|
console.error(` unsupported platform: ${process.platform}`)
|
|
644
|
-
|
|
744
|
+
peachExit(1)
|
|
645
745
|
}
|
|
646
746
|
|
|
647
747
|
async function daemonRestart() {
|
|
@@ -649,7 +749,7 @@ async function daemonRestart() {
|
|
|
649
749
|
const path = macPlistPath()
|
|
650
750
|
if (!existsSync(path)) {
|
|
651
751
|
console.error(' daemon not registered. run `peach daemon install`')
|
|
652
|
-
|
|
752
|
+
peachExit(1)
|
|
653
753
|
}
|
|
654
754
|
await stopMacDaemonBridge(resolveDaemonInvocation())
|
|
655
755
|
await startMacDaemon(path)
|
|
@@ -660,7 +760,7 @@ async function daemonRestart() {
|
|
|
660
760
|
const path = linuxUnitPath()
|
|
661
761
|
if (!existsSync(path)) {
|
|
662
762
|
console.error(' daemon not registered. run `peach daemon install`')
|
|
663
|
-
|
|
763
|
+
peachExit(1)
|
|
664
764
|
}
|
|
665
765
|
const res = spawnSync('systemctl', ['--user', 'restart', SERVICE_NAME_LINUX], {
|
|
666
766
|
stdio: 'pipe',
|
|
@@ -668,13 +768,13 @@ async function daemonRestart() {
|
|
|
668
768
|
})
|
|
669
769
|
if (res.status !== 0) {
|
|
670
770
|
console.error(` restart failed: ${res.stderr?.trim()}`)
|
|
671
|
-
|
|
771
|
+
peachExit(1)
|
|
672
772
|
}
|
|
673
773
|
console.log(' restarted')
|
|
674
774
|
return
|
|
675
775
|
}
|
|
676
776
|
console.error(` unsupported platform: ${process.platform}`)
|
|
677
|
-
|
|
777
|
+
peachExit(1)
|
|
678
778
|
}
|
|
679
779
|
|
|
680
780
|
async function daemonStart() {
|
|
@@ -682,7 +782,7 @@ async function daemonStart() {
|
|
|
682
782
|
const path = macPlistPath()
|
|
683
783
|
if (!existsSync(path)) {
|
|
684
784
|
console.error(' daemon not registered. run `peach daemon install`')
|
|
685
|
-
|
|
785
|
+
peachExit(1)
|
|
686
786
|
}
|
|
687
787
|
await startMacDaemon(path)
|
|
688
788
|
console.log(' started')
|
|
@@ -692,7 +792,7 @@ async function daemonStart() {
|
|
|
692
792
|
const path = linuxUnitPath()
|
|
693
793
|
if (!existsSync(path)) {
|
|
694
794
|
console.error(' daemon not registered. run `peach daemon install`')
|
|
695
|
-
|
|
795
|
+
peachExit(1)
|
|
696
796
|
}
|
|
697
797
|
const res = spawnSync('systemctl', ['--user', 'start', SERVICE_NAME_LINUX], {
|
|
698
798
|
stdio: 'pipe',
|
|
@@ -700,45 +800,43 @@ async function daemonStart() {
|
|
|
700
800
|
})
|
|
701
801
|
if (res.status !== 0) {
|
|
702
802
|
console.error(` start failed: ${res.stderr?.trim()}`)
|
|
703
|
-
|
|
803
|
+
peachExit(1)
|
|
704
804
|
}
|
|
705
805
|
console.log(' started')
|
|
706
806
|
return
|
|
707
807
|
}
|
|
708
808
|
console.error(` unsupported platform: ${process.platform}`)
|
|
709
|
-
|
|
809
|
+
peachExit(1)
|
|
710
810
|
}
|
|
711
811
|
|
|
712
812
|
async function daemonStop() {
|
|
713
813
|
if (process.platform === 'darwin') {
|
|
714
814
|
const path = macPlistPath()
|
|
715
|
-
|
|
815
|
+
const registered = existsSync(path)
|
|
816
|
+
if (!registered && !isDaemonLockfileFresh(readDaemonLockfile())) {
|
|
716
817
|
console.error(' daemon not registered — nothing to stop')
|
|
717
|
-
|
|
818
|
+
peachExit(1)
|
|
718
819
|
}
|
|
719
|
-
await stopMacDaemonBridge(
|
|
820
|
+
await stopMacDaemonBridge(
|
|
821
|
+
resolveDaemonInvocation(),
|
|
822
|
+
registered ? macServiceTarget() : null,
|
|
823
|
+
)
|
|
720
824
|
console.log(' stopped')
|
|
721
825
|
return
|
|
722
826
|
}
|
|
723
827
|
if (process.platform === 'linux') {
|
|
724
828
|
const path = linuxUnitPath()
|
|
725
|
-
|
|
829
|
+
const registered = existsSync(path)
|
|
830
|
+
if (!registered && !isDaemonLockfileFresh(readDaemonLockfile())) {
|
|
726
831
|
console.error(' daemon not registered — nothing to stop')
|
|
727
|
-
|
|
728
|
-
}
|
|
729
|
-
const res = spawnSync('systemctl', ['--user', 'stop', SERVICE_NAME_LINUX], {
|
|
730
|
-
stdio: 'pipe',
|
|
731
|
-
encoding: 'utf8',
|
|
732
|
-
})
|
|
733
|
-
if (res.status !== 0) {
|
|
734
|
-
console.error(` stop failed: ${res.stderr?.trim()}`)
|
|
735
|
-
rnxExit(1)
|
|
832
|
+
peachExit(1)
|
|
736
833
|
}
|
|
834
|
+
await stopLinuxDaemonBridge(resolveDaemonInvocation(), registered)
|
|
737
835
|
console.log(' stopped')
|
|
738
836
|
return
|
|
739
837
|
}
|
|
740
838
|
console.error(` unsupported platform: ${process.platform}`)
|
|
741
|
-
|
|
839
|
+
peachExit(1)
|
|
742
840
|
}
|
|
743
841
|
|
|
744
842
|
// tail the daemon's logs. macOS reads the launchd-redirected files directly
|
|
@@ -758,7 +856,7 @@ async function daemonLogs(rest: string[]) {
|
|
|
758
856
|
const present = [out, err].filter((p) => existsSync(p))
|
|
759
857
|
if (present.length === 0) {
|
|
760
858
|
console.error(` no daemon logs yet at ${LOG_DIR}. run \`peach daemon install\``)
|
|
761
|
-
|
|
859
|
+
peachExit(1)
|
|
762
860
|
}
|
|
763
861
|
const args = follow
|
|
764
862
|
? ['-n', String(lines), '-F', ...present]
|
|
@@ -798,11 +896,11 @@ async function daemonLogs(rest: string[]) {
|
|
|
798
896
|
` could not read --user journal for ${unit} (this user isn't in the systemd-journal group yet).\n` +
|
|
799
897
|
` run: sudo journalctl _SYSTEMD_USER_UNIT=${unit} -n ${lines} --no-pager`,
|
|
800
898
|
)
|
|
801
|
-
|
|
899
|
+
peachExit(1)
|
|
802
900
|
}
|
|
803
901
|
|
|
804
902
|
console.error(` unsupported platform: ${process.platform}`)
|
|
805
|
-
|
|
903
|
+
peachExit(1)
|
|
806
904
|
}
|
|
807
905
|
|
|
808
906
|
function readPlistBinary(path: string): string | null {
|
package/cli/commands/debug.ts
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
import { DEFAULT_SOOTSIM_BRIDGE_PORT } from '../../src/bridge-constants'
|
|
22
22
|
import { printBridgeFailureDiagnostics } from '../bridge-diagnostics'
|
|
23
|
-
import { rethrowIfExit,
|
|
23
|
+
import { rethrowIfExit, peachExit } from '../run-rnx'
|
|
24
24
|
import {
|
|
25
25
|
createBridgeFromParsed,
|
|
26
26
|
evalInBridge,
|
|
@@ -383,7 +383,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
383
383
|
|
|
384
384
|
if (!subcommand || args.includes('--help') || args.includes('-h')) {
|
|
385
385
|
printHelp()
|
|
386
|
-
|
|
386
|
+
peachExit(0)
|
|
387
387
|
}
|
|
388
388
|
|
|
389
389
|
const wsPort = parsed.wsPort
|
|
@@ -398,7 +398,14 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
398
398
|
// implementation lives in inspect.ts. forward to runInspect with the raw
|
|
399
399
|
// `debug` prefix intact — runInspect strips it. done before we open a
|
|
400
400
|
// debug-side bridge so we don't hold two bridges at once.
|
|
401
|
-
const INSPECT_FORWARDED = new Set([
|
|
401
|
+
const INSPECT_FORWARDED = new Set([
|
|
402
|
+
'state',
|
|
403
|
+
'js',
|
|
404
|
+
'eval',
|
|
405
|
+
'perf',
|
|
406
|
+
'memory',
|
|
407
|
+
'sample-color',
|
|
408
|
+
])
|
|
402
409
|
if (INSPECT_FORWARDED.has(sub)) {
|
|
403
410
|
const { runInspect } = await import('./inspect')
|
|
404
411
|
// pass the raw arg list through so every flag (--sim, --json,
|
|
@@ -422,7 +429,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
422
429
|
console.error(
|
|
423
430
|
` usage: peach debug enable <channel[,channel,...]>\n known: ${KNOWN_CHANNELS.join(', ')}`,
|
|
424
431
|
)
|
|
425
|
-
|
|
432
|
+
peachExit(1)
|
|
426
433
|
}
|
|
427
434
|
const active = await setDebugChannels(
|
|
428
435
|
bridge,
|
|
@@ -450,7 +457,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
450
457
|
const channel = rest[0]
|
|
451
458
|
if (!channel) {
|
|
452
459
|
console.error(' usage: peach debug toggle <channel>')
|
|
453
|
-
|
|
460
|
+
peachExit(1)
|
|
454
461
|
}
|
|
455
462
|
const result = await callDebugBridge(
|
|
456
463
|
bridge,
|
|
@@ -518,7 +525,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
518
525
|
const b = rest[1]
|
|
519
526
|
if (!a || !b) {
|
|
520
527
|
console.error(' usage: peach debug diff <labelA> <labelB>')
|
|
521
|
-
|
|
528
|
+
peachExit(1)
|
|
522
529
|
}
|
|
523
530
|
// Maps don't serialize — project added/removed/changed arrays only
|
|
524
531
|
const result = await callDebugBridge(
|
|
@@ -563,7 +570,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
563
570
|
' zero draws means either nothing on screen is an image, or the audit\n' +
|
|
564
571
|
' is not attached to the surface that paints.',
|
|
565
572
|
)
|
|
566
|
-
|
|
573
|
+
peachExit(2)
|
|
567
574
|
}
|
|
568
575
|
const under = report.rows.filter(
|
|
569
576
|
(row) => row.shortfall !== null && row.shortfall < minimum,
|
|
@@ -573,7 +580,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
573
580
|
} else {
|
|
574
581
|
printImageAudit(report, args.includes('--all') ? report.rows : under, minimum)
|
|
575
582
|
}
|
|
576
|
-
if (under.length > 0)
|
|
583
|
+
if (under.length > 0) peachExit(1)
|
|
577
584
|
break
|
|
578
585
|
}
|
|
579
586
|
|
|
@@ -584,7 +591,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
584
591
|
console.log(fmt(result, pretty))
|
|
585
592
|
} else {
|
|
586
593
|
console.error(' usage: peach debug find <sheets|portals|boundaries>')
|
|
587
|
-
|
|
594
|
+
peachExit(1)
|
|
588
595
|
}
|
|
589
596
|
break
|
|
590
597
|
}
|
|
@@ -602,7 +609,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
602
609
|
console.error(
|
|
603
610
|
' usage: peach debug trace anim <on|off|status|clear|<id>> [id|limit]',
|
|
604
611
|
)
|
|
605
|
-
|
|
612
|
+
peachExit(1)
|
|
606
613
|
}
|
|
607
614
|
if (sub === 'on') {
|
|
608
615
|
const raw = rest[2] ?? 'all'
|
|
@@ -610,7 +617,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
610
617
|
const target: number | 'all' = raw === 'all' ? 'all' : Number(raw)
|
|
611
618
|
if (target !== 'all' && !Number.isFinite(target)) {
|
|
612
619
|
console.error(` invalid target: ${raw}`)
|
|
613
|
-
|
|
620
|
+
peachExit(1)
|
|
614
621
|
}
|
|
615
622
|
await callTestBridge(bridge, 'enableAnimationTrace', target, limit)
|
|
616
623
|
const listed = await callTestBridge(bridge, 'listAnimationTraces')
|
|
@@ -622,7 +629,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
622
629
|
const target: number | 'all' = raw === 'all' ? 'all' : Number(raw)
|
|
623
630
|
if (target !== 'all' && !Number.isFinite(target)) {
|
|
624
631
|
console.error(` invalid target: ${raw}`)
|
|
625
|
-
|
|
632
|
+
peachExit(1)
|
|
626
633
|
}
|
|
627
634
|
await callTestBridge(bridge, 'disableAnimationTrace', target)
|
|
628
635
|
console.log(fmt({ disabled: target }, pretty))
|
|
@@ -639,7 +646,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
639
646
|
const id = Number(sub)
|
|
640
647
|
if (!Number.isFinite(id)) {
|
|
641
648
|
console.error(` invalid id: ${sub}`)
|
|
642
|
-
|
|
649
|
+
peachExit(1)
|
|
643
650
|
}
|
|
644
651
|
const limit = rest[2] ? Number(rest[2]) : undefined
|
|
645
652
|
const samples = await callTestBridge(bridge, 'getAnimationTrace', id, limit)
|
|
@@ -648,7 +655,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
648
655
|
}
|
|
649
656
|
if (traceTarget !== 'shell') {
|
|
650
657
|
console.error(' usage: peach debug trace <shell|anim> [args]')
|
|
651
|
-
|
|
658
|
+
peachExit(1)
|
|
652
659
|
}
|
|
653
660
|
if (!traceCommand || /^[0-9]+$/.test(traceCommand)) {
|
|
654
661
|
const recentLimit = traceCommand ? Number(traceCommand) : 50
|
|
@@ -680,7 +687,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
680
687
|
console.error(
|
|
681
688
|
' usage: peach debug trace shell [on [limit]|off|status|clear|recentLimit]',
|
|
682
689
|
)
|
|
683
|
-
|
|
690
|
+
peachExit(1)
|
|
684
691
|
}
|
|
685
692
|
|
|
686
693
|
case 'record': {
|
|
@@ -717,7 +724,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
717
724
|
default:
|
|
718
725
|
console.error(` unknown subcommand: ${sub}`)
|
|
719
726
|
printHelp()
|
|
720
|
-
|
|
727
|
+
peachExit(1)
|
|
721
728
|
}
|
|
722
729
|
} catch (err: any) {
|
|
723
730
|
rethrowIfExit(err)
|
|
@@ -727,7 +734,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
727
734
|
warningsCommand: `peach get warnings 5${simHint}`,
|
|
728
735
|
requestsCommand: `peach get requests 5${simHint}`,
|
|
729
736
|
})
|
|
730
|
-
|
|
737
|
+
peachExit(1)
|
|
731
738
|
} finally {
|
|
732
739
|
bridge.close()
|
|
733
740
|
}
|
package/cli/commands/desktop.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { runElectron } from './electron'
|
|
2
|
-
import { runInstallDesktop } from './install-desktop'
|
|
2
|
+
import { runInstallDesktop, runUninstallDesktop } from './install-desktop'
|
|
3
3
|
|
|
4
4
|
interface DesktopOptions {
|
|
5
5
|
port?: number
|
|
@@ -13,11 +13,13 @@ peach desktop — launch or install the desktop companion
|
|
|
13
13
|
usage:
|
|
14
14
|
peach desktop [options]
|
|
15
15
|
peach desktop install [options]
|
|
16
|
+
peach desktop uninstall
|
|
16
17
|
|
|
17
18
|
options:
|
|
18
19
|
--port <number> connect to a running dev server on this port
|
|
19
20
|
--profile <id> launch with an isolated persistent storage profile
|
|
20
21
|
--ephemeral launch with a temporary isolated storage profile
|
|
22
|
+
--electron launch Electron on Windows; native app on Mac and Linux
|
|
21
23
|
--native launch (macOS arm64) or install (also Linux x64) the native host
|
|
22
24
|
-y, --yes install without prompting
|
|
23
25
|
`)
|
|
@@ -30,6 +32,10 @@ export async function runDesktop(args: string[], opts: DesktopOptions): Promise<
|
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
const sub = args.find((arg) => !arg.startsWith('-'))
|
|
35
|
+
if (sub === 'uninstall') {
|
|
36
|
+
await runUninstallDesktop(args.filter((arg) => arg !== 'uninstall'))
|
|
37
|
+
return
|
|
38
|
+
}
|
|
33
39
|
if (sub === 'install') {
|
|
34
40
|
const index = args.indexOf(sub)
|
|
35
41
|
await runInstallDesktop([...args.slice(0, index), ...args.slice(index + 1)])
|