sootsim 0.1.146 → 0.1.148
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cli/bin.js +3 -3
- package/dist-cli/chunks/{agent-PNNXV6F3.js → agent-A5AQOHSI.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-JTYAONCG.js → agent-wrapper-S6AUOIXU.js} +2 -2
- package/dist-cli/chunks/{app-fonts-YGTRUUJT.js → app-fonts-MQDZ55OI.js} +2 -2
- package/dist-cli/chunks/{assert-HDFDQLHK.js → assert-USJNKN7R.js} +2 -2
- package/dist-cli/chunks/auto-bootstrap-CKH5ZZSJ.js +2 -0
- package/dist-cli/chunks/beta-Q6IKT5HT.js +2 -0
- package/dist-cli/chunks/{camera-4B7OAHRD.js → camera-C4SKSA76.js} +2 -2
- package/dist-cli/chunks/{chunk-H2EIYIRP.js → chunk-23QZQBTT.js} +1 -1
- package/dist-cli/chunks/{chunk-XO4VQYFP.js → chunk-2B26APLC.js} +2 -2
- package/dist-cli/chunks/{chunk-ERAE4LJT.js → chunk-2GROEF3J.js} +3 -3
- package/dist-cli/chunks/{chunk-K6X7LUFG.js → chunk-2OJ53PGA.js} +1 -1
- package/dist-cli/chunks/{chunk-PCW4TKI2.js → chunk-2SDVI2JB.js} +2 -2
- package/dist-cli/chunks/{chunk-C44OZFHJ.js → chunk-474QHKFY.js} +2 -2
- package/dist-cli/chunks/{chunk-YBSNSFBX.js → chunk-4JVDEEJJ.js} +1 -1
- package/dist-cli/chunks/{chunk-HWB7DPXH.js → chunk-4T5Q2CUU.js} +1 -1
- package/dist-cli/chunks/{chunk-DP5FSZHW.js → chunk-7EBPIOTW.js} +1 -1
- package/dist-cli/chunks/{chunk-HZHZY7N5.js → chunk-A57WJDB2.js} +2 -2
- package/dist-cli/chunks/{chunk-IAO27BWC.js → chunk-AXLTLDHE.js} +2 -2
- package/dist-cli/chunks/{chunk-4KNMAGC4.js → chunk-BCRYE4YH.js} +1 -1
- package/dist-cli/chunks/{chunk-A7JX3OQC.js → chunk-BCWW5RSQ.js} +1 -1
- package/dist-cli/chunks/{chunk-XRQDMB2J.js → chunk-BDKC2GLL.js} +2 -2
- package/dist-cli/chunks/{chunk-GD473DHN.js → chunk-BWE6H36P.js} +2 -2
- package/dist-cli/chunks/{chunk-AOPFT3S4.js → chunk-CKOXSYJ6.js} +1 -1
- package/dist-cli/chunks/{chunk-WFXLVOUA.js → chunk-CN3ACF52.js} +2 -2
- package/dist-cli/chunks/{chunk-IADMCPLZ.js → chunk-F3MFOV7R.js} +1 -1
- package/dist-cli/chunks/{chunk-2PYDOYIS.js → chunk-G5BKDQGP.js} +1 -1
- package/dist-cli/chunks/{chunk-ATJRNMNA.js → chunk-GXHVONDU.js} +2 -2
- package/dist-cli/chunks/{chunk-JFQXWAWN.js → chunk-IQVOFR7U.js} +2 -2
- package/dist-cli/chunks/{chunk-G7JMTSF6.js → chunk-IYRFX6KX.js} +1 -1
- package/dist-cli/chunks/chunk-JQFOV34Q.js +1 -0
- package/dist-cli/chunks/{chunk-TZXKFPBJ.js → chunk-K4QZ6WX6.js} +2 -2
- package/dist-cli/chunks/{chunk-UD4SYXDQ.js → chunk-KZ6AQHHA.js} +2 -2
- package/dist-cli/chunks/{chunk-RTD4RNZV.js → chunk-NK6RKGX2.js} +1 -1
- package/dist-cli/chunks/{chunk-MIIAYBFL.js → chunk-NMN4JPG2.js} +1 -1
- package/dist-cli/chunks/{chunk-VZSXOG4N.js → chunk-NOBEILT5.js} +1 -1
- package/dist-cli/chunks/{chunk-BBIN2U26.js → chunk-PMM6MNCR.js} +2 -2
- package/dist-cli/chunks/chunk-ROADBGFV.js +2 -0
- package/dist-cli/chunks/{chunk-MVLNHZMU.js → chunk-S3WEUJM3.js} +2 -2
- package/dist-cli/chunks/chunk-SY5JYGZE.js +1 -0
- package/dist-cli/chunks/{chunk-JZW2R5D7.js → chunk-T4FJHKU4.js} +2 -2
- package/dist-cli/chunks/{chunk-VKKWYLIZ.js → chunk-TWOGFNQ7.js} +1 -1
- package/dist-cli/chunks/{chunk-R7CMXY5T.js → chunk-TYHRA7FX.js} +2 -2
- package/dist-cli/chunks/{chunk-FK2YXBKR.js → chunk-U2U22DTV.js} +1 -1
- package/dist-cli/chunks/{chunk-H6LFGGJW.js → chunk-UK7GX57G.js} +2 -2
- package/dist-cli/chunks/chunk-V4EYA5L5.js +1 -0
- package/dist-cli/chunks/{chunk-SZNVNYEP.js → chunk-XWUUFV45.js} +2 -2
- package/dist-cli/chunks/{chunk-TLFNO2L4.js → chunk-XYFPDYAI.js} +1 -1
- package/dist-cli/chunks/{chunk-Q6BHESL2.js → chunk-Y5E53BEN.js} +2 -2
- package/dist-cli/chunks/{chunk-BE2ZDRIJ.js → chunk-YONGHIDE.js} +2 -2
- package/dist-cli/chunks/{chunk-MSQUL5BU.js → chunk-YXZD545S.js} +3 -3
- package/dist-cli/chunks/{chunk-2FYSNCRJ.js → chunk-ZMG6VGYA.js} +2 -2
- package/dist-cli/chunks/{chunk-35QJJ4MM.js → chunk-ZNYPWEMX.js} +3 -3
- package/dist-cli/chunks/cli-version-5KMLKVRO.js +2 -0
- package/dist-cli/chunks/{compat-F4WAO62Y.js → compat-7NMHHJXV.js} +3 -3
- package/dist-cli/chunks/{config-WAIORJNJ.js → config-XKL7G2P3.js} +2 -2
- package/dist-cli/chunks/{control-M54456XG.js → control-ZGD3NJES.js} +2 -2
- package/dist-cli/chunks/{cpu-profile-NNMDXCWI.js → cpu-profile-ITFDFMIJ.js} +2 -2
- package/dist-cli/chunks/{daemon-UXSN6QDY.js → daemon-LHFCZTK6.js} +2 -2
- package/dist-cli/chunks/{debug-JAQVYKQG.js → debug-C3X2PP3H.js} +3 -3
- package/dist-cli/chunks/{detox-QOL7PD62.js → detox-ITXRK6EB.js} +2 -2
- package/dist-cli/chunks/{device-WPAQY2ZH.js → device-PBA26VX4.js} +2 -2
- package/dist-cli/chunks/{diagnose-FKN4ALSH.js → diagnose-IWYHJJ7K.js} +2 -2
- package/dist-cli/chunks/drivers-5B4IZBF3.js +2 -0
- package/dist-cli/chunks/{electron-YQKH55P6.js → electron-6NRCOUQ3.js} +3 -3
- package/dist-cli/chunks/flow-ITIKFOJJ.js +2 -0
- package/dist-cli/chunks/help-A26MVCNK.js +2 -0
- package/dist-cli/chunks/{hints-GIJN25JB.js → hints-RBTS7PGP.js} +2 -2
- package/dist-cli/chunks/{home-paths-KIR4SAL4.js → home-paths-XKUYGHWD.js} +2 -2
- package/dist-cli/chunks/{inspect-YRP3UFG4.js → inspect-7V5RQUJM.js} +3 -3
- package/dist-cli/chunks/install-AJ3BWZ2Z.js +2 -0
- package/dist-cli/chunks/{install-desktop-INHP4VUQ.js → install-desktop-MD77SEFP.js} +3 -3
- package/dist-cli/chunks/{keys-CBKA6IB7.js → keys-LJMI7F3J.js} +2 -2
- package/dist-cli/chunks/{launch-JZ463USO.js → launch-RKUIUORR.js} +3 -3
- package/dist-cli/chunks/{login-VHP4DNC2.js → login-M7EXKPAT.js} +4 -4
- package/dist-cli/chunks/{logout-NRG4U6Z7.js → logout-OVAZMIW5.js} +2 -2
- package/dist-cli/chunks/{maestro-KPNXHCFR.js → maestro-S4RQPFHB.js} +2 -2
- package/dist-cli/chunks/optional-demo-registry-DA3SDA2G.js +2 -0
- package/dist-cli/chunks/{preview-O44G7W2U.js → preview-QSIZ6KNZ.js} +2 -2
- package/dist-cli/chunks/{profile-RMYP6I2J.js → profile-6QQ3G5X7.js} +2 -2
- package/dist-cli/chunks/{react-CFUB2U76.js → react-HR7OT4NK.js} +2 -2
- package/dist-cli/chunks/{record-YSLIYV2X.js → record-ZRSPOPCY.js} +2 -2
- package/dist-cli/chunks/runtime-X5RH4ZUA.js +2 -0
- package/dist-cli/chunks/{runtime-delivery-DDUSKKTU.js → runtime-delivery-MFVXZGIF.js} +2 -2
- package/dist-cli/chunks/{screenshot-MH7JQVO7.js → screenshot-QNQ4TJ3I.js} +2 -2
- package/dist-cli/chunks/{screenshot-mode-JRRQPP37.js → screenshot-mode-27K7PUTV.js} +2 -2
- package/dist-cli/chunks/{screenshots-32GEAUAF.js → screenshots-LH7R6LV3.js} +2 -2
- package/dist-cli/chunks/{server-ROXPXSIK.js → server-QQRPB6AJ.js} +12 -12
- package/dist-cli/chunks/setup-repo-CTPFDKV3.js +2 -0
- package/dist-cli/chunks/{skills-T74U4JC7.js → skills-KNFHQD77.js} +2 -2
- package/dist-cli/chunks/{slides-OM25OBW3.js → slides-GWMFQQAF.js} +2 -2
- package/dist-cli/chunks/{start-NLHWSRC7.js → start-4INDW3QD.js} +4 -4
- package/dist-cli/chunks/store-SIN5AXHS.js +2 -0
- package/dist-cli/chunks/telemetry-QHL6TKNR.js +2 -0
- package/dist-cli/chunks/{test-RYMENNXC.js → test-Q3CEHSD5.js} +3 -3
- package/dist-cli/chunks/three-mode-GTKSFFV7.js +58 -0
- package/dist-cli/chunks/{timeline-ANKR37NA.js → timeline-NBDNN5SP.js} +2 -2
- package/dist-cli/chunks/{upgrade-ZANSK5HX.js → upgrade-UE7B726I.js} +2 -2
- package/dist-cli/chunks/upload-UXXFJA3K.js +2 -0
- package/dist-cli/chunks/{version-DYXEOGY7.js → version-SS32LC2F.js} +2 -2
- package/dist-cli/chunks/{web-LUMZCTLY.js → web-A3EW2IWT.js} +2 -2
- package/dist-cli/chunks/{what-happened-SIQGZLHO.js → what-happened-NVKZVCHT.js} +2 -2
- package/dist-cli/chunks/{whoami-YI5RAQBT.js → whoami-FWRWWX2E.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +62 -3
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +62 -3
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/src/host/bridge-host.ts +92 -4
- package/dist-cli/chunks/auto-bootstrap-S7SSJMD3.js +0 -2
- package/dist-cli/chunks/beta-E3MSUPWU.js +0 -2
- package/dist-cli/chunks/chunk-3RPHEE3K.js +0 -2
- package/dist-cli/chunks/chunk-DRCRPS2N.js +0 -1
- package/dist-cli/chunks/chunk-OU42HTKN.js +0 -1
- package/dist-cli/chunks/chunk-Y76W7GZV.js +0 -1
- package/dist-cli/chunks/cli-version-AJWPSNS4.js +0 -2
- package/dist-cli/chunks/drivers-FTOUKVJ5.js +0 -2
- package/dist-cli/chunks/flow-EJXOH72E.js +0 -2
- package/dist-cli/chunks/help-ID6MSA6T.js +0 -2
- package/dist-cli/chunks/install-S4YF4O3O.js +0 -2
- package/dist-cli/chunks/optional-demo-registry-VXBG2NEH.js +0 -2
- package/dist-cli/chunks/runtime-YVV2FMMD.js +0 -2
- package/dist-cli/chunks/setup-repo-E2IJJBCE.js +0 -2
- package/dist-cli/chunks/store-EISWHA6H.js +0 -2
- package/dist-cli/chunks/telemetry-7AXVZMQT.js +0 -2
- package/dist-cli/chunks/three-mode-MK242N4J.js +0 -54
- package/dist-cli/chunks/upload-DWWZQMVH.js +0 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{C as T,D as A,E as y,P as _,Q as b,R as S}from"./chunk-
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{C as T,D as A,E as y,P as _,Q as b,R as S}from"./chunk-7EBPIOTW.js";import{c as N,e as F}from"./chunk-PMM6MNCR.js";import{b as k}from"./chunk-4JVDEEJJ.js";import"./chunk-U2U22DTV.js";import"./chunk-F3MFOV7R.js";import"./chunk-XYFPDYAI.js";function O(n){let t=[];for(let e=0;e<n.length;e++)if(n[e]==="--since"&&e+1<n.length){t.push(e,e+1);let s=n[e+1].trim(),l=/^(\d+(?:\.\d+)?)(ms|s|m)?$/.exec(s);if(l){let r=Number(l[1]),u=l[2]??"ms",v=u==="s"?r*1e3:u==="m"?r*6e4:r;return{since:Date.now()-v,consumed:t}}let i=Number(s);if(Number.isFinite(i)&&i>1e12)return{since:i,consumed:t}}return{consumed:t}}function B(n){let t=[];for(let e=0;e<n.length;e++)if(n[e]==="--kinds"&&e+1<n.length)return t.push(e,e+1),{kinds:n[e+1].split(",").map(s=>s.trim()).filter(Boolean),consumed:t};return{consumed:t}}function D(n){let t=[];for(let e=0;e<n.length;e++)if(n[e]==="--limit"&&e+1<n.length){t.push(e,e+1);let s=Number(n[e+1]);if(Number.isFinite(s)&&s>0)return{limit:s,consumed:t}}return{consumed:t}}function x(n){let t=[],e={label:"initial state",events:[],startedAt:n[0]?.t??null};t.push(e);for(let s of n)if(e.events.push(s),s.kind==="screen"||s.kind==="route"){let l=s.data,i=l?.phase;if(!i||i==="enter"||i==="appear"||i==="active"){let r=l?.name||l?.activeName||l?.path||l?.pathname||s.kind;t.length===1&&e.events.length===1?e.label=`${s.kind}: ${r}`:(e={label:`${s.kind}: ${r}`,events:[],startedAt:s.t},t.push(e))}}return t}async function J(n,t){let e=N(n,{port:t.port,stripBooleanFlags:["--summary","--all","--json","--no-advance","--help","-h","--flow","--noisy"],stripValueFlags:["--since","--kinds","--limit"]});(n.includes("--help")||n.includes("-h"))&&(console.log(`
|
|
3
3
|
sootsim what-happened \u2014 show recent events from the semantic timeline
|
|
4
4
|
|
|
5
5
|
usage:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{d as i}from"./chunk-
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{d as i}from"./chunk-A57WJDB2.js";import{d as n}from"./chunk-TYHRA7FX.js";import"./chunk-F3MFOV7R.js";import"./chunk-XYFPDYAI.js";async function u(){let o=i();if(o||(console.log(" not signed in"),console.log(" set SOOTSIM_API_KEY=sk_sootsim_\u2026 or run `sootsim login`"),process.exit(1)),o.kind==="api-key"){let r=`${o.secret.slice(0,14)}\u2026`,t=o.source==="env"?"SOOTSIM_API_KEY env var":"saved key (~/.config/sootsim/credentials.json)";console.log(` api key ${r}`),console.log(` source: ${t}`);return}if(o.kind==="github"){console.log(` github token (${o.source})`),console.log(` repo: ${o.repoId}`);return}let e=await n(),s=e?.user;console.log(` ${s?.email||s?.name||s?.id||"signed in"}`),console.log(` origin: ${e?.origin??o.origin}`),e?.updatedAt&&console.log(` updated: ${e.updatedAt}`)}export{u as runWhoami};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/beta.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/beta.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/config.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/detox/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/home-paths.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (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;
|
|
@@ -2784,9 +2784,24 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
2784
2784
|
// terminal 4001 code, so the client closes the abandoned window instead
|
|
2785
2785
|
// of reconnecting the zombie straight back in.
|
|
2786
2786
|
static SIM_IDLE_REAP_TTL_MS = 30 * 6e4;
|
|
2787
|
+
// automation sims (spawned by the playwright driver: `sootsim open --driver
|
|
2788
|
+
// playwright`, the factory/screenshot capture path — `meta.sootsimHostDriver
|
|
2789
|
+
// === 'playwright'`) are unattended one-shot browsers, never a human's tab. a
|
|
2790
|
+
// capture run opens one per slide/app/retry and the 30-min human/dev TTL lets
|
|
2791
|
+
// hundreds pile up inside the window — orphaned ms-playwright chromiums that
|
|
2792
|
+
// drove the box to swap-thrash (load hit 157 in one incident). give them a far
|
|
2793
|
+
// shorter idle TTL, and cap how many can sit concurrently: reap the most-idle
|
|
2794
|
+
// overflow, but never a sim active within ACTIVE_GRACE (an agent composing
|
|
2795
|
+
// between captures), nor primary / cli-attached / leased sims.
|
|
2796
|
+
static AUTOMATION_SIM_IDLE_REAP_TTL_MS = 10 * 6e4;
|
|
2797
|
+
static MAX_CONCURRENT_AUTOMATION_SIMS = 6;
|
|
2798
|
+
static AUTOMATION_SIM_ACTIVE_GRACE_MS = 6e4;
|
|
2787
2799
|
preferredPort;
|
|
2788
2800
|
portFallbackCount;
|
|
2789
2801
|
simIdleReapTtlMs;
|
|
2802
|
+
automationSimIdleReapTtlMs;
|
|
2803
|
+
maxConcurrentAutomationSims;
|
|
2804
|
+
automationSimActiveGraceMs;
|
|
2790
2805
|
shouldWriteLockfile;
|
|
2791
2806
|
sootbeanOrigin = null;
|
|
2792
2807
|
effectivePort = 0;
|
|
@@ -2823,6 +2838,9 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
2823
2838
|
this.agentHost = new AgentHost({ getExcludePorts: opts.agentScanExcludes });
|
|
2824
2839
|
this.sootbeanOrigin = opts.sootbeanOrigin?.replace(/\/$/, "") || null;
|
|
2825
2840
|
this.simIdleReapTtlMs = opts.simIdleReapTtlMs ?? _SootSimBridgeHost.SIM_IDLE_REAP_TTL_MS;
|
|
2841
|
+
this.automationSimIdleReapTtlMs = opts.automationSimIdleReapTtlMs ?? _SootSimBridgeHost.AUTOMATION_SIM_IDLE_REAP_TTL_MS;
|
|
2842
|
+
this.maxConcurrentAutomationSims = opts.maxConcurrentAutomationSims ?? _SootSimBridgeHost.MAX_CONCURRENT_AUTOMATION_SIMS;
|
|
2843
|
+
this.automationSimActiveGraceMs = opts.automationSimActiveGraceMs ?? _SootSimBridgeHost.AUTOMATION_SIM_ACTIVE_GRACE_MS;
|
|
2826
2844
|
}
|
|
2827
2845
|
/** expose the agent host so tests and embedders can inspect state or
|
|
2828
2846
|
* inject behavior. not part of the public WS protocol. */
|
|
@@ -3819,15 +3837,56 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
3819
3837
|
// using is the primary and/or holds a fresh user-active lease; one that is
|
|
3820
3838
|
// none of those and idle past the TTL is abandoned regardless of a stale
|
|
3821
3839
|
// focus flag.
|
|
3840
|
+
// automation sims are spawned by the playwright driver (`sootsim open
|
|
3841
|
+
// --driver playwright`, the factory/screenshot capture path), which tags them
|
|
3842
|
+
// with `meta.sootsimHostDriver === 'playwright'` via the host's addInitScript.
|
|
3843
|
+
// they are unattended one-shot browsers, never a human's tab, so they get a
|
|
3844
|
+
// shorter idle TTL and a concurrent cap.
|
|
3845
|
+
isAutomationSim(sim) {
|
|
3846
|
+
return sim.meta?.sootsimHostDriver === "playwright";
|
|
3847
|
+
}
|
|
3848
|
+
// an automation sim whose spawning playwright host process is still alive is
|
|
3849
|
+
// an ACTIVE run, not an abandoned tab. mirrors the cli's playwrightHostPidForSim
|
|
3850
|
+
// (control.ts): extract the host pid from meta, then check liveness so the
|
|
3851
|
+
// host-side idle GC never kills a live capture/factory sim mid-run.
|
|
3852
|
+
automationSimOwnerAlive(sim) {
|
|
3853
|
+
const pid = Number(sim.meta?.sootsimHostPid);
|
|
3854
|
+
if (!Number.isInteger(pid) || pid <= 1 || pid === process.pid) return false;
|
|
3855
|
+
try {
|
|
3856
|
+
process.kill(pid, 0);
|
|
3857
|
+
return true;
|
|
3858
|
+
} catch (err) {
|
|
3859
|
+
return err.code === "EPERM";
|
|
3860
|
+
}
|
|
3861
|
+
}
|
|
3822
3862
|
reapIdleSims(now = Date.now()) {
|
|
3823
3863
|
const attachedSimIds = new Set(this.cliSimBySocket.values());
|
|
3864
|
+
const automationLive = [];
|
|
3824
3865
|
for (const sim of this.sims.values()) {
|
|
3825
3866
|
if (sim.id === this.primarySimId) continue;
|
|
3826
3867
|
if (attachedSimIds.has(sim.id)) continue;
|
|
3827
3868
|
if (this.getActiveLease(sim)) continue;
|
|
3828
3869
|
const lastTouched = Math.max(sim.lastActiveAt, sim.connectedAt);
|
|
3829
|
-
|
|
3830
|
-
this.
|
|
3870
|
+
const idleMs = now - lastTouched;
|
|
3871
|
+
const automation = this.isAutomationSim(sim);
|
|
3872
|
+
if (automation && this.automationSimOwnerAlive(sim)) continue;
|
|
3873
|
+
const ttl = automation ? this.automationSimIdleReapTtlMs : this.simIdleReapTtlMs;
|
|
3874
|
+
if (idleMs >= ttl) {
|
|
3875
|
+
this.closeSimSocketFromHost(sim.ws);
|
|
3876
|
+
continue;
|
|
3877
|
+
}
|
|
3878
|
+
if (automation) automationLive.push({ sim, idleMs });
|
|
3879
|
+
}
|
|
3880
|
+
const cap = this.maxConcurrentAutomationSims;
|
|
3881
|
+
if (automationLive.length > cap) {
|
|
3882
|
+
automationLive.sort((a, b) => b.idleMs - a.idleMs);
|
|
3883
|
+
for (const { sim, idleMs } of automationLive.slice(
|
|
3884
|
+
0,
|
|
3885
|
+
automationLive.length - cap
|
|
3886
|
+
)) {
|
|
3887
|
+
if (idleMs < this.automationSimActiveGraceMs) continue;
|
|
3888
|
+
this.closeSimSocketFromHost(sim.ws);
|
|
3889
|
+
}
|
|
3831
3890
|
}
|
|
3832
3891
|
}
|
|
3833
3892
|
// ping every connected ws; if the previous round's ping went unanswered,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/host/fetch-proxy-overrides.ts
|
|
4
4
|
var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/metro.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/profiles.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/render-mode.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/sdk.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/sdk.mjs
CHANGED
package/dist-lib/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (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;
|
|
@@ -12824,9 +12824,24 @@ var init_bridge_host = __esm({
|
|
|
12824
12824
|
// terminal 4001 code, so the client closes the abandoned window instead
|
|
12825
12825
|
// of reconnecting the zombie straight back in.
|
|
12826
12826
|
static SIM_IDLE_REAP_TTL_MS = 30 * 6e4;
|
|
12827
|
+
// automation sims (spawned by the playwright driver: `sootsim open --driver
|
|
12828
|
+
// playwright`, the factory/screenshot capture path — `meta.sootsimHostDriver
|
|
12829
|
+
// === 'playwright'`) are unattended one-shot browsers, never a human's tab. a
|
|
12830
|
+
// capture run opens one per slide/app/retry and the 30-min human/dev TTL lets
|
|
12831
|
+
// hundreds pile up inside the window — orphaned ms-playwright chromiums that
|
|
12832
|
+
// drove the box to swap-thrash (load hit 157 in one incident). give them a far
|
|
12833
|
+
// shorter idle TTL, and cap how many can sit concurrently: reap the most-idle
|
|
12834
|
+
// overflow, but never a sim active within ACTIVE_GRACE (an agent composing
|
|
12835
|
+
// between captures), nor primary / cli-attached / leased sims.
|
|
12836
|
+
static AUTOMATION_SIM_IDLE_REAP_TTL_MS = 10 * 6e4;
|
|
12837
|
+
static MAX_CONCURRENT_AUTOMATION_SIMS = 6;
|
|
12838
|
+
static AUTOMATION_SIM_ACTIVE_GRACE_MS = 6e4;
|
|
12827
12839
|
preferredPort;
|
|
12828
12840
|
portFallbackCount;
|
|
12829
12841
|
simIdleReapTtlMs;
|
|
12842
|
+
automationSimIdleReapTtlMs;
|
|
12843
|
+
maxConcurrentAutomationSims;
|
|
12844
|
+
automationSimActiveGraceMs;
|
|
12830
12845
|
shouldWriteLockfile;
|
|
12831
12846
|
sootbeanOrigin = null;
|
|
12832
12847
|
effectivePort = 0;
|
|
@@ -12863,6 +12878,9 @@ var init_bridge_host = __esm({
|
|
|
12863
12878
|
this.agentHost = new AgentHost({ getExcludePorts: opts.agentScanExcludes });
|
|
12864
12879
|
this.sootbeanOrigin = opts.sootbeanOrigin?.replace(/\/$/, "") || null;
|
|
12865
12880
|
this.simIdleReapTtlMs = opts.simIdleReapTtlMs ?? _SootSimBridgeHost.SIM_IDLE_REAP_TTL_MS;
|
|
12881
|
+
this.automationSimIdleReapTtlMs = opts.automationSimIdleReapTtlMs ?? _SootSimBridgeHost.AUTOMATION_SIM_IDLE_REAP_TTL_MS;
|
|
12882
|
+
this.maxConcurrentAutomationSims = opts.maxConcurrentAutomationSims ?? _SootSimBridgeHost.MAX_CONCURRENT_AUTOMATION_SIMS;
|
|
12883
|
+
this.automationSimActiveGraceMs = opts.automationSimActiveGraceMs ?? _SootSimBridgeHost.AUTOMATION_SIM_ACTIVE_GRACE_MS;
|
|
12866
12884
|
}
|
|
12867
12885
|
/** expose the agent host so tests and embedders can inspect state or
|
|
12868
12886
|
* inject behavior. not part of the public WS protocol. */
|
|
@@ -13859,15 +13877,56 @@ var init_bridge_host = __esm({
|
|
|
13859
13877
|
// using is the primary and/or holds a fresh user-active lease; one that is
|
|
13860
13878
|
// none of those and idle past the TTL is abandoned regardless of a stale
|
|
13861
13879
|
// focus flag.
|
|
13880
|
+
// automation sims are spawned by the playwright driver (`sootsim open
|
|
13881
|
+
// --driver playwright`, the factory/screenshot capture path), which tags them
|
|
13882
|
+
// with `meta.sootsimHostDriver === 'playwright'` via the host's addInitScript.
|
|
13883
|
+
// they are unattended one-shot browsers, never a human's tab, so they get a
|
|
13884
|
+
// shorter idle TTL and a concurrent cap.
|
|
13885
|
+
isAutomationSim(sim) {
|
|
13886
|
+
return sim.meta?.sootsimHostDriver === "playwright";
|
|
13887
|
+
}
|
|
13888
|
+
// an automation sim whose spawning playwright host process is still alive is
|
|
13889
|
+
// an ACTIVE run, not an abandoned tab. mirrors the cli's playwrightHostPidForSim
|
|
13890
|
+
// (control.ts): extract the host pid from meta, then check liveness so the
|
|
13891
|
+
// host-side idle GC never kills a live capture/factory sim mid-run.
|
|
13892
|
+
automationSimOwnerAlive(sim) {
|
|
13893
|
+
const pid = Number(sim.meta?.sootsimHostPid);
|
|
13894
|
+
if (!Number.isInteger(pid) || pid <= 1 || pid === process.pid) return false;
|
|
13895
|
+
try {
|
|
13896
|
+
process.kill(pid, 0);
|
|
13897
|
+
return true;
|
|
13898
|
+
} catch (err) {
|
|
13899
|
+
return err.code === "EPERM";
|
|
13900
|
+
}
|
|
13901
|
+
}
|
|
13862
13902
|
reapIdleSims(now = Date.now()) {
|
|
13863
13903
|
const attachedSimIds = new Set(this.cliSimBySocket.values());
|
|
13904
|
+
const automationLive = [];
|
|
13864
13905
|
for (const sim of this.sims.values()) {
|
|
13865
13906
|
if (sim.id === this.primarySimId) continue;
|
|
13866
13907
|
if (attachedSimIds.has(sim.id)) continue;
|
|
13867
13908
|
if (this.getActiveLease(sim)) continue;
|
|
13868
13909
|
const lastTouched = Math.max(sim.lastActiveAt, sim.connectedAt);
|
|
13869
|
-
|
|
13870
|
-
this.
|
|
13910
|
+
const idleMs = now - lastTouched;
|
|
13911
|
+
const automation = this.isAutomationSim(sim);
|
|
13912
|
+
if (automation && this.automationSimOwnerAlive(sim)) continue;
|
|
13913
|
+
const ttl = automation ? this.automationSimIdleReapTtlMs : this.simIdleReapTtlMs;
|
|
13914
|
+
if (idleMs >= ttl) {
|
|
13915
|
+
this.closeSimSocketFromHost(sim.ws);
|
|
13916
|
+
continue;
|
|
13917
|
+
}
|
|
13918
|
+
if (automation) automationLive.push({ sim, idleMs });
|
|
13919
|
+
}
|
|
13920
|
+
const cap = this.maxConcurrentAutomationSims;
|
|
13921
|
+
if (automationLive.length > cap) {
|
|
13922
|
+
automationLive.sort((a, b) => b.idleMs - a.idleMs);
|
|
13923
|
+
for (const { sim, idleMs } of automationLive.slice(
|
|
13924
|
+
0,
|
|
13925
|
+
automationLive.length - cap
|
|
13926
|
+
)) {
|
|
13927
|
+
if (idleMs < this.automationSimActiveGraceMs) continue;
|
|
13928
|
+
this.closeSimSocketFromHost(sim.ws);
|
|
13929
|
+
}
|
|
13871
13930
|
}
|
|
13872
13931
|
}
|
|
13873
13932
|
// ping every connected ws; if the previous round's ping went unanswered,
|
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/package.json
CHANGED
package/src/host/bridge-host.ts
CHANGED
|
@@ -228,6 +228,18 @@ export interface BridgeHostOptions {
|
|
|
228
228
|
* can drive the real timer path deterministically instead of mocking
|
|
229
229
|
* time. production callers should never set this. */
|
|
230
230
|
simIdleReapTtlMs?: number
|
|
231
|
+
/** override the idle GC TTL (ms) for automation sims (playwright-driver,
|
|
232
|
+
* capture/factory). defaults to AUTOMATION_SIM_IDLE_REAP_TTL_MS (10 min).
|
|
233
|
+
* test-only, like simIdleReapTtlMs. */
|
|
234
|
+
automationSimIdleReapTtlMs?: number
|
|
235
|
+
/** cap on concurrent non-primary automation sims before the reaper drops
|
|
236
|
+
* the most-idle overflow. defaults to MAX_CONCURRENT_AUTOMATION_SIMS (6).
|
|
237
|
+
* test-only. */
|
|
238
|
+
maxConcurrentAutomationSims?: number
|
|
239
|
+
/** grace (ms) below which an automation sim is never reaped by the cap,
|
|
240
|
+
* even when over it. defaults to AUTOMATION_SIM_ACTIVE_GRACE_MS (60 s).
|
|
241
|
+
* test-only. */
|
|
242
|
+
automationSimActiveGraceMs?: number
|
|
231
243
|
}
|
|
232
244
|
|
|
233
245
|
const DAEMON_HEARTBEAT_INTERVAL_MS = 5_000
|
|
@@ -354,10 +366,25 @@ export class SootSimBridgeHost {
|
|
|
354
366
|
// terminal 4001 code, so the client closes the abandoned window instead
|
|
355
367
|
// of reconnecting the zombie straight back in.
|
|
356
368
|
private static SIM_IDLE_REAP_TTL_MS = 30 * 60_000
|
|
369
|
+
// automation sims (spawned by the playwright driver: `sootsim open --driver
|
|
370
|
+
// playwright`, the factory/screenshot capture path — `meta.sootsimHostDriver
|
|
371
|
+
// === 'playwright'`) are unattended one-shot browsers, never a human's tab. a
|
|
372
|
+
// capture run opens one per slide/app/retry and the 30-min human/dev TTL lets
|
|
373
|
+
// hundreds pile up inside the window — orphaned ms-playwright chromiums that
|
|
374
|
+
// drove the box to swap-thrash (load hit 157 in one incident). give them a far
|
|
375
|
+
// shorter idle TTL, and cap how many can sit concurrently: reap the most-idle
|
|
376
|
+
// overflow, but never a sim active within ACTIVE_GRACE (an agent composing
|
|
377
|
+
// between captures), nor primary / cli-attached / leased sims.
|
|
378
|
+
private static AUTOMATION_SIM_IDLE_REAP_TTL_MS = 10 * 60_000
|
|
379
|
+
private static MAX_CONCURRENT_AUTOMATION_SIMS = 6
|
|
380
|
+
private static AUTOMATION_SIM_ACTIVE_GRACE_MS = 60_000
|
|
357
381
|
|
|
358
382
|
private preferredPort: number
|
|
359
383
|
private portFallbackCount: number
|
|
360
384
|
private simIdleReapTtlMs: number
|
|
385
|
+
private automationSimIdleReapTtlMs: number
|
|
386
|
+
private maxConcurrentAutomationSims: number
|
|
387
|
+
private automationSimActiveGraceMs: number
|
|
361
388
|
private shouldWriteLockfile: boolean
|
|
362
389
|
private sootbeanOrigin: string | null = null
|
|
363
390
|
private effectivePort = 0
|
|
@@ -403,6 +430,12 @@ export class SootSimBridgeHost {
|
|
|
403
430
|
this.sootbeanOrigin = opts.sootbeanOrigin?.replace(/\/$/, '') || null
|
|
404
431
|
this.simIdleReapTtlMs =
|
|
405
432
|
opts.simIdleReapTtlMs ?? SootSimBridgeHost.SIM_IDLE_REAP_TTL_MS
|
|
433
|
+
this.automationSimIdleReapTtlMs =
|
|
434
|
+
opts.automationSimIdleReapTtlMs ?? SootSimBridgeHost.AUTOMATION_SIM_IDLE_REAP_TTL_MS
|
|
435
|
+
this.maxConcurrentAutomationSims =
|
|
436
|
+
opts.maxConcurrentAutomationSims ?? SootSimBridgeHost.MAX_CONCURRENT_AUTOMATION_SIMS
|
|
437
|
+
this.automationSimActiveGraceMs =
|
|
438
|
+
opts.automationSimActiveGraceMs ?? SootSimBridgeHost.AUTOMATION_SIM_ACTIVE_GRACE_MS
|
|
406
439
|
}
|
|
407
440
|
|
|
408
441
|
/** expose the agent host so tests and embedders can inspect state or
|
|
@@ -1624,8 +1657,35 @@ export class SootSimBridgeHost {
|
|
|
1624
1657
|
// using is the primary and/or holds a fresh user-active lease; one that is
|
|
1625
1658
|
// none of those and idle past the TTL is abandoned regardless of a stale
|
|
1626
1659
|
// focus flag.
|
|
1660
|
+
// automation sims are spawned by the playwright driver (`sootsim open
|
|
1661
|
+
// --driver playwright`, the factory/screenshot capture path), which tags them
|
|
1662
|
+
// with `meta.sootsimHostDriver === 'playwright'` via the host's addInitScript.
|
|
1663
|
+
// they are unattended one-shot browsers, never a human's tab, so they get a
|
|
1664
|
+
// shorter idle TTL and a concurrent cap.
|
|
1665
|
+
private isAutomationSim(sim: BridgeSimConnection): boolean {
|
|
1666
|
+
return sim.meta?.sootsimHostDriver === 'playwright'
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
// an automation sim whose spawning playwright host process is still alive is
|
|
1670
|
+
// an ACTIVE run, not an abandoned tab. mirrors the cli's playwrightHostPidForSim
|
|
1671
|
+
// (control.ts): extract the host pid from meta, then check liveness so the
|
|
1672
|
+
// host-side idle GC never kills a live capture/factory sim mid-run.
|
|
1673
|
+
private automationSimOwnerAlive(sim: BridgeSimConnection): boolean {
|
|
1674
|
+
const pid = Number(sim.meta?.sootsimHostPid)
|
|
1675
|
+
if (!Number.isInteger(pid) || pid <= 1 || pid === process.pid) return false
|
|
1676
|
+
try {
|
|
1677
|
+
process.kill(pid, 0) // ESRCH → dead; EPERM → alive but unsignalable
|
|
1678
|
+
return true
|
|
1679
|
+
} catch (err) {
|
|
1680
|
+
return (err as NodeJS.ErrnoException).code === 'EPERM'
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1627
1684
|
private reapIdleSims(now = Date.now()) {
|
|
1628
1685
|
const attachedSimIds = new Set(this.cliSimBySocket.values())
|
|
1686
|
+
// automation sims that pass every "someone cares" gate but are still under
|
|
1687
|
+
// their TTL — candidates for the concurrent-cap pass below.
|
|
1688
|
+
const automationLive: { sim: BridgeSimConnection; idleMs: number }[] = []
|
|
1629
1689
|
for (const sim of this.sims.values()) {
|
|
1630
1690
|
if (sim.id === this.primarySimId) continue
|
|
1631
1691
|
if (attachedSimIds.has(sim.id)) continue
|
|
@@ -1633,10 +1693,38 @@ export class SootSimBridgeHost {
|
|
|
1633
1693
|
// never-CLI-driven sims have lastActiveAt 0 — fall back to connectedAt
|
|
1634
1694
|
// so a freshly opened, not-yet-primary tab isn't reaped on the spot.
|
|
1635
1695
|
const lastTouched = Math.max(sim.lastActiveAt, sim.connectedAt)
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
//
|
|
1639
|
-
|
|
1696
|
+
const idleMs = now - lastTouched
|
|
1697
|
+
const automation = this.isAutomationSim(sim)
|
|
1698
|
+
// a live-owner automation sim is an ACTIVE run (its spawning playwright host
|
|
1699
|
+
// process is still alive) — never reap it. the host keeps Chrome alive
|
|
1700
|
+
// intentionally and tears it down itself when ITS owner driver dies; only
|
|
1701
|
+
// orphaned/host-dead autos are the leak this reaper targets. (2026-06: the
|
|
1702
|
+
// 10-min automation TTL was reaping live capture + factory sims mid-run —
|
|
1703
|
+
// too aggressive.) continue skips both the TTL reap and the cap pass below.
|
|
1704
|
+
if (automation && this.automationSimOwnerAlive(sim)) continue
|
|
1705
|
+
const ttl = automation ? this.automationSimIdleReapTtlMs : this.simIdleReapTtlMs
|
|
1706
|
+
if (idleMs >= ttl) {
|
|
1707
|
+
// terminal close → client closes the window, does not reconnect; the
|
|
1708
|
+
// 'close' handler runs rememberDisconnectedSim → this.sims.delete.
|
|
1709
|
+
this.closeSimSocketFromHost(sim.ws)
|
|
1710
|
+
continue
|
|
1711
|
+
}
|
|
1712
|
+
if (automation) automationLive.push({ sim, idleMs })
|
|
1713
|
+
}
|
|
1714
|
+
// concurrent cap: a burst of capture opens can pile up hundreds inside the
|
|
1715
|
+
// TTL window. keep at most maxConcurrentAutomationSims of the freshest;
|
|
1716
|
+
// reap the most-idle overflow, but never one active within the grace (an
|
|
1717
|
+
// agent mid-capture between screenshots).
|
|
1718
|
+
const cap = this.maxConcurrentAutomationSims
|
|
1719
|
+
if (automationLive.length > cap) {
|
|
1720
|
+
automationLive.sort((a, b) => b.idleMs - a.idleMs) // most-idle first
|
|
1721
|
+
for (const { sim, idleMs } of automationLive.slice(
|
|
1722
|
+
0,
|
|
1723
|
+
automationLive.length - cap,
|
|
1724
|
+
)) {
|
|
1725
|
+
if (idleMs < this.automationSimActiveGraceMs) continue
|
|
1726
|
+
this.closeSimSocketFromHost(sim.ws)
|
|
1727
|
+
}
|
|
1640
1728
|
}
|
|
1641
1729
|
}
|
|
1642
1730
|
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.146 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import{a,b,c,d}from"./chunk-MSQUL5BU.js";import"./chunk-BBIN2U26.js";import"./chunk-YBSNSFBX.js";import"./chunk-FK2YXBKR.js";import"./chunk-IADMCPLZ.js";import"./chunk-TLFNO2L4.js";export{c as ensureDaemonRunning,a as ensureRuntimeInstalled,d as ensureSootsimReady,b as resolveBootstrapPort};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.146 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.146 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.146 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.146 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import"./chunk-Y76W7GZV.js";import{a,b,c,d,e,f,g,h,i}from"./chunk-C44OZFHJ.js";import"./chunk-H2EIYIRP.js";import"./chunk-UD4SYXDQ.js";import"./chunk-DRCRPS2N.js";import"./chunk-A7JX3OQC.js";import"./chunk-YBSNSFBX.js";import"./chunk-IADMCPLZ.js";import"./chunk-TLFNO2L4.js";export{e as ALL_DRIVERS,i as buildDriverListRows,a as chromiumDriver,b as electronDriver,f as getAllDrivers,g as getDriver,c as playwrightDriver,h as resolveDriver,d as systemDriver};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.146 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import{a as c,b as d,c as e,d as f}from"./chunk-ERAE4LJT.js";import"./chunk-BE2ZDRIJ.js";import"./chunk-OU42HTKN.js";import"./chunk-PCW4TKI2.js";import"./chunk-JZW2R5D7.js";import"./chunk-HZHZY7N5.js";import{c as a,d as b}from"./chunk-H6LFGGJW.js";import"./chunk-IAO27BWC.js";import"./chunk-XRQDMB2J.js";import"./chunk-MVLNHZMU.js";import"./chunk-DP5FSZHW.js";import"./chunk-MIIAYBFL.js";import"./chunk-BBIN2U26.js";import"./chunk-G7JMTSF6.js";import"./chunk-C44OZFHJ.js";import"./chunk-H2EIYIRP.js";import"./chunk-UD4SYXDQ.js";import"./chunk-DRCRPS2N.js";import"./chunk-A7JX3OQC.js";import"./chunk-YBSNSFBX.js";import"./chunk-Q6BHESL2.js";import"./chunk-R7CMXY5T.js";import"./chunk-WFXLVOUA.js";import"./chunk-3RPHEE3K.js";import"./chunk-FK2YXBKR.js";import"./chunk-XO4VQYFP.js";import"./chunk-RTD4RNZV.js";import"./chunk-IADMCPLZ.js";import"./chunk-TLFNO2L4.js";export{c as discoverSootsimUrl,e as hoistLeadingSimFlag,a as parseFlowFile,f as runFlow,d as runFlowPlayback,b as validateFlowFile};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.146 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import{a,b,c}from"./chunk-TZXKFPBJ.js";import"./chunk-WFXLVOUA.js";import"./chunk-AOPFT3S4.js";import"./chunk-3RPHEE3K.js";import"./chunk-FK2YXBKR.js";import"./chunk-4KNMAGC4.js";import"./chunk-HWB7DPXH.js";import"./chunk-RTD4RNZV.js";import"./chunk-IADMCPLZ.js";import"./chunk-TLFNO2L4.js";export{c as printCommandHelp,b as printGroupHelp,a as printHelp};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.146 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import{a as o}from"./chunk-ATJRNMNA.js";import"./chunk-2PYDOYIS.js";import"./chunk-MSQUL5BU.js";import"./chunk-BBIN2U26.js";import"./chunk-YBSNSFBX.js";import"./chunk-Q6BHESL2.js";import"./chunk-R7CMXY5T.js";import"./chunk-FK2YXBKR.js";import"./chunk-IADMCPLZ.js";import"./chunk-TLFNO2L4.js";async function t(n){console.error(" note: `sootsim install` is now `sootsim setup-repo`. forwarding\u2026\n"),await o(n)}export{t as runInstall};
|