sootsim 0.1.250 → 0.1.252
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -5
- package/dist-cli/bin.js +4 -4
- package/dist-cli/chunks/{agent-JPKDUK4P.js → agent-JRN5KS75.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-Z64YICSQ.js → agent-wrapper-2ZH2WQ2L.js} +2 -2
- package/dist-cli/chunks/{app-fonts-524IXHZF.js → app-fonts-LBQ7A7LL.js} +2 -2
- package/dist-cli/chunks/{assert-WZRU7L2S.js → assert-XFQCRREO.js} +2 -2
- package/dist-cli/chunks/{auth-3ZPMASCJ.js → auth-DAMRQQ53.js} +2 -2
- package/dist-cli/chunks/beta-JJ4YSCOE.js +2 -0
- package/dist-cli/chunks/{camera-FPGFHVAE.js → camera-NQWFOHXI.js} +2 -2
- package/dist-cli/chunks/chunk-25FMG2DR.js +1 -0
- package/dist-cli/chunks/{chunk-ZFJZLRAG.js → chunk-4P7EXY3Q.js} +2 -2
- package/dist-cli/chunks/{chunk-JMJJJQ3N.js → chunk-54RVP6DQ.js} +1 -1
- package/dist-cli/chunks/{chunk-ODXX3PDC.js → chunk-56CSO42W.js} +2 -2
- package/dist-cli/chunks/{chunk-7SDQP3K6.js → chunk-5PVVFMLA.js} +2 -2
- package/dist-cli/chunks/{chunk-LFRFK56L.js → chunk-677KF26C.js} +1 -1
- package/dist-cli/chunks/{chunk-ZBAOOQ7L.js → chunk-AJVA4XFD.js} +2 -2
- package/dist-cli/chunks/{chunk-OOYVCERU.js → chunk-BU4QJGYM.js} +2 -2
- package/dist-cli/chunks/{chunk-LCEWHXGT.js → chunk-F2DZ3EHN.js} +2 -2
- package/dist-cli/chunks/chunk-F7NVK7U5.js +29 -0
- package/dist-cli/chunks/{chunk-GVEBFN3A.js → chunk-FCNI6ZWQ.js} +2 -2
- package/dist-cli/chunks/{chunk-7CESRUUF.js → chunk-GBJS3QVL.js} +2 -2
- package/dist-cli/chunks/{chunk-RDQ4RP2I.js → chunk-GPECMCCD.js} +2 -2
- package/dist-cli/chunks/{chunk-HQVZVJWB.js → chunk-GRPNPAFQ.js} +1 -1
- package/dist-cli/chunks/{chunk-EJQGI6U6.js → chunk-HERRSHL3.js} +2 -2
- package/dist-cli/chunks/{chunk-QQDVBF5C.js → chunk-HNYCB3ZY.js} +1 -1
- package/dist-cli/chunks/chunk-HV773SED.js +4 -0
- package/dist-cli/chunks/{chunk-DOOM7A5G.js → chunk-J4XJHPJV.js} +2 -2
- package/dist-cli/chunks/{chunk-TIWQBBA6.js → chunk-JYJ37QKN.js} +2 -2
- package/dist-cli/chunks/chunk-K5UURTEB.js +1 -0
- package/dist-cli/chunks/{chunk-AV734IPM.js → chunk-LHAUZJH5.js} +1 -1
- package/dist-cli/chunks/{chunk-XBWJ7DPK.js → chunk-LL7KIGNG.js} +2 -2
- package/dist-cli/chunks/{chunk-HTGCR74O.js → chunk-LXRPMNYD.js} +2 -2
- package/dist-cli/chunks/{chunk-2FGQSNTC.js → chunk-LYIN47A5.js} +2 -2
- package/dist-cli/chunks/{chunk-Q72PZST6.js → chunk-MJU6KNLI.js} +3 -3
- package/dist-cli/chunks/{chunk-23DV2XSE.js → chunk-MMCNYDBD.js} +1 -1
- package/dist-cli/chunks/{chunk-G2QKQWCY.js → chunk-NADQK2CU.js} +1 -1
- package/dist-cli/chunks/{chunk-N52AECUU.js → chunk-NB6RTLLI.js} +3 -3
- package/dist-cli/chunks/{chunk-S5ILN4OM.js → chunk-NNEUAQME.js} +3 -3
- package/dist-cli/chunks/{chunk-RMP6YTMJ.js → chunk-NTZYSZ3Q.js} +2 -2
- package/dist-cli/chunks/{chunk-AWT2ISDX.js → chunk-NYKHYDBN.js} +1 -1
- package/dist-cli/chunks/{chunk-7WCUYHR3.js → chunk-OSPFE643.js} +1 -1
- package/dist-cli/chunks/{chunk-DX6CUGUF.js → chunk-PLK4SCBY.js} +2 -2
- package/dist-cli/chunks/{chunk-HLDQHWK5.js → chunk-PVDPE5BH.js} +1 -1
- package/dist-cli/chunks/{chunk-L5VG4RQT.js → chunk-QHNYUT7D.js} +1 -1
- package/dist-cli/chunks/{chunk-ZA4K47LA.js → chunk-S6DIPG7L.js} +2 -2
- package/dist-cli/chunks/{chunk-YACJ3KQ4.js → chunk-T2BJFGBC.js} +1 -1
- package/dist-cli/chunks/{chunk-CJMASJXU.js → chunk-TDWFR6H5.js} +2 -2
- package/dist-cli/chunks/{chunk-COON6LFC.js → chunk-U5JMZPBD.js} +1 -1
- package/dist-cli/chunks/{chunk-N6WXF6OS.js → chunk-UA5FVOEO.js} +1 -1
- package/dist-cli/chunks/chunk-UVE2LY6V.js +7 -0
- package/dist-cli/chunks/{chunk-GHJRRNR3.js → chunk-WS3DDBN3.js} +1 -1
- package/dist-cli/chunks/{chunk-KZZFQRPX.js → chunk-X2IKDV5A.js} +1 -1
- package/dist-cli/chunks/{chunk-GXNJSLZM.js → chunk-ZKN7GCX4.js} +2 -2
- package/dist-cli/chunks/cli-version-OZF5OMW4.js +2 -0
- package/dist-cli/chunks/{compat-C3N6PFK5.js → compat-ME4QWRZ6.js} +3 -3
- package/dist-cli/chunks/{config-UVEGEV7N.js → config-TMMSBXDV.js} +2 -2
- package/dist-cli/chunks/{control-ROSEFQH3.js → control-QGYYWKJP.js} +2 -2
- package/dist-cli/chunks/daemon-6NBHEVXS.js +2 -0
- package/dist-cli/chunks/{debug-VLB6FCUL.js → debug-LFJ46Q45.js} +3 -3
- package/dist-cli/chunks/{desktop-LAPJ2XXG.js → desktop-W5GPU7JA.js} +3 -3
- package/dist-cli/chunks/{detox-UKRIYJBM.js → detox-U3B3N3K7.js} +2 -2
- package/dist-cli/chunks/{device-HABOB4FC.js → device-I2WVQFXL.js} +2 -2
- package/dist-cli/chunks/{diagnose-TPTVALBD.js → diagnose-6TQOA4QJ.js} +2 -2
- package/dist-cli/chunks/drivers-5J25VDIG.js +2 -0
- package/dist-cli/chunks/{film-RZABTGXV.js → film-P5E64XQH.js} +3 -3
- package/dist-cli/chunks/flow-LD6MOZQC.js +2 -0
- package/dist-cli/chunks/help-VCWJZBQU.js +2 -0
- package/dist-cli/chunks/{hidden-runtime-alias-AITHRBI5.js → hidden-runtime-alias-ICP5W4W5.js} +2 -2
- package/dist-cli/chunks/home-paths-MCD3DISJ.js +2 -0
- package/dist-cli/chunks/inspect-VF575AD3.js +2 -0
- package/dist-cli/chunks/install-desktop-Q4Y6FTSA.js +2 -0
- package/dist-cli/chunks/{login-LIPDXOLT.js → login-A5LRYTNO.js} +4 -4
- package/dist-cli/chunks/{logout-7TCXGQM4.js → logout-M3HFZGFU.js} +2 -2
- package/dist-cli/chunks/{maestro-CQRCUEZJ.js → maestro-HNREOYXF.js} +3 -3
- package/dist-cli/chunks/{maestro-generate-TBBDRYEU.js → maestro-generate-BEEDUOOJ.js} +3 -3
- package/dist-cli/chunks/{mode-Z7E6YZTJ.js → mode-IBFHS3G2.js} +2 -2
- package/dist-cli/chunks/optional-demo-registry-6XYQJXI5.js +2 -0
- package/dist-cli/chunks/{perf-OS7TTPQ2.js → perf-62BD5VIU.js} +2 -2
- package/dist-cli/chunks/{record-YH22UVU2.js → record-2ILPO4XB.js} +3 -3
- package/dist-cli/chunks/runtime-WCDQFR7G.js +2 -0
- package/dist-cli/chunks/{screenshot-command-DV35HE24.js → screenshot-command-YZR5KVV2.js} +3 -3
- package/dist-cli/chunks/{screenshots-capture-OV6RMSA2.js → screenshots-capture-QHQ43OBD.js} +2 -2
- package/dist-cli/chunks/{serve-WTZRYS6X.js → serve-GQ4PUD5P.js} +15 -15
- package/dist-cli/chunks/{setup-AQ46RLHL.js → setup-C74I2RO3.js} +3 -3
- package/dist-cli/chunks/{skills-P6P5L7CV.js → skills-I7EVR3MU.js} +2 -2
- package/dist-cli/chunks/{storage-PIHIVEBL.js → storage-CH6BAYB4.js} +2 -2
- package/dist-cli/chunks/store-PTQ4QMFA.js +2 -0
- package/dist-cli/chunks/telemetry-AJDAGOFX.js +2 -0
- package/dist-cli/chunks/{timeline-334MEYTC.js → timeline-FUS7F5LI.js} +2 -2
- package/dist-cli/chunks/{upgrade-UVEGTAME.js → upgrade-DHMZFD5R.js} +4 -4
- package/dist-cli/chunks/upload-XJXPQMKX.js +2 -0
- package/dist-cli/chunks/version-M2GSAVKM.js +4 -0
- package/dist-cli/chunks/web-NV7UM2T7.js +2 -0
- package/dist-cli/chunks/{what-happened-3UH7ZQW6.js → what-happened-VRDDXQWR.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/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 +1 -33
- package/dist-lib/host/bridge-host.cjs +396 -329
- 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/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +517 -437
- package/dist-lib/vite.cjs +1 -1
- package/package.json +2 -1
- package/src/home-paths.ts +5 -40
- package/src/host/bridge-host.ts +4 -5
- package/src/runtime-delivery.ts +32 -377
- package/dist-cli/chunks/beta-BBI3GYZ6.js +0 -2
- package/dist-cli/chunks/chunk-2UGQF7XX.js +0 -4
- package/dist-cli/chunks/chunk-J3XNJTO5.js +0 -1
- package/dist-cli/chunks/chunk-M7NRJV7O.js +0 -1
- package/dist-cli/chunks/chunk-PZR5U4RD.js +0 -29
- package/dist-cli/chunks/chunk-TJBXFUCI.js +0 -7
- package/dist-cli/chunks/cli-version-GWSUBSWJ.js +0 -2
- package/dist-cli/chunks/daemon-NVFYFCWX.js +0 -2
- package/dist-cli/chunks/drivers-ZUD4PX2W.js +0 -2
- package/dist-cli/chunks/flow-NHVT35XI.js +0 -2
- package/dist-cli/chunks/help-CM77GYXU.js +0 -2
- package/dist-cli/chunks/home-paths-XIHGBDLL.js +0 -2
- package/dist-cli/chunks/inspect-2WK43KRH.js +0 -2
- package/dist-cli/chunks/install-desktop-TS2RBWU5.js +0 -2
- package/dist-cli/chunks/optional-demo-registry-ANMKFJWS.js +0 -2
- package/dist-cli/chunks/runtime-WYDPR5RI.js +0 -2
- package/dist-cli/chunks/store-SVTB7QDS.js +0 -2
- package/dist-cli/chunks/telemetry-HM3ULN5U.js +0 -2
- package/dist-cli/chunks/upload-BIEPTIMK.js +0 -2
- package/dist-cli/chunks/version-VITMYQHS.js +0 -4
- package/dist-cli/chunks/web-G5IDDAAI.js +0 -2
package/dist-lib/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.252 | (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;
|
|
@@ -2896,8 +2896,8 @@ var init_registry = __esm({
|
|
|
2896
2896
|
range: ">=0.1.0",
|
|
2897
2897
|
coverage: 0.92,
|
|
2898
2898
|
note: "real canvaskit-wasm backing via the engine instance (`globalThis.__sootsimCanvasKit`); declarative <Canvas> snapshots each commit through an offscreen SkSurface and mounts the encoded PNG as a host image. zero second canvaskit bundle.",
|
|
2899
|
-
working: "<Canvas> with offscreen SkSurface paint\u2192PNG\u2192host <Image>, <Path>/<Rect>/<RoundedRect>/<Circle>/<Oval>/<Line>/<Fill>/<Image>/<Text>/<Group> primitives, <LinearGradient>/<RadialGradient>/<SweepGradient>/<ColorShader> paint shaders, <BlurMask>/<Blur>/<Mask>/<Shadow> mask + image filters, <BackdropFilter>/<BackdropBlur>, <DashPathEffect>/<DiscretePathEffect>/<CornerPathEffect>, Skia.Path/Paint/Color/Shader/MaskFilter/ImageFilter/ColorFilter/Font/Typeface/FontMgr factories, Skia.MakeImageFromEncoded, Skia.XYWHRect/LTRBRect/RRectXY/Point/Matrix, useImage (fetches+decodes through canvaskit), useFont (loads typeface from ArrayBuffer / URL), useFonts (matchFamilyStyle), useCanvasRef + ref.makeImageSnapshot, useValue/useDerivedValue/useComputedValue/useValueEffect/useClockValue listener model, BlendMode/StrokeCap/StrokeJoin/FillType/PaintStyle/TileMode/BlurStyle/FontWeight/FontStyle/FontSlant/FontWidth/ClipOp/PathVerb/PathOp/TextAlign/TextDirection enums.",
|
|
2900
|
-
missing: "<RuntimeShader> SkSL compilation+uniform-binding pipeline, <Points>/<TextPath>/<Glyphs>/<ImageSVG>/<Vertices>/<Patch>/<Atlas>/<
|
|
2899
|
+
working: "<Canvas> with offscreen SkSurface paint\u2192PNG\u2192host <Image>, <Path>/<Rect>/<RoundedRect>/<Circle>/<Oval>/<Line>/<Fill>/<Image>/<Text>/<Picture>/<Group> primitives, shared-value group transforms, rect/rrect group clipping, <LinearGradient>/<RadialGradient>/<SweepGradient>/<ColorShader> paint shaders, <BlurMask>/<Blur>/<Mask>/<Shadow> mask + image filters, <BackdropFilter>/<BackdropBlur>, <DashPathEffect>/<DiscretePathEffect>/<CornerPathEffect>, Skia.Path/Paint/Color/Shader/MaskFilter/ImageFilter/ColorFilter/Font/Typeface/FontMgr factories, Skia.MakeImageFromEncoded, Skia.XYWHRect/LTRBRect/RRectXY/Point/Matrix, useImage (fetches+decodes through canvaskit), useFont (loads typeface from ArrayBuffer / URL), useFonts (URL, module, and Metro asset-id sources with matchFamilyStyle), useCanvasRef + ref.makeImageSnapshot, useValue/useDerivedValue/useComputedValue/useValueEffect/useClockValue listener model, BlendMode/StrokeCap/StrokeJoin/FillType/PaintStyle/TileMode/BlurStyle/FontWeight/FontStyle/FontSlant/FontWidth/ClipOp/PathVerb/PathOp/TextAlign/TextDirection enums.",
|
|
2900
|
+
missing: "<RuntimeShader> SkSL compilation+uniform-binding pipeline, <Points>/<TextPath>/<Glyphs>/<ImageSVG>/<Vertices>/<Patch>/<Atlas>/<FitBox>/<Box>/<BoxShadow> (each logs a one-time hint and renders null), path-shaped group clipping, <Paint> as a declarative component, useTouchHandler full gesture state machine (we forward a minimal touch handler shape; consumers should use Pressable wrappers for hit-testing), reanimated worklet-driven canvas redraws (`useSharedValueEffect` subscribes only to the local SkiaValue listener shape; Canvas display-list encoding and setTick/setDataUrl updates remain owned by React useLayoutEffect, so redraws still reconcile through React), Skia.ParagraphBuilder full layout (we keep measurement-only semantics matching the previous stub; for pixel-perfect skia paragraphs apps should wait on the upstream JsiSkParagraphBuilder adapter), Skia.SVG.MakeFromString (canvaskit-wasm omits svg parsing in the size-tuned builds we ship), GPU SkSurface backing on offscreen paints (we use software MakeSurface so each Canvas paint runs on cpu; deferred until a real engine host element owns its own GrDirectContext for paint-only animation)."
|
|
2901
2901
|
}
|
|
2902
2902
|
]
|
|
2903
2903
|
},
|
|
@@ -10528,10 +10528,10 @@ function tcpPing(port, timeout = TCP_GATE_MS) {
|
|
|
10528
10528
|
sock.connect(port, "localhost");
|
|
10529
10529
|
});
|
|
10530
10530
|
}
|
|
10531
|
-
function httpGet(port,
|
|
10531
|
+
function httpGet(port, path12, method = "GET", timeout = TIMEOUT_MS, headers = {}) {
|
|
10532
10532
|
return new Promise((resolve5) => {
|
|
10533
10533
|
const req = import_http.default.request(
|
|
10534
|
-
{ hostname: "localhost", port, path:
|
|
10534
|
+
{ hostname: "localhost", port, path: path12, method, timeout, headers },
|
|
10535
10535
|
(res) => {
|
|
10536
10536
|
let body = "";
|
|
10537
10537
|
res.on("data", (c) => body += c.toString());
|
|
@@ -11088,34 +11088,6 @@ function writeActiveRuntime(version) {
|
|
|
11088
11088
|
import_node_fs2.default.writeFileSync(activeRuntimeFile(), `${version}
|
|
11089
11089
|
`, "utf8");
|
|
11090
11090
|
}
|
|
11091
|
-
function listInstalledRuntimes() {
|
|
11092
|
-
try {
|
|
11093
|
-
return import_node_fs2.default.readdirSync(runtimesDir(), { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort(compareSemver);
|
|
11094
|
-
} catch {
|
|
11095
|
-
return [];
|
|
11096
|
-
}
|
|
11097
|
-
}
|
|
11098
|
-
function compareSemver(a, b) {
|
|
11099
|
-
const parse = (v) => {
|
|
11100
|
-
const hyphen = v.indexOf("-");
|
|
11101
|
-
const core = hyphen >= 0 ? v.slice(0, hyphen) : v;
|
|
11102
|
-
const pre = hyphen >= 0 ? v.slice(hyphen + 1) : "";
|
|
11103
|
-
const parts = core.split(".").map((n) => Number.parseInt(n, 10));
|
|
11104
|
-
if (parts.some((n) => !Number.isFinite(n))) return [[Number.POSITIVE_INFINITY], v];
|
|
11105
|
-
return [parts, pre];
|
|
11106
|
-
};
|
|
11107
|
-
const [an, ap] = parse(a);
|
|
11108
|
-
const [bn, bp] = parse(b);
|
|
11109
|
-
for (let i = 0; i < Math.max(an.length, bn.length); i++) {
|
|
11110
|
-
const av = an[i] ?? 0;
|
|
11111
|
-
const bv = bn[i] ?? 0;
|
|
11112
|
-
if (av !== bv) return av - bv;
|
|
11113
|
-
}
|
|
11114
|
-
if (ap === bp) return 0;
|
|
11115
|
-
if (!ap) return 1;
|
|
11116
|
-
if (!bp) return -1;
|
|
11117
|
-
return ap < bp ? -1 : 1;
|
|
11118
|
-
}
|
|
11119
11091
|
function activeRuntimeDir() {
|
|
11120
11092
|
const version = readActiveRuntime();
|
|
11121
11093
|
if (!version) return null;
|
|
@@ -11271,139 +11243,237 @@ var init_runtime_assets = __esm({
|
|
|
11271
11243
|
}
|
|
11272
11244
|
});
|
|
11273
11245
|
|
|
11274
|
-
//
|
|
11275
|
-
function
|
|
11246
|
+
// ../contrast-runtime-delivery/src/product.ts
|
|
11247
|
+
function listInstalledRuntimes(product) {
|
|
11276
11248
|
try {
|
|
11277
|
-
|
|
11278
|
-
return parsed && typeof parsed === "object" ? parsed : {};
|
|
11249
|
+
return import_node_fs3.default.readdirSync(product.runtimesDir(), { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort(compareSemver);
|
|
11279
11250
|
} catch {
|
|
11280
|
-
return
|
|
11251
|
+
return [];
|
|
11281
11252
|
}
|
|
11282
11253
|
}
|
|
11283
|
-
function
|
|
11284
|
-
|
|
11285
|
-
const value = input || process.env[RUNTIME_CDN_ORIGIN_ENV] || config.cdnOrigin || DEFAULT_RUNTIME_CDN_ORIGIN;
|
|
11286
|
-
return value.replace(/\/+$/, "");
|
|
11287
|
-
}
|
|
11288
|
-
function resolveRuntimeChannel(input) {
|
|
11289
|
-
const config = readConfig();
|
|
11290
|
-
return input || process.env[RUNTIME_CHANNEL_ENV] || config.runtimeChannel || "stable";
|
|
11291
|
-
}
|
|
11292
|
-
function resolveRuntimePin() {
|
|
11293
|
-
const env = process.env[RUNTIME_PIN_ENV];
|
|
11294
|
-
if (env && env.trim()) return env.trim();
|
|
11295
|
-
const config = readConfig();
|
|
11296
|
-
return typeof config.runtimeVersion === "string" && config.runtimeVersion.trim() ? config.runtimeVersion.trim() : null;
|
|
11297
|
-
}
|
|
11298
|
-
function runtimeManifestUrl(cdnOrigin) {
|
|
11299
|
-
const url = new URL(`${resolveRuntimeCdnOrigin(cdnOrigin)}/runtimes/manifest.json`);
|
|
11300
|
-
url.searchParams.set("t", String(Date.now()));
|
|
11301
|
-
return url.toString();
|
|
11254
|
+
function runtimeTarballCacheName(product, version) {
|
|
11255
|
+
return import_node_path2.default.posix.basename(product.tarballPath(version));
|
|
11302
11256
|
}
|
|
11303
|
-
function
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
11257
|
+
function compareSemver(a, b) {
|
|
11258
|
+
const parse = (v) => {
|
|
11259
|
+
const hyphen = v.indexOf("-");
|
|
11260
|
+
const core = hyphen >= 0 ? v.slice(0, hyphen) : v;
|
|
11261
|
+
const pre = hyphen >= 0 ? v.slice(hyphen + 1) : "";
|
|
11262
|
+
const parts = core.split(".").map((n) => Number.parseInt(n, 10));
|
|
11263
|
+
if (parts.some((n) => !Number.isFinite(n))) return [[Number.POSITIVE_INFINITY], v];
|
|
11264
|
+
return [parts, pre];
|
|
11265
|
+
};
|
|
11266
|
+
const [an, ap] = parse(a);
|
|
11267
|
+
const [bn, bp] = parse(b);
|
|
11268
|
+
for (let i = 0; i < Math.max(an.length, bn.length); i++) {
|
|
11269
|
+
const av = an[i] ?? 0;
|
|
11270
|
+
const bv = bn[i] ?? 0;
|
|
11271
|
+
if (av !== bv) return av - bv;
|
|
11311
11272
|
}
|
|
11312
|
-
|
|
11273
|
+
if (ap === bp) return 0;
|
|
11274
|
+
if (!ap) return 1;
|
|
11275
|
+
if (!bp) return -1;
|
|
11276
|
+
return ap < bp ? -1 : 1;
|
|
11313
11277
|
}
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
11319
|
-
|
|
11320
|
-
);
|
|
11278
|
+
var import_node_fs3, import_node_path2;
|
|
11279
|
+
var init_product = __esm({
|
|
11280
|
+
"../contrast-runtime-delivery/src/product.ts"() {
|
|
11281
|
+
"use strict";
|
|
11282
|
+
import_node_fs3 = __toESM(require("node:fs"), 1);
|
|
11283
|
+
import_node_path2 = __toESM(require("node:path"), 1);
|
|
11321
11284
|
}
|
|
11322
|
-
|
|
11323
|
-
|
|
11324
|
-
|
|
11325
|
-
|
|
11326
|
-
|
|
11285
|
+
});
|
|
11286
|
+
|
|
11287
|
+
// ../contrast-runtime-delivery/src/index.ts
|
|
11288
|
+
function createRuntimeDelivery(product) {
|
|
11289
|
+
function readConfig() {
|
|
11290
|
+
try {
|
|
11291
|
+
const parsed = JSON.parse(
|
|
11292
|
+
import_node_fs4.default.readFileSync(product.configFile(), "utf8")
|
|
11293
|
+
);
|
|
11294
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
11295
|
+
} catch {
|
|
11296
|
+
return {};
|
|
11297
|
+
}
|
|
11327
11298
|
}
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
|
|
11331
|
-
|
|
11332
|
-
|
|
11333
|
-
|
|
11334
|
-
|
|
11335
|
-
|
|
11336
|
-
|
|
11337
|
-
|
|
11338
|
-
|
|
11299
|
+
function resolveCdnOrigin(input) {
|
|
11300
|
+
const config = readConfig();
|
|
11301
|
+
const value = input || process.env[product.env.cdnOrigin] || config.cdnOrigin || product.defaultCdnOrigin;
|
|
11302
|
+
return value.replace(/\/+$/, "");
|
|
11303
|
+
}
|
|
11304
|
+
function resolveChannel(input) {
|
|
11305
|
+
const config = readConfig();
|
|
11306
|
+
return input || process.env[product.env.channel] || config.runtimeChannel || "stable";
|
|
11307
|
+
}
|
|
11308
|
+
function resolvePin() {
|
|
11309
|
+
const env = process.env[product.env.pin];
|
|
11310
|
+
if (env && env.trim()) return env.trim();
|
|
11311
|
+
const config = readConfig();
|
|
11312
|
+
return typeof config.runtimeVersion === "string" && config.runtimeVersion.trim() ? config.runtimeVersion.trim() : null;
|
|
11313
|
+
}
|
|
11314
|
+
function manifestUrl(cdnOrigin) {
|
|
11315
|
+
const url = new URL(`${resolveCdnOrigin(cdnOrigin)}${product.manifestPath}`);
|
|
11316
|
+
url.searchParams.set("t", String(Date.now()));
|
|
11317
|
+
return url.toString();
|
|
11318
|
+
}
|
|
11319
|
+
function tarballUrl(version, cdnOrigin) {
|
|
11320
|
+
return `${resolveCdnOrigin(cdnOrigin)}${product.tarballPath(version)}`;
|
|
11321
|
+
}
|
|
11322
|
+
async function fetchManifest(cdnOrigin) {
|
|
11323
|
+
const url = manifestUrl(cdnOrigin);
|
|
11324
|
+
const res = await fetch(url, { headers: { Accept: "application/json" } });
|
|
11325
|
+
if (!res.ok) {
|
|
11326
|
+
throw new Error(`manifest fetch failed: ${res.status} ${res.statusText} (${url})`);
|
|
11327
|
+
}
|
|
11328
|
+
return await res.json();
|
|
11329
|
+
}
|
|
11330
|
+
function resolveVersion(manifest, opts = {}) {
|
|
11331
|
+
const channel = resolveChannel(opts.channel);
|
|
11332
|
+
const version = opts.version || resolvePin() || manifest.channels[channel]?.latest;
|
|
11333
|
+
if (!version) {
|
|
11334
|
+
throw new Error(
|
|
11335
|
+
`no version specified and channel '${channel}' has no latest entry in the manifest`
|
|
11336
|
+
);
|
|
11337
|
+
}
|
|
11338
|
+
const entry = manifest.versions[version];
|
|
11339
|
+
if (!entry) {
|
|
11340
|
+
throw new Error(
|
|
11341
|
+
`version ${version} not found in manifest; available: ${Object.keys(manifest.versions).slice(-10).join(", ") || "(none)"}`
|
|
11342
|
+
);
|
|
11343
|
+
}
|
|
11344
|
+
return { version, channel, entry };
|
|
11345
|
+
}
|
|
11346
|
+
async function install(opts = {}) {
|
|
11347
|
+
product.ensureHome();
|
|
11348
|
+
const cdnOrigin = resolveCdnOrigin(opts.cdnOrigin);
|
|
11349
|
+
const manifest = await fetchManifest(cdnOrigin);
|
|
11350
|
+
const { version, channel, entry } = resolveVersion(manifest, opts);
|
|
11351
|
+
const destDir = product.runtimeDir(version);
|
|
11352
|
+
const setActive = opts.setActive !== false;
|
|
11353
|
+
if (!opts.force && import_node_fs4.default.existsSync(import_node_path3.default.join(destDir, "index.html"))) {
|
|
11354
|
+
if (setActive) product.writeActiveRuntime(version);
|
|
11355
|
+
return {
|
|
11356
|
+
version,
|
|
11357
|
+
channel,
|
|
11358
|
+
cdnOrigin,
|
|
11359
|
+
runtimeDir: destDir,
|
|
11360
|
+
installed: false,
|
|
11361
|
+
activated: setActive,
|
|
11362
|
+
manifest
|
|
11363
|
+
};
|
|
11364
|
+
}
|
|
11365
|
+
const tarUrl = entry.tarball || tarballUrl(version, cdnOrigin);
|
|
11366
|
+
const tarCachePath = import_node_path3.default.join(
|
|
11367
|
+
product.cacheDir(),
|
|
11368
|
+
runtimeTarballCacheName(product, version)
|
|
11369
|
+
);
|
|
11370
|
+
process.stderr.write(`${product.id}: downloading runtime ${version}\u2026
|
|
11371
|
+
`);
|
|
11372
|
+
await downloadToFile(tarUrl, tarCachePath);
|
|
11373
|
+
process.stderr.write(`${product.id}: extracting runtime ${version}\u2026
|
|
11374
|
+
`);
|
|
11375
|
+
const actualSha = await sha256File(tarCachePath);
|
|
11376
|
+
if (actualSha !== entry.sha256) {
|
|
11377
|
+
import_node_fs4.default.rmSync(tarCachePath, { force: true });
|
|
11378
|
+
throw new Error(
|
|
11379
|
+
`sha256 mismatch for runtime ${version}: expected ${entry.sha256}, actual ${actualSha}`
|
|
11380
|
+
);
|
|
11381
|
+
}
|
|
11382
|
+
const tmpDir = import_node_path3.default.join(
|
|
11383
|
+
import_node_path3.default.dirname(destDir),
|
|
11384
|
+
`.installing-${version}-${process.pid}`
|
|
11385
|
+
);
|
|
11386
|
+
import_node_fs4.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
11387
|
+
import_node_fs4.default.mkdirSync(tmpDir, { recursive: true });
|
|
11388
|
+
try {
|
|
11389
|
+
await extractTarball(tarCachePath, tmpDir);
|
|
11390
|
+
if (!import_node_fs4.default.existsSync(import_node_path3.default.join(tmpDir, "index.html"))) {
|
|
11391
|
+
throw new Error(`extracted tarball for runtime ${version} is missing index.html`);
|
|
11392
|
+
}
|
|
11393
|
+
import_node_fs4.default.rmSync(destDir, { recursive: true, force: true });
|
|
11394
|
+
import_node_fs4.default.renameSync(tmpDir, destDir);
|
|
11395
|
+
} catch (err) {
|
|
11396
|
+
import_node_fs4.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
11397
|
+
throw err;
|
|
11398
|
+
}
|
|
11399
|
+
if (setActive) product.writeActiveRuntime(version);
|
|
11339
11400
|
return {
|
|
11340
11401
|
version,
|
|
11341
11402
|
channel,
|
|
11342
11403
|
cdnOrigin,
|
|
11343
11404
|
runtimeDir: destDir,
|
|
11344
|
-
installed:
|
|
11405
|
+
installed: true,
|
|
11345
11406
|
activated: setActive,
|
|
11346
11407
|
manifest
|
|
11347
11408
|
};
|
|
11348
11409
|
}
|
|
11349
|
-
|
|
11350
|
-
|
|
11351
|
-
|
|
11352
|
-
|
|
11353
|
-
|
|
11354
|
-
|
|
11355
|
-
|
|
11356
|
-
|
|
11357
|
-
|
|
11358
|
-
|
|
11359
|
-
|
|
11360
|
-
|
|
11361
|
-
|
|
11362
|
-
|
|
11363
|
-
|
|
11364
|
-
|
|
11365
|
-
|
|
11366
|
-
|
|
11367
|
-
|
|
11368
|
-
|
|
11369
|
-
|
|
11410
|
+
async function updateToLatest(opts = {}) {
|
|
11411
|
+
product.ensureHome();
|
|
11412
|
+
const cdnOrigin = resolveCdnOrigin(opts.cdnOrigin);
|
|
11413
|
+
const channel = resolveChannel(opts.channel);
|
|
11414
|
+
const pin = resolvePin();
|
|
11415
|
+
if (pin) {
|
|
11416
|
+
const activeVersion2 = product.readActiveRuntime();
|
|
11417
|
+
const pinInstalled = import_node_fs4.default.existsSync(import_node_path3.default.join(product.runtimeDir(pin), "index.html"));
|
|
11418
|
+
if (activeVersion2 === pin && pinInstalled) {
|
|
11419
|
+
return {
|
|
11420
|
+
checked: true,
|
|
11421
|
+
updated: false,
|
|
11422
|
+
reason: `runtime is pinned to ${pin}`,
|
|
11423
|
+
activeVersion: activeVersion2,
|
|
11424
|
+
latestVersion: pin
|
|
11425
|
+
};
|
|
11426
|
+
}
|
|
11427
|
+
const installed3 = await install({
|
|
11428
|
+
version: pin,
|
|
11429
|
+
channel,
|
|
11430
|
+
cdnOrigin,
|
|
11431
|
+
setActive: false
|
|
11432
|
+
});
|
|
11433
|
+
return {
|
|
11434
|
+
checked: true,
|
|
11435
|
+
updated: true,
|
|
11436
|
+
reason: `runtime is pinned to ${pin}`,
|
|
11437
|
+
activeVersion: pin,
|
|
11438
|
+
latestVersion: pin,
|
|
11439
|
+
install: installed3
|
|
11440
|
+
};
|
|
11370
11441
|
}
|
|
11371
|
-
|
|
11372
|
-
|
|
11373
|
-
|
|
11374
|
-
import_fs2.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
11375
|
-
throw err;
|
|
11376
|
-
}
|
|
11377
|
-
if (setActive) writeActiveRuntime(version);
|
|
11378
|
-
return {
|
|
11379
|
-
version,
|
|
11380
|
-
channel,
|
|
11381
|
-
cdnOrigin,
|
|
11382
|
-
runtimeDir: destDir,
|
|
11383
|
-
installed: true,
|
|
11384
|
-
activated: setActive,
|
|
11385
|
-
manifest
|
|
11386
|
-
};
|
|
11387
|
-
}
|
|
11388
|
-
async function updateRuntimeToLatest(opts = {}) {
|
|
11389
|
-
ensureSootsimHome();
|
|
11390
|
-
const cdnOrigin = resolveRuntimeCdnOrigin(opts.cdnOrigin);
|
|
11391
|
-
const channel = resolveRuntimeChannel(opts.channel);
|
|
11392
|
-
const pin = resolveRuntimePin();
|
|
11393
|
-
if (pin) {
|
|
11394
|
-
const activeVersion2 = readActiveRuntime();
|
|
11395
|
-
const pinInstalled = import_fs2.default.existsSync(import_path2.default.join(runtimeDir(pin), "index.html"));
|
|
11396
|
-
if (activeVersion2 === pin && pinInstalled) {
|
|
11442
|
+
const manifest = await fetchManifest(cdnOrigin);
|
|
11443
|
+
const latestVersion = manifest.channels[channel]?.latest;
|
|
11444
|
+
if (!latestVersion) {
|
|
11397
11445
|
return {
|
|
11398
11446
|
checked: true,
|
|
11399
11447
|
updated: false,
|
|
11400
|
-
reason: `
|
|
11401
|
-
activeVersion:
|
|
11402
|
-
|
|
11448
|
+
reason: `channel '${channel}' has no latest runtime`,
|
|
11449
|
+
activeVersion: product.readActiveRuntime()
|
|
11450
|
+
};
|
|
11451
|
+
}
|
|
11452
|
+
const entry = manifest.versions[latestVersion];
|
|
11453
|
+
if (!entry) {
|
|
11454
|
+
return {
|
|
11455
|
+
checked: true,
|
|
11456
|
+
updated: false,
|
|
11457
|
+
reason: `manifest is missing version ${latestVersion}`,
|
|
11458
|
+
activeVersion: product.readActiveRuntime(),
|
|
11459
|
+
latestVersion
|
|
11460
|
+
};
|
|
11461
|
+
}
|
|
11462
|
+
const activeVersion = product.readActiveRuntime();
|
|
11463
|
+
const activeDir = activeVersion ? product.runtimeDir(activeVersion) : null;
|
|
11464
|
+
const activeInstalled = activeDir ? import_node_fs4.default.existsSync(import_node_path3.default.join(activeDir, "index.html")) : false;
|
|
11465
|
+
const shouldInstall = !activeVersion || !activeInstalled || compareSemver(latestVersion, activeVersion) > 0;
|
|
11466
|
+
if (!shouldInstall) {
|
|
11467
|
+
return {
|
|
11468
|
+
checked: true,
|
|
11469
|
+
updated: false,
|
|
11470
|
+
reason: "active runtime is current",
|
|
11471
|
+
activeVersion,
|
|
11472
|
+
latestVersion
|
|
11403
11473
|
};
|
|
11404
11474
|
}
|
|
11405
|
-
const
|
|
11406
|
-
version:
|
|
11475
|
+
const installed2 = await install({
|
|
11476
|
+
version: latestVersion,
|
|
11407
11477
|
channel,
|
|
11408
11478
|
cdnOrigin,
|
|
11409
11479
|
setActive: false
|
|
@@ -11411,57 +11481,40 @@ async function updateRuntimeToLatest(opts = {}) {
|
|
|
11411
11481
|
return {
|
|
11412
11482
|
checked: true,
|
|
11413
11483
|
updated: true,
|
|
11414
|
-
|
|
11415
|
-
|
|
11416
|
-
|
|
11417
|
-
install: install2
|
|
11418
|
-
};
|
|
11419
|
-
}
|
|
11420
|
-
const manifest = await fetchRuntimeManifest(cdnOrigin);
|
|
11421
|
-
const latestVersion = manifest.channels[channel]?.latest;
|
|
11422
|
-
if (!latestVersion) {
|
|
11423
|
-
return {
|
|
11424
|
-
checked: true,
|
|
11425
|
-
updated: false,
|
|
11426
|
-
reason: `channel '${channel}' has no latest runtime`,
|
|
11427
|
-
activeVersion: readActiveRuntime()
|
|
11484
|
+
activeVersion: latestVersion,
|
|
11485
|
+
latestVersion,
|
|
11486
|
+
install: installed2
|
|
11428
11487
|
};
|
|
11429
11488
|
}
|
|
11430
|
-
|
|
11431
|
-
|
|
11432
|
-
|
|
11433
|
-
|
|
11434
|
-
|
|
11435
|
-
|
|
11436
|
-
|
|
11437
|
-
|
|
11438
|
-
|
|
11439
|
-
|
|
11440
|
-
|
|
11441
|
-
|
|
11442
|
-
|
|
11443
|
-
|
|
11444
|
-
|
|
11445
|
-
return {
|
|
11446
|
-
checked: true,
|
|
11447
|
-
updated: false,
|
|
11448
|
-
reason: "active runtime is current",
|
|
11449
|
-
activeVersion,
|
|
11450
|
-
latestVersion
|
|
11451
|
-
};
|
|
11489
|
+
async function checkUpToDate(opts = {}) {
|
|
11490
|
+
const active = product.readActiveRuntime();
|
|
11491
|
+
const pinned = resolvePin();
|
|
11492
|
+
if (pinned) {
|
|
11493
|
+
return { active, latest: pinned, pinned, outdated: active !== pinned };
|
|
11494
|
+
}
|
|
11495
|
+
try {
|
|
11496
|
+
const manifest = await fetchManifest(resolveCdnOrigin(opts.cdnOrigin));
|
|
11497
|
+
const channel = resolveChannel(opts.channel);
|
|
11498
|
+
const latest = manifest.channels[channel]?.latest ?? null;
|
|
11499
|
+
const outdated = !!(latest && (!active || compareSemver(latest, active) > 0));
|
|
11500
|
+
return { active, latest, pinned: null, outdated };
|
|
11501
|
+
} catch {
|
|
11502
|
+
return { active, latest: null, pinned: null, outdated: false };
|
|
11503
|
+
}
|
|
11452
11504
|
}
|
|
11453
|
-
const install = await installRuntime({
|
|
11454
|
-
version: latestVersion,
|
|
11455
|
-
channel,
|
|
11456
|
-
cdnOrigin,
|
|
11457
|
-
setActive: false
|
|
11458
|
-
});
|
|
11459
11505
|
return {
|
|
11460
|
-
|
|
11461
|
-
|
|
11462
|
-
|
|
11463
|
-
|
|
11464
|
-
|
|
11506
|
+
product,
|
|
11507
|
+
resolveCdnOrigin,
|
|
11508
|
+
resolveChannel,
|
|
11509
|
+
resolvePin,
|
|
11510
|
+
manifestUrl,
|
|
11511
|
+
tarballUrl,
|
|
11512
|
+
fetchManifest,
|
|
11513
|
+
resolveVersion,
|
|
11514
|
+
install,
|
|
11515
|
+
updateToLatest,
|
|
11516
|
+
checkUpToDate,
|
|
11517
|
+
listInstalled: () => listInstalledRuntimes(product)
|
|
11465
11518
|
};
|
|
11466
11519
|
}
|
|
11467
11520
|
async function downloadToFile(url, destPath) {
|
|
@@ -11469,17 +11522,17 @@ async function downloadToFile(url, destPath) {
|
|
|
11469
11522
|
if (!res.ok || !res.body) {
|
|
11470
11523
|
throw new Error(`download failed: ${res.status} ${res.statusText} (${url})`);
|
|
11471
11524
|
}
|
|
11472
|
-
|
|
11525
|
+
import_node_fs4.default.mkdirSync(import_node_path3.default.dirname(destPath), { recursive: true });
|
|
11473
11526
|
const tmp = `${destPath}.partial`;
|
|
11474
11527
|
try {
|
|
11475
11528
|
await (0, import_promises.pipeline)(
|
|
11476
|
-
|
|
11477
|
-
|
|
11529
|
+
import_node_stream.Readable.fromWeb(res.body),
|
|
11530
|
+
import_node_fs4.default.createWriteStream(tmp)
|
|
11478
11531
|
);
|
|
11479
|
-
|
|
11532
|
+
import_node_fs4.default.renameSync(tmp, destPath);
|
|
11480
11533
|
} catch (err) {
|
|
11481
11534
|
try {
|
|
11482
|
-
|
|
11535
|
+
import_node_fs4.default.unlinkSync(tmp);
|
|
11483
11536
|
} catch {
|
|
11484
11537
|
}
|
|
11485
11538
|
throw err;
|
|
@@ -11487,8 +11540,8 @@ async function downloadToFile(url, destPath) {
|
|
|
11487
11540
|
}
|
|
11488
11541
|
function sha256File(filePath) {
|
|
11489
11542
|
return new Promise((resolve5, reject) => {
|
|
11490
|
-
const hash =
|
|
11491
|
-
const stream =
|
|
11543
|
+
const hash = import_node_crypto.default.createHash("sha256");
|
|
11544
|
+
const stream = import_node_fs4.default.createReadStream(filePath);
|
|
11492
11545
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
11493
11546
|
stream.on("error", reject);
|
|
11494
11547
|
stream.on("end", () => resolve5(hash.digest("hex")));
|
|
@@ -11496,7 +11549,7 @@ function sha256File(filePath) {
|
|
|
11496
11549
|
}
|
|
11497
11550
|
function extractTarball(tarPath, destDir) {
|
|
11498
11551
|
return new Promise((resolve5, reject) => {
|
|
11499
|
-
const child = (0,
|
|
11552
|
+
const child = (0, import_node_child_process2.spawn)("tar", ["-xzf", tarPath, "-C", destDir], {
|
|
11500
11553
|
stdio: ["ignore", "inherit", "inherit"]
|
|
11501
11554
|
});
|
|
11502
11555
|
child.on("error", reject);
|
|
@@ -11506,21 +11559,48 @@ function extractTarball(tarPath, destDir) {
|
|
|
11506
11559
|
});
|
|
11507
11560
|
});
|
|
11508
11561
|
}
|
|
11509
|
-
var
|
|
11562
|
+
var import_node_child_process2, import_node_crypto, import_node_fs4, import_node_path3, import_node_stream, import_promises;
|
|
11563
|
+
var init_src = __esm({
|
|
11564
|
+
"../contrast-runtime-delivery/src/index.ts"() {
|
|
11565
|
+
"use strict";
|
|
11566
|
+
import_node_child_process2 = require("node:child_process");
|
|
11567
|
+
import_node_crypto = __toESM(require("node:crypto"), 1);
|
|
11568
|
+
import_node_fs4 = __toESM(require("node:fs"), 1);
|
|
11569
|
+
import_node_path3 = __toESM(require("node:path"), 1);
|
|
11570
|
+
import_node_stream = require("node:stream");
|
|
11571
|
+
import_promises = require("node:stream/promises");
|
|
11572
|
+
init_product();
|
|
11573
|
+
init_product();
|
|
11574
|
+
}
|
|
11575
|
+
});
|
|
11576
|
+
|
|
11577
|
+
// src/runtime-delivery.ts
|
|
11578
|
+
var DEFAULT_RUNTIME_CDN_ORIGIN, SOOTSIM_RUNTIME_PRODUCT, sootsimRuntime;
|
|
11510
11579
|
var init_runtime_delivery = __esm({
|
|
11511
11580
|
"src/runtime-delivery.ts"() {
|
|
11512
11581
|
"use strict";
|
|
11513
|
-
|
|
11514
|
-
import_crypto = __toESM(require("crypto"), 1);
|
|
11515
|
-
import_fs2 = __toESM(require("fs"), 1);
|
|
11516
|
-
import_path2 = __toESM(require("path"), 1);
|
|
11517
|
-
import_stream = require("stream");
|
|
11518
|
-
import_promises = require("stream/promises");
|
|
11582
|
+
init_src();
|
|
11519
11583
|
init_home_paths();
|
|
11520
11584
|
DEFAULT_RUNTIME_CDN_ORIGIN = "https://contrast.dev";
|
|
11521
|
-
|
|
11522
|
-
|
|
11523
|
-
|
|
11585
|
+
SOOTSIM_RUNTIME_PRODUCT = {
|
|
11586
|
+
id: "sootsim",
|
|
11587
|
+
defaultCdnOrigin: DEFAULT_RUNTIME_CDN_ORIGIN,
|
|
11588
|
+
manifestPath: "/runtimes/manifest.json",
|
|
11589
|
+
tarballPath: (version) => `/runtimes/sootsim-runtime-${version}.tar.gz`,
|
|
11590
|
+
env: {
|
|
11591
|
+
cdnOrigin: "SOOTSIM_CDN_ORIGIN",
|
|
11592
|
+
channel: "SOOTSIM_RUNTIME_CHANNEL",
|
|
11593
|
+
pin: "SOOTSIM_RUNTIME_VERSION"
|
|
11594
|
+
},
|
|
11595
|
+
ensureHome: ensureSootsimHome,
|
|
11596
|
+
configFile: configFilePath,
|
|
11597
|
+
runtimesDir,
|
|
11598
|
+
runtimeDir,
|
|
11599
|
+
cacheDir,
|
|
11600
|
+
readActiveRuntime,
|
|
11601
|
+
writeActiveRuntime
|
|
11602
|
+
};
|
|
11603
|
+
sootsimRuntime = createRuntimeDelivery(SOOTSIM_RUNTIME_PRODUCT);
|
|
11524
11604
|
}
|
|
11525
11605
|
});
|
|
11526
11606
|
|
|
@@ -11585,7 +11665,7 @@ function getUserDataDir() {
|
|
|
11585
11665
|
return userDataDir();
|
|
11586
11666
|
}
|
|
11587
11667
|
function storeFile() {
|
|
11588
|
-
return
|
|
11668
|
+
return import_node_path4.default.join(userDataDir(), "attached-projects.json");
|
|
11589
11669
|
}
|
|
11590
11670
|
function cloneEmpty() {
|
|
11591
11671
|
return {
|
|
@@ -11599,7 +11679,7 @@ function loadStore() {
|
|
|
11599
11679
|
const file = storeFile();
|
|
11600
11680
|
let raw;
|
|
11601
11681
|
try {
|
|
11602
|
-
raw =
|
|
11682
|
+
raw = import_node_fs5.default.readFileSync(file, "utf8");
|
|
11603
11683
|
} catch (err) {
|
|
11604
11684
|
if (err.code === "ENOENT") return cloneEmpty();
|
|
11605
11685
|
throw err;
|
|
@@ -11616,7 +11696,7 @@ function loadStore() {
|
|
|
11616
11696
|
} catch (err) {
|
|
11617
11697
|
const quarantine = `${file}.corrupt-${Date.now()}`;
|
|
11618
11698
|
try {
|
|
11619
|
-
|
|
11699
|
+
import_node_fs5.default.renameSync(file, quarantine);
|
|
11620
11700
|
console.warn(
|
|
11621
11701
|
`[sootsim] attached-projects.json was unparseable; quarantined to ${quarantine}. original error: ${err.message}`
|
|
11622
11702
|
);
|
|
@@ -11627,16 +11707,16 @@ function loadStore() {
|
|
|
11627
11707
|
}
|
|
11628
11708
|
function writeStore(store) {
|
|
11629
11709
|
const file = storeFile();
|
|
11630
|
-
|
|
11710
|
+
import_node_fs5.default.mkdirSync(import_node_path4.default.dirname(file), { recursive: true });
|
|
11631
11711
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
11632
|
-
const fd =
|
|
11712
|
+
const fd = import_node_fs5.default.openSync(tmp, "w", 384);
|
|
11633
11713
|
try {
|
|
11634
|
-
|
|
11635
|
-
|
|
11714
|
+
import_node_fs5.default.writeFileSync(fd, JSON.stringify(store, null, 2));
|
|
11715
|
+
import_node_fs5.default.fsyncSync(fd);
|
|
11636
11716
|
} finally {
|
|
11637
|
-
|
|
11717
|
+
import_node_fs5.default.closeSync(fd);
|
|
11638
11718
|
}
|
|
11639
|
-
|
|
11719
|
+
import_node_fs5.default.renameSync(tmp, file);
|
|
11640
11720
|
}
|
|
11641
11721
|
function mutateStore(fn) {
|
|
11642
11722
|
const store = loadStore();
|
|
@@ -11645,13 +11725,13 @@ function mutateStore(fn) {
|
|
|
11645
11725
|
return store;
|
|
11646
11726
|
}
|
|
11647
11727
|
function projectIdForCwd(cwd) {
|
|
11648
|
-
return (0,
|
|
11728
|
+
return (0, import_node_crypto2.createHash)("sha256").update(import_node_path4.default.resolve(cwd)).digest("hex").slice(0, 16);
|
|
11649
11729
|
}
|
|
11650
11730
|
function newSessionId() {
|
|
11651
|
-
return `s_${(0,
|
|
11731
|
+
return `s_${(0, import_node_crypto2.randomBytes)(10).toString("hex")}`;
|
|
11652
11732
|
}
|
|
11653
11733
|
function upsertProject(input) {
|
|
11654
|
-
const cwd =
|
|
11734
|
+
const cwd = import_node_path4.default.resolve(input.cwd);
|
|
11655
11735
|
const id = projectIdForCwd(cwd);
|
|
11656
11736
|
let result;
|
|
11657
11737
|
mutateStore((store) => {
|
|
@@ -11677,7 +11757,7 @@ function upsertProject(input) {
|
|
|
11677
11757
|
const now = Date.now();
|
|
11678
11758
|
const created = {
|
|
11679
11759
|
id,
|
|
11680
|
-
name: input.name ??
|
|
11760
|
+
name: input.name ?? import_node_path4.default.basename(cwd),
|
|
11681
11761
|
cwd,
|
|
11682
11762
|
repoRoot: input.repoRoot,
|
|
11683
11763
|
sourceRoots: input.sourceRoots ?? [cwd],
|
|
@@ -11806,8 +11886,8 @@ async function seedFromDemoAppRegistry() {
|
|
|
11806
11886
|
if (apps.length === 0) return;
|
|
11807
11887
|
mutateStore((store) => {
|
|
11808
11888
|
for (const app of apps) {
|
|
11809
|
-
if (!
|
|
11810
|
-
const cwd =
|
|
11889
|
+
if (!import_node_fs5.default.existsSync(app.dir)) continue;
|
|
11890
|
+
const cwd = import_node_path4.default.resolve(app.dir);
|
|
11811
11891
|
const id = projectIdForCwd(cwd);
|
|
11812
11892
|
if (store.attachedProjects.some((p) => p.id === id)) continue;
|
|
11813
11893
|
const now = Date.now();
|
|
@@ -11828,13 +11908,13 @@ async function seedFromDemoAppRegistry() {
|
|
|
11828
11908
|
}
|
|
11829
11909
|
});
|
|
11830
11910
|
}
|
|
11831
|
-
var
|
|
11911
|
+
var import_node_crypto2, import_node_fs5, import_node_path4, overrideDir, COST_HISTORY_MAX_AGE_MS;
|
|
11832
11912
|
var init_attached_projects = __esm({
|
|
11833
11913
|
"src/attached-projects.ts"() {
|
|
11834
11914
|
"use strict";
|
|
11835
|
-
|
|
11836
|
-
|
|
11837
|
-
|
|
11915
|
+
import_node_crypto2 = require("node:crypto");
|
|
11916
|
+
import_node_fs5 = __toESM(require("node:fs"), 1);
|
|
11917
|
+
import_node_path4 = __toESM(require("node:path"), 1);
|
|
11838
11918
|
init_home_paths();
|
|
11839
11919
|
overrideDir = null;
|
|
11840
11920
|
COST_HISTORY_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
@@ -11843,16 +11923,16 @@ var init_attached_projects = __esm({
|
|
|
11843
11923
|
|
|
11844
11924
|
// src/agent-sessions.ts
|
|
11845
11925
|
function sessionDir(sessionId) {
|
|
11846
|
-
return
|
|
11926
|
+
return import_node_path5.default.join(getUserDataDir(), "sessions", sessionId);
|
|
11847
11927
|
}
|
|
11848
11928
|
function promptFifoPath(sessionId) {
|
|
11849
|
-
return
|
|
11929
|
+
return import_node_path5.default.join(sessionDir(sessionId), "prompt.in");
|
|
11850
11930
|
}
|
|
11851
11931
|
function eventsFifoPath(sessionId) {
|
|
11852
|
-
return
|
|
11932
|
+
return import_node_path5.default.join(sessionDir(sessionId), "events.out");
|
|
11853
11933
|
}
|
|
11854
11934
|
function transcriptPath(sessionId) {
|
|
11855
|
-
return
|
|
11935
|
+
return import_node_path5.default.join(getUserDataDir(), "transcripts", `${sessionId}.log`);
|
|
11856
11936
|
}
|
|
11857
11937
|
function pidIsAlive(pid, sessionId) {
|
|
11858
11938
|
if (!pid) return false;
|
|
@@ -11862,7 +11942,7 @@ function pidIsAlive(pid, sessionId) {
|
|
|
11862
11942
|
return false;
|
|
11863
11943
|
}
|
|
11864
11944
|
if (sessionId) {
|
|
11865
|
-
if (!
|
|
11945
|
+
if (!import_node_fs6.default.existsSync(sessionDir(sessionId))) return false;
|
|
11866
11946
|
}
|
|
11867
11947
|
return true;
|
|
11868
11948
|
}
|
|
@@ -11874,11 +11954,11 @@ function resolveSootsimInvocation() {
|
|
|
11874
11954
|
const resourcesPath = process.resourcesPath;
|
|
11875
11955
|
if (resourcesPath) {
|
|
11876
11956
|
const candidates = [
|
|
11877
|
-
|
|
11878
|
-
|
|
11957
|
+
import_node_path5.default.join(resourcesPath, "bin", "sootsim"),
|
|
11958
|
+
import_node_path5.default.join(resourcesPath, "bin", `sootsim-${process.platform}-${process.arch}`)
|
|
11879
11959
|
];
|
|
11880
11960
|
for (const c of candidates) {
|
|
11881
|
-
if (
|
|
11961
|
+
if (import_node_fs6.default.existsSync(c)) return { cmd: c, prefixArgs: [] };
|
|
11882
11962
|
}
|
|
11883
11963
|
}
|
|
11884
11964
|
}
|
|
@@ -11901,15 +11981,15 @@ function tryWorkspaceSootsim() {
|
|
|
11901
11981
|
const sootsimDir = resolveSootsimPackageDir();
|
|
11902
11982
|
if (!sootsimDir) return null;
|
|
11903
11983
|
const binaryName = `sootsim-${process.platform}-${process.arch}`;
|
|
11904
|
-
const distBinary =
|
|
11905
|
-
if (
|
|
11906
|
-
const distBin =
|
|
11907
|
-
if (
|
|
11984
|
+
const distBinary = import_node_path5.default.join(sootsimDir, "dist-bin", binaryName);
|
|
11985
|
+
if (import_node_fs6.default.existsSync(distBinary)) return { cmd: distBinary, prefixArgs: [] };
|
|
11986
|
+
const distBin = import_node_path5.default.join(sootsimDir, "dist-cli", "bin.js");
|
|
11987
|
+
if (import_node_fs6.default.existsSync(distBin)) {
|
|
11908
11988
|
try {
|
|
11909
|
-
const src =
|
|
11910
|
-
if (
|
|
11911
|
-
const srcMtime =
|
|
11912
|
-
const buildMtime =
|
|
11989
|
+
const src = import_node_path5.default.join(sootsimDir, "cli", "commands", "agent-wrapper.ts");
|
|
11990
|
+
if (import_node_fs6.default.existsSync(src)) {
|
|
11991
|
+
const srcMtime = import_node_fs6.default.statSync(src).mtimeMs;
|
|
11992
|
+
const buildMtime = import_node_fs6.default.statSync(distBin).mtimeMs;
|
|
11913
11993
|
if (buildMtime < srcMtime) {
|
|
11914
11994
|
console.warn(
|
|
11915
11995
|
`[sootsim] dist-cli/bin.js is older than agent-wrapper.ts \u2014 rebuild with \`bun run --cwd packages/sootsim build:cli\`.`
|
|
@@ -11928,22 +12008,22 @@ function tryWorkspaceSootsim() {
|
|
|
11928
12008
|
function resolveSootsimPackageDir() {
|
|
11929
12009
|
try {
|
|
11930
12010
|
const resolved = require.resolve("sootsim/package.json");
|
|
11931
|
-
return
|
|
12011
|
+
return import_node_path5.default.dirname(resolved);
|
|
11932
12012
|
} catch {
|
|
11933
12013
|
}
|
|
11934
12014
|
const here = fileFromImportMeta();
|
|
11935
12015
|
if (!here) return null;
|
|
11936
|
-
let cur =
|
|
12016
|
+
let cur = import_node_path5.default.dirname(here);
|
|
11937
12017
|
for (let i = 0; i < 8; i++) {
|
|
11938
|
-
const pkg =
|
|
12018
|
+
const pkg = import_node_path5.default.join(cur, "package.json");
|
|
11939
12019
|
try {
|
|
11940
|
-
if (
|
|
11941
|
-
const parsed = JSON.parse(
|
|
12020
|
+
if (import_node_fs6.default.existsSync(pkg)) {
|
|
12021
|
+
const parsed = JSON.parse(import_node_fs6.default.readFileSync(pkg, "utf8"));
|
|
11942
12022
|
if (parsed.name === "sootsim") return cur;
|
|
11943
12023
|
}
|
|
11944
12024
|
} catch {
|
|
11945
12025
|
}
|
|
11946
|
-
const parent =
|
|
12026
|
+
const parent = import_node_path5.default.dirname(cur);
|
|
11947
12027
|
if (parent === cur) break;
|
|
11948
12028
|
cur = parent;
|
|
11949
12029
|
}
|
|
@@ -11959,28 +12039,28 @@ function fileFromImportMeta() {
|
|
|
11959
12039
|
}
|
|
11960
12040
|
}
|
|
11961
12041
|
async function withStartLock(projectId, provider, fn) {
|
|
11962
|
-
const lockDir =
|
|
11963
|
-
|
|
12042
|
+
const lockDir = import_node_path5.default.join(getUserDataDir(), "locks");
|
|
12043
|
+
import_node_fs6.default.mkdirSync(lockDir, { recursive: true });
|
|
11964
12044
|
try {
|
|
11965
|
-
|
|
12045
|
+
import_node_fs6.default.chmodSync(lockDir, 448);
|
|
11966
12046
|
} catch {
|
|
11967
12047
|
}
|
|
11968
|
-
const lockPath =
|
|
12048
|
+
const lockPath = import_node_path5.default.join(lockDir, `start-${projectId}-${provider}.lock`);
|
|
11969
12049
|
const deadline = Date.now() + 4e3;
|
|
11970
12050
|
let fd = null;
|
|
11971
12051
|
while (fd === null) {
|
|
11972
12052
|
try {
|
|
11973
|
-
fd =
|
|
12053
|
+
fd = import_node_fs6.default.openSync(
|
|
11974
12054
|
lockPath,
|
|
11975
|
-
|
|
12055
|
+
import_node_fs6.constants.O_WRONLY | import_node_fs6.constants.O_CREAT | import_node_fs6.constants.O_EXCL,
|
|
11976
12056
|
384
|
|
11977
12057
|
);
|
|
11978
12058
|
} catch (err) {
|
|
11979
12059
|
if (err.code !== "EEXIST") throw err;
|
|
11980
12060
|
try {
|
|
11981
|
-
const stale = Number(
|
|
12061
|
+
const stale = Number(import_node_fs6.default.readFileSync(lockPath, "utf8").trim());
|
|
11982
12062
|
if (stale && !isProcessAlive(stale)) {
|
|
11983
|
-
|
|
12063
|
+
import_node_fs6.default.unlinkSync(lockPath);
|
|
11984
12064
|
continue;
|
|
11985
12065
|
}
|
|
11986
12066
|
} catch {
|
|
@@ -11994,15 +12074,15 @@ async function withStartLock(projectId, provider, fn) {
|
|
|
11994
12074
|
}
|
|
11995
12075
|
}
|
|
11996
12076
|
try {
|
|
11997
|
-
|
|
12077
|
+
import_node_fs6.default.writeFileSync(fd, String(process.pid));
|
|
11998
12078
|
return await fn();
|
|
11999
12079
|
} finally {
|
|
12000
12080
|
try {
|
|
12001
|
-
|
|
12081
|
+
import_node_fs6.default.closeSync(fd);
|
|
12002
12082
|
} catch {
|
|
12003
12083
|
}
|
|
12004
12084
|
try {
|
|
12005
|
-
|
|
12085
|
+
import_node_fs6.default.unlinkSync(lockPath);
|
|
12006
12086
|
} catch {
|
|
12007
12087
|
}
|
|
12008
12088
|
}
|
|
@@ -12016,28 +12096,28 @@ function isProcessAlive(pid) {
|
|
|
12016
12096
|
}
|
|
12017
12097
|
}
|
|
12018
12098
|
function mkfifoSync(p) {
|
|
12019
|
-
const parent =
|
|
12020
|
-
|
|
12099
|
+
const parent = import_node_path5.default.dirname(p);
|
|
12100
|
+
import_node_fs6.default.mkdirSync(parent, { recursive: true });
|
|
12021
12101
|
try {
|
|
12022
|
-
|
|
12102
|
+
import_node_fs6.default.chmodSync(parent, 448);
|
|
12023
12103
|
} catch {
|
|
12024
12104
|
}
|
|
12025
|
-
if (
|
|
12105
|
+
if (import_node_fs6.default.existsSync(p)) {
|
|
12026
12106
|
try {
|
|
12027
|
-
const stat =
|
|
12107
|
+
const stat = import_node_fs6.default.statSync(p);
|
|
12028
12108
|
if (stat.isFIFO()) {
|
|
12029
12109
|
try {
|
|
12030
|
-
|
|
12110
|
+
import_node_fs6.default.chmodSync(p, 384);
|
|
12031
12111
|
} catch {
|
|
12032
12112
|
}
|
|
12033
12113
|
return;
|
|
12034
12114
|
}
|
|
12035
|
-
|
|
12115
|
+
import_node_fs6.default.unlinkSync(p);
|
|
12036
12116
|
} catch {
|
|
12037
|
-
|
|
12117
|
+
import_node_fs6.default.unlinkSync(p);
|
|
12038
12118
|
}
|
|
12039
12119
|
}
|
|
12040
|
-
const result = (0,
|
|
12120
|
+
const result = (0, import_node_child_process3.spawnSync)("mkfifo", ["-m", "600", p]);
|
|
12041
12121
|
if (result.status !== 0) {
|
|
12042
12122
|
throw new Error(
|
|
12043
12123
|
`mkfifo(${p}) failed: ${result.stderr?.toString().trim() || "unknown error"}`
|
|
@@ -12060,7 +12140,7 @@ async function startSession(opts) {
|
|
|
12060
12140
|
`session already running for project=${project.id} provider=${provider} (session ${existingLive.id}, pid ${existingLive.wrapperPid}). end it first with \`sootsim agent end <sessionId>\`.`
|
|
12061
12141
|
);
|
|
12062
12142
|
}
|
|
12063
|
-
const claudeSessionUuid = provider === "claude" ? (0,
|
|
12143
|
+
const claudeSessionUuid = provider === "claude" ? (0, import_node_crypto3.randomUUID)() : void 0;
|
|
12064
12144
|
const session = upsertSession({
|
|
12065
12145
|
projectId: project.id,
|
|
12066
12146
|
provider,
|
|
@@ -12074,10 +12154,10 @@ async function startSession(opts) {
|
|
|
12074
12154
|
const transcript = transcriptPath(session.id);
|
|
12075
12155
|
mkfifoSync(promptIn);
|
|
12076
12156
|
mkfifoSync(eventsOut);
|
|
12077
|
-
const transcriptDir =
|
|
12078
|
-
|
|
12157
|
+
const transcriptDir = import_node_path5.default.dirname(transcript);
|
|
12158
|
+
import_node_fs6.default.mkdirSync(transcriptDir, { recursive: true });
|
|
12079
12159
|
try {
|
|
12080
|
-
|
|
12160
|
+
import_node_fs6.default.chmodSync(transcriptDir, 448);
|
|
12081
12161
|
} catch {
|
|
12082
12162
|
}
|
|
12083
12163
|
const { cmd, prefixArgs } = resolveSootsimInvocation();
|
|
@@ -12105,7 +12185,7 @@ async function startSession(opts) {
|
|
|
12105
12185
|
if (claudeSessionUuid) {
|
|
12106
12186
|
wrapperArgs.push("--claude-session-uuid", claudeSessionUuid);
|
|
12107
12187
|
}
|
|
12108
|
-
const child = (0,
|
|
12188
|
+
const child = (0, import_node_child_process3.spawn)(cmd, wrapperArgs, {
|
|
12109
12189
|
detached: true,
|
|
12110
12190
|
stdio: "ignore",
|
|
12111
12191
|
env: {
|
|
@@ -12128,7 +12208,7 @@ async function startSession(opts) {
|
|
|
12128
12208
|
}
|
|
12129
12209
|
}
|
|
12130
12210
|
try {
|
|
12131
|
-
|
|
12211
|
+
import_node_fs6.default.rmSync(sessionDir(session.id), { recursive: true, force: true });
|
|
12132
12212
|
} catch {
|
|
12133
12213
|
}
|
|
12134
12214
|
updateSessionStatus(session.id, { status: "ended" });
|
|
@@ -12156,18 +12236,18 @@ async function sendPrompt(sessionId, prompt) {
|
|
|
12156
12236
|
);
|
|
12157
12237
|
}
|
|
12158
12238
|
const fifo = promptFifoPath(sessionId);
|
|
12159
|
-
if (!
|
|
12239
|
+
if (!import_node_fs6.default.existsSync(fifo)) {
|
|
12160
12240
|
throw new AgentSessionError("NO_FIFO", `prompt FIFO missing: ${fifo}`);
|
|
12161
12241
|
}
|
|
12162
|
-
const fd =
|
|
12242
|
+
const fd = import_node_fs6.default.openSync(fifo, import_node_fs6.constants.O_WRONLY);
|
|
12163
12243
|
try {
|
|
12164
12244
|
const wireText = encodeAgentPromptEnvelope(prompt);
|
|
12165
12245
|
if (!wireText) {
|
|
12166
12246
|
throw new AgentSessionError("EMPTY_PROMPT", "prompt text is empty");
|
|
12167
12247
|
}
|
|
12168
|
-
|
|
12248
|
+
import_node_fs6.default.writeSync(fd, wireText + "\n");
|
|
12169
12249
|
} finally {
|
|
12170
|
-
|
|
12250
|
+
import_node_fs6.default.closeSync(fd);
|
|
12171
12251
|
}
|
|
12172
12252
|
updateSessionStatus(sessionId, {
|
|
12173
12253
|
lastPrompt: prompt.displayText ?? prompt.text,
|
|
@@ -12189,7 +12269,7 @@ async function endSession(sessionId) {
|
|
|
12189
12269
|
const base = getUserDataDir();
|
|
12190
12270
|
if (dir.startsWith(base)) {
|
|
12191
12271
|
try {
|
|
12192
|
-
|
|
12272
|
+
import_node_fs6.default.rmSync(dir, { recursive: true, force: true });
|
|
12193
12273
|
} catch {
|
|
12194
12274
|
}
|
|
12195
12275
|
}
|
|
@@ -12197,11 +12277,11 @@ async function endSession(sessionId) {
|
|
|
12197
12277
|
}
|
|
12198
12278
|
function subscribeEvents(sessionId, onEvent) {
|
|
12199
12279
|
const fifo = eventsFifoPath(sessionId);
|
|
12200
|
-
if (!
|
|
12280
|
+
if (!import_node_fs6.default.existsSync(fifo)) {
|
|
12201
12281
|
throw new AgentSessionError("NO_FIFO", `events FIFO missing: ${fifo}`);
|
|
12202
12282
|
}
|
|
12203
|
-
const fd =
|
|
12204
|
-
const stream =
|
|
12283
|
+
const fd = import_node_fs6.default.openSync(fifo, import_node_fs6.constants.O_RDWR);
|
|
12284
|
+
const stream = import_node_fs6.default.createReadStream("", { fd, autoClose: true });
|
|
12205
12285
|
const rl = import_node_readline.default.createInterface({ input: stream, crlfDelay: Infinity });
|
|
12206
12286
|
rl.on("line", (line) => {
|
|
12207
12287
|
const event = parseAgentEventLine(line);
|
|
@@ -12222,7 +12302,7 @@ function subscribeEvents(sessionId, onEvent) {
|
|
|
12222
12302
|
};
|
|
12223
12303
|
}
|
|
12224
12304
|
async function waitForFirstEvent(fifo, predicate, timeoutMs) {
|
|
12225
|
-
const fd =
|
|
12305
|
+
const fd = import_node_fs6.default.openSync(fifo, import_node_fs6.constants.O_RDWR | import_node_fs6.constants.O_NONBLOCK);
|
|
12226
12306
|
const buf = Buffer.alloc(8192);
|
|
12227
12307
|
let leftover = "";
|
|
12228
12308
|
const deadline = Date.now() + timeoutMs;
|
|
@@ -12230,7 +12310,7 @@ async function waitForFirstEvent(fifo, predicate, timeoutMs) {
|
|
|
12230
12310
|
while (Date.now() < deadline) {
|
|
12231
12311
|
let n = 0;
|
|
12232
12312
|
try {
|
|
12233
|
-
n =
|
|
12313
|
+
n = import_node_fs6.default.readSync(fd, buf, 0, buf.length, null);
|
|
12234
12314
|
} catch (err) {
|
|
12235
12315
|
if (err.code !== "EAGAIN") throw err;
|
|
12236
12316
|
n = 0;
|
|
@@ -12250,17 +12330,17 @@ async function waitForFirstEvent(fifo, predicate, timeoutMs) {
|
|
|
12250
12330
|
}
|
|
12251
12331
|
return null;
|
|
12252
12332
|
} finally {
|
|
12253
|
-
|
|
12333
|
+
import_node_fs6.default.closeSync(fd);
|
|
12254
12334
|
}
|
|
12255
12335
|
}
|
|
12256
|
-
var
|
|
12336
|
+
var import_node_child_process3, import_node_crypto3, import_node_fs6, import_node_path5, import_node_readline, AgentSessionError;
|
|
12257
12337
|
var init_agent_sessions = __esm({
|
|
12258
12338
|
"src/agent-sessions.ts"() {
|
|
12259
12339
|
"use strict";
|
|
12260
|
-
|
|
12261
|
-
|
|
12262
|
-
|
|
12263
|
-
|
|
12340
|
+
import_node_child_process3 = require("node:child_process");
|
|
12341
|
+
import_node_crypto3 = require("node:crypto");
|
|
12342
|
+
import_node_fs6 = __toESM(require("node:fs"), 1);
|
|
12343
|
+
import_node_path5 = __toESM(require("node:path"), 1);
|
|
12264
12344
|
import_node_readline = __toESM(require("node:readline"), 1);
|
|
12265
12345
|
init_agent_events();
|
|
12266
12346
|
init_agent_prompt();
|
|
@@ -12302,8 +12382,8 @@ function resolveAgentbusCommand(explicit) {
|
|
|
12302
12382
|
if (fromArg) return fromArg;
|
|
12303
12383
|
const fromEnv = process.env.AGENTBUS_COMMAND?.trim();
|
|
12304
12384
|
if (fromEnv) return fromEnv;
|
|
12305
|
-
const localBin =
|
|
12306
|
-
if (
|
|
12385
|
+
const localBin = import_node_path6.default.join(import_node_os2.default.homedir(), ".local", "bin", "agentbus");
|
|
12386
|
+
if (import_node_fs7.default.existsSync(localBin)) return localBin;
|
|
12307
12387
|
return "agentbus";
|
|
12308
12388
|
}
|
|
12309
12389
|
async function sendPromptToAgentbusSession(input) {
|
|
@@ -12318,7 +12398,7 @@ async function sendPromptToAgentbusSession(input) {
|
|
|
12318
12398
|
const command = resolveAgentbusCommand(input.command);
|
|
12319
12399
|
const timeoutMs = input.timeoutMs ?? 15e3;
|
|
12320
12400
|
await new Promise((resolve5, reject) => {
|
|
12321
|
-
const child = (0,
|
|
12401
|
+
const child = (0, import_node_child_process4.spawn)(command, ["send", sessionId, text], {
|
|
12322
12402
|
stdio: ["ignore", "ignore", "pipe"],
|
|
12323
12403
|
env: process.env
|
|
12324
12404
|
});
|
|
@@ -12353,14 +12433,14 @@ async function sendPromptToAgentbusSession(input) {
|
|
|
12353
12433
|
});
|
|
12354
12434
|
});
|
|
12355
12435
|
}
|
|
12356
|
-
var
|
|
12436
|
+
var import_node_child_process4, import_node_fs7, import_node_os2, import_node_path6;
|
|
12357
12437
|
var init_agentbus_prompt = __esm({
|
|
12358
12438
|
"src/agentbus-prompt.ts"() {
|
|
12359
12439
|
"use strict";
|
|
12360
|
-
|
|
12361
|
-
|
|
12440
|
+
import_node_child_process4 = require("node:child_process");
|
|
12441
|
+
import_node_fs7 = __toESM(require("node:fs"), 1);
|
|
12362
12442
|
import_node_os2 = __toESM(require("node:os"), 1);
|
|
12363
|
-
|
|
12443
|
+
import_node_path6 = __toESM(require("node:path"), 1);
|
|
12364
12444
|
init_agent_identity();
|
|
12365
12445
|
init_agent_identity();
|
|
12366
12446
|
}
|
|
@@ -12379,12 +12459,12 @@ function mapFrameworkToProjectFramework(fw) {
|
|
|
12379
12459
|
if (fw === "one" || fw === "vxrn") return "one";
|
|
12380
12460
|
return "unknown";
|
|
12381
12461
|
}
|
|
12382
|
-
var
|
|
12462
|
+
var import_node_fs8, import_node_path7, WS_OPEN, AgentHost;
|
|
12383
12463
|
var init_agent_host = __esm({
|
|
12384
12464
|
"src/host/agent-host.ts"() {
|
|
12385
12465
|
"use strict";
|
|
12386
|
-
|
|
12387
|
-
|
|
12466
|
+
import_node_fs8 = __toESM(require("node:fs"), 1);
|
|
12467
|
+
import_node_path7 = __toESM(require("node:path"), 1);
|
|
12388
12468
|
init_dev_server_scanner();
|
|
12389
12469
|
init_agent_sessions();
|
|
12390
12470
|
init_agentbus_prompt();
|
|
@@ -12571,7 +12651,7 @@ var init_agent_host = __esm({
|
|
|
12571
12651
|
);
|
|
12572
12652
|
const project = upsertProject({
|
|
12573
12653
|
cwd: match.cwd,
|
|
12574
|
-
name: match.projectName ??
|
|
12654
|
+
name: match.projectName ?? import_node_path7.default.basename(match.cwd),
|
|
12575
12655
|
preferredProvider: input.provider ?? existing?.preferredProvider,
|
|
12576
12656
|
sourceRoots: existing?.sourceRoots ?? [match.cwd],
|
|
12577
12657
|
knownBundleUrls,
|
|
@@ -12582,18 +12662,18 @@ var init_agent_host = __esm({
|
|
|
12582
12662
|
}
|
|
12583
12663
|
getTranscript(sessionId) {
|
|
12584
12664
|
const p = transcriptPath(sessionId);
|
|
12585
|
-
if (!
|
|
12665
|
+
if (!import_node_fs8.default.existsSync(p)) {
|
|
12586
12666
|
return { error: "transcript not found", code: "NO_TRANSCRIPT" };
|
|
12587
12667
|
}
|
|
12588
|
-
return
|
|
12668
|
+
return import_node_fs8.default.readFileSync(p, "utf8");
|
|
12589
12669
|
}
|
|
12590
12670
|
getPaths() {
|
|
12591
12671
|
const dir = getUserDataDir();
|
|
12592
12672
|
return {
|
|
12593
12673
|
userDataDir: dir,
|
|
12594
|
-
storeFile:
|
|
12595
|
-
sessionsDir:
|
|
12596
|
-
transcriptsDir:
|
|
12674
|
+
storeFile: import_node_path7.default.join(dir, "attached-projects.json"),
|
|
12675
|
+
sessionsDir: import_node_path7.default.join(dir, "sessions"),
|
|
12676
|
+
transcriptsDir: import_node_path7.default.join(dir, "transcripts")
|
|
12597
12677
|
};
|
|
12598
12678
|
}
|
|
12599
12679
|
// --- subscription management ---
|
|
@@ -13193,19 +13273,19 @@ var init_fetch_proxy_handler = __esm({
|
|
|
13193
13273
|
|
|
13194
13274
|
// src/host/open-url.ts
|
|
13195
13275
|
function expandHome(candidate) {
|
|
13196
|
-
return candidate.startsWith("~/") ? (0,
|
|
13276
|
+
return candidate.startsWith("~/") ? (0, import_path2.join)((0, import_os.homedir)(), candidate.slice(2)) : candidate;
|
|
13197
13277
|
}
|
|
13198
13278
|
function firstExisting(candidates) {
|
|
13199
13279
|
for (const candidate of candidates) {
|
|
13200
13280
|
const expanded = expandHome(candidate);
|
|
13201
|
-
if ((0,
|
|
13281
|
+
if ((0, import_fs2.existsSync)(expanded)) return expanded;
|
|
13202
13282
|
}
|
|
13203
13283
|
return null;
|
|
13204
13284
|
}
|
|
13205
13285
|
function lookupExecutable(command, platform) {
|
|
13206
13286
|
try {
|
|
13207
13287
|
const tool = platform === "win32" ? "where" : "which";
|
|
13208
|
-
const out = (0,
|
|
13288
|
+
const out = (0, import_child_process2.execFileSync)(tool, [command], {
|
|
13209
13289
|
encoding: "utf8",
|
|
13210
13290
|
timeout: 1500,
|
|
13211
13291
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -13217,7 +13297,7 @@ function lookupExecutable(command, platform) {
|
|
|
13217
13297
|
}
|
|
13218
13298
|
function resolveChromiumBinary(platform = process.platform) {
|
|
13219
13299
|
const envCandidate = process.env.CHROME_PATH || process.env.CHROMIUM_PATH;
|
|
13220
|
-
if (envCandidate && (0,
|
|
13300
|
+
if (envCandidate && (0, import_fs2.existsSync)(envCandidate)) return envCandidate;
|
|
13221
13301
|
const direct = platform === "darwin" ? firstExisting(MAC_CHROMIUM_CANDIDATES) : platform === "win32" ? firstExisting(WINDOWS_CHROMIUM_CANDIDATES) : firstExisting(LINUX_CHROMIUM_CANDIDATES);
|
|
13222
13302
|
if (direct) return direct;
|
|
13223
13303
|
const commands = platform === "win32" ? WINDOWS_CHROMIUM_COMMANDS : UNIX_CHROMIUM_COMMANDS;
|
|
@@ -13274,7 +13354,7 @@ function buildChromiumUrlCommand(url, options = {}) {
|
|
|
13274
13354
|
}
|
|
13275
13355
|
async function spawnLaunch(command, args, detached) {
|
|
13276
13356
|
return new Promise((resolve5, reject) => {
|
|
13277
|
-
const child = (0,
|
|
13357
|
+
const child = (0, import_child_process2.spawn)(command, args, {
|
|
13278
13358
|
detached,
|
|
13279
13359
|
stdio: "ignore"
|
|
13280
13360
|
});
|
|
@@ -13297,14 +13377,14 @@ async function launchUrl(url, options = {}) {
|
|
|
13297
13377
|
async function openUrl(url, options = {}) {
|
|
13298
13378
|
await launchUrl(url, options);
|
|
13299
13379
|
}
|
|
13300
|
-
var
|
|
13380
|
+
var import_child_process2, import_fs2, import_os, import_path2, MAC_CHROMIUM_CANDIDATES, LINUX_CHROMIUM_CANDIDATES, WINDOWS_CHROMIUM_CANDIDATES, UNIX_CHROMIUM_COMMANDS, WINDOWS_CHROMIUM_COMMANDS;
|
|
13301
13381
|
var init_open_url = __esm({
|
|
13302
13382
|
"src/host/open-url.ts"() {
|
|
13303
13383
|
"use strict";
|
|
13304
|
-
|
|
13305
|
-
|
|
13384
|
+
import_child_process2 = require("child_process");
|
|
13385
|
+
import_fs2 = require("fs");
|
|
13306
13386
|
import_os = require("os");
|
|
13307
|
-
|
|
13387
|
+
import_path2 = require("path");
|
|
13308
13388
|
MAC_CHROMIUM_CANDIDATES = [
|
|
13309
13389
|
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
13310
13390
|
"~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
@@ -13566,14 +13646,14 @@ function unrefTimer(timer) {
|
|
|
13566
13646
|
timer.unref();
|
|
13567
13647
|
}
|
|
13568
13648
|
}
|
|
13569
|
-
var
|
|
13649
|
+
var import_child_process3, import_fs3, import_http3, import_path3, 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;
|
|
13570
13650
|
var init_bridge_host = __esm({
|
|
13571
13651
|
"src/host/bridge-host.ts"() {
|
|
13572
13652
|
"use strict";
|
|
13573
|
-
|
|
13574
|
-
|
|
13653
|
+
import_child_process3 = require("child_process");
|
|
13654
|
+
import_fs3 = __toESM(require("fs"), 1);
|
|
13575
13655
|
import_http3 = require("http");
|
|
13576
|
-
|
|
13656
|
+
import_path3 = __toESM(require("path"), 1);
|
|
13577
13657
|
import_ws2 = require("ws");
|
|
13578
13658
|
init_dev_server_scanner();
|
|
13579
13659
|
init_bridge_constants();
|
|
@@ -13865,7 +13945,7 @@ var init_bridge_host = __esm({
|
|
|
13865
13945
|
return;
|
|
13866
13946
|
}
|
|
13867
13947
|
if (msg.type === "runtime:list") {
|
|
13868
|
-
const versions =
|
|
13948
|
+
const versions = sootsimRuntime.listInstalled();
|
|
13869
13949
|
const active = this.getActiveRuntime();
|
|
13870
13950
|
const reply = {
|
|
13871
13951
|
type: "runtime:list:ok",
|
|
@@ -13882,7 +13962,7 @@ var init_bridge_host = __esm({
|
|
|
13882
13962
|
}
|
|
13883
13963
|
if (msg.type === "runtime:use") {
|
|
13884
13964
|
const version = typeof msg.version === "string" ? msg.version : "";
|
|
13885
|
-
const installed2 =
|
|
13965
|
+
const installed2 = sootsimRuntime.listInstalled();
|
|
13886
13966
|
if (!installed2.includes(version)) {
|
|
13887
13967
|
try {
|
|
13888
13968
|
ws.send(
|
|
@@ -14411,7 +14491,7 @@ var init_bridge_host = __esm({
|
|
|
14411
14491
|
if (reason === "startup") {
|
|
14412
14492
|
process.stderr.write("sootsim: checking for runtime updates\u2026\n");
|
|
14413
14493
|
}
|
|
14414
|
-
const result = await
|
|
14494
|
+
const result = await sootsimRuntime.updateToLatest();
|
|
14415
14495
|
if (!result.updated || !result.latestVersion) {
|
|
14416
14496
|
if (reason === "startup") {
|
|
14417
14497
|
process.stderr.write(
|
|
@@ -14647,34 +14727,34 @@ var init_bridge_host = __esm({
|
|
|
14647
14727
|
return;
|
|
14648
14728
|
}
|
|
14649
14729
|
}
|
|
14650
|
-
const resolved =
|
|
14651
|
-
const baseWithSep = baseDir.endsWith(
|
|
14730
|
+
const resolved = import_path3.default.resolve(baseDir, "." + rel);
|
|
14731
|
+
const baseWithSep = baseDir.endsWith(import_path3.default.sep) ? baseDir : baseDir + import_path3.default.sep;
|
|
14652
14732
|
if (!resolved.startsWith(baseWithSep) && resolved !== baseDir) {
|
|
14653
14733
|
res.writeHead(403);
|
|
14654
14734
|
res.end("forbidden");
|
|
14655
14735
|
return;
|
|
14656
14736
|
}
|
|
14657
|
-
|
|
14737
|
+
import_fs3.default.realpath(resolved, (realErr, realResolved) => {
|
|
14658
14738
|
const servePath = realErr ? resolved : realResolved;
|
|
14659
|
-
const servePathWithSep = servePath.endsWith(
|
|
14739
|
+
const servePathWithSep = servePath.endsWith(import_path3.default.sep) ? servePath : servePath + import_path3.default.sep;
|
|
14660
14740
|
if (!realErr) {
|
|
14661
14741
|
const realBaseWithSep = (() => {
|
|
14662
14742
|
try {
|
|
14663
|
-
const rb =
|
|
14664
|
-
return rb.endsWith(
|
|
14743
|
+
const rb = import_fs3.default.realpathSync(baseDir);
|
|
14744
|
+
return rb.endsWith(import_path3.default.sep) ? rb : rb + import_path3.default.sep;
|
|
14665
14745
|
} catch {
|
|
14666
14746
|
return baseWithSep;
|
|
14667
14747
|
}
|
|
14668
14748
|
})();
|
|
14669
|
-
if (!servePathWithSep.startsWith(realBaseWithSep) && servePath +
|
|
14749
|
+
if (!servePathWithSep.startsWith(realBaseWithSep) && servePath + import_path3.default.sep !== realBaseWithSep) {
|
|
14670
14750
|
res.writeHead(403);
|
|
14671
14751
|
res.end("forbidden");
|
|
14672
14752
|
return;
|
|
14673
14753
|
}
|
|
14674
14754
|
}
|
|
14675
|
-
|
|
14755
|
+
import_fs3.default.stat(servePath, (err, stats) => {
|
|
14676
14756
|
if (err || !stats?.isFile()) {
|
|
14677
|
-
const ext2 =
|
|
14757
|
+
const ext2 = import_path3.default.extname(rel).toLowerCase();
|
|
14678
14758
|
if (ext2 && ext2 !== ".html") {
|
|
14679
14759
|
res.writeHead(404);
|
|
14680
14760
|
res.end("not found");
|
|
@@ -14685,8 +14765,8 @@ var init_bridge_host = __esm({
|
|
|
14685
14765
|
res.end("not found");
|
|
14686
14766
|
return;
|
|
14687
14767
|
}
|
|
14688
|
-
const indexPath =
|
|
14689
|
-
|
|
14768
|
+
const indexPath = import_path3.default.join(baseDir, "index.html");
|
|
14769
|
+
import_fs3.default.readFile(indexPath, (err2, data) => {
|
|
14690
14770
|
if (err2) {
|
|
14691
14771
|
res.writeHead(404);
|
|
14692
14772
|
res.end("not found");
|
|
@@ -14706,7 +14786,7 @@ var init_bridge_host = __esm({
|
|
|
14706
14786
|
});
|
|
14707
14787
|
return;
|
|
14708
14788
|
}
|
|
14709
|
-
const ext =
|
|
14789
|
+
const ext = import_path3.default.extname(servePath).toLowerCase();
|
|
14710
14790
|
const contentType = HTTP_MIME_TYPES[ext] || "application/octet-stream";
|
|
14711
14791
|
res.writeHead(200, {
|
|
14712
14792
|
"Content-Type": contentType,
|
|
@@ -14717,7 +14797,7 @@ var init_bridge_host = __esm({
|
|
|
14717
14797
|
return;
|
|
14718
14798
|
}
|
|
14719
14799
|
if (ext === ".html") {
|
|
14720
|
-
|
|
14800
|
+
import_fs3.default.readFile(servePath, (readErr, data) => {
|
|
14721
14801
|
if (readErr) {
|
|
14722
14802
|
try {
|
|
14723
14803
|
res.end();
|
|
@@ -14731,7 +14811,7 @@ var init_bridge_host = __esm({
|
|
|
14731
14811
|
});
|
|
14732
14812
|
return;
|
|
14733
14813
|
}
|
|
14734
|
-
const stream =
|
|
14814
|
+
const stream = import_fs3.default.createReadStream(servePath);
|
|
14735
14815
|
stream.pipe(res);
|
|
14736
14816
|
stream.on("error", () => {
|
|
14737
14817
|
try {
|
|
@@ -14937,7 +15017,7 @@ var init_bridge_host = __esm({
|
|
|
14937
15017
|
const target = `${filePath}${loc}`;
|
|
14938
15018
|
const trySpawn = (cmd, args) => new Promise((resolve5) => {
|
|
14939
15019
|
try {
|
|
14940
|
-
const child = (0,
|
|
15020
|
+
const child = (0, import_child_process3.spawn)(cmd, args, { detached: true, stdio: "ignore" });
|
|
14941
15021
|
let settled = false;
|
|
14942
15022
|
child.on("error", () => {
|
|
14943
15023
|
if (settled) return;
|
|
@@ -15439,7 +15519,7 @@ function buildComm() {
|
|
|
15439
15519
|
if (process.platform === "linux") {
|
|
15440
15520
|
return (pid) => {
|
|
15441
15521
|
try {
|
|
15442
|
-
return (0,
|
|
15522
|
+
return (0, import_fs4.readFileSync)(`/proc/${pid}/comm`, "utf8").trim() || null;
|
|
15443
15523
|
} catch {
|
|
15444
15524
|
return null;
|
|
15445
15525
|
}
|
|
@@ -15468,7 +15548,7 @@ function build() {
|
|
|
15468
15548
|
function buildLinux() {
|
|
15469
15549
|
return (pid) => {
|
|
15470
15550
|
try {
|
|
15471
|
-
const raw = (0,
|
|
15551
|
+
const raw = (0, import_fs4.readFileSync)(`/proc/${pid}/stat`, "utf8");
|
|
15472
15552
|
const end = raw.lastIndexOf(")");
|
|
15473
15553
|
if (end < 0) return null;
|
|
15474
15554
|
const rest = raw.slice(end + 1).trim().split(/\s+/);
|
|
@@ -15532,7 +15612,7 @@ function tryBuildDarwinCommFfi() {
|
|
|
15532
15612
|
function buildDarwinLsofComm() {
|
|
15533
15613
|
return (pid) => {
|
|
15534
15614
|
try {
|
|
15535
|
-
const out = (0,
|
|
15615
|
+
const out = (0, import_child_process4.execFileSync)("lsof", ["-R", "-p", String(pid), "-d", "cwd", "-a"], {
|
|
15536
15616
|
encoding: "utf8",
|
|
15537
15617
|
timeout: 2e3,
|
|
15538
15618
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -15549,7 +15629,7 @@ function buildDarwinLsofComm() {
|
|
|
15549
15629
|
function buildDarwinLsof() {
|
|
15550
15630
|
return (pid) => {
|
|
15551
15631
|
try {
|
|
15552
|
-
const out = (0,
|
|
15632
|
+
const out = (0, import_child_process4.execFileSync)("lsof", ["-R", "-p", String(pid), "-d", "cwd", "-a"], {
|
|
15553
15633
|
encoding: "utf8",
|
|
15554
15634
|
timeout: 2e3,
|
|
15555
15635
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -15564,12 +15644,12 @@ function buildDarwinLsof() {
|
|
|
15564
15644
|
}
|
|
15565
15645
|
};
|
|
15566
15646
|
}
|
|
15567
|
-
var
|
|
15647
|
+
var import_child_process4, import_fs4, import_module, cached3, cachedComm, PROC_PIDTBSDINFO, PROC_BSDINFO_SIZE, PBI_PPID_OFFSET, PBI_COMM_OFFSET, PBI_COMM_LEN;
|
|
15568
15648
|
var init_parent_pid = __esm({
|
|
15569
15649
|
"cli/parent-pid.ts"() {
|
|
15570
15650
|
"use strict";
|
|
15571
|
-
|
|
15572
|
-
|
|
15651
|
+
import_child_process4 = require("child_process");
|
|
15652
|
+
import_fs4 = require("fs");
|
|
15573
15653
|
import_module = require("module");
|
|
15574
15654
|
cached3 = null;
|
|
15575
15655
|
cachedComm = null;
|
|
@@ -15614,18 +15694,18 @@ function getCliIdentityKey() {
|
|
|
15614
15694
|
}
|
|
15615
15695
|
function getCurrentSimPath() {
|
|
15616
15696
|
if (process.env[CURRENT_SIM_PATH_ENV]) {
|
|
15617
|
-
return (0,
|
|
15697
|
+
return (0, import_path4.resolve)(process.env[CURRENT_SIM_PATH_ENV]);
|
|
15618
15698
|
}
|
|
15619
15699
|
const key = getCliIdentityKey();
|
|
15620
|
-
return (0,
|
|
15700
|
+
return (0, import_path4.join)((0, import_os2.tmpdir)(), `sootsim-current-sim-${key}.json`);
|
|
15621
15701
|
}
|
|
15622
15702
|
function readCurrentSim() {
|
|
15623
15703
|
const filepath = getCurrentSimPath();
|
|
15624
|
-
if (!(0,
|
|
15704
|
+
if (!(0, import_fs5.existsSync)(filepath)) return null;
|
|
15625
15705
|
try {
|
|
15626
|
-
const parsed = JSON.parse((0,
|
|
15706
|
+
const parsed = JSON.parse((0, import_fs5.readFileSync)(filepath, "utf8"));
|
|
15627
15707
|
if (parsed.version !== CURRENT_SIM_VERSION || typeof parsed.simId !== "string" || !parsed.simId.trim() || typeof parsed.updatedAt !== "string") {
|
|
15628
|
-
(0,
|
|
15708
|
+
(0, import_fs5.rmSync)(filepath, { force: true });
|
|
15629
15709
|
return null;
|
|
15630
15710
|
}
|
|
15631
15711
|
return {
|
|
@@ -15634,7 +15714,7 @@ function readCurrentSim() {
|
|
|
15634
15714
|
updatedAt: parsed.updatedAt
|
|
15635
15715
|
};
|
|
15636
15716
|
} catch {
|
|
15637
|
-
(0,
|
|
15717
|
+
(0, import_fs5.rmSync)(filepath, { force: true });
|
|
15638
15718
|
return null;
|
|
15639
15719
|
}
|
|
15640
15720
|
}
|
|
@@ -15642,15 +15722,15 @@ function readCurrentSimId() {
|
|
|
15642
15722
|
return readCurrentSim()?.simId || null;
|
|
15643
15723
|
}
|
|
15644
15724
|
function clearCurrentSimId() {
|
|
15645
|
-
(0,
|
|
15725
|
+
(0, import_fs5.rmSync)(getCurrentSimPath(), { force: true });
|
|
15646
15726
|
}
|
|
15647
|
-
var
|
|
15727
|
+
var import_fs5, import_os2, import_path4, CURRENT_SIM_VERSION, CURRENT_SIM_PATH_ENV, IDENTITY_ENV_VARS, IMMORTAL_HOST_COMM_RE;
|
|
15648
15728
|
var init_current_sim = __esm({
|
|
15649
15729
|
"cli/current-sim.ts"() {
|
|
15650
15730
|
"use strict";
|
|
15651
|
-
|
|
15731
|
+
import_fs5 = require("fs");
|
|
15652
15732
|
import_os2 = require("os");
|
|
15653
|
-
|
|
15733
|
+
import_path4 = require("path");
|
|
15654
15734
|
init_parent_pid();
|
|
15655
15735
|
CURRENT_SIM_VERSION = 1;
|
|
15656
15736
|
CURRENT_SIM_PATH_ENV = "SOOTSIM_CLI_CURRENT_SIM_PATH";
|
|
@@ -16091,11 +16171,11 @@ async function evalInBridge(bridge, code, opts = {}) {
|
|
|
16091
16171
|
if (opts.acquireLock) payload.acquireLock = true;
|
|
16092
16172
|
return bridge.send(payload);
|
|
16093
16173
|
}
|
|
16094
|
-
async function callInBridge(bridge,
|
|
16095
|
-
return bridge.send({ type: "call", path:
|
|
16174
|
+
async function callInBridge(bridge, path12, ...args) {
|
|
16175
|
+
return bridge.send({ type: "call", path: path12, args });
|
|
16096
16176
|
}
|
|
16097
|
-
async function callInBridgeWrite(bridge,
|
|
16098
|
-
return bridge.send({ type: "call", path:
|
|
16177
|
+
async function callInBridgeWrite(bridge, path12, ...args) {
|
|
16178
|
+
return bridge.send({ type: "call", path: path12, args, acquireLock: true });
|
|
16099
16179
|
}
|
|
16100
16180
|
var import_ws3, resolvedWorld, BridgeSimLockedError;
|
|
16101
16181
|
var init_ws_bridge = __esm({
|
|
@@ -17091,7 +17171,7 @@ function executeSyncHttp(url, method, params) {
|
|
|
17091
17171
|
delete childEnv[key];
|
|
17092
17172
|
}
|
|
17093
17173
|
}
|
|
17094
|
-
const child = (0,
|
|
17174
|
+
const child = (0, import_child_process5.spawnSync)(process.execPath, ["-e", HTTP_CHILD_SRC], {
|
|
17095
17175
|
input: JSON.stringify({ url, method, headers: params?.headers, body: params?.body }),
|
|
17096
17176
|
encoding: "utf8",
|
|
17097
17177
|
timeout: HTTP_TIMEOUT_MS,
|
|
@@ -17138,11 +17218,11 @@ function scriptConditionIsTruthy(value) {
|
|
|
17138
17218
|
if (!Number.isNaN(num) && num === 0) return false;
|
|
17139
17219
|
return true;
|
|
17140
17220
|
}
|
|
17141
|
-
var
|
|
17221
|
+
var import_child_process5, vm, HTTP_TIMEOUT_MS, HTTP_CHILD_SRC, TEMPLATE_RE, ESCAPED_TEMPLATE_RE, BARE_IDENTIFIER_RE, MaestroJsContext;
|
|
17142
17222
|
var init_maestro_js = __esm({
|
|
17143
17223
|
"cli/maestro-js.ts"() {
|
|
17144
17224
|
"use strict";
|
|
17145
|
-
|
|
17225
|
+
import_child_process5 = require("child_process");
|
|
17146
17226
|
vm = __toESM(require("vm"), 1);
|
|
17147
17227
|
HTTP_TIMEOUT_MS = 3e5;
|
|
17148
17228
|
HTTP_CHILD_SRC = `
|
|
@@ -17322,14 +17402,14 @@ process.stdin.on('end', async () => {
|
|
|
17322
17402
|
function getBaseDir() {
|
|
17323
17403
|
const explicit = process.env[SESSION_FILE_ENV];
|
|
17324
17404
|
if (explicit?.trim()) {
|
|
17325
|
-
return (0,
|
|
17405
|
+
return (0, import_node_path8.dirname)((0, import_node_path8.resolve)(explicit));
|
|
17326
17406
|
}
|
|
17327
17407
|
return electronUserDataDir();
|
|
17328
17408
|
}
|
|
17329
17409
|
function getSharedDesktopAuthFilePath() {
|
|
17330
17410
|
const explicit = process.env[SESSION_FILE_ENV];
|
|
17331
|
-
if (explicit?.trim()) return (0,
|
|
17332
|
-
return (0,
|
|
17411
|
+
if (explicit?.trim()) return (0, import_node_path8.resolve)(explicit);
|
|
17412
|
+
return (0, import_node_path8.join)(getBaseDir(), "desktop-auth.json");
|
|
17333
17413
|
}
|
|
17334
17414
|
function normalizeUser(input) {
|
|
17335
17415
|
if (!input || typeof input !== "object") return null;
|
|
@@ -17375,26 +17455,26 @@ function normalizeSession(input) {
|
|
|
17375
17455
|
}
|
|
17376
17456
|
function readSharedDesktopAuthSession() {
|
|
17377
17457
|
const filepath = getSharedDesktopAuthFilePath();
|
|
17378
|
-
if (!(0,
|
|
17458
|
+
if (!(0, import_node_fs9.existsSync)(filepath)) return null;
|
|
17379
17459
|
try {
|
|
17380
|
-
const parsed = JSON.parse((0,
|
|
17460
|
+
const parsed = JSON.parse((0, import_node_fs9.readFileSync)(filepath, "utf8"));
|
|
17381
17461
|
const normalized = normalizeSession(parsed);
|
|
17382
17462
|
if (!normalized) {
|
|
17383
|
-
(0,
|
|
17463
|
+
(0, import_node_fs9.rmSync)(filepath, { force: true });
|
|
17384
17464
|
return null;
|
|
17385
17465
|
}
|
|
17386
17466
|
return normalized;
|
|
17387
17467
|
} catch {
|
|
17388
|
-
(0,
|
|
17468
|
+
(0, import_node_fs9.rmSync)(filepath, { force: true });
|
|
17389
17469
|
return null;
|
|
17390
17470
|
}
|
|
17391
17471
|
}
|
|
17392
|
-
var
|
|
17472
|
+
var import_node_fs9, import_node_path8, SESSION_VERSION, SESSION_FILE_ENV, DEFAULT_ORIGIN;
|
|
17393
17473
|
var init_shared_session = __esm({
|
|
17394
17474
|
"src/auth/shared-session.ts"() {
|
|
17395
17475
|
"use strict";
|
|
17396
|
-
|
|
17397
|
-
|
|
17476
|
+
import_node_fs9 = require("node:fs");
|
|
17477
|
+
import_node_path8 = require("node:path");
|
|
17398
17478
|
init_home_paths();
|
|
17399
17479
|
SESSION_VERSION = 1;
|
|
17400
17480
|
SESSION_FILE_ENV = "SOOTSIM_SHARED_AUTH_FILE";
|
|
@@ -17670,16 +17750,16 @@ function resolveFlowScreenshotPath(screenshotDir, name) {
|
|
|
17670
17750
|
}
|
|
17671
17751
|
function resolveProjectRelativeFlowBase(flowDir) {
|
|
17672
17752
|
if (!flowDir) return process.cwd();
|
|
17673
|
-
return
|
|
17753
|
+
return path10.basename(flowDir) === ".maestro" ? path10.dirname(flowDir) : flowDir;
|
|
17674
17754
|
}
|
|
17675
17755
|
function resolveFlowScreenshotPathWithMode(screenshotDir, name, opts) {
|
|
17676
17756
|
const normalizedName = name.endsWith(".png") ? name : `${name}.png`;
|
|
17677
|
-
if (
|
|
17757
|
+
if (path10.isAbsolute(normalizedName)) return normalizedName;
|
|
17678
17758
|
if (opts.mode === "flow" && /[\\/]/.test(normalizedName)) {
|
|
17679
17759
|
const baseDir = normalizedName.startsWith("./") || normalizedName.startsWith("../") ? opts.flowDir ?? process.cwd() : resolveProjectRelativeFlowBase(opts.flowDir);
|
|
17680
|
-
return
|
|
17760
|
+
return path10.resolve(baseDir, normalizedName);
|
|
17681
17761
|
}
|
|
17682
|
-
return
|
|
17762
|
+
return path10.join(screenshotDir, normalizedName);
|
|
17683
17763
|
}
|
|
17684
17764
|
function normalizeFlowScreenshotSpec(step) {
|
|
17685
17765
|
if (typeof step === "string") {
|
|
@@ -17736,12 +17816,12 @@ function parseFlowSteps(content) {
|
|
|
17736
17816
|
const parsed = import_yaml.default.parse(candidate);
|
|
17737
17817
|
return Array.isArray(parsed) ? parsed : [];
|
|
17738
17818
|
}
|
|
17739
|
-
var
|
|
17819
|
+
var fs10, path10, import_settings2, import_yaml, DEFAULT_TIMEOUT, FLOW_TIMEOUT_SCALE, scaledTimeout, SCREEN_W, SCREEN_H, SootSimBridgeFlowRunner;
|
|
17740
17820
|
var init_bridge_flow_runner = __esm({
|
|
17741
17821
|
"cli/bridge-flow-runner.ts"() {
|
|
17742
17822
|
"use strict";
|
|
17743
|
-
|
|
17744
|
-
|
|
17823
|
+
fs10 = __toESM(require("fs"), 1);
|
|
17824
|
+
path10 = __toESM(require("path"), 1);
|
|
17745
17825
|
import_settings2 = require("sootsim-engine/settings");
|
|
17746
17826
|
import_yaml = __toESM(require("yaml"), 1);
|
|
17747
17827
|
init_frame_compose();
|
|
@@ -18029,14 +18109,14 @@ var init_bridge_flow_runner = __esm({
|
|
|
18029
18109
|
if (chunks.length === 0) {
|
|
18030
18110
|
throw new Error("recording requested but no video buffer was produced");
|
|
18031
18111
|
}
|
|
18032
|
-
|
|
18112
|
+
fs10.mkdirSync(this.opts.recordingOutputDir, { recursive: true });
|
|
18033
18113
|
const videoMime = stopped.mime || this.opts.recordingFormat || "video/webm";
|
|
18034
18114
|
const extension = videoMime.includes("mp4") ? "mp4" : "webm";
|
|
18035
|
-
const outputPath =
|
|
18115
|
+
const outputPath = path10.join(
|
|
18036
18116
|
this.opts.recordingOutputDir,
|
|
18037
18117
|
`sootsim-${Date.now()}.${extension}`
|
|
18038
18118
|
);
|
|
18039
|
-
|
|
18119
|
+
fs10.writeFileSync(outputPath, Buffer.concat(chunks));
|
|
18040
18120
|
return outputPath;
|
|
18041
18121
|
}
|
|
18042
18122
|
async waitForRecordingTail(opts) {
|
|
@@ -18545,7 +18625,7 @@ var init_bridge_flow_runner = __esm({
|
|
|
18545
18625
|
flowDir: this.opts.flowDir
|
|
18546
18626
|
}
|
|
18547
18627
|
);
|
|
18548
|
-
|
|
18628
|
+
fs10.mkdirSync(path10.dirname(outputPath), { recursive: true });
|
|
18549
18629
|
const layers = spec.layers ?? this.opts.screenshotLayers;
|
|
18550
18630
|
const screenshotRequest = {
|
|
18551
18631
|
type: "screenshot",
|
|
@@ -18561,11 +18641,11 @@ var init_bridge_flow_runner = __esm({
|
|
|
18561
18641
|
throw new Error("could not read current device model for framed screenshot");
|
|
18562
18642
|
}
|
|
18563
18643
|
const framed = await composeFramedScreenshot(rawBuffer, model);
|
|
18564
|
-
|
|
18644
|
+
fs10.writeFileSync(outputPath, framed);
|
|
18565
18645
|
console.log(`[flow] screenshot: ${outputPath} (frame: ${model})`);
|
|
18566
18646
|
return outputPath;
|
|
18567
18647
|
}
|
|
18568
|
-
|
|
18648
|
+
fs10.writeFileSync(outputPath, rawBuffer);
|
|
18569
18649
|
console.log(`[flow] screenshot: ${outputPath}`);
|
|
18570
18650
|
return outputPath;
|
|
18571
18651
|
}
|
|
@@ -18581,22 +18661,22 @@ var init_bridge_flow_runner = __esm({
|
|
|
18581
18661
|
return model;
|
|
18582
18662
|
}
|
|
18583
18663
|
async captureScreenshot(outputPath) {
|
|
18584
|
-
|
|
18664
|
+
fs10.mkdirSync(path10.dirname(outputPath), { recursive: true });
|
|
18585
18665
|
const dataUrl = await this.bridge.send({
|
|
18586
18666
|
type: "screenshot",
|
|
18587
18667
|
simId: this.opts.simId
|
|
18588
18668
|
});
|
|
18589
18669
|
const base64 = dataUrl.replace(/^data:image\/png;base64,/, "");
|
|
18590
|
-
|
|
18670
|
+
fs10.writeFileSync(outputPath, Buffer.from(base64, "base64"));
|
|
18591
18671
|
}
|
|
18592
18672
|
// writes a per-failure debug bundle: screenshot + structured describe
|
|
18593
18673
|
// + a11y tree + console errors/warnings + failed network requests +
|
|
18594
18674
|
// shell state, all under one directory so post-mortem is one grep away.
|
|
18595
18675
|
async captureFailureBundle(outputDir, context) {
|
|
18596
|
-
|
|
18676
|
+
fs10.mkdirSync(outputDir, { recursive: true });
|
|
18597
18677
|
const write = (name, content) => {
|
|
18598
18678
|
try {
|
|
18599
|
-
|
|
18679
|
+
fs10.writeFileSync(path10.join(outputDir, name), content);
|
|
18600
18680
|
} catch {
|
|
18601
18681
|
}
|
|
18602
18682
|
};
|
|
@@ -19138,8 +19218,8 @@ var init_bridge_flow_runner = __esm({
|
|
|
19138
19218
|
runScript(target) {
|
|
19139
19219
|
const spec = typeof target === "string" ? { file: target } : target;
|
|
19140
19220
|
if (!spec.file) throw new Error("runScript requires a file");
|
|
19141
|
-
const scriptPath =
|
|
19142
|
-
const source =
|
|
19221
|
+
const scriptPath = path10.resolve(this.opts.flowDir, spec.file);
|
|
19222
|
+
const source = fs10.readFileSync(scriptPath, "utf8");
|
|
19143
19223
|
this.js.evaluate(source, { env: spec.env });
|
|
19144
19224
|
console.log(`[flow] runScript: ${spec.file} done`);
|
|
19145
19225
|
}
|
|
@@ -19433,10 +19513,10 @@ var init_bridge_flow_runner = __esm({
|
|
|
19433
19513
|
for (const [k, v] of Object.entries(env)) this.js.putEnv(k, v);
|
|
19434
19514
|
}
|
|
19435
19515
|
if (file) {
|
|
19436
|
-
const flowPath =
|
|
19437
|
-
const flowContent =
|
|
19516
|
+
const flowPath = path10.resolve(this.opts.flowDir, file);
|
|
19517
|
+
const flowContent = fs10.readFileSync(flowPath, "utf8");
|
|
19438
19518
|
const previousDir = this.opts.flowDir;
|
|
19439
|
-
this.opts.flowDir =
|
|
19519
|
+
this.opts.flowDir = path10.dirname(flowPath);
|
|
19440
19520
|
try {
|
|
19441
19521
|
await this.runFlow(parseFlowSteps(flowContent));
|
|
19442
19522
|
} finally {
|
|
@@ -19591,8 +19671,8 @@ __export(registry_exports, {
|
|
|
19591
19671
|
skillRegistry: () => skillRegistry
|
|
19592
19672
|
});
|
|
19593
19673
|
module.exports = __toCommonJS(registry_exports);
|
|
19594
|
-
var
|
|
19595
|
-
var
|
|
19674
|
+
var fs11 = __toESM(require("fs"), 1);
|
|
19675
|
+
var path11 = __toESM(require("path"), 1);
|
|
19596
19676
|
|
|
19597
19677
|
// src/skills/builtin/a11y-review.ts
|
|
19598
19678
|
init_reap_browser();
|
|
@@ -19611,8 +19691,8 @@ var skill = {
|
|
|
19611
19691
|
},
|
|
19612
19692
|
async execute(params, context) {
|
|
19613
19693
|
const { chromium } = await import("playwright");
|
|
19614
|
-
const
|
|
19615
|
-
const
|
|
19694
|
+
const path12 = await import("path");
|
|
19695
|
+
const fs12 = await import("fs");
|
|
19616
19696
|
const browser = await launchReapedChrome((options) => chromium.launch(options), {
|
|
19617
19697
|
headless: true
|
|
19618
19698
|
});
|
|
@@ -19667,9 +19747,9 @@ var skill = {
|
|
|
19667
19747
|
warnings: issues.filter((i) => i.severity === "warning").length,
|
|
19668
19748
|
tree: typeof tree === "string" ? tree : JSON.stringify(tree)
|
|
19669
19749
|
};
|
|
19670
|
-
const reportPath =
|
|
19671
|
-
|
|
19672
|
-
|
|
19750
|
+
const reportPath = path12.join(context.outputDir, "a11y-report.json");
|
|
19751
|
+
fs12.mkdirSync(path12.dirname(reportPath), { recursive: true });
|
|
19752
|
+
fs12.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
19673
19753
|
return {
|
|
19674
19754
|
success: issues.filter((i) => i.severity === "error").length === 0,
|
|
19675
19755
|
message: `${report.errors} errors, ${report.warnings} warnings across ${report.nodeCount} nodes`,
|
|
@@ -19707,8 +19787,8 @@ var skill2 = {
|
|
|
19707
19787
|
}
|
|
19708
19788
|
},
|
|
19709
19789
|
async execute(params, context) {
|
|
19710
|
-
const
|
|
19711
|
-
const
|
|
19790
|
+
const fs12 = await import("fs");
|
|
19791
|
+
const path12 = await import("path");
|
|
19712
19792
|
const { POLYFILL_REGISTRY: POLYFILL_REGISTRY2 } = await Promise.resolve().then(() => (init_web(), web_exports));
|
|
19713
19793
|
if (params.packageName) {
|
|
19714
19794
|
const entry = POLYFILL_REGISTRY2[params.packageName];
|
|
@@ -19726,11 +19806,11 @@ var skill2 = {
|
|
|
19726
19806
|
data: { package: params.packageName, status, ...entry }
|
|
19727
19807
|
};
|
|
19728
19808
|
}
|
|
19729
|
-
const pkgPath =
|
|
19730
|
-
if (!
|
|
19809
|
+
const pkgPath = path12.join(context.projectDir, "package.json");
|
|
19810
|
+
if (!fs12.existsSync(pkgPath)) {
|
|
19731
19811
|
return { success: false, message: "No package.json found" };
|
|
19732
19812
|
}
|
|
19733
|
-
const pkg = JSON.parse(
|
|
19813
|
+
const pkg = JSON.parse(fs12.readFileSync(pkgPath, "utf8"));
|
|
19734
19814
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
19735
19815
|
const results = {
|
|
19736
19816
|
full: [],
|
|
@@ -19748,9 +19828,9 @@ var skill2 = {
|
|
|
19748
19828
|
results.unknown.push(dep);
|
|
19749
19829
|
}
|
|
19750
19830
|
}
|
|
19751
|
-
const reportPath =
|
|
19752
|
-
|
|
19753
|
-
|
|
19831
|
+
const reportPath = path12.join(context.outputDir, "compat-report.json");
|
|
19832
|
+
fs12.mkdirSync(path12.dirname(reportPath), { recursive: true });
|
|
19833
|
+
fs12.writeFileSync(reportPath, JSON.stringify(results, null, 2));
|
|
19754
19834
|
return {
|
|
19755
19835
|
success: results.unsupported.length === 0,
|
|
19756
19836
|
message: `${results.full.length} full, ${results.partial.length} partial, ${results.unsupported.length} unsupported, ${results.unknown.length} unknown`,
|
|
@@ -19788,8 +19868,8 @@ var skill3 = {
|
|
|
19788
19868
|
record: { type: "boolean", description: "Record video of the flow" }
|
|
19789
19869
|
},
|
|
19790
19870
|
async execute(params, context) {
|
|
19791
|
-
const
|
|
19792
|
-
const
|
|
19871
|
+
const fs12 = await import("fs");
|
|
19872
|
+
const path12 = await import("path");
|
|
19793
19873
|
const yaml2 = await import("yaml");
|
|
19794
19874
|
const { DEFAULT_SOOTSIM_BRIDGE_PORT: DEFAULT_SOOTSIM_BRIDGE_PORT2 } = await Promise.resolve().then(() => (init_bridge_constants(), bridge_constants_exports));
|
|
19795
19875
|
const { SootSimBridgeHost: SootSimBridgeHost2 } = await Promise.resolve().then(() => (init_bridge_host(), bridge_host_exports));
|
|
@@ -19798,7 +19878,7 @@ var skill3 = {
|
|
|
19798
19878
|
const host = new SootSimBridgeHost2({ port: DEFAULT_SOOTSIM_BRIDGE_PORT2 });
|
|
19799
19879
|
host.start({ silent: true });
|
|
19800
19880
|
try {
|
|
19801
|
-
const flowContent =
|
|
19881
|
+
const flowContent = fs12.readFileSync(params.flowPath, "utf8");
|
|
19802
19882
|
const fmMatch = flowContent.match(/^---\n([\s\S]*?)\n---\n?/);
|
|
19803
19883
|
const stepsBody = fmMatch ? flowContent.slice(fmMatch[0].length) : flowContent;
|
|
19804
19884
|
const steps = yaml2.parse(stepsBody);
|
|
@@ -19823,7 +19903,7 @@ var skill3 = {
|
|
|
19823
19903
|
});
|
|
19824
19904
|
const driver = new SootSimBridgeFlowRunner2(bridge, {
|
|
19825
19905
|
screenshotDir: context.outputDir,
|
|
19826
|
-
flowDir:
|
|
19906
|
+
flowDir: path12.dirname(path12.resolve(params.flowPath)),
|
|
19827
19907
|
simId,
|
|
19828
19908
|
recordingOutputDir: params.record ? context.outputDir : void 0
|
|
19829
19909
|
});
|
|
@@ -19845,7 +19925,7 @@ var skill3 = {
|
|
|
19845
19925
|
simId,
|
|
19846
19926
|
videoPath: videoPath || void 0
|
|
19847
19927
|
},
|
|
19848
|
-
artifacts: videoPath ? [{ type: "video", name:
|
|
19928
|
+
artifacts: videoPath ? [{ type: "video", name: path12.basename(videoPath), path: videoPath }] : void 0
|
|
19849
19929
|
};
|
|
19850
19930
|
} finally {
|
|
19851
19931
|
try {
|
|
@@ -19892,8 +19972,8 @@ var skill4 = {
|
|
|
19892
19972
|
},
|
|
19893
19973
|
async execute(params, context) {
|
|
19894
19974
|
const { chromium } = await import("playwright");
|
|
19895
|
-
const
|
|
19896
|
-
const
|
|
19975
|
+
const path12 = await import("path");
|
|
19976
|
+
const fs12 = await import("fs");
|
|
19897
19977
|
const browser = await launchReapedChrome((options) => chromium.launch(options), {
|
|
19898
19978
|
headless: true
|
|
19899
19979
|
});
|
|
@@ -19919,9 +19999,9 @@ var skill4 = {
|
|
|
19919
19999
|
...profile,
|
|
19920
20000
|
fps: syncCount > 0 ? (syncCount / (duration / 1e3)).toFixed(1) : "0"
|
|
19921
20001
|
};
|
|
19922
|
-
const reportPath =
|
|
19923
|
-
|
|
19924
|
-
|
|
20002
|
+
const reportPath = path12.join(context.outputDir, "perf-report.json");
|
|
20003
|
+
fs12.mkdirSync(path12.dirname(reportPath), { recursive: true });
|
|
20004
|
+
fs12.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
19925
20005
|
return {
|
|
19926
20006
|
success: true,
|
|
19927
20007
|
message: `${report.fps} fps, ${profile.avgSyncMs?.toFixed(1)}ms avg sync, ${nodeCount} nodes`,
|
|
@@ -19954,8 +20034,8 @@ var skill5 = {
|
|
|
19954
20034
|
},
|
|
19955
20035
|
async execute(params, context) {
|
|
19956
20036
|
const { chromium } = await import("playwright");
|
|
19957
|
-
const
|
|
19958
|
-
const
|
|
20037
|
+
const path12 = await import("path");
|
|
20038
|
+
const fs12 = await import("fs");
|
|
19959
20039
|
const browser = await launchReapedChrome((options) => chromium.launch(options), {
|
|
19960
20040
|
headless: true
|
|
19961
20041
|
});
|
|
@@ -19963,8 +20043,8 @@ var skill5 = {
|
|
|
19963
20043
|
try {
|
|
19964
20044
|
await page.goto(context.url, { waitUntil: "networkidle" });
|
|
19965
20045
|
await page.waitForTimeout(2e3);
|
|
19966
|
-
const outputPath =
|
|
19967
|
-
|
|
20046
|
+
const outputPath = path12.join(context.outputDir, `${params.name}.png`);
|
|
20047
|
+
fs12.mkdirSync(path12.dirname(outputPath), { recursive: true });
|
|
19968
20048
|
await page.screenshot({ path: outputPath });
|
|
19969
20049
|
return {
|
|
19970
20050
|
success: true,
|
|
@@ -20005,8 +20085,8 @@ var skill6 = {
|
|
|
20005
20085
|
},
|
|
20006
20086
|
async execute(params, context) {
|
|
20007
20087
|
const { chromium } = await import("playwright");
|
|
20008
|
-
const
|
|
20009
|
-
const
|
|
20088
|
+
const path12 = await import("path");
|
|
20089
|
+
const fs12 = await import("fs");
|
|
20010
20090
|
const browser = await launchReapedChrome((options) => chromium.launch(options), {
|
|
20011
20091
|
headless: true
|
|
20012
20092
|
});
|
|
@@ -20014,14 +20094,14 @@ var skill6 = {
|
|
|
20014
20094
|
try {
|
|
20015
20095
|
await page.goto(context.url, { waitUntil: "networkidle" });
|
|
20016
20096
|
await page.waitForTimeout(2e3);
|
|
20017
|
-
const currentPath =
|
|
20018
|
-
|
|
20097
|
+
const currentPath = path12.join(context.outputDir, `${params.name}-current.png`);
|
|
20098
|
+
fs12.mkdirSync(path12.dirname(currentPath), { recursive: true });
|
|
20019
20099
|
await page.screenshot({ path: currentPath });
|
|
20020
20100
|
try {
|
|
20021
20101
|
const { PNG } = await import("pngjs");
|
|
20022
20102
|
const pixelmatch = (await import("pixelmatch")).default;
|
|
20023
|
-
const baseline = PNG.sync.read(
|
|
20024
|
-
const current = PNG.sync.read(
|
|
20103
|
+
const baseline = PNG.sync.read(fs12.readFileSync(params.baseline));
|
|
20104
|
+
const current = PNG.sync.read(fs12.readFileSync(currentPath));
|
|
20025
20105
|
const { width, height } = baseline;
|
|
20026
20106
|
const diff = new PNG({ width, height });
|
|
20027
20107
|
const numDiffPixels = pixelmatch(
|
|
@@ -20032,8 +20112,8 @@ var skill6 = {
|
|
|
20032
20112
|
height,
|
|
20033
20113
|
{ threshold: params.threshold || 0.1 }
|
|
20034
20114
|
);
|
|
20035
|
-
const diffPath =
|
|
20036
|
-
|
|
20115
|
+
const diffPath = path12.join(context.outputDir, `${params.name}-diff.png`);
|
|
20116
|
+
fs12.writeFileSync(diffPath, PNG.sync.write(diff));
|
|
20037
20117
|
const totalPixels = width * height;
|
|
20038
20118
|
const diffPercent = (numDiffPixels / totalPixels * 100).toFixed(2);
|
|
20039
20119
|
return {
|
|
@@ -20097,10 +20177,10 @@ var skillRegistry = {
|
|
|
20097
20177
|
},
|
|
20098
20178
|
// load skills from a project manifest (sootsim-skills.json)
|
|
20099
20179
|
async loadFromManifest(projectDir) {
|
|
20100
|
-
const manifestPath =
|
|
20101
|
-
if (!
|
|
20180
|
+
const manifestPath = path11.join(projectDir, "sootsim-skills.json");
|
|
20181
|
+
if (!fs11.existsSync(manifestPath)) return;
|
|
20102
20182
|
try {
|
|
20103
|
-
const manifest = JSON.parse(
|
|
20183
|
+
const manifest = JSON.parse(fs11.readFileSync(manifestPath, "utf8"));
|
|
20104
20184
|
if (Array.isArray(manifest.skills)) {
|
|
20105
20185
|
for (const entry of manifest.skills) {
|
|
20106
20186
|
if (typeof entry === "string") {
|
|
@@ -20111,7 +20191,7 @@ var skillRegistry = {
|
|
|
20111
20191
|
}
|
|
20112
20192
|
} else if (entry.file) {
|
|
20113
20193
|
try {
|
|
20114
|
-
const mod = await import(
|
|
20194
|
+
const mod = await import(path11.resolve(projectDir, entry.file));
|
|
20115
20195
|
if (mod.skill) this.register(mod.skill);
|
|
20116
20196
|
} catch {
|
|
20117
20197
|
}
|
|
@@ -20124,10 +20204,10 @@ var skillRegistry = {
|
|
|
20124
20204
|
// auto-discover skills based on project dependencies
|
|
20125
20205
|
suggestSkills(projectDir) {
|
|
20126
20206
|
const suggestions = [];
|
|
20127
|
-
const pkgPath =
|
|
20128
|
-
if (!
|
|
20207
|
+
const pkgPath = path11.join(projectDir, "package.json");
|
|
20208
|
+
if (!fs11.existsSync(pkgPath)) return suggestions;
|
|
20129
20209
|
try {
|
|
20130
|
-
const pkg = JSON.parse(
|
|
20210
|
+
const pkg = JSON.parse(fs11.readFileSync(pkgPath, "utf8"));
|
|
20131
20211
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
20132
20212
|
if (deps["detox"] || deps["maestro"]) {
|
|
20133
20213
|
suggestions.push("maestro-test");
|