rnxsim 0.1.312 → 0.1.314
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/LICENSE +11 -10
- package/README.md +5 -0
- package/cli/app-config.ts +65 -0
- package/cli/app-fonts.ts +408 -0
- package/cli/app-project.ts +231 -0
- package/cli/app-splash.ts +185 -0
- package/cli/app-state-reset.ts +24 -0
- package/cli/auth.ts +155 -0
- package/cli/bin.ts +594 -0
- package/cli/bridge-diagnostics.ts +226 -0
- package/cli/bridge-flow-runner.ts +2830 -0
- package/cli/browser-evals.ts +96 -0
- package/cli/commands/agent-wrapper.ts +986 -0
- package/cli/commands/agent.ts +423 -0
- package/cli/commands/app-fonts.ts +98 -0
- package/cli/commands/assert.ts +541 -0
- package/cli/commands/auth.ts +59 -0
- package/cli/commands/camera.ts +266 -0
- package/cli/commands/cleanup.ts +169 -0
- package/cli/commands/compat.ts +87 -0
- package/cli/commands/config.ts +32 -0
- package/cli/commands/control.ts +2142 -0
- package/cli/commands/cpu-profile.ts +269 -0
- package/cli/commands/daemon-mac-app.ts +169 -0
- package/cli/commands/daemon.ts +874 -0
- package/cli/commands/debug.ts +719 -0
- package/cli/commands/desktop.ts +39 -0
- package/cli/commands/detect.ts +197 -0
- package/cli/commands/detox.ts +385 -0
- package/cli/commands/device.ts +133 -0
- package/cli/commands/diagnose.ts +589 -0
- package/cli/commands/electron.ts +95 -0
- package/cli/commands/film.ts +379 -0
- package/cli/commands/flow.ts +1124 -0
- package/cli/commands/inspect/actions.ts +622 -0
- package/cli/commands/inspect/core.ts +2405 -0
- package/cli/commands/inspect/count.ts +17 -0
- package/cli/commands/inspect/describe.ts +192 -0
- package/cli/commands/inspect/env.ts +23 -0
- package/cli/commands/inspect/find.ts +171 -0
- package/cli/commands/inspect/get-layout.ts +39 -0
- package/cli/commands/inspect/keyboard.ts +52 -0
- package/cli/commands/inspect/list.ts +58 -0
- package/cli/commands/inspect/memory.ts +215 -0
- package/cli/commands/inspect/redaction.ts +39 -0
- package/cli/commands/inspect/resolve-target.ts +82 -0
- package/cli/commands/inspect/screens.ts +78 -0
- package/cli/commands/inspect/settle.ts +22 -0
- package/cli/commands/inspect/settling.ts +158 -0
- package/cli/commands/inspect/shared.ts +353 -0
- package/cli/commands/inspect/sleep.ts +14 -0
- package/cli/commands/inspect/tree.ts +32 -0
- package/cli/commands/inspect/url.ts +17 -0
- package/cli/commands/inspect/wait-event.ts +210 -0
- package/cli/commands/inspect/wait-idle.ts +24 -0
- package/cli/commands/inspect/wait-ready.ts +74 -0
- package/cli/commands/inspect/wait-selector.ts +54 -0
- package/cli/commands/inspect/wait.ts +31 -0
- package/cli/commands/inspect.ts +4519 -0
- package/cli/commands/install-desktop.ts +351 -0
- package/cli/commands/login.ts +331 -0
- package/cli/commands/logout.ts +31 -0
- package/cli/commands/maestro-generate.ts +361 -0
- package/cli/commands/maestro.ts +453 -0
- package/cli/commands/mode.ts +57 -0
- package/cli/commands/no-bridge-hint.ts +80 -0
- package/cli/commands/perf.ts +66 -0
- package/cli/commands/permissions.ts +203 -0
- package/cli/commands/profile.ts +108 -0
- package/cli/commands/react.ts +353 -0
- package/cli/commands/record.ts +1434 -0
- package/cli/commands/report-issue.ts +305 -0
- package/cli/commands/reset.ts +85 -0
- package/cli/commands/runtime.ts +351 -0
- package/cli/commands/screenshot-command.ts +106 -0
- package/cli/commands/screenshot-layers.ts +143 -0
- package/cli/commands/screenshot-mode.ts +37 -0
- package/cli/commands/screenshot.ts +488 -0
- package/cli/commands/screenshots-capture.ts +607 -0
- package/cli/commands/screenshots.ts +127 -0
- package/cli/commands/serve.ts +168 -0
- package/cli/commands/setup.ts +545 -0
- package/cli/commands/shell-boolean-mode.ts +81 -0
- package/cli/commands/skills.ts +467 -0
- package/cli/commands/slides.ts +361 -0
- package/cli/commands/state.ts +87 -0
- package/cli/commands/storage.ts +58 -0
- package/cli/commands/telemetry.ts +54 -0
- package/cli/commands/three-mode.ts +763 -0
- package/cli/commands/timeline.ts +122 -0
- package/cli/commands/upgrade.ts +208 -0
- package/cli/commands/upload.ts +1225 -0
- package/cli/commands/version.ts +54 -0
- package/cli/commands/what-happened.ts +327 -0
- package/cli/current-sim.ts +204 -0
- package/cli/desktop-companion.ts +300 -0
- package/cli/drivers/electron.ts +70 -0
- package/cli/drivers/index.ts +20 -0
- package/cli/drivers/playwright-provisioning.ts +180 -0
- package/cli/drivers/playwright.ts +698 -0
- package/cli/drivers/registry.ts +65 -0
- package/cli/drivers/types.ts +102 -0
- package/cli/flow-file.ts +142 -0
- package/cli/flow-live-status.ts +120 -0
- package/cli/flow-session.ts +187 -0
- package/cli/help.ts +80 -0
- package/cli/hidden-runtime-alias.ts +19 -0
- package/cli/hints.ts +216 -0
- package/cli/inspect-notice-state.ts +114 -0
- package/cli/maestro-js.ts +334 -0
- package/cli/open-url.ts +8 -0
- package/cli/parent-pid.ts +204 -0
- package/cli/parse-args.ts +211 -0
- package/cli/prompt.ts +51 -0
- package/cli/recording-access.ts +107 -0
- package/cli/registry.ts +1 -0
- package/cli/resolve-assets.ts +63 -0
- package/cli/run-registry.ts +226 -0
- package/cli/runtime-notes.ts +66 -0
- package/cli/runtime-summary.ts +25 -0
- package/cli/setup-repository.ts +187 -0
- package/cli/telemetry.ts +187 -0
- package/cli/ws-bridge.ts +798 -0
- package/dist-cli/bin.js +5 -5
- package/dist-cli/chunks/{agent-NXVDDCFG.js → agent-7YBDCYMA.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-DXJCFKL3.js → agent-wrapper-2GHFBHCR.js} +2 -2
- package/dist-cli/chunks/{app-fonts-W5AJZQJF.js → app-fonts-RSNVPQSU.js} +2 -2
- package/dist-cli/chunks/{assert-3LOJEUDT.js → assert-XCMX3XJX.js} +2 -2
- package/dist-cli/chunks/{auth-MFTYYPNX.js → auth-B442HRAX.js} +2 -2
- package/dist-cli/chunks/{beta-GT3NN67B.js → beta-XJ55JK3M.js} +2 -2
- package/dist-cli/chunks/camera-UGYSSLIK.js +33 -0
- package/dist-cli/chunks/{chunk-EUAVBTKU.js → chunk-277AEQZX.js} +2 -2
- package/dist-cli/chunks/{chunk-5OX7ANRA.js → chunk-2JNSK774.js} +2 -2
- package/dist-cli/chunks/{chunk-L24Z3CRS.js → chunk-32WOTSTR.js} +3 -3
- package/dist-cli/chunks/{chunk-BKNOLP3J.js → chunk-3S753SNQ.js} +2 -2
- package/dist-cli/chunks/{chunk-N6A3SXMR.js → chunk-46ZOLOYA.js} +2 -2
- package/dist-cli/chunks/{chunk-GZDHEONW.js → chunk-5L7ELDQL.js} +8 -9
- package/dist-cli/chunks/{chunk-YZRFF4YA.js → chunk-7OOPFSQS.js} +2 -2
- package/dist-cli/chunks/{chunk-TBMVBI26.js → chunk-7SV3RPRW.js} +2 -2
- package/dist-cli/chunks/{chunk-JG6S4RSH.js → chunk-7ZC35MOU.js} +1 -1
- package/dist-cli/chunks/chunk-AMG5E6CC.js +9 -0
- package/dist-cli/chunks/{chunk-MENV7VLD.js → chunk-APWNH3A4.js} +1 -1
- package/dist-cli/chunks/chunk-B57XUKY3.js +4 -0
- package/dist-cli/chunks/{chunk-3D57IBPC.js → chunk-C2NL26TD.js} +1 -1
- package/dist-cli/chunks/chunk-D2FNUWAB.js +15 -0
- package/dist-cli/chunks/{chunk-4BXCZHAU.js → chunk-E5T4XSJ3.js} +2 -2
- package/dist-cli/chunks/{chunk-FTC4M26Q.js → chunk-EAC34EQS.js} +1 -1
- package/dist-cli/chunks/{chunk-NPVGMH2N.js → chunk-EG32ML36.js} +2 -2
- package/dist-cli/chunks/{chunk-DM6KUAOZ.js → chunk-FXUAC6D5.js} +1 -1
- package/dist-cli/chunks/chunk-GQSL4USA.js +6 -0
- package/dist-cli/chunks/{chunk-U4PN6JOT.js → chunk-HAXW27SS.js} +2 -2
- package/dist-cli/chunks/{chunk-ZMZTHU7V.js → chunk-IZAHPAN6.js} +1 -1
- package/dist-cli/chunks/{chunk-SI3BUTQR.js → chunk-J62KM5TB.js} +2 -2
- package/dist-cli/chunks/{chunk-Y2FSZSO7.js → chunk-JEMCD5E4.js} +1 -1
- package/dist-cli/chunks/{chunk-T4FT6CM7.js → chunk-JZS3Q37N.js} +2 -2
- package/dist-cli/chunks/{chunk-2SA2VTGP.js → chunk-KR4JON7D.js} +1 -1
- package/dist-cli/chunks/chunk-KWCYKQIQ.js +4 -0
- package/dist-cli/chunks/{chunk-HG7ORJMT.js → chunk-MCWPL644.js} +2 -2
- package/dist-cli/chunks/chunk-MJYK3N2I.js +4 -0
- package/dist-cli/chunks/{chunk-YRV7HR3P.js → chunk-O6TRIZNS.js} +2 -2
- package/dist-cli/chunks/{chunk-WBT32R6N.js → chunk-P7XL2E73.js} +3 -3
- package/dist-cli/chunks/{chunk-MNGQ42QE.js → chunk-PFQTUKQ4.js} +62 -87
- package/dist-cli/chunks/{chunk-Q3RGLERJ.js → chunk-PG5RZCTN.js} +2 -2
- package/dist-cli/chunks/{chunk-OR3XTXEB.js → chunk-QGRI2Z4M.js} +2 -2
- package/dist-cli/chunks/chunk-QLXXE7GE.js +125 -0
- package/dist-cli/chunks/{chunk-KZW5WBGU.js → chunk-QOJJJWJE.js} +89 -133
- package/dist-cli/chunks/{chunk-BRIZOR4K.js → chunk-RWZY5427.js} +2 -2
- package/dist-cli/chunks/{chunk-TYE3WBSR.js → chunk-RZKU2K3J.js} +2 -2
- package/dist-cli/chunks/{chunk-7VWOSTD5.js → chunk-SBV4IK4H.js} +1 -1
- package/dist-cli/chunks/{chunk-FWYYCUAZ.js → chunk-SGMVFFMK.js} +1 -1
- package/dist-cli/chunks/{chunk-LDQ7HVCW.js → chunk-TAX4UT2N.js} +1 -1
- package/dist-cli/chunks/{chunk-G74YIEVS.js → chunk-TUOFAWXT.js} +1 -1
- package/dist-cli/chunks/{chunk-274UD5FD.js → chunk-UHZLOHGP.js} +1 -1
- package/dist-cli/chunks/{chunk-37I5AIS7.js → chunk-VC7V76U3.js} +1 -1
- package/dist-cli/chunks/{chunk-B7KMNHX7.js → chunk-VQVMLW4U.js} +1 -1
- package/dist-cli/chunks/{chunk-VZBLFMYC.js → chunk-VUKKYPZN.js} +2 -2
- package/dist-cli/chunks/{chunk-VUFRB347.js → chunk-WGGRJDRE.js} +1 -1
- package/dist-cli/chunks/chunk-X6H76EKP.js +15 -0
- package/dist-cli/chunks/chunk-XLZ5FNRT.js +27 -0
- package/dist-cli/chunks/{chunk-TCWQJILS.js → chunk-XULEACM4.js} +2 -2
- package/dist-cli/chunks/{chunk-XRGEEPJ5.js → chunk-YFSDM7AX.js} +4 -4
- package/dist-cli/chunks/chunk-YWI3UEVX.js +5 -0
- package/dist-cli/chunks/{chunk-TGQNQ6XT.js → chunk-ZBSJO4NB.js} +10 -9
- package/dist-cli/chunks/{cleanup-H3GWQB63.js → cleanup-EYLGCA6Z.js} +2 -2
- package/dist-cli/chunks/cli-version-LL2UGIHE.js +4 -0
- package/dist-cli/chunks/{compat-5WG2XJV7.js → compat-TLJYHB4E.js} +2 -2
- package/dist-cli/chunks/{config-ANMBVVLL.js → config-4JWUOEXK.js} +2 -2
- package/dist-cli/chunks/{control-NSGNQFJG.js → control-HPAOYF4N.js} +2 -2
- package/dist-cli/chunks/daemon-OYLASXLE.js +4 -0
- package/dist-cli/chunks/{debug-CHV2O2KF.js → debug-4BKXF6KI.js} +5 -5
- package/dist-cli/chunks/{desktop-FIPIK4CH.js → desktop-ZQ6ZD2S6.js} +3 -3
- package/dist-cli/chunks/{detox-CVUJP7K6.js → detox-WNPASSS3.js} +2 -2
- package/dist-cli/chunks/{device-6WCUM4W6.js → device-BXLXVG3V.js} +2 -2
- package/dist-cli/chunks/{diagnose-I6EMWEII.js → diagnose-3QX7W5RW.js} +2 -2
- package/dist-cli/chunks/{disk-cleanup-P27CYFTN.js → disk-cleanup-KSWKI7WB.js} +2 -2
- package/dist-cli/chunks/drivers-EPIEFF7P.js +4 -0
- package/dist-cli/chunks/{film-UOQFFYNF.js → film-GDMR33VO.js} +3 -3
- package/dist-cli/chunks/flow-NKMPBYCJ.js +4 -0
- package/dist-cli/chunks/help-OGCBHOKA.js +4 -0
- package/dist-cli/chunks/{hidden-runtime-alias-NJYFSJKZ.js → hidden-runtime-alias-S2GTDX3T.js} +2 -2
- package/dist-cli/chunks/home-paths-QRCDLTTV.js +4 -0
- package/dist-cli/chunks/inspect-FUYMOZPY.js +4 -0
- package/dist-cli/chunks/install-desktop-FR6YKW7Y.js +4 -0
- package/dist-cli/chunks/{login-BPFQENCX.js → login-IJAPUZHI.js} +4 -4
- package/dist-cli/chunks/{logout-5A45ZGY7.js → logout-QMXDFU2X.js} +2 -2
- package/dist-cli/chunks/{maestro-E4CSDMLM.js → maestro-ZXU3YCVX.js} +3 -3
- package/dist-cli/chunks/{maestro-generate-CKMOJQX2.js → maestro-generate-PYB5QY7K.js} +3 -3
- package/dist-cli/chunks/{mode-SZYNMIQF.js → mode-WGUCL5FZ.js} +2 -2
- package/dist-cli/chunks/{optional-demo-registry-FRH4SFVG.js → optional-demo-registry-WH2O6H36.js} +2 -2
- package/dist-cli/chunks/{perf-VXU2XJAX.js → perf-TOD3UFAH.js} +2 -2
- package/dist-cli/chunks/{permissions-IRIAOVND.js → permissions-I5BRJGTB.js} +2 -2
- package/dist-cli/chunks/{record-RY7FPLLH.js → record-ZYL2FYSK.js} +3 -3
- package/dist-cli/chunks/{report-issue-KNWXOE53.js → report-issue-TAI6DYZO.js} +2 -2
- package/dist-cli/chunks/reset-7YGYKQPQ.js +4 -0
- package/dist-cli/chunks/runtime-B4JO6QRI.js +4 -0
- package/dist-cli/chunks/{screenshot-command-QLALR6GY.js → screenshot-command-7ANLODZY.js} +7 -7
- package/dist-cli/chunks/{screenshot-layers-OQFMFVRL.js → screenshot-layers-A7FYXSVU.js} +3 -3
- package/dist-cli/chunks/{screenshots-capture-6TSRJFGB.js → screenshots-capture-WT2ZY6CB.js} +2 -2
- package/dist-cli/chunks/serve-TG5WKA4V.js +44 -0
- package/dist-cli/chunks/{setup-7V6UKX4U.js → setup-PCWLD22V.js} +2 -2
- package/dist-cli/chunks/{skills-QQBOSETH.js → skills-27ZHWCQS.js} +2 -2
- package/dist-cli/chunks/state-ZQVY46ZO.js +14 -0
- package/dist-cli/chunks/{storage-TAPMKK5O.js → storage-OYC57C4X.js} +6 -6
- package/dist-cli/chunks/store-32HSPZHI.js +4 -0
- package/dist-cli/chunks/telemetry-PBJR7XHR.js +4 -0
- package/dist-cli/chunks/{timeline-IAM564NA.js → timeline-RAJJFQT6.js} +2 -2
- package/dist-cli/chunks/{upgrade-CD55QXIX.js → upgrade-OEFNZRIP.js} +2 -2
- package/dist-cli/chunks/upload-LQJITLKK.js +4 -0
- package/dist-cli/chunks/version-NIXTY6PL.js +6 -0
- package/dist-cli/chunks/{web-6NW6YLPI.js → web-XBUTBVGR.js} +2 -2
- package/dist-cli/chunks/{what-happened-CZZDOOVG.js → what-happened-YNHRFUDX.js} +3 -3
- 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.cjs +20 -0
- package/dist-lib/cli-constants.cjs +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 +67 -28
- package/dist-lib/host/bridge-host.cjs +140 -12
- 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/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +2815 -40
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +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 +2549 -2061
- package/dist-lib/sdk.mjs +2543 -2061
- package/dist-lib/skills.cjs +493 -282
- package/dist-lib/vite.cjs +1 -1
- package/package.json +8 -2
- package/src/bridge-constants.ts +3 -4
- package/src/bridge-contract.ts +251 -0
- package/src/connect.ts +83 -0
- package/src/disk-cleanup.ts +30 -0
- package/src/home-paths.ts +81 -38
- package/src/host/bridge-host.ts +134 -6
- package/src/index.ts +27 -1
- package/src/sdk.ts +8 -0
- package/src/sim-client.ts +660 -0
- package/dist-cli/chunks/camera-6EAK7CUL.js +0 -22
- package/dist-cli/chunks/chunk-33FKQH54.js +0 -5
- package/dist-cli/chunks/chunk-66NF2KNG.js +0 -9
- package/dist-cli/chunks/chunk-6UKJB2VC.js +0 -125
- package/dist-cli/chunks/chunk-7INBNA3U.js +0 -26
- package/dist-cli/chunks/chunk-AY47WKS5.js +0 -23
- package/dist-cli/chunks/chunk-HMDOLCKG.js +0 -15
- package/dist-cli/chunks/chunk-KR5BGMBZ.js +0 -4
- package/dist-cli/chunks/chunk-NLEMQ4PY.js +0 -6
- package/dist-cli/chunks/chunk-PEPUGJVI.js +0 -4
- package/dist-cli/chunks/cli-version-3QPAJ3LC.js +0 -4
- package/dist-cli/chunks/daemon-JHF4BJ3U.js +0 -4
- package/dist-cli/chunks/drivers-HQ6AKZT6.js +0 -4
- package/dist-cli/chunks/flow-N27MRRNL.js +0 -4
- package/dist-cli/chunks/help-SF6FEGEE.js +0 -4
- package/dist-cli/chunks/home-paths-XOV44JEF.js +0 -4
- package/dist-cli/chunks/inspect-CWFRFQTY.js +0 -4
- package/dist-cli/chunks/install-desktop-KLQDNXZQ.js +0 -4
- package/dist-cli/chunks/runtime-AR3GJTGK.js +0 -4
- package/dist-cli/chunks/serve-F54J2NQO.js +0 -44
- package/dist-cli/chunks/store-7NX3S43H.js +0 -4
- package/dist-cli/chunks/telemetry-E7BUK6RA.js +0 -4
- package/dist-cli/chunks/upload-GZ6LIMYM.js +0 -4
- package/dist-cli/chunks/version-3DYJ5AS3.js +0 -6
package/dist-lib/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.314 | (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;
|
|
@@ -9436,9 +9436,9 @@ function safeChildPlistName(value) {
|
|
|
9436
9436
|
name: file.toLowerCase().endsWith(".plist") ? file : `${file}.plist`
|
|
9437
9437
|
};
|
|
9438
9438
|
}
|
|
9439
|
-
async function readableSettingsBundle(
|
|
9439
|
+
async function readableSettingsBundle(path17) {
|
|
9440
9440
|
try {
|
|
9441
|
-
const root = await (0, import_promises.stat)((0, import_node_path.join)(
|
|
9441
|
+
const root = await (0, import_promises.stat)((0, import_node_path.join)(path17, "Root.plist"));
|
|
9442
9442
|
return root.isFile() && root.size <= MAX_PLIST_BYTES;
|
|
9443
9443
|
} catch {
|
|
9444
9444
|
return false;
|
|
@@ -9483,11 +9483,11 @@ async function settingsBundleFingerprint(bundlePath) {
|
|
|
9483
9483
|
return null;
|
|
9484
9484
|
}
|
|
9485
9485
|
}
|
|
9486
|
-
async function parsePlistRecord(
|
|
9486
|
+
async function parsePlistRecord(path17) {
|
|
9487
9487
|
try {
|
|
9488
|
-
const metadata = await (0, import_promises.stat)(
|
|
9488
|
+
const metadata = await (0, import_promises.stat)(path17);
|
|
9489
9489
|
if (!metadata.isFile() || metadata.size > MAX_PLIST_BYTES) return null;
|
|
9490
|
-
const source = await (0, import_promises.readFile)(
|
|
9490
|
+
const source = await (0, import_promises.readFile)(path17, "utf8");
|
|
9491
9491
|
const parsed = parsePlistSource(source);
|
|
9492
9492
|
return isRecord2(parsed) ? parsed : null;
|
|
9493
9493
|
} catch {
|
|
@@ -9766,10 +9766,10 @@ function tcpPing(port, timeout = TCP_GATE_MS) {
|
|
|
9766
9766
|
sock.connect(port, "localhost");
|
|
9767
9767
|
});
|
|
9768
9768
|
}
|
|
9769
|
-
function httpGet(port,
|
|
9769
|
+
function httpGet(port, path17, method = "GET", timeout = TIMEOUT_MS, headers = {}) {
|
|
9770
9770
|
return new Promise((resolve7) => {
|
|
9771
9771
|
const req = import_http.default.request(
|
|
9772
|
-
{ hostname: "localhost", port, path:
|
|
9772
|
+
{ hostname: "localhost", port, path: path17, method, timeout, headers },
|
|
9773
9773
|
(res) => {
|
|
9774
9774
|
let body = "";
|
|
9775
9775
|
res.on("data", (c) => body += c.toString());
|
|
@@ -10330,11 +10330,12 @@ __export(home_paths_exports, {
|
|
|
10330
10330
|
CONFIG_FILE: () => CONFIG_FILE,
|
|
10331
10331
|
DAEMON_HEARTBEAT_STALE_MS: () => DAEMON_HEARTBEAT_STALE_MS,
|
|
10332
10332
|
DAEMON_LOCKFILE: () => DAEMON_LOCKFILE,
|
|
10333
|
-
|
|
10333
|
+
DEV_BRIDGES_DIR: () => DEV_BRIDGES_DIR,
|
|
10334
10334
|
SOOTSIM_HOME_ENV: () => SOOTSIM_HOME_ENV,
|
|
10335
10335
|
activeRuntimeDir: () => activeRuntimeDir,
|
|
10336
10336
|
activeRuntimeFile: () => activeRuntimeFile,
|
|
10337
10337
|
cacheDir: () => cacheDir,
|
|
10338
|
+
cameraFixturesDir: () => cameraFixturesDir,
|
|
10338
10339
|
claimDaemonLockfile: () => claimDaemonLockfile,
|
|
10339
10340
|
configFilePath: () => configFilePath,
|
|
10340
10341
|
consumeRuntimeUpgradeNotice: () => consumeRuntimeUpgradeNotice,
|
|
@@ -10343,6 +10344,7 @@ __export(home_paths_exports, {
|
|
|
10343
10344
|
daemonAppLauncherPath: () => daemonAppLauncherPath,
|
|
10344
10345
|
daemonLockfilePath: () => daemonLockfilePath,
|
|
10345
10346
|
devBridgeLockfilePath: () => devBridgeLockfilePath,
|
|
10347
|
+
devBridgesDir: () => devBridgesDir,
|
|
10346
10348
|
electronDir: () => electronDir,
|
|
10347
10349
|
electronUserDataDir: () => electronUserDataDir,
|
|
10348
10350
|
electronVersionDir: () => electronVersionDir,
|
|
@@ -10354,7 +10356,7 @@ __export(home_paths_exports, {
|
|
|
10354
10356
|
profilesDir: () => profilesDir,
|
|
10355
10357
|
readActiveRuntime: () => readActiveRuntime,
|
|
10356
10358
|
readDaemonLockfile: () => readDaemonLockfile,
|
|
10357
|
-
|
|
10359
|
+
readDevBridgeLockfiles: () => readDevBridgeLockfiles,
|
|
10358
10360
|
readLiveRuntimeVersions: () => readLiveRuntimeVersions,
|
|
10359
10361
|
readOrCreateAnonymousId: () => readOrCreateAnonymousId,
|
|
10360
10362
|
readPrivacyPreferences: () => readPrivacyPreferences,
|
|
@@ -10420,6 +10422,9 @@ function electronVersionDir(version) {
|
|
|
10420
10422
|
function profilesDir() {
|
|
10421
10423
|
return import_node_path4.default.join(sootsimHomeDir(), "profiles");
|
|
10422
10424
|
}
|
|
10425
|
+
function cameraFixturesDir() {
|
|
10426
|
+
return import_node_path4.default.join(sootsimHomeDir(), "camera-fixtures");
|
|
10427
|
+
}
|
|
10423
10428
|
function daemonAppDir() {
|
|
10424
10429
|
return import_node_path4.default.join(sootsimHomeDir(), "daemon-app");
|
|
10425
10430
|
}
|
|
@@ -10435,8 +10440,14 @@ function cacheDir() {
|
|
|
10435
10440
|
function daemonLockfilePath() {
|
|
10436
10441
|
return import_node_path4.default.join(sootsimHomeDir(), DAEMON_LOCKFILE);
|
|
10437
10442
|
}
|
|
10438
|
-
function
|
|
10439
|
-
return import_node_path4.default.join(sootsimHomeDir(),
|
|
10443
|
+
function devBridgesDir() {
|
|
10444
|
+
return import_node_path4.default.join(sootsimHomeDir(), DEV_BRIDGES_DIR);
|
|
10445
|
+
}
|
|
10446
|
+
function devBridgeLockfilePath(bridgePort) {
|
|
10447
|
+
if (!Number.isInteger(bridgePort) || bridgePort <= 0) {
|
|
10448
|
+
throw new Error(`invalid development bridge port: ${bridgePort}`);
|
|
10449
|
+
}
|
|
10450
|
+
return import_node_path4.default.join(devBridgesDir(), `${bridgePort}.json`);
|
|
10440
10451
|
}
|
|
10441
10452
|
function configFilePath() {
|
|
10442
10453
|
return import_node_path4.default.join(sootsimHomeDir(), CONFIG_FILE);
|
|
@@ -10565,25 +10576,47 @@ function readDaemonLockfile() {
|
|
|
10565
10576
|
return null;
|
|
10566
10577
|
}
|
|
10567
10578
|
}
|
|
10568
|
-
function
|
|
10579
|
+
function parseDevBridgeLockfile(raw) {
|
|
10569
10580
|
try {
|
|
10570
|
-
const
|
|
10571
|
-
|
|
10572
|
-
|
|
10573
|
-
const bytesRead = import_node_fs3.default.readSync(fd, buf, 0, DAEMON_LOCKFILE_MAX_BYTES, 0);
|
|
10574
|
-
const raw = buf.subarray(0, bytesRead).toString("utf8");
|
|
10575
|
-
const parsed = JSON.parse(raw);
|
|
10576
|
-
if (parsed && parsed.schema === 1 && parsed.source === "vite-dev" && typeof parsed.pid === "number" && typeof parsed.bridgePort === "number" && typeof parsed.runtimePort === "number" && typeof parsed.cwd === "string" && typeof parsed.startedAt === "number" && typeof parsed.heartbeatAt === "number" && (parsed.shellPort === void 0 || typeof parsed.shellPort === "number") && (parsed.servedRuntimes === void 0 || Array.isArray(parsed.servedRuntimes) && parsed.servedRuntimes.every((version) => typeof version === "string"))) {
|
|
10577
|
-
return parsed;
|
|
10578
|
-
}
|
|
10579
|
-
return null;
|
|
10580
|
-
} finally {
|
|
10581
|
-
import_node_fs3.default.closeSync(fd);
|
|
10581
|
+
const parsed = JSON.parse(raw);
|
|
10582
|
+
if (parsed && parsed.schema === 1 && parsed.source === "vite-dev" && typeof parsed.pid === "number" && typeof parsed.bridgePort === "number" && typeof parsed.runtimePort === "number" && typeof parsed.cwd === "string" && typeof parsed.startedAt === "number" && typeof parsed.heartbeatAt === "number" && (parsed.shellPort === void 0 || typeof parsed.shellPort === "number") && (parsed.servedRuntimes === void 0 || Array.isArray(parsed.servedRuntimes) && parsed.servedRuntimes.every((version) => typeof version === "string"))) {
|
|
10583
|
+
return parsed;
|
|
10582
10584
|
}
|
|
10585
|
+
return null;
|
|
10583
10586
|
} catch {
|
|
10584
10587
|
return null;
|
|
10585
10588
|
}
|
|
10586
10589
|
}
|
|
10590
|
+
function readDevBridgeLockfiles() {
|
|
10591
|
+
let entries;
|
|
10592
|
+
try {
|
|
10593
|
+
entries = import_node_fs3.default.readdirSync(devBridgesDir(), { withFileTypes: true });
|
|
10594
|
+
} catch {
|
|
10595
|
+
return [];
|
|
10596
|
+
}
|
|
10597
|
+
const lockfiles = [];
|
|
10598
|
+
for (const entry of entries) {
|
|
10599
|
+
if (!entry.isFile() || !/^\d+\.json$/.test(entry.name)) continue;
|
|
10600
|
+
try {
|
|
10601
|
+
const filePath = import_node_path4.default.join(devBridgesDir(), entry.name);
|
|
10602
|
+
const fd = import_node_fs3.default.openSync(filePath, "r");
|
|
10603
|
+
try {
|
|
10604
|
+
const buf = Buffer.alloc(DAEMON_LOCKFILE_MAX_BYTES);
|
|
10605
|
+
const bytesRead = import_node_fs3.default.readSync(fd, buf, 0, DAEMON_LOCKFILE_MAX_BYTES, 0);
|
|
10606
|
+
const lockfile = parseDevBridgeLockfile(
|
|
10607
|
+
buf.subarray(0, bytesRead).toString("utf8")
|
|
10608
|
+
);
|
|
10609
|
+
if (lockfile && entry.name === `${lockfile.bridgePort}.json`) {
|
|
10610
|
+
lockfiles.push(lockfile);
|
|
10611
|
+
}
|
|
10612
|
+
} finally {
|
|
10613
|
+
import_node_fs3.default.closeSync(fd);
|
|
10614
|
+
}
|
|
10615
|
+
} catch {
|
|
10616
|
+
}
|
|
10617
|
+
}
|
|
10618
|
+
return lockfiles.sort((left, right) => left.bridgePort - right.bridgePort);
|
|
10619
|
+
}
|
|
10587
10620
|
function isDaemonLockfileFresh(lock, now = Date.now()) {
|
|
10588
10621
|
if (!lock) return false;
|
|
10589
10622
|
if (now - lock.heartbeatAt > DAEMON_HEARTBEAT_STALE_MS) return false;
|
|
@@ -10611,8 +10644,8 @@ function readLiveRuntimeVersions() {
|
|
|
10611
10644
|
if (daemon.activeRuntime) versions.add(daemon.activeRuntime);
|
|
10612
10645
|
for (const version of daemon.servedRuntimes ?? []) versions.add(version);
|
|
10613
10646
|
}
|
|
10614
|
-
const devBridge
|
|
10615
|
-
|
|
10647
|
+
for (const devBridge of readDevBridgeLockfiles()) {
|
|
10648
|
+
if (!isDevBridgeLockfileFresh(devBridge)) continue;
|
|
10616
10649
|
for (const version of devBridge.servedRuntimes ?? []) versions.add(version);
|
|
10617
10650
|
}
|
|
10618
10651
|
return [...versions].sort();
|
|
@@ -10625,11 +10658,12 @@ function writeDaemonLockfile(data) {
|
|
|
10625
10658
|
import_node_fs3.default.renameSync(tmp, daemonLockfilePath());
|
|
10626
10659
|
}
|
|
10627
10660
|
function writeDevBridgeLockfile(data) {
|
|
10628
|
-
|
|
10629
|
-
const
|
|
10661
|
+
import_node_fs3.default.mkdirSync(devBridgesDir(), { recursive: true });
|
|
10662
|
+
const lockfilePath = devBridgeLockfilePath(data.bridgePort);
|
|
10663
|
+
const tmp = `${lockfilePath}.${data.pid}.tmp`;
|
|
10630
10664
|
import_node_fs3.default.writeFileSync(tmp, `${JSON.stringify(data, null, 2)}
|
|
10631
10665
|
`, "utf8");
|
|
10632
|
-
import_node_fs3.default.renameSync(tmp,
|
|
10666
|
+
import_node_fs3.default.renameSync(tmp, lockfilePath);
|
|
10633
10667
|
}
|
|
10634
10668
|
function claimDaemonLockfile(data) {
|
|
10635
10669
|
ensureSootsimHome();
|
|
@@ -10646,13 +10680,16 @@ function removeDaemonLockfile() {
|
|
|
10646
10680
|
} catch {
|
|
10647
10681
|
}
|
|
10648
10682
|
}
|
|
10649
|
-
function removeDevBridgeLockfile() {
|
|
10683
|
+
function removeDevBridgeLockfile(owner) {
|
|
10650
10684
|
try {
|
|
10651
|
-
|
|
10685
|
+
const lockfilePath = devBridgeLockfilePath(owner.bridgePort);
|
|
10686
|
+
const lockfile = parseDevBridgeLockfile(import_node_fs3.default.readFileSync(lockfilePath, "utf8"));
|
|
10687
|
+
if (lockfile?.pid !== owner.pid || lockfile.startedAt !== owner.startedAt) return;
|
|
10688
|
+
import_node_fs3.default.unlinkSync(lockfilePath);
|
|
10652
10689
|
} catch {
|
|
10653
10690
|
}
|
|
10654
10691
|
}
|
|
10655
|
-
var import_node_crypto, import_node_fs3, import_node_os, import_node_path4, SOOTSIM_HOME_ENV, ACTIVE_RUNTIME_FILE, DAEMON_LOCKFILE,
|
|
10692
|
+
var import_node_crypto, import_node_fs3, import_node_os, import_node_path4, SOOTSIM_HOME_ENV, ACTIVE_RUNTIME_FILE, DAEMON_LOCKFILE, DEV_BRIDGES_DIR, CONFIG_FILE, DAEMON_HEARTBEAT_STALE_MS, DAEMON_LOCKFILE_MAX_BYTES;
|
|
10656
10693
|
var init_home_paths = __esm({
|
|
10657
10694
|
"src/home-paths.ts"() {
|
|
10658
10695
|
"use strict";
|
|
@@ -10663,7 +10700,7 @@ var init_home_paths = __esm({
|
|
|
10663
10700
|
SOOTSIM_HOME_ENV = "SOOTSIM_HOME";
|
|
10664
10701
|
ACTIVE_RUNTIME_FILE = "active";
|
|
10665
10702
|
DAEMON_LOCKFILE = "daemon.json";
|
|
10666
|
-
|
|
10703
|
+
DEV_BRIDGES_DIR = "dev-bridges";
|
|
10667
10704
|
CONFIG_FILE = "config.json";
|
|
10668
10705
|
DAEMON_HEARTBEAT_STALE_MS = 3e4;
|
|
10669
10706
|
DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
|
|
@@ -13211,7 +13248,7 @@ function unrefTimer(timer) {
|
|
|
13211
13248
|
timer.unref();
|
|
13212
13249
|
}
|
|
13213
13250
|
}
|
|
13214
|
-
var import_child_process3, import_fs2, import_http3, import_path2, import_ws2, SOOTSIM_CROSS_ORIGIN_EMBEDDER_POLICY, WRITE_COMMAND_TYPES, FORCE_CLOSE_GRACE_MS, FORCE_CLOSE_TERMINATE_MS, DAEMON_HEARTBEAT_INTERVAL_MS, DEFAULT_RUNTIME_UPDATE_INTERVAL_MS, RUNTIME_UPDATE_INTERVAL_ENV, HTTP_MIME_TYPES, SootSimBridgeHost;
|
|
13251
|
+
var import_child_process3, import_fs2, import_http3, import_path2, import_ws2, SOOTSIM_CROSS_ORIGIN_EMBEDDER_POLICY, WRITE_COMMAND_TYPES, FORCE_CLOSE_GRACE_MS, FORCE_CLOSE_TERMINATE_MS, DAEMON_HEARTBEAT_INTERVAL_MS, DEFAULT_RUNTIME_UPDATE_INTERVAL_MS, RUNTIME_UPDATE_INTERVAL_ENV, HTTP_MIME_TYPES, CAMERA_FIXTURE_ROUTE, CAMERA_FIXTURE_NAME_RE, SootSimBridgeHost;
|
|
13215
13252
|
var init_bridge_host = __esm({
|
|
13216
13253
|
"src/host/bridge-host.ts"() {
|
|
13217
13254
|
"use strict";
|
|
@@ -13231,7 +13268,14 @@ var init_bridge_host = __esm({
|
|
|
13231
13268
|
init_open_url();
|
|
13232
13269
|
init_websocket_proxy();
|
|
13233
13270
|
SOOTSIM_CROSS_ORIGIN_EMBEDDER_POLICY = "require-corp";
|
|
13234
|
-
WRITE_COMMAND_TYPES = /* @__PURE__ */ new Set([
|
|
13271
|
+
WRITE_COMMAND_TYPES = /* @__PURE__ */ new Set([
|
|
13272
|
+
"tap",
|
|
13273
|
+
"keyboard",
|
|
13274
|
+
"longPress",
|
|
13275
|
+
"perform",
|
|
13276
|
+
"reset",
|
|
13277
|
+
"camera"
|
|
13278
|
+
]);
|
|
13235
13279
|
FORCE_CLOSE_GRACE_MS = 2e3;
|
|
13236
13280
|
FORCE_CLOSE_TERMINATE_MS = 1e3;
|
|
13237
13281
|
DAEMON_HEARTBEAT_INTERVAL_MS = 5e3;
|
|
@@ -13258,8 +13302,14 @@ var init_bridge_host = __esm({
|
|
|
13258
13302
|
".woff": "font/woff",
|
|
13259
13303
|
".woff2": "font/woff2",
|
|
13260
13304
|
".map": "application/json",
|
|
13261
|
-
".txt": "text/plain; charset=utf-8"
|
|
13305
|
+
".txt": "text/plain; charset=utf-8",
|
|
13306
|
+
".mp4": "video/mp4",
|
|
13307
|
+
".m4v": "video/mp4",
|
|
13308
|
+
".webm": "video/webm",
|
|
13309
|
+
".mov": "video/quicktime"
|
|
13262
13310
|
};
|
|
13311
|
+
CAMERA_FIXTURE_ROUTE = "/__camera-fixtures/";
|
|
13312
|
+
CAMERA_FIXTURE_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
13263
13313
|
SootSimBridgeHost = class _SootSimBridgeHost {
|
|
13264
13314
|
port;
|
|
13265
13315
|
openUrlHandler;
|
|
@@ -14019,6 +14069,89 @@ var init_bridge_host = __esm({
|
|
|
14019
14069
|
});
|
|
14020
14070
|
return this.inflightScan;
|
|
14021
14071
|
}
|
|
14072
|
+
// serves one staged camera fixture. addressed by basename inside
|
|
14073
|
+
// ~/.sootsim/camera-fixtures, never by a caller-supplied path, so there is
|
|
14074
|
+
// no traversal surface to defend: a name that is not a plain basename is
|
|
14075
|
+
// rejected outright. range support is not optional here — chrome asks for
|
|
14076
|
+
// byte ranges on media and cannot seek or loop a fixture without it.
|
|
14077
|
+
handleCameraFixture(name2, req, res) {
|
|
14078
|
+
const method = (req.method || "GET").toUpperCase();
|
|
14079
|
+
const cors = {
|
|
14080
|
+
"Access-Control-Allow-Origin": "*",
|
|
14081
|
+
"Cache-Control": "no-store"
|
|
14082
|
+
};
|
|
14083
|
+
if (method === "OPTIONS") {
|
|
14084
|
+
res.writeHead(204, {
|
|
14085
|
+
...cors,
|
|
14086
|
+
"Access-Control-Allow-Methods": "GET, HEAD, OPTIONS",
|
|
14087
|
+
"Access-Control-Allow-Headers": "range"
|
|
14088
|
+
});
|
|
14089
|
+
res.end();
|
|
14090
|
+
return;
|
|
14091
|
+
}
|
|
14092
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
14093
|
+
res.writeHead(405, cors);
|
|
14094
|
+
res.end();
|
|
14095
|
+
return;
|
|
14096
|
+
}
|
|
14097
|
+
if (!CAMERA_FIXTURE_NAME_RE.test(name2)) {
|
|
14098
|
+
res.writeHead(400, { ...cors, "Content-Type": "text/plain; charset=utf-8" });
|
|
14099
|
+
res.end("bad fixture name");
|
|
14100
|
+
return;
|
|
14101
|
+
}
|
|
14102
|
+
const root = cameraFixturesDir();
|
|
14103
|
+
const filePath = import_path2.default.join(root, name2);
|
|
14104
|
+
let stats;
|
|
14105
|
+
try {
|
|
14106
|
+
stats = import_fs2.default.lstatSync(filePath);
|
|
14107
|
+
} catch {
|
|
14108
|
+
res.writeHead(404, { ...cors, "Content-Type": "text/plain; charset=utf-8" });
|
|
14109
|
+
res.end("not found");
|
|
14110
|
+
return;
|
|
14111
|
+
}
|
|
14112
|
+
if (!stats.isFile()) {
|
|
14113
|
+
res.writeHead(403, { ...cors, "Content-Type": "text/plain; charset=utf-8" });
|
|
14114
|
+
res.end("forbidden");
|
|
14115
|
+
return;
|
|
14116
|
+
}
|
|
14117
|
+
const contentType = HTTP_MIME_TYPES[import_path2.default.extname(filePath).toLowerCase()] || "application/octet-stream";
|
|
14118
|
+
const total = stats.size;
|
|
14119
|
+
const range = /^bytes=(\d*)-(\d*)$/.exec(req.headers.range || "");
|
|
14120
|
+
if (range) {
|
|
14121
|
+
const [, startRaw, endRaw] = range;
|
|
14122
|
+
const start = startRaw ? Number(startRaw) : 0;
|
|
14123
|
+
const end = endRaw ? Math.min(Number(endRaw), total - 1) : total - 1;
|
|
14124
|
+
if (!Number.isFinite(start) || start > end || start >= total) {
|
|
14125
|
+
res.writeHead(416, { ...cors, "Content-Range": `bytes */${total}` });
|
|
14126
|
+
res.end();
|
|
14127
|
+
return;
|
|
14128
|
+
}
|
|
14129
|
+
res.writeHead(206, {
|
|
14130
|
+
...cors,
|
|
14131
|
+
"Content-Type": contentType,
|
|
14132
|
+
"Content-Range": `bytes ${start}-${end}/${total}`,
|
|
14133
|
+
"Accept-Ranges": "bytes",
|
|
14134
|
+
"Content-Length": String(end - start + 1)
|
|
14135
|
+
});
|
|
14136
|
+
if (method === "HEAD") {
|
|
14137
|
+
res.end();
|
|
14138
|
+
return;
|
|
14139
|
+
}
|
|
14140
|
+
import_fs2.default.createReadStream(filePath, { start, end }).pipe(res);
|
|
14141
|
+
return;
|
|
14142
|
+
}
|
|
14143
|
+
res.writeHead(200, {
|
|
14144
|
+
...cors,
|
|
14145
|
+
"Content-Type": contentType,
|
|
14146
|
+
"Accept-Ranges": "bytes",
|
|
14147
|
+
"Content-Length": String(total)
|
|
14148
|
+
});
|
|
14149
|
+
if (method === "HEAD") {
|
|
14150
|
+
res.end();
|
|
14151
|
+
return;
|
|
14152
|
+
}
|
|
14153
|
+
import_fs2.default.createReadStream(filePath).pipe(res);
|
|
14154
|
+
}
|
|
14022
14155
|
handleServerScan(res) {
|
|
14023
14156
|
const sendJson = (body) => {
|
|
14024
14157
|
res.writeHead(200, {
|
|
@@ -14242,6 +14375,10 @@ var init_bridge_host = __esm({
|
|
|
14242
14375
|
res.end("method not allowed");
|
|
14243
14376
|
return;
|
|
14244
14377
|
}
|
|
14378
|
+
if (url.pathname.startsWith(CAMERA_FIXTURE_ROUTE)) {
|
|
14379
|
+
this.handleCameraFixture(url.pathname.slice(CAMERA_FIXTURE_ROUTE.length), req, res);
|
|
14380
|
+
return;
|
|
14381
|
+
}
|
|
14245
14382
|
if (method !== "GET" && method !== "HEAD") {
|
|
14246
14383
|
res.writeHead(405, { Allow: "GET, HEAD" });
|
|
14247
14384
|
res.end("method not allowed");
|
|
@@ -14710,7 +14847,11 @@ var init_bridge_host = __esm({
|
|
|
14710
14847
|
}
|
|
14711
14848
|
if (this.shouldWriteDevLockfile) {
|
|
14712
14849
|
try {
|
|
14713
|
-
removeDevBridgeLockfile(
|
|
14850
|
+
removeDevBridgeLockfile({
|
|
14851
|
+
bridgePort: this.effectivePort,
|
|
14852
|
+
pid: process.pid,
|
|
14853
|
+
startedAt: this.startedAt
|
|
14854
|
+
});
|
|
14714
14855
|
} catch {
|
|
14715
14856
|
}
|
|
14716
14857
|
}
|
|
@@ -15465,6 +15606,53 @@ __export(ws_bridge_exports, {
|
|
|
15465
15606
|
resolveDefaultBridgePort: () => resolveDefaultBridgePort,
|
|
15466
15607
|
worldForBridgePort: () => worldForBridgePort
|
|
15467
15608
|
});
|
|
15609
|
+
function liveDevBridgeLockfiles() {
|
|
15610
|
+
return readDevBridgeLockfiles().filter((lockfile) => isDevBridgeLockfileFresh(lockfile));
|
|
15611
|
+
}
|
|
15612
|
+
function checkoutRoot(cwd) {
|
|
15613
|
+
let current = import_node_path10.default.resolve(cwd);
|
|
15614
|
+
while (true) {
|
|
15615
|
+
if (import_node_fs9.default.existsSync(import_node_path10.default.join(current, ".git"))) return current;
|
|
15616
|
+
const parent = import_node_path10.default.dirname(current);
|
|
15617
|
+
if (parent === current) return null;
|
|
15618
|
+
current = parent;
|
|
15619
|
+
}
|
|
15620
|
+
}
|
|
15621
|
+
function pathContains(parent, child) {
|
|
15622
|
+
const relative = import_node_path10.default.relative(parent, child);
|
|
15623
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${import_node_path10.default.sep}`) && !import_node_path10.default.isAbsolute(relative);
|
|
15624
|
+
}
|
|
15625
|
+
function resolveDefaultDevBridgeLockfile() {
|
|
15626
|
+
const lockfiles = liveDevBridgeLockfiles();
|
|
15627
|
+
if (lockfiles.length === 0) return null;
|
|
15628
|
+
if (process.env.SOOTSIM_BRIDGE_PORT !== void 0 || process.env.PORT_OFFSET !== void 0) {
|
|
15629
|
+
const requestedPort = resolveSootsimBridgePort({
|
|
15630
|
+
explicitPort: process.env.SOOTSIM_BRIDGE_PORT,
|
|
15631
|
+
portOffset: process.env.PORT_OFFSET
|
|
15632
|
+
});
|
|
15633
|
+
const requested = lockfiles.find((lockfile) => lockfile.bridgePort === requestedPort);
|
|
15634
|
+
if (requested) return requested;
|
|
15635
|
+
}
|
|
15636
|
+
let cwd = null;
|
|
15637
|
+
try {
|
|
15638
|
+
cwd = process.cwd();
|
|
15639
|
+
} catch {
|
|
15640
|
+
}
|
|
15641
|
+
if (cwd) {
|
|
15642
|
+
const currentCheckout = checkoutRoot(cwd);
|
|
15643
|
+
const sameCheckout = lockfiles.filter((lockfile) => {
|
|
15644
|
+
const bridgeCheckout = checkoutRoot(lockfile.cwd);
|
|
15645
|
+
if (currentCheckout && bridgeCheckout) return currentCheckout === bridgeCheckout;
|
|
15646
|
+
return pathContains(cwd, lockfile.cwd) || pathContains(lockfile.cwd, cwd);
|
|
15647
|
+
});
|
|
15648
|
+
if (sameCheckout.length > 0) {
|
|
15649
|
+
return sameCheckout.find(
|
|
15650
|
+
(lockfile) => lockfile.bridgePort === DEFAULT_SOOTSIM_BRIDGE_PORT
|
|
15651
|
+
) ?? sameCheckout[0];
|
|
15652
|
+
}
|
|
15653
|
+
}
|
|
15654
|
+
return lockfiles.find((lockfile) => lockfile.bridgePort === DEFAULT_SOOTSIM_BRIDGE_PORT) ?? lockfiles[0];
|
|
15655
|
+
}
|
|
15468
15656
|
function resolveBridgeWorld() {
|
|
15469
15657
|
const homeDir = sootsimHomeDir();
|
|
15470
15658
|
if (resolvedWorld?.homeDir === homeDir) return resolvedWorld.world;
|
|
@@ -15473,8 +15661,8 @@ function resolveBridgeWorld() {
|
|
|
15473
15661
|
return world;
|
|
15474
15662
|
}
|
|
15475
15663
|
function resolveBridgeWorldFresh() {
|
|
15476
|
-
const dev =
|
|
15477
|
-
if (dev
|
|
15664
|
+
const dev = resolveDefaultDevBridgeLockfile();
|
|
15665
|
+
if (dev) {
|
|
15478
15666
|
return {
|
|
15479
15667
|
source: "dev-bridge",
|
|
15480
15668
|
bridgePort: dev.bridgePort,
|
|
@@ -15498,8 +15686,8 @@ function resolveBridgeWorldFresh() {
|
|
|
15498
15686
|
};
|
|
15499
15687
|
}
|
|
15500
15688
|
function worldForBridgePort(port) {
|
|
15501
|
-
const dev =
|
|
15502
|
-
if (dev
|
|
15689
|
+
const dev = liveDevBridgeLockfiles().find((lockfile) => lockfile.bridgePort === port);
|
|
15690
|
+
if (dev) {
|
|
15503
15691
|
return {
|
|
15504
15692
|
source: "dev-bridge",
|
|
15505
15693
|
shellBaseUrl: dev.shellPort ? `http://localhost:${dev.shellPort}/` : DEFAULT_SOOTSIM_SHELL_URL
|
|
@@ -15523,8 +15711,10 @@ function bridgePortForShellBaseUrl(baseUrl) {
|
|
|
15523
15711
|
return null;
|
|
15524
15712
|
}
|
|
15525
15713
|
if (!Number.isFinite(port) || port <= 0) return null;
|
|
15526
|
-
const dev =
|
|
15527
|
-
|
|
15714
|
+
const dev = liveDevBridgeLockfiles().find(
|
|
15715
|
+
(lockfile) => lockfile.shellPort === port || lockfile.runtimePort === port || lockfile.bridgePort === port
|
|
15716
|
+
);
|
|
15717
|
+
if (dev) {
|
|
15528
15718
|
return dev.bridgePort;
|
|
15529
15719
|
}
|
|
15530
15720
|
const lock = readDaemonLockfile();
|
|
@@ -15539,7 +15729,7 @@ function resolveDefaultBridgePort() {
|
|
|
15539
15729
|
function printBridgeWorldNotice(bridgePort, shellBaseUrl) {
|
|
15540
15730
|
const world = worldForBridgePort(bridgePort);
|
|
15541
15731
|
const kind = world?.source === "dev-bridge" ? "dev bridge" : world?.source === "daemon" ? "daemon bridge" : "bridge";
|
|
15542
|
-
const origin = world ?
|
|
15732
|
+
const origin = world?.source === "dev-bridge" ? `dev-bridges/${bridgePort}.json` : world?.source === "daemon" ? "daemon.json" : "no lockfile";
|
|
15543
15733
|
const shell = shellBaseUrl ?? world?.shellBaseUrl;
|
|
15544
15734
|
process.stderr.write(
|
|
15545
15735
|
` \u2192 ${kind} :${bridgePort} (${shell ? `shell ${shell}, ` : ""}${origin})
|
|
@@ -15659,6 +15849,8 @@ function createBridge(wsPort, opts = {}) {
|
|
|
15659
15849
|
reject(new Error(`could not connect to ws://localhost:${wsPort}${cause}`));
|
|
15660
15850
|
});
|
|
15661
15851
|
});
|
|
15852
|
+
ready.catch(() => {
|
|
15853
|
+
});
|
|
15662
15854
|
let warnedAboutContention = false;
|
|
15663
15855
|
let noticedTarget = false;
|
|
15664
15856
|
function maybeNoticeTarget(cmdType, simId) {
|
|
@@ -15851,16 +16043,18 @@ async function evalInBridge(bridge, code, opts = {}) {
|
|
|
15851
16043
|
if (opts.acquireLock) payload.acquireLock = true;
|
|
15852
16044
|
return bridge.send(payload);
|
|
15853
16045
|
}
|
|
15854
|
-
async function callInBridge(bridge,
|
|
15855
|
-
return bridge.send({ type: "call", path:
|
|
16046
|
+
async function callInBridge(bridge, path17, ...args) {
|
|
16047
|
+
return bridge.send({ type: "call", path: path17, args });
|
|
15856
16048
|
}
|
|
15857
|
-
async function callInBridgeWrite(bridge,
|
|
15858
|
-
return bridge.send({ type: "call", path:
|
|
16049
|
+
async function callInBridgeWrite(bridge, path17, ...args) {
|
|
16050
|
+
return bridge.send({ type: "call", path: path17, args, acquireLock: true });
|
|
15859
16051
|
}
|
|
15860
|
-
var import_ws3, resolvedWorld, BridgeSimLockedError;
|
|
16052
|
+
var import_node_fs9, import_node_path10, import_ws3, resolvedWorld, BridgeSimLockedError;
|
|
15861
16053
|
var init_ws_bridge = __esm({
|
|
15862
16054
|
"cli/ws-bridge.ts"() {
|
|
15863
16055
|
"use strict";
|
|
16056
|
+
import_node_fs9 = __toESM(require("node:fs"), 1);
|
|
16057
|
+
import_node_path10 = __toESM(require("node:path"), 1);
|
|
15864
16058
|
import_ws3 = require("ws");
|
|
15865
16059
|
init_bridge_constants();
|
|
15866
16060
|
init_cli_constants();
|
|
@@ -15915,8 +16109,8 @@ function getDefaultPortForProtocol(protocol) {
|
|
|
15915
16109
|
return protocol === "https:" ? 443 : 80;
|
|
15916
16110
|
}
|
|
15917
16111
|
function isBaseServerUrl(url) {
|
|
15918
|
-
const
|
|
15919
|
-
return (
|
|
16112
|
+
const path17 = url.pathname || "/";
|
|
16113
|
+
return (path17 === "/" || path17 === "") && !url.search && !url.hash;
|
|
15920
16114
|
}
|
|
15921
16115
|
async function resolvePortViaServerScan(port) {
|
|
15922
16116
|
try {
|
|
@@ -16136,9 +16330,9 @@ var init_profiles = __esm({
|
|
|
16136
16330
|
// cli/app-project.ts
|
|
16137
16331
|
function firstNamedFile(dir, names) {
|
|
16138
16332
|
for (const name2 of names) {
|
|
16139
|
-
const candidate =
|
|
16333
|
+
const candidate = import_node_path11.default.join(dir, name2);
|
|
16140
16334
|
try {
|
|
16141
|
-
if (
|
|
16335
|
+
if (import_node_fs10.default.statSync(candidate).isFile()) return candidate;
|
|
16142
16336
|
} catch {
|
|
16143
16337
|
}
|
|
16144
16338
|
}
|
|
@@ -16152,7 +16346,7 @@ function findSootSimAppConfig(dir) {
|
|
|
16152
16346
|
}
|
|
16153
16347
|
function readWorkspacePatterns(rootDir) {
|
|
16154
16348
|
try {
|
|
16155
|
-
const value = JSON.parse(
|
|
16349
|
+
const value = JSON.parse(import_node_fs10.default.readFileSync(import_node_path11.default.join(rootDir, "package.json"), "utf8"));
|
|
16156
16350
|
if (!value || typeof value !== "object") return [];
|
|
16157
16351
|
const workspaces = Reflect.get(value, "workspaces");
|
|
16158
16352
|
if (Array.isArray(workspaces)) {
|
|
@@ -16174,7 +16368,7 @@ function workspaceDirectories(rootDir) {
|
|
|
16174
16368
|
complete = false;
|
|
16175
16369
|
break;
|
|
16176
16370
|
}
|
|
16177
|
-
if (!pattern ||
|
|
16371
|
+
if (!pattern || import_node_path11.default.isAbsolute(pattern)) continue;
|
|
16178
16372
|
const segments = pattern.split(/[\\/]+/).filter(Boolean);
|
|
16179
16373
|
if (segments.length === 0 || segments.length > MAX_SCAN_DEPTH) continue;
|
|
16180
16374
|
if (segments.some((segment) => segment === ".." || segment === "**")) continue;
|
|
@@ -16190,19 +16384,19 @@ function workspaceDirectories(rootDir) {
|
|
|
16190
16384
|
if (segment === "*") {
|
|
16191
16385
|
let entries;
|
|
16192
16386
|
try {
|
|
16193
|
-
entries =
|
|
16387
|
+
entries = import_node_fs10.default.readdirSync(parent, { withFileTypes: true });
|
|
16194
16388
|
} catch {
|
|
16195
16389
|
continue;
|
|
16196
16390
|
}
|
|
16197
16391
|
for (const entry of entries) {
|
|
16198
16392
|
if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
|
|
16199
16393
|
if (entry.name.startsWith(".") || SKIP_DIR_NAMES.has(entry.name)) continue;
|
|
16200
|
-
next.push(
|
|
16394
|
+
next.push(import_node_path11.default.join(parent, entry.name));
|
|
16201
16395
|
}
|
|
16202
16396
|
} else if (!segment.includes("*")) {
|
|
16203
|
-
const candidate =
|
|
16397
|
+
const candidate = import_node_path11.default.join(parent, segment);
|
|
16204
16398
|
try {
|
|
16205
|
-
const stat2 =
|
|
16399
|
+
const stat2 = import_node_fs10.default.lstatSync(candidate);
|
|
16206
16400
|
if (stat2.isDirectory() && !stat2.isSymbolicLink()) next.push(candidate);
|
|
16207
16401
|
} catch {
|
|
16208
16402
|
}
|
|
@@ -16235,7 +16429,7 @@ function boundedConfigDirectories(rootDir) {
|
|
|
16235
16429
|
if (current.depth >= MAX_SCAN_DEPTH) continue;
|
|
16236
16430
|
let entries;
|
|
16237
16431
|
try {
|
|
16238
|
-
entries =
|
|
16432
|
+
entries = import_node_fs10.default.readdirSync(current.dir, { withFileTypes: true });
|
|
16239
16433
|
} catch {
|
|
16240
16434
|
continue;
|
|
16241
16435
|
}
|
|
@@ -16246,22 +16440,22 @@ function boundedConfigDirectories(rootDir) {
|
|
|
16246
16440
|
complete = false;
|
|
16247
16441
|
break;
|
|
16248
16442
|
}
|
|
16249
|
-
queue.push({ dir:
|
|
16443
|
+
queue.push({ dir: import_node_path11.default.join(current.dir, entry.name), depth: current.depth + 1 });
|
|
16250
16444
|
}
|
|
16251
16445
|
}
|
|
16252
16446
|
return { directories: matches, complete: complete && nextIndex === queue.length };
|
|
16253
16447
|
}
|
|
16254
16448
|
function resolveAppProject(startDir, opts = {}) {
|
|
16255
|
-
const rootDir =
|
|
16449
|
+
const rootDir = import_node_path11.default.resolve(startDir);
|
|
16256
16450
|
const rootConfigPath = findSootSimAppConfig(rootDir);
|
|
16257
|
-
if (findExpoAppConfig(rootDir) || opts.trustStart &&
|
|
16451
|
+
if (findExpoAppConfig(rootDir) || opts.trustStart && import_node_fs10.default.existsSync(rootDir)) {
|
|
16258
16452
|
let configPath = rootConfigPath;
|
|
16259
16453
|
if (!configPath && opts.trustStart) {
|
|
16260
|
-
let parent =
|
|
16261
|
-
for (let depth = 0; depth < MAX_SCAN_DEPTH && parent !==
|
|
16454
|
+
let parent = import_node_path11.default.dirname(rootDir);
|
|
16455
|
+
for (let depth = 0; depth < MAX_SCAN_DEPTH && parent !== import_node_path11.default.dirname(parent); depth++) {
|
|
16262
16456
|
configPath = findSootSimAppConfig(parent);
|
|
16263
16457
|
if (configPath) break;
|
|
16264
|
-
parent =
|
|
16458
|
+
parent = import_node_path11.default.dirname(parent);
|
|
16265
16459
|
}
|
|
16266
16460
|
}
|
|
16267
16461
|
return { appDir: rootDir, configPath };
|
|
@@ -16293,12 +16487,12 @@ function resolveAppProject(startDir, opts = {}) {
|
|
|
16293
16487
|
if (rootConfigPath) return { appDir: rootDir, configPath: rootConfigPath };
|
|
16294
16488
|
return null;
|
|
16295
16489
|
}
|
|
16296
|
-
var
|
|
16490
|
+
var import_node_fs10, import_node_path11, EXPO_APP_CONFIG_NAMES, SOOTSIM_APP_CONFIG_NAMES, SKIP_DIR_NAMES, MAX_SCANNED_DIRECTORIES, MAX_SCAN_DEPTH;
|
|
16297
16491
|
var init_app_project = __esm({
|
|
16298
16492
|
"cli/app-project.ts"() {
|
|
16299
16493
|
"use strict";
|
|
16300
|
-
|
|
16301
|
-
|
|
16494
|
+
import_node_fs10 = __toESM(require("node:fs"), 1);
|
|
16495
|
+
import_node_path11 = __toESM(require("node:path"), 1);
|
|
16302
16496
|
EXPO_APP_CONFIG_NAMES = [
|
|
16303
16497
|
"app.config.js",
|
|
16304
16498
|
"app.config.ts",
|
|
@@ -16399,7 +16593,7 @@ function localOriginOf(value) {
|
|
|
16399
16593
|
}
|
|
16400
16594
|
function hasPackageJson(dir) {
|
|
16401
16595
|
try {
|
|
16402
|
-
return
|
|
16596
|
+
return import_node_fs11.default.statSync(import_node_path12.default.join(dir, "package.json")).isFile();
|
|
16403
16597
|
} catch {
|
|
16404
16598
|
return false;
|
|
16405
16599
|
}
|
|
@@ -16408,7 +16602,7 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
16408
16602
|
const metroOrigin = localOriginOf(opts.bundleUrl);
|
|
16409
16603
|
if (!metroOrigin) return [];
|
|
16410
16604
|
const explicit = opts.repoDir || process.env.CONTRAST_REPO_DIR;
|
|
16411
|
-
const startDir = explicit ?
|
|
16605
|
+
const startDir = explicit ? import_node_path12.default.resolve(explicit) : process.cwd();
|
|
16412
16606
|
if (!explicit && !hasPackageJson(startDir)) return [];
|
|
16413
16607
|
const project = resolveAppProject(startDir, { trustStart: opts.exactProjectDir });
|
|
16414
16608
|
const selectedAppDir = project?.appDir ?? null;
|
|
@@ -16454,13 +16648,13 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
16454
16648
|
scannedFontDirectories++;
|
|
16455
16649
|
let entries;
|
|
16456
16650
|
try {
|
|
16457
|
-
entries =
|
|
16651
|
+
entries = import_node_fs11.default.readdirSync(current.dir, { withFileTypes: true });
|
|
16458
16652
|
} catch {
|
|
16459
16653
|
continue;
|
|
16460
16654
|
}
|
|
16461
16655
|
for (const entry of entries) {
|
|
16462
16656
|
if (entry.isSymbolicLink()) continue;
|
|
16463
|
-
const fullPath =
|
|
16657
|
+
const fullPath = import_node_path12.default.join(current.dir, entry.name);
|
|
16464
16658
|
if (entry.isDirectory()) {
|
|
16465
16659
|
if (current.depth < 4 && pending.length < 64 && !entry.name.startsWith(".")) {
|
|
16466
16660
|
pending.push({ dir: fullPath, depth: current.depth + 1 });
|
|
@@ -16468,15 +16662,15 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
16468
16662
|
continue;
|
|
16469
16663
|
}
|
|
16470
16664
|
if (!entry.isFile() || !/\.(ttf|otf|woff|woff2)$/i.test(entry.name)) continue;
|
|
16471
|
-
const relative =
|
|
16472
|
-
fontPaths.push(
|
|
16665
|
+
const relative = import_node_path12.default.relative(root, fullPath).split(import_node_path12.default.sep).join("/");
|
|
16666
|
+
fontPaths.push(import_node_path12.default.posix.join(metroPathPrefix, relative));
|
|
16473
16667
|
if (fontPaths.length >= 256) break;
|
|
16474
16668
|
}
|
|
16475
16669
|
}
|
|
16476
16670
|
};
|
|
16477
16671
|
try {
|
|
16478
16672
|
const packageJson = JSON.parse(
|
|
16479
|
-
|
|
16673
|
+
import_node_fs11.default.readFileSync(import_node_path12.default.join(selectedAppDir, "package.json"), "utf8")
|
|
16480
16674
|
);
|
|
16481
16675
|
const dependencyNames = /* @__PURE__ */ new Set();
|
|
16482
16676
|
for (const field of ["dependencies", "devDependencies", "optionalDependencies"]) {
|
|
@@ -16491,24 +16685,24 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
16491
16685
|
const config = Reflect.get(packageJson, "reactNativeVectorIcons");
|
|
16492
16686
|
const configuredFontDir = config && typeof config === "object" ? Reflect.get(config, "fontDir") : null;
|
|
16493
16687
|
const configuredDir = typeof configuredFontDir === "string" ? configuredFontDir : "rnvi-fonts";
|
|
16494
|
-
const root =
|
|
16495
|
-
const relativeRoot =
|
|
16496
|
-
if (!relativeRoot.startsWith("..") && !
|
|
16497
|
-
collectFontFiles(root, relativeRoot.split(
|
|
16688
|
+
const root = import_node_path12.default.resolve(selectedAppDir, configuredDir);
|
|
16689
|
+
const relativeRoot = import_node_path12.default.relative(selectedAppDir, root);
|
|
16690
|
+
if (!relativeRoot.startsWith("..") && !import_node_path12.default.isAbsolute(relativeRoot)) {
|
|
16691
|
+
collectFontFiles(root, relativeRoot.split(import_node_path12.default.sep).join("/"));
|
|
16498
16692
|
}
|
|
16499
|
-
const vectorIconRequire = (0, import_node_module2.createRequire)(
|
|
16693
|
+
const vectorIconRequire = (0, import_node_module2.createRequire)(import_node_path12.default.join(selectedAppDir, "package.json"));
|
|
16500
16694
|
for (const dependencyName of vectorIconDependencies) {
|
|
16501
16695
|
try {
|
|
16502
16696
|
const entryPath = vectorIconRequire.resolve(dependencyName);
|
|
16503
|
-
const dependencyPath = dependencyName.split("/").join(
|
|
16504
|
-
const marker = `${
|
|
16697
|
+
const dependencyPath = dependencyName.split("/").join(import_node_path12.default.sep);
|
|
16698
|
+
const marker = `${import_node_path12.default.sep}node_modules${import_node_path12.default.sep}${dependencyPath}${import_node_path12.default.sep}`;
|
|
16505
16699
|
const markerIndex = entryPath.lastIndexOf(marker);
|
|
16506
16700
|
if (markerIndex === -1) continue;
|
|
16507
16701
|
const packageRoot = entryPath.slice(0, markerIndex + marker.length - 1);
|
|
16508
16702
|
const fontsDir = dependencyName === "react-native-vector-icons" ? "Fonts" : "fonts";
|
|
16509
16703
|
collectFontFiles(
|
|
16510
|
-
|
|
16511
|
-
|
|
16704
|
+
import_node_path12.default.join(packageRoot, fontsDir),
|
|
16705
|
+
import_node_path12.default.posix.join("node_modules", dependencyName, fontsDir)
|
|
16512
16706
|
);
|
|
16513
16707
|
} catch {
|
|
16514
16708
|
}
|
|
@@ -16517,37 +16711,37 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
16517
16711
|
} catch {
|
|
16518
16712
|
}
|
|
16519
16713
|
try {
|
|
16520
|
-
const configPath =
|
|
16521
|
-
if (
|
|
16522
|
-
const appConfigRequire = (0, import_node_module2.createRequire)(
|
|
16714
|
+
const configPath = import_node_path12.default.join(selectedAppDir, "react-native.config.js");
|
|
16715
|
+
if (import_node_fs11.default.statSync(configPath).isFile()) {
|
|
16716
|
+
const appConfigRequire = (0, import_node_module2.createRequire)(import_node_path12.default.join(selectedAppDir, "package.json"));
|
|
16523
16717
|
const rnConfig = appConfigRequire(configPath);
|
|
16524
16718
|
const assets = rnConfig && typeof rnConfig === "object" ? Reflect.get(rnConfig, "assets") : null;
|
|
16525
16719
|
if (Array.isArray(assets)) {
|
|
16526
16720
|
for (const assetDir of assets) {
|
|
16527
16721
|
if (typeof assetDir !== "string") continue;
|
|
16528
|
-
const root =
|
|
16529
|
-
const relativeRoot =
|
|
16530
|
-
if (relativeRoot.startsWith("..") ||
|
|
16531
|
-
collectFontFiles(root, relativeRoot.split(
|
|
16722
|
+
const root = import_node_path12.default.resolve(selectedAppDir, assetDir);
|
|
16723
|
+
const relativeRoot = import_node_path12.default.relative(selectedAppDir, root);
|
|
16724
|
+
if (relativeRoot.startsWith("..") || import_node_path12.default.isAbsolute(relativeRoot)) continue;
|
|
16725
|
+
collectFontFiles(root, relativeRoot.split(import_node_path12.default.sep).join("/"));
|
|
16532
16726
|
}
|
|
16533
16727
|
}
|
|
16534
16728
|
}
|
|
16535
16729
|
} catch {
|
|
16536
16730
|
}
|
|
16537
16731
|
if (platform === "ios") {
|
|
16538
|
-
const iosDir =
|
|
16732
|
+
const iosDir = import_node_path12.default.join(selectedAppDir, "ios");
|
|
16539
16733
|
try {
|
|
16540
|
-
const targetDirs =
|
|
16734
|
+
const targetDirs = import_node_fs11.default.readdirSync(iosDir, { withFileTypes: true }).filter(
|
|
16541
16735
|
(entry) => entry.isDirectory() && !entry.isSymbolicLink() && entry.name !== "Pods" && entry.name !== "build" && !entry.name.startsWith(".")
|
|
16542
16736
|
).slice(0, 64);
|
|
16543
|
-
const plistPaths = [
|
|
16737
|
+
const plistPaths = [import_node_path12.default.join(iosDir, "Info.plist")];
|
|
16544
16738
|
for (const entry of targetDirs) {
|
|
16545
|
-
plistPaths.push(
|
|
16739
|
+
plistPaths.push(import_node_path12.default.join(iosDir, entry.name, "Info.plist"));
|
|
16546
16740
|
}
|
|
16547
16741
|
for (const plistPath of plistPaths) {
|
|
16548
16742
|
let parsed;
|
|
16549
16743
|
try {
|
|
16550
|
-
parsed = parsePlistSource(
|
|
16744
|
+
parsed = parsePlistSource(import_node_fs11.default.readFileSync(plistPath, "utf8"));
|
|
16551
16745
|
} catch {
|
|
16552
16746
|
continue;
|
|
16553
16747
|
}
|
|
@@ -16557,21 +16751,21 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
16557
16751
|
for (const declaredFont of declaredFonts) {
|
|
16558
16752
|
if (typeof declaredFont !== "string") continue;
|
|
16559
16753
|
const candidates = [
|
|
16560
|
-
|
|
16561
|
-
|
|
16754
|
+
import_node_path12.default.resolve(import_node_path12.default.dirname(plistPath), declaredFont),
|
|
16755
|
+
import_node_path12.default.resolve(iosDir, declaredFont)
|
|
16562
16756
|
];
|
|
16563
16757
|
const fontPath = candidates.find((candidate) => {
|
|
16564
|
-
const relative =
|
|
16565
|
-
if (relative.startsWith("..") ||
|
|
16758
|
+
const relative = import_node_path12.default.relative(selectedAppDir, candidate);
|
|
16759
|
+
if (relative.startsWith("..") || import_node_path12.default.isAbsolute(relative)) return false;
|
|
16566
16760
|
try {
|
|
16567
|
-
return
|
|
16761
|
+
return import_node_fs11.default.statSync(candidate).isFile();
|
|
16568
16762
|
} catch {
|
|
16569
16763
|
return false;
|
|
16570
16764
|
}
|
|
16571
16765
|
});
|
|
16572
16766
|
if (!fontPath) continue;
|
|
16573
16767
|
fontPaths.push(
|
|
16574
|
-
|
|
16768
|
+
import_node_path12.default.relative(selectedAppDir, fontPath).split(import_node_path12.default.sep).join("/")
|
|
16575
16769
|
);
|
|
16576
16770
|
}
|
|
16577
16771
|
}
|
|
@@ -16610,13 +16804,13 @@ async function resolveMetroProjectRoot(bundleUrl, opts) {
|
|
|
16610
16804
|
function encodeAppFontsWire(specs) {
|
|
16611
16805
|
return specs.map((spec) => `${encodeURIComponent(spec.url)}::${encodeURIComponent(spec.family)}`).join(",");
|
|
16612
16806
|
}
|
|
16613
|
-
var
|
|
16807
|
+
var import_node_fs11, import_node_module2, import_node_path12, import_config_plugin_fonts, require3;
|
|
16614
16808
|
var init_app_fonts = __esm({
|
|
16615
16809
|
"cli/app-fonts.ts"() {
|
|
16616
16810
|
"use strict";
|
|
16617
|
-
|
|
16811
|
+
import_node_fs11 = __toESM(require("node:fs"), 1);
|
|
16618
16812
|
import_node_module2 = require("node:module");
|
|
16619
|
-
|
|
16813
|
+
import_node_path12 = __toESM(require("node:path"), 1);
|
|
16620
16814
|
import_config_plugin_fonts = require("sootsim-engine/engine/config-plugin-fonts");
|
|
16621
16815
|
init_dev_server_scanner();
|
|
16622
16816
|
init_plist();
|
|
@@ -16639,7 +16833,7 @@ function localOriginOf2(value) {
|
|
|
16639
16833
|
}
|
|
16640
16834
|
function hasPackageJson2(dir) {
|
|
16641
16835
|
try {
|
|
16642
|
-
return
|
|
16836
|
+
return import_node_fs12.default.statSync(import_node_path13.default.join(dir, "package.json")).isFile();
|
|
16643
16837
|
} catch {
|
|
16644
16838
|
return false;
|
|
16645
16839
|
}
|
|
@@ -16648,7 +16842,7 @@ function discoverConfigPluginAppSplash(opts) {
|
|
|
16648
16842
|
const metroOrigin = localOriginOf2(opts.bundleUrl);
|
|
16649
16843
|
if (!metroOrigin) return null;
|
|
16650
16844
|
const explicit = opts.repoDir || process.env.CONTRAST_REPO_DIR;
|
|
16651
|
-
const startDir = explicit ?
|
|
16845
|
+
const startDir = explicit ? import_node_path13.default.resolve(explicit) : process.cwd();
|
|
16652
16846
|
if (!explicit && !hasPackageJson2(startDir)) return null;
|
|
16653
16847
|
const project = resolveAppProject(startDir, { trustStart: opts.exactProjectDir });
|
|
16654
16848
|
const selectedAppDir = project?.appDir ?? null;
|
|
@@ -16682,13 +16876,13 @@ function discoverConfigPluginAppSplash(opts) {
|
|
|
16682
16876
|
function encodeAppSplashWire(spec) {
|
|
16683
16877
|
return encodeURIComponent(JSON.stringify(spec));
|
|
16684
16878
|
}
|
|
16685
|
-
var
|
|
16879
|
+
var import_node_fs12, import_node_module3, import_node_path13, import_config_plugin_splash, require4;
|
|
16686
16880
|
var init_app_splash = __esm({
|
|
16687
16881
|
"cli/app-splash.ts"() {
|
|
16688
16882
|
"use strict";
|
|
16689
|
-
|
|
16883
|
+
import_node_fs12 = __toESM(require("node:fs"), 1);
|
|
16690
16884
|
import_node_module3 = require("node:module");
|
|
16691
|
-
|
|
16885
|
+
import_node_path13 = __toESM(require("node:path"), 1);
|
|
16692
16886
|
import_config_plugin_splash = require("sootsim-engine/engine/config-plugin-splash");
|
|
16693
16887
|
init_app_project();
|
|
16694
16888
|
require4 = (0, import_node_module3.createRequire)(__sootsim_import_meta_url);
|
|
@@ -17706,7 +17900,7 @@ function resolvePlaywright() {
|
|
|
17706
17900
|
try {
|
|
17707
17901
|
const modulePath = requireFromRoot.resolve(spec);
|
|
17708
17902
|
const packageJsonPath = requireFromRoot.resolve(`${spec}/package.json`);
|
|
17709
|
-
const parsed = JSON.parse((0,
|
|
17903
|
+
const parsed = JSON.parse((0, import_node_fs13.readFileSync)(packageJsonPath, "utf8"));
|
|
17710
17904
|
if (!isRecord3(parsed) || typeof parsed.version !== "string") continue;
|
|
17711
17905
|
const bin = parsed.bin;
|
|
17712
17906
|
let binPath = null;
|
|
@@ -17718,8 +17912,8 @@ function resolvePlaywright() {
|
|
|
17718
17912
|
binPath = typeof named === "string" ? named : typeof first === "string" ? first : null;
|
|
17719
17913
|
}
|
|
17720
17914
|
if (!binPath) continue;
|
|
17721
|
-
const cliPath = (0,
|
|
17722
|
-
if (!(0,
|
|
17915
|
+
const cliPath = (0, import_node_path14.join)((0, import_node_path14.dirname)(packageJsonPath), binPath);
|
|
17916
|
+
if (!(0, import_node_fs13.existsSync)(cliPath)) continue;
|
|
17723
17917
|
return {
|
|
17724
17918
|
spec,
|
|
17725
17919
|
modulePath,
|
|
@@ -17758,7 +17952,7 @@ function probeBrowser(resolved, env) {
|
|
|
17758
17952
|
return {
|
|
17759
17953
|
ok: true,
|
|
17760
17954
|
executablePath: parsed.executablePath,
|
|
17761
|
-
exists: parsed.exists && (0,
|
|
17955
|
+
exists: parsed.exists && (0, import_node_fs13.existsSync)(parsed.executablePath)
|
|
17762
17956
|
};
|
|
17763
17957
|
} catch (error) {
|
|
17764
17958
|
return {
|
|
@@ -17797,14 +17991,14 @@ ${detail}` : ""}`
|
|
|
17797
17991
|
}
|
|
17798
17992
|
return { ok: true, executablePath: after.executablePath, installed: true };
|
|
17799
17993
|
}
|
|
17800
|
-
var import_node_child_process5,
|
|
17994
|
+
var import_node_child_process5, import_node_fs13, import_node_module4, import_node_path14, PLAYWRIGHT_BROWSER_PROBE;
|
|
17801
17995
|
var init_playwright_provisioning = __esm({
|
|
17802
17996
|
"cli/drivers/playwright-provisioning.ts"() {
|
|
17803
17997
|
"use strict";
|
|
17804
17998
|
import_node_child_process5 = require("node:child_process");
|
|
17805
|
-
|
|
17999
|
+
import_node_fs13 = require("node:fs");
|
|
17806
18000
|
import_node_module4 = require("node:module");
|
|
17807
|
-
|
|
18001
|
+
import_node_path14 = require("node:path");
|
|
17808
18002
|
PLAYWRIGHT_BROWSER_PROBE = `
|
|
17809
18003
|
const { existsSync } = require('node:fs');
|
|
17810
18004
|
const modulePath = process.env.SOOTSIM_PW_MODULE;
|
|
@@ -17901,7 +18095,10 @@ async function launch2(opts) {
|
|
|
17901
18095
|
SOOTSIM_PW_HEADLESS: opts.headless ?? true ? "1" : "0",
|
|
17902
18096
|
SOOTSIM_PW_USERDATADIR: resolveUserDataDir(opts),
|
|
17903
18097
|
SOOTSIM_PW_CDP_PORT: opts.cdpPort ? String(opts.cdpPort) : "",
|
|
17904
|
-
|
|
18098
|
+
// when the caller passed no viewport, leave the inherited
|
|
18099
|
+
// SOOTSIM_PW_VIEWPORT (from playwrightEnv) alone instead of
|
|
18100
|
+
// clobbering it with '' — the driver reads it as its own default.
|
|
18101
|
+
...opts.viewport ? { SOOTSIM_PW_VIEWPORT: `${opts.viewport.width}x${opts.viewport.height}` } : {},
|
|
17905
18102
|
SOOTSIM_PW_CONNECTED_ACK_FILE: connectAckFile,
|
|
17906
18103
|
SOOTSIM_PW_CONNECT_TIMEOUT_MS: String(opts.connectTimeoutMs ?? 12e4),
|
|
17907
18104
|
SOOTSIM_PW_OWNER_PID: String(ownerPid)
|
|
@@ -18953,14 +19150,14 @@ function assertExplicitBridgeLock(preferredPort, explicitPort, lock) {
|
|
|
18953
19150
|
}
|
|
18954
19151
|
async function ensureRuntimeForOpen() {
|
|
18955
19152
|
const active = readActiveRuntime();
|
|
18956
|
-
if (active &&
|
|
19153
|
+
if (active && import_node_fs14.default.existsSync(runtimeDir(active))) return;
|
|
18957
19154
|
console.error(" installing rnx engine runtime...");
|
|
18958
19155
|
const { runRuntime: runRuntime2 } = await Promise.resolve().then(() => (init_runtime(), runtime_exports));
|
|
18959
19156
|
await runRuntime2(["install"], {});
|
|
18960
19157
|
}
|
|
18961
19158
|
function spawnSootsim(args) {
|
|
18962
19159
|
const entry = process.argv[1];
|
|
18963
|
-
if (entry &&
|
|
19160
|
+
if (entry && import_node_fs14.default.existsSync(entry)) {
|
|
18964
19161
|
return (0, import_node_child_process6.spawn)(process.execPath, [entry, ...args], {
|
|
18965
19162
|
detached: true,
|
|
18966
19163
|
stdio: "ignore",
|
|
@@ -19107,10 +19304,10 @@ async function buildResolvedBundleOpenUrl(target, baseUrl, opts = {}) {
|
|
|
19107
19304
|
}
|
|
19108
19305
|
function normalizeReplacementPath(filePath) {
|
|
19109
19306
|
if (filePath.startsWith("~/")) {
|
|
19110
|
-
return
|
|
19307
|
+
return import_node_path15.default.join(import_node_os3.default.homedir(), filePath.slice(2));
|
|
19111
19308
|
}
|
|
19112
|
-
if (
|
|
19113
|
-
return
|
|
19309
|
+
if (import_node_path15.default.isAbsolute(filePath)) return filePath;
|
|
19310
|
+
return import_node_path15.default.resolve(process.cwd(), filePath);
|
|
19114
19311
|
}
|
|
19115
19312
|
function parseOpenRuntimeConfig(args) {
|
|
19116
19313
|
const modules = {};
|
|
@@ -19129,7 +19326,7 @@ function parseOpenRuntimeConfig(args) {
|
|
|
19129
19326
|
}
|
|
19130
19327
|
const moduleName = raw.slice(0, eqIndex).trim();
|
|
19131
19328
|
const filePath = normalizeReplacementPath(raw.slice(eqIndex + 1).trim());
|
|
19132
|
-
if (!
|
|
19329
|
+
if (!import_node_fs14.default.existsSync(filePath)) {
|
|
19133
19330
|
console.error(` rnxsim open: replacement file not found: ${filePath}`);
|
|
19134
19331
|
process.exit(1);
|
|
19135
19332
|
}
|
|
@@ -19164,7 +19361,7 @@ async function resolveOpenAppProject(resolvedBundle) {
|
|
|
19164
19361
|
return resolveAppProject(process.env.CONTRAST_REPO_DIR || process.cwd());
|
|
19165
19362
|
}
|
|
19166
19363
|
async function ensureConfiguredRuntime(version) {
|
|
19167
|
-
if (
|
|
19364
|
+
if (import_node_fs14.default.existsSync(import_node_path15.default.join(runtimeDir(version), "index.html"))) return;
|
|
19168
19365
|
console.error(` installing configured engine runtime ${version}...`);
|
|
19169
19366
|
const result = await sootsimRuntime.install({
|
|
19170
19367
|
version,
|
|
@@ -19528,7 +19725,7 @@ function playwrightHostPidForSim(sim) {
|
|
|
19528
19725
|
function signalDriverLaunchConnected(result) {
|
|
19529
19726
|
if (!result.connectAckFile) return false;
|
|
19530
19727
|
try {
|
|
19531
|
-
|
|
19728
|
+
import_node_fs14.default.writeFileSync(
|
|
19532
19729
|
result.connectAckFile,
|
|
19533
19730
|
`${JSON.stringify({ connectedAt: Date.now(), pid: result.pid ?? null })}
|
|
19534
19731
|
`,
|
|
@@ -19542,19 +19739,19 @@ function signalDriverLaunchConnected(result) {
|
|
|
19542
19739
|
function printDriverDiagnosticLogTail(result) {
|
|
19543
19740
|
if (!result.diagnosticLogPath) return;
|
|
19544
19741
|
try {
|
|
19545
|
-
const detail =
|
|
19742
|
+
const detail = import_node_fs14.default.readFileSync(result.diagnosticLogPath, "utf8").trim();
|
|
19546
19743
|
if (!detail) {
|
|
19547
|
-
console.error(` ${
|
|
19744
|
+
console.error(` ${import_node_path15.default.basename(result.diagnosticLogPath)} was empty`);
|
|
19548
19745
|
return;
|
|
19549
19746
|
}
|
|
19550
19747
|
const shown = detail.length > 4e3 ? `\u2026
|
|
19551
19748
|
${detail.slice(-4e3)}` : detail;
|
|
19552
|
-
console.error(` ${
|
|
19749
|
+
console.error(` ${import_node_path15.default.basename(result.diagnosticLogPath)}:`);
|
|
19553
19750
|
console.error(shown);
|
|
19554
19751
|
} catch (err) {
|
|
19555
19752
|
const message = err instanceof Error ? err.message : String(err);
|
|
19556
19753
|
console.error(
|
|
19557
|
-
` failed to read ${
|
|
19754
|
+
` failed to read ${import_node_path15.default.basename(result.diagnosticLogPath)}: ${message}`
|
|
19558
19755
|
);
|
|
19559
19756
|
}
|
|
19560
19757
|
}
|
|
@@ -19793,7 +19990,8 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
19793
19990
|
"--driver",
|
|
19794
19991
|
"--profile",
|
|
19795
19992
|
"--cdp-port",
|
|
19796
|
-
"--device"
|
|
19993
|
+
"--device",
|
|
19994
|
+
"--viewport"
|
|
19797
19995
|
]
|
|
19798
19996
|
});
|
|
19799
19997
|
const requestedProfileId = args.find((_, i) => args[i - 1] === "--profile");
|
|
@@ -19900,6 +20098,15 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
19900
20098
|
process.exit(1);
|
|
19901
20099
|
}
|
|
19902
20100
|
const deviceSpec = deviceArg ? import_settings.devices[deviceArg] : void 0;
|
|
20101
|
+
const viewportArg = args.find((_, i) => args[i - 1] === "--viewport");
|
|
20102
|
+
const viewportMatch = viewportArg ? /^(\d+)x(\d+)$/.exec(viewportArg) : null;
|
|
20103
|
+
if (viewportArg && !viewportMatch) {
|
|
20104
|
+
console.error(
|
|
20105
|
+
` rnxsim open: --viewport must be <width>x<height>, got "${viewportArg}"`
|
|
20106
|
+
);
|
|
20107
|
+
process.exit(1);
|
|
20108
|
+
}
|
|
20109
|
+
const explicitViewport = viewportMatch ? { width: Number(viewportMatch[1]), height: Number(viewportMatch[2]) } : void 0;
|
|
19903
20110
|
const buildShellUrlOpts = {
|
|
19904
20111
|
hot: hotMode,
|
|
19905
20112
|
device: deviceArg,
|
|
@@ -20048,7 +20255,7 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
20048
20255
|
cdpPort,
|
|
20049
20256
|
device: deviceArg,
|
|
20050
20257
|
ownerPid,
|
|
20051
|
-
viewport: deviceSpec ? { width: deviceSpec.width + 120, height: deviceSpec.height + 60 } : void 0,
|
|
20258
|
+
viewport: explicitViewport ?? (deviceSpec ? { width: deviceSpec.width + 120, height: deviceSpec.height + 60 } : void 0),
|
|
20052
20259
|
connectTimeoutMs: connectWait.hostTimeoutMs
|
|
20053
20260
|
});
|
|
20054
20261
|
if (!result.launched) {
|
|
@@ -20350,14 +20557,14 @@ async function runCloseCommand(args, opts = {}) {
|
|
|
20350
20557
|
bridge.close();
|
|
20351
20558
|
}
|
|
20352
20559
|
}
|
|
20353
|
-
var import_node_child_process6,
|
|
20560
|
+
var import_node_child_process6, import_node_fs14, import_node_os3, import_node_path15, import_settings, import_ws5, DEFAULT_DRIVER_CONNECT_TIMEOUT_MS, DRIVER_CONNECT_INTERVAL_MS, DRIVER_CONNECT_HOST_GRACE_MS, OPEN_BRIDGE_SPAWN_TIMEOUT_MS, SHELL_APPS, DEEP_LINK_SCHEME_RE;
|
|
20354
20561
|
var init_control = __esm({
|
|
20355
20562
|
"cli/commands/control.ts"() {
|
|
20356
20563
|
"use strict";
|
|
20357
20564
|
import_node_child_process6 = require("node:child_process");
|
|
20358
|
-
|
|
20565
|
+
import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
20359
20566
|
import_node_os3 = __toESM(require("node:os"), 1);
|
|
20360
|
-
|
|
20567
|
+
import_node_path15 = __toESM(require("node:path"), 1);
|
|
20361
20568
|
import_settings = require("sootsim-engine/settings");
|
|
20362
20569
|
import_ws5 = require("ws");
|
|
20363
20570
|
init_dev_server_scanner();
|
|
@@ -21139,14 +21346,14 @@ process.stdin.on('end', async () => {
|
|
|
21139
21346
|
function getBaseDir() {
|
|
21140
21347
|
const explicit = process.env[SESSION_FILE_ENV];
|
|
21141
21348
|
if (explicit?.trim()) {
|
|
21142
|
-
return (0,
|
|
21349
|
+
return (0, import_node_path16.dirname)((0, import_node_path16.resolve)(explicit));
|
|
21143
21350
|
}
|
|
21144
21351
|
return electronUserDataDir();
|
|
21145
21352
|
}
|
|
21146
21353
|
function getSharedDesktopAuthFilePath() {
|
|
21147
21354
|
const explicit = process.env[SESSION_FILE_ENV];
|
|
21148
|
-
if (explicit?.trim()) return (0,
|
|
21149
|
-
return (0,
|
|
21355
|
+
if (explicit?.trim()) return (0, import_node_path16.resolve)(explicit);
|
|
21356
|
+
return (0, import_node_path16.join)(getBaseDir(), "desktop-auth.json");
|
|
21150
21357
|
}
|
|
21151
21358
|
function normalizeUser(input) {
|
|
21152
21359
|
if (!input || typeof input !== "object") return null;
|
|
@@ -21193,26 +21400,26 @@ function normalizeSession(input) {
|
|
|
21193
21400
|
}
|
|
21194
21401
|
function readSharedDesktopAuthSession() {
|
|
21195
21402
|
const filepath = getSharedDesktopAuthFilePath();
|
|
21196
|
-
if (!(0,
|
|
21403
|
+
if (!(0, import_node_fs15.existsSync)(filepath)) return null;
|
|
21197
21404
|
try {
|
|
21198
|
-
const parsed = JSON.parse((0,
|
|
21405
|
+
const parsed = JSON.parse((0, import_node_fs15.readFileSync)(filepath, "utf8"));
|
|
21199
21406
|
const normalized = normalizeSession(parsed);
|
|
21200
21407
|
if (!normalized) {
|
|
21201
|
-
(0,
|
|
21408
|
+
(0, import_node_fs15.rmSync)(filepath, { force: true });
|
|
21202
21409
|
return null;
|
|
21203
21410
|
}
|
|
21204
21411
|
return normalized;
|
|
21205
21412
|
} catch {
|
|
21206
|
-
(0,
|
|
21413
|
+
(0, import_node_fs15.rmSync)(filepath, { force: true });
|
|
21207
21414
|
return null;
|
|
21208
21415
|
}
|
|
21209
21416
|
}
|
|
21210
|
-
var
|
|
21417
|
+
var import_node_fs15, import_node_path16, SESSION_VERSION, SESSION_FILE_ENV, DEFAULT_ORIGIN;
|
|
21211
21418
|
var init_shared_session = __esm({
|
|
21212
21419
|
"src/auth/shared-session.ts"() {
|
|
21213
21420
|
"use strict";
|
|
21214
|
-
|
|
21215
|
-
|
|
21421
|
+
import_node_fs15 = require("node:fs");
|
|
21422
|
+
import_node_path16 = require("node:path");
|
|
21216
21423
|
init_home_paths();
|
|
21217
21424
|
SESSION_VERSION = 1;
|
|
21218
21425
|
SESSION_FILE_ENV = "SOOTSIM_SHARED_AUTH_FILE";
|
|
@@ -21475,16 +21682,16 @@ function resolveFlowScreenshotPath(screenshotDir, name2) {
|
|
|
21475
21682
|
}
|
|
21476
21683
|
function resolveProjectRelativeFlowBase(flowDir) {
|
|
21477
21684
|
if (!flowDir) return process.cwd();
|
|
21478
|
-
return
|
|
21685
|
+
return path15.basename(flowDir) === ".maestro" ? path15.dirname(flowDir) : flowDir;
|
|
21479
21686
|
}
|
|
21480
21687
|
function resolveFlowScreenshotPathWithMode(screenshotDir, name2, opts) {
|
|
21481
21688
|
const normalizedName = name2.endsWith(".png") ? name2 : `${name2}.png`;
|
|
21482
|
-
if (
|
|
21689
|
+
if (path15.isAbsolute(normalizedName)) return normalizedName;
|
|
21483
21690
|
if (opts.mode === "flow" && /[\\/]/.test(normalizedName)) {
|
|
21484
21691
|
const baseDir = normalizedName.startsWith("./") || normalizedName.startsWith("../") ? opts.flowDir ?? process.cwd() : resolveProjectRelativeFlowBase(opts.flowDir);
|
|
21485
|
-
return
|
|
21692
|
+
return path15.resolve(baseDir, normalizedName);
|
|
21486
21693
|
}
|
|
21487
|
-
return
|
|
21694
|
+
return path15.join(screenshotDir, normalizedName);
|
|
21488
21695
|
}
|
|
21489
21696
|
function normalizeFlowScreenshotSpec(step) {
|
|
21490
21697
|
if (typeof step === "string") {
|
|
@@ -21541,12 +21748,12 @@ function parseFlowSteps(content) {
|
|
|
21541
21748
|
const parsed = import_yaml.default.parse(candidate);
|
|
21542
21749
|
return Array.isArray(parsed) ? parsed : [];
|
|
21543
21750
|
}
|
|
21544
|
-
var
|
|
21751
|
+
var fs16, path15, import_settings3, import_yaml, DEFAULT_TIMEOUT, FLOW_TIMEOUT_SCALE, scaledTimeout, SCREEN_W, SCREEN_H, SootSimBridgeFlowRunner;
|
|
21545
21752
|
var init_bridge_flow_runner = __esm({
|
|
21546
21753
|
"cli/bridge-flow-runner.ts"() {
|
|
21547
21754
|
"use strict";
|
|
21548
|
-
|
|
21549
|
-
|
|
21755
|
+
fs16 = __toESM(require("fs"), 1);
|
|
21756
|
+
path15 = __toESM(require("path"), 1);
|
|
21550
21757
|
import_settings3 = require("sootsim-engine/settings");
|
|
21551
21758
|
import_yaml = __toESM(require("yaml"), 1);
|
|
21552
21759
|
init_frame_compose();
|
|
@@ -21657,6 +21864,15 @@ var init_bridge_flow_runner = __esm({
|
|
|
21657
21864
|
args
|
|
21658
21865
|
});
|
|
21659
21866
|
}
|
|
21867
|
+
// ordered input batch executed inside the page in one round-trip; the
|
|
21868
|
+
// engine emits agent-cursor actions for every step natively.
|
|
21869
|
+
async perform(steps) {
|
|
21870
|
+
return this.bridge.send({
|
|
21871
|
+
type: "perform",
|
|
21872
|
+
simId: this.opts.simId,
|
|
21873
|
+
steps
|
|
21874
|
+
});
|
|
21875
|
+
}
|
|
21660
21876
|
async waitForTree(timeout = DEFAULT_TIMEOUT) {
|
|
21661
21877
|
const deadline = Date.now() + scaledTimeout(timeout);
|
|
21662
21878
|
const startedAt = Date.now();
|
|
@@ -21834,14 +22050,14 @@ var init_bridge_flow_runner = __esm({
|
|
|
21834
22050
|
if (chunks.length === 0) {
|
|
21835
22051
|
throw new Error("recording requested but no video buffer was produced");
|
|
21836
22052
|
}
|
|
21837
|
-
|
|
22053
|
+
fs16.mkdirSync(this.opts.recordingOutputDir, { recursive: true });
|
|
21838
22054
|
const videoMime = stopped.mime || this.opts.recordingFormat || "video/webm";
|
|
21839
22055
|
const extension = videoMime.includes("mp4") ? "mp4" : "webm";
|
|
21840
|
-
const outputPath =
|
|
22056
|
+
const outputPath = path15.join(
|
|
21841
22057
|
this.opts.recordingOutputDir,
|
|
21842
22058
|
`sootsim-${Date.now()}.${extension}`
|
|
21843
22059
|
);
|
|
21844
|
-
|
|
22060
|
+
fs16.writeFileSync(outputPath, Buffer.concat(chunks));
|
|
21845
22061
|
return outputPath;
|
|
21846
22062
|
}
|
|
21847
22063
|
async waitForRecordingTail(opts) {
|
|
@@ -22175,20 +22391,14 @@ var init_bridge_flow_runner = __esm({
|
|
|
22175
22391
|
await sleep3(300);
|
|
22176
22392
|
}
|
|
22177
22393
|
async doubleTapAtCoords(x, y, gapMs = 80) {
|
|
22178
|
-
const
|
|
22179
|
-
|
|
22180
|
-
|
|
22181
|
-
|
|
22182
|
-
|
|
22183
|
-
|
|
22184
|
-
|
|
22185
|
-
|
|
22186
|
-
if (!first || first.hit === false) return false
|
|
22187
|
-
await new Promise((resolve) => setTimeout(resolve, ${waitMs}))
|
|
22188
|
-
const second = await interact.tap(${x}, ${y})
|
|
22189
|
-
return !!second && second.hit !== false
|
|
22190
|
-
})()`);
|
|
22191
|
-
if (!ok) throw new Error(`doubleTapAtCoords failed at (${x}, ${y})`);
|
|
22394
|
+
const result = await this.perform([
|
|
22395
|
+
{ type: "doubleTap", x, y, gapMs: Math.max(0, Math.round(gapMs)) }
|
|
22396
|
+
]);
|
|
22397
|
+
if (!result?.ok) {
|
|
22398
|
+
throw new Error(
|
|
22399
|
+
`doubleTapAtCoords failed at (${x}, ${y}): ${result?.error ?? "double tap missed"}`
|
|
22400
|
+
);
|
|
22401
|
+
}
|
|
22192
22402
|
await sleep3(300);
|
|
22193
22403
|
}
|
|
22194
22404
|
async assertVisible(target) {
|
|
@@ -22350,7 +22560,7 @@ var init_bridge_flow_runner = __esm({
|
|
|
22350
22560
|
flowDir: this.opts.flowDir
|
|
22351
22561
|
}
|
|
22352
22562
|
);
|
|
22353
|
-
|
|
22563
|
+
fs16.mkdirSync(path15.dirname(outputPath), { recursive: true });
|
|
22354
22564
|
const layers = spec.layers ?? this.opts.screenshotLayers;
|
|
22355
22565
|
const screenshotRequest = {
|
|
22356
22566
|
type: "screenshot",
|
|
@@ -22366,11 +22576,11 @@ var init_bridge_flow_runner = __esm({
|
|
|
22366
22576
|
throw new Error("could not read current device model for framed screenshot");
|
|
22367
22577
|
}
|
|
22368
22578
|
const framed = await composeFramedScreenshot(rawBuffer, model);
|
|
22369
|
-
|
|
22579
|
+
fs16.writeFileSync(outputPath, framed);
|
|
22370
22580
|
console.log(`[flow] screenshot: ${outputPath} (frame: ${model})`);
|
|
22371
22581
|
return outputPath;
|
|
22372
22582
|
}
|
|
22373
|
-
|
|
22583
|
+
fs16.writeFileSync(outputPath, rawBuffer);
|
|
22374
22584
|
console.log(`[flow] screenshot: ${outputPath}`);
|
|
22375
22585
|
return outputPath;
|
|
22376
22586
|
}
|
|
@@ -22386,22 +22596,22 @@ var init_bridge_flow_runner = __esm({
|
|
|
22386
22596
|
return model;
|
|
22387
22597
|
}
|
|
22388
22598
|
async captureScreenshot(outputPath) {
|
|
22389
|
-
|
|
22599
|
+
fs16.mkdirSync(path15.dirname(outputPath), { recursive: true });
|
|
22390
22600
|
const dataUrl = await this.bridge.send({
|
|
22391
22601
|
type: "screenshot",
|
|
22392
22602
|
simId: this.opts.simId
|
|
22393
22603
|
});
|
|
22394
22604
|
const base64 = dataUrl.replace(/^data:image\/png;base64,/, "");
|
|
22395
|
-
|
|
22605
|
+
fs16.writeFileSync(outputPath, Buffer.from(base64, "base64"));
|
|
22396
22606
|
}
|
|
22397
22607
|
// writes a per-failure debug bundle: screenshot + structured describe
|
|
22398
22608
|
// + a11y tree + console errors/warnings + failed network requests +
|
|
22399
22609
|
// shell state, all under one directory so post-mortem is one grep away.
|
|
22400
22610
|
async captureFailureBundle(outputDir, context) {
|
|
22401
|
-
|
|
22611
|
+
fs16.mkdirSync(outputDir, { recursive: true });
|
|
22402
22612
|
const write = (name2, content) => {
|
|
22403
22613
|
try {
|
|
22404
|
-
|
|
22614
|
+
fs16.writeFileSync(path15.join(outputDir, name2), content);
|
|
22405
22615
|
} catch {
|
|
22406
22616
|
}
|
|
22407
22617
|
};
|
|
@@ -22529,14 +22739,19 @@ var init_bridge_flow_runner = __esm({
|
|
|
22529
22739
|
await this.drag(fromX, fromY, toX, toY, steps, 16);
|
|
22530
22740
|
}
|
|
22531
22741
|
async drag(fromX, fromY, toX, toY, steps = 12, stepMs = 16) {
|
|
22532
|
-
const result = await this.
|
|
22533
|
-
|
|
22534
|
-
|
|
22535
|
-
|
|
22536
|
-
|
|
22537
|
-
|
|
22742
|
+
const result = await this.perform([
|
|
22743
|
+
{
|
|
22744
|
+
type: "drag",
|
|
22745
|
+
fromX,
|
|
22746
|
+
fromY,
|
|
22747
|
+
toX,
|
|
22748
|
+
toY,
|
|
22749
|
+
steps: Math.max(1, Math.round(steps)),
|
|
22750
|
+
stepMs: Math.max(0, Math.round(stepMs))
|
|
22751
|
+
}
|
|
22752
|
+
]);
|
|
22538
22753
|
if (!result?.ok) {
|
|
22539
|
-
throw new Error(
|
|
22754
|
+
throw new Error(`drag failed: ${result?.error ?? "drag missed"}`);
|
|
22540
22755
|
}
|
|
22541
22756
|
await sleep3(300);
|
|
22542
22757
|
}
|
|
@@ -22585,18 +22800,23 @@ var init_bridge_flow_runner = __esm({
|
|
|
22585
22800
|
await sleep3(250);
|
|
22586
22801
|
}
|
|
22587
22802
|
async pinch(opts) {
|
|
22588
|
-
const result = await this.
|
|
22589
|
-
|
|
22590
|
-
|
|
22591
|
-
|
|
22592
|
-
|
|
22593
|
-
|
|
22594
|
-
|
|
22595
|
-
|
|
22596
|
-
|
|
22597
|
-
|
|
22803
|
+
const result = await this.perform([
|
|
22804
|
+
{
|
|
22805
|
+
type: "pinch",
|
|
22806
|
+
fromX1: opts.from[0],
|
|
22807
|
+
fromY1: opts.from[1],
|
|
22808
|
+
fromX2: opts.from[2],
|
|
22809
|
+
fromY2: opts.from[3],
|
|
22810
|
+
toX1: opts.to[0],
|
|
22811
|
+
toY1: opts.to[1],
|
|
22812
|
+
toX2: opts.to[2],
|
|
22813
|
+
toY2: opts.to[3],
|
|
22814
|
+
steps: opts.steps || 12,
|
|
22815
|
+
stepMs: opts.stepMs || 16
|
|
22816
|
+
}
|
|
22817
|
+
]);
|
|
22598
22818
|
if (!result?.ok) {
|
|
22599
|
-
throw new Error(`pinch failed: ${result?.
|
|
22819
|
+
throw new Error(`pinch failed: ${result?.error || "unknown error"}`);
|
|
22600
22820
|
}
|
|
22601
22821
|
await sleep3(250);
|
|
22602
22822
|
}
|
|
@@ -22673,43 +22893,31 @@ var init_bridge_flow_runner = __esm({
|
|
|
22673
22893
|
}
|
|
22674
22894
|
throw new Error("extendedWaitUntil timed out");
|
|
22675
22895
|
}
|
|
22676
|
-
|
|
22677
|
-
// 1. clear tenant-scoped storage through the engine bridge (best-effort).
|
|
22678
|
-
// 2. ALWAYS hard-reload the page to reset the tenant worker.
|
|
22679
|
-
// phase 2 is the important one for a long suite: the engine soft reload alone
|
|
22680
|
-
// keeps the same worker alive across every flow, so a saturated event loop /
|
|
22681
|
-
// accumulated state from one flow's post-PDS-reset auth-failure storm carries
|
|
22682
|
-
// into the next and degrades until the worker wedges or the tab crashes (the
|
|
22683
|
-
// failures clustered in the tail of a 21-flow run). a full page reload starts
|
|
22684
|
-
// each flow on a fresh worker — worker-independent, so it also recovers a
|
|
22685
|
-
// worker the bridge clear couldn't even ack. storage persists across a page
|
|
22686
|
-
// reload, so the clear in phase 1 is what actually logs the guest out.
|
|
22687
|
-
async reloadGuestApp(resetStorage) {
|
|
22688
|
-
if (resetStorage) {
|
|
22689
|
-
const ATTEMPTS = 3;
|
|
22690
|
-
const PER_ATTEMPT_MS = 2e4;
|
|
22691
|
-
let cleared = false;
|
|
22692
|
-
for (let attempt = 0; attempt < ATTEMPTS && !cleared; attempt++) {
|
|
22693
|
-
try {
|
|
22694
|
-
cleared = await this.evaluate(
|
|
22695
|
-
resetGuestAppStateEval(true),
|
|
22696
|
-
PER_ATTEMPT_MS
|
|
22697
|
-
);
|
|
22698
|
-
} catch {
|
|
22699
|
-
await sleep3(1e3);
|
|
22700
|
-
}
|
|
22701
|
-
}
|
|
22702
|
-
if (!cleared) {
|
|
22703
|
-
console.warn(
|
|
22704
|
-
" warn: tenant storage clear did not ack \u2014 hard-reloading anyway (worker reset follows)"
|
|
22705
|
-
);
|
|
22706
|
-
}
|
|
22707
|
-
}
|
|
22896
|
+
async reloadGuestApp() {
|
|
22708
22897
|
await this.evaluate("window.location.reload()").catch(() => {
|
|
22709
22898
|
});
|
|
22710
22899
|
await sleep3(500);
|
|
22711
22900
|
await this.refreshSimId();
|
|
22712
22901
|
}
|
|
22902
|
+
async resetGuestAppData() {
|
|
22903
|
+
const reset = await this.bridge.send(
|
|
22904
|
+
{
|
|
22905
|
+
type: "reset",
|
|
22906
|
+
simId: this.opts.simId,
|
|
22907
|
+
resetOptions: { strategy: "data" }
|
|
22908
|
+
},
|
|
22909
|
+
{ timeoutMs: 12e4 }
|
|
22910
|
+
);
|
|
22911
|
+
if (!reset.ok) {
|
|
22912
|
+
throw new Error(reset.error ?? "guest app data reset failed");
|
|
22913
|
+
}
|
|
22914
|
+
if (!reset.relaunched) {
|
|
22915
|
+
throw new Error("guest app data reset did not relaunch the app");
|
|
22916
|
+
}
|
|
22917
|
+
if (reset.workerReloaded !== true) {
|
|
22918
|
+
throw new Error("guest app data reset did not replace the tenant worker");
|
|
22919
|
+
}
|
|
22920
|
+
}
|
|
22713
22921
|
async softReloadGuestApp(resetStorage) {
|
|
22714
22922
|
const reloaded = await this.evaluate(
|
|
22715
22923
|
resetGuestAppStateEval(resetStorage),
|
|
@@ -22758,7 +22966,11 @@ var init_bridge_flow_runner = __esm({
|
|
|
22758
22966
|
await this.waitForTree(3e4);
|
|
22759
22967
|
} else {
|
|
22760
22968
|
this.firstLaunchDone = true;
|
|
22761
|
-
|
|
22969
|
+
if (wantsClear) {
|
|
22970
|
+
await this.resetGuestAppData();
|
|
22971
|
+
} else {
|
|
22972
|
+
await this.reloadGuestApp();
|
|
22973
|
+
}
|
|
22762
22974
|
await this.waitForTree(12e4);
|
|
22763
22975
|
if (this.opts.onAfterLaunch) {
|
|
22764
22976
|
try {
|
|
@@ -22871,13 +23083,12 @@ var init_bridge_flow_runner = __esm({
|
|
|
22871
23083
|
// nearest equivalent to killing and later re-launching the tenant runtime.
|
|
22872
23084
|
// State clearing belongs to clearState / launchApp({ clearState: true }).
|
|
22873
23085
|
async stopApp() {
|
|
22874
|
-
await this.reloadGuestApp(
|
|
23086
|
+
await this.reloadGuestApp();
|
|
22875
23087
|
await this.rearmCaptureAfterRuntimeReload();
|
|
22876
23088
|
}
|
|
22877
|
-
// maestro clearState: wipe app-owned storage and relaunch fresh.
|
|
22878
|
-
// through the same engine soft-reload launchApp uses under `clearState: true`.
|
|
23089
|
+
// maestro clearState: wipe app-owned storage and relaunch fresh.
|
|
22879
23090
|
async clearState() {
|
|
22880
|
-
await this.
|
|
23091
|
+
await this.resetGuestAppData();
|
|
22881
23092
|
await this.rearmCaptureAfterRuntimeReload();
|
|
22882
23093
|
}
|
|
22883
23094
|
// maestro clearKeychain: there is no real keychain in sootsim's browser
|
|
@@ -22919,8 +23130,8 @@ var init_bridge_flow_runner = __esm({
|
|
|
22919
23130
|
runScript(target) {
|
|
22920
23131
|
const spec = typeof target === "string" ? { file: target } : target;
|
|
22921
23132
|
if (!spec.file) throw new Error("runScript requires a file");
|
|
22922
|
-
const scriptPath =
|
|
22923
|
-
const source =
|
|
23133
|
+
const scriptPath = path15.resolve(this.opts.flowDir, spec.file);
|
|
23134
|
+
const source = fs16.readFileSync(scriptPath, "utf8");
|
|
22924
23135
|
this.js.evaluate(source, { env: spec.env });
|
|
22925
23136
|
console.log(`[flow] runScript: ${spec.file} done`);
|
|
22926
23137
|
}
|
|
@@ -23214,10 +23425,10 @@ var init_bridge_flow_runner = __esm({
|
|
|
23214
23425
|
for (const [k, v] of Object.entries(env)) this.js.putEnv(k, v);
|
|
23215
23426
|
}
|
|
23216
23427
|
if (file) {
|
|
23217
|
-
const flowPath =
|
|
23218
|
-
const flowContent =
|
|
23428
|
+
const flowPath = path15.resolve(this.opts.flowDir, file);
|
|
23429
|
+
const flowContent = fs16.readFileSync(flowPath, "utf8");
|
|
23219
23430
|
const previousDir = this.opts.flowDir;
|
|
23220
|
-
this.opts.flowDir =
|
|
23431
|
+
this.opts.flowDir = path15.dirname(flowPath);
|
|
23221
23432
|
try {
|
|
23222
23433
|
await this.runFlow(parseFlowSteps(flowContent));
|
|
23223
23434
|
} finally {
|
|
@@ -23372,8 +23583,8 @@ __export(registry_exports, {
|
|
|
23372
23583
|
skillRegistry: () => skillRegistry
|
|
23373
23584
|
});
|
|
23374
23585
|
module.exports = __toCommonJS(registry_exports);
|
|
23375
|
-
var
|
|
23376
|
-
var
|
|
23586
|
+
var fs17 = __toESM(require("fs"), 1);
|
|
23587
|
+
var path16 = __toESM(require("path"), 1);
|
|
23377
23588
|
|
|
23378
23589
|
// src/skills/builtin/a11y-review.ts
|
|
23379
23590
|
init_reap_browser();
|
|
@@ -23392,8 +23603,8 @@ var skill = {
|
|
|
23392
23603
|
},
|
|
23393
23604
|
async execute(params, context) {
|
|
23394
23605
|
const { chromium } = await import("playwright");
|
|
23395
|
-
const
|
|
23396
|
-
const
|
|
23606
|
+
const path17 = await import("path");
|
|
23607
|
+
const fs18 = await import("fs");
|
|
23397
23608
|
const browser = await launchReapedChrome((options) => chromium.launch(options), {
|
|
23398
23609
|
headless: true
|
|
23399
23610
|
});
|
|
@@ -23448,9 +23659,9 @@ var skill = {
|
|
|
23448
23659
|
warnings: issues.filter((i) => i.severity === "warning").length,
|
|
23449
23660
|
tree: typeof tree === "string" ? tree : JSON.stringify(tree)
|
|
23450
23661
|
};
|
|
23451
|
-
const reportPath =
|
|
23452
|
-
|
|
23453
|
-
|
|
23662
|
+
const reportPath = path17.join(context.outputDir, "a11y-report.json");
|
|
23663
|
+
fs18.mkdirSync(path17.dirname(reportPath), { recursive: true });
|
|
23664
|
+
fs18.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
23454
23665
|
return {
|
|
23455
23666
|
success: issues.filter((i) => i.severity === "error").length === 0,
|
|
23456
23667
|
message: `${report.errors} errors, ${report.warnings} warnings across ${report.nodeCount} nodes`,
|
|
@@ -23483,14 +23694,14 @@ var skill2 = {
|
|
|
23483
23694
|
}
|
|
23484
23695
|
},
|
|
23485
23696
|
async execute(params, context) {
|
|
23486
|
-
const
|
|
23487
|
-
const
|
|
23697
|
+
const fs18 = await import("node:fs");
|
|
23698
|
+
const path17 = await import("node:path");
|
|
23488
23699
|
const { COMPAT_RESULT_CAVEAT: COMPAT_RESULT_CAVEAT2, formatPackageStatus: formatPackageStatus2, formatScanCounts: formatScanCounts2, scanDeps: scanDeps2 } = await Promise.resolve().then(() => (init_web(), web_exports));
|
|
23489
|
-
const packagePath =
|
|
23490
|
-
if (!
|
|
23700
|
+
const packagePath = path17.join(context.projectDir, "package.json");
|
|
23701
|
+
if (!fs18.existsSync(packagePath)) {
|
|
23491
23702
|
return { success: false, message: "No package.json found" };
|
|
23492
23703
|
}
|
|
23493
|
-
const parsed = JSON.parse(
|
|
23704
|
+
const parsed = JSON.parse(fs18.readFileSync(packagePath, "utf8"));
|
|
23494
23705
|
if (!parsed || typeof parsed !== "object") {
|
|
23495
23706
|
return { success: false, message: "package.json is not an object" };
|
|
23496
23707
|
}
|
|
@@ -23502,9 +23713,9 @@ var skill2 = {
|
|
|
23502
23713
|
}) : scanDeps2(parsed);
|
|
23503
23714
|
const packageResult = params.packageName ? scan.packages[0] : void 0;
|
|
23504
23715
|
const message = packageResult ? `${params.packageName}: ${formatPackageStatus2(packageResult)}. ${COMPAT_RESULT_CAVEAT2}` : `${formatScanCounts2(scan)}. ${COMPAT_RESULT_CAVEAT2}`;
|
|
23505
|
-
const reportPath =
|
|
23506
|
-
|
|
23507
|
-
|
|
23716
|
+
const reportPath = path17.join(context.outputDir, "compat-report.json");
|
|
23717
|
+
fs18.mkdirSync(path17.dirname(reportPath), { recursive: true });
|
|
23718
|
+
fs18.writeFileSync(reportPath, `${JSON.stringify(scan, null, 2)}
|
|
23508
23719
|
`);
|
|
23509
23720
|
return {
|
|
23510
23721
|
success: true,
|
|
@@ -23548,8 +23759,8 @@ var skill3 = {
|
|
|
23548
23759
|
record: { type: "boolean", description: "Record video of the flow" }
|
|
23549
23760
|
},
|
|
23550
23761
|
async execute(params, context) {
|
|
23551
|
-
const
|
|
23552
|
-
const
|
|
23762
|
+
const fs18 = await import("fs");
|
|
23763
|
+
const path17 = await import("path");
|
|
23553
23764
|
const yaml2 = await import("yaml");
|
|
23554
23765
|
const { DEFAULT_SOOTSIM_BRIDGE_PORT: DEFAULT_SOOTSIM_BRIDGE_PORT2 } = await Promise.resolve().then(() => (init_bridge_constants(), bridge_constants_exports));
|
|
23555
23766
|
const { SootSimBridgeHost: SootSimBridgeHost2 } = await Promise.resolve().then(() => (init_bridge_host(), bridge_host_exports));
|
|
@@ -23559,7 +23770,7 @@ var skill3 = {
|
|
|
23559
23770
|
const host = new SootSimBridgeHost2({ port: DEFAULT_SOOTSIM_BRIDGE_PORT2 });
|
|
23560
23771
|
host.start({ silent: true });
|
|
23561
23772
|
try {
|
|
23562
|
-
const flowContent =
|
|
23773
|
+
const flowContent = fs18.readFileSync(params.flowPath, "utf8");
|
|
23563
23774
|
const fmMatch = flowContent.match(/^---\n([\s\S]*?)\n---\n?/);
|
|
23564
23775
|
const stepsBody = fmMatch ? flowContent.slice(fmMatch[0].length) : flowContent;
|
|
23565
23776
|
const steps = yaml2.parse(stepsBody);
|
|
@@ -23586,7 +23797,7 @@ var skill3 = {
|
|
|
23586
23797
|
});
|
|
23587
23798
|
const driver = new SootSimBridgeFlowRunner2(bridge, {
|
|
23588
23799
|
screenshotDir: context.outputDir,
|
|
23589
|
-
flowDir:
|
|
23800
|
+
flowDir: path17.dirname(path17.resolve(params.flowPath)),
|
|
23590
23801
|
simId,
|
|
23591
23802
|
recordingOutputDir: params.record ? context.outputDir : void 0
|
|
23592
23803
|
});
|
|
@@ -23608,7 +23819,7 @@ var skill3 = {
|
|
|
23608
23819
|
simId,
|
|
23609
23820
|
videoPath: videoPath || void 0
|
|
23610
23821
|
},
|
|
23611
|
-
artifacts: videoPath ? [{ type: "video", name:
|
|
23822
|
+
artifacts: videoPath ? [{ type: "video", name: path17.basename(videoPath), path: videoPath }] : void 0
|
|
23612
23823
|
};
|
|
23613
23824
|
} finally {
|
|
23614
23825
|
try {
|
|
@@ -23655,8 +23866,8 @@ var skill4 = {
|
|
|
23655
23866
|
},
|
|
23656
23867
|
async execute(params, context) {
|
|
23657
23868
|
const { chromium } = await import("playwright");
|
|
23658
|
-
const
|
|
23659
|
-
const
|
|
23869
|
+
const path17 = await import("path");
|
|
23870
|
+
const fs18 = await import("fs");
|
|
23660
23871
|
const browser = await launchReapedChrome((options) => chromium.launch(options), {
|
|
23661
23872
|
headless: true
|
|
23662
23873
|
});
|
|
@@ -23682,9 +23893,9 @@ var skill4 = {
|
|
|
23682
23893
|
...profile,
|
|
23683
23894
|
fps: syncCount > 0 ? (syncCount / (duration / 1e3)).toFixed(1) : "0"
|
|
23684
23895
|
};
|
|
23685
|
-
const reportPath =
|
|
23686
|
-
|
|
23687
|
-
|
|
23896
|
+
const reportPath = path17.join(context.outputDir, "perf-report.json");
|
|
23897
|
+
fs18.mkdirSync(path17.dirname(reportPath), { recursive: true });
|
|
23898
|
+
fs18.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
23688
23899
|
return {
|
|
23689
23900
|
success: true,
|
|
23690
23901
|
message: `${report.fps} fps, ${profile.avgSyncMs?.toFixed(1)}ms avg sync, ${nodeCount} nodes`,
|
|
@@ -23717,8 +23928,8 @@ var skill5 = {
|
|
|
23717
23928
|
},
|
|
23718
23929
|
async execute(params, context) {
|
|
23719
23930
|
const { chromium } = await import("playwright");
|
|
23720
|
-
const
|
|
23721
|
-
const
|
|
23931
|
+
const path17 = await import("path");
|
|
23932
|
+
const fs18 = await import("fs");
|
|
23722
23933
|
const browser = await launchReapedChrome((options) => chromium.launch(options), {
|
|
23723
23934
|
headless: true
|
|
23724
23935
|
});
|
|
@@ -23726,8 +23937,8 @@ var skill5 = {
|
|
|
23726
23937
|
try {
|
|
23727
23938
|
await page.goto(context.url, { waitUntil: "networkidle" });
|
|
23728
23939
|
await page.waitForTimeout(2e3);
|
|
23729
|
-
const outputPath =
|
|
23730
|
-
|
|
23940
|
+
const outputPath = path17.join(context.outputDir, `${params.name}.png`);
|
|
23941
|
+
fs18.mkdirSync(path17.dirname(outputPath), { recursive: true });
|
|
23731
23942
|
await page.screenshot({ path: outputPath });
|
|
23732
23943
|
return {
|
|
23733
23944
|
success: true,
|
|
@@ -23768,8 +23979,8 @@ var skill6 = {
|
|
|
23768
23979
|
},
|
|
23769
23980
|
async execute(params, context) {
|
|
23770
23981
|
const { chromium } = await import("playwright");
|
|
23771
|
-
const
|
|
23772
|
-
const
|
|
23982
|
+
const path17 = await import("path");
|
|
23983
|
+
const fs18 = await import("fs");
|
|
23773
23984
|
const browser = await launchReapedChrome((options) => chromium.launch(options), {
|
|
23774
23985
|
headless: true
|
|
23775
23986
|
});
|
|
@@ -23777,14 +23988,14 @@ var skill6 = {
|
|
|
23777
23988
|
try {
|
|
23778
23989
|
await page.goto(context.url, { waitUntil: "networkidle" });
|
|
23779
23990
|
await page.waitForTimeout(2e3);
|
|
23780
|
-
const currentPath =
|
|
23781
|
-
|
|
23991
|
+
const currentPath = path17.join(context.outputDir, `${params.name}-current.png`);
|
|
23992
|
+
fs18.mkdirSync(path17.dirname(currentPath), { recursive: true });
|
|
23782
23993
|
await page.screenshot({ path: currentPath });
|
|
23783
23994
|
try {
|
|
23784
23995
|
const { PNG } = await import("pngjs");
|
|
23785
23996
|
const pixelmatch = (await import("pixelmatch")).default;
|
|
23786
|
-
const baseline = PNG.sync.read(
|
|
23787
|
-
const current = PNG.sync.read(
|
|
23997
|
+
const baseline = PNG.sync.read(fs18.readFileSync(params.baseline));
|
|
23998
|
+
const current = PNG.sync.read(fs18.readFileSync(currentPath));
|
|
23788
23999
|
const { width, height } = baseline;
|
|
23789
24000
|
const diff = new PNG({ width, height });
|
|
23790
24001
|
const numDiffPixels = pixelmatch(
|
|
@@ -23795,8 +24006,8 @@ var skill6 = {
|
|
|
23795
24006
|
height,
|
|
23796
24007
|
{ threshold: params.threshold || 0.1 }
|
|
23797
24008
|
);
|
|
23798
|
-
const diffPath =
|
|
23799
|
-
|
|
24009
|
+
const diffPath = path17.join(context.outputDir, `${params.name}-diff.png`);
|
|
24010
|
+
fs18.writeFileSync(diffPath, PNG.sync.write(diff));
|
|
23800
24011
|
const totalPixels = width * height;
|
|
23801
24012
|
const diffPercent = (numDiffPixels / totalPixels * 100).toFixed(2);
|
|
23802
24013
|
return {
|
|
@@ -23860,10 +24071,10 @@ var skillRegistry = {
|
|
|
23860
24071
|
},
|
|
23861
24072
|
// load skills from a project manifest (sootsim-skills.json)
|
|
23862
24073
|
async loadFromManifest(projectDir) {
|
|
23863
|
-
const manifestPath =
|
|
23864
|
-
if (!
|
|
24074
|
+
const manifestPath = path16.join(projectDir, "sootsim-skills.json");
|
|
24075
|
+
if (!fs17.existsSync(manifestPath)) return;
|
|
23865
24076
|
try {
|
|
23866
|
-
const manifest = JSON.parse(
|
|
24077
|
+
const manifest = JSON.parse(fs17.readFileSync(manifestPath, "utf8"));
|
|
23867
24078
|
if (Array.isArray(manifest.skills)) {
|
|
23868
24079
|
for (const entry of manifest.skills) {
|
|
23869
24080
|
if (typeof entry === "string") {
|
|
@@ -23874,7 +24085,7 @@ var skillRegistry = {
|
|
|
23874
24085
|
}
|
|
23875
24086
|
} else if (entry.file) {
|
|
23876
24087
|
try {
|
|
23877
|
-
const mod = await import(
|
|
24088
|
+
const mod = await import(path16.resolve(projectDir, entry.file));
|
|
23878
24089
|
if (mod.skill) this.register(mod.skill);
|
|
23879
24090
|
} catch {
|
|
23880
24091
|
}
|
|
@@ -23887,10 +24098,10 @@ var skillRegistry = {
|
|
|
23887
24098
|
// auto-discover skills based on project dependencies
|
|
23888
24099
|
suggestSkills(projectDir) {
|
|
23889
24100
|
const suggestions = [];
|
|
23890
|
-
const pkgPath =
|
|
23891
|
-
if (!
|
|
24101
|
+
const pkgPath = path16.join(projectDir, "package.json");
|
|
24102
|
+
if (!fs17.existsSync(pkgPath)) return suggestions;
|
|
23892
24103
|
try {
|
|
23893
|
-
const pkg = JSON.parse(
|
|
24104
|
+
const pkg = JSON.parse(fs17.readFileSync(pkgPath, "utf8"));
|
|
23894
24105
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
23895
24106
|
if (deps["detox"] || deps["maestro"]) {
|
|
23896
24107
|
suggestions.push("maestro-test");
|