sootsim 0.1.268 → 0.1.270
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 +7 -3
- package/detox/index.ts +5 -2
- package/dist-cli/bin.js +4 -4
- package/dist-cli/chunks/{agent-KQSZFG6R.js → agent-4YXUPSJ2.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-DLDQVS7O.js → agent-wrapper-BMJPWHWK.js} +2 -2
- package/dist-cli/chunks/{app-fonts-6XVNNHAB.js → app-fonts-EDRH6ETC.js} +2 -2
- package/dist-cli/chunks/{assert-DLGUW4JS.js → assert-CRDV324D.js} +2 -2
- package/dist-cli/chunks/{auth-MTSJWWMS.js → auth-WYRQIJEN.js} +2 -2
- package/dist-cli/chunks/beta-NBANSL2S.js +2 -0
- package/dist-cli/chunks/{camera-MGJUBHWZ.js → camera-5TO6IVBP.js} +3 -3
- package/dist-cli/chunks/{chunk-LJGOZ77E.js → chunk-2J3E5TPS.js} +1 -1
- package/dist-cli/chunks/{chunk-GUXMUE5A.js → chunk-3VIMSXQZ.js} +2 -2
- package/dist-cli/chunks/{chunk-YUDUKMJV.js → chunk-3ZOF2BTJ.js} +1 -1
- package/dist-cli/chunks/{chunk-RCU4A7LU.js → chunk-44ISBOEK.js} +3 -3
- package/dist-cli/chunks/{chunk-F7DMZRQX.js → chunk-4HPWZVBS.js} +1 -1
- package/dist-cli/chunks/{chunk-K5ZMEBMQ.js → chunk-557IYHPC.js} +1 -1
- package/dist-cli/chunks/{chunk-RG6QF6DY.js → chunk-5IHDZOMR.js} +1 -1
- package/dist-cli/chunks/{chunk-XIBSRCKK.js → chunk-6CI73D3X.js} +2 -2
- package/dist-cli/chunks/chunk-6JLIPPNB.js +2 -0
- package/dist-cli/chunks/{chunk-YMTVQA6W.js → chunk-74HIBIJQ.js} +4 -4
- package/dist-cli/chunks/{chunk-6TXGR4HK.js → chunk-ABSUFSOH.js} +2 -2
- package/dist-cli/chunks/{chunk-NPSDN7D7.js → chunk-AG563BSO.js} +2 -2
- package/dist-cli/chunks/{chunk-IWJTCFAE.js → chunk-AMA3YGJ5.js} +2 -2
- package/dist-cli/chunks/{chunk-EG3JCOGS.js → chunk-AMVYE3F4.js} +2 -2
- package/dist-cli/chunks/{chunk-LOOHTTDV.js → chunk-B5IBLYEO.js} +3 -3
- package/dist-cli/chunks/{chunk-M2LYCMW4.js → chunk-DCJXHSIA.js} +2 -2
- package/dist-cli/chunks/{chunk-ITQ7WKNC.js → chunk-ERXCR7NU.js} +2 -2
- package/dist-cli/chunks/{chunk-KR4LGQWN.js → chunk-FCMEOOQE.js} +2 -2
- package/dist-cli/chunks/{chunk-YNMYUJYR.js → chunk-FHPXOPMC.js} +2 -2
- package/dist-cli/chunks/{chunk-V27FSRID.js → chunk-FNBFRG64.js} +1 -1
- package/dist-cli/chunks/{chunk-5JH5F4TM.js → chunk-GAYG7AO4.js} +1 -1
- package/dist-cli/chunks/chunk-GQDQO3KU.js +5 -0
- package/dist-cli/chunks/{chunk-JERNRAFO.js → chunk-HWGKGIWE.js} +2 -2
- package/dist-cli/chunks/{chunk-YLMP3AEX.js → chunk-IIXRM6BB.js} +2 -2
- package/dist-cli/chunks/{chunk-EPKHW3XW.js → chunk-LHMVSKKD.js} +3 -3
- package/dist-cli/chunks/chunk-M32JVXHU.js +5 -0
- package/dist-cli/chunks/{chunk-FGKDYXO3.js → chunk-M5VURHXD.js} +1 -1
- package/dist-cli/chunks/{chunk-6YB3URLB.js → chunk-MD24VVKT.js} +2 -2
- package/dist-cli/chunks/{chunk-CWC7QMVM.js → chunk-MYBY7OHL.js} +1 -1
- package/dist-cli/chunks/{chunk-7XWLSCXZ.js → chunk-NTO6SKS5.js} +1 -1
- package/dist-cli/chunks/{chunk-H2WCONSC.js → chunk-OUKH6UGN.js} +1 -1
- package/dist-cli/chunks/{chunk-OOVGROTR.js → chunk-PDFKRVDC.js} +1 -1
- package/dist-cli/chunks/{chunk-74QJWGDX.js → chunk-SDKIUJUO.js} +2 -2
- package/dist-cli/chunks/chunk-SLR3HWMB.js +13 -0
- package/dist-cli/chunks/{chunk-WUOPQL2J.js → chunk-SW5HZ5LK.js} +1 -1
- package/dist-cli/chunks/{chunk-WT3OYHU7.js → chunk-TIONGRTA.js} +3 -3
- package/dist-cli/chunks/{chunk-EH3A54PO.js → chunk-TLNGREAA.js} +2 -2
- package/dist-cli/chunks/{chunk-5MIRQ65V.js → chunk-TMWNOQAA.js} +1 -1
- package/dist-cli/chunks/{chunk-3MZJ2KVR.js → chunk-TZH4VH32.js} +3 -3
- package/dist-cli/chunks/{chunk-FGY5ESGU.js → chunk-UPRCATUH.js} +2 -2
- package/dist-cli/chunks/chunk-XTTXSDDA.js +1 -0
- package/dist-cli/chunks/{chunk-ZTOWO5CK.js → chunk-YKK2QUGO.js} +1 -1
- package/dist-cli/chunks/{chunk-SV6D5FXN.js → chunk-ZTKDHPA6.js} +2 -2
- package/dist-cli/chunks/chunk-ZZH2AFPJ.js +1 -0
- package/dist-cli/chunks/cli-version-BLKUTVJ2.js +2 -0
- package/dist-cli/chunks/{compat-IVBKZVGH.js → compat-IZEDAAUW.js} +3 -3
- package/dist-cli/chunks/{config-PQ3KBTIM.js → config-I4CXZ6M7.js} +2 -2
- package/dist-cli/chunks/{control-BKTYM5XP.js → control-DVF7UL5D.js} +2 -2
- package/dist-cli/chunks/daemon-FPKQPSSY.js +2 -0
- package/dist-cli/chunks/{debug-HRR2LK2J.js → debug-5X2F2WRP.js} +3 -3
- package/dist-cli/chunks/{desktop-466O4AQA.js → desktop-JHEYQZGF.js} +3 -3
- package/dist-cli/chunks/{detox-UH44KHQJ.js → detox-W64UENQG.js} +2 -2
- package/dist-cli/chunks/{device-FZLXTC3W.js → device-ZBSW2EHS.js} +2 -2
- package/dist-cli/chunks/{diagnose-RJMRI27P.js → diagnose-WER4X3P5.js} +2 -2
- package/dist-cli/chunks/drivers-6P53DLMM.js +2 -0
- package/dist-cli/chunks/{film-VL66UAM3.js → film-TIXNUTR6.js} +3 -3
- package/dist-cli/chunks/flow-53XFDYLL.js +2 -0
- package/dist-cli/chunks/help-MPYJLD7I.js +2 -0
- package/dist-cli/chunks/{hidden-runtime-alias-3ZAR7GCH.js → hidden-runtime-alias-R3JH3INM.js} +2 -2
- package/dist-cli/chunks/{home-paths-S2GRJWV3.js → home-paths-CNNARPCT.js} +2 -2
- package/dist-cli/chunks/inspect-JBDDYUA5.js +2 -0
- package/dist-cli/chunks/install-desktop-BBP7AMK4.js +2 -0
- package/dist-cli/chunks/{login-TR3YAEA2.js → login-6NCCZ3CZ.js} +4 -4
- package/dist-cli/chunks/{logout-WPY2DOYZ.js → logout-C4VKXUH4.js} +2 -2
- package/dist-cli/chunks/{maestro-DSG7V2BA.js → maestro-ZRGFQ3MV.js} +3 -3
- package/dist-cli/chunks/{maestro-generate-6KA7PCN5.js → maestro-generate-A5XZS5GC.js} +3 -3
- package/dist-cli/chunks/{mode-QUYGPNBW.js → mode-IFFZ55HM.js} +2 -2
- package/dist-cli/chunks/optional-demo-registry-TQZA65K3.js +2 -0
- package/dist-cli/chunks/{perf-ELBRUVVU.js → perf-44KZNTIV.js} +2 -2
- package/dist-cli/chunks/{record-6PDTULUN.js → record-GZLZNXYZ.js} +3 -3
- package/dist-cli/chunks/runtime-F4FCEPPB.js +2 -0
- package/dist-cli/chunks/{screenshot-command-E2A4VY6D.js → screenshot-command-GL3STSWK.js} +3 -3
- package/dist-cli/chunks/{screenshots-capture-TRCRHK2E.js → screenshots-capture-QSSBWHN6.js} +2 -2
- package/dist-cli/chunks/serve-AFK6X2Q3.js +42 -0
- package/dist-cli/chunks/{setup-5BHQNK2L.js → setup-DYSDNEUE.js} +3 -3
- package/dist-cli/chunks/{skills-NQLI6WXW.js → skills-YXWQ43PZ.js} +2 -2
- package/dist-cli/chunks/{storage-SKARYTYK.js → storage-C7IS5GTM.js} +2 -2
- package/dist-cli/chunks/store-LVF2C2XZ.js +2 -0
- package/dist-cli/chunks/telemetry-5V3OXY6C.js +2 -0
- package/dist-cli/chunks/{timeline-DYJ4GKGE.js → timeline-FDTIHQ5V.js} +2 -2
- package/dist-cli/chunks/{upgrade-PHUUE5QV.js → upgrade-VRQCFJEI.js} +2 -2
- package/dist-cli/chunks/upload-CRCPDN6G.js +2 -0
- package/dist-cli/chunks/{version-XQQSXS3E.js → version-MP6NKJ27.js} +2 -2
- package/dist-cli/chunks/web-XYPFJHKW.js +2 -0
- package/dist-cli/chunks/{what-happened-I2N3FFIV.js → what-happened-IM6UH24Q.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 +10 -10
- package/dist-lib/agent-sessions.cjs +29 -13
- package/dist-lib/attached-projects.cjs +33 -13
- 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 +23 -6
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +6 -4
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +110 -54
- 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 +220 -148
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/src/agent-daemon-client.ts +2 -2
- package/src/agent-identity.ts +7 -5
- package/src/attached-projects.ts +35 -11
- package/src/bridge-constants.ts +23 -4
- package/src/host/agent-host.ts +63 -14
- package/src/{agentbus-prompt.ts → team-machine-prompt.ts} +13 -20
- package/dist-cli/chunks/beta-7R4DRB3R.js +0 -2
- package/dist-cli/chunks/chunk-2LWDKYJ3.js +0 -1
- package/dist-cli/chunks/chunk-346C7547.js +0 -2
- package/dist-cli/chunks/chunk-CD2GF6PV.js +0 -5
- package/dist-cli/chunks/chunk-PN2LR6T4.js +0 -5
- package/dist-cli/chunks/chunk-Y3IYHVEX.js +0 -13
- package/dist-cli/chunks/chunk-ZHSXFJ7W.js +0 -1
- package/dist-cli/chunks/cli-version-362THKXA.js +0 -2
- package/dist-cli/chunks/daemon-SCTA3HTZ.js +0 -2
- package/dist-cli/chunks/drivers-S7D5OZQN.js +0 -2
- package/dist-cli/chunks/flow-IM5OXO5S.js +0 -2
- package/dist-cli/chunks/help-G5CN3KXU.js +0 -2
- package/dist-cli/chunks/inspect-WI7GXOH5.js +0 -2
- package/dist-cli/chunks/install-desktop-PVBWQQHY.js +0 -2
- package/dist-cli/chunks/optional-demo-registry-CROVHXTW.js +0 -2
- package/dist-cli/chunks/runtime-ITR3EUXS.js +0 -2
- package/dist-cli/chunks/serve-JLLSEZDN.js +0 -41
- package/dist-cli/chunks/store-VR5QRAYX.js +0 -2
- package/dist-cli/chunks/telemetry-PMYZDJGO.js +0 -2
- package/dist-cli/chunks/upload-OUKKXVNC.js +0 -2
- package/dist-cli/chunks/web-AZI3JODI.js +0 -2
package/dist-lib/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.270 | (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;
|
|
@@ -1038,7 +1038,7 @@ var init_registry = __esm({
|
|
|
1038
1038
|
{
|
|
1039
1039
|
range: ">=55.0.0",
|
|
1040
1040
|
coverage: 0.9,
|
|
1041
|
-
note: "SymbolView renders the
|
|
1041
|
+
note: "SymbolView renders the shared SootSim SF Symbol vector and preserves the requested system name for frozen Design replay. Unknown names use the supplied fallback. unstable_getMaterialSymbolSourceAsync returns a stable URI/size shape so apps that gate on the source resolve correctly.",
|
|
1042
1042
|
working: "SymbolView, name object/string selection (string | { ios, android, web }), size/tintColor styling, fallback rendering, unstable_getMaterialSymbolSourceAsync",
|
|
1043
1043
|
missing: "bundled SF Symbols font (Apple license), bundled Material Symbols font (size budget), animation/effect modifiers (.bounce, .scale)"
|
|
1044
1044
|
}
|
|
@@ -1233,7 +1233,7 @@ var init_registry = __esm({
|
|
|
1233
1233
|
{
|
|
1234
1234
|
range: ">=13.0.0",
|
|
1235
1235
|
coverage: 0.94,
|
|
1236
|
-
note: "real SQLite via lazy-loaded bedrock-sqlite (~1MB WASM) \u2014 full SQL support including joins, transactions, prepared statements, RETURNING. WASM ships in the runtime tarball,
|
|
1236
|
+
note: "real SQLite via lazy-loaded bedrock-sqlite (~1MB WASM) \u2014 full SQL support including joins, transactions, prepared statements, RETURNING. WASM ships in the runtime tarball and loads with the expo-sqlite compatibility chunk, so synchronous APIs are ready as soon as the module import resolves. memfs persists to IDB via Module._memfs (requires the bedrock-sqlite build with the memfs-on-module export from orez/sqlite-wasm); reloads restore the prior state \u2014 verified end-to-end via the orbstack/published-runtime probe across 3 page reloads.",
|
|
1237
1237
|
working: "openDatabaseAsync / openDatabaseSync (real bedrock instance), execAsync / execSync, prepareAsync / prepareSync, runAsync / runSync, getFirstAsync / getFirstSync, getAllAsync / getAllSync, getEachAsync / getEachSync, withTransactionAsync / withTransactionSync, withExclusiveTransactionAsync, isInTransactionAsync / isInTransactionSync, closeAsync / closeSync, deleteDatabaseAsync / deleteDatabaseSync, SQLiteStatement.executeAsync / executeSync / executeForRawResultAsync / executeForRawResultSync / getColumnNames* / finalize*, SQLiteProvider, useSQLiteContext, defaultDatabaseDirectory, async iteration via for-await-of, RETURNING clauses",
|
|
1238
1238
|
missing: "serializeAsync (bedrock does not expose sqlite3_serialize through its module surface), backupDatabaseAsync, addDatabaseChangeListener (no sqlite3_update_hook bindings), createSessionAsync, loadExtensionAsync, SQLiteTaggedQuery (Bun-style template literal API)"
|
|
1239
1239
|
}
|
|
@@ -3854,7 +3854,7 @@ var init_registry = __esm({
|
|
|
3854
3854
|
{
|
|
3855
3855
|
range: ">=1.21.0",
|
|
3856
3856
|
coverage: 0.72,
|
|
3857
|
-
note: "native-seam only for toolbar/menu host views. the real @vxrn/native
|
|
3857
|
+
note: "native-seam only for toolbar/menu host views. One's public Stack.Toolbar components use the real @vxrn/native implementation, whose React code runs from the bundle and converts the composition API into native host props and native-stack header items.",
|
|
3858
3858
|
working: "StackToolbar header and bottom placements, Button, Label, Icon with SF Symbols/image sources, Badge, fixed/fluid Spacer, View children, nested Menu/MenuAction trees, disabled/selected/destructive actions, visible action callbacks, and native-stack header bar item integration",
|
|
3859
3859
|
missing: "Color and zoom-transition native hosts, SplitView gamma host, bottom SearchBarSlot integration with a configured native search controller, exact UIKit shared-background grouping"
|
|
3860
3860
|
}
|
|
@@ -10326,7 +10326,8 @@ __export(bridge_constants_exports, {
|
|
|
10326
10326
|
resolveSootsimBridgePort: () => resolveSootsimBridgePort,
|
|
10327
10327
|
resolveSootsimBridgePortForHttpPort: () => resolveSootsimBridgePortForHttpPort,
|
|
10328
10328
|
resolveSootsimBridgePortForRuntimeLocation: () => resolveSootsimBridgePortForRuntimeLocation,
|
|
10329
|
-
resolveSootsimBridgeWebSocketUrl: () => resolveSootsimBridgeWebSocketUrl
|
|
10329
|
+
resolveSootsimBridgeWebSocketUrl: () => resolveSootsimBridgeWebSocketUrl,
|
|
10330
|
+
resolveSootsimWebSocketProxyUrl: () => resolveSootsimWebSocketProxyUrl
|
|
10330
10331
|
});
|
|
10331
10332
|
function parsePort(value) {
|
|
10332
10333
|
if (typeof value === "number") {
|
|
@@ -10393,16 +10394,31 @@ function resolveSootsimBridgePortForRuntimeLocation(input = {}) {
|
|
|
10393
10394
|
if (baseHttpPort === null) return DEFAULT_SOOTSIM_BRIDGE_PORT;
|
|
10394
10395
|
return resolveSootsimBridgePortForHttpPort({ httpPort, baseHttpPort });
|
|
10395
10396
|
}
|
|
10396
|
-
function
|
|
10397
|
+
function resolveSootsimWebSocketProxyUrl(input) {
|
|
10397
10398
|
const pageUrl = parseHrefUrl(input.href);
|
|
10398
10399
|
if (!pageUrl || pageUrl.protocol !== "http:" && pageUrl.protocol !== "https:") {
|
|
10399
|
-
throw new Error(`invalid SootSim
|
|
10400
|
+
throw new Error(`invalid SootSim websocket proxy page URL: ${input.href}`);
|
|
10401
|
+
}
|
|
10402
|
+
let targetUrl;
|
|
10403
|
+
try {
|
|
10404
|
+
targetUrl = new URL(input.targetUrl);
|
|
10405
|
+
} catch {
|
|
10406
|
+
throw new Error(`invalid SootSim websocket proxy target URL: ${input.targetUrl}`);
|
|
10407
|
+
}
|
|
10408
|
+
if (targetUrl.protocol !== "ws:" && targetUrl.protocol !== "wss:") {
|
|
10409
|
+
throw new Error(`invalid SootSim websocket proxy target URL: ${input.targetUrl}`);
|
|
10400
10410
|
}
|
|
10401
10411
|
const proxyUrl = new URL("/__websocket-proxy", pageUrl);
|
|
10402
10412
|
proxyUrl.protocol = pageUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
10403
|
-
proxyUrl.searchParams.set("url",
|
|
10413
|
+
proxyUrl.searchParams.set("url", input.targetUrl);
|
|
10404
10414
|
return proxyUrl.href;
|
|
10405
10415
|
}
|
|
10416
|
+
function resolveSootsimBridgeWebSocketUrl(input) {
|
|
10417
|
+
return resolveSootsimWebSocketProxyUrl({
|
|
10418
|
+
targetUrl: `ws://localhost:${input.bridgePort}`,
|
|
10419
|
+
href: input.href
|
|
10420
|
+
});
|
|
10421
|
+
}
|
|
10406
10422
|
var DEFAULT_SOOTSIM_BRIDGE_PORT, CONTRAST_DEV_HTTP_BASE_PORT, SOOTSIM_SITE_DEV_HTTP_BASE_PORT, SOOTSIM_SHELL_DEV_HTTP_BASE_PORT, LOCAL_DEV_HTTP_BASE_PORTS, MAX_LOCAL_DEV_PORT_OFFSET, SOOTSIM_BRIDGE_SIM_CLOSE_CODE, SOOTSIM_BRIDGE_SIM_CLOSE_REASON;
|
|
10407
10423
|
var init_bridge_constants = __esm({
|
|
10408
10424
|
"src/bridge-constants.ts"() {
|
|
@@ -10541,10 +10557,10 @@ function tcpPing(port, timeout = TCP_GATE_MS) {
|
|
|
10541
10557
|
sock.connect(port, "localhost");
|
|
10542
10558
|
});
|
|
10543
10559
|
}
|
|
10544
|
-
function httpGet(port,
|
|
10560
|
+
function httpGet(port, path11, method = "GET", timeout = TIMEOUT_MS, headers = {}) {
|
|
10545
10561
|
return new Promise((resolve5) => {
|
|
10546
10562
|
const req = import_http.default.request(
|
|
10547
|
-
{ hostname: "localhost", port, path:
|
|
10563
|
+
{ hostname: "localhost", port, path: path11, method, timeout, headers },
|
|
10548
10564
|
(res) => {
|
|
10549
10565
|
let body = "";
|
|
10550
10566
|
res.on("data", (c) => body += c.toString());
|
|
@@ -11885,21 +11901,37 @@ function listSessions(projectId) {
|
|
|
11885
11901
|
const all = loadStore().agentSessions;
|
|
11886
11902
|
return projectId ? all.filter((s) => s.projectId === projectId) : all;
|
|
11887
11903
|
}
|
|
11888
|
-
function
|
|
11904
|
+
function applySessionStatusPatch(existing, patch, now = Date.now()) {
|
|
11905
|
+
return {
|
|
11906
|
+
...existing,
|
|
11907
|
+
...patch,
|
|
11908
|
+
id: existing.id,
|
|
11909
|
+
projectId: existing.projectId,
|
|
11910
|
+
createdAt: existing.createdAt,
|
|
11911
|
+
lastSeenAt: now
|
|
11912
|
+
};
|
|
11913
|
+
}
|
|
11914
|
+
function updateSessionStatuses(updates) {
|
|
11915
|
+
if (updates.length === 0) return;
|
|
11889
11916
|
mutateStore((store) => {
|
|
11890
|
-
const
|
|
11891
|
-
|
|
11892
|
-
|
|
11893
|
-
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
|
|
11897
|
-
|
|
11898
|
-
|
|
11899
|
-
|
|
11900
|
-
|
|
11917
|
+
const now = Date.now();
|
|
11918
|
+
const indexById = new Map(
|
|
11919
|
+
store.agentSessions.map((session, index) => [session.id, index])
|
|
11920
|
+
);
|
|
11921
|
+
for (const { id, patch } of updates) {
|
|
11922
|
+
const idx = indexById.get(id);
|
|
11923
|
+
if (idx === void 0) continue;
|
|
11924
|
+
store.agentSessions[idx] = applySessionStatusPatch(
|
|
11925
|
+
store.agentSessions[idx],
|
|
11926
|
+
patch,
|
|
11927
|
+
now
|
|
11928
|
+
);
|
|
11929
|
+
}
|
|
11901
11930
|
});
|
|
11902
11931
|
}
|
|
11932
|
+
function updateSessionStatus(id, patch) {
|
|
11933
|
+
updateSessionStatuses([{ id, patch }]);
|
|
11934
|
+
}
|
|
11903
11935
|
async function seedFromDemoAppRegistry() {
|
|
11904
11936
|
const existing = loadStore().attachedProjects;
|
|
11905
11937
|
if (existing.length > 0) return;
|
|
@@ -12382,46 +12414,42 @@ var init_agent_sessions = __esm({
|
|
|
12382
12414
|
});
|
|
12383
12415
|
|
|
12384
12416
|
// src/agent-identity.ts
|
|
12385
|
-
function
|
|
12417
|
+
function teamMachineSessionIdFromCliIdentity(identity) {
|
|
12386
12418
|
if (!identity?.startsWith("AGENTBUS_SESSION:")) return null;
|
|
12387
12419
|
const sessionId = identity.slice("AGENTBUS_SESSION:".length).trim();
|
|
12388
|
-
if (!
|
|
12420
|
+
if (!TEAM_MACHINE_SESSION_RE.test(sessionId)) return null;
|
|
12389
12421
|
return sessionId;
|
|
12390
12422
|
}
|
|
12391
|
-
function
|
|
12392
|
-
return
|
|
12423
|
+
function isValidTeamMachineSessionId(sessionId) {
|
|
12424
|
+
return TEAM_MACHINE_SESSION_RE.test(sessionId);
|
|
12393
12425
|
}
|
|
12394
|
-
var
|
|
12426
|
+
var TEAM_MACHINE_SESSION_RE;
|
|
12395
12427
|
var init_agent_identity = __esm({
|
|
12396
12428
|
"src/agent-identity.ts"() {
|
|
12397
12429
|
"use strict";
|
|
12398
|
-
|
|
12430
|
+
TEAM_MACHINE_SESSION_RE = /^[A-Za-z0-9._:-]{1,160}$/;
|
|
12399
12431
|
}
|
|
12400
12432
|
});
|
|
12401
12433
|
|
|
12402
|
-
// src/
|
|
12403
|
-
function
|
|
12434
|
+
// src/team-machine-prompt.ts
|
|
12435
|
+
function formatTeamMachinePromptText(prompt) {
|
|
12404
12436
|
return typeof prompt.text === "string" ? prompt.text.trim() : "";
|
|
12405
12437
|
}
|
|
12406
|
-
function
|
|
12438
|
+
function resolveTeamMachineCommand(explicit) {
|
|
12407
12439
|
const fromArg = explicit?.trim();
|
|
12408
12440
|
if (fromArg) return fromArg;
|
|
12409
|
-
|
|
12410
|
-
if (fromEnv) return fromEnv;
|
|
12411
|
-
const localBin = import_node_path6.default.join(import_node_os2.default.homedir(), ".local", "bin", "agentbus");
|
|
12412
|
-
if (import_node_fs7.default.existsSync(localBin)) return localBin;
|
|
12413
|
-
return "agentbus";
|
|
12441
|
+
return "tm";
|
|
12414
12442
|
}
|
|
12415
|
-
async function
|
|
12443
|
+
async function sendPromptToTeamMachineSession(input) {
|
|
12416
12444
|
const sessionId = input.sessionId.trim();
|
|
12417
|
-
if (!
|
|
12418
|
-
throw new Error(`invalid
|
|
12445
|
+
if (!isValidTeamMachineSessionId(sessionId)) {
|
|
12446
|
+
throw new Error(`invalid Team Machine session id: ${sessionId || "<empty>"}`);
|
|
12419
12447
|
}
|
|
12420
|
-
const text =
|
|
12448
|
+
const text = formatTeamMachinePromptText(input.prompt);
|
|
12421
12449
|
if (!text) {
|
|
12422
12450
|
throw new Error("prompt text is empty");
|
|
12423
12451
|
}
|
|
12424
|
-
const command =
|
|
12452
|
+
const command = resolveTeamMachineCommand(input.command);
|
|
12425
12453
|
const timeoutMs = input.timeoutMs ?? 15e3;
|
|
12426
12454
|
await new Promise((resolve5, reject) => {
|
|
12427
12455
|
const child = (0, import_node_child_process4.spawn)(command, ["send", sessionId, text], {
|
|
@@ -12434,7 +12462,7 @@ async function sendPromptToAgentbusSession(input) {
|
|
|
12434
12462
|
child.kill("SIGTERM");
|
|
12435
12463
|
} catch {
|
|
12436
12464
|
}
|
|
12437
|
-
reject(new Error(`
|
|
12465
|
+
reject(new Error(`tm send timed out after ${Math.round(timeoutMs / 1e3)}s`));
|
|
12438
12466
|
}, timeoutMs);
|
|
12439
12467
|
child.stderr?.setEncoding("utf8");
|
|
12440
12468
|
child.stderr?.on("data", (chunk) => {
|
|
@@ -12453,20 +12481,17 @@ async function sendPromptToAgentbusSession(input) {
|
|
|
12453
12481
|
const detail = stderr.trim();
|
|
12454
12482
|
reject(
|
|
12455
12483
|
new Error(
|
|
12456
|
-
detail || `
|
|
12484
|
+
detail || `tm send exited with ${signal ? `signal ${signal}` : `code ${code ?? "unknown"}`}`
|
|
12457
12485
|
)
|
|
12458
12486
|
);
|
|
12459
12487
|
});
|
|
12460
12488
|
});
|
|
12461
12489
|
}
|
|
12462
|
-
var import_node_child_process4
|
|
12463
|
-
var
|
|
12464
|
-
"src/
|
|
12490
|
+
var import_node_child_process4;
|
|
12491
|
+
var init_team_machine_prompt = __esm({
|
|
12492
|
+
"src/team-machine-prompt.ts"() {
|
|
12465
12493
|
"use strict";
|
|
12466
12494
|
import_node_child_process4 = require("node:child_process");
|
|
12467
|
-
import_node_fs7 = __toESM(require("node:fs"), 1);
|
|
12468
|
-
import_node_os2 = __toESM(require("node:os"), 1);
|
|
12469
|
-
import_node_path6 = __toESM(require("node:path"), 1);
|
|
12470
12495
|
init_agent_identity();
|
|
12471
12496
|
init_agent_identity();
|
|
12472
12497
|
}
|
|
@@ -12485,17 +12510,18 @@ function mapFrameworkToProjectFramework(fw) {
|
|
|
12485
12510
|
if (fw === "one" || fw === "vxrn") return "one";
|
|
12486
12511
|
return "unknown";
|
|
12487
12512
|
}
|
|
12488
|
-
var
|
|
12513
|
+
var import_node_fs7, import_node_path6, WS_OPEN, SESSION_STATUS_PERSIST_DELAY_MS, AgentHost;
|
|
12489
12514
|
var init_agent_host = __esm({
|
|
12490
12515
|
"src/host/agent-host.ts"() {
|
|
12491
12516
|
"use strict";
|
|
12492
|
-
|
|
12493
|
-
|
|
12517
|
+
import_node_fs7 = __toESM(require("node:fs"), 1);
|
|
12518
|
+
import_node_path6 = __toESM(require("node:path"), 1);
|
|
12494
12519
|
init_dev_server_scanner();
|
|
12495
12520
|
init_agent_sessions();
|
|
12496
|
-
init_agentbus_prompt();
|
|
12497
12521
|
init_attached_projects();
|
|
12522
|
+
init_team_machine_prompt();
|
|
12498
12523
|
WS_OPEN = 1;
|
|
12524
|
+
SESSION_STATUS_PERSIST_DELAY_MS = 25;
|
|
12499
12525
|
AgentHost = class {
|
|
12500
12526
|
// live fan-out, keyed by sessionId. refcount tracks how many sockets have
|
|
12501
12527
|
// subscribed; the FIFO reader stays open as long as refcount > 0.
|
|
@@ -12517,6 +12543,12 @@ var init_agent_host = __esm({
|
|
|
12517
12543
|
// in-memory count so session status stays `working` until that backlog
|
|
12518
12544
|
// truly drains.
|
|
12519
12545
|
pendingTurns = /* @__PURE__ */ new Map();
|
|
12546
|
+
// status fan-out is realtime state. keep the current value in memory and
|
|
12547
|
+
// batch its durable store write so an fsync cannot delay the websocket event
|
|
12548
|
+
// it describes. close() flushes the final batch synchronously.
|
|
12549
|
+
pendingSessionStates = /* @__PURE__ */ new Map();
|
|
12550
|
+
pendingSessionPatches = /* @__PURE__ */ new Map();
|
|
12551
|
+
sessionStatusPersistTimer = null;
|
|
12520
12552
|
opts;
|
|
12521
12553
|
constructor(opts = {}) {
|
|
12522
12554
|
this.opts = opts;
|
|
@@ -12567,6 +12599,11 @@ var init_agent_host = __esm({
|
|
|
12567
12599
|
/** terminate every subscription and drop every socket reference. called
|
|
12568
12600
|
* by the bridge host during shutdown. */
|
|
12569
12601
|
close() {
|
|
12602
|
+
if (this.sessionStatusPersistTimer) {
|
|
12603
|
+
clearTimeout(this.sessionStatusPersistTimer);
|
|
12604
|
+
this.sessionStatusPersistTimer = null;
|
|
12605
|
+
}
|
|
12606
|
+
this.flushSessionStatuses();
|
|
12570
12607
|
for (const sub of this.subscriptions.values()) {
|
|
12571
12608
|
try {
|
|
12572
12609
|
sub.unsubscribe();
|
|
@@ -12635,18 +12672,18 @@ var init_agent_host = __esm({
|
|
|
12635
12672
|
if (!lease || lease.kind !== "cli" || lease.expiresAt <= Date.now()) {
|
|
12636
12673
|
throw new AgentSessionError("NO_CLAIM", `sim ${simId} has no active CLI claim`);
|
|
12637
12674
|
}
|
|
12638
|
-
const sessionId =
|
|
12675
|
+
const sessionId = teamMachineSessionIdFromCliIdentity(lease.cliIdentityKey);
|
|
12639
12676
|
if (!sessionId) {
|
|
12640
12677
|
throw new AgentSessionError(
|
|
12641
12678
|
"UNSUPPORTED_CLAIM",
|
|
12642
12679
|
`sim ${simId} is claimed by a CLI identity that is not promptable`
|
|
12643
12680
|
);
|
|
12644
12681
|
}
|
|
12645
|
-
await
|
|
12682
|
+
await sendPromptToTeamMachineSession({
|
|
12646
12683
|
sessionId,
|
|
12647
12684
|
prompt: this.normalizePromptEnvelope(msg)
|
|
12648
12685
|
});
|
|
12649
|
-
return { ok: true, routed: "
|
|
12686
|
+
return { ok: true, routed: "team-machine", sessionId };
|
|
12650
12687
|
}
|
|
12651
12688
|
async doStartSession(input) {
|
|
12652
12689
|
const project = findProjectById(input.projectId);
|
|
@@ -12677,7 +12714,7 @@ var init_agent_host = __esm({
|
|
|
12677
12714
|
);
|
|
12678
12715
|
const project = upsertProject({
|
|
12679
12716
|
cwd: match.cwd,
|
|
12680
|
-
name: match.projectName ??
|
|
12717
|
+
name: match.projectName ?? import_node_path6.default.basename(match.cwd),
|
|
12681
12718
|
preferredProvider: input.provider ?? existing?.preferredProvider,
|
|
12682
12719
|
sourceRoots: existing?.sourceRoots ?? [match.cwd],
|
|
12683
12720
|
knownBundleUrls,
|
|
@@ -12688,18 +12725,18 @@ var init_agent_host = __esm({
|
|
|
12688
12725
|
}
|
|
12689
12726
|
getTranscript(sessionId) {
|
|
12690
12727
|
const p = transcriptPath(sessionId);
|
|
12691
|
-
if (!
|
|
12728
|
+
if (!import_node_fs7.default.existsSync(p)) {
|
|
12692
12729
|
return { error: "transcript not found", code: "NO_TRANSCRIPT" };
|
|
12693
12730
|
}
|
|
12694
|
-
return
|
|
12731
|
+
return import_node_fs7.default.readFileSync(p, "utf8");
|
|
12695
12732
|
}
|
|
12696
12733
|
getPaths() {
|
|
12697
12734
|
const dir = getUserDataDir();
|
|
12698
12735
|
return {
|
|
12699
12736
|
userDataDir: dir,
|
|
12700
|
-
storeFile:
|
|
12701
|
-
sessionsDir:
|
|
12702
|
-
transcriptsDir:
|
|
12737
|
+
storeFile: import_node_path6.default.join(dir, "attached-projects.json"),
|
|
12738
|
+
sessionsDir: import_node_path6.default.join(dir, "sessions"),
|
|
12739
|
+
transcriptsDir: import_node_path6.default.join(dir, "transcripts")
|
|
12703
12740
|
};
|
|
12704
12741
|
}
|
|
12705
12742
|
// --- subscription management ---
|
|
@@ -12879,10 +12916,45 @@ var init_agent_host = __esm({
|
|
|
12879
12916
|
}
|
|
12880
12917
|
}
|
|
12881
12918
|
patchSession(sessionId, patch) {
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
|
|
12885
|
-
|
|
12919
|
+
const existing = this.pendingSessionStates.get(sessionId) ?? findSessionById(sessionId);
|
|
12920
|
+
if (!existing) return;
|
|
12921
|
+
const updated = applySessionStatusPatch(existing, patch);
|
|
12922
|
+
this.pendingSessionStates.set(sessionId, updated);
|
|
12923
|
+
this.pendingSessionPatches.set(sessionId, {
|
|
12924
|
+
...this.pendingSessionPatches.get(sessionId),
|
|
12925
|
+
...patch
|
|
12926
|
+
});
|
|
12927
|
+
this.broadcastSessionStatus(updated);
|
|
12928
|
+
if (this.sessionStatusPersistTimer) return;
|
|
12929
|
+
this.sessionStatusPersistTimer = setTimeout(() => {
|
|
12930
|
+
this.sessionStatusPersistTimer = null;
|
|
12931
|
+
this.flushSessionStatuses();
|
|
12932
|
+
}, SESSION_STATUS_PERSIST_DELAY_MS);
|
|
12933
|
+
}
|
|
12934
|
+
flushSessionStatuses() {
|
|
12935
|
+
if (this.pendingSessionPatches.size === 0) return;
|
|
12936
|
+
const pendingStates = this.pendingSessionStates;
|
|
12937
|
+
const pendingPatches = this.pendingSessionPatches;
|
|
12938
|
+
this.pendingSessionStates = /* @__PURE__ */ new Map();
|
|
12939
|
+
this.pendingSessionPatches = /* @__PURE__ */ new Map();
|
|
12940
|
+
try {
|
|
12941
|
+
updateSessionStatuses([...pendingPatches].map(([id, patch]) => ({ id, patch })));
|
|
12942
|
+
} catch (error) {
|
|
12943
|
+
for (const [id, session] of pendingStates) {
|
|
12944
|
+
if (!this.pendingSessionStates.has(id)) {
|
|
12945
|
+
this.pendingSessionStates.set(id, session);
|
|
12946
|
+
}
|
|
12947
|
+
}
|
|
12948
|
+
for (const [id, patch] of pendingPatches) {
|
|
12949
|
+
this.pendingSessionPatches.set(id, {
|
|
12950
|
+
...patch,
|
|
12951
|
+
...this.pendingSessionPatches.get(id)
|
|
12952
|
+
});
|
|
12953
|
+
}
|
|
12954
|
+
process.stderr.write(
|
|
12955
|
+
`[sootsim-agent] session status persistence failed: ${error instanceof Error ? error.message : String(error)}
|
|
12956
|
+
`
|
|
12957
|
+
);
|
|
12886
12958
|
}
|
|
12887
12959
|
}
|
|
12888
12960
|
coalescePromptEcho(sessionId, event) {
|
|
@@ -15766,7 +15838,7 @@ var init_current_sim = __esm({
|
|
|
15766
15838
|
"SOOTSIM_CLI_IDENTITY",
|
|
15767
15839
|
// explicit override — fastest path, skips all pid lookups
|
|
15768
15840
|
"AGENTBUS_SESSION",
|
|
15769
|
-
//
|
|
15841
|
+
// Team Machine session id; routes prompt-bar followups back to this agent
|
|
15770
15842
|
"CLAUDE_CODE_SESSION_ID",
|
|
15771
15843
|
// claude code, if ever set
|
|
15772
15844
|
"CODEX_THREAD_ID",
|
|
@@ -15790,7 +15862,7 @@ var init_current_sim = __esm({
|
|
|
15790
15862
|
"VSCODE_INJECTION"
|
|
15791
15863
|
// vscode integrated terminal
|
|
15792
15864
|
];
|
|
15793
|
-
IMMORTAL_HOST_COMM_RE = /^(?:tmux|screen)|^
|
|
15865
|
+
IMMORTAL_HOST_COMM_RE = /^(?:tmux|screen)|^tm$/i;
|
|
15794
15866
|
}
|
|
15795
15867
|
});
|
|
15796
15868
|
|
|
@@ -16199,11 +16271,11 @@ async function evalInBridge(bridge, code, opts = {}) {
|
|
|
16199
16271
|
if (opts.acquireLock) payload.acquireLock = true;
|
|
16200
16272
|
return bridge.send(payload);
|
|
16201
16273
|
}
|
|
16202
|
-
async function callInBridge(bridge,
|
|
16203
|
-
return bridge.send({ type: "call", path:
|
|
16274
|
+
async function callInBridge(bridge, path11, ...args) {
|
|
16275
|
+
return bridge.send({ type: "call", path: path11, args });
|
|
16204
16276
|
}
|
|
16205
|
-
async function callInBridgeWrite(bridge,
|
|
16206
|
-
return bridge.send({ type: "call", path:
|
|
16277
|
+
async function callInBridgeWrite(bridge, path11, ...args) {
|
|
16278
|
+
return bridge.send({ type: "call", path: path11, args, acquireLock: true });
|
|
16207
16279
|
}
|
|
16208
16280
|
var import_ws3, resolvedWorld, BridgeSimLockedError;
|
|
16209
16281
|
var init_ws_bridge = __esm({
|
|
@@ -17431,14 +17503,14 @@ process.stdin.on('end', async () => {
|
|
|
17431
17503
|
function getBaseDir() {
|
|
17432
17504
|
const explicit = process.env[SESSION_FILE_ENV];
|
|
17433
17505
|
if (explicit?.trim()) {
|
|
17434
|
-
return (0,
|
|
17506
|
+
return (0, import_node_path7.dirname)((0, import_node_path7.resolve)(explicit));
|
|
17435
17507
|
}
|
|
17436
17508
|
return electronUserDataDir();
|
|
17437
17509
|
}
|
|
17438
17510
|
function getSharedDesktopAuthFilePath() {
|
|
17439
17511
|
const explicit = process.env[SESSION_FILE_ENV];
|
|
17440
|
-
if (explicit?.trim()) return (0,
|
|
17441
|
-
return (0,
|
|
17512
|
+
if (explicit?.trim()) return (0, import_node_path7.resolve)(explicit);
|
|
17513
|
+
return (0, import_node_path7.join)(getBaseDir(), "desktop-auth.json");
|
|
17442
17514
|
}
|
|
17443
17515
|
function normalizeUser(input) {
|
|
17444
17516
|
if (!input || typeof input !== "object") return null;
|
|
@@ -17484,26 +17556,26 @@ function normalizeSession(input) {
|
|
|
17484
17556
|
}
|
|
17485
17557
|
function readSharedDesktopAuthSession() {
|
|
17486
17558
|
const filepath = getSharedDesktopAuthFilePath();
|
|
17487
|
-
if (!(0,
|
|
17559
|
+
if (!(0, import_node_fs8.existsSync)(filepath)) return null;
|
|
17488
17560
|
try {
|
|
17489
|
-
const parsed = JSON.parse((0,
|
|
17561
|
+
const parsed = JSON.parse((0, import_node_fs8.readFileSync)(filepath, "utf8"));
|
|
17490
17562
|
const normalized = normalizeSession(parsed);
|
|
17491
17563
|
if (!normalized) {
|
|
17492
|
-
(0,
|
|
17564
|
+
(0, import_node_fs8.rmSync)(filepath, { force: true });
|
|
17493
17565
|
return null;
|
|
17494
17566
|
}
|
|
17495
17567
|
return normalized;
|
|
17496
17568
|
} catch {
|
|
17497
|
-
(0,
|
|
17569
|
+
(0, import_node_fs8.rmSync)(filepath, { force: true });
|
|
17498
17570
|
return null;
|
|
17499
17571
|
}
|
|
17500
17572
|
}
|
|
17501
|
-
var
|
|
17573
|
+
var import_node_fs8, import_node_path7, SESSION_VERSION, SESSION_FILE_ENV, DEFAULT_ORIGIN;
|
|
17502
17574
|
var init_shared_session = __esm({
|
|
17503
17575
|
"src/auth/shared-session.ts"() {
|
|
17504
17576
|
"use strict";
|
|
17505
|
-
|
|
17506
|
-
|
|
17577
|
+
import_node_fs8 = require("node:fs");
|
|
17578
|
+
import_node_path7 = require("node:path");
|
|
17507
17579
|
init_home_paths();
|
|
17508
17580
|
SESSION_VERSION = 1;
|
|
17509
17581
|
SESSION_FILE_ENV = "SOOTSIM_SHARED_AUTH_FILE";
|
|
@@ -17779,16 +17851,16 @@ function resolveFlowScreenshotPath(screenshotDir, name) {
|
|
|
17779
17851
|
}
|
|
17780
17852
|
function resolveProjectRelativeFlowBase(flowDir) {
|
|
17781
17853
|
if (!flowDir) return process.cwd();
|
|
17782
|
-
return
|
|
17854
|
+
return path9.basename(flowDir) === ".maestro" ? path9.dirname(flowDir) : flowDir;
|
|
17783
17855
|
}
|
|
17784
17856
|
function resolveFlowScreenshotPathWithMode(screenshotDir, name, opts) {
|
|
17785
17857
|
const normalizedName = name.endsWith(".png") ? name : `${name}.png`;
|
|
17786
|
-
if (
|
|
17858
|
+
if (path9.isAbsolute(normalizedName)) return normalizedName;
|
|
17787
17859
|
if (opts.mode === "flow" && /[\\/]/.test(normalizedName)) {
|
|
17788
17860
|
const baseDir = normalizedName.startsWith("./") || normalizedName.startsWith("../") ? opts.flowDir ?? process.cwd() : resolveProjectRelativeFlowBase(opts.flowDir);
|
|
17789
|
-
return
|
|
17861
|
+
return path9.resolve(baseDir, normalizedName);
|
|
17790
17862
|
}
|
|
17791
|
-
return
|
|
17863
|
+
return path9.join(screenshotDir, normalizedName);
|
|
17792
17864
|
}
|
|
17793
17865
|
function normalizeFlowScreenshotSpec(step) {
|
|
17794
17866
|
if (typeof step === "string") {
|
|
@@ -17845,12 +17917,12 @@ function parseFlowSteps(content) {
|
|
|
17845
17917
|
const parsed = import_yaml.default.parse(candidate);
|
|
17846
17918
|
return Array.isArray(parsed) ? parsed : [];
|
|
17847
17919
|
}
|
|
17848
|
-
var
|
|
17920
|
+
var fs9, path9, import_settings2, import_yaml, DEFAULT_TIMEOUT, FLOW_TIMEOUT_SCALE, scaledTimeout, SCREEN_W, SCREEN_H, SootSimBridgeFlowRunner;
|
|
17849
17921
|
var init_bridge_flow_runner = __esm({
|
|
17850
17922
|
"cli/bridge-flow-runner.ts"() {
|
|
17851
17923
|
"use strict";
|
|
17852
|
-
|
|
17853
|
-
|
|
17924
|
+
fs9 = __toESM(require("fs"), 1);
|
|
17925
|
+
path9 = __toESM(require("path"), 1);
|
|
17854
17926
|
import_settings2 = require("sootsim-engine/settings");
|
|
17855
17927
|
import_yaml = __toESM(require("yaml"), 1);
|
|
17856
17928
|
init_frame_compose();
|
|
@@ -18138,14 +18210,14 @@ var init_bridge_flow_runner = __esm({
|
|
|
18138
18210
|
if (chunks.length === 0) {
|
|
18139
18211
|
throw new Error("recording requested but no video buffer was produced");
|
|
18140
18212
|
}
|
|
18141
|
-
|
|
18213
|
+
fs9.mkdirSync(this.opts.recordingOutputDir, { recursive: true });
|
|
18142
18214
|
const videoMime = stopped.mime || this.opts.recordingFormat || "video/webm";
|
|
18143
18215
|
const extension = videoMime.includes("mp4") ? "mp4" : "webm";
|
|
18144
|
-
const outputPath =
|
|
18216
|
+
const outputPath = path9.join(
|
|
18145
18217
|
this.opts.recordingOutputDir,
|
|
18146
18218
|
`sootsim-${Date.now()}.${extension}`
|
|
18147
18219
|
);
|
|
18148
|
-
|
|
18220
|
+
fs9.writeFileSync(outputPath, Buffer.concat(chunks));
|
|
18149
18221
|
return outputPath;
|
|
18150
18222
|
}
|
|
18151
18223
|
async waitForRecordingTail(opts) {
|
|
@@ -18654,7 +18726,7 @@ var init_bridge_flow_runner = __esm({
|
|
|
18654
18726
|
flowDir: this.opts.flowDir
|
|
18655
18727
|
}
|
|
18656
18728
|
);
|
|
18657
|
-
|
|
18729
|
+
fs9.mkdirSync(path9.dirname(outputPath), { recursive: true });
|
|
18658
18730
|
const layers = spec.layers ?? this.opts.screenshotLayers;
|
|
18659
18731
|
const screenshotRequest = {
|
|
18660
18732
|
type: "screenshot",
|
|
@@ -18670,11 +18742,11 @@ var init_bridge_flow_runner = __esm({
|
|
|
18670
18742
|
throw new Error("could not read current device model for framed screenshot");
|
|
18671
18743
|
}
|
|
18672
18744
|
const framed = await composeFramedScreenshot(rawBuffer, model);
|
|
18673
|
-
|
|
18745
|
+
fs9.writeFileSync(outputPath, framed);
|
|
18674
18746
|
console.log(`[flow] screenshot: ${outputPath} (frame: ${model})`);
|
|
18675
18747
|
return outputPath;
|
|
18676
18748
|
}
|
|
18677
|
-
|
|
18749
|
+
fs9.writeFileSync(outputPath, rawBuffer);
|
|
18678
18750
|
console.log(`[flow] screenshot: ${outputPath}`);
|
|
18679
18751
|
return outputPath;
|
|
18680
18752
|
}
|
|
@@ -18690,22 +18762,22 @@ var init_bridge_flow_runner = __esm({
|
|
|
18690
18762
|
return model;
|
|
18691
18763
|
}
|
|
18692
18764
|
async captureScreenshot(outputPath) {
|
|
18693
|
-
|
|
18765
|
+
fs9.mkdirSync(path9.dirname(outputPath), { recursive: true });
|
|
18694
18766
|
const dataUrl = await this.bridge.send({
|
|
18695
18767
|
type: "screenshot",
|
|
18696
18768
|
simId: this.opts.simId
|
|
18697
18769
|
});
|
|
18698
18770
|
const base64 = dataUrl.replace(/^data:image\/png;base64,/, "");
|
|
18699
|
-
|
|
18771
|
+
fs9.writeFileSync(outputPath, Buffer.from(base64, "base64"));
|
|
18700
18772
|
}
|
|
18701
18773
|
// writes a per-failure debug bundle: screenshot + structured describe
|
|
18702
18774
|
// + a11y tree + console errors/warnings + failed network requests +
|
|
18703
18775
|
// shell state, all under one directory so post-mortem is one grep away.
|
|
18704
18776
|
async captureFailureBundle(outputDir, context) {
|
|
18705
|
-
|
|
18777
|
+
fs9.mkdirSync(outputDir, { recursive: true });
|
|
18706
18778
|
const write = (name, content) => {
|
|
18707
18779
|
try {
|
|
18708
|
-
|
|
18780
|
+
fs9.writeFileSync(path9.join(outputDir, name), content);
|
|
18709
18781
|
} catch {
|
|
18710
18782
|
}
|
|
18711
18783
|
};
|
|
@@ -19247,8 +19319,8 @@ var init_bridge_flow_runner = __esm({
|
|
|
19247
19319
|
runScript(target) {
|
|
19248
19320
|
const spec = typeof target === "string" ? { file: target } : target;
|
|
19249
19321
|
if (!spec.file) throw new Error("runScript requires a file");
|
|
19250
|
-
const scriptPath =
|
|
19251
|
-
const source =
|
|
19322
|
+
const scriptPath = path9.resolve(this.opts.flowDir, spec.file);
|
|
19323
|
+
const source = fs9.readFileSync(scriptPath, "utf8");
|
|
19252
19324
|
this.js.evaluate(source, { env: spec.env });
|
|
19253
19325
|
console.log(`[flow] runScript: ${spec.file} done`);
|
|
19254
19326
|
}
|
|
@@ -19542,10 +19614,10 @@ var init_bridge_flow_runner = __esm({
|
|
|
19542
19614
|
for (const [k, v] of Object.entries(env)) this.js.putEnv(k, v);
|
|
19543
19615
|
}
|
|
19544
19616
|
if (file) {
|
|
19545
|
-
const flowPath =
|
|
19546
|
-
const flowContent =
|
|
19617
|
+
const flowPath = path9.resolve(this.opts.flowDir, file);
|
|
19618
|
+
const flowContent = fs9.readFileSync(flowPath, "utf8");
|
|
19547
19619
|
const previousDir = this.opts.flowDir;
|
|
19548
|
-
this.opts.flowDir =
|
|
19620
|
+
this.opts.flowDir = path9.dirname(flowPath);
|
|
19549
19621
|
try {
|
|
19550
19622
|
await this.runFlow(parseFlowSteps(flowContent));
|
|
19551
19623
|
} finally {
|
|
@@ -19700,8 +19772,8 @@ __export(registry_exports, {
|
|
|
19700
19772
|
skillRegistry: () => skillRegistry
|
|
19701
19773
|
});
|
|
19702
19774
|
module.exports = __toCommonJS(registry_exports);
|
|
19703
|
-
var
|
|
19704
|
-
var
|
|
19775
|
+
var fs10 = __toESM(require("fs"), 1);
|
|
19776
|
+
var path10 = __toESM(require("path"), 1);
|
|
19705
19777
|
|
|
19706
19778
|
// src/skills/builtin/a11y-review.ts
|
|
19707
19779
|
init_reap_browser();
|
|
@@ -19720,8 +19792,8 @@ var skill = {
|
|
|
19720
19792
|
},
|
|
19721
19793
|
async execute(params, context) {
|
|
19722
19794
|
const { chromium } = await import("playwright");
|
|
19723
|
-
const
|
|
19724
|
-
const
|
|
19795
|
+
const path11 = await import("path");
|
|
19796
|
+
const fs11 = await import("fs");
|
|
19725
19797
|
const browser = await launchReapedChrome((options) => chromium.launch(options), {
|
|
19726
19798
|
headless: true
|
|
19727
19799
|
});
|
|
@@ -19776,9 +19848,9 @@ var skill = {
|
|
|
19776
19848
|
warnings: issues.filter((i) => i.severity === "warning").length,
|
|
19777
19849
|
tree: typeof tree === "string" ? tree : JSON.stringify(tree)
|
|
19778
19850
|
};
|
|
19779
|
-
const reportPath =
|
|
19780
|
-
|
|
19781
|
-
|
|
19851
|
+
const reportPath = path11.join(context.outputDir, "a11y-report.json");
|
|
19852
|
+
fs11.mkdirSync(path11.dirname(reportPath), { recursive: true });
|
|
19853
|
+
fs11.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
19782
19854
|
return {
|
|
19783
19855
|
success: issues.filter((i) => i.severity === "error").length === 0,
|
|
19784
19856
|
message: `${report.errors} errors, ${report.warnings} warnings across ${report.nodeCount} nodes`,
|
|
@@ -19816,8 +19888,8 @@ var skill2 = {
|
|
|
19816
19888
|
}
|
|
19817
19889
|
},
|
|
19818
19890
|
async execute(params, context) {
|
|
19819
|
-
const
|
|
19820
|
-
const
|
|
19891
|
+
const fs11 = await import("fs");
|
|
19892
|
+
const path11 = await import("path");
|
|
19821
19893
|
const { POLYFILL_REGISTRY: POLYFILL_REGISTRY2 } = await Promise.resolve().then(() => (init_web(), web_exports));
|
|
19822
19894
|
if (params.packageName) {
|
|
19823
19895
|
const entry = POLYFILL_REGISTRY2[params.packageName];
|
|
@@ -19835,11 +19907,11 @@ var skill2 = {
|
|
|
19835
19907
|
data: { package: params.packageName, status, ...entry }
|
|
19836
19908
|
};
|
|
19837
19909
|
}
|
|
19838
|
-
const pkgPath =
|
|
19839
|
-
if (!
|
|
19910
|
+
const pkgPath = path11.join(context.projectDir, "package.json");
|
|
19911
|
+
if (!fs11.existsSync(pkgPath)) {
|
|
19840
19912
|
return { success: false, message: "No package.json found" };
|
|
19841
19913
|
}
|
|
19842
|
-
const pkg = JSON.parse(
|
|
19914
|
+
const pkg = JSON.parse(fs11.readFileSync(pkgPath, "utf8"));
|
|
19843
19915
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
19844
19916
|
const results = {
|
|
19845
19917
|
full: [],
|
|
@@ -19857,9 +19929,9 @@ var skill2 = {
|
|
|
19857
19929
|
results.unknown.push(dep);
|
|
19858
19930
|
}
|
|
19859
19931
|
}
|
|
19860
|
-
const reportPath =
|
|
19861
|
-
|
|
19862
|
-
|
|
19932
|
+
const reportPath = path11.join(context.outputDir, "compat-report.json");
|
|
19933
|
+
fs11.mkdirSync(path11.dirname(reportPath), { recursive: true });
|
|
19934
|
+
fs11.writeFileSync(reportPath, JSON.stringify(results, null, 2));
|
|
19863
19935
|
return {
|
|
19864
19936
|
success: results.unsupported.length === 0,
|
|
19865
19937
|
message: `${results.full.length} full, ${results.partial.length} partial, ${results.unsupported.length} unsupported, ${results.unknown.length} unknown`,
|
|
@@ -19897,8 +19969,8 @@ var skill3 = {
|
|
|
19897
19969
|
record: { type: "boolean", description: "Record video of the flow" }
|
|
19898
19970
|
},
|
|
19899
19971
|
async execute(params, context) {
|
|
19900
|
-
const
|
|
19901
|
-
const
|
|
19972
|
+
const fs11 = await import("fs");
|
|
19973
|
+
const path11 = await import("path");
|
|
19902
19974
|
const yaml2 = await import("yaml");
|
|
19903
19975
|
const { DEFAULT_SOOTSIM_BRIDGE_PORT: DEFAULT_SOOTSIM_BRIDGE_PORT2 } = await Promise.resolve().then(() => (init_bridge_constants(), bridge_constants_exports));
|
|
19904
19976
|
const { SootSimBridgeHost: SootSimBridgeHost2 } = await Promise.resolve().then(() => (init_bridge_host(), bridge_host_exports));
|
|
@@ -19907,7 +19979,7 @@ var skill3 = {
|
|
|
19907
19979
|
const host = new SootSimBridgeHost2({ port: DEFAULT_SOOTSIM_BRIDGE_PORT2 });
|
|
19908
19980
|
host.start({ silent: true });
|
|
19909
19981
|
try {
|
|
19910
|
-
const flowContent =
|
|
19982
|
+
const flowContent = fs11.readFileSync(params.flowPath, "utf8");
|
|
19911
19983
|
const fmMatch = flowContent.match(/^---\n([\s\S]*?)\n---\n?/);
|
|
19912
19984
|
const stepsBody = fmMatch ? flowContent.slice(fmMatch[0].length) : flowContent;
|
|
19913
19985
|
const steps = yaml2.parse(stepsBody);
|
|
@@ -19932,7 +20004,7 @@ var skill3 = {
|
|
|
19932
20004
|
});
|
|
19933
20005
|
const driver = new SootSimBridgeFlowRunner2(bridge, {
|
|
19934
20006
|
screenshotDir: context.outputDir,
|
|
19935
|
-
flowDir:
|
|
20007
|
+
flowDir: path11.dirname(path11.resolve(params.flowPath)),
|
|
19936
20008
|
simId,
|
|
19937
20009
|
recordingOutputDir: params.record ? context.outputDir : void 0
|
|
19938
20010
|
});
|
|
@@ -19954,7 +20026,7 @@ var skill3 = {
|
|
|
19954
20026
|
simId,
|
|
19955
20027
|
videoPath: videoPath || void 0
|
|
19956
20028
|
},
|
|
19957
|
-
artifacts: videoPath ? [{ type: "video", name:
|
|
20029
|
+
artifacts: videoPath ? [{ type: "video", name: path11.basename(videoPath), path: videoPath }] : void 0
|
|
19958
20030
|
};
|
|
19959
20031
|
} finally {
|
|
19960
20032
|
try {
|
|
@@ -20001,8 +20073,8 @@ var skill4 = {
|
|
|
20001
20073
|
},
|
|
20002
20074
|
async execute(params, context) {
|
|
20003
20075
|
const { chromium } = await import("playwright");
|
|
20004
|
-
const
|
|
20005
|
-
const
|
|
20076
|
+
const path11 = await import("path");
|
|
20077
|
+
const fs11 = await import("fs");
|
|
20006
20078
|
const browser = await launchReapedChrome((options) => chromium.launch(options), {
|
|
20007
20079
|
headless: true
|
|
20008
20080
|
});
|
|
@@ -20028,9 +20100,9 @@ var skill4 = {
|
|
|
20028
20100
|
...profile,
|
|
20029
20101
|
fps: syncCount > 0 ? (syncCount / (duration / 1e3)).toFixed(1) : "0"
|
|
20030
20102
|
};
|
|
20031
|
-
const reportPath =
|
|
20032
|
-
|
|
20033
|
-
|
|
20103
|
+
const reportPath = path11.join(context.outputDir, "perf-report.json");
|
|
20104
|
+
fs11.mkdirSync(path11.dirname(reportPath), { recursive: true });
|
|
20105
|
+
fs11.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
20034
20106
|
return {
|
|
20035
20107
|
success: true,
|
|
20036
20108
|
message: `${report.fps} fps, ${profile.avgSyncMs?.toFixed(1)}ms avg sync, ${nodeCount} nodes`,
|
|
@@ -20063,8 +20135,8 @@ var skill5 = {
|
|
|
20063
20135
|
},
|
|
20064
20136
|
async execute(params, context) {
|
|
20065
20137
|
const { chromium } = await import("playwright");
|
|
20066
|
-
const
|
|
20067
|
-
const
|
|
20138
|
+
const path11 = await import("path");
|
|
20139
|
+
const fs11 = await import("fs");
|
|
20068
20140
|
const browser = await launchReapedChrome((options) => chromium.launch(options), {
|
|
20069
20141
|
headless: true
|
|
20070
20142
|
});
|
|
@@ -20072,8 +20144,8 @@ var skill5 = {
|
|
|
20072
20144
|
try {
|
|
20073
20145
|
await page.goto(context.url, { waitUntil: "networkidle" });
|
|
20074
20146
|
await page.waitForTimeout(2e3);
|
|
20075
|
-
const outputPath =
|
|
20076
|
-
|
|
20147
|
+
const outputPath = path11.join(context.outputDir, `${params.name}.png`);
|
|
20148
|
+
fs11.mkdirSync(path11.dirname(outputPath), { recursive: true });
|
|
20077
20149
|
await page.screenshot({ path: outputPath });
|
|
20078
20150
|
return {
|
|
20079
20151
|
success: true,
|
|
@@ -20114,8 +20186,8 @@ var skill6 = {
|
|
|
20114
20186
|
},
|
|
20115
20187
|
async execute(params, context) {
|
|
20116
20188
|
const { chromium } = await import("playwright");
|
|
20117
|
-
const
|
|
20118
|
-
const
|
|
20189
|
+
const path11 = await import("path");
|
|
20190
|
+
const fs11 = await import("fs");
|
|
20119
20191
|
const browser = await launchReapedChrome((options) => chromium.launch(options), {
|
|
20120
20192
|
headless: true
|
|
20121
20193
|
});
|
|
@@ -20123,14 +20195,14 @@ var skill6 = {
|
|
|
20123
20195
|
try {
|
|
20124
20196
|
await page.goto(context.url, { waitUntil: "networkidle" });
|
|
20125
20197
|
await page.waitForTimeout(2e3);
|
|
20126
|
-
const currentPath =
|
|
20127
|
-
|
|
20198
|
+
const currentPath = path11.join(context.outputDir, `${params.name}-current.png`);
|
|
20199
|
+
fs11.mkdirSync(path11.dirname(currentPath), { recursive: true });
|
|
20128
20200
|
await page.screenshot({ path: currentPath });
|
|
20129
20201
|
try {
|
|
20130
20202
|
const { PNG } = await import("pngjs");
|
|
20131
20203
|
const pixelmatch = (await import("pixelmatch")).default;
|
|
20132
|
-
const baseline = PNG.sync.read(
|
|
20133
|
-
const current = PNG.sync.read(
|
|
20204
|
+
const baseline = PNG.sync.read(fs11.readFileSync(params.baseline));
|
|
20205
|
+
const current = PNG.sync.read(fs11.readFileSync(currentPath));
|
|
20134
20206
|
const { width, height } = baseline;
|
|
20135
20207
|
const diff = new PNG({ width, height });
|
|
20136
20208
|
const numDiffPixels = pixelmatch(
|
|
@@ -20141,8 +20213,8 @@ var skill6 = {
|
|
|
20141
20213
|
height,
|
|
20142
20214
|
{ threshold: params.threshold || 0.1 }
|
|
20143
20215
|
);
|
|
20144
|
-
const diffPath =
|
|
20145
|
-
|
|
20216
|
+
const diffPath = path11.join(context.outputDir, `${params.name}-diff.png`);
|
|
20217
|
+
fs11.writeFileSync(diffPath, PNG.sync.write(diff));
|
|
20146
20218
|
const totalPixels = width * height;
|
|
20147
20219
|
const diffPercent = (numDiffPixels / totalPixels * 100).toFixed(2);
|
|
20148
20220
|
return {
|
|
@@ -20206,10 +20278,10 @@ var skillRegistry = {
|
|
|
20206
20278
|
},
|
|
20207
20279
|
// load skills from a project manifest (sootsim-skills.json)
|
|
20208
20280
|
async loadFromManifest(projectDir) {
|
|
20209
|
-
const manifestPath =
|
|
20210
|
-
if (!
|
|
20281
|
+
const manifestPath = path10.join(projectDir, "sootsim-skills.json");
|
|
20282
|
+
if (!fs10.existsSync(manifestPath)) return;
|
|
20211
20283
|
try {
|
|
20212
|
-
const manifest = JSON.parse(
|
|
20284
|
+
const manifest = JSON.parse(fs10.readFileSync(manifestPath, "utf8"));
|
|
20213
20285
|
if (Array.isArray(manifest.skills)) {
|
|
20214
20286
|
for (const entry of manifest.skills) {
|
|
20215
20287
|
if (typeof entry === "string") {
|
|
@@ -20220,7 +20292,7 @@ var skillRegistry = {
|
|
|
20220
20292
|
}
|
|
20221
20293
|
} else if (entry.file) {
|
|
20222
20294
|
try {
|
|
20223
|
-
const mod = await import(
|
|
20295
|
+
const mod = await import(path10.resolve(projectDir, entry.file));
|
|
20224
20296
|
if (mod.skill) this.register(mod.skill);
|
|
20225
20297
|
} catch {
|
|
20226
20298
|
}
|
|
@@ -20233,10 +20305,10 @@ var skillRegistry = {
|
|
|
20233
20305
|
// auto-discover skills based on project dependencies
|
|
20234
20306
|
suggestSkills(projectDir) {
|
|
20235
20307
|
const suggestions = [];
|
|
20236
|
-
const pkgPath =
|
|
20237
|
-
if (!
|
|
20308
|
+
const pkgPath = path10.join(projectDir, "package.json");
|
|
20309
|
+
if (!fs10.existsSync(pkgPath)) return suggestions;
|
|
20238
20310
|
try {
|
|
20239
|
-
const pkg = JSON.parse(
|
|
20311
|
+
const pkg = JSON.parse(fs10.readFileSync(pkgPath, "utf8"));
|
|
20240
20312
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
20241
20313
|
if (deps["detox"] || deps["maestro"]) {
|
|
20242
20314
|
suggestions.push("maestro-test");
|