peachsim 0.1.631 → 0.1.633
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 +9 -1
- package/cli/commands/maestro.ts +5 -1
- package/cli/commands/test.ts +29 -1
- package/cli/drivers/playwright-core-pin.ts +10 -0
- package/cli/drivers/playwright-provisioning.ts +36 -1
- package/cli/drivers/playwright.ts +26 -19
- package/cli/shell-init.ts +6 -1
- package/cli/ws-bridge.ts +8 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.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 +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +17 -5
- package/dist-lib/cloud-test-args.mjs +17 -5
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +6 -1
- package/dist-lib/host/bridge-host.cjs +48 -47
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +7 -2
- 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 +1 -1
- 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 +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/native-app-identity.cjs +1 -1
- package/dist-lib/native-app-identity.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 +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +136 -83
- package/dist-lib/swift-compile.cjs +1 -1
- package/dist-lib/swift-compile.mjs +1 -1
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift.cjs +9 -8
- package/dist-lib/vite-swift.cjs +1 -1
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/src/cloud-test-args.ts +18 -6
- package/src/home-paths.ts +8 -0
package/dist-lib/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.633 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -4380,7 +4380,7 @@ var init_supported_native_packages = __esm({
|
|
|
4380
4380
|
"@dariyd/react-native-document-scanner",
|
|
4381
4381
|
// seam
|
|
4382
4382
|
"@datadog/mobile-react-native",
|
|
4383
|
-
// coverage
|
|
4383
|
+
// seam+coverage
|
|
4384
4384
|
"@dbkable/react-native-speech-to-text",
|
|
4385
4385
|
// seam
|
|
4386
4386
|
"@dimaportenko/react-native-shadow-view",
|
|
@@ -4551,6 +4551,8 @@ var init_supported_native_packages = __esm({
|
|
|
4551
4551
|
// seam
|
|
4552
4552
|
"@segment/analytics-react-native",
|
|
4553
4553
|
// coverage
|
|
4554
|
+
"@segment/sovran-react-native",
|
|
4555
|
+
// seam
|
|
4554
4556
|
"@sentry/react-native",
|
|
4555
4557
|
// seam+coverage
|
|
4556
4558
|
"@shakebugs/react-native-shake",
|
|
@@ -4658,7 +4660,7 @@ var init_supported_native_packages = __esm({
|
|
|
4658
4660
|
"expo-image",
|
|
4659
4661
|
// visual-proof+seam+coverage
|
|
4660
4662
|
"expo-image-manipulator",
|
|
4661
|
-
// coverage
|
|
4663
|
+
// seam+coverage
|
|
4662
4664
|
"expo-image-picker",
|
|
4663
4665
|
// seam+coverage
|
|
4664
4666
|
"expo-insights",
|
|
@@ -4678,7 +4680,7 @@ var init_supported_native_packages = __esm({
|
|
|
4678
4680
|
"expo-localization",
|
|
4679
4681
|
// coverage
|
|
4680
4682
|
"expo-mail-composer",
|
|
4681
|
-
// semantic-proof
|
|
4683
|
+
// semantic-proof+seam
|
|
4682
4684
|
"expo-maps",
|
|
4683
4685
|
// visual-proof+seam
|
|
4684
4686
|
"expo-media-control",
|
|
@@ -4708,13 +4710,13 @@ var init_supported_native_packages = __esm({
|
|
|
4708
4710
|
"expo-secure-store",
|
|
4709
4711
|
// semantic-proof+coverage
|
|
4710
4712
|
"expo-sensors",
|
|
4711
|
-
// semantic-proof
|
|
4713
|
+
// semantic-proof+seam
|
|
4712
4714
|
"expo-sharing",
|
|
4713
4715
|
// semantic-proof+coverage
|
|
4714
4716
|
"expo-sms",
|
|
4715
4717
|
// semantic-proof
|
|
4716
4718
|
"expo-speech",
|
|
4717
|
-
// semantic-proof
|
|
4719
|
+
// semantic-proof+seam
|
|
4718
4720
|
"expo-speech-recognition",
|
|
4719
4721
|
// seam
|
|
4720
4722
|
"expo-splash-screen",
|
|
@@ -7252,7 +7254,7 @@ var init_registry = __esm({
|
|
|
7252
7254
|
{
|
|
7253
7255
|
range: ">=18.0.0",
|
|
7254
7256
|
coverage: 0.95,
|
|
7255
|
-
note: "upstream @react-native-firebase/crashlytics JS runs unchanged against
|
|
7257
|
+
note: "upstream @react-native-firebase/crashlytics JS runs unchanged against the NativeRNFBTurboCrashlytics (v26) and RNFBCrashlyticsModule native seam; collection reports disabled in a development bundle, as an iOS debug build does without crashlytics_debug_enabled",
|
|
7256
7258
|
working: "default callable export, getCrashlytics, modular helpers, crash, log, recordError, setAttribute, setAttributes, setUserId, collection enablement, unsent report helpers, didCrashOnPreviousExecution",
|
|
7257
7259
|
missing: "native crash capture, report persistence, upload to Firebase Crashlytics"
|
|
7258
7260
|
}
|
|
@@ -7616,9 +7618,9 @@ var init_registry = __esm({
|
|
|
7616
7618
|
{
|
|
7617
7619
|
range: ">=13.0.0",
|
|
7618
7620
|
coverage: 0.85,
|
|
7619
|
-
note: "
|
|
7620
|
-
working: "upstream DeviceSensor/Pedometer wrappers, listener bookkeeping, update intervals, permissions,
|
|
7621
|
-
missing: "
|
|
7621
|
+
note: "upstream expo-sensors JS runs unchanged over native modules that follow ios/*Module.swift on the reference iOS Simulator, where CoreMotion reports every sensor unavailable and delivers no samples",
|
|
7622
|
+
working: "upstream DeviceSensor/Pedometer wrappers, listener bookkeeping, update intervals, motion permissions, Gravity constant, isAvailableAsync false for every sensor as on the simulator, getStepCountAsync rejecting with ERR_PEDOMETER_QUERY",
|
|
7623
|
+
missing: "sensor samples: the simulator has no motion hardware, so a physical-device stream is out of scope"
|
|
7622
7624
|
}
|
|
7623
7625
|
]
|
|
7624
7626
|
},
|
|
@@ -7669,9 +7671,9 @@ var init_registry = __esm({
|
|
|
7669
7671
|
{
|
|
7670
7672
|
range: ">=13.0.0",
|
|
7671
7673
|
coverage: 0.93,
|
|
7672
|
-
note: "native-seam only. real expo-av package runs from the bundle (Audio.Sound + Audio.Recording classes, AVPlaybackStatus shape, PitchCorrectionQuality enum, RecordingOptionsPresets, Video component).
|
|
7673
|
-
working: "Audio.Sound (createAsync/loadAsync/unloadAsync/play/pause/stop/seek/setRate/setVolume/setMuted/setLooping/setProgressUpdateInterval/setOnPlaybackStatusUpdate via element-keyed seam), Audio.Recording (prepareToRecordAsync/startAsync/pauseAsync/stopAndUnloadAsync/getStatusAsync/getURI via singleton MediaRecorder), Video ref API (playAsync/pauseAsync/setPositionAsync/setStatusAsync/setRate/setVolume/setIsMuted/setIsLooping), real getUserMedia permission probe with PermissionStatus reflection, didUpdatePlaybackStatus + ExponentAV.onError events via DeviceEventEmitter, RecordingOptionsPresets, PitchCorrectionQuality enum (Low/Medium/High), ResizeMode",
|
|
7674
|
-
missing: "setAudioModeAsync is noop (no browser equivalent for AVAudioSession), audio metering/analyzer data absent (would need AnalyserNode), Video fullscreen
|
|
7674
|
+
note: "native-seam only. real expo-av package runs from the bundle (Audio.Sound + Audio.Recording classes, AVPlaybackStatus shape, PitchCorrectionQuality enum, RecordingOptionsPresets, Video component). audio: the ExponentAV native module keeps the web-ported element-keyed sound and recorder methods. video: the ExpoVideoView module and view follow ios/EXAV/Video (tag-addressed loadForVideo/setStatusForVideo/replayVideo/getStatusForVideo, the EXAVPlayerData status dictionary, onLoadStart/onLoad/onReadyForDisplay/onStatusUpdate/onError) over the shared video channel.",
|
|
7675
|
+
working: "Audio.Sound (createAsync/loadAsync/unloadAsync/play/pause/stop/seek/setRate/setVolume/setMuted/setLooping/setProgressUpdateInterval/setOnPlaybackStatusUpdate via element-keyed seam), Audio.Recording (prepareToRecordAsync/startAsync/pauseAsync/stopAndUnloadAsync/getStatusAsync/getURI via singleton MediaRecorder), Video component playback of bundled and remote sources with the ref API (loadAsync/unloadAsync/playAsync/pauseAsync/setPositionAsync/setStatusAsync/replayAsync/setRate/setVolume/setIsMuted/setIsLooping) and its events, real getUserMedia permission probe with PermissionStatus reflection, didUpdatePlaybackStatus + ExponentAV.onError events via DeviceEventEmitter, RecordingOptionsPresets, PitchCorrectionQuality enum (Low/Medium/High), ResizeMode",
|
|
7676
|
+
missing: "setAudioModeAsync is noop (no browser equivalent for AVAudioSession), audio metering/analyzer data absent (would need AnalyserNode), Video fullscreen rejects (no system AVPlayerViewController) and useNativeControls draws no controls, sound keys are elements where iOS uses numbers, shouldDuckAndroid / playThroughEarpieceAndroid ignored"
|
|
7675
7677
|
}
|
|
7676
7678
|
]
|
|
7677
7679
|
},
|
|
@@ -8038,7 +8040,7 @@ var init_registry = __esm({
|
|
|
8038
8040
|
coverage: 0.85,
|
|
8039
8041
|
note: "upstream expo-mail-composer JS runs unchanged; package-local wrapper only registers the ExpoMailComposer native module with clean unavailable simulator state.",
|
|
8040
8042
|
working: "isAvailableAsync, getClients, composeAsync, MailComposerStatus enum, and types through upstream MailComposer.ts/MailComposer.types; simulator state reports unavailable with no installed mail clients",
|
|
8041
|
-
missing: "cannot present native MFMailComposeViewController or query installed mail apps from the worker; composeAsync rejects
|
|
8043
|
+
missing: "cannot present native MFMailComposeViewController or query installed mail apps from the worker; composeAsync rejects with ERR_CANNOT_SEND_MAIL, matching iOS simulator behavior"
|
|
8042
8044
|
}
|
|
8043
8045
|
]
|
|
8044
8046
|
},
|
|
@@ -8117,9 +8119,9 @@ var init_registry = __esm({
|
|
|
8117
8119
|
{
|
|
8118
8120
|
range: ">=11.0.0",
|
|
8119
8121
|
coverage: 0.93,
|
|
8120
|
-
note: "real
|
|
8121
|
-
working: "manipulateAsync
|
|
8122
|
-
missing: "
|
|
8122
|
+
note: "the real package JS runs over an ExpoImageManipulator native seam that follows ios/ImageManipulatorModule.swift: manipulate takes a url or an image ref, the Context chains resize/rotate/flip/crop/reset onto one render task, and Image.saveAsync encodes and writes Caches/ImageManipulator/<UUID>.<ext>. Pixels go through OffscreenCanvas with the transformers sizing rules (resize rounds up at scale 1, rotate floors the rotated bounds, crop rejects out-of-range rects and clips the integral rect). iOS has no extent, so upstream skips it as on device.",
|
|
8123
|
+
working: "manipulateAsync and ImageManipulator.manipulate over data, file and http urls and expo-image refs, useImageManipulator, Context resize/rotate/flip/crop/reset/renderAsync, Image width/height/saveAsync with jpeg/png/webp, compress and base64, native exception codes and messages",
|
|
8124
|
+
missing: "ph:// and assets-library:// photo library sources reject as not found, decoding uses the browser codecs (webp output depends on the browser encoder), and EXIF orientation is applied at decode again after reset"
|
|
8123
8125
|
}
|
|
8124
8126
|
]
|
|
8125
8127
|
},
|
|
@@ -8144,8 +8146,9 @@ var init_registry = __esm({
|
|
|
8144
8146
|
{
|
|
8145
8147
|
range: ">=1.0.0",
|
|
8146
8148
|
coverage: 0.95,
|
|
8147
|
-
note: "
|
|
8148
|
-
|
|
8149
|
+
note: "the published JS runs unchanged over DdSdk, DdRum, DdLogs, DdTrace and DdFlags native seams from src/specs; each call settles as ios/Sources/*Implementation.swift does, with no Datadog SDK behind it",
|
|
8150
|
+
working: "DdSdkReactNative and DatadogProvider initialization, CoreConfiguration and every exported class and enum, DdRum views/actions/resources/errors/timings/attributes, DdLogs, DdTrace spans with UUID ids, user and account info, tracking consent, the fetch/XHR/error/navigation instrumentation",
|
|
8151
|
+
missing: "no events are recorded or uploaded, getCurrentSessionId resolves null because no RUM session runs, and DdFlags never receives a flags snapshot"
|
|
8149
8152
|
}
|
|
8150
8153
|
]
|
|
8151
8154
|
},
|
|
@@ -8902,9 +8905,9 @@ var init_registry = __esm({
|
|
|
8902
8905
|
{
|
|
8903
8906
|
range: ">=1.0.0",
|
|
8904
8907
|
coverage: 0.85,
|
|
8905
|
-
note: "JS store runs unmodified
|
|
8906
|
-
working: "createStore, dispatch/getState/subscribe queue, registerBridgeStore, AsyncStorage persistor through async-storage stub",
|
|
8907
|
-
missing: "
|
|
8908
|
+
note: "JS store runs unmodified over a Sovran native seam that follows ios/Sovran.swift: ON_STORE_ACTION constant and the RCTEventEmitter listener contract",
|
|
8909
|
+
working: "createStore, dispatch/getState/subscribe queue, registerBridgeStore, the native bridge listener, AsyncStorage persistor through async-storage stub",
|
|
8910
|
+
missing: "store actions dispatched from other native SDK code, since a simulated app runs none"
|
|
8908
8911
|
}
|
|
8909
8912
|
]
|
|
8910
8913
|
},
|
|
@@ -20487,6 +20490,7 @@ __export(home_paths_exports, {
|
|
|
20487
20490
|
isDevWorkstation: () => isDevWorkstation,
|
|
20488
20491
|
isOnboardingComplete: () => isOnboardingComplete,
|
|
20489
20492
|
isSootsimDevCheckout: () => isSootsimDevCheckout,
|
|
20493
|
+
playwrightCoreDir: () => playwrightCoreDir,
|
|
20490
20494
|
profilesDir: () => profilesDir,
|
|
20491
20495
|
readActiveRuntime: () => readActiveRuntime,
|
|
20492
20496
|
readDaemonLockfile: () => readDaemonLockfile,
|
|
@@ -20557,6 +20561,9 @@ function electronUserDataDir() {
|
|
|
20557
20561
|
function electronVersionDir(version) {
|
|
20558
20562
|
return import_node_path4.default.join(electronDir(), version);
|
|
20559
20563
|
}
|
|
20564
|
+
function playwrightCoreDir(version) {
|
|
20565
|
+
return import_node_path4.default.join(rnxHomeDir(), "playwright-core", version);
|
|
20566
|
+
}
|
|
20560
20567
|
function profilesDir() {
|
|
20561
20568
|
return import_node_path4.default.join(rnxHomeDir(), "profiles");
|
|
20562
20569
|
}
|
|
@@ -21215,48 +21222,16 @@ function createRuntimeDelivery(product) {
|
|
|
21215
21222
|
manifest
|
|
21216
21223
|
};
|
|
21217
21224
|
}
|
|
21218
|
-
|
|
21219
|
-
|
|
21220
|
-
import_node_path7.default.join(import_node_os2.default.tmpdir(), `${product.id}-runtime-download-`)
|
|
21221
|
-
);
|
|
21222
|
-
const runtimeArchivePath = import_node_path7.default.join(
|
|
21223
|
-
downloadDir,
|
|
21224
|
-
runtimeTarballCacheName(product, version)
|
|
21225
|
-
);
|
|
21226
|
-
const tmpDir = import_node_path7.default.join(
|
|
21227
|
-
import_node_path7.default.dirname(destDir),
|
|
21228
|
-
`.installing-${version}-${process.pid}`
|
|
21229
|
-
);
|
|
21230
|
-
import_node_fs7.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
21231
|
-
try {
|
|
21232
|
-
if (!opts.quiet)
|
|
21233
|
-
process.stderr.write(`${product.id}: downloading runtime ${version}\u2026
|
|
21225
|
+
if (!opts.quiet)
|
|
21226
|
+
process.stderr.write(`${product.id}: downloading runtime ${version}\u2026
|
|
21234
21227
|
`);
|
|
21235
|
-
|
|
21236
|
-
|
|
21237
|
-
|
|
21238
|
-
|
|
21239
|
-
|
|
21240
|
-
|
|
21241
|
-
|
|
21242
|
-
`sha256 mismatch for runtime ${version}: expected ${entry.sha256}, actual ${actualSha}`
|
|
21243
|
-
);
|
|
21244
|
-
}
|
|
21245
|
-
import_node_fs7.default.mkdirSync(tmpDir, { recursive: true });
|
|
21246
|
-
await extractTarball(runtimeArchivePath, tmpDir);
|
|
21247
|
-
if (!import_node_fs7.default.existsSync(import_node_path7.default.join(tmpDir, product.installedMarker))) {
|
|
21248
|
-
throw new Error(
|
|
21249
|
-
`extracted tarball for runtime ${version} is missing ${product.installedMarker}`
|
|
21250
|
-
);
|
|
21251
|
-
}
|
|
21252
|
-
import_node_fs7.default.rmSync(destDir, { recursive: true, force: true });
|
|
21253
|
-
import_node_fs7.default.renameSync(tmpDir, destDir);
|
|
21254
|
-
} catch (err) {
|
|
21255
|
-
import_node_fs7.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
21256
|
-
throw err;
|
|
21257
|
-
} finally {
|
|
21258
|
-
import_node_fs7.default.rmSync(downloadDir, { recursive: true, force: true });
|
|
21259
|
-
}
|
|
21228
|
+
await installVerifiedTarball({
|
|
21229
|
+
url: entry.tarball || tarballUrl(version, cdnOrigin),
|
|
21230
|
+
digest: { algorithm: "sha256", encoding: "hex", value: entry.sha256 },
|
|
21231
|
+
destDir,
|
|
21232
|
+
installedMarker: product.installedMarker,
|
|
21233
|
+
label: `runtime ${version}`
|
|
21234
|
+
});
|
|
21260
21235
|
if (setActive) product.writeActiveRuntime(version);
|
|
21261
21236
|
pruneLocalRetention({ protectVersions });
|
|
21262
21237
|
return {
|
|
@@ -21446,6 +21421,37 @@ function createRuntimeDelivery(product) {
|
|
|
21446
21421
|
listInstalled: () => listInstalledRuntimes(product)
|
|
21447
21422
|
};
|
|
21448
21423
|
}
|
|
21424
|
+
async function installVerifiedTarball(tarball) {
|
|
21425
|
+
const { url, digest, destDir, installedMarker, label } = tarball;
|
|
21426
|
+
const downloadDir = import_node_fs7.default.mkdtempSync(import_node_path7.default.join(import_node_os2.default.tmpdir(), "runtime-delivery-download-"));
|
|
21427
|
+
const archivePath = import_node_path7.default.join(downloadDir, "archive.tar.gz");
|
|
21428
|
+
const tmpDir = import_node_path7.default.join(
|
|
21429
|
+
import_node_path7.default.dirname(destDir),
|
|
21430
|
+
`.installing-${import_node_path7.default.basename(destDir)}-${process.pid}`
|
|
21431
|
+
);
|
|
21432
|
+
import_node_fs7.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
21433
|
+
try {
|
|
21434
|
+
await downloadToFile(url, archivePath);
|
|
21435
|
+
const actual = await digestFile(archivePath, digest.algorithm, digest.encoding);
|
|
21436
|
+
if (actual !== digest.value) {
|
|
21437
|
+
throw new Error(
|
|
21438
|
+
`${digest.algorithm} mismatch for ${label}: expected ${digest.value}, actual ${actual}`
|
|
21439
|
+
);
|
|
21440
|
+
}
|
|
21441
|
+
import_node_fs7.default.mkdirSync(tmpDir, { recursive: true });
|
|
21442
|
+
await extractTarball(archivePath, tmpDir, tarball.stripComponents ?? 0);
|
|
21443
|
+
if (!import_node_fs7.default.existsSync(import_node_path7.default.join(tmpDir, installedMarker))) {
|
|
21444
|
+
throw new Error(`extracted tarball for ${label} is missing ${installedMarker}`);
|
|
21445
|
+
}
|
|
21446
|
+
import_node_fs7.default.rmSync(destDir, { recursive: true, force: true });
|
|
21447
|
+
import_node_fs7.default.renameSync(tmpDir, destDir);
|
|
21448
|
+
} catch (err) {
|
|
21449
|
+
import_node_fs7.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
21450
|
+
throw err;
|
|
21451
|
+
} finally {
|
|
21452
|
+
import_node_fs7.default.rmSync(downloadDir, { recursive: true, force: true });
|
|
21453
|
+
}
|
|
21454
|
+
}
|
|
21449
21455
|
async function downloadToFile(url, destPath) {
|
|
21450
21456
|
const res = await fetch(url);
|
|
21451
21457
|
if (!res.ok || !res.body) {
|
|
@@ -21467,18 +21473,20 @@ async function downloadToFile(url, destPath) {
|
|
|
21467
21473
|
throw err;
|
|
21468
21474
|
}
|
|
21469
21475
|
}
|
|
21470
|
-
function
|
|
21476
|
+
function digestFile(filePath, algorithm, encoding) {
|
|
21471
21477
|
return new Promise((resolve9, reject) => {
|
|
21472
|
-
const hash = import_node_crypto2.default.createHash(
|
|
21478
|
+
const hash = import_node_crypto2.default.createHash(algorithm);
|
|
21473
21479
|
const stream = import_node_fs7.default.createReadStream(filePath);
|
|
21474
21480
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
21475
21481
|
stream.on("error", reject);
|
|
21476
|
-
stream.on("end", () => resolve9(hash.digest(
|
|
21482
|
+
stream.on("end", () => resolve9(hash.digest(encoding)));
|
|
21477
21483
|
});
|
|
21478
21484
|
}
|
|
21479
|
-
function extractTarball(tarPath, destDir) {
|
|
21485
|
+
function extractTarball(tarPath, destDir, stripComponents) {
|
|
21480
21486
|
return new Promise((resolve9, reject) => {
|
|
21481
|
-
const
|
|
21487
|
+
const args = ["-xzf", tarPath, "-C", destDir];
|
|
21488
|
+
if (stripComponents > 0) args.push(`--strip-components=${stripComponents}`);
|
|
21489
|
+
const child = (0, import_node_child_process3.spawn)("tar", args, {
|
|
21482
21490
|
stdio: ["ignore", "inherit", "inherit"]
|
|
21483
21491
|
});
|
|
21484
21492
|
child.on("error", reject);
|
|
@@ -31690,7 +31698,12 @@ function createBridge(wsPort, opts = {}) {
|
|
|
31690
31698
|
});
|
|
31691
31699
|
ws.on("error", (err) => {
|
|
31692
31700
|
const cause = err.message ? `: ${err.message}` : "";
|
|
31693
|
-
reject(
|
|
31701
|
+
reject(
|
|
31702
|
+
new Error(
|
|
31703
|
+
`could not connect to ${bridgeWsUrl(wsPort)}${cause}
|
|
31704
|
+
for sandboxed or agent runners, keep \`peach serve --port ${wsPort}\` running in a persistent terminal or background task.`
|
|
31705
|
+
)
|
|
31706
|
+
);
|
|
31694
31707
|
});
|
|
31695
31708
|
});
|
|
31696
31709
|
ready.catch(() => {
|
|
@@ -34132,11 +34145,24 @@ var init_internal_child = __esm({
|
|
|
34132
34145
|
}
|
|
34133
34146
|
});
|
|
34134
34147
|
|
|
34148
|
+
// cli/drivers/playwright-core-pin.ts
|
|
34149
|
+
var PINNED_PLAYWRIGHT_CORE;
|
|
34150
|
+
var init_playwright_core_pin = __esm({
|
|
34151
|
+
"cli/drivers/playwright-core-pin.ts"() {
|
|
34152
|
+
"use strict";
|
|
34153
|
+
PINNED_PLAYWRIGHT_CORE = {
|
|
34154
|
+
version: "1.61.0",
|
|
34155
|
+
integrity: "sha512-caX7TrY3Ml6egyDX0WUcTHDxodl/b51y5wJOdCEA36QviK/s2g081hvmGs8eaE3DWb6NYZQ6BjO/QkNRPenoPA=="
|
|
34156
|
+
};
|
|
34157
|
+
}
|
|
34158
|
+
});
|
|
34159
|
+
|
|
34135
34160
|
// cli/drivers/playwright-provisioning.ts
|
|
34136
34161
|
function resolvePlaywright() {
|
|
34137
34162
|
const roots = [`${process.cwd()}/`];
|
|
34138
34163
|
const self = rnxSelfInvocation();
|
|
34139
34164
|
roots.push(self.prefixArgs[0] ?? self.executable);
|
|
34165
|
+
roots.push(`${playwrightCoreDir(PINNED_PLAYWRIGHT_CORE.version)}/`);
|
|
34140
34166
|
for (const root of roots) {
|
|
34141
34167
|
try {
|
|
34142
34168
|
const requireFromRoot = (0, import_node_module5.createRequire)(root);
|
|
@@ -34172,6 +34198,33 @@ function resolvePlaywright() {
|
|
|
34172
34198
|
}
|
|
34173
34199
|
return null;
|
|
34174
34200
|
}
|
|
34201
|
+
async function provisionPlaywright() {
|
|
34202
|
+
const existing = resolvePlaywright();
|
|
34203
|
+
if (existing) return existing;
|
|
34204
|
+
const { version, integrity } = PINNED_PLAYWRIGHT_CORE;
|
|
34205
|
+
const [algorithm, digest] = integrity.split("-", 2);
|
|
34206
|
+
if (algorithm !== "sha512" || !digest) {
|
|
34207
|
+
throw new Error(`pinned playwright-core integrity is not sha512: ${integrity}`);
|
|
34208
|
+
}
|
|
34209
|
+
process.stderr.write(`peach: installing playwright-core ${version}\u2026
|
|
34210
|
+
`);
|
|
34211
|
+
await installVerifiedTarball({
|
|
34212
|
+
url: `https://registry.npmjs.org/playwright-core/-/playwright-core-${version}.tgz`,
|
|
34213
|
+
digest: { algorithm, encoding: "base64", value: digest },
|
|
34214
|
+
destDir: (0, import_node_path25.join)(playwrightCoreDir(version), "node_modules", "playwright-core"),
|
|
34215
|
+
installedMarker: "package.json",
|
|
34216
|
+
// npm tarballs hold the package under a leading `package/`
|
|
34217
|
+
stripComponents: 1,
|
|
34218
|
+
label: `playwright-core ${version}`
|
|
34219
|
+
});
|
|
34220
|
+
const installed2 = resolvePlaywright();
|
|
34221
|
+
if (!installed2) {
|
|
34222
|
+
throw new Error(
|
|
34223
|
+
`playwright-core ${version} installed to ${playwrightCoreDir(version)} but does not resolve`
|
|
34224
|
+
);
|
|
34225
|
+
}
|
|
34226
|
+
return installed2;
|
|
34227
|
+
}
|
|
34175
34228
|
function probeBrowser(resolved, env) {
|
|
34176
34229
|
const self = rnxSelfInvocation();
|
|
34177
34230
|
const probe3 = (0, import_node_child_process6.spawnSync)(
|
|
@@ -34260,25 +34313,22 @@ var init_playwright_provisioning = __esm({
|
|
|
34260
34313
|
import_node_fs23 = require("node:fs");
|
|
34261
34314
|
import_node_module5 = require("node:module");
|
|
34262
34315
|
import_node_path25 = require("node:path");
|
|
34316
|
+
init_src();
|
|
34317
|
+
init_home_paths();
|
|
34263
34318
|
init_is_record();
|
|
34264
34319
|
init_internal_child();
|
|
34265
34320
|
init_self_invocation();
|
|
34321
|
+
init_playwright_core_pin();
|
|
34266
34322
|
}
|
|
34267
34323
|
});
|
|
34268
34324
|
|
|
34269
34325
|
// cli/drivers/playwright.ts
|
|
34270
34326
|
function probe2() {
|
|
34271
34327
|
const resolved = resolvePlaywright();
|
|
34272
|
-
if (!resolved) {
|
|
34273
|
-
return {
|
|
34274
|
-
available: false,
|
|
34275
|
-
reason: "playwright not installed in the current workspace"
|
|
34276
|
-
};
|
|
34277
|
-
}
|
|
34278
34328
|
return {
|
|
34279
34329
|
available: true,
|
|
34280
34330
|
reason: null,
|
|
34281
|
-
detail: `resolved via ${resolved.spec}@${resolved.version}`
|
|
34331
|
+
detail: resolved ? `resolved via ${resolved.spec}@${resolved.version}` : `installs playwright-core@${PINNED_PLAYWRIGHT_CORE.version} on first launch`
|
|
34282
34332
|
};
|
|
34283
34333
|
}
|
|
34284
34334
|
function headlessHintForLinuxFailure(opts, detail) {
|
|
@@ -34300,13 +34350,6 @@ function resolveUserDataDir(opts) {
|
|
|
34300
34350
|
return "";
|
|
34301
34351
|
}
|
|
34302
34352
|
async function launch2(opts) {
|
|
34303
|
-
const resolved = resolvePlaywright();
|
|
34304
|
-
if (!resolved) {
|
|
34305
|
-
return {
|
|
34306
|
-
launched: false,
|
|
34307
|
-
message: "playwright not installed \u2014 run `bun add -D playwright` first"
|
|
34308
|
-
};
|
|
34309
|
-
}
|
|
34310
34353
|
if (!opts.url) {
|
|
34311
34354
|
return { launched: false, message: "playwright driver requires a target url" };
|
|
34312
34355
|
}
|
|
@@ -34317,6 +34360,15 @@ async function launch2(opts) {
|
|
|
34317
34360
|
message: "playwright driver requires a valid owning session process"
|
|
34318
34361
|
};
|
|
34319
34362
|
}
|
|
34363
|
+
let resolved;
|
|
34364
|
+
try {
|
|
34365
|
+
resolved = await provisionPlaywright();
|
|
34366
|
+
} catch (error) {
|
|
34367
|
+
return {
|
|
34368
|
+
launched: false,
|
|
34369
|
+
message: `playwright provisioning failed: ${error instanceof Error ? error.message : String(error)}`
|
|
34370
|
+
};
|
|
34371
|
+
}
|
|
34320
34372
|
const playwrightEnv = { ...process.env };
|
|
34321
34373
|
const provisioning = ensurePlaywrightBrowser(resolved, playwrightEnv);
|
|
34322
34374
|
if (!provisioning.ok) {
|
|
@@ -34407,6 +34459,7 @@ var init_playwright = __esm({
|
|
|
34407
34459
|
init_internal_child();
|
|
34408
34460
|
init_parent_pid();
|
|
34409
34461
|
init_self_invocation();
|
|
34462
|
+
init_playwright_core_pin();
|
|
34410
34463
|
init_playwright_provisioning();
|
|
34411
34464
|
playwrightDriver = {
|
|
34412
34465
|
id: "playwright",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.633 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.633 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.633 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/swift.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.633 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -7388,6 +7388,9 @@ var LANGUAGE_FONT_SUBSETS = [
|
|
|
7388
7388
|
}
|
|
7389
7389
|
];
|
|
7390
7390
|
|
|
7391
|
+
// ../peach-engine/src/engine/generated/sf-pro-font.ts
|
|
7392
|
+
var SF_PRO_FONT_URL = "/fonts/sf-pro.ttf?sha256=ba43865c3955d7d30888927bfdfef2476c932f9b930b5ad6adb50c33ac6a8de0";
|
|
7393
|
+
|
|
7391
7394
|
// ../peach-engine/src/engine/font-config.ts
|
|
7392
7395
|
var DEFAULT_FONT_FAMILY = "SF Pro";
|
|
7393
7396
|
var SF_PRO_VARIANT_FONT_FAMILY = "SF Pro Variant";
|
|
@@ -7414,7 +7417,7 @@ function normalizeFontWeight(fontWeight) {
|
|
|
7414
7417
|
}
|
|
7415
7418
|
return 400;
|
|
7416
7419
|
}
|
|
7417
|
-
var BASE_FONT_URLS = [
|
|
7420
|
+
var BASE_FONT_URLS = [SF_PRO_FONT_URL];
|
|
7418
7421
|
var BOOT_FONT_URLS = [...BASE_FONT_URLS];
|
|
7419
7422
|
function activePlatform() {
|
|
7420
7423
|
return peekDeviceSpec()?.platform ?? "ios";
|
|
@@ -9424,15 +9427,13 @@ function resetTextureLayerFlattenState(state5) {
|
|
|
9424
9427
|
}
|
|
9425
9428
|
function releaseRasterImage(chunk) {
|
|
9426
9429
|
if (chunk.kind !== "picture") return;
|
|
9427
|
-
if (chunk.
|
|
9430
|
+
if (chunk.rasterImageHandle) {
|
|
9428
9431
|
LIVE.rasterImages--;
|
|
9429
9432
|
LIVE.rasterBytes -= chunk.rasterWidth * chunk.rasterHeight * 4;
|
|
9430
|
-
|
|
9431
|
-
chunk.rasterImage.delete();
|
|
9432
|
-
} catch {
|
|
9433
|
-
}
|
|
9433
|
+
chunk.rasterNative?._peach_raster_release(chunk.rasterImageHandle);
|
|
9434
9434
|
}
|
|
9435
|
-
chunk.
|
|
9435
|
+
chunk.rasterImageHandle = 0;
|
|
9436
|
+
chunk.rasterNative = null;
|
|
9436
9437
|
chunk.rasterWidth = 0;
|
|
9437
9438
|
chunk.rasterHeight = 0;
|
|
9438
9439
|
chunk.rasterDpr = 0;
|
package/dist-lib/vite-swift.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.633 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.633 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/package.json
CHANGED
package/src/cloud-test-args.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
// hosted `
|
|
1
|
+
// hosted `peach test` selection and explicit environment arguments: the argv slice a cloud submitter
|
|
2
2
|
// forwards and the recorder appends verbatim to its executor invocation.
|
|
3
3
|
//
|
|
4
|
-
//
|
|
5
|
-
// about HOW they run (workers, timeouts, shards, devices
|
|
4
|
+
// the flags below choose tests and provide explicit flow variables. everything
|
|
5
|
+
// about HOW they run (workers, timeouts, shards, devices)
|
|
6
6
|
// stays with the recorder that owns the execution environment, and
|
|
7
7
|
// everything about WHERE they run (app, origin, tunnel) is consumed by
|
|
8
8
|
// the submitter. a flag outside this list never reaches the executor:
|
|
@@ -22,6 +22,8 @@ export const CLOUD_TEST_VALUE_FLAGS: readonly string[] = [
|
|
|
22
22
|
'--include-tags',
|
|
23
23
|
'--exclude-tags',
|
|
24
24
|
'--grep',
|
|
25
|
+
'--env',
|
|
26
|
+
'-e',
|
|
25
27
|
]
|
|
26
28
|
|
|
27
29
|
const CLOUD_TEST_VALUE_FLAG_SET = new Set<string>(CLOUD_TEST_VALUE_FLAGS)
|
|
@@ -57,7 +59,7 @@ export function parseCloudTestArgs(value: unknown): CloudTestArgsVerdict {
|
|
|
57
59
|
return { ok: false, message: 'testArgs entries must be non-empty strings' }
|
|
58
60
|
}
|
|
59
61
|
if (entry.length > CLOUD_TEST_ARG_MAX_LENGTH || entry.includes('\0')) {
|
|
60
|
-
return { ok: false, message:
|
|
62
|
+
return { ok: false, message: 'testArgs entry is too long or carries a NUL byte' }
|
|
61
63
|
}
|
|
62
64
|
bytes += encoder.encode(entry).length
|
|
63
65
|
if (bytes > CLOUD_TEST_ARGS_MAX_BYTES) {
|
|
@@ -80,12 +82,19 @@ export function parseCloudTestArgs(value: unknown): CloudTestArgsVerdict {
|
|
|
80
82
|
const eq = entry.indexOf('=')
|
|
81
83
|
const head = eq > 0 ? entry.slice(0, eq) : entry
|
|
82
84
|
if (!isCloudTestValueFlag(head)) {
|
|
83
|
-
return {
|
|
85
|
+
return {
|
|
86
|
+
ok: false,
|
|
87
|
+
message: `testArgs carries an unknown flag: ${head.slice(0, 60)}`,
|
|
88
|
+
}
|
|
84
89
|
}
|
|
85
90
|
if (eq > 0) {
|
|
86
|
-
|
|
91
|
+
const value = entry.slice(eq + 1)
|
|
92
|
+
if (!value) {
|
|
87
93
|
return { ok: false, message: `${head} expects a value` }
|
|
88
94
|
}
|
|
95
|
+
if ((head === '--env' || head === '-e') && value.indexOf('=') < 1) {
|
|
96
|
+
return { ok: false, message: `${head} expects KEY=VALUE with a non-empty key` }
|
|
97
|
+
}
|
|
89
98
|
args.push(entry)
|
|
90
99
|
continue
|
|
91
100
|
}
|
|
@@ -93,6 +102,9 @@ export function parseCloudTestArgs(value: unknown): CloudTestArgsVerdict {
|
|
|
93
102
|
if (val === undefined || val.startsWith('-')) {
|
|
94
103
|
return { ok: false, message: `${head} expects a value` }
|
|
95
104
|
}
|
|
105
|
+
if ((head === '--env' || head === '-e') && val.indexOf('=') < 1) {
|
|
106
|
+
return { ok: false, message: `${head} expects KEY=VALUE with a non-empty key` }
|
|
107
|
+
}
|
|
96
108
|
args.push(entry, val)
|
|
97
109
|
i += 1
|
|
98
110
|
}
|
package/src/home-paths.ts
CHANGED
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
// │ alternative to a symlink)
|
|
10
10
|
// ├── electron/
|
|
11
11
|
// │ └── <version>/ pinned electron binary (future: playwright-style)
|
|
12
|
+
// ├── playwright-core/
|
|
13
|
+
// │ └── <version>/node_modules/playwright-core
|
|
14
|
+
// │ the pinned package, provisioned on first need when
|
|
15
|
+
// │ neither the app nor the CLI's install tree has one
|
|
12
16
|
// ├── profiles/
|
|
13
17
|
// │ └── profiles.json storage profile metadata
|
|
14
18
|
// ├── cache/
|
|
@@ -126,6 +130,10 @@ export function electronVersionDir(version: string): string {
|
|
|
126
130
|
return path.join(electronDir(), version)
|
|
127
131
|
}
|
|
128
132
|
|
|
133
|
+
export function playwrightCoreDir(version: string): string {
|
|
134
|
+
return path.join(rnxHomeDir(), 'playwright-core', version)
|
|
135
|
+
}
|
|
136
|
+
|
|
129
137
|
export function profilesDir(): string {
|
|
130
138
|
return path.join(rnxHomeDir(), 'profiles')
|
|
131
139
|
}
|