peachsim 0.1.628 → 0.1.630
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 +8 -4
- package/cli/bridge-flow-runner.ts +10 -3
- package/cli/cli-update.ts +2 -7
- package/cli/cloud-test-tunnel.ts +16 -3
- package/cli/commands/config.ts +1 -1
- package/cli/commands/control.ts +28 -3
- package/cli/commands/daemon-mac-app.ts +4 -2
- package/cli/commands/daemon.ts +4 -4
- package/cli/commands/device.ts +2 -3
- package/cli/commands/inspect/actions.ts +125 -90
- package/cli/commands/inspect/core.ts +5 -0
- package/cli/commands/inspect.ts +27 -13
- package/cli/commands/platform.ts +1 -1
- package/cli/commands/screenshot-layers.ts +1 -1
- package/cli/commands/screenshot.ts +1 -1
- package/cli/commands/skills.ts +0 -31
- package/cli/drivers/playwright-provisioning.ts +3 -2
- package/cli/drivers/playwright-sim-host.ts +25 -9
- package/cli/main.ts +8 -2
- package/cli/outbound-endpoints.ts +0 -4
- package/detox/index.ts +74 -43
- 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 +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- 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 +129 -27
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +290 -315
- 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 +253 -121
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/{vite-kotlin.cjs → kotlin-host.cjs} +130 -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 +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +132 -9
- package/dist-lib/native-app-identity.cjs +278 -0
- package/dist-lib/native-app-identity.mjs +245 -0
- 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 +110 -87
- package/dist-lib/sdk.mjs +110 -87
- package/dist-lib/skills.cjs +841 -643
- 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 +282 -177
- package/dist-lib/vite-swift.cjs +1 -1
- package/dist-lib/vite.cjs +11 -28
- package/kotlin/README.md +32 -4
- package/kotlin/fixtures/counter/Counter.kt +26 -0
- package/kotlin/fixtures/counter/CounterScreen.kt +40 -0
- package/kotlin/fixtures/headless-counter/Headless.kt +228 -0
- package/kotlin/fixtures/runtime-state/RuntimeState.kt +200 -0
- package/kotlin/fork/LICENSE +178 -0
- package/kotlin/fork/NOTICE +25 -0
- package/kotlin/fork/README.md +59 -0
- package/kotlin/fork/build.sh +128 -0
- package/kotlin/fork/compose-worker-globals.patch +96 -0
- package/kotlin/fork/fork.json +33 -0
- package/kotlin/fork/publish.ts +77 -0
- package/kotlin/fork/skiko-worker-clock.patch +33 -0
- package/kotlin/toolchain.json +288 -0
- package/package.json +12 -5
- package/src/automatic-update-policy.ts +17 -0
- package/src/host/bridge-host.ts +3 -1
- package/src/{vite-plugin-kotlin.ts → kotlin-host.ts} +155 -12
- package/src/metro-plugin.ts +18 -0
- package/src/native-app-identity.ts +376 -0
- package/src/native-firebase-config.ts +90 -0
- package/src/screenshots/frame-compose.ts +5 -2
- package/src/screenshots/registry.ts +1 -1
- package/src/screenshots/schema.ts +2 -2
- package/src/vite-plugin-one.ts +11 -28
- package/src/vite-plugin.ts +6 -1
package/cli/commands/skills.ts
CHANGED
|
@@ -286,37 +286,6 @@ function linkSkill(skill: SkillInfo, targetDir: string, force: boolean): LinkRes
|
|
|
286
286
|
return 'conflict'
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
-
// quiet, conflict-safe (re)install of all bundled skills into the agent stores
|
|
290
|
-
// that already exist on this machine. wired into the CLI build so building or
|
|
291
|
-
// updating the CLI re-establishes the symlinks idempotently — never forces, so
|
|
292
|
-
// it can't clobber a skill the user customized, and never creates a store for
|
|
293
|
-
// an agent that isn't set up here. silent on success.
|
|
294
|
-
export function refreshInstalledSkills() {
|
|
295
|
-
const skills = listSkills()
|
|
296
|
-
if (skills.length === 0) return
|
|
297
|
-
for (const target of defaultAgentTargets()) {
|
|
298
|
-
const skillsDir = path.resolve(target.dir)
|
|
299
|
-
// only touch agents already present (~/.claude, ~/.codex) — don't seed a
|
|
300
|
-
// store on a CI runner or a machine that doesn't use that agent.
|
|
301
|
-
if (!fs.existsSync(path.dirname(skillsDir))) continue
|
|
302
|
-
try {
|
|
303
|
-
fs.mkdirSync(skillsDir, { recursive: true })
|
|
304
|
-
} catch {
|
|
305
|
-
continue
|
|
306
|
-
}
|
|
307
|
-
try {
|
|
308
|
-
removeLegacyBundledSkills(skillsDir)
|
|
309
|
-
} catch {}
|
|
310
|
-
for (const skill of skills) {
|
|
311
|
-
try {
|
|
312
|
-
linkSkill(skill, skillsDir, false)
|
|
313
|
-
} catch {
|
|
314
|
-
// best-effort: a single bad store must not fail the build
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
289
|
const LEGACY_BUNDLED_SKILL_DIRS = [
|
|
321
290
|
'sootsim-setup',
|
|
322
291
|
'sootsim-debug',
|
|
@@ -2,9 +2,9 @@ import { spawnSync } from 'node:child_process'
|
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs'
|
|
3
3
|
import { createRequire } from 'node:module'
|
|
4
4
|
import { dirname, join } from 'node:path'
|
|
5
|
+
import { isRecord } from '../../src/is-record'
|
|
5
6
|
import { RNX_INTERNAL_CHILDREN, RNX_INTERNAL_COMMAND } from '../internal-child'
|
|
6
7
|
import { rnxSelfInvocation } from '../self-invocation'
|
|
7
|
-
import { isRecord } from '../../src/is-record'
|
|
8
8
|
|
|
9
9
|
export interface ResolvedPlaywright {
|
|
10
10
|
// package name that resolved (for human-facing messaging)
|
|
@@ -32,7 +32,8 @@ export function resolvePlaywright(): ResolvedPlaywright | null {
|
|
|
32
32
|
// resolve from several roots, not just cwd. a user can invoke a global CLI
|
|
33
33
|
// from an arbitrary directory while Playwright is installed beside the CLI.
|
|
34
34
|
const roots = [`${process.cwd()}/`]
|
|
35
|
-
|
|
35
|
+
const self = rnxSelfInvocation()
|
|
36
|
+
roots.push(self.prefixArgs[0] ?? self.executable)
|
|
36
37
|
for (const root of roots) {
|
|
37
38
|
try {
|
|
38
39
|
const requireFromRoot = createRequire(root)
|
|
@@ -2,6 +2,11 @@ import {
|
|
|
2
2
|
readBrowserCompositeCaptureRequest,
|
|
3
3
|
resolveBrowserCompositeCdpClip,
|
|
4
4
|
} from '../../../peach-engine/src/capture/browser-composite'
|
|
5
|
+
import {
|
|
6
|
+
AUTH_BROWSER_EXTERNAL_NAVIGATION_EVENT,
|
|
7
|
+
AUTH_BROWSER_SESSION_FRAGMENT_KEY,
|
|
8
|
+
forwardPopupSchemeNavigations,
|
|
9
|
+
} from '../../../peach-engine/src/open-external'
|
|
5
10
|
import { createBrowserPointerDispatcher } from '../../../peach-engine/src/render-worker/browser-pointer'
|
|
6
11
|
// the detached browser host, as CJS source.
|
|
7
12
|
//
|
|
@@ -46,11 +51,13 @@ const cdpPort = process.env.SOOTSIM_PW_CDP_PORT || '';
|
|
|
46
51
|
const extraChromeArgs = (process.env.SOOTSIM_PW_CHROME_ARGS || '')
|
|
47
52
|
.split(' ')
|
|
48
53
|
.filter(Boolean);
|
|
49
|
-
//
|
|
50
|
-
// renderer
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
+
// A Mac always has a GPU, so a local macOS drive that lands on Playwright's
|
|
55
|
+
// software renderer is a misconfiguration that pegs every core: it fails
|
|
56
|
+
// closed unless the hardware-backed test browser is proven after launch. CI
|
|
57
|
+
// and Linux or Windows hosts, which are often GPU-less servers, use the
|
|
58
|
+
// bundled browser and render in software when no GPU is present.
|
|
59
|
+
const hardwareGpuRequired =
|
|
60
|
+
process.platform === 'darwin' && process.env.CI !== '1' && process.env.CI !== 'true';
|
|
54
61
|
const softwareRendererPattern = /swiftshader|software(?: rasterizer)?|llvmpipe|lavapipe|softpipe/i;
|
|
55
62
|
// page viewport as '<w>x<h>'. the caller sizes it from the device profile;
|
|
56
63
|
// the fallback is phone-shaped because the page hosts a phone sim — the
|
|
@@ -74,6 +81,7 @@ const { execSync } = require('child_process');
|
|
|
74
81
|
const { tmpdir } = require('os');
|
|
75
82
|
const { join } = require('path');
|
|
76
83
|
const createBrowserPointerDispatcher = ${createBrowserPointerDispatcher.toString()};
|
|
84
|
+
const forwardPopupSchemeNavigations = ${forwardPopupSchemeNavigations.toString()};
|
|
77
85
|
const readBrowserCompositeCaptureRequest = ${readBrowserCompositeCaptureRequest.toString()};
|
|
78
86
|
const resolveBrowserCompositeCdpClip = ${resolveBrowserCompositeCdpClip.toString()};
|
|
79
87
|
// chrome tree reaper — playwright's browser.close() and even SIGKILLing the
|
|
@@ -300,9 +308,9 @@ const cleanupProfile = () => {
|
|
|
300
308
|
startOwnerWatch();
|
|
301
309
|
// Local rendering uses Playwright's full Chrome for Testing app. On macOS its
|
|
302
310
|
// com.google.chrome.for.testing identity cannot intercept open/quit events for
|
|
303
|
-
// the user's com.google.Chrome browser. CI
|
|
304
|
-
// local rendering fails closed because that
|
|
305
|
-
// chooses SwiftShader. NOTE: this is NOT enough to make \`peach perf cpu\`
|
|
311
|
+
// the user's com.google.Chrome browser. CI and non-Mac hosts use
|
|
312
|
+
// chromium_headless_shell; local Mac rendering fails closed because that
|
|
313
|
+
// shell has no GPU and silently chooses SwiftShader. NOTE: this is NOT enough to make \`peach perf cpu\`
|
|
306
314
|
// work — that profiles the tenant *worker*, and the JS Self-Profiler API
|
|
307
315
|
// cannot be constructed in a dedicated worker (see
|
|
308
316
|
// worker-handlers/cpu-profile.ts). cpu-profile needs a CDP-based profiler
|
|
@@ -317,7 +325,8 @@ const cleanupProfile = () => {
|
|
|
317
325
|
throw new Error('[playwright-driver] refused SwiftShader launch arguments');
|
|
318
326
|
}
|
|
319
327
|
// one browser path per environment: the full, separately identified test app
|
|
320
|
-
//
|
|
328
|
+
// on a local Mac; the bundled chromium everywhere else. never launch a
|
|
329
|
+
// branded user browser.
|
|
321
330
|
const channelsToTry = hardwareGpuRequired ? ['chromium'] : [null];
|
|
322
331
|
const launchWith = async (channel) => {
|
|
323
332
|
const opts = channel
|
|
@@ -429,6 +438,13 @@ const cleanupProfile = () => {
|
|
|
429
438
|
await context.addInitScript({
|
|
430
439
|
content: 'Object.defineProperty(window, "__sootsimHostMeta", { value: ' + JSON.stringify(hostMeta) + ', configurable: true });' + bridgePortInject,
|
|
431
440
|
});
|
|
441
|
+
// ASWebAuthenticationSession completes on a navigation to its callback
|
|
442
|
+
// scheme, which a browser popup cannot follow.
|
|
443
|
+
await forwardPopupSchemeNavigations(
|
|
444
|
+
context,
|
|
445
|
+
${JSON.stringify(AUTH_BROWSER_EXTERNAL_NAVIGATION_EVENT)},
|
|
446
|
+
${JSON.stringify(AUTH_BROWSER_SESSION_FRAGMENT_KEY)},
|
|
447
|
+
);
|
|
432
448
|
await context.exposeBinding('__sootsimHostClose', async () => {
|
|
433
449
|
await shutdown(0);
|
|
434
450
|
});
|
package/cli/main.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// single lazy-imported command a run dispatches to. `./bin` imports this only
|
|
3
3
|
// when none of its hidden entry points claimed the process.
|
|
4
4
|
|
|
5
|
+
import { automaticPeachUpdatesEnabled } from '../src/automatic-update-policy'
|
|
5
6
|
import { rnxPublicBrand } from '../src/public-brand'
|
|
6
7
|
import { levenshtein } from './levenshtein'
|
|
7
8
|
import { COMMANDS, parseArgs, TOP_LEVEL_RUNTIME_COMMANDS } from './parse-args'
|
|
@@ -92,7 +93,7 @@ const isReadOnlyInvocation =
|
|
|
92
93
|
parsed.commandArgs.includes('--dry-run')
|
|
93
94
|
|
|
94
95
|
if (isCliUpdateWorker) {
|
|
95
|
-
if (IS_STANDALONE) {
|
|
96
|
+
if (IS_STANDALONE && automaticPeachUpdatesEnabled()) {
|
|
96
97
|
try {
|
|
97
98
|
const { refreshCliUpdateCache } = await import('./cli-update')
|
|
98
99
|
await refreshCliUpdateCache()
|
|
@@ -119,7 +120,12 @@ if (
|
|
|
119
120
|
// interactive command runs next prints it once (stderr, so --json stdout
|
|
120
121
|
// stays parseable) and deletes it. the daemon/serve processes skip it so a
|
|
121
122
|
// background process can't eat the notice before a human sees it.
|
|
122
|
-
if (
|
|
123
|
+
if (
|
|
124
|
+
automaticPeachUpdatesEnabled() &&
|
|
125
|
+
!isReadOnlyInvocation &&
|
|
126
|
+
parsed.command !== 'serve' &&
|
|
127
|
+
parsed.command !== 'daemon'
|
|
128
|
+
) {
|
|
123
129
|
const { consumeRuntimeUpgradeNotice } = await import('../src/home-paths')
|
|
124
130
|
const notice = consumeRuntimeUpgradeNotice()
|
|
125
131
|
if (notice) {
|
|
@@ -349,12 +349,8 @@ export const DECLARED_OUTBOUND_CALLS: Record<string, OutboundCallDeclaration> =
|
|
|
349
349
|
category: 'guest_app_network',
|
|
350
350
|
count: 1,
|
|
351
351
|
},
|
|
352
|
-
'packages/peach-engine/src/engine/config-plugin-splash-loader.ts :: fetch :: manifestFetchUrl(origin)':
|
|
353
|
-
{ category: 'local_development', count: 1 },
|
|
354
352
|
'packages/peach-engine/src/engine/emoji-metrics-font-loader.ts :: fetch :: attemptedBundledUrl':
|
|
355
353
|
{ category: 'same_origin_runtime', count: 1 },
|
|
356
|
-
'packages/peach-engine/src/engine/expo-app-config.ts :: fetch :: manifestFetchUrl(origin)':
|
|
357
|
-
{ category: 'local_development', count: 1 },
|
|
358
354
|
'packages/peach-engine/src/engine/image-loader.ts :: fetch :: resolveImageFetchUri(uri)':
|
|
359
355
|
{ category: 'guest_app_network', count: 1 },
|
|
360
356
|
'packages/peach-engine/src/engine/language-font-loader.ts :: fetch :: url': {
|
package/detox/index.ts
CHANGED
|
@@ -10,6 +10,11 @@ import {
|
|
|
10
10
|
readBrowserCompositeCaptureRequest,
|
|
11
11
|
resolveBrowserCompositeCdpClip,
|
|
12
12
|
} from '../../peach-engine/src/capture/browser-composite'
|
|
13
|
+
import {
|
|
14
|
+
AUTH_BROWSER_EXTERNAL_NAVIGATION_EVENT,
|
|
15
|
+
AUTH_BROWSER_SESSION_FRAGMENT_KEY,
|
|
16
|
+
forwardPopupSchemeNavigations,
|
|
17
|
+
} from '../../peach-engine/src/open-external'
|
|
13
18
|
import { isAppBootTargetUrl } from '../../peach-engine/src/render-worker/app-load'
|
|
14
19
|
import { SOOTSIM_SHELL_COMMAND_NAME } from '../src/menu'
|
|
15
20
|
import { pollUntil } from '../src/poll-until'
|
|
@@ -55,7 +60,6 @@ let _reapBrowserNow: (() => void) | null = null
|
|
|
55
60
|
let _context: BrowserContext | null = null
|
|
56
61
|
let _page: Page | null = null
|
|
57
62
|
let _synchronizationEnabled = false
|
|
58
|
-
let _suspendedAppId: string | null = null
|
|
59
63
|
let _browserCompromised: string | null = null
|
|
60
64
|
let browserIdentity = 0
|
|
61
65
|
let contextIdentity = 0
|
|
@@ -933,7 +937,22 @@ async function dispatchDeviceOrientation(orientation: 'portrait' | 'landscape')
|
|
|
933
937
|
landscapeSide: DETOX_PLATFORM === 'ios' ? 'right' : 'left',
|
|
934
938
|
},
|
|
935
939
|
)
|
|
936
|
-
|
|
940
|
+
// destination dimensions publish before the interface finishes turning.
|
|
941
|
+
await page.waitForFunction(
|
|
942
|
+
(next) => {
|
|
943
|
+
const settings = window.SootSim?.bridges?.settings?.get?.()
|
|
944
|
+
const rotation = Reflect.get(window, '__sootsimDeviceRotation')
|
|
945
|
+
return (
|
|
946
|
+
typeof settings === 'object' &&
|
|
947
|
+
settings !== null &&
|
|
948
|
+
'orientation' in settings &&
|
|
949
|
+
settings.orientation === next &&
|
|
950
|
+
rotation?.active !== true
|
|
951
|
+
)
|
|
952
|
+
},
|
|
953
|
+
orientation,
|
|
954
|
+
{ timeout: 15000 },
|
|
955
|
+
)
|
|
937
956
|
}
|
|
938
957
|
|
|
939
958
|
const MAX_SETTLED_SPEED_PT_PER_SEC = 2.0
|
|
@@ -1584,14 +1603,18 @@ function createSootSimElement(matcher: Matcher): SootSimElement {
|
|
|
1584
1603
|
visible: node.layout.width > 0 && node.layout.height > 0,
|
|
1585
1604
|
enabled: !node.accessibilityState?.disabled,
|
|
1586
1605
|
...node,
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1606
|
+
// the transformed rect when the node reports one; a node resolved
|
|
1607
|
+
// without a size (x and y only) keeps its own frame
|
|
1608
|
+
frame:
|
|
1609
|
+
node.absolutePosition?.width !== undefined &&
|
|
1610
|
+
node.absolutePosition.height !== undefined
|
|
1611
|
+
? {
|
|
1612
|
+
x: node.absolutePosition.x,
|
|
1613
|
+
y: node.absolutePosition.y,
|
|
1614
|
+
width: node.absolutePosition.width,
|
|
1615
|
+
height: node.absolutePosition.height,
|
|
1616
|
+
}
|
|
1617
|
+
: node.frame,
|
|
1595
1618
|
}
|
|
1596
1619
|
},
|
|
1597
1620
|
|
|
@@ -1755,36 +1778,41 @@ export const device = {
|
|
|
1755
1778
|
if (_browserCompromised) {
|
|
1756
1779
|
throw new Error(`sootsim browser is compromised: ${_browserCompromised}`)
|
|
1757
1780
|
}
|
|
1758
|
-
if (
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
) {
|
|
1781
|
+
if (_page && opts?.newInstance === false && !opts.delete && !opts.recordVideoDir) {
|
|
1782
|
+
// detox activates the running app without relaunching it; a url would
|
|
1783
|
+
// need a delivery path into the running guest that the adapter lacks.
|
|
1784
|
+
if (opts.url) {
|
|
1785
|
+
throw new Error(`SootSim cannot deliver a url to a running app: ${opts.url}`)
|
|
1786
|
+
}
|
|
1765
1787
|
const page = _page
|
|
1766
|
-
const appId =
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
()
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
)
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
+
const appId = await page.evaluate(async () => {
|
|
1789
|
+
const state = await window.SootSim?.bridges?.mainShell?.getState?.()
|
|
1790
|
+
const guestApp = state?.guestApp
|
|
1791
|
+
if (typeof guestApp !== 'string') {
|
|
1792
|
+
throw new Error('SootSim main shell reports no guest app')
|
|
1793
|
+
}
|
|
1794
|
+
if (state?.state === 'app' && state.activeApp === guestApp) return null
|
|
1795
|
+
window.SootSim?.bridges?.mainShell?.launchApp?.(guestApp)
|
|
1796
|
+
return guestApp
|
|
1797
|
+
})
|
|
1798
|
+
if (appId !== null) {
|
|
1799
|
+
await pollUntil(
|
|
1800
|
+
() =>
|
|
1801
|
+
page.evaluate(async (id) => {
|
|
1802
|
+
const state = await window.SootSim?.bridges?.mainShell?.getState?.()
|
|
1803
|
+
return (
|
|
1804
|
+
state?.state === 'app' &&
|
|
1805
|
+
state.activeApp === id &&
|
|
1806
|
+
state.switcherPhase === 'idle'
|
|
1807
|
+
)
|
|
1808
|
+
}, appId),
|
|
1809
|
+
Boolean,
|
|
1810
|
+
{
|
|
1811
|
+
timeoutMs: 10000,
|
|
1812
|
+
label: `SootSim app ${appId} to resume`,
|
|
1813
|
+
},
|
|
1814
|
+
)
|
|
1815
|
+
}
|
|
1788
1816
|
await waitForSootsimTree(page, 10000)
|
|
1789
1817
|
if (opts?.userNotification) {
|
|
1790
1818
|
await postRemotePushToSimulator(opts.userNotification, true)
|
|
@@ -1833,6 +1861,11 @@ export const device = {
|
|
|
1833
1861
|
reapOwnedBrowser()
|
|
1834
1862
|
throw error
|
|
1835
1863
|
}
|
|
1864
|
+
await forwardPopupSchemeNavigations(
|
|
1865
|
+
_context,
|
|
1866
|
+
AUTH_BROWSER_EXTERNAL_NAVIGATION_EVENT,
|
|
1867
|
+
AUTH_BROWSER_SESSION_FRAGMENT_KEY,
|
|
1868
|
+
)
|
|
1836
1869
|
await _context.exposeBinding('__sootsimHostCapture', async (source, value) => {
|
|
1837
1870
|
const request = readBrowserCompositeCaptureRequest(value)
|
|
1838
1871
|
const session = await source.page.context().newCDPSession(source.page)
|
|
@@ -3178,14 +3211,12 @@ export const device = {
|
|
|
3178
3211
|
|
|
3179
3212
|
async sendToHome() {
|
|
3180
3213
|
const page = getPage()
|
|
3181
|
-
|
|
3214
|
+
await page.evaluate(async () => {
|
|
3182
3215
|
const state = await window.SootSim?.bridges?.mainShell?.getState?.()
|
|
3183
|
-
|
|
3184
|
-
if (typeof appId !== 'string') {
|
|
3216
|
+
if (typeof state?.activeApp !== 'string') {
|
|
3185
3217
|
throw new Error(`cannot send an inactive SootSim app home`)
|
|
3186
3218
|
}
|
|
3187
3219
|
window.SootSim?.bridges?.mainShell?.goHome?.()
|
|
3188
|
-
return appId
|
|
3189
3220
|
})
|
|
3190
3221
|
await pollUntil(
|
|
3191
3222
|
() =>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (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.630 | (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.630 | (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.630 | (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.630 | (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.630 | (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.630 | (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/beta.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (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/beta.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (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.630 | (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.630 | (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.630 | (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.630 | (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.630 | (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.630 | (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/cloud.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (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/cloud.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
package/dist-lib/config.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (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;
|