peachsim 0.1.637 → 0.1.638
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 -5
- package/cli/bridge-flow-runner.ts +442 -14
- package/cli/commands/inspect/core.ts +93 -24
- package/cli/commands/maestro.ts +2 -2
- package/cli/commands/serve.ts +13 -1
- package/cli/drivers/playwright-provisioning.ts +8 -16
- package/cli/drivers/playwright-sim-host.ts +3 -0
- package/cli/drivers/playwright.ts +1 -0
- package/cli/internal-child.ts +51 -8
- 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 +3 -2
- package/dist-lib/bridge-contract-input.mjs +3 -2
- 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 +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +4 -2
- 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 +76 -20
- 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 +78 -20
- package/dist-lib/sdk.mjs +77 -20
- package/dist-lib/skills.cjs +394 -62
- package/dist-lib/swift-compile.cjs +89 -7
- package/dist-lib/swift-compile.mjs +89 -7
- 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 +122 -34
- package/dist-lib/vite-swift.cjs +89 -7
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/src/bridge-contract-input.ts +3 -2
- package/src/bridge-contract.ts +8 -0
- package/src/host/bridge-host.ts +5 -5
- package/src/native-seam-manifest.ts +4 -6
- package/src/swift-compile.ts +105 -9
package/cli/commands/maestro.ts
CHANGED
|
@@ -114,6 +114,7 @@ supported verbs:
|
|
|
114
114
|
launchApp (including arguments), stopApp, clearState, clearKeychain (warn-only),
|
|
115
115
|
selectors: text, id, index (negative from the end), childOf, below, above,
|
|
116
116
|
leftOf, rightOf, width / height / tolerance, traits, enabled, selected, checked,
|
|
117
|
+
focused, containsChild, containsDescendants,
|
|
117
118
|
tapOn (including repeat / delay), doubleTapOn, tapAtCoords, longPressOn,
|
|
118
119
|
inputText, pressKey, dispatchKey, hideKeyboard, eraseText,
|
|
119
120
|
setClipboard, pasteText,
|
|
@@ -166,8 +167,7 @@ not yet implemented (the step fails with "unsupported flow step"):
|
|
|
166
167
|
travel, setLocation, setAirplaneMode, killApp, faker, inputRandom*,
|
|
167
168
|
addMedia, startRecording, stopRecording (use --record flag),
|
|
168
169
|
repeat.while (only repeat.times is supported).
|
|
169
|
-
selector keys that fail the step:
|
|
170
|
-
focused, css.
|
|
170
|
+
selector keys that fail the step: css.
|
|
171
171
|
`)
|
|
172
172
|
}
|
|
173
173
|
|
package/cli/commands/serve.ts
CHANGED
|
@@ -36,11 +36,13 @@ usage:
|
|
|
36
36
|
|
|
37
37
|
options:
|
|
38
38
|
--port <n> bridge port (defaults to ${DEFAULT_SOOTSIM_BRIDGE_PORT})
|
|
39
|
+
--host <address> listener address (defaults to 127.0.0.1)
|
|
39
40
|
--quiet suppress per-connection logging
|
|
40
41
|
|
|
41
42
|
examples:
|
|
42
43
|
peach serve
|
|
43
44
|
peach serve --port 7668 --quiet
|
|
45
|
+
peach serve --host 0.0.0.0
|
|
44
46
|
`)
|
|
45
47
|
rnxExit(0)
|
|
46
48
|
}
|
|
@@ -54,6 +56,12 @@ examples:
|
|
|
54
56
|
console.error(` invalid --port value: ${args[portArgIdx + 1]}`)
|
|
55
57
|
rnxExit(1)
|
|
56
58
|
}
|
|
59
|
+
const hostArgIdx = args.indexOf('--host')
|
|
60
|
+
const bindHost = hostArgIdx >= 0 ? args[hostArgIdx + 1] : '127.0.0.1'
|
|
61
|
+
if (!bindHost || bindHost.startsWith('-')) {
|
|
62
|
+
console.error(' --host requires a listener address')
|
|
63
|
+
rnxExit(1)
|
|
64
|
+
}
|
|
57
65
|
const quiet = args.includes('--quiet') || args.includes('-q')
|
|
58
66
|
|
|
59
67
|
// only one bridge per peach home. refuse to start a second one
|
|
@@ -74,6 +82,7 @@ examples:
|
|
|
74
82
|
const contrastOrigin = await resolveDefaultUploadOrigin()
|
|
75
83
|
const host = new SootSimBridgeHost({
|
|
76
84
|
port,
|
|
85
|
+
host: bindHost,
|
|
77
86
|
writeLockfile: true,
|
|
78
87
|
contrastOrigin,
|
|
79
88
|
})
|
|
@@ -102,7 +111,10 @@ examples:
|
|
|
102
111
|
for (const id of currentIds) lastSimIds.add(id)
|
|
103
112
|
}, 500)
|
|
104
113
|
|
|
105
|
-
|
|
114
|
+
const displayHost = bindHost.includes(':') ? `[${bindHost}]` : bindHost
|
|
115
|
+
log(
|
|
116
|
+
`peach bridge listening on ws://${displayHost}:${boundPort} (runtime http on same port)`,
|
|
117
|
+
)
|
|
106
118
|
if (boundPort !== port) {
|
|
107
119
|
log(` (preferred port ${port} was taken — fell back to ${boundPort})`)
|
|
108
120
|
}
|
|
@@ -48,18 +48,12 @@ export function resolvePlaywright(): ResolvedPlaywright | null {
|
|
|
48
48
|
const packageJsonPath = requireFromRoot.resolve(`${spec}/package.json`)
|
|
49
49
|
const parsed: unknown = JSON.parse(readFileSync(packageJsonPath, 'utf8'))
|
|
50
50
|
if (!isRecord(parsed) || typeof parsed.version !== 'string') continue
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const first = Object.values(bin).find((value) => typeof value === 'string')
|
|
58
|
-
binPath =
|
|
59
|
-
typeof named === 'string' ? named : typeof first === 'string' ? first : null
|
|
60
|
-
}
|
|
61
|
-
if (!binPath) continue
|
|
62
|
-
const cliPath = join(dirname(packageJsonPath), binPath)
|
|
51
|
+
// resolve the core beside the API entry, never from the caller's
|
|
52
|
+
// project when running this package's provisioning subcommand.
|
|
53
|
+
const corePackagePath = createRequire(modulePath).resolve(
|
|
54
|
+
'playwright-core/package.json',
|
|
55
|
+
)
|
|
56
|
+
const cliPath = join(dirname(corePackagePath), 'cli.js')
|
|
63
57
|
if (!existsSync(cliPath)) continue
|
|
64
58
|
return {
|
|
65
59
|
spec,
|
|
@@ -166,10 +160,8 @@ export function ensurePlaywrightBrowser(
|
|
|
166
160
|
return { ok: true, executablePath: before.executablePath, installed: false }
|
|
167
161
|
}
|
|
168
162
|
|
|
169
|
-
//
|
|
170
|
-
//
|
|
171
|
-
// revision: Playwright's own CLI installs the exact revision its API named.
|
|
172
|
-
// that CLI is a javascript file, so this CLI runs it as itself.
|
|
163
|
+
// install only when neither an explicit binary nor an installed cache
|
|
164
|
+
// revision is available. the absolute core CLI owns its downloader scripts.
|
|
173
165
|
const installer = rnxSelfInvocation()
|
|
174
166
|
const install = spawnSync(
|
|
175
167
|
installer.executable,
|
|
@@ -26,6 +26,8 @@ import { DISPOSABLE_BROWSER_CACHE_DIR_NAMES } from '../../src/browser-cache'
|
|
|
26
26
|
|
|
27
27
|
export const PLAYWRIGHT_SIM_HOST = `
|
|
28
28
|
const modulePath = process.env.SOOTSIM_PW_MODULE;
|
|
29
|
+
const executablePath = process.env.SOOTSIM_PW_EXECUTABLE;
|
|
30
|
+
if (!executablePath) throw new Error('SOOTSIM_PW_EXECUTABLE is not set');
|
|
29
31
|
const url = process.env.SOOTSIM_PW_URL;
|
|
30
32
|
// the WS bridge port the sim page must register with, injected below as
|
|
31
33
|
// window.__sootsimBridgePort so the page skips its shell-port heuristic (which
|
|
@@ -332,6 +334,7 @@ const cleanupProfile = () => {
|
|
|
332
334
|
const opts = channel
|
|
333
335
|
? { headless, channel, viewport, deviceScaleFactor }
|
|
334
336
|
: { headless, viewport, deviceScaleFactor };
|
|
337
|
+
opts.executablePath = executablePath;
|
|
335
338
|
// playwright injects --force-color-profile=srgb by default, which reads
|
|
336
339
|
// visibly washed-out next to a normal chrome window on a wide-gamut mac
|
|
337
340
|
// display. strip it so driver-launched sims color-match the user's own
|
|
@@ -132,6 +132,7 @@ async function launch(opts: DriverLaunchOptions): Promise<DriverLaunchResult> {
|
|
|
132
132
|
env: {
|
|
133
133
|
...playwrightEnv,
|
|
134
134
|
SOOTSIM_PW_MODULE: resolved.modulePath,
|
|
135
|
+
SOOTSIM_PW_EXECUTABLE: provisioning.executablePath,
|
|
135
136
|
SOOTSIM_PW_URL: opts.url,
|
|
136
137
|
SOOTSIM_PW_BRIDGE_PORT: opts.bridgePort ? String(opts.bridgePort) : '',
|
|
137
138
|
SOOTSIM_PW_HEADLESS: (opts.headless ?? true) ? '1' : '0',
|
package/cli/internal-child.ts
CHANGED
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
// the same path. bin.ts dispatches here straight from argv, before any CLI
|
|
13
13
|
// startup work, which keeps a per-request worker (sync-http) cheap.
|
|
14
14
|
|
|
15
|
-
import { existsSync, writeFileSync } from 'node:fs'
|
|
15
|
+
import { accessSync, constants, existsSync, readdirSync, writeFileSync } from 'node:fs'
|
|
16
16
|
import { createRequire } from 'node:module'
|
|
17
|
+
import { basename, dirname, join, relative, resolve } from 'node:path'
|
|
17
18
|
import * as vm from 'node:vm'
|
|
18
19
|
|
|
19
20
|
export const RNX_INTERNAL_COMMAND = '__internal'
|
|
@@ -88,8 +89,8 @@ export async function runInternalChild(args: string[]): Promise<void> {
|
|
|
88
89
|
// own work does.
|
|
89
90
|
}
|
|
90
91
|
|
|
91
|
-
/**
|
|
92
|
-
*
|
|
92
|
+
/** select an explicit executable or the newest installed chromium in the
|
|
93
|
+
* resolved package's cache. a separate process so the caller's environment
|
|
93
94
|
* snapshot — PLAYWRIGHT_BROWSERS_PATH above all — is the only browser cache
|
|
94
95
|
* this ever sees. */
|
|
95
96
|
function playwrightProbe(): ChildReply {
|
|
@@ -100,19 +101,61 @@ function playwrightProbe(): ChildReply {
|
|
|
100
101
|
if (!isRecord(chromium) || typeof chromium.executablePath !== 'function') {
|
|
101
102
|
throw new Error('resolved package does not expose browser "chromium"')
|
|
102
103
|
}
|
|
103
|
-
const
|
|
104
|
-
if (typeof
|
|
104
|
+
const expectedPath: unknown = chromium.executablePath()
|
|
105
|
+
if (typeof expectedPath !== 'string') {
|
|
105
106
|
throw new Error('browser "chromium" reported no executable path')
|
|
106
107
|
}
|
|
108
|
+
let executablePath = expectedPath
|
|
109
|
+
const override = process.env.PEACH_CHROMIUM_EXECUTABLE
|
|
110
|
+
if (override) {
|
|
111
|
+
executablePath = resolve(override)
|
|
112
|
+
accessSync(executablePath, constants.X_OK)
|
|
113
|
+
} else {
|
|
114
|
+
// use full chromium for both headed and headless launches. selecting it
|
|
115
|
+
// explicitly also avoids a second, revision-pinned headless-shell lookup.
|
|
116
|
+
let browserDir = dirname(expectedPath)
|
|
117
|
+
while (!/^chromium-\d+$/.test(basename(browserDir))) {
|
|
118
|
+
const parent = dirname(browserDir)
|
|
119
|
+
if (parent === browserDir) throw new Error('unexpected chromium cache layout')
|
|
120
|
+
browserDir = parent
|
|
121
|
+
}
|
|
122
|
+
const cacheDir = dirname(browserDir)
|
|
123
|
+
const binaryPath = relative(browserDir, expectedPath)
|
|
124
|
+
const revisions = existsSync(cacheDir)
|
|
125
|
+
? readdirSync(cacheDir)
|
|
126
|
+
.filter((name) => /^chromium-\d+$/.test(name))
|
|
127
|
+
.sort((a, b) => Number(b.slice(9)) - Number(a.slice(9)))
|
|
128
|
+
: []
|
|
129
|
+
for (const revision of revisions) {
|
|
130
|
+
// chromium switched its linux archive directory to chrome-linux64.
|
|
131
|
+
const paths =
|
|
132
|
+
process.platform === 'linux'
|
|
133
|
+
? ['chrome-linux64/chrome', 'chrome-linux/chrome']
|
|
134
|
+
: [binaryPath]
|
|
135
|
+
const installed = paths
|
|
136
|
+
.map((path) => join(cacheDir, revision, path))
|
|
137
|
+
.find((path) => {
|
|
138
|
+
try {
|
|
139
|
+
accessSync(path, constants.X_OK)
|
|
140
|
+
return true
|
|
141
|
+
} catch {
|
|
142
|
+
return false
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
if (installed) {
|
|
146
|
+
executablePath = installed
|
|
147
|
+
break
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
107
151
|
return {
|
|
108
152
|
stdout: JSON.stringify({ executablePath, exists: existsSync(executablePath) }),
|
|
109
153
|
code: 0,
|
|
110
154
|
}
|
|
111
155
|
}
|
|
112
156
|
|
|
113
|
-
/** run playwright's
|
|
114
|
-
*
|
|
115
|
-
* parser expects to receive it from node. it owns this process from here:
|
|
157
|
+
/** run the resolved playwright core's absolute CLI entry. argv is shaped the
|
|
158
|
+
* way its parser expects to receive it from node. it owns this process from here:
|
|
116
159
|
* it sets the exit code and may exit outright. */
|
|
117
160
|
function playwrightInstall(args: string[]): void {
|
|
118
161
|
const [cliPath, ...cliArgs] = args
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.638 | (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.638 | (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.638 | (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.638 | (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.638 | (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.638 | (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.638 | (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.638 | (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.638 | (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.638 | (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;
|
|
@@ -337,6 +337,7 @@ function parseSemanticQuery(value) {
|
|
|
337
337
|
const query = recordValue(value, "query");
|
|
338
338
|
const kind = stringValue(query.kind, "query.kind");
|
|
339
339
|
if (kind === "count") return { kind };
|
|
340
|
+
if (kind === "accessibility") return { kind };
|
|
340
341
|
if (kind === "tree") {
|
|
341
342
|
const depth = optionalNumber(query, "depth", "query");
|
|
342
343
|
return { kind, ...depth === void 0 ? {} : { depth } };
|
|
@@ -344,7 +345,7 @@ function parseSemanticQuery(value) {
|
|
|
344
345
|
if (kind === "find") {
|
|
345
346
|
return { kind, selector: parseSemanticSelector(query.selector, "query.selector") };
|
|
346
347
|
}
|
|
347
|
-
return validationFailure("query.kind", "must be tree, find, or
|
|
348
|
+
return validationFailure("query.kind", "must be tree, find, count, or accessibility");
|
|
348
349
|
}
|
|
349
350
|
function semanticResolveSelector(value, path) {
|
|
350
351
|
const selector = recordValue(value, path);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.638 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/bridge-contract.ts
|
|
4
4
|
var SIM_LONG_PRESS_MAX_MS = 5e3;
|
|
@@ -301,6 +301,7 @@ function parseSemanticQuery(value) {
|
|
|
301
301
|
const query = recordValue(value, "query");
|
|
302
302
|
const kind = stringValue(query.kind, "query.kind");
|
|
303
303
|
if (kind === "count") return { kind };
|
|
304
|
+
if (kind === "accessibility") return { kind };
|
|
304
305
|
if (kind === "tree") {
|
|
305
306
|
const depth = optionalNumber(query, "depth", "query");
|
|
306
307
|
return { kind, ...depth === void 0 ? {} : { depth } };
|
|
@@ -308,7 +309,7 @@ function parseSemanticQuery(value) {
|
|
|
308
309
|
if (kind === "find") {
|
|
309
310
|
return { kind, selector: parseSemanticSelector(query.selector, "query.selector") };
|
|
310
311
|
}
|
|
311
|
-
return validationFailure("query.kind", "must be tree, find, or
|
|
312
|
+
return validationFailure("query.kind", "must be tree, find, count, or accessibility");
|
|
312
313
|
}
|
|
313
314
|
function semanticResolveSelector(value, path) {
|
|
314
315
|
const selector = recordValue(value, path);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.638 | (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.638 | (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.638 | (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.638 | (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.638 | (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.638 | (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.638 | (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.638 | (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/detox/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.638 | (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.638 | (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/home-paths.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.638 | (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.638 | (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;
|
|
@@ -9497,6 +9497,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
9497
9497
|
// terminal 4001 code, so the client closes the abandoned window instead
|
|
9498
9498
|
// of reconnecting the zombie straight back in.
|
|
9499
9499
|
static SIM_IDLE_REAP_TTL_MS = 30 * 6e4;
|
|
9500
|
+
bindHost;
|
|
9500
9501
|
preferredPort;
|
|
9501
9502
|
portFallbackCount;
|
|
9502
9503
|
shouldWriteLockfile;
|
|
@@ -9530,6 +9531,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
9530
9531
|
inflightScan = null;
|
|
9531
9532
|
static SCAN_FRESH_MS = 2e3;
|
|
9532
9533
|
constructor(opts = {}) {
|
|
9534
|
+
this.bindHost = opts.host ?? "127.0.0.1";
|
|
9533
9535
|
this.preferredPort = opts.port ?? DEFAULT_SOOTSIM_BRIDGE_PORT;
|
|
9534
9536
|
this.port = this.preferredPort;
|
|
9535
9537
|
this.shouldWriteLockfile = opts.writeLockfile === true;
|
|
@@ -9606,7 +9608,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
9606
9608
|
reject(err);
|
|
9607
9609
|
};
|
|
9608
9610
|
server.once("error", onError);
|
|
9609
|
-
server.listen(port,
|
|
9611
|
+
server.listen(port, this.bindHost, () => {
|
|
9610
9612
|
if (settled) return;
|
|
9611
9613
|
const address = server.address();
|
|
9612
9614
|
if (!address || typeof address === "string") {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.638 | (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.638 | (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.638 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/host/fetch-proxy-overrides.ts
|
|
4
4
|
var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.638 | (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.638 | (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/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.638 | (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;
|
|
@@ -1780,33 +1780,89 @@ function layoutGetNativeEval(opts = {}) {
|
|
|
1780
1780
|
})()`;
|
|
1781
1781
|
}
|
|
1782
1782
|
var LAYOUT_GET_NATIVE_EVAL = layoutGetNativeEval();
|
|
1783
|
+
function isPeachAccessibilityTree(value) {
|
|
1784
|
+
if (!Array.isArray(value)) return false;
|
|
1785
|
+
return value.every((node) => {
|
|
1786
|
+
if (node === null || typeof node !== "object") return false;
|
|
1787
|
+
if (Reflect.get(node, "platform") !== "ios" && Reflect.get(node, "platform") !== "android")
|
|
1788
|
+
return false;
|
|
1789
|
+
if (typeof Reflect.get(node, "elementId") !== "string") return false;
|
|
1790
|
+
if (!Number.isInteger(Reflect.get(node, "nodeId"))) return false;
|
|
1791
|
+
for (const key of ["type", "role"]) {
|
|
1792
|
+
if (typeof Reflect.get(node, key) !== "string") return false;
|
|
1793
|
+
}
|
|
1794
|
+
for (const key of ["testID", "label", "hint", "value", "placeholder"]) {
|
|
1795
|
+
const field = Reflect.get(node, key);
|
|
1796
|
+
if (field !== null && typeof field !== "string") return false;
|
|
1797
|
+
}
|
|
1798
|
+
for (const key of [
|
|
1799
|
+
"isAccessibilityElement",
|
|
1800
|
+
"enabled",
|
|
1801
|
+
"selected",
|
|
1802
|
+
"checked",
|
|
1803
|
+
"clickable",
|
|
1804
|
+
"isTextInput"
|
|
1805
|
+
]) {
|
|
1806
|
+
if (typeof Reflect.get(node, key) !== "boolean") return false;
|
|
1807
|
+
}
|
|
1808
|
+
const hasFocus = Reflect.get(node, "hasFocus");
|
|
1809
|
+
if (hasFocus !== void 0 && typeof hasFocus !== "boolean") return false;
|
|
1810
|
+
const state = Reflect.get(node, "state");
|
|
1811
|
+
if (state !== null) {
|
|
1812
|
+
if (typeof state !== "object") return false;
|
|
1813
|
+
const checked = Reflect.get(state, "checked");
|
|
1814
|
+
if (typeof checked !== "boolean" && checked !== "mixed") return false;
|
|
1815
|
+
for (const key of ["disabled", "selected", "busy", "expanded"]) {
|
|
1816
|
+
if (typeof Reflect.get(state, key) !== "boolean") return false;
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
const value2 = Reflect.get(node, "accessibilityValue");
|
|
1820
|
+
if (value2 !== null) {
|
|
1821
|
+
if (typeof value2 !== "object") return false;
|
|
1822
|
+
for (const key of ["min", "max", "now"]) {
|
|
1823
|
+
const field = Reflect.get(value2, key);
|
|
1824
|
+
if (field !== void 0 && (typeof field !== "number" || !Number.isFinite(field)))
|
|
1825
|
+
return false;
|
|
1826
|
+
}
|
|
1827
|
+
const text = Reflect.get(value2, "text");
|
|
1828
|
+
if (text !== void 0 && typeof text !== "string") return false;
|
|
1829
|
+
}
|
|
1830
|
+
if (!isSemanticGeometry(Reflect.get(node, "frame"))) return false;
|
|
1831
|
+
return isPeachAccessibilityTree(Reflect.get(node, "children"));
|
|
1832
|
+
});
|
|
1833
|
+
}
|
|
1783
1834
|
async function inspectAccessibilityTree(bridge) {
|
|
1784
1835
|
const result = await bridge.send({
|
|
1785
1836
|
type: "query",
|
|
1786
|
-
query: { kind: "
|
|
1837
|
+
query: { kind: "accessibility" }
|
|
1787
1838
|
});
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1839
|
+
const tree = result !== null && typeof result === "object" ? Reflect.get(result, "accessibility") : void 0;
|
|
1840
|
+
if (!isPeachAccessibilityTree(tree))
|
|
1841
|
+
throw new Error("engine returned an invalid accessibility snapshot");
|
|
1842
|
+
const nodes = [];
|
|
1843
|
+
const visit = (node) => {
|
|
1844
|
+
if (node.isAccessibilityElement) {
|
|
1845
|
+
nodes.push({
|
|
1846
|
+
role: node.role,
|
|
1847
|
+
label: node.label,
|
|
1848
|
+
hint: node.hint,
|
|
1849
|
+
state: node.state ? { ...node.state } : null,
|
|
1850
|
+
testID: node.testID,
|
|
1799
1851
|
position: {
|
|
1800
|
-
x: Math.round(node.
|
|
1801
|
-
y: Math.round(node.
|
|
1852
|
+
x: Math.round(node.frame.x),
|
|
1853
|
+
y: Math.round(node.frame.y)
|
|
1802
1854
|
},
|
|
1803
1855
|
size: {
|
|
1804
|
-
w: Math.round(node.
|
|
1805
|
-
h: Math.round(node.
|
|
1856
|
+
w: Math.round(node.frame.width),
|
|
1857
|
+
h: Math.round(node.frame.height)
|
|
1806
1858
|
}
|
|
1807
|
-
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1859
|
+
});
|
|
1860
|
+
if (node.platform === "ios") return;
|
|
1861
|
+
}
|
|
1862
|
+
for (const child of node.children) visit(child);
|
|
1863
|
+
};
|
|
1864
|
+
for (const root of tree) visit(root);
|
|
1865
|
+
return nodes;
|
|
1810
1866
|
}
|
|
1811
1867
|
function resolveFindMode(q) {
|
|
1812
1868
|
if (q.testId) {
|