sootsim 0.1.140 → 0.1.141
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-N767ME6M.js → agent-BFN5TIRU.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-ELHIUFZZ.js → agent-wrapper-A4UNOJOD.js} +2 -2
- package/dist-cli/chunks/{app-fonts-OZ3OSNAJ.js → app-fonts-KEAMDLYZ.js} +2 -2
- package/dist-cli/chunks/{assert-GGFUQBNB.js → assert-BWBAKX5N.js} +2 -2
- package/dist-cli/chunks/auto-bootstrap-WJH44ZIE.js +2 -0
- package/dist-cli/chunks/beta-VFKZHKER.js +2 -0
- package/dist-cli/chunks/{camera-5PYEDLLB.js → camera-P5TTGC72.js} +2 -2
- package/dist-cli/chunks/{chunk-PBS47TD5.js → chunk-33EJL7CG.js} +2 -2
- package/dist-cli/chunks/{chunk-BLQBPN76.js → chunk-3LN2PP4L.js} +2 -2
- package/dist-cli/chunks/{chunk-MRQRJINW.js → chunk-4ISWLDJG.js} +1 -1
- package/dist-cli/chunks/{chunk-EMNVJOEL.js → chunk-53DRW635.js} +3 -3
- package/dist-cli/chunks/{chunk-7SMEXHWJ.js → chunk-7A7VFR2C.js} +1 -1
- package/dist-cli/chunks/{chunk-GL74P6NR.js → chunk-7SO2SJ4H.js} +1 -1
- package/dist-cli/chunks/{chunk-RAY2DLSK.js → chunk-A5W3HB44.js} +1 -1
- package/dist-cli/chunks/{chunk-SSZBFWV7.js → chunk-AJGTCVQX.js} +1 -1
- package/dist-cli/chunks/{chunk-R5F7XGAO.js → chunk-AMSIP5PD.js} +3 -3
- package/dist-cli/chunks/{chunk-ZGDJ5TFU.js → chunk-AQVB4G34.js} +2 -2
- package/dist-cli/chunks/{chunk-N2XPC4Z7.js → chunk-DM5KNA7Q.js} +2 -2
- package/dist-cli/chunks/{chunk-ZN4Z2W7F.js → chunk-EIZ6LJP2.js} +2 -2
- package/dist-cli/chunks/{chunk-5VTYMBUK.js → chunk-ETB6DHJM.js} +2 -2
- package/dist-cli/chunks/{chunk-WGDXZMKT.js → chunk-HDCTWR2Q.js} +2 -2
- package/dist-cli/chunks/chunk-I3JPJMJB.js +5 -0
- package/dist-cli/chunks/{chunk-QRRBQE6M.js → chunk-I6SWX7OI.js} +2 -2
- package/dist-cli/chunks/{chunk-BGXNYXBC.js → chunk-IILFDOSF.js} +1 -1
- package/dist-cli/chunks/{chunk-4FGNOWB6.js → chunk-IITPPGBS.js} +1 -1
- package/dist-cli/chunks/{chunk-QXOZB7WD.js → chunk-ITJLXD4X.js} +2 -2
- package/dist-cli/chunks/{chunk-BM7QWZRI.js → chunk-JJBNA2JO.js} +2 -2
- package/dist-cli/chunks/{chunk-AI65UVSN.js → chunk-JM5XCDBF.js} +2 -2
- package/dist-cli/chunks/{chunk-AOICEZCA.js → chunk-JQTHQOPS.js} +2 -2
- package/dist-cli/chunks/{chunk-X6AWKKL4.js → chunk-KMQWCYU7.js} +2 -2
- package/dist-cli/chunks/{chunk-XGYD25DJ.js → chunk-LHIPDN4B.js} +1 -1
- package/dist-cli/chunks/{chunk-6KUVOSFF.js → chunk-LHS4PEAA.js} +2 -2
- package/dist-cli/chunks/{chunk-ZVQOEMXS.js → chunk-M7S4VLEL.js} +54 -54
- package/dist-cli/chunks/{chunk-REIC7HRW.js → chunk-MENSR2TZ.js} +1 -1
- package/dist-cli/chunks/chunk-MHUNWWWS.js +412 -0
- package/dist-cli/chunks/chunk-MYKHUFW2.js +1 -0
- package/dist-cli/chunks/chunk-NOAONZTZ.js +119 -0
- package/dist-cli/chunks/{chunk-C3FURRBF.js → chunk-NQJD2WTM.js} +1 -1
- package/dist-cli/chunks/{chunk-QOZ2Q4FH.js → chunk-PVPWCA2K.js} +1 -1
- package/dist-cli/chunks/{chunk-GYZNLDBX.js → chunk-RBUJZXNR.js} +5 -5
- package/dist-cli/chunks/{chunk-AP2MOP44.js → chunk-RUXWU3UH.js} +1 -1
- package/dist-cli/chunks/{chunk-UHTE6FLK.js → chunk-SXHBK5IJ.js} +2 -2
- package/dist-cli/chunks/chunk-SYRS7NKN.js +1 -0
- package/dist-cli/chunks/chunk-TUZVZ5QS.js +1 -0
- package/dist-cli/chunks/{chunk-CQ3LV5VL.js → chunk-URPQTI2I.js} +2 -2
- package/dist-cli/chunks/{chunk-GI43DDEI.js → chunk-UYQDGXHQ.js} +1 -1
- package/dist-cli/chunks/{chunk-4FBFOWV3.js → chunk-WUQHVDJU.js} +2 -2
- package/dist-cli/chunks/{chunk-FYUDIUFX.js → chunk-XD7XHQUO.js} +2 -2
- package/dist-cli/chunks/{chunk-77TL74AM.js → chunk-XERRDQLM.js} +1 -1
- package/dist-cli/chunks/{chunk-O2SQNUDP.js → chunk-XQRCVSK3.js} +1 -1
- package/dist-cli/chunks/{chunk-HPTMLB7V.js → chunk-YOJ6BZCH.js} +1 -1
- package/dist-cli/chunks/chunk-ZBN3P5JE.js +2 -0
- package/dist-cli/chunks/cli-version-3G6HHMRW.js +2 -0
- package/dist-cli/chunks/{compat-U3772TUK.js → compat-3Z67EPSJ.js} +3 -3
- package/dist-cli/chunks/{config-6CZCIYKJ.js → config-SH3NTYZ2.js} +2 -2
- package/dist-cli/chunks/{control-NVA25O65.js → control-2XVEDKYZ.js} +2 -2
- package/dist-cli/chunks/{cpu-profile-WRLTZYO6.js → cpu-profile-FANLHU4S.js} +2 -2
- package/dist-cli/chunks/{daemon-QQPGLGS6.js → daemon-QGDVR4JT.js} +2 -2
- package/dist-cli/chunks/{debug-RKYLSDZV.js → debug-EIUEPLFN.js} +3 -3
- package/dist-cli/chunks/{detox-ZRUQQU22.js → detox-EV3KYFKR.js} +2 -2
- package/dist-cli/chunks/{device-HXTOLEWY.js → device-UC5DAVA6.js} +2 -2
- package/dist-cli/chunks/{diagnose-QN4E4WA6.js → diagnose-Q2M2AJBD.js} +2 -2
- package/dist-cli/chunks/drivers-VJIWLDTC.js +2 -0
- package/dist-cli/chunks/{electron-ZHRC4WQ5.js → electron-PXKF52Q6.js} +3 -3
- package/dist-cli/chunks/flow-RGMXGVLL.js +2 -0
- package/dist-cli/chunks/help-TBZZP4SA.js +2 -0
- package/dist-cli/chunks/{hints-HCHKMDUE.js → hints-HS7X2FIO.js} +2 -2
- package/dist-cli/chunks/{home-paths-3OHKRAE4.js → home-paths-KPMXMJQ7.js} +2 -2
- package/dist-cli/chunks/{inspect-QXUBDKJJ.js → inspect-ZUWEMCIG.js} +3 -3
- package/dist-cli/chunks/install-FPYDDDQ4.js +2 -0
- package/dist-cli/chunks/{install-desktop-QCX44BGL.js → install-desktop-H6ZTTVXC.js} +3 -3
- package/dist-cli/chunks/{keys-VEP2KPUF.js → keys-6OBZZLCJ.js} +2 -2
- package/dist-cli/chunks/{launch-K4BPQLTP.js → launch-7JASEDHP.js} +3 -3
- package/dist-cli/chunks/{login-UVC5XRKR.js → login-JWMB6JNS.js} +4 -4
- package/dist-cli/chunks/{logout-3VW34IBA.js → logout-LWVFUKF5.js} +2 -2
- package/dist-cli/chunks/maestro-WX22SLCR.js +94 -0
- package/dist-cli/chunks/optional-demo-registry-52MHQCYV.js +2 -0
- package/dist-cli/chunks/{preview-TZYJMLEJ.js → preview-SDMLCW3U.js} +2 -2
- package/dist-cli/chunks/{profile-HDJRF7YB.js → profile-MQVLCO7R.js} +2 -2
- package/dist-cli/chunks/{react-RLJR26M7.js → react-2JFP5W4W.js} +2 -2
- package/dist-cli/chunks/{record-2LDDHHUY.js → record-IJJ3SPXP.js} +2 -2
- package/dist-cli/chunks/runtime-JJMZ4AF3.js +2 -0
- package/dist-cli/chunks/{runtime-delivery-3F6O57E5.js → runtime-delivery-5M2P7LEI.js} +2 -2
- package/dist-cli/chunks/{screenshot-QAUSSEPK.js → screenshot-4QAGJCPZ.js} +2 -2
- package/dist-cli/chunks/{screenshot-mode-K6HEVK4K.js → screenshot-mode-PSAU7TH4.js} +2 -2
- package/dist-cli/chunks/{screenshots-TWMCGUBT.js → screenshots-73VI4UUL.js} +2 -2
- package/dist-cli/chunks/{server-ZPIZCBW5.js → server-BXD5WKQS.js} +3 -3
- package/dist-cli/chunks/setup-repo-F2P5RZ4R.js +2 -0
- package/dist-cli/chunks/{skills-NI3RH7CW.js → skills-IEJOURWM.js} +2 -2
- package/dist-cli/chunks/{start-G6CQL6HJ.js → start-CLBAJ4LJ.js} +4 -4
- package/dist-cli/chunks/store-7DIOVJNK.js +2 -0
- package/dist-cli/chunks/telemetry-3XHPQYOQ.js +2 -0
- package/dist-cli/chunks/{test-V47D6EPK.js → test-42YWJ5ZT.js} +3 -3
- package/dist-cli/chunks/{three-mode-G7N3LRHM.js → three-mode-5DU4IBF5.js} +2 -2
- package/dist-cli/chunks/{timeline-EBUOILTJ.js → timeline-WJYQRW5S.js} +2 -2
- package/dist-cli/chunks/{upgrade-OQJLTCQP.js → upgrade-F7ADMCLU.js} +2 -2
- package/dist-cli/chunks/upload-TJ2XKWDS.js +2 -0
- package/dist-cli/chunks/{version-3YJPPUE5.js → version-SLA5P34B.js} +2 -2
- package/dist-cli/chunks/{web-ZKUX5ICX.js → web-OGC6GSKM.js} +2 -2
- package/dist-cli/chunks/{what-happened-HOY3TA42.js → what-happened-VYXK3O2C.js} +2 -2
- package/dist-cli/chunks/{whoami-GOCSBVTG.js → whoami-QL2LTKOF.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 +5 -2
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +2 -2
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +2 -2
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +351 -80
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/src/config.ts +13 -0
- package/dist-cli/chunks/auto-bootstrap-L5E6XMCK.js +0 -2
- package/dist-cli/chunks/beta-D74SDA2L.js +0 -2
- package/dist-cli/chunks/chunk-5EP5RRNS.js +0 -381
- package/dist-cli/chunks/chunk-BEA3AO36.js +0 -5
- package/dist-cli/chunks/chunk-EH6YDCSN.js +0 -119
- package/dist-cli/chunks/chunk-NQG4R5K2.js +0 -1
- package/dist-cli/chunks/chunk-Q5Z7P54I.js +0 -2
- package/dist-cli/chunks/chunk-S7I6ZCT2.js +0 -1
- package/dist-cli/chunks/chunk-WN3WZEE5.js +0 -1
- package/dist-cli/chunks/cli-version-EZRTEUXF.js +0 -2
- package/dist-cli/chunks/drivers-EVK22AX5.js +0 -2
- package/dist-cli/chunks/flow-ICCRVJVX.js +0 -2
- package/dist-cli/chunks/help-QMZ35MIQ.js +0 -2
- package/dist-cli/chunks/install-JSDZIE2T.js +0 -2
- package/dist-cli/chunks/maestro-HTFXXMLR.js +0 -80
- package/dist-cli/chunks/optional-demo-registry-5YYEAL46.js +0 -2
- package/dist-cli/chunks/runtime-QPYF2WQX.js +0 -2
- package/dist-cli/chunks/setup-repo-VHOZJEIV.js +0 -2
- package/dist-cli/chunks/store-F6MJUJYW.js +0 -2
- package/dist-cli/chunks/telemetry-DM2Y7OQJ.js +0 -2
- package/dist-cli/chunks/upload-W3YCA65H.js +0 -2
package/dist-lib/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.141 | (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;
|
|
@@ -9982,7 +9982,7 @@ function hasOwnKeys(value) {
|
|
|
9982
9982
|
}
|
|
9983
9983
|
function hasSootSimConfig(config) {
|
|
9984
9984
|
if (!config) return false;
|
|
9985
|
-
return hasOwnKeys(config.modules) || hasOwnKeys(config.turboModules) || hasOwnKeys(config.nativeModules) || hasOwnKeys(config.env) || hasOwnKeys(config.settings) || hasOwnKeys(config.initialState);
|
|
9985
|
+
return hasOwnKeys(config.modules) || hasOwnKeys(config.turboModules) || hasOwnKeys(config.nativeModules) || hasOwnKeys(config.env) || hasOwnKeys(config.network?.remap) || hasOwnKeys(config.settings) || hasOwnKeys(config.initialState);
|
|
9986
9986
|
}
|
|
9987
9987
|
function applySootSimConfigToUrl(url, config) {
|
|
9988
9988
|
const parsed = new URL(url);
|
|
@@ -15465,36 +15465,234 @@ var init_settling = __esm({
|
|
|
15465
15465
|
}
|
|
15466
15466
|
});
|
|
15467
15467
|
|
|
15468
|
-
// cli/
|
|
15469
|
-
function
|
|
15470
|
-
if (
|
|
15471
|
-
|
|
15472
|
-
if (scopedVars?.has(name)) return scopedVars.get(name);
|
|
15473
|
-
const resolved = process.env[name];
|
|
15474
|
-
if (resolved === void 0) {
|
|
15475
|
-
throw new Error(`missing environment variable for flow placeholder: ${name}`);
|
|
15476
|
-
}
|
|
15477
|
-
return resolved;
|
|
15478
|
-
});
|
|
15468
|
+
// cli/maestro-js.ts
|
|
15469
|
+
function executeSyncHttp(url, method, params) {
|
|
15470
|
+
if (params?.multipartForm) {
|
|
15471
|
+
throw new Error("http: multipartForm is not supported by sootsim yet");
|
|
15479
15472
|
}
|
|
15480
|
-
|
|
15481
|
-
|
|
15473
|
+
const child = (0, import_child_process6.spawnSync)(process.execPath, ["-e", HTTP_CHILD_SRC], {
|
|
15474
|
+
input: JSON.stringify({ url, method, headers: params?.headers, body: params?.body }),
|
|
15475
|
+
encoding: "utf8",
|
|
15476
|
+
timeout: HTTP_TIMEOUT_MS,
|
|
15477
|
+
maxBuffer: 64 * 1024 * 1024
|
|
15478
|
+
});
|
|
15479
|
+
if (child.error) {
|
|
15480
|
+
throw new Error(`http ${method} ${url} failed: ${child.error.message}`);
|
|
15482
15481
|
}
|
|
15483
|
-
|
|
15484
|
-
|
|
15485
|
-
|
|
15486
|
-
|
|
15487
|
-
|
|
15488
|
-
|
|
15482
|
+
let parsed;
|
|
15483
|
+
try {
|
|
15484
|
+
parsed = JSON.parse(child.stdout || "");
|
|
15485
|
+
} catch {
|
|
15486
|
+
throw new Error(
|
|
15487
|
+
`http ${method} ${url} failed: no response (${(child.stderr || "").trim().slice(0, 200)})`
|
|
15489
15488
|
);
|
|
15490
15489
|
}
|
|
15491
|
-
|
|
15490
|
+
const result = parsed;
|
|
15491
|
+
if (result.__error) {
|
|
15492
|
+
throw new Error(`http ${method} ${url} failed: ${result.__error}`);
|
|
15493
|
+
}
|
|
15494
|
+
return result;
|
|
15495
|
+
}
|
|
15496
|
+
function stringifyJs(value) {
|
|
15497
|
+
if (value === void 0) return "undefined";
|
|
15498
|
+
if (value === null) return "null";
|
|
15499
|
+
if (typeof value === "object") {
|
|
15500
|
+
try {
|
|
15501
|
+
return JSON.stringify(value);
|
|
15502
|
+
} catch {
|
|
15503
|
+
return String(value);
|
|
15504
|
+
}
|
|
15505
|
+
}
|
|
15506
|
+
return String(value);
|
|
15492
15507
|
}
|
|
15493
|
-
|
|
15494
|
-
|
|
15495
|
-
"
|
|
15508
|
+
function scriptConditionIsTruthy(value) {
|
|
15509
|
+
if (value === void 0 || value === null) return false;
|
|
15510
|
+
if (typeof value === "boolean") return value;
|
|
15511
|
+
const text = String(value);
|
|
15512
|
+
if (text.trim().length === 0) return false;
|
|
15513
|
+
if (text.toLowerCase() === "false") return false;
|
|
15514
|
+
if (text === "undefined" || text === "null") return false;
|
|
15515
|
+
const num = Number(text);
|
|
15516
|
+
if (!Number.isNaN(num) && num === 0) return false;
|
|
15517
|
+
return true;
|
|
15518
|
+
}
|
|
15519
|
+
var import_child_process6, vm, HTTP_TIMEOUT_MS, HTTP_CHILD_SRC, TEMPLATE_RE, ESCAPED_TEMPLATE_RE, BARE_IDENTIFIER_RE, MaestroJsContext;
|
|
15520
|
+
var init_maestro_js = __esm({
|
|
15521
|
+
"cli/maestro-js.ts"() {
|
|
15496
15522
|
"use strict";
|
|
15497
|
-
|
|
15523
|
+
import_child_process6 = require("child_process");
|
|
15524
|
+
vm = __toESM(require("vm"), 1);
|
|
15525
|
+
HTTP_TIMEOUT_MS = 3e5;
|
|
15526
|
+
HTTP_CHILD_SRC = `
|
|
15527
|
+
let input = '';
|
|
15528
|
+
process.stdin.on('data', (c) => { input += c });
|
|
15529
|
+
process.stdin.on('end', async () => {
|
|
15530
|
+
try {
|
|
15531
|
+
const req = JSON.parse(input);
|
|
15532
|
+
const res = await fetch(req.url, {
|
|
15533
|
+
method: req.method,
|
|
15534
|
+
headers: req.headers,
|
|
15535
|
+
body: req.body === undefined || req.body === null ? undefined : req.body,
|
|
15536
|
+
});
|
|
15537
|
+
const body = await res.text();
|
|
15538
|
+
const headers = {};
|
|
15539
|
+
for (const [k, v] of res.headers.entries()) {
|
|
15540
|
+
headers[k] = headers[k] ? headers[k] + ',' + v : v;
|
|
15541
|
+
}
|
|
15542
|
+
process.stdout.write(JSON.stringify({ ok: res.ok, status: res.status, body, headers }));
|
|
15543
|
+
} catch (err) {
|
|
15544
|
+
process.stdout.write(JSON.stringify({ __error: (err && err.message) || String(err) }));
|
|
15545
|
+
process.exitCode = 1;
|
|
15546
|
+
}
|
|
15547
|
+
});
|
|
15548
|
+
`;
|
|
15549
|
+
TEMPLATE_RE = /(?<!\\)\$\{([^$]*)\}/g;
|
|
15550
|
+
ESCAPED_TEMPLATE_RE = /\\(\$\{[^$]*\})/g;
|
|
15551
|
+
BARE_IDENTIFIER_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
15552
|
+
MaestroJsContext = class {
|
|
15553
|
+
context;
|
|
15554
|
+
envBinding = /* @__PURE__ */ new Map();
|
|
15555
|
+
envScopeStack = [];
|
|
15556
|
+
// env keys currently materialized as context globals — cleared and re-set
|
|
15557
|
+
// before each evaluation, mirroring upstream syncBindingsToContext.
|
|
15558
|
+
syncedEnvKeys = /* @__PURE__ */ new Set();
|
|
15559
|
+
output = {};
|
|
15560
|
+
maestro;
|
|
15561
|
+
constructor(opts = {}) {
|
|
15562
|
+
this.maestro = { copiedText: null, platform: opts.platform ?? "ios" };
|
|
15563
|
+
const onLog = opts.onLog ?? ((msg) => console.log(`[flow] js: ${msg}`));
|
|
15564
|
+
const sandbox = {
|
|
15565
|
+
output: this.output,
|
|
15566
|
+
maestro: this.maestro,
|
|
15567
|
+
http: {
|
|
15568
|
+
get: (url, params) => executeSyncHttp(url, "GET", params),
|
|
15569
|
+
post: (url, params) => executeSyncHttp(url, "POST", params),
|
|
15570
|
+
put: (url, params) => executeSyncHttp(url, "PUT", params),
|
|
15571
|
+
delete: (url, params) => executeSyncHttp(url, "DELETE", params),
|
|
15572
|
+
request: (url, params) => executeSyncHttp(url, (params?.method ?? "GET").toUpperCase(), params)
|
|
15573
|
+
},
|
|
15574
|
+
console: {
|
|
15575
|
+
log: (...args) => onLog(args.map((a) => typeof a === "string" ? a : stringifyJs(a)).join(" "))
|
|
15576
|
+
}
|
|
15577
|
+
};
|
|
15578
|
+
this.context = vm.createContext(sandbox);
|
|
15579
|
+
vm.runInContext(
|
|
15580
|
+
`
|
|
15581
|
+
globalThis.__maestroScope = new Proxy(globalThis, {
|
|
15582
|
+
has() { return true },
|
|
15583
|
+
get(target, key) { return target[key] },
|
|
15584
|
+
})
|
|
15585
|
+
function json(text) { return JSON.parse(text) }
|
|
15586
|
+
function relativePoint(x, y) {
|
|
15587
|
+
var xPercent = Math.ceil(x * 100) + '%'
|
|
15588
|
+
var yPercent = Math.ceil(y * 100) + '%'
|
|
15589
|
+
return xPercent + ',' + yPercent
|
|
15590
|
+
}
|
|
15591
|
+
`,
|
|
15592
|
+
this.context
|
|
15593
|
+
);
|
|
15594
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
15595
|
+
if (value !== void 0) this.envBinding.set(key, value);
|
|
15596
|
+
}
|
|
15597
|
+
}
|
|
15598
|
+
putEnv(key, value) {
|
|
15599
|
+
this.envBinding.set(key, value);
|
|
15600
|
+
}
|
|
15601
|
+
setCopiedText(text) {
|
|
15602
|
+
this.maestro.copiedText = text;
|
|
15603
|
+
}
|
|
15604
|
+
enterEnvScope() {
|
|
15605
|
+
this.envScopeStack.push(new Map(this.envBinding));
|
|
15606
|
+
}
|
|
15607
|
+
leaveEnvScope() {
|
|
15608
|
+
const previous = this.envScopeStack.pop();
|
|
15609
|
+
if (previous) {
|
|
15610
|
+
this.envBinding.clear();
|
|
15611
|
+
for (const [k, v] of previous) this.envBinding.set(k, v);
|
|
15612
|
+
}
|
|
15613
|
+
}
|
|
15614
|
+
// evaluate a JS snippet in the shared context. mirrors upstream
|
|
15615
|
+
// evalWithIIFE: the script is embedded in a template literal and run
|
|
15616
|
+
// through eval inside an IIFE so var/let/const stay scoped to this
|
|
15617
|
+
// evaluation while the last expression's value is returned.
|
|
15618
|
+
evaluate(script, opts = {}) {
|
|
15619
|
+
const env = opts.env;
|
|
15620
|
+
if (env && Object.keys(env).length > 0) {
|
|
15621
|
+
this.enterEnvScope();
|
|
15622
|
+
try {
|
|
15623
|
+
for (const [k, v] of Object.entries(env)) this.envBinding.set(k, v);
|
|
15624
|
+
return this.evalRaw(script);
|
|
15625
|
+
} finally {
|
|
15626
|
+
this.leaveEnvScope();
|
|
15627
|
+
}
|
|
15628
|
+
}
|
|
15629
|
+
return this.evalRaw(script);
|
|
15630
|
+
}
|
|
15631
|
+
evalRaw(script) {
|
|
15632
|
+
this.syncEnvToContext();
|
|
15633
|
+
const escaped = script.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
15634
|
+
return vm.runInContext(
|
|
15635
|
+
`(function(){ with(__maestroScope){ return eval(\`${escaped}\`) } })()`,
|
|
15636
|
+
this.context
|
|
15637
|
+
);
|
|
15638
|
+
}
|
|
15639
|
+
syncEnvToContext() {
|
|
15640
|
+
const globals = vm.runInContext("globalThis", this.context);
|
|
15641
|
+
for (const key of this.syncedEnvKeys) {
|
|
15642
|
+
if (!this.envBinding.has(key)) delete globals[key];
|
|
15643
|
+
}
|
|
15644
|
+
this.syncedEnvKeys = /* @__PURE__ */ new Set();
|
|
15645
|
+
for (const [key, value] of this.envBinding) {
|
|
15646
|
+
try {
|
|
15647
|
+
globals[key] = value;
|
|
15648
|
+
this.syncedEnvKeys.add(key);
|
|
15649
|
+
} catch {
|
|
15650
|
+
}
|
|
15651
|
+
}
|
|
15652
|
+
}
|
|
15653
|
+
// upstream Env.kt String.evaluateScripts: replace every unescaped `${expr}`
|
|
15654
|
+
// with the stringified evaluation result, then unescape `\${...}`.
|
|
15655
|
+
evaluateStringTemplate(value) {
|
|
15656
|
+
const replaced = value.replace(TEMPLATE_RE, (_match, expr) => {
|
|
15657
|
+
if (expr.trim().length === 0) return "";
|
|
15658
|
+
const result = this.evaluate(expr);
|
|
15659
|
+
if (result === void 0 && BARE_IDENTIFIER_RE.test(expr.trim())) {
|
|
15660
|
+
throw new Error(`missing variable for flow placeholder: ${expr.trim()}`);
|
|
15661
|
+
}
|
|
15662
|
+
return stringifyJs(result);
|
|
15663
|
+
});
|
|
15664
|
+
return replaced.replace(ESCAPED_TEMPLATE_RE, (_match, inner) => inner);
|
|
15665
|
+
}
|
|
15666
|
+
// walk a parsed step and evaluate every string template. nested command
|
|
15667
|
+
// lists are skipped — each nested command evaluates its own strings when
|
|
15668
|
+
// it executes (matching upstream per-command evaluateScripts timing, and
|
|
15669
|
+
// required for values that change between iterations, e.g. copyTextFrom
|
|
15670
|
+
// inside repeat).
|
|
15671
|
+
interpolateStep(step) {
|
|
15672
|
+
return this.interpolateValue(step, null);
|
|
15673
|
+
}
|
|
15674
|
+
interpolateValue(value, parentKey) {
|
|
15675
|
+
if (typeof value === "string") {
|
|
15676
|
+
if (parentKey === "evalScript") return value;
|
|
15677
|
+
return this.evaluateStringTemplate(value);
|
|
15678
|
+
}
|
|
15679
|
+
if (Array.isArray(value)) {
|
|
15680
|
+
if (parentKey === "commands" || parentKey === "onFlowStart" || parentKey === "onFlowComplete") {
|
|
15681
|
+
return value;
|
|
15682
|
+
}
|
|
15683
|
+
return value.map((entry) => this.interpolateValue(entry, parentKey));
|
|
15684
|
+
}
|
|
15685
|
+
if (value && typeof value === "object") {
|
|
15686
|
+
return Object.fromEntries(
|
|
15687
|
+
Object.entries(value).map(([key, entry]) => [
|
|
15688
|
+
key,
|
|
15689
|
+
this.interpolateValue(entry, key)
|
|
15690
|
+
])
|
|
15691
|
+
);
|
|
15692
|
+
}
|
|
15693
|
+
return value;
|
|
15694
|
+
}
|
|
15695
|
+
};
|
|
15498
15696
|
}
|
|
15499
15697
|
});
|
|
15500
15698
|
|
|
@@ -15814,19 +16012,11 @@ var init_recording_access = __esm({
|
|
|
15814
16012
|
var bridge_flow_runner_exports = {};
|
|
15815
16013
|
__export(bridge_flow_runner_exports, {
|
|
15816
16014
|
SootSimBridgeFlowRunner: () => SootSimBridgeFlowRunner,
|
|
15817
|
-
clearFlowScopedVars: () => clearFlowScopedVars,
|
|
15818
16015
|
normalizeFlowScreenshotSpec: () => normalizeFlowScreenshotSpec,
|
|
15819
16016
|
parseFlowSteps: () => parseFlowSteps,
|
|
15820
16017
|
resolveFlowScreenshotPath: () => resolveFlowScreenshotPath,
|
|
15821
|
-
resolveFlowScreenshotPathWithMode: () => resolveFlowScreenshotPathWithMode
|
|
15822
|
-
setFlowScopedVar: () => setFlowScopedVar
|
|
16018
|
+
resolveFlowScreenshotPathWithMode: () => resolveFlowScreenshotPathWithMode
|
|
15823
16019
|
});
|
|
15824
|
-
function setFlowScopedVar(name, value) {
|
|
15825
|
-
flowScopedVars.set(name, value);
|
|
15826
|
-
}
|
|
15827
|
-
function clearFlowScopedVars() {
|
|
15828
|
-
flowScopedVars.clear();
|
|
15829
|
-
}
|
|
15830
16020
|
function sleep(ms) {
|
|
15831
16021
|
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
15832
16022
|
}
|
|
@@ -15873,34 +16063,39 @@ function parsePoint(value) {
|
|
|
15873
16063
|
function parseFlowSteps(content) {
|
|
15874
16064
|
const parts = content.split(/^---$/m);
|
|
15875
16065
|
const candidate = parts.length > 1 ? parts[parts.length - 1] : content;
|
|
15876
|
-
const parsed =
|
|
16066
|
+
const parsed = import_yaml.default.parse(candidate);
|
|
15877
16067
|
return Array.isArray(parsed) ? parsed : [];
|
|
15878
16068
|
}
|
|
15879
|
-
var fs7, path7, import_settings2,
|
|
16069
|
+
var fs7, path7, import_settings2, import_yaml, DEFAULT_TIMEOUT, SCREEN_W, SCREEN_H, CLI_PERF_SESSION_GLOBAL, SootSimBridgeFlowRunner;
|
|
15880
16070
|
var init_bridge_flow_runner = __esm({
|
|
15881
16071
|
"cli/bridge-flow-runner.ts"() {
|
|
15882
16072
|
"use strict";
|
|
15883
16073
|
fs7 = __toESM(require("fs"), 1);
|
|
15884
16074
|
path7 = __toESM(require("path"), 1);
|
|
15885
16075
|
import_settings2 = require("sootsim-engine/settings");
|
|
15886
|
-
|
|
16076
|
+
import_yaml = __toESM(require("yaml"), 1);
|
|
15887
16077
|
init_frame_compose();
|
|
15888
16078
|
init_app_state_reset();
|
|
15889
16079
|
init_settling();
|
|
15890
|
-
|
|
16080
|
+
init_maestro_js();
|
|
15891
16081
|
init_recording_access();
|
|
15892
16082
|
DEFAULT_TIMEOUT = 1e4;
|
|
15893
16083
|
SCREEN_W = 393;
|
|
15894
16084
|
SCREEN_H = 852;
|
|
15895
16085
|
CLI_PERF_SESSION_GLOBAL = "__sootsimCliPerf";
|
|
15896
|
-
MAESTRO_COPIED_TEXT_KEY = "maestroCopiedText";
|
|
15897
|
-
flowScopedVars = /* @__PURE__ */ new Map();
|
|
15898
16086
|
SootSimBridgeFlowRunner = class {
|
|
15899
16087
|
constructor(bridge, opts) {
|
|
15900
16088
|
this.bridge = bridge;
|
|
15901
16089
|
this.opts = opts;
|
|
15902
16090
|
}
|
|
15903
16091
|
stepDelay = 0;
|
|
16092
|
+
// maestro-compatible JS context for the whole flow run (shared with
|
|
16093
|
+
// runFlow sub-flows): `${...}` templates, runScript, evalScript, output,
|
|
16094
|
+
// maestro.copiedText. one per runner = one per flow file, like upstream.
|
|
16095
|
+
js = new MaestroJsContext({
|
|
16096
|
+
platform: "ios",
|
|
16097
|
+
onLog: (msg) => console.log(`[flow] js: ${msg}`)
|
|
16098
|
+
});
|
|
15904
16099
|
firstLaunchDone = false;
|
|
15905
16100
|
profilingEnabled = false;
|
|
15906
16101
|
recordingEnabled = false;
|
|
@@ -16717,6 +16912,9 @@ var init_bridge_flow_runner = __esm({
|
|
|
16717
16912
|
}
|
|
16718
16913
|
async launchApp(opts) {
|
|
16719
16914
|
await this.refreshSimId();
|
|
16915
|
+
if (opts && typeof opts === "object" && opts.arguments) {
|
|
16916
|
+
console.log("[flow] launchApp.arguments ignored (sootsim has no native process)");
|
|
16917
|
+
}
|
|
16720
16918
|
const wantsClear = !!(opts && typeof opts === "object" && opts.clearState);
|
|
16721
16919
|
if (wantsClear) {
|
|
16722
16920
|
await this.evaluate(`(async () => {
|
|
@@ -16900,7 +17098,8 @@ var init_bridge_flow_runner = __esm({
|
|
|
16900
17098
|
);
|
|
16901
17099
|
}
|
|
16902
17100
|
// maestro copyTextFrom: find an element and capture its text for use in
|
|
16903
|
-
// later steps via ${
|
|
17101
|
+
// later steps via ${maestro.copiedText} (upstream form) or the legacy
|
|
17102
|
+
// ${maestroCopiedText}. the matcher shape matches tapOn.
|
|
16904
17103
|
async copyTextFrom(target) {
|
|
16905
17104
|
const opts = typeof target === "string" ? { id: target } : target;
|
|
16906
17105
|
const node = await this.findElement(opts);
|
|
@@ -16908,36 +17107,52 @@ var init_bridge_flow_runner = __esm({
|
|
|
16908
17107
|
throw new Error(`copyTextFrom: element not found: ${JSON.stringify(opts)}`);
|
|
16909
17108
|
}
|
|
16910
17109
|
const captured = node.text ?? node.testID ?? "";
|
|
16911
|
-
|
|
17110
|
+
this.js.setCopiedText(captured);
|
|
17111
|
+
this.js.putEnv("maestroCopiedText", captured);
|
|
16912
17112
|
console.log(`[flow] copied text: ${JSON.stringify(captured)}`);
|
|
16913
17113
|
}
|
|
16914
|
-
// maestro evalScript: run
|
|
16915
|
-
//
|
|
16916
|
-
//
|
|
16917
|
-
|
|
16918
|
-
|
|
16919
|
-
|
|
16920
|
-
|
|
16921
|
-
|
|
16922
|
-
|
|
16923
|
-
|
|
16924
|
-
|
|
16925
|
-
const r = result;
|
|
16926
|
-
if (!r.ok) throw new Error(`evalScript failed: ${r.error}`);
|
|
16927
|
-
if (r.value !== void 0) {
|
|
16928
|
-
console.log(`[flow] evalScript ->`, r.value);
|
|
17114
|
+
// maestro evalScript: run JS in the flow's shared HOST-side context (the
|
|
17115
|
+
// same engine that owns `output` and env vars) — never in the app page.
|
|
17116
|
+
// the canonical maestro form is `evalScript: ${output.x = 1}`, which is
|
|
17117
|
+
// pure template evaluation. a script with no `${}` at all would be a
|
|
17118
|
+
// silent no-op upstream; we charitably evaluate it as raw JS in the same
|
|
17119
|
+
// context so plain-JS evalScript blocks fail or work loudly.
|
|
17120
|
+
evalScript(code) {
|
|
17121
|
+
const hasTemplate = /(?<!\\)\$\{[^$]*\}/.test(code);
|
|
17122
|
+
const result = hasTemplate ? this.js.evaluateStringTemplate(code) : this.js.evaluate(code);
|
|
17123
|
+
if (result !== void 0 && result !== "") {
|
|
17124
|
+
console.log(`[flow] evalScript ->`, result);
|
|
16929
17125
|
}
|
|
16930
17126
|
}
|
|
16931
|
-
// maestro
|
|
16932
|
-
//
|
|
16933
|
-
//
|
|
17127
|
+
// maestro runScript: execute a JS file in the shared flow context. env
|
|
17128
|
+
// vars are scoped to the script (upstream runInSubScope=true). paths
|
|
17129
|
+
// resolve relative to the flow file, like runFlow.
|
|
17130
|
+
runScript(target) {
|
|
17131
|
+
const spec = typeof target === "string" ? { file: target } : target;
|
|
17132
|
+
if (!spec.file) throw new Error("runScript requires a file");
|
|
17133
|
+
const scriptPath = path7.resolve(this.opts.flowDir, spec.file);
|
|
17134
|
+
const source = fs7.readFileSync(scriptPath, "utf8");
|
|
17135
|
+
this.js.evaluate(source, { env: spec.env });
|
|
17136
|
+
console.log(`[flow] runScript: ${spec.file} done`);
|
|
17137
|
+
}
|
|
17138
|
+
// maestro openLink: on-device maestro asks the OS to open the link, and
|
|
17139
|
+
// iOS routes an app-claimed URL into the running app as a Linking 'url'
|
|
17140
|
+
// event. sootsim mirrors that: dispatch through the engine's Linking
|
|
17141
|
+
// emulation so react-navigation useLinking / addEventListener('url')
|
|
17142
|
+
// handlers fire exactly like on a real device. an app that doesn't
|
|
17143
|
+
// handle the link simply ignores it (same as iOS routing to Safari —
|
|
17144
|
+
// the app under test sees nothing).
|
|
16934
17145
|
async openLink(target) {
|
|
16935
17146
|
const link = typeof target === "string" ? target : target.link;
|
|
16936
17147
|
if (!link) throw new Error("openLink: missing link");
|
|
16937
|
-
|
|
17148
|
+
const result = await this.callTest(
|
|
17149
|
+
"openDeepLink",
|
|
17150
|
+
link
|
|
17151
|
+
);
|
|
17152
|
+
if (!result?.ok) {
|
|
17153
|
+
throw new Error(`openLink failed: ${result?.error || "no test bridge"}`);
|
|
17154
|
+
}
|
|
16938
17155
|
await sleep(300);
|
|
16939
|
-
await this.refreshSimId();
|
|
16940
|
-
await this.waitForTree(3e4);
|
|
16941
17156
|
}
|
|
16942
17157
|
// evaluate a `when:` predicate. returns true if the step should run.
|
|
16943
17158
|
async evaluateWhen(when) {
|
|
@@ -16952,10 +17167,10 @@ var init_bridge_flow_runner = __esm({
|
|
|
16952
17167
|
return !el;
|
|
16953
17168
|
}
|
|
16954
17169
|
if (when.platform !== void 0) {
|
|
16955
|
-
return when.platform.toLowerCase() ===
|
|
17170
|
+
return when.platform.toLowerCase() === this.js.maestro.platform.toLowerCase();
|
|
16956
17171
|
}
|
|
16957
17172
|
if (when.true !== void 0) {
|
|
16958
|
-
return when.true
|
|
17173
|
+
return scriptConditionIsTruthy(when.true);
|
|
16959
17174
|
}
|
|
16960
17175
|
return true;
|
|
16961
17176
|
}
|
|
@@ -16966,9 +17181,26 @@ var init_bridge_flow_runner = __esm({
|
|
|
16966
17181
|
const value = entry ? entry[1] : void 0;
|
|
16967
17182
|
return !!(value && typeof value === "object" && "optional" in value && value.optional);
|
|
16968
17183
|
}
|
|
16969
|
-
async runStep(
|
|
16970
|
-
const stepName = Object.keys(
|
|
17184
|
+
async runStep(rawStep, stepIndex) {
|
|
17185
|
+
const stepName = Object.keys(rawStep).find((k) => k !== "when") || Object.keys(rawStep)[0];
|
|
16971
17186
|
console.log(`[flow] step ${stepIndex + 1}: ${stepName}`);
|
|
17187
|
+
let step;
|
|
17188
|
+
try {
|
|
17189
|
+
step = this.js.interpolateStep(rawStep);
|
|
17190
|
+
} catch (error) {
|
|
17191
|
+
if (this.isOptional(rawStep)) {
|
|
17192
|
+
console.log(
|
|
17193
|
+
`[flow] (optional, skipped: ${error.message.slice(0, 80)})`
|
|
17194
|
+
);
|
|
17195
|
+
return;
|
|
17196
|
+
}
|
|
17197
|
+
this.lastFailedStep = {
|
|
17198
|
+
index: stepIndex,
|
|
17199
|
+
kind: stepName,
|
|
17200
|
+
target: rawStep[stepName]
|
|
17201
|
+
};
|
|
17202
|
+
throw error;
|
|
17203
|
+
}
|
|
16972
17204
|
if (step.when) {
|
|
16973
17205
|
const shouldRun = await this.evaluateWhen(step.when);
|
|
16974
17206
|
if (!shouldRun) {
|
|
@@ -16977,7 +17209,9 @@ var init_bridge_flow_runner = __esm({
|
|
|
16977
17209
|
}
|
|
16978
17210
|
}
|
|
16979
17211
|
try {
|
|
16980
|
-
const hasExplicitWait = !!(step.extendedWaitUntil || step.waitFor || step.scrollUntilVisible || step.launchApp || step.runFlow
|
|
17212
|
+
const hasExplicitWait = !!(step.extendedWaitUntil || step.waitFor || step.scrollUntilVisible || step.launchApp || step.runFlow || // runScript http calls are synchronous with a 5-minute upstream
|
|
17213
|
+
// timeout — the 10s watchdog would kill legitimate setup scripts.
|
|
17214
|
+
step.runScript);
|
|
16981
17215
|
const STEP_WATCHDOG_MS = 1e4;
|
|
16982
17216
|
const body = this.runStepInner(step);
|
|
16983
17217
|
if (hasExplicitWait) {
|
|
@@ -17073,7 +17307,11 @@ var init_bridge_flow_runner = __esm({
|
|
|
17073
17307
|
} else if (typeof step.eraseText === "number") {
|
|
17074
17308
|
await this.eraseText(step.eraseText);
|
|
17075
17309
|
} else if (step.repeat) {
|
|
17076
|
-
|
|
17310
|
+
const times = Number(step.repeat.times);
|
|
17311
|
+
if (!Number.isFinite(times)) {
|
|
17312
|
+
throw new Error(`repeat.times is not a number: ${step.repeat.times}`);
|
|
17313
|
+
}
|
|
17314
|
+
for (let i = 0; i < times; i++) {
|
|
17077
17315
|
for (let j = 0; j < step.repeat.commands.length; j++) {
|
|
17078
17316
|
await this.runStep(step.repeat.commands[j], j);
|
|
17079
17317
|
}
|
|
@@ -17087,26 +17325,59 @@ var init_bridge_flow_runner = __esm({
|
|
|
17087
17325
|
} else if (step.copyTextFrom !== void 0) {
|
|
17088
17326
|
await this.copyTextFrom(step.copyTextFrom);
|
|
17089
17327
|
} else if (typeof step.evalScript === "string") {
|
|
17090
|
-
|
|
17328
|
+
this.evalScript(step.evalScript);
|
|
17329
|
+
} else if (step.runScript) {
|
|
17330
|
+
const rs = step.runScript;
|
|
17331
|
+
const innerWhen = typeof rs === "string" ? void 0 : rs.when;
|
|
17332
|
+
if (innerWhen && !await this.evaluateWhen(innerWhen)) {
|
|
17333
|
+
console.log(`[flow] runScript skipped (when predicate false)`);
|
|
17334
|
+
return;
|
|
17335
|
+
}
|
|
17336
|
+
this.runScript(rs);
|
|
17091
17337
|
} else if (step.openLink !== void 0) {
|
|
17092
17338
|
await this.openLink(step.openLink);
|
|
17093
17339
|
} else if (step.runFlow) {
|
|
17094
17340
|
const rf = step.runFlow;
|
|
17095
17341
|
const file = typeof rf === "string" ? rf : rf.file;
|
|
17342
|
+
const commands = typeof rf === "string" ? void 0 : rf.commands;
|
|
17343
|
+
const env = typeof rf === "string" ? void 0 : rf.env;
|
|
17096
17344
|
const innerWhen = typeof rf === "string" ? void 0 : rf.when;
|
|
17097
17345
|
if (innerWhen) {
|
|
17098
17346
|
const shouldRun = await this.evaluateWhen(innerWhen);
|
|
17099
17347
|
if (!shouldRun) {
|
|
17100
|
-
console.log(
|
|
17348
|
+
console.log(
|
|
17349
|
+
`[flow] runFlow skipped (when predicate false): ${file ?? "inline commands"}`
|
|
17350
|
+
);
|
|
17101
17351
|
return;
|
|
17102
17352
|
}
|
|
17103
17353
|
}
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
|
|
17107
|
-
this.
|
|
17108
|
-
|
|
17109
|
-
|
|
17354
|
+
if (!file && !commands) {
|
|
17355
|
+
throw new Error("runFlow requires either file or commands");
|
|
17356
|
+
}
|
|
17357
|
+
this.js.enterEnvScope();
|
|
17358
|
+
try {
|
|
17359
|
+
if (env) {
|
|
17360
|
+
for (const [k, v] of Object.entries(env)) this.js.putEnv(k, v);
|
|
17361
|
+
}
|
|
17362
|
+
if (file) {
|
|
17363
|
+
const flowPath = path7.resolve(this.opts.flowDir, file);
|
|
17364
|
+
const flowContent = fs7.readFileSync(flowPath, "utf8");
|
|
17365
|
+
const previousDir = this.opts.flowDir;
|
|
17366
|
+
this.opts.flowDir = path7.dirname(flowPath);
|
|
17367
|
+
try {
|
|
17368
|
+
await this.runFlow(parseFlowSteps(flowContent));
|
|
17369
|
+
} finally {
|
|
17370
|
+
;
|
|
17371
|
+
this.opts.flowDir = previousDir;
|
|
17372
|
+
}
|
|
17373
|
+
} else if (commands) {
|
|
17374
|
+
for (let i = 0; i < commands.length; i++) {
|
|
17375
|
+
await this.runStep(commands[i], i);
|
|
17376
|
+
}
|
|
17377
|
+
}
|
|
17378
|
+
} finally {
|
|
17379
|
+
this.js.leaveEnvScope();
|
|
17380
|
+
}
|
|
17110
17381
|
} else {
|
|
17111
17382
|
throw new Error(`unsupported flow step: ${JSON.stringify(step)}`);
|
|
17112
17383
|
}
|
|
@@ -17489,7 +17760,7 @@ var skill5 = {
|
|
|
17489
17760
|
async execute(params, context) {
|
|
17490
17761
|
const fs9 = await import("fs");
|
|
17491
17762
|
const path9 = await import("path");
|
|
17492
|
-
const
|
|
17763
|
+
const yaml2 = await import("yaml");
|
|
17493
17764
|
const { DEFAULT_SOOTSIM_BRIDGE_PORT: DEFAULT_SOOTSIM_BRIDGE_PORT2 } = await Promise.resolve().then(() => (init_bridge_constants(), bridge_constants_exports));
|
|
17494
17765
|
const { SootSimBridgeHost: SootSimBridgeHost2 } = await Promise.resolve().then(() => (init_bridge_host(), bridge_host_exports));
|
|
17495
17766
|
const { createBridge: createBridge2 } = await Promise.resolve().then(() => (init_ws_bridge(), ws_bridge_exports));
|
|
@@ -17500,7 +17771,7 @@ var skill5 = {
|
|
|
17500
17771
|
const flowContent = fs9.readFileSync(params.flowPath, "utf8");
|
|
17501
17772
|
const fmMatch = flowContent.match(/^---\n([\s\S]*?)\n---\n?/);
|
|
17502
17773
|
const stepsBody = fmMatch ? flowContent.slice(fmMatch[0].length) : flowContent;
|
|
17503
|
-
const steps =
|
|
17774
|
+
const steps = yaml2.parse(stepsBody);
|
|
17504
17775
|
const beforeIds = new Set(host.listSims().map((sim) => sim.id));
|
|
17505
17776
|
await host.openUrl(context.url);
|
|
17506
17777
|
let simId = null;
|
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.141 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/package.json
CHANGED
package/src/config.ts
CHANGED
|
@@ -20,6 +20,15 @@ export interface SootSimConfig<
|
|
|
20
20
|
turboModules?: Record<string, NativeModuleResolution>
|
|
21
21
|
nativeModules?: Record<string, NativeModuleResolution>
|
|
22
22
|
env?: Record<string, string>
|
|
23
|
+
// generic per-sim network rewrites for the guest app's runtime fetches.
|
|
24
|
+
// `remap` keys/values are `host:port` (or bare `host`) — a tenant fetch whose
|
|
25
|
+
// url matches a key has its host:port swapped for the value before the
|
|
26
|
+
// request is issued. exists for third-party e2e suites that hardcode a port
|
|
27
|
+
// (e.g. bluesky's flows type `http://localhost:3000`) which collides with a
|
|
28
|
+
// host service; map it to the real bound port without editing the app.
|
|
29
|
+
network?: {
|
|
30
|
+
remap?: Record<string, string>
|
|
31
|
+
}
|
|
23
32
|
settings?: Partial<Settings>
|
|
24
33
|
initialState?: {
|
|
25
34
|
authenticated?: boolean
|
|
@@ -51,6 +60,7 @@ export function hasSootSimConfig<
|
|
|
51
60
|
hasOwnKeys(config.turboModules as Record<string, unknown> | undefined) ||
|
|
52
61
|
hasOwnKeys(config.nativeModules as Record<string, unknown> | undefined) ||
|
|
53
62
|
hasOwnKeys(config.env as Record<string, unknown> | undefined) ||
|
|
63
|
+
hasOwnKeys(config.network?.remap as Record<string, unknown> | undefined) ||
|
|
54
64
|
hasOwnKeys(config.settings as Record<string, unknown> | undefined) ||
|
|
55
65
|
hasOwnKeys(config.initialState as Record<string, unknown> | undefined)
|
|
56
66
|
)
|
|
@@ -74,6 +84,9 @@ export function mergeSootSimConfig<
|
|
|
74
84
|
...(override.nativeModules || {}),
|
|
75
85
|
},
|
|
76
86
|
env: { ...(base.env || {}), ...(override.env || {}) },
|
|
87
|
+
network: {
|
|
88
|
+
remap: { ...(base.network?.remap || {}), ...(override.network?.remap || {}) },
|
|
89
|
+
},
|
|
77
90
|
settings: {
|
|
78
91
|
...(base.settings || {}),
|
|
79
92
|
...(override.settings || {}),
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.140 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import{a,b,c,d}from"./chunk-R5F7XGAO.js";import"./chunk-AOICEZCA.js";import"./chunk-RAY2DLSK.js";import"./chunk-QOZ2Q4FH.js";import"./chunk-GL74P6NR.js";import"./chunk-O2SQNUDP.js";export{c as ensureDaemonRunning,a as ensureRuntimeInstalled,d as ensureSootsimReady,b as resolveBootstrapPort};
|