sootsim 0.1.294 → 0.1.296
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -4
- package/dist-cli/bin.js +5 -5
- package/dist-cli/chunks/{agent-GDFF6G7N.js → agent-3F4K6MQK.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-ZUKQUOD2.js → agent-wrapper-5LLVCQRZ.js} +2 -2
- package/dist-cli/chunks/app-fonts-LPTY7A5G.js +4 -0
- package/dist-cli/chunks/{assert-GXOGZUKO.js → assert-R2ZUXEMS.js} +2 -2
- package/dist-cli/chunks/{auth-P7FAKLHQ.js → auth-CA62Q6IS.js} +2 -2
- package/dist-cli/chunks/{beta-RXT5RU3A.js → beta-4AXSOQLU.js} +2 -2
- package/dist-cli/chunks/{camera-RNVAC4IO.js → camera-Y4RBIONE.js} +2 -2
- package/dist-cli/chunks/{chunk-OYYQQBKP.js → chunk-222Y7NQA.js} +1 -1
- package/dist-cli/chunks/chunk-2LQOLMRK.js +4 -0
- package/dist-cli/chunks/{chunk-AFLGWOX3.js → chunk-2XUKWIAL.js} +1 -1
- package/dist-cli/chunks/{chunk-DI55E6CS.js → chunk-3PAZJSIG.js} +2 -2
- package/dist-cli/chunks/{chunk-2M7OZ6Y4.js → chunk-4MDLYOEI.js} +2 -2
- package/dist-cli/chunks/{chunk-EXTV6NWM.js → chunk-4NFGOGB7.js} +2 -2
- package/dist-cli/chunks/chunk-54TQ3ZGI.js +30 -0
- package/dist-cli/chunks/chunk-5FNPAMP4.js +125 -0
- package/dist-cli/chunks/{chunk-4Z4URZOG.js → chunk-6C24WCDK.js} +2 -2
- package/dist-cli/chunks/{chunk-KWIURH7N.js → chunk-74FOMZP7.js} +2 -2
- package/dist-cli/chunks/{chunk-JUOQ4ZPA.js → chunk-7GQWF7HE.js} +1 -1
- package/dist-cli/chunks/{chunk-BXO2PTNM.js → chunk-7V3JNANH.js} +4 -4
- package/dist-cli/chunks/{chunk-DUHBRW7J.js → chunk-7YQXQSG7.js} +1 -1
- package/dist-cli/chunks/{chunk-FSRRJGYC.js → chunk-AUBP44CY.js} +2 -2
- package/dist-cli/chunks/chunk-B2FB6IYX.js +4 -0
- package/dist-cli/chunks/{chunk-FNCSUHUR.js → chunk-B2LDO55K.js} +1 -1
- package/dist-cli/chunks/{chunk-K53YCAQM.js → chunk-BVWIR4CD.js} +1 -1
- package/dist-cli/chunks/{chunk-RWUNC66S.js → chunk-C462URRQ.js} +2 -2
- package/dist-cli/chunks/chunk-CAAADPRH.js +10 -0
- package/dist-cli/chunks/{chunk-VXGCZUX4.js → chunk-CDCVWGNU.js} +3 -3
- package/dist-cli/chunks/{chunk-WYRLRNIP.js → chunk-CS23DQB2.js} +2 -2
- package/dist-cli/chunks/chunk-DUYKBCM7.js +4 -0
- package/dist-cli/chunks/chunk-EISE56VD.js +6 -0
- package/dist-cli/chunks/{chunk-VVVORIQI.js → chunk-EJ6BAJKX.js} +1 -1
- package/dist-cli/chunks/chunk-F2MS365Z.js +4 -0
- package/dist-cli/chunks/{chunk-AMKQUZA2.js → chunk-FROCFR77.js} +1 -1
- package/dist-cli/chunks/{chunk-I233T2T4.js → chunk-FUPQIX4U.js} +2 -2
- package/dist-cli/chunks/{chunk-V2MYTL4C.js → chunk-G2SO5FPN.js} +2 -2
- package/dist-cli/chunks/chunk-GG5PWLGC.js +4 -0
- package/dist-cli/chunks/chunk-GG6XOQ5P.js +15 -0
- package/dist-cli/chunks/chunk-HSGS2U7P.js +6 -0
- package/dist-cli/chunks/{chunk-PZTKQG6H.js → chunk-IR3DUBRF.js} +5 -5
- package/dist-cli/chunks/chunk-LHUY46GE.js +4 -0
- package/dist-cli/chunks/{chunk-N4MT5KEB.js → chunk-MDBR4XTV.js} +3 -3
- package/dist-cli/chunks/{chunk-SLMUW2WU.js → chunk-MQ6QX46T.js} +2 -2
- package/dist-cli/chunks/chunk-N3FZRJT7.js +4 -0
- package/dist-cli/chunks/{chunk-ISJ4ACWL.js → chunk-NEARYPSC.js} +11 -11
- package/dist-cli/chunks/chunk-P7HBJBHH.js +4 -0
- package/dist-cli/chunks/{chunk-24BJFJFB.js → chunk-PEUWZRXA.js} +5 -5
- package/dist-cli/chunks/{chunk-PSOUSJSZ.js → chunk-QIDFGREY.js} +1 -1
- package/dist-cli/chunks/{chunk-ZUX5PIGI.js → chunk-R65XMN4D.js} +1 -1
- package/dist-cli/chunks/{chunk-AO65WEF7.js → chunk-S5Z4HKWX.js} +1 -1
- package/dist-cli/chunks/chunk-SUJSGGSS.js +23 -0
- package/dist-cli/chunks/{chunk-O6I5ZGMY.js → chunk-TIOPG6QZ.js} +1 -1
- package/dist-cli/chunks/chunk-WJVBD2UL.js +9 -0
- package/dist-cli/chunks/{chunk-D2R7PDN5.js → chunk-X7B5KJ6N.js} +1 -1
- package/dist-cli/chunks/{chunk-7HVMAGDK.js → chunk-XMVVZCIM.js} +2 -2
- package/dist-cli/chunks/chunk-ZIBKGZJD.js +4 -0
- package/dist-cli/chunks/chunk-ZPBIHFQW.js +12 -0
- package/dist-cli/chunks/cleanup-4RSKYPQ7.js +25 -0
- package/dist-cli/chunks/{cli-version-2JGMYL4O.js → cli-version-VZFF7GGM.js} +2 -2
- package/dist-cli/chunks/compat-FABLN4UI.js +20 -0
- package/dist-cli/chunks/config-74J37LKC.js +13 -0
- package/dist-cli/chunks/control-VBK32Y7F.js +4 -0
- package/dist-cli/chunks/daemon-VFO7LRR4.js +4 -0
- package/dist-cli/chunks/{debug-XUGWZLIW.js → debug-AOYA2CLR.js} +3 -3
- package/dist-cli/chunks/{desktop-IO5HPX5Z.js → desktop-G7XWDCTM.js} +3 -3
- package/dist-cli/chunks/{detox-E42OEJJZ.js → detox-QXJ3L2ZI.js} +2 -2
- package/dist-cli/chunks/{device-XA67L2EB.js → device-NZZ5ZT3Q.js} +2 -2
- package/dist-cli/chunks/{diagnose-36FD6ECF.js → diagnose-5CAEJ42M.js} +2 -2
- package/dist-cli/chunks/disk-cleanup-GZSUZJ6Y.js +4 -0
- package/dist-cli/chunks/drivers-OLJCUSPO.js +4 -0
- package/dist-cli/chunks/{film-XARTGFIZ.js → film-C25VRUNC.js} +3 -3
- package/dist-cli/chunks/flow-IW3WUF5D.js +4 -0
- package/dist-cli/chunks/help-GEVJF2DA.js +4 -0
- package/dist-cli/chunks/{hidden-runtime-alias-T4ZALBE2.js → hidden-runtime-alias-NSLIK6XT.js} +2 -2
- package/dist-cli/chunks/home-paths-OC6JZXIM.js +4 -0
- package/dist-cli/chunks/inspect-KXJNI7CU.js +4 -0
- package/dist-cli/chunks/install-desktop-IYWPRFPB.js +4 -0
- package/dist-cli/chunks/{login-GF6WVVER.js → login-LB4TMM4T.js} +4 -4
- package/dist-cli/chunks/{logout-6F6UKUNI.js → logout-33IOBD4X.js} +2 -2
- package/dist-cli/chunks/{maestro-FMPKHEMX.js → maestro-EEVXX536.js} +3 -3
- package/dist-cli/chunks/{maestro-generate-QGPGNXI6.js → maestro-generate-ICPWVXGA.js} +3 -3
- package/dist-cli/chunks/{mode-JSNMAHDZ.js → mode-6IXOZDK3.js} +2 -2
- package/dist-cli/chunks/{optional-demo-registry-K4VERLJV.js → optional-demo-registry-KBMC7SNI.js} +2 -2
- package/dist-cli/chunks/{perf-PO7ARUTG.js → perf-CTTJSAIJ.js} +2 -2
- package/dist-cli/chunks/{permissions-XI2QUAEZ.js → permissions-BFQS4DIY.js} +2 -2
- package/dist-cli/chunks/{record-4CJCJAFD.js → record-MJR5ELHE.js} +3 -3
- package/dist-cli/chunks/report-issue-FMJRNDKH.js +29 -0
- package/dist-cli/chunks/runtime-PV4HH2OB.js +4 -0
- package/dist-cli/chunks/{screenshot-command-NDVULWMZ.js → screenshot-command-MGNASAXR.js} +3 -3
- package/dist-cli/chunks/{screenshots-capture-Q7UTXF3V.js → screenshots-capture-N6PANAVT.js} +2 -2
- package/dist-cli/chunks/serve-RS6TIO7U.js +44 -0
- package/dist-cli/chunks/setup-MFYGYR2F.js +32 -0
- package/dist-cli/chunks/{skills-NFG6VAO5.js → skills-TD35LDKK.js} +2 -2
- package/dist-cli/chunks/{storage-POWCOUCQ.js → storage-VCFXDJNO.js} +2 -2
- package/dist-cli/chunks/store-VNSTKYBQ.js +4 -0
- package/dist-cli/chunks/telemetry-GPNHSYFF.js +4 -0
- package/dist-cli/chunks/{timeline-MNHZCVAL.js → timeline-UJCZAWJV.js} +2 -2
- package/dist-cli/chunks/upgrade-S24NH4YG.js +7 -0
- package/dist-cli/chunks/upload-CCKAO2M5.js +4 -0
- package/dist-cli/chunks/version-IVPWT2ZQ.js +6 -0
- package/dist-cli/chunks/web-6BMWAWJL.js +4 -0
- package/dist-cli/chunks/{what-happened-H74HHGRK.js → what-happened-HRHB6ETL.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +2 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +4 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +3 -2
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +41 -14
- package/dist-lib/host/bridge-host.cjs +216 -84
- 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 +5 -2
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +2 -3
- package/dist-lib/menu.mjs +2 -3
- 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 +373 -159
- package/dist-lib/vite.cjs +3 -2
- package/package.json +2 -1
- package/scripts/postinstall.cjs +2 -78
- package/skills/contrast/SKILL.md +3 -2
- package/skills/sootsim-setup/SKILL.md +25 -0
- package/src/bridge-constants.ts +1 -0
- package/src/config.ts +4 -0
- package/src/disk-cleanup.ts +5 -26
- package/src/home-paths.ts +58 -23
- package/src/host/bridge-host.ts +152 -57
- package/src/index.ts +4 -1
- package/src/menu.ts +0 -1
- package/src/runtime-assets.ts +35 -0
- package/src/runtime-delivery.ts +5 -8
- package/src/skills/builtin/compat-check.ts +32 -65
- package/dist-cli/chunks/app-fonts-IMYBO6AQ.js +0 -4
- package/dist-cli/chunks/chunk-37ZXWXM3.js +0 -4
- package/dist-cli/chunks/chunk-3F2GAJ4Z.js +0 -6
- package/dist-cli/chunks/chunk-5S3GPTX7.js +0 -6
- package/dist-cli/chunks/chunk-6YN3IAWJ.js +0 -4
- package/dist-cli/chunks/chunk-7Q77LTPT.js +0 -15
- package/dist-cli/chunks/chunk-BBVBMGTT.js +0 -31
- package/dist-cli/chunks/chunk-CTMPC5DN.js +0 -6
- package/dist-cli/chunks/chunk-JFWEDISV.js +0 -120
- package/dist-cli/chunks/chunk-JGGXQHXH.js +0 -10
- package/dist-cli/chunks/chunk-OKSGM6IG.js +0 -4
- package/dist-cli/chunks/chunk-SPQKJDIK.js +0 -4
- package/dist-cli/chunks/chunk-W44PDEQH.js +0 -4
- package/dist-cli/chunks/chunk-WQL3BLFD.js +0 -9
- package/dist-cli/chunks/chunk-XYFP466E.js +0 -12
- package/dist-cli/chunks/chunk-ZFMJFX27.js +0 -4
- package/dist-cli/chunks/cleanup-74SKOD2P.js +0 -25
- package/dist-cli/chunks/compat-ME6HXEEU.js +0 -35
- package/dist-cli/chunks/config-PM67EWT3.js +0 -13
- package/dist-cli/chunks/control-HV7GZXAH.js +0 -4
- package/dist-cli/chunks/daemon-LKRHF5OK.js +0 -4
- package/dist-cli/chunks/disk-cleanup-DDCFGFWK.js +0 -4
- package/dist-cli/chunks/drivers-C2SH3DWS.js +0 -4
- package/dist-cli/chunks/flow-E64G5LF3.js +0 -4
- package/dist-cli/chunks/help-4ZSRG4F4.js +0 -4
- package/dist-cli/chunks/home-paths-5L7N2FLS.js +0 -4
- package/dist-cli/chunks/inspect-U2SV25ER.js +0 -4
- package/dist-cli/chunks/install-desktop-LTGVT7ID.js +0 -4
- package/dist-cli/chunks/runtime-SN2RWDES.js +0 -4
- package/dist-cli/chunks/serve-UEUIBHCK.js +0 -44
- package/dist-cli/chunks/setup-ZEEWYK4B.js +0 -99
- package/dist-cli/chunks/store-BJK7V7FL.js +0 -4
- package/dist-cli/chunks/telemetry-EJP5EW7K.js +0 -4
- package/dist-cli/chunks/upgrade-X57SIG7L.js +0 -6
- package/dist-cli/chunks/upload-JABM3ITZ.js +0 -4
- package/dist-cli/chunks/version-V4IKIDX7.js +0 -6
- package/dist-cli/chunks/web-F5CLF34I.js +0 -4
package/dist-lib/home-paths.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.296 | (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;
|
|
@@ -61,9 +61,10 @@ __export(home_paths_exports, {
|
|
|
61
61
|
readActiveRuntime: () => readActiveRuntime,
|
|
62
62
|
readDaemonLockfile: () => readDaemonLockfile,
|
|
63
63
|
readDevBridgeLockfile: () => readDevBridgeLockfile,
|
|
64
|
+
readLiveRuntimeVersions: () => readLiveRuntimeVersions,
|
|
64
65
|
readOrCreateAnonymousId: () => readOrCreateAnonymousId,
|
|
66
|
+
readPrivacyPreferences: () => readPrivacyPreferences,
|
|
65
67
|
readSharedConfig: () => readSharedConfig,
|
|
66
|
-
readTelemetryEnabled: () => readTelemetryEnabled,
|
|
67
68
|
removeDaemonLockfile: () => removeDaemonLockfile,
|
|
68
69
|
removeDevBridgeLockfile: () => removeDevBridgeLockfile,
|
|
69
70
|
runtimeDir: () => runtimeDir,
|
|
@@ -74,9 +75,9 @@ __export(home_paths_exports, {
|
|
|
74
75
|
writeActiveRuntime: () => writeActiveRuntime,
|
|
75
76
|
writeDaemonLockfile: () => writeDaemonLockfile,
|
|
76
77
|
writeDevBridgeLockfile: () => writeDevBridgeLockfile,
|
|
78
|
+
writePrivacyPreferences: () => writePrivacyPreferences,
|
|
77
79
|
writeRuntimeUpgradeNotice: () => writeRuntimeUpgradeNotice,
|
|
78
|
-
writeSharedConfig: () => writeSharedConfig
|
|
79
|
-
writeTelemetryEnabled: () => writeTelemetryEnabled
|
|
80
|
+
writeSharedConfig: () => writeSharedConfig
|
|
80
81
|
});
|
|
81
82
|
module.exports = __toCommonJS(home_paths_exports);
|
|
82
83
|
var import_node_crypto = require("node:crypto");
|
|
@@ -182,8 +183,23 @@ function writeSharedConfig(patch) {
|
|
|
182
183
|
import_node_fs.default.renameSync(tmp, configFilePath());
|
|
183
184
|
return next;
|
|
184
185
|
}
|
|
185
|
-
function
|
|
186
|
-
|
|
186
|
+
function readPrivacyPreferences() {
|
|
187
|
+
const settings = readSharedConfig().settings;
|
|
188
|
+
const productAnalytics = settings?.productAnalytics;
|
|
189
|
+
const crashReports = settings?.crashReports;
|
|
190
|
+
return {
|
|
191
|
+
productAnalytics: typeof productAnalytics === "boolean" ? productAnalytics : true,
|
|
192
|
+
crashReports: typeof crashReports === "boolean" ? crashReports : true,
|
|
193
|
+
configured: typeof productAnalytics === "boolean" && typeof crashReports === "boolean"
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function writePrivacyPreferences(preferences) {
|
|
197
|
+
writeSharedConfig({
|
|
198
|
+
settings: {
|
|
199
|
+
productAnalytics: preferences.productAnalytics,
|
|
200
|
+
crashReports: preferences.crashReports
|
|
201
|
+
}
|
|
202
|
+
});
|
|
187
203
|
}
|
|
188
204
|
function readOrCreateAnonymousId() {
|
|
189
205
|
const existing = readSharedConfig().anonymousId;
|
|
@@ -192,9 +208,6 @@ function readOrCreateAnonymousId() {
|
|
|
192
208
|
writeSharedConfig({ anonymousId: created });
|
|
193
209
|
return created;
|
|
194
210
|
}
|
|
195
|
-
function writeTelemetryEnabled(enabled) {
|
|
196
|
-
writeSharedConfig({ telemetry: enabled });
|
|
197
|
-
}
|
|
198
211
|
function runtimeUpgradeNoticePath() {
|
|
199
212
|
return import_node_path.default.join(sootsimHomeDir(), "runtime-upgraded.json");
|
|
200
213
|
}
|
|
@@ -259,7 +272,7 @@ function readDaemonLockfile() {
|
|
|
259
272
|
const bytesRead = import_node_fs.default.readSync(fd, buf, 0, DAEMON_LOCKFILE_MAX_BYTES, 0);
|
|
260
273
|
const raw = buf.subarray(0, bytesRead).toString("utf8");
|
|
261
274
|
const parsed = JSON.parse(raw);
|
|
262
|
-
if (parsed && parsed.schema === 1 && typeof parsed.pid === "number" && typeof parsed.bridgePort === "number" && typeof parsed.runtimePort === "number" && typeof parsed.startedAt === "number" && typeof parsed.heartbeatAt === "number") {
|
|
275
|
+
if (parsed && parsed.schema === 1 && typeof parsed.pid === "number" && typeof parsed.bridgePort === "number" && typeof parsed.runtimePort === "number" && typeof parsed.startedAt === "number" && typeof parsed.heartbeatAt === "number" && (parsed.servedRuntimes === void 0 || Array.isArray(parsed.servedRuntimes) && parsed.servedRuntimes.every((version) => typeof version === "string"))) {
|
|
263
276
|
return parsed;
|
|
264
277
|
}
|
|
265
278
|
return null;
|
|
@@ -278,7 +291,7 @@ function readDevBridgeLockfile() {
|
|
|
278
291
|
const bytesRead = import_node_fs.default.readSync(fd, buf, 0, DAEMON_LOCKFILE_MAX_BYTES, 0);
|
|
279
292
|
const raw = buf.subarray(0, bytesRead).toString("utf8");
|
|
280
293
|
const parsed = JSON.parse(raw);
|
|
281
|
-
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")) {
|
|
294
|
+
if (parsed && parsed.schema === 1 && parsed.source === "vite-dev" && typeof parsed.pid === "number" && typeof parsed.bridgePort === "number" && typeof parsed.runtimePort === "number" && typeof parsed.cwd === "string" && typeof parsed.startedAt === "number" && typeof parsed.heartbeatAt === "number" && (parsed.shellPort === void 0 || typeof parsed.shellPort === "number") && (parsed.servedRuntimes === void 0 || Array.isArray(parsed.servedRuntimes) && parsed.servedRuntimes.every((version) => typeof version === "string"))) {
|
|
282
295
|
return parsed;
|
|
283
296
|
}
|
|
284
297
|
return null;
|
|
@@ -309,6 +322,19 @@ function isDevBridgeLockfileFresh(lock, now = Date.now()) {
|
|
|
309
322
|
return false;
|
|
310
323
|
}
|
|
311
324
|
}
|
|
325
|
+
function readLiveRuntimeVersions() {
|
|
326
|
+
const versions = /* @__PURE__ */ new Set();
|
|
327
|
+
const daemon = readDaemonLockfile();
|
|
328
|
+
if (isDaemonLockfileFresh(daemon)) {
|
|
329
|
+
if (daemon.activeRuntime) versions.add(daemon.activeRuntime);
|
|
330
|
+
for (const version of daemon.servedRuntimes ?? []) versions.add(version);
|
|
331
|
+
}
|
|
332
|
+
const devBridge = readDevBridgeLockfile();
|
|
333
|
+
if (isDevBridgeLockfileFresh(devBridge)) {
|
|
334
|
+
for (const version of devBridge.servedRuntimes ?? []) versions.add(version);
|
|
335
|
+
}
|
|
336
|
+
return [...versions].sort();
|
|
337
|
+
}
|
|
312
338
|
function writeDaemonLockfile(data) {
|
|
313
339
|
ensureSootsimHome();
|
|
314
340
|
const tmp = `${daemonLockfilePath()}.tmp`;
|
|
@@ -375,9 +401,10 @@ function removeDevBridgeLockfile() {
|
|
|
375
401
|
readActiveRuntime,
|
|
376
402
|
readDaemonLockfile,
|
|
377
403
|
readDevBridgeLockfile,
|
|
404
|
+
readLiveRuntimeVersions,
|
|
378
405
|
readOrCreateAnonymousId,
|
|
406
|
+
readPrivacyPreferences,
|
|
379
407
|
readSharedConfig,
|
|
380
|
-
readTelemetryEnabled,
|
|
381
408
|
removeDaemonLockfile,
|
|
382
409
|
removeDevBridgeLockfile,
|
|
383
410
|
runtimeDir,
|
|
@@ -388,7 +415,7 @@ function removeDevBridgeLockfile() {
|
|
|
388
415
|
writeActiveRuntime,
|
|
389
416
|
writeDaemonLockfile,
|
|
390
417
|
writeDevBridgeLockfile,
|
|
418
|
+
writePrivacyPreferences,
|
|
391
419
|
writeRuntimeUpgradeNotice,
|
|
392
|
-
writeSharedConfig
|
|
393
|
-
writeTelemetryEnabled
|
|
420
|
+
writeSharedConfig
|
|
394
421
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.296 | (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;
|
|
@@ -99,7 +99,7 @@ function hasOwnKeys(value) {
|
|
|
99
99
|
}
|
|
100
100
|
function hasSootSimConfig(config) {
|
|
101
101
|
if (!config) return false;
|
|
102
|
-
return hasOwnKeys(config.modules) || hasOwnKeys(config.turboModules) || hasOwnKeys(config.nativeModules) || hasOwnKeys(config.env) || hasOwnKeys(config.network?.remap) || hasOwnKeys(config.settings) || hasOwnKeys(config.initialState);
|
|
102
|
+
return typeof config.runtimeVersion === "string" && config.runtimeVersion.length > 0 || hasOwnKeys(config.modules) || hasOwnKeys(config.turboModules) || hasOwnKeys(config.nativeModules) || hasOwnKeys(config.env) || hasOwnKeys(config.network?.remap) || hasOwnKeys(config.settings) || hasOwnKeys(config.initialState);
|
|
103
103
|
}
|
|
104
104
|
function applySootSimConfigToUrl(url, config) {
|
|
105
105
|
const parsed = new URL(url);
|
|
@@ -920,6 +920,7 @@ async function scanDevServers(opts = {}) {
|
|
|
920
920
|
|
|
921
921
|
// src/bridge-constants.ts
|
|
922
922
|
var DEFAULT_SOOTSIM_BRIDGE_PORT = 7668;
|
|
923
|
+
var DEFAULT_SOOTSIM_BRIDGE_URL = `http://localhost:${DEFAULT_SOOTSIM_BRIDGE_PORT}/`;
|
|
923
924
|
var SOOTSIM_BRIDGE_SIM_CLOSE_CODE = 4001;
|
|
924
925
|
var SOOTSIM_BRIDGE_SIM_CLOSE_REASON = "sootsim close";
|
|
925
926
|
|
|
@@ -1081,7 +1082,7 @@ function readDaemonLockfile() {
|
|
|
1081
1082
|
const bytesRead = import_node_fs2.default.readSync(fd, buf, 0, DAEMON_LOCKFILE_MAX_BYTES, 0);
|
|
1082
1083
|
const raw = buf.subarray(0, bytesRead).toString("utf8");
|
|
1083
1084
|
const parsed = JSON.parse(raw);
|
|
1084
|
-
if (parsed && parsed.schema === 1 && typeof parsed.pid === "number" && typeof parsed.bridgePort === "number" && typeof parsed.runtimePort === "number" && typeof parsed.startedAt === "number" && typeof parsed.heartbeatAt === "number") {
|
|
1085
|
+
if (parsed && parsed.schema === 1 && typeof parsed.pid === "number" && typeof parsed.bridgePort === "number" && typeof parsed.runtimePort === "number" && typeof parsed.startedAt === "number" && typeof parsed.heartbeatAt === "number" && (parsed.servedRuntimes === void 0 || Array.isArray(parsed.servedRuntimes) && parsed.servedRuntimes.every((version) => typeof version === "string"))) {
|
|
1085
1086
|
return parsed;
|
|
1086
1087
|
}
|
|
1087
1088
|
return null;
|
|
@@ -1142,35 +1143,12 @@ function removeDevBridgeLockfile() {
|
|
|
1142
1143
|
var import_fs = __toESM(require("fs"), 1);
|
|
1143
1144
|
var import_path = __toESM(require("path"), 1);
|
|
1144
1145
|
var import_url = require("url");
|
|
1145
|
-
var _monorepoRootCache;
|
|
1146
|
-
function findMonorepoRoot() {
|
|
1147
|
-
if (_monorepoRootCache !== void 0) return _monorepoRootCache;
|
|
1148
|
-
let dir = import_path.default.dirname((0, import_url.fileURLToPath)(__sootsim_import_meta_url));
|
|
1149
|
-
for (let i = 0; i < 12 && dir !== import_path.default.dirname(dir); i++) {
|
|
1150
|
-
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"))) {
|
|
1151
|
-
_monorepoRootCache = dir;
|
|
1152
|
-
return dir;
|
|
1153
|
-
}
|
|
1154
|
-
dir = import_path.default.dirname(dir);
|
|
1155
|
-
}
|
|
1156
|
-
_monorepoRootCache = null;
|
|
1157
|
-
return null;
|
|
1158
|
-
}
|
|
1159
|
-
function resolveDevCheckoutRuntimeRoot() {
|
|
1160
|
-
if (process.env.SOOTSIM_HOME && readActiveRuntime()) return null;
|
|
1161
|
-
const root = findMonorepoRoot();
|
|
1162
|
-
if (!root) return null;
|
|
1163
|
-
const devBuild = import_path.default.join(root, "public/sootsim");
|
|
1164
|
-
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"))) {
|
|
1165
|
-
return devBuild;
|
|
1166
|
-
}
|
|
1167
|
-
return null;
|
|
1168
|
-
}
|
|
1169
1146
|
|
|
1170
1147
|
// ../contrast-runtime-delivery/src/index.ts
|
|
1171
1148
|
var import_node_child_process = require("node:child_process");
|
|
1172
1149
|
var import_node_crypto = __toESM(require("node:crypto"), 1);
|
|
1173
1150
|
var import_node_fs4 = __toESM(require("node:fs"), 1);
|
|
1151
|
+
var import_node_os2 = __toESM(require("node:os"), 1);
|
|
1174
1152
|
var import_node_path4 = __toESM(require("node:path"), 1);
|
|
1175
1153
|
var import_node_stream = require("node:stream");
|
|
1176
1154
|
var import_promises2 = require("node:stream/promises");
|
|
@@ -1178,6 +1156,9 @@ var import_promises2 = require("node:stream/promises");
|
|
|
1178
1156
|
// ../contrast-runtime-delivery/src/product.ts
|
|
1179
1157
|
var import_node_fs3 = __toESM(require("node:fs"), 1);
|
|
1180
1158
|
var import_node_path3 = __toESM(require("node:path"), 1);
|
|
1159
|
+
function isValidRuntimeVersion(value) {
|
|
1160
|
+
return value.length <= 100 && /^[0-9A-Za-z][0-9A-Za-z._+-]*$/.test(value);
|
|
1161
|
+
}
|
|
1181
1162
|
function listInstalledRuntimes(product) {
|
|
1182
1163
|
try {
|
|
1183
1164
|
return import_node_fs3.default.readdirSync(product.runtimesDir(), { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort(compareSemver);
|
|
@@ -1233,6 +1214,7 @@ function createRuntimeDelivery(product) {
|
|
|
1233
1214
|
return input || process.env[product.env.channel] || config.runtimeChannel || "stable";
|
|
1234
1215
|
}
|
|
1235
1216
|
function resolvePin() {
|
|
1217
|
+
if (!product.env.pin) return null;
|
|
1236
1218
|
const env = process.env[product.env.pin];
|
|
1237
1219
|
if (env && env.trim()) return env.trim();
|
|
1238
1220
|
const config = readConfig();
|
|
@@ -1262,6 +1244,9 @@ function createRuntimeDelivery(product) {
|
|
|
1262
1244
|
`no version specified and channel '${channel}' has no latest entry in the manifest`
|
|
1263
1245
|
);
|
|
1264
1246
|
}
|
|
1247
|
+
if (!isValidRuntimeVersion(version)) {
|
|
1248
|
+
throw new Error(`invalid runtime version: ${version}`);
|
|
1249
|
+
}
|
|
1265
1250
|
const entry = manifest.versions[version];
|
|
1266
1251
|
if (!entry) {
|
|
1267
1252
|
throw new Error(
|
|
@@ -1277,10 +1262,11 @@ function createRuntimeDelivery(product) {
|
|
|
1277
1262
|
const { version, channel, entry } = resolveVersion(manifest, opts);
|
|
1278
1263
|
const destDir = product.runtimeDir(version);
|
|
1279
1264
|
const setActive = opts.setActive !== false;
|
|
1280
|
-
|
|
1265
|
+
const protectVersions = [version, ...opts.protectVersions ?? []];
|
|
1266
|
+
pruneLocalRetention({ protectVersions });
|
|
1281
1267
|
if (!opts.force && import_node_fs4.default.existsSync(import_node_path4.default.join(destDir, product.installedMarker))) {
|
|
1282
1268
|
if (setActive) product.writeActiveRuntime(version);
|
|
1283
|
-
pruneLocalRetention({ protectVersions
|
|
1269
|
+
pruneLocalRetention({ protectVersions });
|
|
1284
1270
|
return {
|
|
1285
1271
|
version,
|
|
1286
1272
|
channel,
|
|
@@ -1292,29 +1278,32 @@ function createRuntimeDelivery(product) {
|
|
|
1292
1278
|
};
|
|
1293
1279
|
}
|
|
1294
1280
|
const tarUrl = entry.tarball || tarballUrl(version, cdnOrigin);
|
|
1295
|
-
const
|
|
1296
|
-
|
|
1281
|
+
const downloadDir = import_node_fs4.default.mkdtempSync(
|
|
1282
|
+
import_node_path4.default.join(import_node_os2.default.tmpdir(), `${product.id}-runtime-download-`)
|
|
1283
|
+
);
|
|
1284
|
+
const runtimeArchivePath = import_node_path4.default.join(
|
|
1285
|
+
downloadDir,
|
|
1297
1286
|
runtimeTarballCacheName(product, version)
|
|
1298
1287
|
);
|
|
1299
|
-
process.stderr.write(`${product.id}: downloading runtime ${version}\u2026
|
|
1300
|
-
`);
|
|
1301
|
-
await downloadToFile(tarUrl, tarCachePath);
|
|
1302
|
-
process.stderr.write(`${product.id}: extracting runtime ${version}\u2026
|
|
1303
|
-
`);
|
|
1304
1288
|
const tmpDir = import_node_path4.default.join(
|
|
1305
1289
|
import_node_path4.default.dirname(destDir),
|
|
1306
1290
|
`.installing-${version}-${process.pid}`
|
|
1307
1291
|
);
|
|
1308
1292
|
import_node_fs4.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
1309
1293
|
try {
|
|
1310
|
-
|
|
1294
|
+
process.stderr.write(`${product.id}: downloading runtime ${version}\u2026
|
|
1295
|
+
`);
|
|
1296
|
+
await downloadToFile(tarUrl, runtimeArchivePath);
|
|
1297
|
+
process.stderr.write(`${product.id}: extracting runtime ${version}\u2026
|
|
1298
|
+
`);
|
|
1299
|
+
const actualSha = await sha256File(runtimeArchivePath);
|
|
1311
1300
|
if (actualSha !== entry.sha256) {
|
|
1312
1301
|
throw new Error(
|
|
1313
1302
|
`sha256 mismatch for runtime ${version}: expected ${entry.sha256}, actual ${actualSha}`
|
|
1314
1303
|
);
|
|
1315
1304
|
}
|
|
1316
1305
|
import_node_fs4.default.mkdirSync(tmpDir, { recursive: true });
|
|
1317
|
-
await extractTarball(
|
|
1306
|
+
await extractTarball(runtimeArchivePath, tmpDir);
|
|
1318
1307
|
if (!import_node_fs4.default.existsSync(import_node_path4.default.join(tmpDir, product.installedMarker))) {
|
|
1319
1308
|
throw new Error(
|
|
1320
1309
|
`extracted tarball for runtime ${version} is missing ${product.installedMarker}`
|
|
@@ -1326,10 +1315,10 @@ function createRuntimeDelivery(product) {
|
|
|
1326
1315
|
import_node_fs4.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
1327
1316
|
throw err;
|
|
1328
1317
|
} finally {
|
|
1329
|
-
import_node_fs4.default.rmSync(
|
|
1318
|
+
import_node_fs4.default.rmSync(downloadDir, { recursive: true, force: true });
|
|
1330
1319
|
}
|
|
1331
1320
|
if (setActive) product.writeActiveRuntime(version);
|
|
1332
|
-
pruneLocalRetention({ protectVersions
|
|
1321
|
+
pruneLocalRetention({ protectVersions });
|
|
1333
1322
|
return {
|
|
1334
1323
|
version,
|
|
1335
1324
|
channel,
|
|
@@ -1342,7 +1331,7 @@ function createRuntimeDelivery(product) {
|
|
|
1342
1331
|
}
|
|
1343
1332
|
async function updateToLatest(opts = {}) {
|
|
1344
1333
|
product.ensureHome();
|
|
1345
|
-
pruneLocalRetention();
|
|
1334
|
+
pruneLocalRetention({ protectVersions: opts.protectVersions });
|
|
1346
1335
|
const cdnOrigin = resolveCdnOrigin(opts.cdnOrigin);
|
|
1347
1336
|
const channel = resolveChannel(opts.channel);
|
|
1348
1337
|
const pin = resolvePin();
|
|
@@ -1364,7 +1353,8 @@ function createRuntimeDelivery(product) {
|
|
|
1364
1353
|
version: pin,
|
|
1365
1354
|
channel,
|
|
1366
1355
|
cdnOrigin,
|
|
1367
|
-
setActive: false
|
|
1356
|
+
setActive: false,
|
|
1357
|
+
protectVersions: opts.protectVersions
|
|
1368
1358
|
});
|
|
1369
1359
|
return {
|
|
1370
1360
|
checked: true,
|
|
@@ -1412,7 +1402,8 @@ function createRuntimeDelivery(product) {
|
|
|
1412
1402
|
version: latestVersion,
|
|
1413
1403
|
channel,
|
|
1414
1404
|
cdnOrigin,
|
|
1415
|
-
setActive: false
|
|
1405
|
+
setActive: false,
|
|
1406
|
+
protectVersions: opts.protectVersions
|
|
1416
1407
|
});
|
|
1417
1408
|
return {
|
|
1418
1409
|
checked: true,
|
|
@@ -1555,6 +1546,53 @@ function extractTarball(tarPath, destDir) {
|
|
|
1555
1546
|
});
|
|
1556
1547
|
}
|
|
1557
1548
|
|
|
1549
|
+
// src/runtime-assets.ts
|
|
1550
|
+
var _monorepoRootCache;
|
|
1551
|
+
function findMonorepoRoot() {
|
|
1552
|
+
if (_monorepoRootCache !== void 0) return _monorepoRootCache;
|
|
1553
|
+
let dir = import_path.default.dirname((0, import_url.fileURLToPath)(__sootsim_import_meta_url));
|
|
1554
|
+
for (let i = 0; i < 12 && dir !== import_path.default.dirname(dir); i++) {
|
|
1555
|
+
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"))) {
|
|
1556
|
+
_monorepoRootCache = dir;
|
|
1557
|
+
return dir;
|
|
1558
|
+
}
|
|
1559
|
+
dir = import_path.default.dirname(dir);
|
|
1560
|
+
}
|
|
1561
|
+
_monorepoRootCache = null;
|
|
1562
|
+
return null;
|
|
1563
|
+
}
|
|
1564
|
+
function resolveDevCheckoutRuntimeRoot() {
|
|
1565
|
+
if (process.env.SOOTSIM_HOME && readActiveRuntime()) return null;
|
|
1566
|
+
const root = findMonorepoRoot();
|
|
1567
|
+
if (!root) return null;
|
|
1568
|
+
const devBuild = import_path.default.join(root, "public/sootsim");
|
|
1569
|
+
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"))) {
|
|
1570
|
+
return devBuild;
|
|
1571
|
+
}
|
|
1572
|
+
return null;
|
|
1573
|
+
}
|
|
1574
|
+
function runtimeVersionFromHostname(hostname) {
|
|
1575
|
+
const suffix = ".runtime.localhost";
|
|
1576
|
+
if (!hostname.toLowerCase().endsWith(suffix)) return null;
|
|
1577
|
+
const labels = hostname.slice(0, -suffix.length).split(".");
|
|
1578
|
+
if (labels.length === 0 || labels.some((label) => !/^[0-9a-f]{1,60}$/i.test(label))) {
|
|
1579
|
+
return null;
|
|
1580
|
+
}
|
|
1581
|
+
const encoded = labels.join("");
|
|
1582
|
+
if (encoded.length % 2 !== 0) return null;
|
|
1583
|
+
try {
|
|
1584
|
+
const version = Buffer.from(encoded, "hex").toString("utf8");
|
|
1585
|
+
return isValidRuntimeVersion(version) ? version : null;
|
|
1586
|
+
} catch {
|
|
1587
|
+
return null;
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
function resolveInstalledRuntimeRoot(version) {
|
|
1591
|
+
const dir = runtimeDir(version);
|
|
1592
|
+
if (!import_fs.default.existsSync(import_path.default.join(dir, "index.html"))) return null;
|
|
1593
|
+
return dir;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1558
1596
|
// src/runtime-delivery.ts
|
|
1559
1597
|
var DEFAULT_RUNTIME_CDN_ORIGIN = "https://contrast.dev";
|
|
1560
1598
|
var SOOTSIM_RUNTIME_PRODUCT = {
|
|
@@ -1568,8 +1606,7 @@ var SOOTSIM_RUNTIME_PRODUCT = {
|
|
|
1568
1606
|
installedMarker: "index.html",
|
|
1569
1607
|
env: {
|
|
1570
1608
|
cdnOrigin: "SOOTSIM_CDN_ORIGIN",
|
|
1571
|
-
channel: "SOOTSIM_RUNTIME_CHANNEL"
|
|
1572
|
-
pin: "SOOTSIM_RUNTIME_VERSION"
|
|
1609
|
+
channel: "SOOTSIM_RUNTIME_CHANNEL"
|
|
1573
1610
|
},
|
|
1574
1611
|
ensureHome: ensureSootsimHome,
|
|
1575
1612
|
configFile: configFilePath,
|
|
@@ -3862,6 +3899,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
3862
3899
|
recentActions: []
|
|
3863
3900
|
};
|
|
3864
3901
|
this.sims.set(sim.id, sim);
|
|
3902
|
+
this.writeConnectedRuntimeSnapshot();
|
|
3865
3903
|
if (this.shouldPromoteSim(sim)) {
|
|
3866
3904
|
this.primarySimId = sim.id;
|
|
3867
3905
|
}
|
|
@@ -3953,6 +3991,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
3953
3991
|
sim = null;
|
|
3954
3992
|
role = "cli";
|
|
3955
3993
|
this.cliIdentityKeyBySocket.set(ws, `ws-${this.nextCliFallbackId++}`);
|
|
3994
|
+
this.writeConnectedRuntimeSnapshot();
|
|
3956
3995
|
this.broadcastSimAssignments();
|
|
3957
3996
|
this.broadcastSimClientStates();
|
|
3958
3997
|
}
|
|
@@ -3966,6 +4005,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
3966
4005
|
sim.url = registration.url;
|
|
3967
4006
|
sim.title = registration.title;
|
|
3968
4007
|
sim.userAgent = registration.userAgent;
|
|
4008
|
+
this.writeConnectedRuntimeSnapshot();
|
|
3969
4009
|
if (typeof registration.kind === "string" && registration.kind.trim()) {
|
|
3970
4010
|
sim.kind = registration.kind.trim();
|
|
3971
4011
|
}
|
|
@@ -3990,11 +4030,14 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
3990
4030
|
return;
|
|
3991
4031
|
}
|
|
3992
4032
|
if (msg.type === "bridge:write-shared-config") {
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
4033
|
+
if (!msg.patch || typeof msg.patch !== "object" || Array.isArray(msg.patch)) {
|
|
4034
|
+
return;
|
|
4035
|
+
}
|
|
4036
|
+
const patch = Object.fromEntries(
|
|
4037
|
+
Object.entries(msg.patch)
|
|
4038
|
+
);
|
|
3996
4039
|
try {
|
|
3997
|
-
|
|
4040
|
+
this.writeAndBroadcastSharedConfig(patch);
|
|
3998
4041
|
} catch (err) {
|
|
3999
4042
|
process.stderr.write(
|
|
4000
4043
|
`sootsim: bridge:write-shared-config failed: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -4002,17 +4045,6 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
4002
4045
|
);
|
|
4003
4046
|
return;
|
|
4004
4047
|
}
|
|
4005
|
-
const payload = JSON.stringify({
|
|
4006
|
-
type: "bridge:shared-config-changed",
|
|
4007
|
-
config: next
|
|
4008
|
-
});
|
|
4009
|
-
for (const peer of this.sims.values()) {
|
|
4010
|
-
if (peer.ws.readyState !== import_ws2.WebSocket.OPEN) continue;
|
|
4011
|
-
try {
|
|
4012
|
-
peer.ws.send(payload);
|
|
4013
|
-
} catch {
|
|
4014
|
-
}
|
|
4015
|
-
}
|
|
4016
4048
|
return;
|
|
4017
4049
|
}
|
|
4018
4050
|
if (msg.type === "bridge:open-path") {
|
|
@@ -4327,6 +4359,18 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
4327
4359
|
void this.agentHost.seedOnBoot();
|
|
4328
4360
|
}
|
|
4329
4361
|
bootstrapping = true;
|
|
4362
|
+
connectedRuntimeVersions() {
|
|
4363
|
+
const versions = /* @__PURE__ */ new Set();
|
|
4364
|
+
for (const sim of this.sims.values()) {
|
|
4365
|
+
try {
|
|
4366
|
+
const url = new URL(sim.url || sim.origin || "http://localhost");
|
|
4367
|
+
const version = runtimeVersionFromHostname(url.hostname);
|
|
4368
|
+
if (version) versions.add(version);
|
|
4369
|
+
} catch {
|
|
4370
|
+
}
|
|
4371
|
+
}
|
|
4372
|
+
return [...versions].sort();
|
|
4373
|
+
}
|
|
4330
4374
|
buildLockfileSnapshot() {
|
|
4331
4375
|
return {
|
|
4332
4376
|
schema: 1,
|
|
@@ -4336,6 +4380,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
4336
4380
|
runtimePort: this.effectivePort,
|
|
4337
4381
|
activeRuntime: this.activeRuntimeVersion,
|
|
4338
4382
|
activeRuntimeDir: this.activeRuntimeDirPath,
|
|
4383
|
+
servedRuntimes: this.connectedRuntimeVersions(),
|
|
4339
4384
|
startedAt: this.startedAt,
|
|
4340
4385
|
heartbeatAt: Date.now(),
|
|
4341
4386
|
bootstrapping: this.bootstrapping
|
|
@@ -4353,7 +4398,8 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
4353
4398
|
cwd: process.cwd(),
|
|
4354
4399
|
startedAt: this.startedAt,
|
|
4355
4400
|
heartbeatAt: Date.now(),
|
|
4356
|
-
source: "vite-dev"
|
|
4401
|
+
source: "vite-dev",
|
|
4402
|
+
servedRuntimes: this.connectedRuntimeVersions()
|
|
4357
4403
|
};
|
|
4358
4404
|
}
|
|
4359
4405
|
writeLockfileSnapshot() {
|
|
@@ -4362,6 +4408,20 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
4362
4408
|
writeDevLockfileSnapshot() {
|
|
4363
4409
|
writeDevBridgeLockfile(this.buildDevLockfileSnapshot());
|
|
4364
4410
|
}
|
|
4411
|
+
writeConnectedRuntimeSnapshot() {
|
|
4412
|
+
if (this.shouldWriteLockfile && this.httpServer) {
|
|
4413
|
+
try {
|
|
4414
|
+
this.writeLockfileSnapshot();
|
|
4415
|
+
} catch {
|
|
4416
|
+
}
|
|
4417
|
+
}
|
|
4418
|
+
if (this.shouldWriteDevLockfile && this.httpServer) {
|
|
4419
|
+
try {
|
|
4420
|
+
this.writeDevLockfileSnapshot();
|
|
4421
|
+
} catch {
|
|
4422
|
+
}
|
|
4423
|
+
}
|
|
4424
|
+
}
|
|
4365
4425
|
refreshActiveRuntime() {
|
|
4366
4426
|
this.activeRuntimeVersion = readActiveRuntime();
|
|
4367
4427
|
this.activeRuntimeDirPath = resolveDevCheckoutRuntimeRoot() ?? activeRuntimeDir();
|
|
@@ -4413,6 +4473,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
4413
4473
|
}
|
|
4414
4474
|
startRuntimeUpdater() {
|
|
4415
4475
|
if (!this.shouldWriteLockfile || this.runtimeUpdateTimer) return;
|
|
4476
|
+
if (import_fs3.default.existsSync(import_path3.default.join(sootsimHomeDir(), "runtime-update-disabled"))) return;
|
|
4416
4477
|
if (process.env.SOOTSIM_HOME && isSootsimDevCheckout() && !readActiveRuntime()) {
|
|
4417
4478
|
return;
|
|
4418
4479
|
}
|
|
@@ -4430,7 +4491,9 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
4430
4491
|
if (reason === "startup") {
|
|
4431
4492
|
process.stderr.write("sootsim: checking for runtime updates\u2026\n");
|
|
4432
4493
|
}
|
|
4433
|
-
const result = await sootsimRuntime.updateToLatest(
|
|
4494
|
+
const result = await sootsimRuntime.updateToLatest({
|
|
4495
|
+
protectVersions: this.connectedRuntimeVersions()
|
|
4496
|
+
});
|
|
4434
4497
|
if (!result.updated || !result.latestVersion) {
|
|
4435
4498
|
if (reason === "startup") {
|
|
4436
4499
|
process.stderr.write(
|
|
@@ -4491,6 +4554,11 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
4491
4554
|
runtimeDir: this.activeRuntimeDirPath
|
|
4492
4555
|
});
|
|
4493
4556
|
for (const sim of this.sims.values()) {
|
|
4557
|
+
try {
|
|
4558
|
+
const simUrl = new URL(sim.url || sim.origin || "http://localhost");
|
|
4559
|
+
if (runtimeVersionFromHostname(simUrl.hostname)) continue;
|
|
4560
|
+
} catch {
|
|
4561
|
+
}
|
|
4494
4562
|
if (sim.ws.readyState === import_ws2.WebSocket.OPEN) {
|
|
4495
4563
|
try {
|
|
4496
4564
|
sim.ws.send(payload);
|
|
@@ -4534,12 +4602,77 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
4534
4602
|
return;
|
|
4535
4603
|
}
|
|
4536
4604
|
const method = (req.method || "GET").toUpperCase();
|
|
4605
|
+
let url;
|
|
4606
|
+
try {
|
|
4607
|
+
url = new URL(req.url || "/", `http://${req.headers.host || "localhost"}`);
|
|
4608
|
+
} catch {
|
|
4609
|
+
res.writeHead(400, { "Content-Type": "text/plain; charset=utf-8" });
|
|
4610
|
+
res.end("invalid request URL or host");
|
|
4611
|
+
return;
|
|
4612
|
+
}
|
|
4613
|
+
if (url.pathname === "/__sootsim/shared-config") {
|
|
4614
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
4615
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
4616
|
+
res.setHeader("Cache-Control", "no-store");
|
|
4617
|
+
if (method === "OPTIONS") {
|
|
4618
|
+
res.writeHead(204, { Allow: "GET, HEAD, POST, OPTIONS" });
|
|
4619
|
+
res.end();
|
|
4620
|
+
return;
|
|
4621
|
+
}
|
|
4622
|
+
if (method === "GET" || method === "HEAD") {
|
|
4623
|
+
let body = "{}";
|
|
4624
|
+
try {
|
|
4625
|
+
body = JSON.stringify(readSharedConfig());
|
|
4626
|
+
} catch {
|
|
4627
|
+
}
|
|
4628
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
4629
|
+
if (method === "HEAD") res.end();
|
|
4630
|
+
else res.end(body);
|
|
4631
|
+
return;
|
|
4632
|
+
}
|
|
4633
|
+
if (method === "POST") {
|
|
4634
|
+
void (async () => {
|
|
4635
|
+
try {
|
|
4636
|
+
const chunks = [];
|
|
4637
|
+
let size = 0;
|
|
4638
|
+
for await (const chunk of req) {
|
|
4639
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
4640
|
+
size += buffer.byteLength;
|
|
4641
|
+
if (size > 8 * 1024 * 1024) {
|
|
4642
|
+
res.writeHead(413, { "Content-Type": "text/plain; charset=utf-8" });
|
|
4643
|
+
res.end("shared config patch is too large");
|
|
4644
|
+
return;
|
|
4645
|
+
}
|
|
4646
|
+
chunks.push(buffer);
|
|
4647
|
+
}
|
|
4648
|
+
const parsed = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
4649
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
4650
|
+
throw new Error("shared config patch must be an object");
|
|
4651
|
+
}
|
|
4652
|
+
const patch = Object.fromEntries(
|
|
4653
|
+
Object.entries(parsed)
|
|
4654
|
+
);
|
|
4655
|
+
const next = this.writeAndBroadcastSharedConfig(patch);
|
|
4656
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
4657
|
+
res.end(JSON.stringify(next));
|
|
4658
|
+
} catch (error) {
|
|
4659
|
+
res.writeHead(400, { "Content-Type": "text/plain; charset=utf-8" });
|
|
4660
|
+
res.end(
|
|
4661
|
+
`invalid shared config patch: ${error instanceof Error ? error.message : String(error)}`
|
|
4662
|
+
);
|
|
4663
|
+
}
|
|
4664
|
+
})();
|
|
4665
|
+
return;
|
|
4666
|
+
}
|
|
4667
|
+
res.writeHead(405, { Allow: "GET, HEAD, POST, OPTIONS" });
|
|
4668
|
+
res.end("method not allowed");
|
|
4669
|
+
return;
|
|
4670
|
+
}
|
|
4537
4671
|
if (method !== "GET" && method !== "HEAD") {
|
|
4538
4672
|
res.writeHead(405, { Allow: "GET, HEAD" });
|
|
4539
4673
|
res.end("method not allowed");
|
|
4540
4674
|
return;
|
|
4541
4675
|
}
|
|
4542
|
-
const url = new URL(req.url || "/", "http://localhost");
|
|
4543
4676
|
if (url.pathname === "/__bundle-proxy") {
|
|
4544
4677
|
const target = url.searchParams.get("url");
|
|
4545
4678
|
if (!target) {
|
|
@@ -4616,30 +4749,13 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
4616
4749
|
);
|
|
4617
4750
|
return;
|
|
4618
4751
|
}
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
if (method === "GET" || method === "HEAD") {
|
|
4623
|
-
let body = "{}";
|
|
4624
|
-
try {
|
|
4625
|
-
body = JSON.stringify(readSharedConfig());
|
|
4626
|
-
} catch {
|
|
4627
|
-
}
|
|
4628
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
4629
|
-
if (method === "HEAD") res.end();
|
|
4630
|
-
else res.end(body);
|
|
4631
|
-
return;
|
|
4632
|
-
}
|
|
4633
|
-
res.writeHead(405, { Allow: "GET, HEAD" });
|
|
4634
|
-
res.end("method not allowed (use the bridge over WS for writes)");
|
|
4635
|
-
return;
|
|
4636
|
-
}
|
|
4637
|
-
this.refreshActiveRuntime();
|
|
4638
|
-
const baseDir = this.activeRuntimeDirPath;
|
|
4752
|
+
const requestedRuntime = runtimeVersionFromHostname(url.hostname);
|
|
4753
|
+
if (!requestedRuntime) this.refreshActiveRuntime();
|
|
4754
|
+
const baseDir = requestedRuntime ? resolveInstalledRuntimeRoot(requestedRuntime) : this.activeRuntimeDirPath;
|
|
4639
4755
|
if (!baseDir) {
|
|
4640
4756
|
res.writeHead(503, { "Content-Type": "text/plain; charset=utf-8" });
|
|
4641
4757
|
res.end(
|
|
4642
|
-
"sootsim: no active runtime installed. run `sootsim runtime install` to fetch one."
|
|
4758
|
+
requestedRuntime ? `sootsim: runtime ${requestedRuntime} is not installed. run \`sootsim open\` from that app again.` : "sootsim: no active runtime installed. run `sootsim runtime install` to fetch one."
|
|
4643
4759
|
);
|
|
4644
4760
|
return;
|
|
4645
4761
|
}
|
|
@@ -5246,6 +5362,21 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
5246
5362
|
);
|
|
5247
5363
|
}
|
|
5248
5364
|
}
|
|
5365
|
+
writeAndBroadcastSharedConfig(patch) {
|
|
5366
|
+
const next = writeSharedConfig(patch);
|
|
5367
|
+
const payload = JSON.stringify({
|
|
5368
|
+
type: "bridge:shared-config-changed",
|
|
5369
|
+
config: next
|
|
5370
|
+
});
|
|
5371
|
+
for (const peer of this.sims.values()) {
|
|
5372
|
+
if (peer.ws.readyState !== import_ws2.WebSocket.OPEN) continue;
|
|
5373
|
+
try {
|
|
5374
|
+
peer.ws.send(payload);
|
|
5375
|
+
} catch {
|
|
5376
|
+
}
|
|
5377
|
+
}
|
|
5378
|
+
return next;
|
|
5379
|
+
}
|
|
5249
5380
|
broadcastSimClientStates() {
|
|
5250
5381
|
for (const sim of this.sims.values()) {
|
|
5251
5382
|
if (sim.ws.readyState !== import_ws2.WebSocket.OPEN) continue;
|
|
@@ -5384,6 +5515,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
5384
5515
|
expiresAt: Date.now() + _SootSimBridgeHost.SIM_RECONNECT_TTL_MS
|
|
5385
5516
|
});
|
|
5386
5517
|
this.sims.delete(sim.id);
|
|
5518
|
+
this.writeConnectedRuntimeSnapshot();
|
|
5387
5519
|
}
|
|
5388
5520
|
getRestorableSimState(simId) {
|
|
5389
5521
|
const snapshot = this.restorableSims.get(simId);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.296 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.296 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|