sootsim 0.1.185 → 0.1.186
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/dist-cli/bin.js +3 -3
- package/dist-cli/chunks/{agent-VF756RZU.js → agent-HOCS7BA7.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-IAFL7ROV.js → agent-wrapper-OFIKO65K.js} +2 -2
- package/dist-cli/chunks/{app-fonts-VWLEC7ZA.js → app-fonts-PXVMBZZ7.js} +2 -2
- package/dist-cli/chunks/{assert-I55QVGG7.js → assert-OZS6AXZE.js} +2 -2
- package/dist-cli/chunks/beta-LUMNYREE.js +2 -0
- package/dist-cli/chunks/{camera-CYYBJH7W.js → camera-QJ2PKIJB.js} +2 -2
- package/dist-cli/chunks/{chunk-2T73IGB2.js → chunk-2B2D2EBR.js} +2 -2
- package/dist-cli/chunks/{chunk-ARNLQPMQ.js → chunk-353E6UCU.js} +2 -2
- package/dist-cli/chunks/chunk-3ISH4ZRW.js +1 -0
- package/dist-cli/chunks/{chunk-PIUKLO3W.js → chunk-4HVMPXJZ.js} +1 -1
- package/dist-cli/chunks/chunk-5TTEOJ4A.js +1 -0
- package/dist-cli/chunks/chunk-5XIRXMOS.js +971 -0
- package/dist-cli/chunks/chunk-6MJVRIUP.js +118 -0
- package/dist-cli/chunks/{chunk-EXFB33AZ.js → chunk-6OQVIQY7.js} +2 -2
- package/dist-cli/chunks/chunk-BU5CRHHR.js +24 -0
- package/dist-cli/chunks/{chunk-TUF6EPCQ.js → chunk-DPXVA7ZF.js} +2 -2
- package/dist-cli/chunks/{chunk-R4KLD4P4.js → chunk-FN64EREO.js} +2 -2
- package/dist-cli/chunks/{chunk-BI56RR3G.js → chunk-FUHNIWFL.js} +4 -4
- package/dist-cli/chunks/{chunk-WEJKLJ4B.js → chunk-GNGEYMS3.js} +2 -2
- package/dist-cli/chunks/{chunk-QTFCJYBF.js → chunk-I65LTDPY.js} +3 -3
- package/dist-cli/chunks/{chunk-BMCBPMTC.js → chunk-INIASYOZ.js} +1 -1
- package/dist-cli/chunks/{chunk-FUHXL6BW.js → chunk-KNICGV7H.js} +1 -1
- package/dist-cli/chunks/{chunk-E5DE33BU.js → chunk-LV7DFIBL.js} +1 -1
- package/dist-cli/chunks/{chunk-M3P67TBN.js → chunk-MAGDSBXT.js} +1 -1
- package/dist-cli/chunks/chunk-MP4CRGWM.js +2 -0
- package/dist-cli/chunks/{chunk-MADEJDFD.js → chunk-MPUCQL3Q.js} +1 -1
- package/dist-cli/chunks/{chunk-FY6DJGOS.js → chunk-N3PLEUYD.js} +39 -15
- package/dist-cli/chunks/{chunk-CYBRFHPU.js → chunk-NYYP5QQK.js} +2 -2
- package/dist-cli/chunks/{chunk-4OUQAR34.js → chunk-O2SQQXUO.js} +1 -1
- package/dist-cli/chunks/{chunk-K2THZIVC.js → chunk-OMFESSKA.js} +1 -1
- package/dist-cli/chunks/{chunk-C3UEINOZ.js → chunk-P5UT637B.js} +2 -2
- package/dist-cli/chunks/{chunk-C63EVPDN.js → chunk-POOE26UD.js} +2 -2
- package/dist-cli/chunks/{chunk-HQG4DRQ3.js → chunk-PTUTIFWJ.js} +1 -1
- package/dist-cli/chunks/{chunk-IJP257WP.js → chunk-QBLTH2F6.js} +1 -1
- package/dist-cli/chunks/{chunk-LJ3SOZBF.js → chunk-RAY2ZSNI.js} +2 -2
- package/dist-cli/chunks/{chunk-DZLBZGHN.js → chunk-RDM3LVH2.js} +2 -2
- package/dist-cli/chunks/chunk-RP5CVR6O.js +382 -0
- package/dist-cli/chunks/{chunk-PKZNXDUJ.js → chunk-TYV3FMBE.js} +2 -2
- package/dist-cli/chunks/{chunk-4NUQVW5P.js → chunk-U3BTJLRM.js} +17 -6
- package/dist-cli/chunks/{chunk-QQ4NSPAD.js → chunk-UATE6GSA.js} +2 -2
- package/dist-cli/chunks/chunk-V434ATFM.js +13 -0
- package/dist-cli/chunks/{chunk-GX6MKIFC.js → chunk-VGAD3CMW.js} +1 -1
- package/dist-cli/chunks/{chunk-LI4RLX6B.js → chunk-VPUJQTEO.js} +1 -1
- package/dist-cli/chunks/chunk-WBPTJ3WC.js +5 -0
- package/dist-cli/chunks/{chunk-NL5IFN4T.js → chunk-WFSLSEGX.js} +2 -2
- package/dist-cli/chunks/{chunk-TFZO277G.js → chunk-XFQOFRYY.js} +1 -1
- package/dist-cli/chunks/{chunk-TNHF6BON.js → chunk-XQ6PPMM6.js} +1 -1
- package/dist-cli/chunks/{chunk-FHJTTB3W.js → chunk-YYZGAZQI.js} +2 -2
- package/dist-cli/chunks/{chunk-WBY4JJ2K.js → chunk-ZE2O7AA5.js} +2 -2
- package/dist-cli/chunks/{chunk-X4KS33ZC.js → chunk-ZJ64K2PL.js} +2 -2
- package/dist-cli/chunks/cli-version-474OBNTF.js +2 -0
- package/dist-cli/chunks/{compat-ZJA3N4ZT.js → compat-BNXJOVMU.js} +3 -3
- package/dist-cli/chunks/control-6LPRGKTF.js +2 -0
- package/dist-cli/chunks/{cpu-profile-ACSQMVXY.js → cpu-profile-3KXOGOJP.js} +2 -2
- package/dist-cli/chunks/daemon-OMT3RVU4.js +2 -0
- package/dist-cli/chunks/{debug-W2ZOVTQO.js → debug-B3MN6772.js} +11 -10
- package/dist-cli/chunks/{detox-ANJO6T27.js → detox-YKSX4DUO.js} +2 -2
- package/dist-cli/chunks/{device-KPPN4KYD.js → device-NZX6AKQI.js} +2 -2
- package/dist-cli/chunks/{diagnose-5PEJYGES.js → diagnose-26HE6KS5.js} +2 -2
- package/dist-cli/chunks/drivers-2PZC4QA3.js +2 -0
- package/dist-cli/chunks/{electron-U456QLSQ.js → electron-XEUWIM47.js} +3 -3
- package/dist-cli/chunks/flow-P22NDT6V.js +2 -0
- package/dist-cli/chunks/help-ECGL4JSP.js +2 -0
- package/dist-cli/chunks/{hints-MBBQLMQU.js → hints-C56M4PMW.js} +2 -2
- package/dist-cli/chunks/{home-paths-KQKYP2SE.js → home-paths-EYH3RBPS.js} +2 -2
- package/dist-cli/chunks/inspect-LJYG4WC6.js +2 -0
- package/dist-cli/chunks/{install-desktop-OR6ZJ43X.js → install-desktop-UWHLWFKB.js} +3 -3
- package/dist-cli/chunks/{keys-JSQMBUE7.js → keys-Q37NM52E.js} +2 -2
- package/dist-cli/chunks/{login-DVMWAI3G.js → login-6E6ZEJRF.js} +4 -4
- package/dist-cli/chunks/{logout-RIVPFE5N.js → logout-A7QHH6DQ.js} +2 -2
- package/dist-cli/chunks/{maestro-TX6FPTVH.js → maestro-YJRGFGDQ.js} +2 -2
- package/dist-cli/chunks/optional-demo-registry-OVWOHGTW.js +2 -0
- package/dist-cli/chunks/{preview-3AD7WNA6.js → preview-3OYFVL4A.js} +2 -2
- package/dist-cli/chunks/{profile-HY55VFNR.js → profile-5Z2YGBCJ.js} +2 -2
- package/dist-cli/chunks/{react-HDRCKCKV.js → react-ZNFFE3VQ.js} +2 -2
- package/dist-cli/chunks/{record-HW4C7QYN.js → record-V4CBW3GG.js} +2 -2
- package/dist-cli/chunks/runtime-OC6S2C22.js +2 -0
- package/dist-cli/chunks/{screenshot-XFR3QN5T.js → screenshot-QWMRWTIQ.js} +2 -2
- package/dist-cli/chunks/{screenshot-mode-Y5CVO267.js → screenshot-mode-36EUFBF5.js} +2 -2
- package/dist-cli/chunks/{screenshots-RKUL2ZZT.js → screenshots-LOS6WHZN.js} +2 -2
- package/dist-cli/chunks/{screenshots-capture-RVNF75ZD.js → screenshots-capture-6D6TBI6A.js} +2 -2
- package/dist-cli/chunks/{serve-QMRYLWL5.js → serve-YWGZ2JSI.js} +16 -16
- package/dist-cli/chunks/{setup-ELNJS7AI.js → setup-JS35KZ6P.js} +3 -3
- package/dist-cli/chunks/{skills-GPSJYS4W.js → skills-2TRDAXNC.js} +2 -2
- package/dist-cli/chunks/{slides-OCFNPIFG.js → slides-AO5MBP5Q.js} +2 -2
- package/dist-cli/chunks/store-HQKPCA6W.js +2 -0
- package/dist-cli/chunks/telemetry-I2H25VVF.js +2 -0
- package/dist-cli/chunks/{telemetry-KFZQUFG5.js → telemetry-MBWJUKBU.js} +2 -2
- package/dist-cli/chunks/{test-Z2HZXCZM.js → test-TRP2O6AP.js} +3 -3
- package/dist-cli/chunks/{three-mode-NKJFCDYS.js → three-mode-VVNOGAZT.js} +2 -2
- package/dist-cli/chunks/{timeline-PRGQMQRR.js → timeline-4WDFXUXB.js} +2 -2
- package/dist-cli/chunks/{upgrade-3NW7JRRX.js → upgrade-NHQRFD4J.js} +2 -2
- package/dist-cli/chunks/upload-6C2EC56N.js +2 -0
- package/dist-cli/chunks/{version-FDTZRIYT.js → version-T7O46MZL.js} +2 -2
- package/dist-cli/chunks/{web-4N5QQEQJ.js → web-7YW2ISLF.js} +2 -2
- package/dist-cli/chunks/{what-happened-IX2RRCOS.js → what-happened-IDOUXSFI.js} +2 -2
- package/dist-cli/chunks/{whoami-QZ42FYYF.js → whoami-DQBR3UTO.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.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/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 +2 -2
- package/dist-lib/host/bridge-host.cjs +77 -44
- 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 +28 -1
- 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 +28 -1
- package/dist-lib/profiles.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 +38 -10
- package/dist-lib/sdk.mjs +38 -10
- package/dist-lib/skills.cjs +283 -254
- package/dist-lib/vite.cjs +28 -1
- package/package.json +1 -1
- package/src/home-paths.ts +8 -1
- package/src/host/bridge-host.ts +15 -1
- package/src/runtime-assets.ts +70 -0
- package/src/vite-plugin.ts +9 -0
- package/dist-cli/chunks/beta-X6YPQVZH.js +0 -2
- package/dist-cli/chunks/chunk-7OAUPGLN.js +0 -23
- package/dist-cli/chunks/chunk-IGJHME3T.js +0 -1
- package/dist-cli/chunks/chunk-JRL7PFNZ.js +0 -463
- package/dist-cli/chunks/chunk-KOKIECMB.js +0 -118
- package/dist-cli/chunks/chunk-OAHGYDJR.js +0 -13
- package/dist-cli/chunks/chunk-PDLQWZN4.js +0 -2
- package/dist-cli/chunks/chunk-SL6565MR.js +0 -1
- package/dist-cli/chunks/chunk-V4M2R6FZ.js +0 -2
- package/dist-cli/chunks/chunk-V5JEPE3P.js +0 -5
- package/dist-cli/chunks/chunk-XU5EMZ4B.js +0 -264
- package/dist-cli/chunks/cli-version-ICHQMND6.js +0 -2
- package/dist-cli/chunks/control-CZFSYSYG.js +0 -2
- package/dist-cli/chunks/daemon-337B4P3B.js +0 -2
- package/dist-cli/chunks/drivers-MSDIFHBD.js +0 -2
- package/dist-cli/chunks/flow-JL3SC6HC.js +0 -2
- package/dist-cli/chunks/help-PA4RTR5X.js +0 -2
- package/dist-cli/chunks/inspect-ZP5SM4EW.js +0 -987
- package/dist-cli/chunks/optional-demo-registry-ONYG6DUI.js +0 -2
- package/dist-cli/chunks/runtime-RHHPW5WO.js +0 -2
- package/dist-cli/chunks/store-MBKDUQEQ.js +0 -2
- package/dist-cli/chunks/telemetry-46XXIUEE.js +0 -2
- package/dist-cli/chunks/upload-QVDVJ6ZK.js +0 -2
package/dist-lib/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.186 | (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;
|
|
@@ -10119,10 +10119,10 @@ function tcpPing(port, timeout = TCP_GATE_MS) {
|
|
|
10119
10119
|
sock.connect(port, "localhost");
|
|
10120
10120
|
});
|
|
10121
10121
|
}
|
|
10122
|
-
function httpGet(port,
|
|
10122
|
+
function httpGet(port, path11, method = "GET", timeout = TIMEOUT_MS, headers = {}) {
|
|
10123
10123
|
return new Promise((resolve6) => {
|
|
10124
10124
|
const req = import_http.default.request(
|
|
10125
|
-
{ hostname: "localhost", port, path:
|
|
10125
|
+
{ hostname: "localhost", port, path: path11, method, timeout, headers },
|
|
10126
10126
|
(res) => {
|
|
10127
10127
|
let body = "";
|
|
10128
10128
|
res.on("data", (c) => body += c.toString());
|
|
@@ -10580,27 +10580,6 @@ function sootsimHomeDir() {
|
|
|
10580
10580
|
if (override && override.length > 0) return import_node_path.default.resolve(override);
|
|
10581
10581
|
return import_node_path.default.join((0, import_node_os.homedir)(), ".sootsim");
|
|
10582
10582
|
}
|
|
10583
|
-
function isSootsimDevCheckout() {
|
|
10584
|
-
if (process.env.SOOTSIM_FORCE_DAEMON_INSTALL === "1") return false;
|
|
10585
|
-
const env = process.env.SOOTSIM_DEV;
|
|
10586
|
-
if (env === "1" || env === "true") return true;
|
|
10587
|
-
if (env === "0" || env === "false") return false;
|
|
10588
|
-
const argv1 = process.argv[1];
|
|
10589
|
-
if (!argv1) return false;
|
|
10590
|
-
try {
|
|
10591
|
-
const real = import_node_fs2.default.realpathSync(argv1);
|
|
10592
|
-
return real.includes(`${import_node_path.default.sep}packages${import_node_path.default.sep}sootsim${import_node_path.default.sep}`);
|
|
10593
|
-
} catch {
|
|
10594
|
-
return false;
|
|
10595
|
-
}
|
|
10596
|
-
}
|
|
10597
|
-
function isDevWorkstation() {
|
|
10598
|
-
if (process.env.SOOTSIM_FORCE_DAEMON_INSTALL === "1") return false;
|
|
10599
|
-
return process.env.IS_TAMAGUI_DEV === "1";
|
|
10600
|
-
}
|
|
10601
|
-
function shouldSkipPersistentDaemon() {
|
|
10602
|
-
return isSootsimDevCheckout() || isDevWorkstation();
|
|
10603
|
-
}
|
|
10604
10583
|
function runtimesDir() {
|
|
10605
10584
|
return import_node_path.default.join(sootsimHomeDir(), "runtimes");
|
|
10606
10585
|
}
|
|
@@ -10741,7 +10720,7 @@ function readDevBridgeLockfile() {
|
|
|
10741
10720
|
const bytesRead = import_node_fs2.default.readSync(fd, buf, 0, DAEMON_LOCKFILE_MAX_BYTES, 0);
|
|
10742
10721
|
const raw = buf.subarray(0, bytesRead).toString("utf8");
|
|
10743
10722
|
const parsed = JSON.parse(raw);
|
|
10744
|
-
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") {
|
|
10723
|
+
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")) {
|
|
10745
10724
|
return parsed;
|
|
10746
10725
|
}
|
|
10747
10726
|
return null;
|
|
@@ -10824,10 +10803,45 @@ var init_home_paths = __esm({
|
|
|
10824
10803
|
}
|
|
10825
10804
|
});
|
|
10826
10805
|
|
|
10806
|
+
// src/runtime-assets.ts
|
|
10807
|
+
function findMonorepoRoot() {
|
|
10808
|
+
if (_monorepoRootCache !== void 0) return _monorepoRootCache;
|
|
10809
|
+
let dir = import_path.default.dirname((0, import_url.fileURLToPath)(__sootsim_import_meta_url));
|
|
10810
|
+
for (let i = 0; i < 12 && dir !== import_path.default.dirname(dir); i++) {
|
|
10811
|
+
if (import_fs.default.existsSync(import_path.default.join(dir, "packages/sootsim-engine/package.json")) && import_fs.default.existsSync(import_path.default.join(dir, "public/sootsim"))) {
|
|
10812
|
+
_monorepoRootCache = dir;
|
|
10813
|
+
return dir;
|
|
10814
|
+
}
|
|
10815
|
+
dir = import_path.default.dirname(dir);
|
|
10816
|
+
}
|
|
10817
|
+
_monorepoRootCache = null;
|
|
10818
|
+
return null;
|
|
10819
|
+
}
|
|
10820
|
+
function resolveDevCheckoutRuntimeRoot() {
|
|
10821
|
+
if (process.env.SOOTSIM_HOME && readActiveRuntime()) return null;
|
|
10822
|
+
const root = findMonorepoRoot();
|
|
10823
|
+
if (!root) return null;
|
|
10824
|
+
const devBuild = import_path.default.join(root, "public/sootsim");
|
|
10825
|
+
if (import_fs.default.existsSync(import_path.default.join(devBuild, "index.html")) && import_fs.default.existsSync(import_path.default.join(devBuild, "engine/index.html")) && import_fs.default.existsSync(import_path.default.join(devBuild, "engine-tenant/worker.js"))) {
|
|
10826
|
+
return devBuild;
|
|
10827
|
+
}
|
|
10828
|
+
return null;
|
|
10829
|
+
}
|
|
10830
|
+
var import_fs, import_path, import_url, _monorepoRootCache;
|
|
10831
|
+
var init_runtime_assets = __esm({
|
|
10832
|
+
"src/runtime-assets.ts"() {
|
|
10833
|
+
"use strict";
|
|
10834
|
+
import_fs = __toESM(require("fs"), 1);
|
|
10835
|
+
import_path = __toESM(require("path"), 1);
|
|
10836
|
+
import_url = require("url");
|
|
10837
|
+
init_home_paths();
|
|
10838
|
+
}
|
|
10839
|
+
});
|
|
10840
|
+
|
|
10827
10841
|
// src/runtime-delivery.ts
|
|
10828
10842
|
function readConfig() {
|
|
10829
10843
|
try {
|
|
10830
|
-
const parsed = JSON.parse(
|
|
10844
|
+
const parsed = JSON.parse(import_fs2.default.readFileSync(configFilePath(), "utf8"));
|
|
10831
10845
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
10832
10846
|
} catch {
|
|
10833
10847
|
return {};
|
|
@@ -10881,7 +10895,7 @@ async function installRuntime(opts = {}) {
|
|
|
10881
10895
|
const { version, channel, entry } = resolveRuntimeVersion(manifest, opts);
|
|
10882
10896
|
const destDir = runtimeDir(version);
|
|
10883
10897
|
const setActive = opts.setActive !== false;
|
|
10884
|
-
if (!opts.force &&
|
|
10898
|
+
if (!opts.force && import_fs2.default.existsSync(import_path2.default.join(destDir, "index.html"))) {
|
|
10885
10899
|
if (setActive) writeActiveRuntime(version);
|
|
10886
10900
|
return {
|
|
10887
10901
|
version,
|
|
@@ -10894,7 +10908,7 @@ async function installRuntime(opts = {}) {
|
|
|
10894
10908
|
};
|
|
10895
10909
|
}
|
|
10896
10910
|
const tarUrl = entry.tarball || runtimeTarballUrl(version, cdnOrigin);
|
|
10897
|
-
const tarCachePath =
|
|
10911
|
+
const tarCachePath = import_path2.default.join(cacheDir(), `sootsim-runtime-${version}.tar.gz`);
|
|
10898
10912
|
process.stderr.write(`sootsim: downloading runtime ${version}\u2026
|
|
10899
10913
|
`);
|
|
10900
10914
|
await downloadToFile(tarUrl, tarCachePath);
|
|
@@ -10902,23 +10916,23 @@ async function installRuntime(opts = {}) {
|
|
|
10902
10916
|
`);
|
|
10903
10917
|
const actualSha = await sha256File(tarCachePath);
|
|
10904
10918
|
if (actualSha !== entry.sha256) {
|
|
10905
|
-
|
|
10919
|
+
import_fs2.default.rmSync(tarCachePath, { force: true });
|
|
10906
10920
|
throw new Error(
|
|
10907
10921
|
`sha256 mismatch for runtime ${version}: expected ${entry.sha256}, actual ${actualSha}`
|
|
10908
10922
|
);
|
|
10909
10923
|
}
|
|
10910
|
-
const tmpDir =
|
|
10911
|
-
|
|
10912
|
-
|
|
10924
|
+
const tmpDir = import_path2.default.join(import_path2.default.dirname(destDir), `.installing-${version}-${process.pid}`);
|
|
10925
|
+
import_fs2.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
10926
|
+
import_fs2.default.mkdirSync(tmpDir, { recursive: true });
|
|
10913
10927
|
try {
|
|
10914
10928
|
await extractTarball(tarCachePath, tmpDir);
|
|
10915
|
-
if (!
|
|
10929
|
+
if (!import_fs2.default.existsSync(import_path2.default.join(tmpDir, "index.html"))) {
|
|
10916
10930
|
throw new Error(`extracted tarball for runtime ${version} is missing index.html`);
|
|
10917
10931
|
}
|
|
10918
|
-
|
|
10919
|
-
|
|
10932
|
+
import_fs2.default.rmSync(destDir, { recursive: true, force: true });
|
|
10933
|
+
import_fs2.default.renameSync(tmpDir, destDir);
|
|
10920
10934
|
} catch (err) {
|
|
10921
|
-
|
|
10935
|
+
import_fs2.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
10922
10936
|
throw err;
|
|
10923
10937
|
}
|
|
10924
10938
|
if (setActive) writeActiveRuntime(version);
|
|
@@ -10958,7 +10972,7 @@ async function updateRuntimeToLatest(opts = {}) {
|
|
|
10958
10972
|
}
|
|
10959
10973
|
const activeVersion = readActiveRuntime();
|
|
10960
10974
|
const activeDir = activeVersion ? runtimeDir(activeVersion) : null;
|
|
10961
|
-
const activeInstalled = activeDir ?
|
|
10975
|
+
const activeInstalled = activeDir ? import_fs2.default.existsSync(import_path2.default.join(activeDir, "index.html")) : false;
|
|
10962
10976
|
const shouldInstall = !activeVersion || !activeInstalled || compareSemver(latestVersion, activeVersion) > 0;
|
|
10963
10977
|
if (!shouldInstall) {
|
|
10964
10978
|
return {
|
|
@@ -10988,17 +11002,17 @@ async function downloadToFile(url, destPath) {
|
|
|
10988
11002
|
if (!res.ok || !res.body) {
|
|
10989
11003
|
throw new Error(`download failed: ${res.status} ${res.statusText} (${url})`);
|
|
10990
11004
|
}
|
|
10991
|
-
|
|
11005
|
+
import_fs2.default.mkdirSync(import_path2.default.dirname(destPath), { recursive: true });
|
|
10992
11006
|
const tmp = `${destPath}.partial`;
|
|
10993
11007
|
try {
|
|
10994
11008
|
await (0, import_promises.pipeline)(
|
|
10995
11009
|
import_stream.Readable.fromWeb(res.body),
|
|
10996
|
-
|
|
11010
|
+
import_fs2.default.createWriteStream(tmp)
|
|
10997
11011
|
);
|
|
10998
|
-
|
|
11012
|
+
import_fs2.default.renameSync(tmp, destPath);
|
|
10999
11013
|
} catch (err) {
|
|
11000
11014
|
try {
|
|
11001
|
-
|
|
11015
|
+
import_fs2.default.unlinkSync(tmp);
|
|
11002
11016
|
} catch {
|
|
11003
11017
|
}
|
|
11004
11018
|
throw err;
|
|
@@ -11007,7 +11021,7 @@ async function downloadToFile(url, destPath) {
|
|
|
11007
11021
|
function sha256File(filePath) {
|
|
11008
11022
|
return new Promise((resolve6, reject) => {
|
|
11009
11023
|
const hash = import_crypto.default.createHash("sha256");
|
|
11010
|
-
const stream =
|
|
11024
|
+
const stream = import_fs2.default.createReadStream(filePath);
|
|
11011
11025
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
11012
11026
|
stream.on("error", reject);
|
|
11013
11027
|
stream.on("end", () => resolve6(hash.digest("hex")));
|
|
@@ -11025,14 +11039,14 @@ function extractTarball(tarPath, destDir) {
|
|
|
11025
11039
|
});
|
|
11026
11040
|
});
|
|
11027
11041
|
}
|
|
11028
|
-
var import_child_process2, import_crypto,
|
|
11042
|
+
var import_child_process2, import_crypto, import_fs2, import_path2, import_stream, import_promises, DEFAULT_RUNTIME_CDN_ORIGIN, RUNTIME_CDN_ORIGIN_ENV, RUNTIME_CHANNEL_ENV;
|
|
11029
11043
|
var init_runtime_delivery = __esm({
|
|
11030
11044
|
"src/runtime-delivery.ts"() {
|
|
11031
11045
|
"use strict";
|
|
11032
11046
|
import_child_process2 = require("child_process");
|
|
11033
11047
|
import_crypto = __toESM(require("crypto"), 1);
|
|
11034
|
-
|
|
11035
|
-
|
|
11048
|
+
import_fs2 = __toESM(require("fs"), 1);
|
|
11049
|
+
import_path2 = __toESM(require("path"), 1);
|
|
11036
11050
|
import_stream = require("stream");
|
|
11037
11051
|
import_promises = require("stream/promises");
|
|
11038
11052
|
init_home_paths();
|
|
@@ -12647,12 +12661,12 @@ var init_fetch_proxy_handler = __esm({
|
|
|
12647
12661
|
|
|
12648
12662
|
// src/host/open-url.ts
|
|
12649
12663
|
function expandHome(candidate) {
|
|
12650
|
-
return candidate.startsWith("~/") ? (0,
|
|
12664
|
+
return candidate.startsWith("~/") ? (0, import_path3.join)((0, import_os.homedir)(), candidate.slice(2)) : candidate;
|
|
12651
12665
|
}
|
|
12652
12666
|
function firstExisting(candidates) {
|
|
12653
12667
|
for (const candidate of candidates) {
|
|
12654
12668
|
const expanded = expandHome(candidate);
|
|
12655
|
-
if ((0,
|
|
12669
|
+
if ((0, import_fs3.existsSync)(expanded)) return expanded;
|
|
12656
12670
|
}
|
|
12657
12671
|
return null;
|
|
12658
12672
|
}
|
|
@@ -12671,7 +12685,7 @@ function lookupExecutable(command, platform) {
|
|
|
12671
12685
|
}
|
|
12672
12686
|
function resolveChromiumBinary(platform = process.platform) {
|
|
12673
12687
|
const envCandidate = process.env.CHROME_PATH || process.env.CHROMIUM_PATH;
|
|
12674
|
-
if (envCandidate && (0,
|
|
12688
|
+
if (envCandidate && (0, import_fs3.existsSync)(envCandidate)) return envCandidate;
|
|
12675
12689
|
const direct = platform === "darwin" ? firstExisting(MAC_CHROMIUM_CANDIDATES) : platform === "win32" ? firstExisting(WINDOWS_CHROMIUM_CANDIDATES) : firstExisting(LINUX_CHROMIUM_CANDIDATES);
|
|
12676
12690
|
if (direct) return direct;
|
|
12677
12691
|
const commands = platform === "win32" ? WINDOWS_CHROMIUM_COMMANDS : UNIX_CHROMIUM_COMMANDS;
|
|
@@ -12751,14 +12765,14 @@ async function launchUrl(url, options = {}) {
|
|
|
12751
12765
|
async function openUrl(url, options = {}) {
|
|
12752
12766
|
await launchUrl(url, options);
|
|
12753
12767
|
}
|
|
12754
|
-
var import_child_process3,
|
|
12768
|
+
var import_child_process3, import_fs3, import_os, import_path3, MAC_CHROMIUM_CANDIDATES, LINUX_CHROMIUM_CANDIDATES, WINDOWS_CHROMIUM_CANDIDATES, UNIX_CHROMIUM_COMMANDS, WINDOWS_CHROMIUM_COMMANDS;
|
|
12755
12769
|
var init_open_url = __esm({
|
|
12756
12770
|
"src/host/open-url.ts"() {
|
|
12757
12771
|
"use strict";
|
|
12758
12772
|
import_child_process3 = require("child_process");
|
|
12759
|
-
|
|
12773
|
+
import_fs3 = require("fs");
|
|
12760
12774
|
import_os = require("os");
|
|
12761
|
-
|
|
12775
|
+
import_path3 = require("path");
|
|
12762
12776
|
MAC_CHROMIUM_CANDIDATES = [
|
|
12763
12777
|
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
12764
12778
|
"~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
@@ -13013,19 +13027,20 @@ function unrefTimer(timer) {
|
|
|
13013
13027
|
timer.unref();
|
|
13014
13028
|
}
|
|
13015
13029
|
}
|
|
13016
|
-
var import_child_process4,
|
|
13030
|
+
var import_child_process4, import_fs4, import_http3, import_path4, 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;
|
|
13017
13031
|
var init_bridge_host = __esm({
|
|
13018
13032
|
"src/host/bridge-host.ts"() {
|
|
13019
13033
|
"use strict";
|
|
13020
13034
|
import_child_process4 = require("child_process");
|
|
13021
|
-
|
|
13035
|
+
import_fs4 = __toESM(require("fs"), 1);
|
|
13022
13036
|
import_http3 = require("http");
|
|
13023
|
-
|
|
13037
|
+
import_path4 = __toESM(require("path"), 1);
|
|
13024
13038
|
import_ws2 = require("ws");
|
|
13025
13039
|
init_dev_server_scanner();
|
|
13026
13040
|
init_bridge_constants();
|
|
13027
13041
|
init_cli_version();
|
|
13028
13042
|
init_home_paths();
|
|
13043
|
+
init_runtime_assets();
|
|
13029
13044
|
init_runtime_delivery();
|
|
13030
13045
|
init_agent_host();
|
|
13031
13046
|
init_fetch_proxy_handler();
|
|
@@ -13118,6 +13133,7 @@ var init_bridge_host = __esm({
|
|
|
13118
13133
|
automationSimActiveGraceMs;
|
|
13119
13134
|
shouldWriteLockfile;
|
|
13120
13135
|
shouldWriteDevLockfile;
|
|
13136
|
+
getShellPort;
|
|
13121
13137
|
sootbeanOrigin = null;
|
|
13122
13138
|
effectivePort = 0;
|
|
13123
13139
|
startedAt = 0;
|
|
@@ -13150,6 +13166,7 @@ var init_bridge_host = __esm({
|
|
|
13150
13166
|
this.port = this.preferredPort;
|
|
13151
13167
|
this.shouldWriteLockfile = opts.writeLockfile === true;
|
|
13152
13168
|
this.shouldWriteDevLockfile = opts.writeDevLockfile === true;
|
|
13169
|
+
this.getShellPort = opts.getShellPort ?? null;
|
|
13153
13170
|
this.portFallbackCount = Math.max(1, opts.portFallbackCount ?? 10);
|
|
13154
13171
|
this.openUrlHandler = opts.openUrl;
|
|
13155
13172
|
this.agentHost = new AgentHost({
|
|
@@ -13755,12 +13772,14 @@ var init_bridge_host = __esm({
|
|
|
13755
13772
|
};
|
|
13756
13773
|
}
|
|
13757
13774
|
buildDevLockfileSnapshot() {
|
|
13775
|
+
const shellPort = this.getShellPort?.() ?? null;
|
|
13758
13776
|
return {
|
|
13759
13777
|
schema: 1,
|
|
13760
13778
|
pid: process.pid,
|
|
13761
13779
|
platform: process.platform,
|
|
13762
13780
|
bridgePort: this.effectivePort,
|
|
13763
13781
|
runtimePort: this.effectivePort,
|
|
13782
|
+
...shellPort && shellPort > 0 ? { shellPort } : {},
|
|
13764
13783
|
cwd: process.cwd(),
|
|
13765
13784
|
startedAt: this.startedAt,
|
|
13766
13785
|
heartbeatAt: Date.now(),
|
|
@@ -13775,7 +13794,7 @@ var init_bridge_host = __esm({
|
|
|
13775
13794
|
}
|
|
13776
13795
|
refreshActiveRuntime() {
|
|
13777
13796
|
this.activeRuntimeVersion = readActiveRuntime();
|
|
13778
|
-
this.activeRuntimeDirPath = activeRuntimeDir();
|
|
13797
|
+
this.activeRuntimeDirPath = resolveDevCheckoutRuntimeRoot() ?? activeRuntimeDir();
|
|
13779
13798
|
}
|
|
13780
13799
|
runServerScan() {
|
|
13781
13800
|
if (this.inflightScan) return this.inflightScan;
|
|
@@ -14065,34 +14084,34 @@ var init_bridge_host = __esm({
|
|
|
14065
14084
|
return;
|
|
14066
14085
|
}
|
|
14067
14086
|
}
|
|
14068
|
-
const resolved =
|
|
14069
|
-
const baseWithSep = baseDir.endsWith(
|
|
14087
|
+
const resolved = import_path4.default.resolve(baseDir, "." + rel);
|
|
14088
|
+
const baseWithSep = baseDir.endsWith(import_path4.default.sep) ? baseDir : baseDir + import_path4.default.sep;
|
|
14070
14089
|
if (!resolved.startsWith(baseWithSep) && resolved !== baseDir) {
|
|
14071
14090
|
res.writeHead(403);
|
|
14072
14091
|
res.end("forbidden");
|
|
14073
14092
|
return;
|
|
14074
14093
|
}
|
|
14075
|
-
|
|
14094
|
+
import_fs4.default.realpath(resolved, (realErr, realResolved) => {
|
|
14076
14095
|
const servePath = realErr ? resolved : realResolved;
|
|
14077
|
-
const servePathWithSep = servePath.endsWith(
|
|
14096
|
+
const servePathWithSep = servePath.endsWith(import_path4.default.sep) ? servePath : servePath + import_path4.default.sep;
|
|
14078
14097
|
if (!realErr) {
|
|
14079
14098
|
const realBaseWithSep = (() => {
|
|
14080
14099
|
try {
|
|
14081
|
-
const rb =
|
|
14082
|
-
return rb.endsWith(
|
|
14100
|
+
const rb = import_fs4.default.realpathSync(baseDir);
|
|
14101
|
+
return rb.endsWith(import_path4.default.sep) ? rb : rb + import_path4.default.sep;
|
|
14083
14102
|
} catch {
|
|
14084
14103
|
return baseWithSep;
|
|
14085
14104
|
}
|
|
14086
14105
|
})();
|
|
14087
|
-
if (!servePathWithSep.startsWith(realBaseWithSep) && servePath +
|
|
14106
|
+
if (!servePathWithSep.startsWith(realBaseWithSep) && servePath + import_path4.default.sep !== realBaseWithSep) {
|
|
14088
14107
|
res.writeHead(403);
|
|
14089
14108
|
res.end("forbidden");
|
|
14090
14109
|
return;
|
|
14091
14110
|
}
|
|
14092
14111
|
}
|
|
14093
|
-
|
|
14112
|
+
import_fs4.default.stat(servePath, (err, stats) => {
|
|
14094
14113
|
if (err || !stats?.isFile()) {
|
|
14095
|
-
const ext2 =
|
|
14114
|
+
const ext2 = import_path4.default.extname(rel).toLowerCase();
|
|
14096
14115
|
if (ext2 && ext2 !== ".html") {
|
|
14097
14116
|
res.writeHead(404);
|
|
14098
14117
|
res.end("not found");
|
|
@@ -14103,8 +14122,8 @@ var init_bridge_host = __esm({
|
|
|
14103
14122
|
res.end("not found");
|
|
14104
14123
|
return;
|
|
14105
14124
|
}
|
|
14106
|
-
const indexPath =
|
|
14107
|
-
|
|
14125
|
+
const indexPath = import_path4.default.join(baseDir, "index.html");
|
|
14126
|
+
import_fs4.default.readFile(indexPath, (err2, data) => {
|
|
14108
14127
|
if (err2) {
|
|
14109
14128
|
res.writeHead(404);
|
|
14110
14129
|
res.end("not found");
|
|
@@ -14124,7 +14143,7 @@ var init_bridge_host = __esm({
|
|
|
14124
14143
|
});
|
|
14125
14144
|
return;
|
|
14126
14145
|
}
|
|
14127
|
-
const ext =
|
|
14146
|
+
const ext = import_path4.default.extname(servePath).toLowerCase();
|
|
14128
14147
|
const contentType = HTTP_MIME_TYPES[ext] || "application/octet-stream";
|
|
14129
14148
|
res.writeHead(200, {
|
|
14130
14149
|
"Content-Type": contentType,
|
|
@@ -14135,7 +14154,7 @@ var init_bridge_host = __esm({
|
|
|
14135
14154
|
return;
|
|
14136
14155
|
}
|
|
14137
14156
|
if (ext === ".html") {
|
|
14138
|
-
|
|
14157
|
+
import_fs4.default.readFile(servePath, (readErr, data) => {
|
|
14139
14158
|
if (readErr) {
|
|
14140
14159
|
try {
|
|
14141
14160
|
res.end();
|
|
@@ -14149,7 +14168,7 @@ var init_bridge_host = __esm({
|
|
|
14149
14168
|
});
|
|
14150
14169
|
return;
|
|
14151
14170
|
}
|
|
14152
|
-
const stream =
|
|
14171
|
+
const stream = import_fs4.default.createReadStream(servePath);
|
|
14153
14172
|
stream.pipe(res);
|
|
14154
14173
|
stream.on("error", () => {
|
|
14155
14174
|
try {
|
|
@@ -14819,6 +14838,15 @@ var init_bridge_host = __esm({
|
|
|
14819
14838
|
}
|
|
14820
14839
|
});
|
|
14821
14840
|
|
|
14841
|
+
// src/cli-constants.ts
|
|
14842
|
+
var DEFAULT_SOOTSIM_SHELL_URL;
|
|
14843
|
+
var init_cli_constants = __esm({
|
|
14844
|
+
"src/cli-constants.ts"() {
|
|
14845
|
+
"use strict";
|
|
14846
|
+
DEFAULT_SOOTSIM_SHELL_URL = "http://localhost:5173/";
|
|
14847
|
+
}
|
|
14848
|
+
});
|
|
14849
|
+
|
|
14822
14850
|
// cli/parent-pid.ts
|
|
14823
14851
|
function getParentPid(pid) {
|
|
14824
14852
|
if (!cached3) cached3 = build();
|
|
@@ -14844,7 +14872,7 @@ function build() {
|
|
|
14844
14872
|
function buildLinux() {
|
|
14845
14873
|
return (pid) => {
|
|
14846
14874
|
try {
|
|
14847
|
-
const raw = (0,
|
|
14875
|
+
const raw = (0, import_fs5.readFileSync)(`/proc/${pid}/stat`, "utf8");
|
|
14848
14876
|
const end = raw.lastIndexOf(")");
|
|
14849
14877
|
if (end < 0) return null;
|
|
14850
14878
|
const rest = raw.slice(end + 1).trim().split(/\s+/);
|
|
@@ -14897,12 +14925,12 @@ function buildDarwinLsof() {
|
|
|
14897
14925
|
}
|
|
14898
14926
|
};
|
|
14899
14927
|
}
|
|
14900
|
-
var import_child_process5,
|
|
14928
|
+
var import_child_process5, import_fs5, import_module, cached3, PROC_PIDTBSDINFO, PROC_BSDINFO_SIZE, PBI_PPID_OFFSET;
|
|
14901
14929
|
var init_parent_pid = __esm({
|
|
14902
14930
|
"cli/parent-pid.ts"() {
|
|
14903
14931
|
"use strict";
|
|
14904
14932
|
import_child_process5 = require("child_process");
|
|
14905
|
-
|
|
14933
|
+
import_fs5 = require("fs");
|
|
14906
14934
|
import_module = require("module");
|
|
14907
14935
|
cached3 = null;
|
|
14908
14936
|
PROC_PIDTBSDINFO = 3;
|
|
@@ -14940,18 +14968,18 @@ function getCliIdentityKey() {
|
|
|
14940
14968
|
}
|
|
14941
14969
|
function getCurrentSimPath() {
|
|
14942
14970
|
if (process.env[CURRENT_SIM_PATH_ENV]) {
|
|
14943
|
-
return (0,
|
|
14971
|
+
return (0, import_path5.resolve)(process.env[CURRENT_SIM_PATH_ENV]);
|
|
14944
14972
|
}
|
|
14945
14973
|
const key = getCliIdentityKey();
|
|
14946
|
-
return (0,
|
|
14974
|
+
return (0, import_path5.join)((0, import_os2.tmpdir)(), `sootsim-current-sim-${key}.json`);
|
|
14947
14975
|
}
|
|
14948
14976
|
function readCurrentSim() {
|
|
14949
14977
|
const filepath = getCurrentSimPath();
|
|
14950
|
-
if (!(0,
|
|
14978
|
+
if (!(0, import_fs6.existsSync)(filepath)) return null;
|
|
14951
14979
|
try {
|
|
14952
|
-
const parsed = JSON.parse((0,
|
|
14980
|
+
const parsed = JSON.parse((0, import_fs6.readFileSync)(filepath, "utf8"));
|
|
14953
14981
|
if (parsed.version !== CURRENT_SIM_VERSION || typeof parsed.simId !== "string" || !parsed.simId.trim() || typeof parsed.updatedAt !== "string") {
|
|
14954
|
-
(0,
|
|
14982
|
+
(0, import_fs6.rmSync)(filepath, { force: true });
|
|
14955
14983
|
return null;
|
|
14956
14984
|
}
|
|
14957
14985
|
return {
|
|
@@ -14960,7 +14988,7 @@ function readCurrentSim() {
|
|
|
14960
14988
|
updatedAt: parsed.updatedAt
|
|
14961
14989
|
};
|
|
14962
14990
|
} catch {
|
|
14963
|
-
(0,
|
|
14991
|
+
(0, import_fs6.rmSync)(filepath, { force: true });
|
|
14964
14992
|
return null;
|
|
14965
14993
|
}
|
|
14966
14994
|
}
|
|
@@ -14968,15 +14996,15 @@ function readCurrentSimId() {
|
|
|
14968
14996
|
return readCurrentSim()?.simId || null;
|
|
14969
14997
|
}
|
|
14970
14998
|
function clearCurrentSimId() {
|
|
14971
|
-
(0,
|
|
14999
|
+
(0, import_fs6.rmSync)(getCurrentSimPath(), { force: true });
|
|
14972
15000
|
}
|
|
14973
|
-
var
|
|
15001
|
+
var import_fs6, import_os2, import_path5, CURRENT_SIM_VERSION, CURRENT_SIM_PATH_ENV, IDENTITY_ENV_VARS;
|
|
14974
15002
|
var init_current_sim = __esm({
|
|
14975
15003
|
"cli/current-sim.ts"() {
|
|
14976
15004
|
"use strict";
|
|
14977
|
-
|
|
15005
|
+
import_fs6 = require("fs");
|
|
14978
15006
|
import_os2 = require("os");
|
|
14979
|
-
|
|
15007
|
+
import_path5 = require("path");
|
|
14980
15008
|
init_parent_pid();
|
|
14981
15009
|
CURRENT_SIM_VERSION = 1;
|
|
14982
15010
|
CURRENT_SIM_PATH_ENV = "SOOTSIM_CLI_CURRENT_SIM_PATH";
|
|
@@ -15015,6 +15043,7 @@ var init_current_sim = __esm({
|
|
|
15015
15043
|
var ws_bridge_exports = {};
|
|
15016
15044
|
__export(ws_bridge_exports, {
|
|
15017
15045
|
BridgeSimLockedError: () => BridgeSimLockedError,
|
|
15046
|
+
bridgePortForShellBaseUrl: () => bridgePortForShellBaseUrl,
|
|
15018
15047
|
callInBridge: () => callInBridge,
|
|
15019
15048
|
callInBridgeWrite: () => callInBridgeWrite,
|
|
15020
15049
|
checkSimHealth: () => checkSimHealth,
|
|
@@ -15022,16 +15051,84 @@ __export(ws_bridge_exports, {
|
|
|
15022
15051
|
createBridgeFromParsed: () => createBridgeFromParsed,
|
|
15023
15052
|
evalInBridge: () => evalInBridge,
|
|
15024
15053
|
parseBridgeCliArgs: () => parseBridgeCliArgs,
|
|
15025
|
-
|
|
15054
|
+
printBridgeWorldNotice: () => printBridgeWorldNotice,
|
|
15055
|
+
resolveBridgeWorld: () => resolveBridgeWorld,
|
|
15056
|
+
resolveDefaultBridgePort: () => resolveDefaultBridgePort,
|
|
15057
|
+
worldForBridgePort: () => worldForBridgePort
|
|
15026
15058
|
});
|
|
15027
|
-
function
|
|
15028
|
-
|
|
15029
|
-
|
|
15030
|
-
|
|
15059
|
+
function resolveBridgeWorld() {
|
|
15060
|
+
const dev = readDevBridgeLockfile();
|
|
15061
|
+
if (dev && isDevBridgeLockfileFresh(dev)) {
|
|
15062
|
+
return {
|
|
15063
|
+
source: "dev-bridge",
|
|
15064
|
+
bridgePort: dev.bridgePort,
|
|
15065
|
+
// older lockfile writers don't record the vite http port; the default
|
|
15066
|
+
// shell URL is the dev shell anyway, so the fallback stays coherent.
|
|
15067
|
+
shellBaseUrl: dev.shellPort ? `http://localhost:${dev.shellPort}/` : DEFAULT_SOOTSIM_SHELL_URL
|
|
15068
|
+
};
|
|
15031
15069
|
}
|
|
15032
15070
|
const lock = readDaemonLockfile();
|
|
15033
|
-
if (lock && isDaemonLockfileFresh(lock))
|
|
15034
|
-
|
|
15071
|
+
if (lock && isDaemonLockfileFresh(lock)) {
|
|
15072
|
+
return {
|
|
15073
|
+
source: "daemon",
|
|
15074
|
+
bridgePort: lock.bridgePort,
|
|
15075
|
+
shellBaseUrl: lock.runtimePort > 0 ? `http://localhost:${lock.runtimePort}/` : DEFAULT_SOOTSIM_SHELL_URL
|
|
15076
|
+
};
|
|
15077
|
+
}
|
|
15078
|
+
return {
|
|
15079
|
+
source: "default",
|
|
15080
|
+
bridgePort: DEFAULT_SOOTSIM_BRIDGE_PORT,
|
|
15081
|
+
shellBaseUrl: DEFAULT_SOOTSIM_SHELL_URL
|
|
15082
|
+
};
|
|
15083
|
+
}
|
|
15084
|
+
function worldForBridgePort(port) {
|
|
15085
|
+
const dev = readDevBridgeLockfile();
|
|
15086
|
+
if (dev && isDevBridgeLockfileFresh(dev) && dev.bridgePort === port) {
|
|
15087
|
+
return {
|
|
15088
|
+
source: "dev-bridge",
|
|
15089
|
+
shellBaseUrl: dev.shellPort ? `http://localhost:${dev.shellPort}/` : DEFAULT_SOOTSIM_SHELL_URL
|
|
15090
|
+
};
|
|
15091
|
+
}
|
|
15092
|
+
const lock = readDaemonLockfile();
|
|
15093
|
+
if (lock && isDaemonLockfileFresh(lock) && lock.bridgePort === port) {
|
|
15094
|
+
return {
|
|
15095
|
+
source: "daemon",
|
|
15096
|
+
shellBaseUrl: lock.runtimePort > 0 ? `http://localhost:${lock.runtimePort}/` : DEFAULT_SOOTSIM_SHELL_URL
|
|
15097
|
+
};
|
|
15098
|
+
}
|
|
15099
|
+
return null;
|
|
15100
|
+
}
|
|
15101
|
+
function bridgePortForShellBaseUrl(baseUrl) {
|
|
15102
|
+
let port;
|
|
15103
|
+
try {
|
|
15104
|
+
const url = new URL(baseUrl);
|
|
15105
|
+
port = url.port ? Number(url.port) : url.protocol === "https:" ? 443 : 80;
|
|
15106
|
+
} catch {
|
|
15107
|
+
return null;
|
|
15108
|
+
}
|
|
15109
|
+
if (!Number.isFinite(port) || port <= 0) return null;
|
|
15110
|
+
const dev = readDevBridgeLockfile();
|
|
15111
|
+
if (dev && isDevBridgeLockfileFresh(dev) && (dev.shellPort === port || dev.runtimePort === port || dev.bridgePort === port)) {
|
|
15112
|
+
return dev.bridgePort;
|
|
15113
|
+
}
|
|
15114
|
+
const lock = readDaemonLockfile();
|
|
15115
|
+
if (lock && isDaemonLockfileFresh(lock) && (lock.runtimePort === port || lock.bridgePort === port)) {
|
|
15116
|
+
return lock.bridgePort;
|
|
15117
|
+
}
|
|
15118
|
+
return null;
|
|
15119
|
+
}
|
|
15120
|
+
function resolveDefaultBridgePort() {
|
|
15121
|
+
return resolveBridgeWorld().bridgePort;
|
|
15122
|
+
}
|
|
15123
|
+
function printBridgeWorldNotice(bridgePort, shellBaseUrl) {
|
|
15124
|
+
const world = worldForBridgePort(bridgePort);
|
|
15125
|
+
const kind = world?.source === "dev-bridge" ? "dev bridge" : world?.source === "daemon" ? "daemon bridge" : "bridge";
|
|
15126
|
+
const origin = world ? `${world.source}.json` : "no lockfile";
|
|
15127
|
+
const shell = shellBaseUrl ?? world?.shellBaseUrl;
|
|
15128
|
+
process.stderr.write(
|
|
15129
|
+
` \u2192 ${kind} :${bridgePort} (${shell ? `shell ${shell}, ` : ""}${origin})
|
|
15130
|
+
`
|
|
15131
|
+
);
|
|
15035
15132
|
}
|
|
15036
15133
|
function describeSimIdSource(source) {
|
|
15037
15134
|
if (source === "flag") return "via --sim";
|
|
@@ -15339,11 +15436,11 @@ async function evalInBridge(bridge, code, opts = {}) {
|
|
|
15339
15436
|
if (opts.acquireLock) payload.acquireLock = true;
|
|
15340
15437
|
return bridge.send(payload);
|
|
15341
15438
|
}
|
|
15342
|
-
async function callInBridge(bridge,
|
|
15343
|
-
return bridge.send({ type: "call", path:
|
|
15439
|
+
async function callInBridge(bridge, path11, ...args) {
|
|
15440
|
+
return bridge.send({ type: "call", path: path11, args });
|
|
15344
15441
|
}
|
|
15345
|
-
async function callInBridgeWrite(bridge,
|
|
15346
|
-
return bridge.send({ type: "call", path:
|
|
15442
|
+
async function callInBridgeWrite(bridge, path11, ...args) {
|
|
15443
|
+
return bridge.send({ type: "call", path: path11, args, acquireLock: true });
|
|
15347
15444
|
}
|
|
15348
15445
|
var import_ws3, BridgeSimLockedError;
|
|
15349
15446
|
var init_ws_bridge = __esm({
|
|
@@ -15351,6 +15448,7 @@ var init_ws_bridge = __esm({
|
|
|
15351
15448
|
"use strict";
|
|
15352
15449
|
import_ws3 = require("ws");
|
|
15353
15450
|
init_bridge_constants();
|
|
15451
|
+
init_cli_constants();
|
|
15354
15452
|
init_home_paths();
|
|
15355
15453
|
init_current_sim();
|
|
15356
15454
|
BridgeSimLockedError = class extends Error {
|
|
@@ -15925,6 +16023,7 @@ var init_core = __esm({
|
|
|
15925
16023
|
let externalReady = null
|
|
15926
16024
|
let externalStatus = ''
|
|
15927
16025
|
let externalError = ''
|
|
16026
|
+
let suppressedEntryError = ''
|
|
15928
16027
|
try {
|
|
15929
16028
|
const getExternalAppState = t?.getExternalAppState
|
|
15930
16029
|
const external = typeof getExternalAppState === 'function'
|
|
@@ -15949,10 +16048,16 @@ var init_core = __esm({
|
|
|
15949
16048
|
if (typeof state.error === 'string') externalError = state.error
|
|
15950
16049
|
}
|
|
15951
16050
|
if (!externalError && Array.isArray(external?.entryErrors)) {
|
|
15952
|
-
|
|
15953
|
-
|
|
15954
|
-
|
|
15955
|
-
|
|
16051
|
+
// suppressed-and-continued entry errors (bundle-loader's patched __r
|
|
16052
|
+
// swallows entry throws and moves on) must NOT gate readiness \u2014 the
|
|
16053
|
+
// app frequently runs fine after one (e.g. metro's "Unknown named
|
|
16054
|
+
// module" probing noise). they surface separately as a diagnostic
|
|
16055
|
+
// for the timeout path.
|
|
16056
|
+
const isReal = (item) => item && typeof item.message === 'string' && item.message.trim()
|
|
16057
|
+
const fatal = external.entryErrors.find((item) => isReal(item) && item.suppressed !== true)
|
|
16058
|
+
if (fatal) externalError = fatal.message
|
|
16059
|
+
const suppressed = external.entryErrors.find((item) => isReal(item) && item.suppressed === true)
|
|
16060
|
+
if (suppressed) suppressedEntryError = suppressed.message
|
|
15956
16061
|
}
|
|
15957
16062
|
if (externalReady === false && externalStatus) loadingText = externalStatus
|
|
15958
16063
|
} catch {}
|
|
@@ -15968,6 +16073,7 @@ var init_core = __esm({
|
|
|
15968
16073
|
externalReady,
|
|
15969
16074
|
externalStatus,
|
|
15970
16075
|
externalError,
|
|
16076
|
+
suppressedEntryError,
|
|
15971
16077
|
}
|
|
15972
16078
|
})()`;
|
|
15973
16079
|
READY_CONTENT_NODE_FLOOR = 100;
|
|
@@ -16754,16 +16860,16 @@ function resolveFlowScreenshotPath(screenshotDir, name) {
|
|
|
16754
16860
|
}
|
|
16755
16861
|
function resolveProjectRelativeFlowBase(flowDir) {
|
|
16756
16862
|
if (!flowDir) return process.cwd();
|
|
16757
|
-
return
|
|
16863
|
+
return path9.basename(flowDir) === ".maestro" ? path9.dirname(flowDir) : flowDir;
|
|
16758
16864
|
}
|
|
16759
16865
|
function resolveFlowScreenshotPathWithMode(screenshotDir, name, opts) {
|
|
16760
16866
|
const normalizedName = name.endsWith(".png") ? name : `${name}.png`;
|
|
16761
|
-
if (
|
|
16867
|
+
if (path9.isAbsolute(normalizedName)) return normalizedName;
|
|
16762
16868
|
if (opts.mode === "flow" && /[\\/]/.test(normalizedName)) {
|
|
16763
16869
|
const baseDir = normalizedName.startsWith("./") || normalizedName.startsWith("../") ? opts.flowDir ?? process.cwd() : resolveProjectRelativeFlowBase(opts.flowDir);
|
|
16764
|
-
return
|
|
16870
|
+
return path9.resolve(baseDir, normalizedName);
|
|
16765
16871
|
}
|
|
16766
|
-
return
|
|
16872
|
+
return path9.join(screenshotDir, normalizedName);
|
|
16767
16873
|
}
|
|
16768
16874
|
function normalizeFlowScreenshotSpec(step) {
|
|
16769
16875
|
if (typeof step === "string") {
|
|
@@ -16818,12 +16924,12 @@ function parseFlowSteps(content) {
|
|
|
16818
16924
|
const parsed = import_yaml.default.parse(candidate);
|
|
16819
16925
|
return Array.isArray(parsed) ? parsed : [];
|
|
16820
16926
|
}
|
|
16821
|
-
var
|
|
16927
|
+
var fs9, path9, import_settings2, import_yaml, DEFAULT_TIMEOUT, SCREEN_W, SCREEN_H, SootSimBridgeFlowRunner;
|
|
16822
16928
|
var init_bridge_flow_runner = __esm({
|
|
16823
16929
|
"cli/bridge-flow-runner.ts"() {
|
|
16824
16930
|
"use strict";
|
|
16825
|
-
|
|
16826
|
-
|
|
16931
|
+
fs9 = __toESM(require("fs"), 1);
|
|
16932
|
+
path9 = __toESM(require("path"), 1);
|
|
16827
16933
|
import_settings2 = require("sootsim-engine/settings");
|
|
16828
16934
|
import_yaml = __toESM(require("yaml"), 1);
|
|
16829
16935
|
init_frame_compose();
|
|
@@ -16836,7 +16942,6 @@ var init_bridge_flow_runner = __esm({
|
|
|
16836
16942
|
DEFAULT_TIMEOUT = 1e4;
|
|
16837
16943
|
SCREEN_W = 393;
|
|
16838
16944
|
SCREEN_H = 852;
|
|
16839
|
-
CLI_PERF_SESSION_GLOBAL = "__sootsimCliPerf";
|
|
16840
16945
|
SootSimBridgeFlowRunner = class {
|
|
16841
16946
|
constructor(bridge, opts) {
|
|
16842
16947
|
this.bridge = bridge;
|
|
@@ -17047,14 +17152,14 @@ var init_bridge_flow_runner = __esm({
|
|
|
17047
17152
|
if (chunks.length === 0) {
|
|
17048
17153
|
throw new Error("recording requested but no video buffer was produced");
|
|
17049
17154
|
}
|
|
17050
|
-
|
|
17155
|
+
fs9.mkdirSync(this.opts.recordingOutputDir, { recursive: true });
|
|
17051
17156
|
const videoMime = stopped.mime || this.opts.recordingFormat || "video/webm";
|
|
17052
17157
|
const extension = videoMime.includes("mp4") ? "mp4" : "webm";
|
|
17053
|
-
const outputPath =
|
|
17158
|
+
const outputPath = path9.join(
|
|
17054
17159
|
this.opts.recordingOutputDir,
|
|
17055
17160
|
`sootsim-${Date.now()}.${extension}`
|
|
17056
17161
|
);
|
|
17057
|
-
|
|
17162
|
+
fs9.writeFileSync(outputPath, Buffer.concat(chunks));
|
|
17058
17163
|
return outputPath;
|
|
17059
17164
|
}
|
|
17060
17165
|
async waitForRecordingTail(opts) {
|
|
@@ -17493,7 +17598,7 @@ var init_bridge_flow_runner = __esm({
|
|
|
17493
17598
|
flowDir: this.opts.flowDir
|
|
17494
17599
|
}
|
|
17495
17600
|
);
|
|
17496
|
-
|
|
17601
|
+
fs9.mkdirSync(path9.dirname(outputPath), { recursive: true });
|
|
17497
17602
|
const layers = spec.layers ?? this.opts.screenshotLayers;
|
|
17498
17603
|
const screenshotRequest = {
|
|
17499
17604
|
type: "screenshot",
|
|
@@ -17509,11 +17614,11 @@ var init_bridge_flow_runner = __esm({
|
|
|
17509
17614
|
throw new Error("could not read current device model for framed screenshot");
|
|
17510
17615
|
}
|
|
17511
17616
|
const framed = await composeFramedScreenshot(rawBuffer, model);
|
|
17512
|
-
|
|
17617
|
+
fs9.writeFileSync(outputPath, framed);
|
|
17513
17618
|
console.log(`[flow] screenshot: ${outputPath} (frame: ${model})`);
|
|
17514
17619
|
return;
|
|
17515
17620
|
}
|
|
17516
|
-
|
|
17621
|
+
fs9.writeFileSync(outputPath, rawBuffer);
|
|
17517
17622
|
console.log(`[flow] screenshot: ${outputPath}`);
|
|
17518
17623
|
}
|
|
17519
17624
|
async readCurrentDeviceModel() {
|
|
@@ -17528,22 +17633,22 @@ var init_bridge_flow_runner = __esm({
|
|
|
17528
17633
|
return model;
|
|
17529
17634
|
}
|
|
17530
17635
|
async captureFailureScreenshot(outputPath) {
|
|
17531
|
-
|
|
17636
|
+
fs9.mkdirSync(path9.dirname(outputPath), { recursive: true });
|
|
17532
17637
|
const dataUrl = await this.bridge.send({
|
|
17533
17638
|
type: "screenshot",
|
|
17534
17639
|
simId: this.opts.simId
|
|
17535
17640
|
});
|
|
17536
17641
|
const base64 = dataUrl.replace(/^data:image\/png;base64,/, "");
|
|
17537
|
-
|
|
17642
|
+
fs9.writeFileSync(outputPath, Buffer.from(base64, "base64"));
|
|
17538
17643
|
}
|
|
17539
17644
|
// writes a per-failure debug bundle: screenshot + structured describe
|
|
17540
17645
|
// + a11y tree + console errors/warnings + failed network requests +
|
|
17541
17646
|
// shell state, all under one directory so post-mortem is one grep away.
|
|
17542
17647
|
async captureFailureBundle(outputDir, context) {
|
|
17543
|
-
|
|
17648
|
+
fs9.mkdirSync(outputDir, { recursive: true });
|
|
17544
17649
|
const write = (name, content) => {
|
|
17545
17650
|
try {
|
|
17546
|
-
|
|
17651
|
+
fs9.writeFileSync(path9.join(outputDir, name), content);
|
|
17547
17652
|
} catch {
|
|
17548
17653
|
}
|
|
17549
17654
|
};
|
|
@@ -17983,101 +18088,25 @@ var init_bridge_flow_runner = __esm({
|
|
|
17983
18088
|
return true;
|
|
17984
18089
|
}
|
|
17985
18090
|
async startProfile() {
|
|
17986
|
-
await this.evaluate(`((
|
|
17987
|
-
|
|
17988
|
-
|
|
17989
|
-
perf?.enableFrameStats?.(true)
|
|
17990
|
-
perf?.resetFrameStats?.()
|
|
17991
|
-
a11y?.resetProfile?.()
|
|
17992
|
-
window[sessionKey] = {
|
|
17993
|
-
active: true,
|
|
17994
|
-
mode: window.__sootsimRenderHost ? 'render-worker' : 'main-thread',
|
|
17995
|
-
lastSamples: [],
|
|
17996
|
-
startedAt: performance.now(),
|
|
18091
|
+
const result = await this.evaluate(`(() => {
|
|
18092
|
+
if (!window.__sootsimShellPerf) {
|
|
18093
|
+
return { error: "shell frame profile unavailable (__sootsimShellPerf missing on the page)" }
|
|
17997
18094
|
}
|
|
17998
|
-
|
|
18095
|
+
window.__sootsimShellPerf.start()
|
|
18096
|
+
return { started: true }
|
|
18097
|
+
})()`);
|
|
18098
|
+
if (result?.error) {
|
|
18099
|
+
throw new Error(result.error);
|
|
18100
|
+
}
|
|
17999
18101
|
this.profilingEnabled = true;
|
|
18000
18102
|
}
|
|
18001
18103
|
async stopProfile() {
|
|
18002
|
-
const result = await this.evaluate(`(async (
|
|
18003
|
-
|
|
18004
|
-
|
|
18005
|
-
const perf = window.__sootsimPerf
|
|
18006
|
-
const session = window[sessionKey] || {}
|
|
18007
|
-
const priorSamples = session.active && Array.isArray(session.lastSamples)
|
|
18008
|
-
? session.lastSamples
|
|
18009
|
-
: []
|
|
18010
|
-
const flushedSamples = await host.flushSamples()
|
|
18011
|
-
await perf?.disableFrameStats?.()
|
|
18012
|
-
const samples = priorSamples.concat(flushedSamples)
|
|
18013
|
-
window[sessionKey] = {
|
|
18014
|
-
...session,
|
|
18015
|
-
active: false,
|
|
18016
|
-
mode: 'render-worker',
|
|
18017
|
-
lastSamples: samples,
|
|
18018
|
-
stoppedAt: performance.now(),
|
|
18019
|
-
}
|
|
18020
|
-
|
|
18021
|
-
const frameTimes = samples.map((sample) => Number(sample?.[1]) || 0)
|
|
18022
|
-
const sorted = [...frameTimes].sort((a, b) => a - b)
|
|
18023
|
-
const worstFrames = samples
|
|
18024
|
-
.slice()
|
|
18025
|
-
.sort((a, b) => (Number(b?.[1]) || 0) - (Number(a?.[1]) || 0))
|
|
18026
|
-
.slice(0, 10)
|
|
18027
|
-
.map((sample) => [
|
|
18028
|
-
Number(sample?.[0]) || 0,
|
|
18029
|
-
Number(sample?.[1]) || 0,
|
|
18030
|
-
Number(sample?.[2]) || 0,
|
|
18031
|
-
Number(sample?.[3]) || 0,
|
|
18032
|
-
Number(sample?.[4]) || 0,
|
|
18033
|
-
])
|
|
18034
|
-
|
|
18035
|
-
return {
|
|
18036
|
-
mode: 'render-worker',
|
|
18037
|
-
frames: frameTimes.length,
|
|
18038
|
-
totalMs: frameTimes.reduce((sum, value) => sum + value, 0),
|
|
18039
|
-
avgMs: frameTimes.length ? frameTimes.reduce((sum, value) => sum + value, 0) / frameTimes.length : 0,
|
|
18040
|
-
maxMs: sorted[sorted.length - 1] || 0,
|
|
18041
|
-
layoutTotalMs: samples.reduce((sum, sample) => sum + (Number(sample?.[2]) || 0), 0),
|
|
18042
|
-
renderTotalMs: samples.reduce((sum, sample) => sum + (Number(sample?.[3]) || 0), 0),
|
|
18043
|
-
copyTotalMs: samples.reduce((sum, sample) => sum + (Number(sample?.[4]) || 0), 0),
|
|
18044
|
-
layoutAvgMs: frameTimes.length ? samples.reduce((sum, sample) => sum + (Number(sample?.[2]) || 0), 0) / frameTimes.length : 0,
|
|
18045
|
-
renderAvgMs: frameTimes.length ? samples.reduce((sum, sample) => sum + (Number(sample?.[3]) || 0), 0) / frameTimes.length : 0,
|
|
18046
|
-
copyAvgMs: frameTimes.length ? samples.reduce((sum, sample) => sum + (Number(sample?.[4]) || 0), 0) / frameTimes.length : 0,
|
|
18047
|
-
p50: sorted[Math.floor(sorted.length * 0.5)] || 0,
|
|
18048
|
-
p95: sorted[Math.floor(sorted.length * 0.95)] || 0,
|
|
18049
|
-
p99: sorted[Math.floor(sorted.length * 0.99)] || 0,
|
|
18050
|
-
jankFrames: frameTimes.filter((value) => value > 16.67).length,
|
|
18051
|
-
sampleCount: frameTimes.length,
|
|
18052
|
-
worstFrames,
|
|
18053
|
-
}
|
|
18054
|
-
}
|
|
18055
|
-
|
|
18056
|
-
const perf = window.__sootsimPerf
|
|
18057
|
-
const a11y = window.__sootsimA11y
|
|
18058
|
-
if (!perf && !a11y) return { error: 'no perf globals available' }
|
|
18059
|
-
|
|
18060
|
-
const stoppedStats = await perf?.disableFrameStats?.()
|
|
18061
|
-
const frameStats = stoppedStats || await perf?.getFrameStats?.() || {}
|
|
18062
|
-
const profile = a11y?.profile?.() || {}
|
|
18063
|
-
const recent = Array.isArray(frameStats.recentFrames) ? frameStats.recentFrames : []
|
|
18064
|
-
const sorted = [...recent].sort((a, b) => a - b)
|
|
18065
|
-
|
|
18066
|
-
return {
|
|
18067
|
-
mode: 'main-thread',
|
|
18068
|
-
frames: frameStats.frames || profile.syncCount || 0,
|
|
18069
|
-
totalMs: frameStats.totalMs || 0,
|
|
18070
|
-
avgMs: frameStats.totalMs && frameStats.frames ? frameStats.totalMs / frameStats.frames : profile.avgSyncMs || 0,
|
|
18071
|
-
maxMs: frameStats.maxMs || profile.maxSyncMs || 0,
|
|
18072
|
-
layoutTotalMs: frameStats.layoutTotalMs || 0,
|
|
18073
|
-
p50: sorted[Math.floor(sorted.length * 0.5)] || 0,
|
|
18074
|
-
p95: sorted[Math.floor(sorted.length * 0.95)] || 0,
|
|
18075
|
-
p99: sorted[Math.floor(sorted.length * 0.99)] || 0,
|
|
18076
|
-
jankFrames: recent.filter((value) => value > 16.67).length,
|
|
18077
|
-
sampleCount: recent.length,
|
|
18078
|
-
worstFrames: recent.slice().sort((a, b) => b - a).slice(0, 10),
|
|
18104
|
+
const result = await this.evaluate(`(async () => {
|
|
18105
|
+
if (!window.__sootsimShellPerf) {
|
|
18106
|
+
return { error: "shell frame profile unavailable (__sootsimShellPerf missing on the page)" }
|
|
18079
18107
|
}
|
|
18080
|
-
|
|
18108
|
+
return await window.__sootsimShellPerf.stop()
|
|
18109
|
+
})()`);
|
|
18081
18110
|
this.profilingEnabled = false;
|
|
18082
18111
|
if (result?.error) {
|
|
18083
18112
|
throw new Error(result.error);
|
|
@@ -18139,8 +18168,8 @@ var init_bridge_flow_runner = __esm({
|
|
|
18139
18168
|
runScript(target) {
|
|
18140
18169
|
const spec = typeof target === "string" ? { file: target } : target;
|
|
18141
18170
|
if (!spec.file) throw new Error("runScript requires a file");
|
|
18142
|
-
const scriptPath =
|
|
18143
|
-
const source =
|
|
18171
|
+
const scriptPath = path9.resolve(this.opts.flowDir, spec.file);
|
|
18172
|
+
const source = fs9.readFileSync(scriptPath, "utf8");
|
|
18144
18173
|
this.js.evaluate(source, { env: spec.env });
|
|
18145
18174
|
console.log(`[flow] runScript: ${spec.file} done`);
|
|
18146
18175
|
}
|
|
@@ -18380,10 +18409,10 @@ var init_bridge_flow_runner = __esm({
|
|
|
18380
18409
|
for (const [k, v] of Object.entries(env)) this.js.putEnv(k, v);
|
|
18381
18410
|
}
|
|
18382
18411
|
if (file) {
|
|
18383
|
-
const flowPath =
|
|
18384
|
-
const flowContent =
|
|
18412
|
+
const flowPath = path9.resolve(this.opts.flowDir, file);
|
|
18413
|
+
const flowContent = fs9.readFileSync(flowPath, "utf8");
|
|
18385
18414
|
const previousDir = this.opts.flowDir;
|
|
18386
|
-
this.opts.flowDir =
|
|
18415
|
+
this.opts.flowDir = path9.dirname(flowPath);
|
|
18387
18416
|
try {
|
|
18388
18417
|
await this.runFlow(parseFlowSteps(flowContent));
|
|
18389
18418
|
} finally {
|
|
@@ -18479,8 +18508,8 @@ __export(registry_exports, {
|
|
|
18479
18508
|
skillRegistry: () => skillRegistry
|
|
18480
18509
|
});
|
|
18481
18510
|
module.exports = __toCommonJS(registry_exports);
|
|
18482
|
-
var
|
|
18483
|
-
var
|
|
18511
|
+
var fs10 = __toESM(require("fs"), 1);
|
|
18512
|
+
var path10 = __toESM(require("path"), 1);
|
|
18484
18513
|
|
|
18485
18514
|
// src/skills/builtin/a11y-review.ts
|
|
18486
18515
|
var skill = {
|
|
@@ -18498,8 +18527,8 @@ var skill = {
|
|
|
18498
18527
|
},
|
|
18499
18528
|
async execute(params, context) {
|
|
18500
18529
|
const { chromium } = await import("playwright");
|
|
18501
|
-
const
|
|
18502
|
-
const
|
|
18530
|
+
const path11 = await import("path");
|
|
18531
|
+
const fs11 = await import("fs");
|
|
18503
18532
|
const browser = await chromium.launch({ channel: "chrome", headless: true });
|
|
18504
18533
|
const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
|
|
18505
18534
|
try {
|
|
@@ -18552,9 +18581,9 @@ var skill = {
|
|
|
18552
18581
|
warnings: issues.filter((i) => i.severity === "warning").length,
|
|
18553
18582
|
tree: typeof tree === "string" ? tree : JSON.stringify(tree)
|
|
18554
18583
|
};
|
|
18555
|
-
const reportPath =
|
|
18556
|
-
|
|
18557
|
-
|
|
18584
|
+
const reportPath = path11.join(context.outputDir, "a11y-report.json");
|
|
18585
|
+
fs11.mkdirSync(path11.dirname(reportPath), { recursive: true });
|
|
18586
|
+
fs11.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
18558
18587
|
return {
|
|
18559
18588
|
success: issues.filter((i) => i.severity === "error").length === 0,
|
|
18560
18589
|
message: `${report.errors} errors, ${report.warnings} warnings across ${report.nodeCount} nodes`,
|
|
@@ -18592,8 +18621,8 @@ var skill2 = {
|
|
|
18592
18621
|
}
|
|
18593
18622
|
},
|
|
18594
18623
|
async execute(params, context) {
|
|
18595
|
-
const
|
|
18596
|
-
const
|
|
18624
|
+
const fs11 = await import("fs");
|
|
18625
|
+
const path11 = await import("path");
|
|
18597
18626
|
const { POLYFILL_REGISTRY: POLYFILL_REGISTRY2 } = await Promise.resolve().then(() => (init_web(), web_exports));
|
|
18598
18627
|
if (params.packageName) {
|
|
18599
18628
|
const entry = POLYFILL_REGISTRY2[params.packageName];
|
|
@@ -18611,11 +18640,11 @@ var skill2 = {
|
|
|
18611
18640
|
data: { package: params.packageName, status, ...entry }
|
|
18612
18641
|
};
|
|
18613
18642
|
}
|
|
18614
|
-
const pkgPath =
|
|
18615
|
-
if (!
|
|
18643
|
+
const pkgPath = path11.join(context.projectDir, "package.json");
|
|
18644
|
+
if (!fs11.existsSync(pkgPath)) {
|
|
18616
18645
|
return { success: false, message: "No package.json found" };
|
|
18617
18646
|
}
|
|
18618
|
-
const pkg = JSON.parse(
|
|
18647
|
+
const pkg = JSON.parse(fs11.readFileSync(pkgPath, "utf8"));
|
|
18619
18648
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
18620
18649
|
const results = {
|
|
18621
18650
|
full: [],
|
|
@@ -18633,9 +18662,9 @@ var skill2 = {
|
|
|
18633
18662
|
results.unknown.push(dep);
|
|
18634
18663
|
}
|
|
18635
18664
|
}
|
|
18636
|
-
const reportPath =
|
|
18637
|
-
|
|
18638
|
-
|
|
18665
|
+
const reportPath = path11.join(context.outputDir, "compat-report.json");
|
|
18666
|
+
fs11.mkdirSync(path11.dirname(reportPath), { recursive: true });
|
|
18667
|
+
fs11.writeFileSync(reportPath, JSON.stringify(results, null, 2));
|
|
18639
18668
|
return {
|
|
18640
18669
|
success: results.unsupported.length === 0,
|
|
18641
18670
|
message: `${results.full.length} full, ${results.partial.length} partial, ${results.unsupported.length} unsupported, ${results.unknown.length} unknown`,
|
|
@@ -18673,8 +18702,8 @@ var skill3 = {
|
|
|
18673
18702
|
},
|
|
18674
18703
|
async execute(params, context) {
|
|
18675
18704
|
const { chromium } = await import("playwright");
|
|
18676
|
-
const
|
|
18677
|
-
const
|
|
18705
|
+
const path11 = await import("path");
|
|
18706
|
+
const fs11 = await import("fs");
|
|
18678
18707
|
const browser = await chromium.launch({ channel: "chrome", headless: true });
|
|
18679
18708
|
const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
|
|
18680
18709
|
try {
|
|
@@ -18698,9 +18727,9 @@ var skill3 = {
|
|
|
18698
18727
|
...profile,
|
|
18699
18728
|
fps: syncCount > 0 ? (syncCount / (duration / 1e3)).toFixed(1) : "0"
|
|
18700
18729
|
};
|
|
18701
|
-
const reportPath =
|
|
18702
|
-
|
|
18703
|
-
|
|
18730
|
+
const reportPath = path11.join(context.outputDir, "perf-report.json");
|
|
18731
|
+
fs11.mkdirSync(path11.dirname(reportPath), { recursive: true });
|
|
18732
|
+
fs11.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
18704
18733
|
return {
|
|
18705
18734
|
success: true,
|
|
18706
18735
|
message: `${report.fps} fps, ${profile.avgSyncMs?.toFixed(1)}ms avg sync, ${nodeCount} nodes`,
|
|
@@ -18732,15 +18761,15 @@ var skill4 = {
|
|
|
18732
18761
|
},
|
|
18733
18762
|
async execute(params, context) {
|
|
18734
18763
|
const { chromium } = await import("playwright");
|
|
18735
|
-
const
|
|
18736
|
-
const
|
|
18764
|
+
const path11 = await import("path");
|
|
18765
|
+
const fs11 = await import("fs");
|
|
18737
18766
|
const browser = await chromium.launch({ channel: "chrome", headless: true });
|
|
18738
18767
|
const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
|
|
18739
18768
|
try {
|
|
18740
18769
|
await page.goto(context.url, { waitUntil: "networkidle" });
|
|
18741
18770
|
await page.waitForTimeout(2e3);
|
|
18742
|
-
const outputPath =
|
|
18743
|
-
|
|
18771
|
+
const outputPath = path11.join(context.outputDir, `${params.name}.png`);
|
|
18772
|
+
fs11.mkdirSync(path11.dirname(outputPath), { recursive: true });
|
|
18744
18773
|
await page.screenshot({ path: outputPath });
|
|
18745
18774
|
return {
|
|
18746
18775
|
success: true,
|
|
@@ -18778,8 +18807,8 @@ var skill5 = {
|
|
|
18778
18807
|
record: { type: "boolean", description: "Record video of the flow" }
|
|
18779
18808
|
},
|
|
18780
18809
|
async execute(params, context) {
|
|
18781
|
-
const
|
|
18782
|
-
const
|
|
18810
|
+
const fs11 = await import("fs");
|
|
18811
|
+
const path11 = await import("path");
|
|
18783
18812
|
const yaml2 = await import("yaml");
|
|
18784
18813
|
const { DEFAULT_SOOTSIM_BRIDGE_PORT: DEFAULT_SOOTSIM_BRIDGE_PORT2 } = await Promise.resolve().then(() => (init_bridge_constants(), bridge_constants_exports));
|
|
18785
18814
|
const { SootSimBridgeHost: SootSimBridgeHost2 } = await Promise.resolve().then(() => (init_bridge_host(), bridge_host_exports));
|
|
@@ -18788,7 +18817,7 @@ var skill5 = {
|
|
|
18788
18817
|
const host = new SootSimBridgeHost2({ port: DEFAULT_SOOTSIM_BRIDGE_PORT2 });
|
|
18789
18818
|
host.start({ silent: true });
|
|
18790
18819
|
try {
|
|
18791
|
-
const flowContent =
|
|
18820
|
+
const flowContent = fs11.readFileSync(params.flowPath, "utf8");
|
|
18792
18821
|
const fmMatch = flowContent.match(/^---\n([\s\S]*?)\n---\n?/);
|
|
18793
18822
|
const stepsBody = fmMatch ? flowContent.slice(fmMatch[0].length) : flowContent;
|
|
18794
18823
|
const steps = yaml2.parse(stepsBody);
|
|
@@ -18813,7 +18842,7 @@ var skill5 = {
|
|
|
18813
18842
|
});
|
|
18814
18843
|
const driver = new SootSimBridgeFlowRunner2(bridge, {
|
|
18815
18844
|
screenshotDir: context.outputDir,
|
|
18816
|
-
flowDir:
|
|
18845
|
+
flowDir: path11.dirname(path11.resolve(params.flowPath)),
|
|
18817
18846
|
simId,
|
|
18818
18847
|
recordingOutputDir: params.record ? context.outputDir : void 0
|
|
18819
18848
|
});
|
|
@@ -18835,7 +18864,7 @@ var skill5 = {
|
|
|
18835
18864
|
simId,
|
|
18836
18865
|
videoPath: videoPath || void 0
|
|
18837
18866
|
},
|
|
18838
|
-
artifacts: videoPath ? [{ type: "video", name:
|
|
18867
|
+
artifacts: videoPath ? [{ type: "video", name: path11.basename(videoPath), path: videoPath }] : void 0
|
|
18839
18868
|
};
|
|
18840
18869
|
} finally {
|
|
18841
18870
|
try {
|
|
@@ -18883,21 +18912,21 @@ var skill6 = {
|
|
|
18883
18912
|
},
|
|
18884
18913
|
async execute(params, context) {
|
|
18885
18914
|
const { chromium } = await import("playwright");
|
|
18886
|
-
const
|
|
18887
|
-
const
|
|
18915
|
+
const path11 = await import("path");
|
|
18916
|
+
const fs11 = await import("fs");
|
|
18888
18917
|
const browser = await chromium.launch({ channel: "chrome", headless: true });
|
|
18889
18918
|
const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
|
|
18890
18919
|
try {
|
|
18891
18920
|
await page.goto(context.url, { waitUntil: "networkidle" });
|
|
18892
18921
|
await page.waitForTimeout(2e3);
|
|
18893
|
-
const currentPath =
|
|
18894
|
-
|
|
18922
|
+
const currentPath = path11.join(context.outputDir, `${params.name}-current.png`);
|
|
18923
|
+
fs11.mkdirSync(path11.dirname(currentPath), { recursive: true });
|
|
18895
18924
|
await page.screenshot({ path: currentPath });
|
|
18896
18925
|
try {
|
|
18897
18926
|
const { PNG } = await import("pngjs");
|
|
18898
18927
|
const pixelmatch = (await import("pixelmatch")).default;
|
|
18899
|
-
const baseline = PNG.sync.read(
|
|
18900
|
-
const current = PNG.sync.read(
|
|
18928
|
+
const baseline = PNG.sync.read(fs11.readFileSync(params.baseline));
|
|
18929
|
+
const current = PNG.sync.read(fs11.readFileSync(currentPath));
|
|
18901
18930
|
const { width, height } = baseline;
|
|
18902
18931
|
const diff = new PNG({ width, height });
|
|
18903
18932
|
const numDiffPixels = pixelmatch(
|
|
@@ -18908,8 +18937,8 @@ var skill6 = {
|
|
|
18908
18937
|
height,
|
|
18909
18938
|
{ threshold: params.threshold || 0.1 }
|
|
18910
18939
|
);
|
|
18911
|
-
const diffPath =
|
|
18912
|
-
|
|
18940
|
+
const diffPath = path11.join(context.outputDir, `${params.name}-diff.png`);
|
|
18941
|
+
fs11.writeFileSync(diffPath, PNG.sync.write(diff));
|
|
18913
18942
|
const totalPixels = width * height;
|
|
18914
18943
|
const diffPercent = (numDiffPixels / totalPixels * 100).toFixed(2);
|
|
18915
18944
|
return {
|
|
@@ -18973,10 +19002,10 @@ var skillRegistry = {
|
|
|
18973
19002
|
},
|
|
18974
19003
|
// load skills from a project manifest (sootsim-skills.json)
|
|
18975
19004
|
async loadFromManifest(projectDir) {
|
|
18976
|
-
const manifestPath =
|
|
18977
|
-
if (!
|
|
19005
|
+
const manifestPath = path10.join(projectDir, "sootsim-skills.json");
|
|
19006
|
+
if (!fs10.existsSync(manifestPath)) return;
|
|
18978
19007
|
try {
|
|
18979
|
-
const manifest = JSON.parse(
|
|
19008
|
+
const manifest = JSON.parse(fs10.readFileSync(manifestPath, "utf8"));
|
|
18980
19009
|
if (Array.isArray(manifest.skills)) {
|
|
18981
19010
|
for (const entry of manifest.skills) {
|
|
18982
19011
|
if (typeof entry === "string") {
|
|
@@ -18987,7 +19016,7 @@ var skillRegistry = {
|
|
|
18987
19016
|
}
|
|
18988
19017
|
} else if (entry.file) {
|
|
18989
19018
|
try {
|
|
18990
|
-
const mod = await import(
|
|
19019
|
+
const mod = await import(path10.resolve(projectDir, entry.file));
|
|
18991
19020
|
if (mod.skill) this.register(mod.skill);
|
|
18992
19021
|
} catch {
|
|
18993
19022
|
}
|
|
@@ -19000,10 +19029,10 @@ var skillRegistry = {
|
|
|
19000
19029
|
// auto-discover skills based on project dependencies
|
|
19001
19030
|
suggestSkills(projectDir) {
|
|
19002
19031
|
const suggestions = [];
|
|
19003
|
-
const pkgPath =
|
|
19004
|
-
if (!
|
|
19032
|
+
const pkgPath = path10.join(projectDir, "package.json");
|
|
19033
|
+
if (!fs10.existsSync(pkgPath)) return suggestions;
|
|
19005
19034
|
try {
|
|
19006
|
-
const pkg = JSON.parse(
|
|
19035
|
+
const pkg = JSON.parse(fs10.readFileSync(pkgPath, "utf8"));
|
|
19007
19036
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
19008
19037
|
if (deps["detox"] || deps["maestro"]) {
|
|
19009
19038
|
suggestions.push("test-flow");
|