sootsim 0.1.305 → 0.1.307
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 +10 -4
- package/dist-cli/bin.js +5 -5
- package/dist-cli/chunks/{agent-OJP4VF2K.js → agent-BQ3KAQAU.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-HMVFZKH3.js → agent-wrapper-DS6FBIAI.js} +2 -2
- package/dist-cli/chunks/{app-fonts-INFYQMIN.js → app-fonts-VTLZYBCH.js} +2 -2
- package/dist-cli/chunks/{assert-YSFBCP5P.js → assert-MPQ4CDNH.js} +2 -2
- package/dist-cli/chunks/{auth-M7RKDYQV.js → auth-O3PQ5WAK.js} +2 -2
- package/dist-cli/chunks/{beta-4NRMM37T.js → beta-CHK46VAX.js} +2 -2
- package/dist-cli/chunks/{camera-MHLM35MB.js → camera-YOO6XYC5.js} +2 -2
- package/dist-cli/chunks/{chunk-6EXIYEOQ.js → chunk-2ODPPVQC.js} +2 -2
- package/dist-cli/chunks/{chunk-2UKSI3VX.js → chunk-2P5OBO7Z.js} +1 -1
- package/dist-cli/chunks/{chunk-R5TBMYGH.js → chunk-3JLFWHOZ.js} +1 -1
- package/dist-cli/chunks/{chunk-CWDEDUOZ.js → chunk-3S57XWPX.js} +1 -1
- package/dist-cli/chunks/{chunk-JKIPNRAK.js → chunk-4BZ6SM53.js} +24 -25
- package/dist-cli/chunks/{chunk-H5D6E3DR.js → chunk-4QCKHLRV.js} +2 -2
- package/dist-cli/chunks/{chunk-UUKUKTV3.js → chunk-537ULSCX.js} +11 -11
- package/dist-cli/chunks/chunk-5MN7CUQB.js +6 -0
- package/dist-cli/chunks/{chunk-XI6CPN53.js → chunk-6Q3FIZGP.js} +1 -1
- package/dist-cli/chunks/{chunk-TRV5K6D2.js → chunk-746PZ7ND.js} +1 -1
- package/dist-cli/chunks/{chunk-B65RMI7A.js → chunk-7HPBPICZ.js} +1 -1
- package/dist-cli/chunks/{chunk-2D7NF3XK.js → chunk-7T5WCLEU.js} +2 -2
- package/dist-cli/chunks/{chunk-KG2WUKD2.js → chunk-AD2J3Y5G.js} +2 -2
- package/dist-cli/chunks/chunk-BO2XSJJA.js +5 -0
- package/dist-cli/chunks/{chunk-IJ64Z77P.js → chunk-CKLXK3SU.js} +2 -2
- package/dist-cli/chunks/{chunk-DHDSGBZB.js → chunk-E2AY5MPI.js} +1 -1
- package/dist-cli/chunks/chunk-EWSHWBPU.js +4 -0
- package/dist-cli/chunks/chunk-EY5RFXHC.js +125 -0
- package/dist-cli/chunks/{chunk-6YE25EJB.js → chunk-FRTR2EUL.js} +3 -3
- package/dist-cli/chunks/{chunk-SWBTXTEO.js → chunk-IBM36KUP.js} +2 -2
- package/dist-cli/chunks/{chunk-WQYUHDBU.js → chunk-J52NXD2T.js} +2 -2
- package/dist-cli/chunks/chunk-KCRDI5B2.js +5 -0
- package/dist-cli/chunks/{chunk-JQRRJIMT.js → chunk-KPDYFXBD.js} +1 -1
- package/dist-cli/chunks/{chunk-NNR3BU5O.js → chunk-LL76B22R.js} +7 -7
- package/dist-cli/chunks/{chunk-4Q42Y64Y.js → chunk-LTS6OYSK.js} +2 -2
- package/dist-cli/chunks/{chunk-HKPJYMJC.js → chunk-NK72QUBY.js} +15 -12
- package/dist-cli/chunks/chunk-NLE5PR7V.js +15 -0
- package/dist-cli/chunks/{chunk-EWVEUNRO.js → chunk-NWOGE4YS.js} +81 -37
- package/dist-cli/chunks/{chunk-DTHOMSAA.js → chunk-OQ6KN4TP.js} +2 -2
- package/dist-cli/chunks/{chunk-W3M4676V.js → chunk-Q32TOAPX.js} +3 -3
- package/dist-cli/chunks/{chunk-54AINFEF.js → chunk-Q35WXZFI.js} +2 -2
- package/dist-cli/chunks/{chunk-BDNZULU7.js → chunk-QJ7B6FFD.js} +2 -2
- package/dist-cli/chunks/chunk-RCLJQZQR.js +4 -0
- package/dist-cli/chunks/chunk-S5QHC5LD.js +4 -0
- package/dist-cli/chunks/{chunk-VKBCGFOU.js → chunk-SKMVVRFI.js} +2 -2
- package/dist-cli/chunks/{chunk-EBCXFB3K.js → chunk-SLEKK2UU.js} +1 -1
- package/dist-cli/chunks/chunk-SZDXEZ2I.js +4 -0
- package/dist-cli/chunks/{chunk-43SNLCXR.js → chunk-SZX2PHDS.js} +1 -1
- package/dist-cli/chunks/{chunk-AJCL7DHI.js → chunk-UKKB52JO.js} +2 -2
- package/dist-cli/chunks/{chunk-R6MBDR56.js → chunk-UURKPOZU.js} +1 -1
- package/dist-cli/chunks/{chunk-3PREBGTH.js → chunk-WE6WXVYB.js} +2 -2
- package/dist-cli/chunks/{chunk-EPZG2F4I.js → chunk-WPVMW3I5.js} +1 -1
- package/dist-cli/chunks/{chunk-J653UMCU.js → chunk-WTWGQFNU.js} +2 -2
- package/dist-cli/chunks/{chunk-SLCYXISJ.js → chunk-XRUSCWIH.js} +2 -2
- package/dist-cli/chunks/{chunk-LOF3WUKB.js → chunk-XVQ2YGCI.js} +1 -1
- package/dist-cli/chunks/{chunk-HMOYEM6V.js → chunk-YIKFWG22.js} +2 -2
- package/dist-cli/chunks/{chunk-KVLXMWV5.js → chunk-YPKDDYIE.js} +2 -2
- package/dist-cli/chunks/{chunk-HHLH4TWF.js → chunk-Z772XMEF.js} +1 -1
- package/dist-cli/chunks/{chunk-KSZRLJPA.js → chunk-ZJR2AKLU.js} +2 -2
- package/dist-cli/chunks/{chunk-POIK3AHY.js → chunk-ZZBMQEEE.js} +2 -2
- package/dist-cli/chunks/{cleanup-ZJ7FQKED.js → cleanup-RT2PX5NP.js} +2 -2
- package/dist-cli/chunks/{cli-version-5LGCFOAC.js → cli-version-W3D5LXK5.js} +2 -2
- package/dist-cli/chunks/{compat-EQACACVP.js → compat-LGAXCMPJ.js} +2 -2
- package/dist-cli/chunks/{config-ADGNCDG5.js → config-3MQYRCSB.js} +2 -2
- package/dist-cli/chunks/control-MDWGTCXV.js +4 -0
- package/dist-cli/chunks/daemon-4FHSWZSV.js +4 -0
- package/dist-cli/chunks/{debug-PU73W33T.js → debug-UKOFTGI3.js} +3 -3
- package/dist-cli/chunks/desktop-N6TEZAIJ.js +31 -0
- package/dist-cli/chunks/{detox-SHVVEPPX.js → detox-T2Y4HE44.js} +2 -2
- package/dist-cli/chunks/{device-NMRUACB4.js → device-ZE2WSDJN.js} +2 -2
- package/dist-cli/chunks/{diagnose-S2AVGABT.js → diagnose-WFEFBH6U.js} +2 -2
- package/dist-cli/chunks/disk-cleanup-YXC3JGG5.js +4 -0
- package/dist-cli/chunks/drivers-62L33HHX.js +4 -0
- package/dist-cli/chunks/{film-UB7N4EKB.js → film-THTAWD5P.js} +3 -3
- package/dist-cli/chunks/flow-3HCUMLZL.js +4 -0
- package/dist-cli/chunks/help-KEXQPE2I.js +4 -0
- package/dist-cli/chunks/{hidden-runtime-alias-M44SGZLM.js → hidden-runtime-alias-SNP5LSQD.js} +2 -2
- package/dist-cli/chunks/{home-paths-ZTEBHBUO.js → home-paths-WUCC72RE.js} +2 -2
- package/dist-cli/chunks/inspect-2SR5AEEA.js +4 -0
- package/dist-cli/chunks/install-desktop-KE5ZPY6L.js +4 -0
- package/dist-cli/chunks/{login-YQ3HRPPS.js → login-ZEB4WSVZ.js} +4 -4
- package/dist-cli/chunks/{logout-XGBDWO4J.js → logout-P6PV2WRO.js} +2 -2
- package/dist-cli/chunks/{maestro-CESBE2SF.js → maestro-TUA7YURM.js} +3 -3
- package/dist-cli/chunks/{maestro-generate-4IHISKJL.js → maestro-generate-HI4UM47Q.js} +3 -3
- package/dist-cli/chunks/{mode-BQGGZ737.js → mode-ILLUAGCG.js} +2 -2
- package/dist-cli/chunks/optional-demo-registry-R7UFXPBP.js +4 -0
- package/dist-cli/chunks/{perf-TUR22UTE.js → perf-4CE5R2TN.js} +2 -2
- package/dist-cli/chunks/{permissions-POJIVSRV.js → permissions-NQCKUHGU.js} +2 -2
- package/dist-cli/chunks/{record-Q55SGXLU.js → record-5JRY7R54.js} +3 -3
- package/dist-cli/chunks/{report-issue-LRRX7VJV.js → report-issue-PFE7RDDV.js} +2 -2
- package/dist-cli/chunks/runtime-MP2QVB2X.js +4 -0
- package/dist-cli/chunks/{screenshot-command-C7EU43J3.js → screenshot-command-R3MPUAQI.js} +3 -3
- package/dist-cli/chunks/{screenshot-layers-NYVOJYUU.js → screenshot-layers-TKLUUDFA.js} +2 -2
- package/dist-cli/chunks/{screenshots-capture-AYKJKBLR.js → screenshots-capture-6UT2EVTR.js} +2 -2
- package/dist-cli/chunks/{serve-EN3ZPJSA.js → serve-L5GFNPAX.js} +3 -3
- package/dist-cli/chunks/{setup-KKMKLJZE.js → setup-IZQ7IXYW.js} +2 -2
- package/dist-cli/chunks/{skills-DR5DG2SK.js → skills-2CY6YIL7.js} +2 -2
- package/dist-cli/chunks/{storage-GMDBVTQ5.js → storage-EPY4VXCY.js} +2 -2
- package/dist-cli/chunks/store-F5RQZH7P.js +4 -0
- package/dist-cli/chunks/telemetry-MZKLKJAS.js +4 -0
- package/dist-cli/chunks/{timeline-VY3444AZ.js → timeline-LK5IA74W.js} +2 -2
- package/dist-cli/chunks/{upgrade-EUYCW55F.js → upgrade-ZK6YJMUA.js} +2 -2
- package/dist-cli/chunks/upload-LP6UOKRF.js +4 -0
- package/dist-cli/chunks/{version-TEGM4WRU.js → version-SRC2HVYI.js} +2 -2
- package/dist-cli/chunks/{web-QF7LF4VB.js → web-SVNHYKX5.js} +2 -2
- package/dist-cli/chunks/{what-happened-HDTJGNND.js → what-happened-URW3Q7QP.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +43 -21
- 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 +8 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +51 -41
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +222 -302
- 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 +43 -13
- package/dist-lib/sdk.cjs +47 -10
- package/dist-lib/sdk.mjs +47 -10
- package/dist-lib/skills.cjs +11364 -6863
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/scripts/dev-server-scanner.ts +9 -15
- package/scripts/optional-demo-registry.ts +52 -10
- package/skills/sootsim-debug/SKILL.md +4 -5
- package/skills/sootsim-setup/SKILL.md +29 -49
- package/src/bridge-constants.ts +15 -0
- package/src/host/bridge-host.ts +0 -16
- package/src/host/open-url.ts +2 -147
- package/src/plist.ts +27 -0
- package/src/settings-bundle.ts +2 -23
- package/src/skills/builtin/maestro-test.ts +4 -1
- package/src/vite-plugin.ts +2 -1
- package/dist-cli/chunks/chunk-COD6QGS2.js +0 -125
- package/dist-cli/chunks/chunk-KVOY4Z2X.js +0 -4
- package/dist-cli/chunks/chunk-OCRL2VU4.js +0 -4
- package/dist-cli/chunks/chunk-PELXRGDN.js +0 -4
- package/dist-cli/chunks/chunk-QJUKXBH5.js +0 -15
- package/dist-cli/chunks/chunk-QVH276LI.js +0 -5
- package/dist-cli/chunks/chunk-WIRBJTTU.js +0 -7
- package/dist-cli/chunks/chunk-XWMTLVCE.js +0 -4
- package/dist-cli/chunks/chunk-ZRQFYMTL.js +0 -4
- package/dist-cli/chunks/control-Y3E5IIMO.js +0 -4
- package/dist-cli/chunks/daemon-A6CWUYMR.js +0 -4
- package/dist-cli/chunks/desktop-V675PYF4.js +0 -34
- package/dist-cli/chunks/disk-cleanup-EJEZIIT4.js +0 -4
- package/dist-cli/chunks/drivers-PM4PVYHY.js +0 -4
- package/dist-cli/chunks/flow-XJRNL25V.js +0 -4
- package/dist-cli/chunks/help-2ZJHCVUZ.js +0 -4
- package/dist-cli/chunks/inspect-L76RUF62.js +0 -4
- package/dist-cli/chunks/install-desktop-UIXKNXKF.js +0 -4
- package/dist-cli/chunks/optional-demo-registry-LWYRXVIE.js +0 -4
- package/dist-cli/chunks/runtime-NHDHZJJN.js +0 -4
- package/dist-cli/chunks/store-QZEMKQDC.js +0 -4
- package/dist-cli/chunks/telemetry-TNX72J2B.js +0 -4
- package/dist-cli/chunks/upload-D43U7RGT.js +0 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.307 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
3
|
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
-
import{G as E,H as F,I as j,k as L,l as N,u as U,x as _}from"./chunk-
|
|
4
|
+
import{G as E,H as F,I as j,k as L,l as N,u as U,x as _}from"./chunk-SLEKK2UU.js";import z from"node:fs";import G from"node:path";function A(e){return e.length<=100&&/^[0-9A-Za-z][0-9A-Za-z._+-]*$/.test(e)}function M(e){try{return z.readdirSync(e.runtimesDir(),{withFileTypes:!0}).filter(c=>c.isDirectory()).map(c=>c.name).sort(k)}catch{return[]}}function T(e,c){return G.posix.basename(e.tarballPath(c))}function k(e,c){let l=f=>{let v=f.indexOf("-"),V=v>=0?f.slice(0,v):f,$=v>=0?f.slice(v+1):"",D=V.split(".").map(I=>Number.parseInt(I,10));return D.some(I=>!Number.isFinite(I))?[[Number.POSITIVE_INFINITY],f]:[D,$]},[m,u]=l(e),[R,x]=l(c);for(let f=0;f<Math.max(m.length,R.length);f++){let v=m[f]??0,V=R[f]??0;if(v!==V)return v-V}return u===x?0:u?x?u<x?-1:1:-1:1}import{spawn as Z}from"node:child_process";import J from"node:crypto";import o from"node:fs";import Y from"node:os";import y from"node:path";import{Readable as q}from"node:stream";import{pipeline as B}from"node:stream/promises";var K=2;function H(e){function c(){try{let n=JSON.parse(o.readFileSync(e.configFile(),"utf8"));return n&&typeof n=="object"?n:{}}catch{return{}}}function l(n){let t=c();return(n||process.env[e.env.cdnOrigin]||t.cdnOrigin||e.defaultCdnOrigin).replace(/\/+$/,"")}function m(n){let t=c();return n||process.env[e.env.channel]||t.runtimeChannel||"stable"}function u(){if(!e.env.pin)return null;let n=process.env[e.env.pin];if(n&&n.trim())return n.trim();let t=c();return typeof t.runtimeVersion=="string"&&t.runtimeVersion.trim()?t.runtimeVersion.trim():null}function R(n){let t=new URL(`${l(n)}${e.manifestPath}`);return t.searchParams.set("t",String(Date.now())),t.toString()}function x(n,t){return`${l(t)}${e.tarballPath(n)}`}async function f(n){let t=R(n),r=await fetch(t,{headers:{Accept:"application/json"}});if(!r.ok)throw new Error(`manifest fetch failed: ${r.status} ${r.statusText} (${t})`);return await r.json()}function v(n,t={}){let r=m(t.channel),i=t.version||u()||n.channels[r]?.latest;if(!i)throw new Error(`no version specified and channel '${r}' has no latest entry in the manifest`);if(!A(i))throw new Error(`invalid runtime version: ${i}`);let h=n.versions[i];if(!h)throw new Error(`version ${i} not found in manifest; available: ${Object.keys(n.versions).slice(-10).join(", ")||"(none)"}`);return{version:i,channel:r,entry:h}}async function V(n={}){e.ensureHome();let t=l(n.cdnOrigin),r=await f(t),{version:i,channel:h,entry:a}=v(r,n),d=e.runtimeDir(i),g=n.setActive!==!1,O=[i,...n.protectVersions??[]];if(b({protectVersions:O}),!n.force&&o.existsSync(y.join(d,e.installedMarker)))return g&&e.writeActiveRuntime(i),b({protectVersions:O}),{version:i,channel:h,cdnOrigin:t,runtimeDir:d,installed:!1,activated:g,manifest:r};let P=a.tarball||x(i,t),S=o.mkdtempSync(y.join(Y.tmpdir(),`${e.id}-runtime-download-`)),w=y.join(S,T(e,i)),p=y.join(y.dirname(d),`.installing-${i}-${process.pid}`);o.rmSync(p,{recursive:!0,force:!0});try{process.stderr.write(`${e.id}: downloading runtime ${i}\u2026
|
|
5
5
|
`),await Q(P,w),process.stderr.write(`${e.id}: extracting runtime ${i}\u2026
|
|
6
6
|
`);let s=await X(w);if(s!==a.sha256)throw new Error(`sha256 mismatch for runtime ${i}: expected ${a.sha256}, actual ${s}`);if(o.mkdirSync(p,{recursive:!0}),await ee(w,p),!o.existsSync(y.join(p,e.installedMarker)))throw new Error(`extracted tarball for runtime ${i} is missing ${e.installedMarker}`);o.rmSync(d,{recursive:!0,force:!0}),o.renameSync(p,d)}catch(s){throw o.rmSync(p,{recursive:!0,force:!0}),s}finally{o.rmSync(S,{recursive:!0,force:!0})}return g&&e.writeActiveRuntime(i),b({protectVersions:O}),{version:i,channel:h,cdnOrigin:t,runtimeDir:d,installed:!0,activated:g,manifest:r}}async function $(n={}){e.ensureHome(),b({protectVersions:n.protectVersions});let t=l(n.cdnOrigin),r=m(n.channel),i=u();if(i){let p=e.readActiveRuntime(),s=o.existsSync(y.join(e.runtimeDir(i),e.installedMarker));if(p===i&&s)return{checked:!0,updated:!1,reason:`runtime is pinned to ${i}`,activeVersion:p,latestVersion:i};let C=await V({version:i,channel:r,cdnOrigin:t,setActive:!1,protectVersions:n.protectVersions});return{checked:!0,updated:!0,reason:`runtime is pinned to ${i}`,activeVersion:i,latestVersion:i,install:C}}let h=await f(t),a=h.channels[r]?.latest;if(!a)return{checked:!0,updated:!1,reason:`channel '${r}' has no latest runtime`,activeVersion:e.readActiveRuntime()};if(!h.versions[a])return{checked:!0,updated:!1,reason:`manifest is missing version ${a}`,activeVersion:e.readActiveRuntime(),latestVersion:a};let g=e.readActiveRuntime(),O=g?e.runtimeDir(g):null,P=O?o.existsSync(y.join(O,e.installedMarker)):!1;if(!(!g||!P||k(a,g)>0))return{checked:!0,updated:!1,reason:"active runtime is current",activeVersion:g,latestVersion:a};let w=await V({version:a,channel:r,cdnOrigin:t,setActive:!1,protectVersions:n.protectVersions});return{checked:!0,updated:!0,activeVersion:a,latestVersion:a,install:w}}async function D(n={}){let t=e.readActiveRuntime(),r=u();if(r)return{active:t,latest:r,pinned:r,outdated:t!==r};try{let i=await f(l(n.cdnOrigin)),h=m(n.channel),a=i.channels[h]?.latest??null,d=!!(a&&(!t||k(a,t)>0));return{active:t,latest:a,pinned:null,outdated:d}}catch{return{active:t,latest:null,pinned:null,outdated:!1}}}function I(n={}){e.ensureHome();let t=Math.max(1,Math.floor(n.retainVersions??K)),r=M(e),i=new Set(r),h=e.readActiveRuntime(),a=u(),d=new Set;for(let s of[h,a,...n.protectVersions??[]])s&&i.has(s)&&d.add(s);for(let s of[...r].reverse()){if(d.size>=t)break;d.add(s)}let g="__RUNTIME_VERSION__",O=T(e,g),P=O.indexOf(g),S=O.slice(0,P),w=O.slice(P+g.length),p=[];if(P>=0)try{p=o.readdirSync(e.cacheDir(),{withFileTypes:!0}).filter(s=>{if(!s.isFile())return!1;let C=s.name.startsWith(S)&&s.name.endsWith(w),W=s.name.startsWith(S)&&s.name.endsWith(`${w}.partial`);return C||W}).map(s=>y.join(e.cacheDir(),s.name)).sort()}catch{}return{activeVersion:h,pinnedVersion:a,keepVersions:r.filter(s=>d.has(s)),removeVersions:r.filter(s=>!d.has(s)),removeCacheFiles:p}}function b(n={}){let t=I(n);for(let r of t.removeVersions)o.rmSync(e.runtimeDir(r),{recursive:!0,force:!0});for(let r of t.removeCacheFiles)o.rmSync(r,{force:!0});return t}return{product:e,resolveCdnOrigin:l,resolveChannel:m,resolvePin:u,manifestUrl:R,tarballUrl:x,fetchManifest:f,resolveVersion:v,install:V,updateToLatest:$,checkUpToDate:D,planLocalRetention:I,pruneLocalRetention:b,listInstalled:()=>M(e)}}async function Q(e,c){let l=await fetch(e);if(!l.ok||!l.body)throw new Error(`download failed: ${l.status} ${l.statusText} (${e})`);o.mkdirSync(y.dirname(c),{recursive:!0});let m=`${c}.partial`;try{await B(q.fromWeb(l.body),o.createWriteStream(m)),o.renameSync(m,c)}catch(u){try{o.unlinkSync(m)}catch{}throw u}}function X(e){return new Promise((c,l)=>{let m=J.createHash("sha256"),u=o.createReadStream(e);u.on("data",R=>m.update(R)),u.on("error",l),u.on("end",()=>c(m.digest("hex")))})}function ee(e,c){return new Promise((l,m)=>{let u=Z("tar",["-xzf",e,"-C",c],{stdio:["ignore","inherit","inherit"]});u.on("error",m),u.on("exit",R=>{R===0?l():m(new Error(`tar exited with code ${R}`))})})}var ne="https://contrast.dev",ve="https://sootsim.com/changelog",Oe="https://contrast.dev/api/changelog/sootsim",te={id:"sootsim",defaultCdnOrigin:ne,manifestPath:"/runtimes/manifest.json",tarballPath:e=>`/runtimes/sootsim-runtime-${e}.tar.gz`,installedMarker:"index.html",env:{cdnOrigin:"SOOTSIM_CDN_ORIGIN",channel:"SOOTSIM_RUNTIME_CHANNEL"},ensureHome:E,configFile:_,runtimesDir:L,runtimeDir:N,cacheDir:U,readActiveRuntime:F,writeActiveRuntime:j},ye=H(te);export{A as a,k as b,ne as c,ve as d,Oe as e,ye as f};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.307 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
3
|
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
-
import{a as o}from"./chunk-
|
|
4
|
+
import{a as o}from"./chunk-YPKDDYIE.js";var c=["ghs_","ghp_","gho_","ghu_","github_pat_"];function d(n){return!!(n&&n.length>=20&&c.some(t=>n.startsWith(t)))}function p(){let n=process.env.CONTRAST_INSTALLATION_TOKEN?.trim(),t=process.env.GITHUB_TOKEN?.trim(),e=n||t;if(!d(e))return null;let r=(process.env.CONTRAST_REPO||process.env.GITHUB_REPOSITORY||"").trim();if(!r)return null;let[i,s]=r.includes("/")?r.split("/",2):[null,null],u=(process.env.CONTRAST_REPO_ID||process.env.GITHUB_REPOSITORY_ID||"").trim(),l=(process.env.CONTRAST_INSTALLATION_ID||process.env.GITHUB_APP_INSTALLATION_ID||"").trim();return{kind:"github",token:e,repoId:r,repositoryId:u||null,owner:i||null,repo:s||null,installationId:l||null,source:n?"contrast-runner":"github-actions"}}function a(){let n=process.env.SOOTSIM_API_KEY?.trim();if(n&&n.startsWith("sk_sootsim_"))return{kind:"api-key",secret:n,source:"env"};let t=p();if(t)return t;let e=o();return e?.token?{kind:"session",token:e.token,origin:e.origin}:null}function g(n){return n.kind==="api-key"?`Bearer ${n.secret}`:`Bearer ${n.token}`}function _(n){return!n||n.kind!=="github"?null:{repoId:n.repoId,owner:n.owner??void 0,repo:n.repo??void 0,installationId:n.installationId}}export{a,g as b,_ as c};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/*! sootsim v0.1.307 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
|
+
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
+
import{a as u,b as c}from"./chunk-5MN7CUQB.js";var w="http://localhost:7668/";var _=5173;var I=2e3;function y(t){let r=t-7668;return r<0||r>I?null:`http://localhost:${_+r}/`}var A=4001,C="sootsim close";import{existsSync as T,mkdirSync as O,readFileSync as d,rmSync as l,writeFileSync as P}from"fs";import{tmpdir as E}from"os";import{dirname as g,join as R,resolve as b}from"path";var p=1,S="SOOTSIM_CLI_CURRENT_SIM_PATH",h=["SOOTSIM_CLI_IDENTITY","TM_SESSION","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","TERM_SESSION_ID","ITERM_SESSION_ID","TMUX_PANE","STY","KITTY_WINDOW_ID","WEZTERM_PANE","ALACRITTY_WINDOW_ID","WINDOWID","VSCODE_INJECTION"],m=/^(?:tmux|screen)|^tm$/i;function a(t,r=20){let e=t,o=u(t);if(!o||o<=1){let n=c(t);return t>1&&n&&!m.test(n)?t:null}for(let n=0;n<r;n++){let s=c(o);if(s&&m.test(s))return e;let i=u(o);if(!i||i<=1)return s?o:e;e=o,o=i}return o}function D(){for(let r of h){let e=process.env[r];if(e&&e.trim())return{key:`${r}:${e.trim()}`,source:r,stable:!0}}let t=a(process.ppid);return t&&t>1?{key:`gppid-${t}`,source:"grand-ppid",stable:!0}:{key:`pid-${process.ppid}`,source:"ppid",stable:!1}}function x(){return D().key}function H(){return a(process.ppid)}function f(){if(process.env[S])return b(process.env[S]);let t=x();return R(E(),`sootsim-current-sim-${t}.json`)}function U(){let t=f();if(!T(t))return null;try{let r=JSON.parse(d(t,"utf8"));return r.version!==p||typeof r.simId!="string"||!r.simId.trim()||typeof r.updatedAt!="string"?(l(t,{force:!0}),null):{version:p,simId:r.simId.trim(),updatedAt:r.updatedAt}}catch{return l(t,{force:!0}),null}}function v(){return U()?.simId||null}function F(t){let r=t.trim();if(!r)return;let e=f();O(g(e),{recursive:!0}),P(e,JSON.stringify({version:p,simId:r,updatedAt:new Date().toISOString()},null,2)+`
|
|
5
|
+
`)}function V(){l(f(),{force:!0})}export{w as a,y as b,A as c,C as d,D as e,x as f,H as g,v as h,F as i,V as j};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.307 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
3
|
var require = __sootsimCreateRequire(import.meta.url)
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.307 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
3
|
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
-
import{
|
|
5
|
-
`)}var
|
|
6
|
-
`)}return t.on("message",s=>{let
|
|
7
|
-
\u26A0 ${
|
|
4
|
+
import{e as A,h as T,j as E}from"./chunk-KCRDI5B2.js";import{K as I,L as B,M as w,N as P,g as F}from"./chunk-SLEKK2UU.js";var b="http://localhost:5173/";import{WebSocket as $}from"ws";var C=null;function M(){let i=F();if(C?.homeDir===i)return C.world;let r=_();return C={homeDir:i,world:r},r}function _(){let i=B();if(i&&P(i))return{source:"dev-bridge",bridgePort:i.bridgePort,shellBaseUrl:i.shellPort?`http://localhost:${i.shellPort}/`:b};let r=I();return r&&w(r)?{source:"daemon",bridgePort:r.bridgePort,shellBaseUrl:r.runtimePort>0?`http://localhost:${r.runtimePort}/`:b}:{source:"default",bridgePort:7668,shellBaseUrl:b}}function U(i){let r=B();if(r&&P(r)&&r.bridgePort===i)return{source:"dev-bridge",shellBaseUrl:r.shellPort?`http://localhost:${r.shellPort}/`:b};let e=I();return e&&w(e)&&e.bridgePort===i?{source:"daemon",shellBaseUrl:e.runtimePort>0?`http://localhost:${e.runtimePort}/`:b}:null}function Q(i){let r;try{let l=new URL(i);r=l.port?Number(l.port):l.protocol==="https:"?443:80}catch{return null}if(!Number.isFinite(r)||r<=0)return null;let e=B();if(e&&P(e)&&(e.shellPort===r||e.runtimePort===r||e.bridgePort===r))return e.bridgePort;let o=I();return o&&w(o)&&(o.runtimePort===r||o.bridgePort===r)?o.bridgePort:null}function D(){return M().bridgePort}function z(i,r){let e=U(i),o=e?.source==="dev-bridge"?"dev bridge":e?.source==="daemon"?"daemon bridge":"bridge",l=e?`${e.source}.json`:"no lockfile",t=r??e?.shellBaseUrl;process.stderr.write(` \u2192 ${o} :${i} (${t?`shell ${t}, `:""}${l})
|
|
5
|
+
`)}var L=class extends Error{lock;constructor(r,e){super(r),this.name="BridgeSimLockedError",this.lock=e}};function N(i){return i==="flag"?"via --sim":i==="saved"?"saved via `sootsim use`":"primary fallback \u2014 no sim pinned"}function X(i,r={}){let e=new Set,o=r.port??D(),l=r.commandTimeoutMs??15e3,t,u="none",v=new Set(r.stripBooleanFlags??[]),y=new Set(r.stripValueFlags??[]);for(let n=0;n<i.length;n++){let a=i[n];if(a==="--port"||a==="-p"){e.add(n),n+1<i.length&&(e.add(n+1),o=Number(i[n+1])),n++;continue}if(a.startsWith("--port=")){e.add(n),o=Number(a.slice(7));continue}if(a==="--timeout"){e.add(n),n+1<i.length&&(e.add(n+1),l=Number(i[n+1])),n++;continue}if(a==="--sim"||a==="--session"||a==="--tab"){e.add(n),n+1<i.length&&(e.add(n+1),t=i[n+1]?.trim()||void 0,u="flag"),n++;continue}let s=a.startsWith("--sim=")?a.slice(6):a.startsWith("--session=")?a.slice(10):a.startsWith("--tab=")?a.slice(6):void 0;if(s!==void 0){e.add(n),t=s.trim()||void 0,u="flag";continue}if(v.has(a)){e.add(n);continue}y.has(a)&&(e.add(n),n+1<i.length&&e.add(n+1),n++)}if(!t){let n=T();n&&(t=n.trim()||void 0,u="saved")}return{positional:i.filter((n,a)=>!e.has(a)),wsPort:o,simId:t,simIdSource:u,commandTimeoutMs:l}}function R(i,r={}){let e=1,o=r.commandTimeoutMs??15e3,l=new Map,t=new $(`ws://localhost:${i}`),u=A(),v=new Promise((s,d)=>{t.on("open",()=>{try{t.send(JSON.stringify({type:"bridge:hello",id:0,cliIdentityKey:u.key,cliIdentitySource:u.source,cliLabel:r.cliLabel}))}catch{}s()}),t.on("error",c=>{let m=c.message?`: ${c.message}`:"";d(new Error(`could not connect to ws://localhost:${i}${m}`))})}),y=!1,n=!1;function a(s,d){if(n||process.env.SOOTSIM_QUIET_TARGET_NOTICE==="1"||s.startsWith("bridge:")||s==="focus"||s==="close")return;n=!0;let c=d??"primary",m=N(d?r.simIdSource:"none");process.stderr.write(` \u2192 ${c} (${m})
|
|
6
|
+
`)}return t.on("message",s=>{let d;try{d=JSON.parse(s.toString())}catch{return}if(d.id===0)return;let c=l.get(d.id);c&&(l.delete(d.id),d._otherCliCount>0&&!y&&(y=!0,process.stderr.write(`
|
|
7
|
+
\u26A0 ${d._otherCliCount} other CLI identity/identities are driving this sim
|
|
8
8
|
taps, scrolls, and keyboard input from multiple agents will collide on
|
|
9
9
|
the same screen state (this is not a bridge throughput limit).
|
|
10
10
|
use \`sootsim open --new\` for an isolated sim per agent.
|
|
11
11
|
|
|
12
|
-
`)),
|
|
12
|
+
`)),d.error?d._locked?c.reject(new L(d.error,d._locked)):c.reject(new Error(d.error)):c.resolve(d.result))}),t.on("close",(s,d)=>{let c=d?.toString()||"connection closed";for(let[m,h]of l)l.delete(m),h.reject(new Error(`sim disconnected: ${c} (code ${s})`))}),{async send(s,d){let c=d?.timeoutMs??o,m=async g=>{await v;let f=e++;return new Promise((p,W)=>{let x=setTimeout(()=>{l.delete(f),W(new Error(`command timed out after ${Math.round(c/1e3)}s`))},c);l.set(f,{resolve:k=>{clearTimeout(x),p(k)},reject:k=>{clearTimeout(x),W(k)}});let S={...s,id:f};S.simId===void 0&&g&&(S.simId=g),a(s.type??"",S.simId),t.send(JSON.stringify(S))})},h=r.simIdSource==="flag"?r.simId:T()??r.simId;try{return await m(h)}catch(g){let f=g instanceof Error?g.message:String(g),p=`no sim connected with id ${h}`;throw r.simIdSource!=="flag"&&h&&s.simId===void 0&&(f===p||f.startsWith(`${p};`))?(E(),new Error(`saved sim ${h} is gone${f.slice(p.length)}; run \`sootsim list\` and \`sootsim use <sim>\`, or open a fresh sim`)):g}},async listSims(){let s=await this.send({type:"bridge:list-sims"});return Array.isArray(s)?s:[]},async focusSim(s){return this.send({type:"focus",simId:s})},async closeSim(s){return this.send({type:"close",simId:s})},async claim(s,d={}){return await this.send({type:"bridge:claim",simId:s,force:d.force===!0})},close(){try{t.readyState===$.OPEN&&t.send(JSON.stringify({type:"bridge:bye",id:0}))}catch{}t.close();let s=setTimeout(()=>{t.readyState!==$.CLOSED&&t.terminate()},250)}}}function Y(i){return R(i.wsPort,{commandTimeoutMs:i.commandTimeoutMs,simId:i.simId,simIdSource:i.simIdSource})}function V(i,r){let e=i.filter(t=>t.readyState==="open"&&t.id!==r),o=e.find(t=>t.userFocused)??e.find(t=>t.userVisible===!0&&t.isPrimary)??e.find(t=>t.userVisible===!0)??e.find(t=>t.isPrimary);if(!o)return null;let l=[o.isPrimary?"primary":null,o.userVisible===!1?"hidden":o.userVisible===!0?"visible":null,o.userFocused?"focused":null].filter(Boolean);return`${o.id}${l.length?` [${l.join(", ")}]`:""}`}async function Z(i){try{let r=await i.send({type:"evaluate",code:`(() => ({
|
|
13
13
|
hidden: document.hidden,
|
|
14
14
|
visibilityState: document.visibilityState,
|
|
15
15
|
hasFocus: typeof document.hasFocus === 'function' ? document.hasFocus() : null,
|
|
@@ -23,4 +23,4 @@ import{b as A,e as T,g as E}from"./chunk-WIRBJTTU.js";import{K as S,L as I,M as
|
|
|
23
23
|
`+(l?` another open sim looks usable: ${l}; target it with --sim.
|
|
24
24
|
`:" run `sootsim list` to find the visible sim and target it with --sim.\n")+` page-level window.focus() cannot unhide a browser tab.
|
|
25
25
|
|
|
26
|
-
`),{hidden:!0,warned:!0,simId:e.simId}}return{hidden:!1,warned:!1,simId:e.simId}}catch{return{hidden:!1,warned:!1}}}async function ee(i,r,e={}){let
|
|
26
|
+
`),{hidden:!0,warned:!0,simId:e.simId}}return{hidden:!1,warned:!1,simId:e.simId}}catch{return{hidden:!1,warned:!1}}}async function ee(i,r,e={}){let o={type:"evaluate",code:r};return e.acquireLock&&(o.acquireLock=!0),i.send(o)}async function re(i,r,...e){return i.send({type:"call",path:r,args:e})}async function ie(i,r,...e){return i.send({type:"call",path:r,args:e,acquireLock:!0})}export{b as a,M as b,U as c,Q as d,D as e,z as f,L as g,X as h,R as i,Y as j,Z as k,ee as l,re as m,ie as n};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.307 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
3
|
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
-
import{H as t,L as n,N as l,j as r}from"./chunk-
|
|
4
|
+
import{H as t,L as n,N as l,j as r}from"./chunk-SLEKK2UU.js";function m(){let e=t(),i=r()?n():null;return i&&l(i)?{primary:`engine dev source (:${i.bridgePort})`,installedRuntime:e?`installed runtime v${e}`:null,isDevBridge:!0}:{primary:e?`runtime v${e}`:"runtime not installed",installedRuntime:null,isDevBridge:!1}}export{m as a};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.307 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
3
|
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
-
import{a as m,b as
|
|
5
|
-
`,"utf8"),
|
|
4
|
+
import{a as m,b as I}from"./chunk-SZX2PHDS.js";import{a as D}from"./chunk-6Q3FIZGP.js";import{b as _}from"./chunk-5MN7CUQB.js";import{G as O,o as x,q as f}from"./chunk-SLEKK2UU.js";import p from"fs";import g from"path";var c="default",F="profiles.json",a=1;function n(e){let r=e.trim();if(!r)throw new Error("profile id is required");if(!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(r))throw new Error("profile ids must start with a letter or number and contain only letters, numbers, dot, dash, or underscore");if(r==="."||r==="..")throw new Error(`invalid profile id: ${r}`);return r}function w(){return g.join(f(),F)}function $(e){return`sootsim-profile-${n(e)}`}function G(e){return g.join(x(),"Partitions",$(e))}function v(e){return g.join(f(),"playwright",n(e))}function b(){try{let e=JSON.parse(p.readFileSync(w(),"utf8"));if(!e||e.version!==a)return{version:a,profiles:[]};let r=Array.isArray(e.profiles)?e.profiles.filter(t=>!!t&&typeof t.id=="string"&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string").map(t=>({id:n(t.id),createdAt:t.createdAt,updatedAt:t.updatedAt})):[];return{version:a,profiles:r}}catch{return{version:a,profiles:[]}}}function E(e){return[...e].sort((r,t)=>r.id===c?-1:t.id===c?1:r.id.localeCompare(t.id))}function y(e){if(e.profiles.some(t=>t.id===c))return{...e,profiles:E(e.profiles)};let r=new Date().toISOString();return{version:a,profiles:E([{id:c,createdAt:r,updatedAt:r},...e.profiles])}}function P(e){O();let r=y(e),t=`${w()}.tmp`;return p.writeFileSync(t,`${JSON.stringify(r,null,2)}
|
|
5
|
+
`,"utf8"),p.renameSync(t,w()),r}function U(){return P(b()).profiles}function B(e){let r=n(e);return U().find(t=>t.id===r)??null}function T(e=c){let r=n(e),t=B(r);return t||j(r)}function j(e){let r=n(e),t=y(b());if(t.profiles.some(u=>u.id===r))throw new Error(`profile already exists: ${r}`);let o=new Date().toISOString(),i={id:r,createdAt:o,updatedAt:o};return P({version:a,profiles:[...t.profiles,i]}),i}function ae(e){let r=n(e);if(r===c)throw new Error("the default profile cannot be deleted; clear it instead");let t=y(b()),o=t.profiles.find(i=>i.id===r);if(!o)throw new Error(`profile not found: ${r}`);return P({version:a,profiles:t.profiles.filter(i=>i.id!==r)}),q(r),o}function q(e){let r=n(e);for(let t of[G(r),v(r)])try{p.rmSync(t,{recursive:!0,force:!0})}catch{}}function H(){let e=m();return e?{available:!0,reason:null,detail:`${e.kind} @ ${e.path}`}:{available:!1,reason:"sootsim desktop app not installed (run `sootsim desktop install`)"}}async function z(e){let r=m();if(!r)return{launched:!1,message:"sootsim desktop app not installed"};try{let t=await I(e.url,r,{device:e.device,profileId:e.profileId,ephemeralProfile:e.ephemeralProfile,ownerPid:e.ownerPid});return t.launched?{launched:!0,message:e.url?`electron launched via ${t.via} \u2192 ${e.url}`:`electron launched via ${t.via}`,target:t.target,attachUrl:e.url}:{launched:!1,message:"desktop companion failed to start"}}catch(t){return{launched:!1,message:`electron launch failed: ${t instanceof Error?t.message:String(t)}`}}}var C={id:"electron",name:"electron",description:"sootsim desktop companion app (native window, menu bar)",kind:"native",availability:H,launch:z};import{spawn as K}from"child_process";import{closeSync as Y,mkdtempSync as V,openSync as J,readFileSync as X}from"fs";import{createRequire as Z}from"module";import{tmpdir as A}from"os";import{join as M}from"path";var Q=`
|
|
6
6
|
const modulePath = process.env.SOOTSIM_PW_MODULE;
|
|
7
7
|
const url = process.env.SOOTSIM_PW_URL;
|
|
8
8
|
// the WS bridge port the sim page must register with, injected below as
|
|
@@ -12,9 +12,10 @@ const bridgePort = process.env.SOOTSIM_PW_BRIDGE_PORT || '';
|
|
|
12
12
|
const headless = process.env.SOOTSIM_PW_HEADLESS === '1';
|
|
13
13
|
const callerUserDataDir = process.env.SOOTSIM_PW_USERDATADIR || '';
|
|
14
14
|
// pid of the session that launched us (its topmost non-init ancestor). when
|
|
15
|
-
// that process exits we tear Chrome down \u2014 see startOwnerWatch below.
|
|
16
|
-
//
|
|
17
|
-
// the 5s poll interval;
|
|
15
|
+
// that process exits we tear Chrome down \u2014 see startOwnerWatch below. it is a
|
|
16
|
+
// required lifetime bound: an invalid value aborts before Chrome launches.
|
|
17
|
+
// SOOTSIM_PW_OWNER_POLL_MS is a test-only override of the 5s poll interval;
|
|
18
|
+
// production never sets it.
|
|
18
19
|
const ownerPid = Number(process.env.SOOTSIM_PW_OWNER_PID || 0);
|
|
19
20
|
const ownerPollMs = Number(process.env.SOOTSIM_PW_OWNER_POLL_MS || 5000);
|
|
20
21
|
// optional CDP port \u2014 exposes Chrome's remote-debugging endpoint so a
|
|
@@ -56,7 +57,7 @@ const viewport = viewportSpec
|
|
|
56
57
|
const deviceScaleFactor = Number(process.env.SOOTSIM_PW_DSF || 2);
|
|
57
58
|
const closeTimeoutMs = Number(process.env.SOOTSIM_PW_CLOSE_TIMEOUT_MS || 2500);
|
|
58
59
|
const connectAckFile = process.env.SOOTSIM_PW_CONNECTED_ACK_FILE || '';
|
|
59
|
-
const disposableBrowserCacheDirs = new Set(${JSON.stringify(
|
|
60
|
+
const disposableBrowserCacheDirs = new Set(${JSON.stringify(D)});
|
|
60
61
|
const { existsSync, mkdtempSync, readdirSync, rmSync, unlinkSync } = require('fs');
|
|
61
62
|
const { execSync } = require('child_process');
|
|
62
63
|
const { tmpdir } = require('os');
|
|
@@ -267,7 +268,9 @@ const cleanupProfile = () => {
|
|
|
267
268
|
// down when it's gone. ESRCH (kill throws) = owner exited; EPERM = alive but
|
|
268
269
|
// not signalable by us, which still counts as alive.
|
|
269
270
|
const startOwnerWatch = () => {
|
|
270
|
-
if (!Number.isInteger(ownerPid) || ownerPid <= 1)
|
|
271
|
+
if (!Number.isInteger(ownerPid) || ownerPid <= 1) {
|
|
272
|
+
throw new Error('[playwright-driver] missing valid owning process; refusing unsupervised browser host');
|
|
273
|
+
}
|
|
271
274
|
const intervalMs = Number.isFinite(ownerPollMs) && ownerPollMs > 0 ? ownerPollMs : 5000;
|
|
272
275
|
ownerWatch = setInterval(() => {
|
|
273
276
|
try {
|
|
@@ -402,7 +405,7 @@ const cleanupProfile = () => {
|
|
|
402
405
|
const hostMeta = {
|
|
403
406
|
sootsimHostDriver: 'playwright',
|
|
404
407
|
sootsimHostPid: process.pid,
|
|
405
|
-
sootsimHostOwnerPid: ownerPid
|
|
408
|
+
sootsimHostOwnerPid: ownerPid,
|
|
406
409
|
sootsimHostStartedAt: Date.now(),
|
|
407
410
|
};
|
|
408
411
|
// inject the resolved bridge port (numeric literal) BEFORE the page runs, so
|
|
@@ -496,6 +499,6 @@ const cleanupProfile = () => {
|
|
|
496
499
|
process.stderr.write(String((err && err.stack) || err) + '\\n');
|
|
497
500
|
process.exit(1);
|
|
498
501
|
});
|
|
499
|
-
`;function
|
|
500
|
-
${l}`:""}${
|
|
501
|
-
${
|
|
502
|
+
`;function L(){let e=[process.cwd()+"/"];try{process.argv[1]&&e.push(process.argv[1])}catch{}for(let r of e)try{let t=Z(r);for(let o of["playwright","playwright-chromium","playwright-core"])try{return{spec:o,modulePath:t.resolve(o)}}catch{}}catch{}return null}function ee(){let e=L();return e?{available:!0,reason:null,detail:`resolved via ${e.spec}`}:{available:!1,reason:"playwright not installed in the current workspace"}}function re(e,r){return process.platform!=="linux"||e.headless||process.env.DISPLAY||process.env.WAYLAND_DISPLAY||!/missing x server|cannot open display|x server|x11/i.test(r)?null:" hint: linux without DISPLAY/WAYLAND_DISPLAY \u2014 rerun without --headed (or add --headless) to run playwright headless."}function te(e){return e.profileId?v(T(e.profileId).id):e.ephemeralProfile?V(M(A(),"sootsim-playwright-profile-")):""}async function oe(e){let r=L();if(!r)return{launched:!1,message:"playwright not installed \u2014 run `bun add -D playwright` first"};if(!e.url)return{launched:!1,message:"playwright driver requires a target url"};let t=e.ownerPid;if(t===void 0||!Number.isInteger(t)||t<=1)return{launched:!1,message:"playwright driver requires a valid owning session process"};let o=M(A(),`sootsim-playwright-host-${Date.now().toString(36)}-${process.pid}.log`),i=`${o}.connected`,u=J(o,"a");try{let s=K(process.execPath,["-e",Q],{detached:!0,stdio:["ignore","ignore",u],env:{...process.env,SOOTSIM_PW_MODULE:r.modulePath,SOOTSIM_PW_URL:e.url,SOOTSIM_PW_BRIDGE_PORT:e.bridgePort?String(e.bridgePort):"",SOOTSIM_PW_HEADLESS:e.headless??!0?"1":"0",SOOTSIM_PW_USERDATADIR:te(e),SOOTSIM_PW_CDP_PORT:e.cdpPort?String(e.cdpPort):"",SOOTSIM_PW_BROWSER:e.browser??"",SOOTSIM_PW_VIEWPORT:e.viewport?`${e.viewport.width}x${e.viewport.height}`:"",SOOTSIM_PW_CONNECTED_ACK_FILE:i,SOOTSIM_PW_CONNECT_TIMEOUT_MS:String(e.connectTimeoutMs??12e4),SOOTSIM_PW_OWNER_PID:String(t)}});s.unref();let S=await new Promise(l=>{let h=setTimeout(()=>l(null),4e3);s.once("exit",N=>{clearTimeout(h),l(N??0)})});if(S!==null){let l=X(o,"utf8").trim(),h=re(e,l);return{launched:!1,message:`playwright host exited early (code ${S}) \u2014 host log ${o}${l?`:
|
|
503
|
+
${l}`:""}${h?`
|
|
504
|
+
${h}`:""}`}}let k=_(t),W=` \u2014 browser closes when pid ${t}${k?` (${k})`:""} exits`;return{launched:!0,message:`playwright chrome launched \u2192 ${e.url}${W}`,pid:s.pid,target:r.spec,attachUrl:e.url,connectAckFile:i,diagnosticLogPath:o}}catch(s){return{launched:!1,message:`playwright launch failed: ${s instanceof Error?s.message:String(s)}`}}finally{Y(u)}}var R={id:"playwright",name:"playwright",description:"programmatic chromium via the playwright package \u2014 headless default",kind:"automation",availability:ee,launch:oe};var d=[C,R];function Se(){return d}function ke(e){return d.find(r=>r.id===e)??null}function xe(e,r){if(e)return d.find(o=>o.id===e)??null;for(let t of r){let o=d.find(i=>i.id===t);if(o&&o.availability().available)return o}return null}function Oe(){return d.map(e=>{let r=e.availability();return{id:e.id,name:e.name,kind:e.kind,description:e.description,available:r.available,reason:r.reason,detail:r.detail??null}})}export{U as a,T as b,j as c,ae as d,q as e,C as f,R as g,d as h,Se as i,ke as j,xe as k,Oe as l};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*! sootsim v0.1.307 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
|
+
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
+
import{a as I,b as Le,c as Ne}from"./chunk-4QCKHLRV.js";import{m as A}from"./chunk-CKLXK3SU.js";import{m as Re,p as Ue}from"./chunk-UURKPOZU.js";import{b as Ae,j as qe}from"./chunk-NK72QUBY.js";import{a as We,b as Ke,d as ze}from"./chunk-RCLJQZQR.js";import{a as Oe,b as L,c as ae,d as le,e as De,f as Be,h as je,i as z,j as He}from"./chunk-537ULSCX.js";import{a as Fe}from"./chunk-SKMVVRFI.js";import{a as ce}from"./chunk-746PZ7ND.js";import{b as Ee,c as _e,d as ie,f as Te,g as Me,h as _,i as P,j as T}from"./chunk-LL76B22R.js";import{f as Pe}from"./chunk-IBM36KUP.js";import{b as se,d as Ie}from"./chunk-2ODPPVQC.js";import{b as ke,g as Ce,h as D,i as x,j as B}from"./chunk-KCRDI5B2.js";import{H as $e,K as oe,M as q,O as xe,l as re}from"./chunk-SLEKK2UU.js";import{spawn as Ze,spawnSync as Xe}from"node:child_process";import M from"node:fs";import kt from"node:os";import R from"node:path";import{WebSocket as Ct}from"ws";function Ve(e){return new Error(`could not resolve a native bundle for ${e}. pass an explicit bundle URL or open Connect and choose the app there.`)}function yt(e,t){return e?.includes("/one/metro-entry.bundle")?"one":typeof t=="string"&&t?"expo":"unknown"}function Je(e,t,n){return`${e}//${t}:${n}`}function St(e){if(typeof window>"u")return!1;try{let t=new URL(e);return I(t.hostname)&&I(window.location.hostname)&&t.origin!==window.location.origin}catch{return!1}}async function Ge(e,t){let n={...t,cache:t?.cache??"no-store"};return St(e)?fetch(`/__fetch-proxy?url=${encodeURIComponent(e)}`,n):fetch(e,n)}function $t(e){return e==="https:"?443:80}function xt(e){let t=e.pathname||"/";return(t==="/"||t==="")&&!e.search&&!e.hash}async function Pt(e){try{let t=await fetch("/__server-scan",{cache:"no-store"});if(!t.ok||!(t.headers.get("content-type")||"").toLowerCase().includes("json"))return null;let n=await t.json();if(!Array.isArray(n))return null;let r=n.find(o=>!!o&&typeof o=="object"&&o.port===e&&typeof o.bundleUrl=="string");return r?{bundleUrl:le(r.bundleUrl),port:e,framework:typeof r.framework=="string"?r.framework:"unknown",projectName:typeof r.projectName=="string"?r.projectName:void 0}:null}catch{return null}}async function Qe(e,t){let n=e.replace(/\/+$/,"");try{if(I(new URL(n).hostname)){let r=await Pt(t);if(r)return r}}catch{}try{let r=await Ge(`${n}/`,{headers:{"expo-platform":"ios"}});if(r.ok){let o=await r.json(),s=o?.extra?.expoClient||o?.extra||{},i=typeof o?.launchAsset?.url=="string"?o.launchAsset.url:void 0;if(i||s.name)return{bundleUrl:le(i||`${n}${ae}`),port:t,framework:yt(i,s.sdkVersion),projectName:s.name}}}catch{}try{let r=await Ge(`${n}/status`);if(r.ok&&(await r.text()).includes("packager-status:running"))return{bundleUrl:`${n}${ae}`,port:t,framework:"metro"}}catch{}return null}async function It(e){return Qe(Je("http:","localhost",e),e)}async function Ye(e){let t=e.trim();if(/^\d+$/.test(t)){let a=parseInt(t,10),l=await It(a);if(l)return l;throw Ve(`localhost:${a}`)}let n=t.startsWith("http")?t:`http://${t}`,r;try{r=new URL(n)}catch{throw new Error(`could not parse "${e}". pass a dev-server port, a dev-server base URL, or a full bundle URL.`)}let o=r.protocol||"http:",s=r.port?parseInt(r.port,10):$t(o),i=Je(o,r.hostname,s);if(xt(r)){let a=await Qe(i,s);if(a)return a;throw Ve(i)}return{bundleUrl:r.toString(),port:s,framework:"unknown"}}var Rt=12e4,et=100,Ut=5e3,tt=1e4,Et={rn:"/rn",connectrn:"/rn","connect-rn":"/rn",clock:"/app/clock","native-ui":"/app/native-ui",tamagui:"/app/tamagui",settings:"/app/settings",photos:"/app/photos",camera:"/app/camera"};function S(e){return new Promise(t=>setTimeout(t,e))}function nt(e){let t=process.env[e]?.trim();if(!t)return null;let n=Number(t);return Number.isInteger(n)&&n>0?n:null}function _t(){let e=nt("SOOTSIM_DRIVER_CONNECT_TIMEOUT_MS")??nt("SOOTSIM_PW_CONNECT_TIMEOUT_MS")??Rt;return{timeoutMs:e,hostTimeoutMs:e+Ut,intervalMs:et,attempts:Math.max(1,Math.ceil(e/et))}}function rt(e){return e==="electron"||e==="playwright"}function ue(e,t){return t==="playwright"?e.meta?.sootsimHostDriver==="playwright":e.userAgent?.includes("Electron/")===!0}function Tt(e,t){return e.includes("--headless")?!0:e.includes("--headed")?!1:t==="playwright"&&process.platform==="linux"&&!process.env.DISPLAY&&!process.env.WAYLAND_DISPLAY?(console.error(" no display detected \u2192 running playwright headless (override with --headed)"),!0):!1}function J(e){return e.trim()}var ct=/^[A-Za-z][A-Za-z0-9+.-]*:/;function Mt(e){let t=e.trim();if(!t)throw new Error("expected <url-or-route>");return ct.test(t)||t.startsWith("/")?t:`/${t}`}function Ot(e){return e!==null&&typeof e=="object"}function Dt(e){let t=e.trim();return t?t.startsWith("/")?!0:ct.test(t)?!/^https?:\/\//i.test(t):!1:!1}async function Bt(e){if(await V(e,250))return e;let t=oe();if(t&&q(t)&&await V(t.bridgePort,500))return t.bridgePort;if(t&&q(t))throw new Error(`sootsim bridge lockfile is fresh (port ${t.bridgePort}) but the bridge is not reachable. run \`sootsim daemon restart\` or \`sootsim daemon uninstall\`.`);await At();let n=Lt(["serve","--quiet","--port",String(e)]),r=null;n.once("exit",(s,i)=>{r=String(s??i??"unknown")}),n.unref();let o=Date.now()+tt;for(;Date.now()<o;){let s=oe();if(s&&q(s)&&await V(s.bridgePort,250))return console.error(` started local bridge on port ${s.bridgePort}; run \`sootsim setup\` to install the background daemon`),s.bridgePort;if(await V(e,250))return console.error(` started local bridge on port ${e}; run \`sootsim setup\` to install the background daemon`),e;if(r)throw new Error(`sootsim bridge exited before becoming ready (exit ${r})`);await S(150)}throw new Error(`sootsim bridge did not start within ${Math.round(tt/1e3)}s`)}async function At(){let e=$e();if(e&&M.existsSync(re(e)))return;console.error(" installing sootsim engine runtime...");let{runRuntime:t}=await import("./runtime-MP2QVB2X.js");await t(["install"],{})}function Lt(e){let t=process.argv[1];return t&&M.existsSync(t)?Ze(process.execPath,[t,...e],{detached:!0,stdio:"ignore",env:process.env}):Ze("sootsim",e,{detached:!0,stdio:"ignore",env:process.env})}function V(e,t){return new Promise(n=>{let r=new Ct(`ws://127.0.0.1:${e}`,{handshakeTimeout:t}),o=!1,s=i=>{if(!o){o=!0;try{r.close()}catch{}n(i)}};r.once("open",()=>s(!0)),r.once("error",()=>s(!1)),setTimeout(()=>s(!1),t)})}function me(e){try{let t=new URL(e),n=t.pathname.replace(/\/+$/,"")||"/";return t.searchParams.has("open")||t.searchParams.has("port")||t.searchParams.has("bundle")||t.searchParams.has("demo")||t.pathname.includes("/sootsim/index.html")||n==="/sootsim"||t.pathname==="/__soot"||t.pathname==="/__soot/"||n==="/rn"||/^\/rn\/[^/]+$/i.test(n)||/^\/app\/[^/]+$/i.test(n)||n==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(n)||/^\/__soot\/app\/[^/]+$/i.test(n)}catch{return!1}}function Nt(e){try{let t=new URL(e,"http://sootsim.local");if(t.origin!=="http://sootsim.local")return!1;let n=t.pathname.replace(/\/+$/,"")||"/";return n==="/rn"||/^\/rn\/[^/]+$/i.test(n)||/^\/app\/[^/]+$/i.test(n)||n==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(n)||/^\/__soot\/app\/[^/]+$/i.test(n)}catch{return!1}}function Ft(e,t){let n=new URL(e,"http://sootsim.local"),r=new URL(t),o=Q(r.pathname),s=n.pathname.startsWith("/__soot/")?n.pathname.slice(7):n.pathname;return r.pathname=`${o}${s}`,r.search=n.search,r.hash=n.hash,r.toString()}function jt(e){try{let t=new URL(e).pathname.replace(/\/+$/,"")||"/";return/^\/preview\/[^/]+$/.test(t)||/^\/build\/.+/.test(t)}catch{return!1}}async function Gn(e){let t=J(e);return(await fe(t)).bundleUrl}function Ht(e){try{let t=new URL(e.startsWith("http")?e:`http://${e}`),n=t.pathname||"/";if(n!=="/"&&n!==""||t.search||t.hash||!I(t.hostname))return null;let r=t.port?Number(t.port):t.protocol==="https:"?443:80;return Number.isFinite(r)&&r>0?r:null}catch{return null}}async function fe(e){let t=J(e),n=/^\d+$/.test(t)?Number(t):Ht(t);if(n&&n>0){let r=await Be(n);if(r)return{bundleUrl:r.bundleUrl,port:r.port,framework:r.framework,projectName:r.projectName}}return Ye(t)}function Q(e){let t=e.replace(/\/+$/,"")||"/";return t==="/__soot"||t.startsWith("/__soot/")?"/__soot":""}function Wt(e,t){let n=J(e),r=new URL(t),o=Q(r.pathname);return r.pathname=`${o}/rn`,r.searchParams.delete("bundle"),r.searchParams.delete("demo"),r.searchParams.delete("app"),r.searchParams.delete("open"),r.searchParams.delete("port"),/^\d+$/.test(n)?r.pathname=`${o}/rn/${n}`:(r.pathname=`${o}/rn`,r.searchParams.set("open",n)),r.toString()}function ut(e){let t=J(e);return/^\d+$/.test(t)||/^https?:\/\//i.test(t)?!0:/^(localhost|127\.0\.0\.1|\[::1\]|[^/]+\.localhost):\d+(?:\/.*)?$/i.test(t)}async function Kt(e,t,n={}){let r=n.resolvedBundle??await fe(e),o=new URL(t),s=Q(o.pathname);o.pathname=`${s}/rn`,o.searchParams.delete("open"),o.searchParams.delete("port"),o.searchParams.delete("demo"),o.searchParams.delete("app");let i=n.hot===void 0?r.bundleUrl:De(r.bundleUrl,n.hot);return o.searchParams.set("bundle",i),o.toString()}function qt(e){return e.startsWith("~/")?R.join(kt.homedir(),e.slice(2)):R.isAbsolute(e)?e:R.resolve(process.cwd(),e)}function zt(e){let t={},n={};for(let o=0;o<e.length;o++){if(e[o]==="--replace"){let s=e[o+1];s||(console.error(" sootsim open: --replace expects <module>=<file>"),process.exit(1));let i=s.indexOf("=");(i<=0||i===s.length-1)&&(console.error(" sootsim open: --replace expects <module>=<file>"),process.exit(1));let a=s.slice(0,i).trim(),l=qt(s.slice(i+1).trim());M.existsSync(l)||(console.error(` sootsim open: replacement file not found: ${l}`),process.exit(1)),t[a]={file:l},o++;continue}if(e[o]==="--remap"){let s=e[o+1],i=s?s.indexOf("="):-1;(!s||i<=0||i===s.length-1)&&(console.error(" sootsim open: --remap expects <host:port>=<host:port>"),process.exit(1)),n[s.slice(0,i).trim()]=s.slice(i+1).trim(),o++;continue}}let r={};return Object.keys(t).length>0&&(r.modules=t),Object.keys(n).length>0&&(r.network={remap:n}),r.modules||r.network?r:void 0}async function Vt(e){if(e){let t=await z(e.bundleUrl);if(t)return ce(t,{trustStart:!0})}return ce(process.env.CONTRAST_REPO_DIR||process.cwd())}async function Gt(e){if(M.existsSync(R.join(re(e),"index.html")))return;console.error(` installing configured engine runtime ${e}...`);let t=await Pe.install({version:e,setActive:!1,protectVersions:xe()});console.error(` installed engine runtime ${t.version}`)}function Jt(e,t){if(!t)return e;let n=new URL(e);if(!I(n.hostname))throw new Error(`runtimeVersion ${t} requires a local SootSim host; got ${n.origin}`);return n.hostname=Ne(t),n.toString()}function dt(){return Ee().shellBaseUrl}function Qt(e){return _e(e)?.shellBaseUrl??ke(e)??dt()}async function Yt(e,t){try{let n=new URL(e),r=n.searchParams.get("bundle")||"";if(!r)return e;let o=t?.appDir??await z(r)??void 0,s=je({bundleUrl:r,repoDir:o,exactProjectDir:!!t||!!o});if(s.length===0)return e;let i=await Zt(s);return i.length===0?e:(n.searchParams.set("appFonts",He(i)),n.toString())}catch{return e}}async function Zt(e){let t=await Promise.all(e.map(async r=>{let o=new AbortController,s=setTimeout(()=>o.abort(),1500);try{let i=await fetch(r.url,{method:"HEAD",signal:o.signal});return i.status>=200&&i.status<400?r:null}catch{return null}finally{clearTimeout(s)}})),n=[];for(let r of t)r!==null&&n.push(r);return n}async function Xt(e,t,n={}){if(!e)return new URL(t).toString();if(me(e))return new URL(e).toString();if(Nt(e))return Ft(e,t);let r=Et[e.toLowerCase()];if(r){let o=new URL(t),s=Q(o.pathname);return o.pathname=`${s}${r}`,o.toString()}return ut(e)?Kt(e,t,n):Wt(e,t)}async function en(e,t){try{let n=new URL(e),r=n.searchParams.get("bundle")||"";if(!r)return e;let o=t?.appDir??await z(r)??void 0,s=We({bundleUrl:r,repoDir:o,exactProjectDir:!!t||!!o});return!s||s.imageUrl&&!await tn(s.imageUrl)?e:(n.searchParams.set("appSplash",Ke(s)),n.toString())}catch{return e}}async function tn(e){let t=new AbortController,n=setTimeout(()=>t.abort(),1500);try{let r=await fetch(e,{method:"HEAD",signal:t.signal});return r.status>=200&&r.status<400}catch{return!1}finally{clearTimeout(n)}}async function G(e,t=dt(),n={}){let r=await Xt(e,t,n),o=await en(await Yt(r,n.project),n.project);if(!n.device)return o;let s=new URL(o);return s.searchParams.set("device",n.device),s.toString()}function ot(e,t){let n=e?.url||e?.origin||t;try{let r=new URL(n);return r.searchParams.delete("bundle"),r.searchParams.delete("demo"),r.searchParams.delete("app"),r.searchParams.delete("open"),r.searchParams.delete("port"),r.searchParams.delete("inspectOpen"),r.searchParams.delete("appFonts"),r.searchParams.delete("appSplash"),r.toString()}catch{return t}}async function nn(e,t,n,r={}){let o=new URL(await G(e,t,r));return o.searchParams.set("inspectOpen",n),o.toString()}async function rn(e,t,n,r={}){let o=r.attempts??30,s=r.intervalMs??500,i=r.minNodeCount??10;for(let a=0;a<o;a++){let l=P(e,{commandTimeoutMs:t,simId:n,simIdSource:"flag"});try{let u=await l.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount()) || 0)()"});if(typeof u=="number"&&u>i)return{bridge:l,count:u}}catch{}l.close(),await S(s)}return null}function on(e){if(!e)return null;try{let t=new URL(e);if(t.searchParams.has("bundle")){let n=t.searchParams.get("bundle")||"";try{let r=new URL(n),o=r.pathname.length>36?`...${r.pathname.slice(-36)}`:r.pathname;return`bundle ${r.host}${o}`}catch{return"bundle"}}return t.searchParams.has("port")?`connect :${t.searchParams.get("port")||""}`:t.searchParams.has("open")?`connect ${t.searchParams.get("open")||""}`:t.searchParams.has("demo")?`demo ${t.searchParams.get("demo")||"default"}`:t.pathname.includes("/sootsim/index.html")||t.pathname==="/sootsim/"||t.pathname==="/sootsim"?"embedded sootsim":null}catch{return null}}function sn(e){let t=e.indexOf(":");if(t<=0)return e.length>24?`${e.slice(0,21)}\u2026`:e;let n=e.slice(0,t),r=e.slice(t+1),o=r.length>12?`${r.slice(0,8)}\u2026`:r;return n==="TM_SESSION"||n==="CLAUDE_CODE_SESSION_ID"||n==="CODEX_THREAD_ID"?`agent ${o}`:`${n} ${o}`}function Jn(e,t){if(e.length===0){console.log(" no sims connected");return}console.log(` connected sims (${e.length}):
|
|
5
|
+
`);for(let n of e){let r=n.lockedBy&&n.lockExpiresAt?`locked by ${sn(n.lockedBy)} (${Math.max(0,Math.round((n.lockExpiresAt-Date.now())/1e3))}s)`:"",o=[n.isPrimary?"primary":"",n.id===t?"selected":"",n.readyState,n.userVisible===!1?"hidden":n.userVisible===!0?"visible":"",n.attachedCliCount&&n.attachedCliCount>0?"in use":"",n.userFocused?"focused":"",r].filter(Boolean);console.log(` ${n.id}${o.length?` [${o.join(", ")}]`:""}`);let s=on(n.url);if(s)console.log(` loaded: ${s}`);else if(n.url){let a=n.url.length>96?`${n.url.slice(0,93)}\u2026`:n.url;console.log(` url: ${a}`)}else n.origin&&console.log(` origin: ${n.origin}`);let i=an(n);i&&console.log(` engine: ${i}`),n.title&&console.log(` title: ${n.title}`),n.visibilityState&&n.visibilityState!=="visible"&&console.log(` visibility: ${n.visibilityState}`),console.log(` connected: ${st(Date.now()-n.connectedAt)}`),n.lastActiveAt&&n.lastActiveAt>0&&console.log(` last active: ${st(Date.now()-n.lastActiveAt)}`)}}function an(e){let t=e.url||e.origin||"";if(!t)return null;try{let n=new URL(t).port;return n==="5173"?"dev \u2014 local source (:5173)":n==="3000"?"Contrast app embedded (:3000)":Le()?`dev \u2014 local build (:${n||"?"})`:`runtime \u2014 published engine (:${n||"?"})`}catch{return null}}function st(e){let t=Math.max(0,Math.round(e/1e3));return t<60?`${t}s ago`:t<3600?`${Math.round(t/60)}m ago`:t<86400?`${Math.round(t/3600)}h ago`:`${Math.round(t/86400)}d ago`}async function Qn(e,t,n,r={}){let o=r.attempts??30,s=r.intervalMs??500;for(let i=0;i<o;i++){let a=P(e,{commandTimeoutMs:t});try{let u=(await a.listSims()).find(n);if(u)return u}catch{}finally{a.close()}await S(s)}return null}async function ln(e,t,n,r,o={}){let s=o.attempts??30,i=o.intervalMs??500,a=!!r&&Number.isInteger(r)&&r>1,l=()=>a&&r!==void 0&&!pe(r);for(let u=0;u<s;u++){if(l())return{kind:"host-exit"};let c=P(e,{commandTimeoutMs:t});try{let g=(await c.listSims()).find(n);if(g)return l()?{kind:"host-exit"}:{kind:"match",sim:g}}catch{}finally{c.close()}if(l())return{kind:"host-exit"};await S(i)}return{kind:"timeout"}}async function cn(e,t,n,r={}){let o=r.attempts??20,s=r.intervalMs??250;for(let i=0;i<o;i++){let a=P(e,{commandTimeoutMs:t});try{let u=(await a.listSims()).find(c=>c.id===n);if(!u||u.readyState!=="open")return!0}catch{return!0}finally{a.close()}await S(s)}return!1}function un(e){let t=e.meta;if(!t||t.sootsimHostDriver!=="playwright")return null;let n=Number(t.sootsimHostPid);return!Number.isInteger(n)||n<=1||n===process.pid?null:n}function dn(e){if(!e.connectAckFile)return!1;try{return M.writeFileSync(e.connectAckFile,`${JSON.stringify({connectedAt:Date.now(),pid:e.pid??null})}
|
|
6
|
+
`,{flag:"w"}),!0}catch{return!1}}function it(e){if(e.diagnosticLogPath)try{let t=M.readFileSync(e.diagnosticLogPath,"utf8").trim();if(!t){console.error(` ${R.basename(e.diagnosticLogPath)} was empty`);return}let n=t.length>4e3?`\u2026
|
|
7
|
+
${t.slice(-4e3)}`:t;console.error(` ${R.basename(e.diagnosticLogPath)}:`),console.error(n)}catch(t){let n=t instanceof Error?t.message:String(t);console.error(` failed to read ${R.basename(e.diagnosticLogPath)}: ${n}`)}}function pe(e){try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}async function mn(e,t=2500){let n=Date.now()+t;for(;Date.now()<n;){if(!pe(e))return!0;await S(100)}return!pe(e)}function pn(e){let t=Xe("ps",["-o","command=","-p",String(e)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),n=Xe("ps",["eww","-o","command=","-p",String(e)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]});if(t.status!==0||n.status!==0)return!1;let r=(t.stdout||"").trimEnd(),o=(n.stdout||"").trimEnd();return(o.startsWith(r)?o.slice(r.length):o).includes("SOOTSIM_PW_URL=")}async function de(e,t){let n=new Set(t),r=new Set;for(let o of e){if(!n.has(o.id))continue;let s=un(o);s&&r.add(s)}for(let o of r){if(!pn(o)){console.log(` skipped pid ${o}: not a sootsim playwright host (stale sim record)`);continue}try{process.kill(o,"SIGTERM")}catch{}if(await mn(o)){console.log(` closed playwright host process ${o}`);continue}try{process.kill(o,"SIGKILL"),console.log(` force-closed playwright host process ${o}`)}catch{}}}function Y(e,t){if(t){let o=t.trim(),s=e.find(i=>i.id===o);if(!s)throw new Error(`no sim connected with id ${o}`);return s}let n=e.find(o=>o.isPrimary&&o.readyState==="open");if(n)return n;let r=e.find(o=>o.readyState==="open");if(r)return r;throw new Error("no sim connected")}function at(e,t,n){console.log(` ${n==="current sim"?"loaded":"opened"}: ${e} [${n}]`),console.log(` current sim: ${t.id}`),console.log(JSON.stringify({simId:t.id,url:t.url},null,2))}async function lt(e,t,n){if(n.includes("--no-describe"))return;let r=process.env.SOOTSIM_QUIET_TARGET_NOTICE;process.env.SOOTSIM_QUIET_TARGET_NOTICE="1";try{await fn(e,t,{stableMs:150,maxMs:400});let o=P(e,{commandTimeoutMs:3e3,simId:t,cliLabel:"open --describe",simIdSource:"flag"});try{let s=null;try{s=await o.send({type:"evaluate",code:Re})}catch{}if(s&&!(s.flag===!0&&!s.loadingText&&Ue(s))){let c=s.loadingText?`still showing "${s.loadingText}"`:s.flag!==!0?"guest ready event has not fired":s.targets<=0?"no visible app content is inspectable yet":"app tree is still stabilizing";console.log(` app still loading: ${c} (nodes: ${s.nodes}, targets: ${s.targets})`),console.log(" before interacting, run: sootsim wait ready --max-ms 120000")}let a=`(async () => {
|
|
8
|
+
const t = window.__sootsimTest
|
|
9
|
+
const ms = window.SootSim?.bridges?.mainShell
|
|
10
|
+
if (!t) return null
|
|
11
|
+
let shell = null
|
|
12
|
+
try { shell = ms?.getState ? await ms.getState() : null } catch {}
|
|
13
|
+
const tree = await t.dumpTree(12, ${JSON.stringify({describe:!0,verbose:!1,filter:""})})
|
|
14
|
+
return { tree, shell }
|
|
15
|
+
})()`,l=await o.send({type:"evaluate",code:a});if(!l?.tree)return;if(console.log(""),l.shell?.state){let u=[`state=${l.shell.state}`,l.shell.activeApp?`app=${l.shell.activeApp}`:null].filter(Boolean);console.log(` shell: ${u.join(" ")}`)}console.log(l.tree)}finally{o.close()}}catch{}finally{r===void 0?delete process.env.SOOTSIM_QUIET_TARGET_NOTICE:process.env.SOOTSIM_QUIET_TARGET_NOTICE=r}}async function fn(e,t,n){let r=Date.now()+n.maxMs,o="(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()",s=P(e,{commandTimeoutMs:2e3,simId:t,simIdSource:"flag"});try{let i=-1,a=0;for(;Date.now()<r;){let l=-1;try{let u=await s.send({type:"evaluate",code:o});typeof u=="number"&&(l=u)}catch{}if(l>=0&&l===i){if(Date.now()-a>=n.stableMs)return}else i=l,a=Date.now();await S(50)}}finally{s.close()}}async function gn(e,t={}){let n=_(e,{port:t.port,commandTimeoutMs:t.timeoutMs});n.positional.length!==1&&(console.error(" sootsim open: expected exactly one <url-or-route>"),console.error(" examples: sootsim open /settings | sootsim open myapp://settings"),process.exit(1));let r;try{r=Mt(n.positional[0]??"")}catch(i){console.error(` sootsim open: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}let o=T(n),s=n.simId?` --sim ${n.simId}`:"";try{let i=await o.send({type:"call",path:"SootSim.bridges.test.openDeepLink",args:[r]});if(Ot(i)&&i.ok===!1)throw new Error(typeof i.error=="string"?i.error:"deep-link dispatch failed");console.log(` opened deep link: ${r}`)}catch(i){console.error(` link failed: ${i instanceof Error?i.message:String(i)}`),await A(o,{errorsCommand:`sootsim get errors 5${s}`,warningsCommand:`sootsim get warnings 5${s}`,requestsCommand:`sootsim get requests 5${s}`}),process.exit(1)}finally{o.close()}}async function Yn(e,t={}){let n=_(e,{port:t.port,commandTimeoutMs:t.timeoutMs,stripBooleanFlags:["--new","--headless","--headed","--ephemeral","--hot","--no-hmr","--no-describe"],stripValueFlags:["--base-url","--replace","--driver","--profile","--cdp-port","--browser","--device"]}),r=e.find((m,p)=>e[p-1]==="--profile"),o=e.includes("--ephemeral"),s=e.find((m,p)=>e[p-1]==="--cdp-port"),i=s?Number(s):void 0;s&&(!Number.isFinite(i)||i<=0)&&(console.error(` sootsim open: --cdp-port must be a positive port number, got "${s}"`),process.exit(1)),r&&o&&(console.error(" sootsim open: --profile cannot be combined with --ephemeral"),process.exit(1));let a=r?Ae(r).id:void 0,l=e.includes("--new")||!!a||o,u=zt(e);l&&n.simIdSource==="flag"&&(console.error(" sootsim open: --new, --profile, and --ephemeral cannot be combined with --sim"),process.exit(1));let c=n.positional[0]||"";if(Dt(c)){l&&(console.error(" sootsim open: deep links target the current app; remove --new, --profile, or --ephemeral"),process.exit(1)),await gn(e,t);return}if(jt(c)){let m=(()=>{try{return I(new URL(c).hostname)}catch{return!1}})();console.log(" that\u2019s a SootSim preview/build link \u2014 a full player page, not a driveable sim."),console.log(" opening it in your browser for viewing\u2026");try{await ze(c,{background:!1})}catch(p){console.error(` could not launch a browser: ${p instanceof Error?p.message:String(p)}`),console.error(` open it yourself: ${c}`),process.exit(1)}console.log(m?" to drive it under the CLI, point `sootsim open` at the app\u2019s dev port instead (e.g. `sootsim open 8081`).":" the CLI can\u2019t drive a remote preview (the engine only attaches to the local bridge from localhost). to drive the app, run it locally and `sootsim open <port>`.");return}let d=ut(c)?await fe(c):void 0,g=await Vt(d),O=await Fe(g),N=O?.runtimeVersion,F=Oe(O?{...O,runtimeVersion:void 0}:void 0,u);N&&await Gt(N);let Z=e.find((m,p)=>e[p-1]==="--base-url"),pt=t.port!==void 0||e.some(m=>m==="--port"||m==="-p"||m.startsWith("--port="));if(Z&&!pt){let m=ie(Z);m&&(n.wsPort=m)}n.wsPort=await Bt(n.wsPort);let U=e.find((m,p)=>e[p-1]==="--driver")||"";U&&!rt(U)&&(console.error(` unknown driver "${U}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let b=rt(U)?U:"playwright",ft=Tt(e,b);i&&b!=="playwright"&&(console.error(" sootsim open: --cdp-port is only honored by the playwright driver"),process.exit(1));let k=e.find((m,p)=>e[p-1]==="--browser");k&&b!=="playwright"&&(console.error(" sootsim open: --browser is only honored by the playwright driver"),process.exit(1));let j=k==="chromium"||k==="webkit"||k==="firefox"?k:void 0;k&&!j&&(console.error(` sootsim open: --browser must be chromium, webkit, or firefox \u2014 got "${k}"`),process.exit(1)),i&&j&&j!=="chromium"&&(console.error(" sootsim open: --cdp-port requires the chromium engine"),process.exit(1));let ge=e.includes("--hot"),he=e.includes("--no-hmr");ge&&he&&(console.error(" sootsim open: --hot and --no-hmr cannot be combined"),process.exit(1));let gt=ge?!0:he?!1:U!=="playwright",C=e.find((m,p)=>e[p-1]==="--device");C&&!(C in se)&&(console.error(` sootsim open: unknown device "${C}"`),console.error(` known devices: ${Ie().join(", ")}`),process.exit(1));let X=C?se[C]:void 0,H={hot:gt,device:C,resolvedBundle:d,project:g},ht=N?`http://localhost:${n.wsPort}/`:Z||Qt(n.wsPort),$=Jt(ht,N),we=e.includes("--base-url");Te(n.wsPort,$);let wt=D();if(!l){let m=T(n),p=n.simId?` --sim ${n.simId}`:"",ne=!1;try{let f=null,K=null;try{let h=await m.listSims();if(n.simIdSource==="saved")f=h.find(w=>w.id===wt&&w.readyState==="open"&&ue(w,b))??null,f||B();else if(n.simIdSource==="flag"&&(f=Y(h,n.simId),!ue(f,b)))throw new Error(`sim ${f.id} is not managed by the ${b} driver`);if(!f&&n.simIdSource!=="flag"){K=await G(c,L($,F),H);let w=new URL(K);w.searchParams.delete("inspectOpen"),f=h.find(y=>{if(y.readyState!=="open"||!y.url||!ue(y,b))return!1;try{let Se=new URL(y.url);return Se.searchParams.delete("inspectOpen"),Se.toString()===w.toString()}catch{return!1}})??null}if(!f)if(n.simIdSource!=="flag")ne=!0;else throw new Error("no sim connected");if(!ne&&f){let w=we||me(c)?$:ot(f,$),y=K??await G(c,L(w,F),H);m.send({type:"evaluate",simId:f.id,code:`window.location.href = ${JSON.stringify(y)}`}).catch(()=>{})}}catch(h){console.error(` open failed: ${h instanceof Error?h.message:String(h)}`),await A(m,{errorsCommand:`sootsim get errors 5${p}`,warningsCommand:`sootsim get warnings 5${p}`,requestsCommand:`sootsim get requests 5${p}`}),process.exit(1)}if(!ne&&f){await S(1500);let h=await rn(n.wsPort,n.commandTimeoutMs,f.id);h||(console.error(" timed out waiting for current sim to load target"),process.exit(1)),h.bridge.close(),x(f.id);let w=we||me(c)?$:ot(f,$),y=K??await G(c,L(w,F),H);at(y,{...f,url:y},"current sim"),await lt(n.wsPort,f.id,e);return}}finally{m.close()}}let bt=L($,F),be=`cli-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,ve=await nn(c,bt,be,H),ye=Ce();ye||(console.error(" could not resolve a stable owning process; refusing unsupervised sim host"),process.exit(1));let vt=m=>m.url?.includes(`inspectOpen=${be}`)??!1,E=qe(b);E||(console.error(` unknown driver "${b}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let W=_t(),v=await E.launch({url:ve,bridgePort:ie($)??n.wsPort,headless:ft,profileId:a,ephemeralProfile:o,cdpPort:i,browser:j,device:C,ownerPid:ye,viewport:X?{width:X.width+120,height:X.height+60}:void 0,connectTimeoutMs:W.hostTimeoutMs});v.launched||(console.error(` ${E.name} driver: ${v.message}`),process.exit(1));let ee=await ln(n.wsPort,n.commandTimeoutMs,vt,v.pid,{attempts:W.attempts,intervalMs:W.intervalMs});if(ee.kind==="host-exit"&&(it(v),console.error(` ${E.name} host crashed \u2014 sim is no longer attached`),process.exit(1)),ee.kind==="timeout"){if(v.pid)try{process.kill(v.pid,"SIGTERM"),console.error(` closed ${E.name} host process ${v.pid}`)}catch{}it(v),console.error(` timed out after ${W.timeoutMs}ms waiting for opened sim to connect`),process.exit(1)}let te=ee.sim;x(te.id),dn(v),at(ve,te,`${E.name} driver`),await lt(n.wsPort,te.id,e)}async function mt(e,t={}){let n=_(e,{port:t.port,commandTimeoutMs:t.timeoutMs,stripBooleanFlags:["--force"]}),r=e.includes("--force"),o=T(n),s=n.simId?` --sim ${n.simId}`:"";try{try{let i=await o.listSims(),a=Y(i,n.positional[0]||n.simId);if(a.lockedBy&&a.lockExpiresAt&&a.lockExpiresAt>Date.now()){let l=Math.max(0,Math.round((a.lockExpiresAt-Date.now())/1e3));a.lockedByKind==="user-active"&&(console.error(` refused: ${a.id} is locked by the active user (${l}s) \u2014 that's a live human tab`),console.error(" run `sootsim open --new` for a fresh investigation sim"),process.exit(1)),r||(console.error(` refused: ${a.id} is leased by ${a.lockedBy} (${l}s)`),console.error(` \`sootsim use ${a.id} --force\` to take it, or \`sootsim open --new\` for a fresh sim`),process.exit(1))}await o.focusSim(a.id),x(a.id),console.log(` using: ${a.id}`)}catch(i){console.error(` use failed: ${i instanceof Error?i.message:String(i)}`),await A(o,{errorsCommand:`sootsim get errors 5${s}`,warningsCommand:`sootsim get warnings 5${s}`,requestsCommand:`sootsim get requests 5${s}`}),process.exit(1)}}finally{o.close()}}async function Zn(e,t={}){await mt(e,t)}async function Xn(e,t={}){await mt(e,t)}async function er(e,t={}){let n=_(e,{port:t.port,commandTimeoutMs:t.timeoutMs,stripBooleanFlags:["--force"]}),r=e.includes("--force"),o=T(n);try{try{let s=await o.listSims(),i=Y(s,n.positional[0]||n.simId),a=r&&i.lockedBy&&i.lockedByKind!=="user-active"?i.lockedBy:null,l=await o.claim(i.id,{force:r});x(i.id);let u=Math.max(0,Math.round((l.lockExpiresAt-Date.now())/1e3)),c=l.bootedCount>0?` (booted ${l.bootedCount})`:"";console.log(` claimed: ${l.simId} [${u}s]${c}`),a&&console.log(` took over from: ${a}`)}catch(s){if(s instanceof Me){let i=Math.max(0,Math.round(s.lock.expiresInMs/1e3));console.error(` claim failed: locked by ${s.lock.by} for ${i}s more`),console.error(" use --force to take it, or `sootsim open --new` for a fresh sim"),process.exit(1)}console.error(` claim failed: ${s instanceof Error?s.message:String(s)}`),process.exit(1)}}finally{o.close()}}async function hn(e,t,n,r){if(r.length===0)return{closed:[],remaining:[]};await Promise.all(r.map(s=>e.closeSim(s).catch(()=>{})));let o=new Set(r);for(let s=0;s<40;s++){let i=[];try{let a=P(t,{commandTimeoutMs:n});try{i=(await a.listSims()).filter(u=>o.has(u.id)&&u.readyState==="open").map(u=>u.id)}finally{a.close()}}catch{i=[]}if(i.length===0)return{closed:[...o],remaining:[]};if(s===39)return{closed:[...o].filter(a=>!i.includes(a)),remaining:i};await S(250)}return{closed:[...o],remaining:[]}}function wn(e,t){let n=e.filter(d=>d.readyState==="open"),r=n.map(d=>d.id),o=t.explicitKeepId?.trim()||"",s=t.savedKeepId?.trim()||"",i=s?n.some(d=>d.id===s):!1,a=s&&!i?s:null,l=null,u=null,c=null;if(t.closeOthers)if(o){let d=n.find(g=>g.id===o);d?l=d.id:u=o}else if(s&&i)l=s;else{let d=n.find(g=>g.isPrimary)??n[0]??null;d&&(l=d.id,s&&!i&&(c=d.id))}return{openIds:r,keepId:l,targets:u?[]:r.filter(d=>d!==l),staleSavedId:a,missingExplicitKeepId:u,fallbackKeepId:c}}async function tr(e,t={}){let n=_(e,{port:t.port,commandTimeoutMs:t.timeoutMs,stripBooleanFlags:["--all","--others"]}),r=T(n),o=n.simId?` --sim ${n.simId}`:"",s=e.includes("--all"),i=e.includes("--others");if(s||i){try{let a=await r.listSims(),l=D(),u=n.positional[0]||(n.simIdSource==="flag"?n.simId:void 0),c=wn(a,{closeOthers:i,explicitKeepId:u,savedKeepId:l});if(c.staleSavedId&&B(),c.fallbackKeepId&&(x(c.fallbackKeepId),console.log(` saved sim ${c.staleSavedId} is gone \u2014 keeping primary ${c.fallbackKeepId}`)),c.missingExplicitKeepId&&(console.error(` close failed: keep sim ${c.missingExplicitKeepId} is not connected; not closing other sims`),process.exit(1)),c.targets.length===0){console.log(c.keepId?` nothing to close \u2014 only the kept sim ${c.keepId} is connected`:c.staleSavedId?` nothing to close \u2014 no sims connected (cleared stale current sim ${c.staleSavedId})`:" nothing to close \u2014 no sims connected");return}let d=await hn(r,n.wsPort,n.commandTimeoutMs,c.targets);await de(a,c.targets);let g=D();g&&d.closed.includes(g)&&(c.keepId?x(c.keepId):B());let O=` closed ${d.closed.length} sim(s)${c.keepId?` (kept ${c.keepId})`:""}`;console.log(O),d.remaining.length>0&&(console.error(` close failed: still connected: ${d.remaining.join(", ")}`),process.exit(1))}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),process.exit(1)}finally{r.close()}return}try{try{let a=await r.listSims(),l=Y(a,n.positional[0]||n.simId),u=a.find(d=>d.id!==l.id&&d.readyState==="open");await r.closeSim(l.id),await cn(n.wsPort,n.commandTimeoutMs,l.id)||(await de(a,[l.id]),console.error(` close failed: ${l.id} is still connected`),process.exit(1)),await de(a,[l.id]),D()===l.id&&(u?x(u.id):B()),console.log(` closed: ${l.id}`)}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),await A(r,{errorsCommand:`sootsim get errors 5${o}`,warningsCommand:`sootsim get warnings 5${o}`,requestsCommand:`sootsim get requests 5${o}`}),process.exit(1)}}finally{r.close()}}export{_t as a,Mt as b,Gn as c,Jt as d,dt as e,Qt as f,G as g,nn as h,on as i,Jn as j,Qn as k,ln as l,un as m,dn as n,de as o,gn as p,Yn as q,Zn as r,Xn as s,er as t,hn as u,wn as v,tr as w};
|