sootsim 0.1.293 → 0.1.294

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.
Files changed (165) hide show
  1. package/detox/expectations.ts +4 -3
  2. package/detox/index.ts +2 -4
  3. package/dist-cli/bin.js +7 -5
  4. package/dist-cli/chunks/{agent-YWI2NWL7.js → agent-GDFF6G7N.js} +4 -2
  5. package/dist-cli/chunks/{agent-wrapper-IYJ7UZOA.js → agent-wrapper-ZUKQUOD2.js} +4 -2
  6. package/dist-cli/chunks/{app-fonts-FQFUC4LR.js → app-fonts-IMYBO6AQ.js} +4 -2
  7. package/dist-cli/chunks/{assert-XUCELWAC.js → assert-GXOGZUKO.js} +4 -2
  8. package/dist-cli/chunks/{auth-4DQTV3OW.js → auth-P7FAKLHQ.js} +4 -2
  9. package/dist-cli/chunks/beta-RXT5RU3A.js +4 -0
  10. package/dist-cli/chunks/{camera-RYOHBVZA.js → camera-RNVAC4IO.js} +4 -2
  11. package/dist-cli/chunks/{chunk-2XYCSFGN.js → chunk-24BJFJFB.js} +26 -24
  12. package/dist-cli/chunks/{chunk-WVMYRKSS.js → chunk-2M7OZ6Y4.js} +4 -2
  13. package/dist-cli/chunks/chunk-37ZXWXM3.js +4 -0
  14. package/dist-cli/chunks/{chunk-UOHGYYSO.js → chunk-3F2GAJ4Z.js} +3 -1
  15. package/dist-cli/chunks/{chunk-KC5SCOGS.js → chunk-4Z4URZOG.js} +4 -2
  16. package/dist-cli/chunks/{chunk-LOQLZFRK.js → chunk-5S3GPTX7.js} +4 -2
  17. package/dist-cli/chunks/chunk-6YN3IAWJ.js +4 -0
  18. package/dist-cli/chunks/{chunk-YRFWATLA.js → chunk-7HVMAGDK.js} +4 -2
  19. package/dist-cli/chunks/{chunk-4B4VFT73.js → chunk-7Q77LTPT.js} +7 -5
  20. package/dist-cli/chunks/{chunk-RKXHQ2Q3.js → chunk-AFLGWOX3.js} +18 -16
  21. package/dist-cli/chunks/{chunk-LA5DIO33.js → chunk-AMKQUZA2.js} +3 -1
  22. package/dist-cli/chunks/{chunk-TJS5IMOH.js → chunk-AO65WEF7.js} +3 -1
  23. package/dist-cli/chunks/{chunk-BQT5YDTV.js → chunk-BBVBMGTT.js} +5 -3
  24. package/dist-cli/chunks/{chunk-WPPMUUML.js → chunk-BXO2PTNM.js} +4 -2
  25. package/dist-cli/chunks/{chunk-2VKTOZQ5.js → chunk-CTMPC5DN.js} +4 -2
  26. package/dist-cli/chunks/{chunk-RV67J726.js → chunk-D2R7PDN5.js} +3 -1
  27. package/dist-cli/chunks/{chunk-RMLJXP7T.js → chunk-DI55E6CS.js} +4 -2
  28. package/dist-cli/chunks/chunk-DUHBRW7J.js +4 -0
  29. package/dist-cli/chunks/chunk-EXTV6NWM.js +74 -0
  30. package/dist-cli/chunks/{chunk-6IFJLHDA.js → chunk-FNCSUHUR.js} +3 -1
  31. package/dist-cli/chunks/{chunk-DE4ZA3NL.js → chunk-FSRRJGYC.js} +4 -2
  32. package/dist-cli/chunks/{chunk-UPKYK52K.js → chunk-I233T2T4.js} +4 -2
  33. package/dist-cli/chunks/{chunk-E5WYXRGV.js → chunk-ISJ4ACWL.js} +28 -26
  34. package/dist-cli/chunks/{chunk-AFRXWKTA.js → chunk-JFWEDISV.js} +3 -1
  35. package/dist-cli/chunks/chunk-JGGXQHXH.js +10 -0
  36. package/dist-cli/chunks/chunk-JUOQ4ZPA.js +7 -0
  37. package/dist-cli/chunks/{chunk-2M57EAWS.js → chunk-K53YCAQM.js} +3 -1
  38. package/dist-cli/chunks/{chunk-7B6RGFTM.js → chunk-KWIURH7N.js} +4 -2
  39. package/dist-cli/chunks/{chunk-VO74GDXL.js → chunk-N4MT5KEB.js} +5 -3
  40. package/dist-cli/chunks/{chunk-VZ44FQDG.js → chunk-O6I5ZGMY.js} +3 -1
  41. package/dist-cli/chunks/chunk-OKSGM6IG.js +4 -0
  42. package/dist-cli/chunks/chunk-OYYQQBKP.js +3 -0
  43. package/dist-cli/chunks/{chunk-NCCMRFXU.js → chunk-PSOUSJSZ.js} +3 -1
  44. package/dist-cli/chunks/{chunk-J6P2UPXH.js → chunk-PZTKQG6H.js} +4 -2
  45. package/dist-cli/chunks/{chunk-B7TX4WFB.js → chunk-RWUNC66S.js} +4 -2
  46. package/dist-cli/chunks/{chunk-547W23BB.js → chunk-SLMUW2WU.js} +4 -2
  47. package/dist-cli/chunks/{chunk-WI36YJ23.js → chunk-SPQKJDIK.js} +3 -1
  48. package/dist-cli/chunks/{chunk-PCAPHXN3.js → chunk-V2MYTL4C.js} +4 -2
  49. package/dist-cli/chunks/{chunk-JOPKZVOW.js → chunk-VVVORIQI.js} +3 -1
  50. package/dist-cli/chunks/chunk-VXGCZUX4.js +5 -0
  51. package/dist-cli/chunks/chunk-W44PDEQH.js +4 -0
  52. package/dist-cli/chunks/{chunk-WOWLO4LL.js → chunk-WQL3BLFD.js} +3 -1
  53. package/dist-cli/chunks/{chunk-U3564F2Y.js → chunk-WYRLRNIP.js} +4 -2
  54. package/dist-cli/chunks/{chunk-WP3TFHFL.js → chunk-XYFP466E.js} +4 -2
  55. package/dist-cli/chunks/chunk-ZFMJFX27.js +4 -0
  56. package/dist-cli/chunks/{chunk-67CIS55C.js → chunk-ZUX5PIGI.js} +3 -1
  57. package/dist-cli/chunks/{cleanup-BLFDJSFS.js → cleanup-74SKOD2P.js} +4 -2
  58. package/dist-cli/chunks/cli-version-2JGMYL4O.js +4 -0
  59. package/dist-cli/chunks/{compat-Q3WCSTB7.js → compat-ME6HXEEU.js} +5 -3
  60. package/dist-cli/chunks/{config-NHNMRRNB.js → config-PM67EWT3.js} +4 -2
  61. package/dist-cli/chunks/control-HV7GZXAH.js +4 -0
  62. package/dist-cli/chunks/daemon-LKRHF5OK.js +4 -0
  63. package/dist-cli/chunks/{debug-PGRMZFXA.js → debug-XUGWZLIW.js} +5 -3
  64. package/dist-cli/chunks/{desktop-NVTQ37LH.js → desktop-IO5HPX5Z.js} +5 -3
  65. package/dist-cli/chunks/{detox-W3JDXS76.js → detox-E42OEJJZ.js} +4 -2
  66. package/dist-cli/chunks/{device-KQYN3EVK.js → device-XA67L2EB.js} +4 -2
  67. package/dist-cli/chunks/{diagnose-CPUKSGNO.js → diagnose-36FD6ECF.js} +4 -2
  68. package/dist-cli/chunks/disk-cleanup-DDCFGFWK.js +4 -0
  69. package/dist-cli/chunks/drivers-C2SH3DWS.js +4 -0
  70. package/dist-cli/chunks/{film-VZGAZ2YY.js → film-XARTGFIZ.js} +11 -24
  71. package/dist-cli/chunks/flow-E64G5LF3.js +4 -0
  72. package/dist-cli/chunks/help-4ZSRG4F4.js +4 -0
  73. package/dist-cli/chunks/{hidden-runtime-alias-KWHABCNZ.js → hidden-runtime-alias-T4ZALBE2.js} +4 -2
  74. package/dist-cli/chunks/{home-paths-O4CGYVHF.js → home-paths-5L7N2FLS.js} +4 -2
  75. package/dist-cli/chunks/inspect-U2SV25ER.js +4 -0
  76. package/dist-cli/chunks/install-desktop-LTGVT7ID.js +4 -0
  77. package/dist-cli/chunks/{login-KPN4Z26Q.js → login-GF6WVVER.js} +6 -4
  78. package/dist-cli/chunks/logout-6F6UKUNI.js +4 -0
  79. package/dist-cli/chunks/{maestro-PYA4AHTS.js → maestro-FMPKHEMX.js} +13 -11
  80. package/dist-cli/chunks/{maestro-generate-KCMYWPWL.js → maestro-generate-QGPGNXI6.js} +5 -3
  81. package/dist-cli/chunks/{mode-AEB7G2SJ.js → mode-JSNMAHDZ.js} +4 -2
  82. package/dist-cli/chunks/optional-demo-registry-K4VERLJV.js +4 -0
  83. package/dist-cli/chunks/{perf-YLXGZI3E.js → perf-PO7ARUTG.js} +4 -2
  84. package/dist-cli/chunks/{permissions-7VMVZOUV.js → permissions-XI2QUAEZ.js} +4 -2
  85. package/dist-cli/chunks/{record-AVQO45PE.js → record-4CJCJAFD.js} +5 -3
  86. package/dist-cli/chunks/runtime-SN2RWDES.js +4 -0
  87. package/dist-cli/chunks/{screenshot-command-LACQLA4N.js → screenshot-command-NDVULWMZ.js} +5 -3
  88. package/dist-cli/chunks/{screenshots-capture-PROOBSGB.js → screenshots-capture-Q7UTXF3V.js} +4 -2
  89. package/dist-cli/chunks/{serve-FJN2FRGW.js → serve-UEUIBHCK.js} +4 -2
  90. package/dist-cli/chunks/{setup-IVV4NRYQ.js → setup-ZEEWYK4B.js} +5 -3
  91. package/dist-cli/chunks/{skills-WYR3PJOH.js → skills-NFG6VAO5.js} +4 -2
  92. package/dist-cli/chunks/{storage-GM7K4MGM.js → storage-POWCOUCQ.js} +4 -2
  93. package/dist-cli/chunks/store-BJK7V7FL.js +4 -0
  94. package/dist-cli/chunks/telemetry-EJP5EW7K.js +4 -0
  95. package/dist-cli/chunks/{timeline-R5UL3N4T.js → timeline-MNHZCVAL.js} +4 -2
  96. package/dist-cli/chunks/{upgrade-RWHSFZRX.js → upgrade-X57SIG7L.js} +4 -2
  97. package/dist-cli/chunks/upload-JABM3ITZ.js +4 -0
  98. package/dist-cli/chunks/{version-7K6TVQOW.js → version-V4IKIDX7.js} +4 -2
  99. package/dist-cli/chunks/web-F5CLF34I.js +4 -0
  100. package/dist-cli/chunks/{what-happened-K24TSJZX.js → what-happened-H74HHGRK.js} +4 -2
  101. package/dist-lib/agent-daemon-client.cjs +1 -1
  102. package/dist-lib/agent-events.cjs +1 -1
  103. package/dist-lib/agent-identity.cjs +3 -3
  104. package/dist-lib/agent-sessions.cjs +1 -1
  105. package/dist-lib/attached-projects.cjs +1 -1
  106. package/dist-lib/auth/shared-session.cjs +1 -1
  107. package/dist-lib/backend-origin.cjs +1 -1
  108. package/dist-lib/beta.cjs +1 -1
  109. package/dist-lib/beta.mjs +1 -1
  110. package/dist-lib/bridge-constants.cjs +1 -1
  111. package/dist-lib/cli-constants.cjs +1 -1
  112. package/dist-lib/config.cjs +1 -1
  113. package/dist-lib/detox/index.cjs +5 -4
  114. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  115. package/dist-lib/home-paths.cjs +1 -1
  116. package/dist-lib/host/bridge-host.cjs +3 -3
  117. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  118. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  119. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  120. package/dist-lib/host/websocket-proxy.cjs +1 -1
  121. package/dist-lib/index.cjs +1 -1
  122. package/dist-lib/jump-to-source-babel.cjs +1 -1
  123. package/dist-lib/menu.cjs +45 -4
  124. package/dist-lib/menu.mjs +42 -4
  125. package/dist-lib/metro.cjs +1 -1
  126. package/dist-lib/profiles.cjs +1 -1
  127. package/dist-lib/render-mode.cjs +1 -1
  128. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  129. package/dist-lib/sdk.cjs +5 -2
  130. package/dist-lib/sdk.mjs +4 -2
  131. package/dist-lib/skills.cjs +325 -182
  132. package/dist-lib/vite.cjs +1 -1
  133. package/package.json +6 -1
  134. package/scripts/postinstall.cjs +11 -2
  135. package/src/agent-identity.ts +2 -2
  136. package/src/menu.ts +53 -4
  137. package/src/vite-plugin.ts +102 -2
  138. package/dist-cli/chunks/beta-CFDAW6UN.js +0 -2
  139. package/dist-cli/chunks/chunk-3UX6AY2B.js +0 -2
  140. package/dist-cli/chunks/chunk-6VVLDYPV.js +0 -8
  141. package/dist-cli/chunks/chunk-7H34H74K.js +0 -72
  142. package/dist-cli/chunks/chunk-7H5G4HUK.js +0 -2
  143. package/dist-cli/chunks/chunk-ACSTEPSD.js +0 -2
  144. package/dist-cli/chunks/chunk-HKMWUN7F.js +0 -2
  145. package/dist-cli/chunks/chunk-K5JEUI5G.js +0 -5
  146. package/dist-cli/chunks/chunk-MOU2WLO4.js +0 -2
  147. package/dist-cli/chunks/chunk-QXDXUDJD.js +0 -1
  148. package/dist-cli/chunks/chunk-USJTVC7T.js +0 -2
  149. package/dist-cli/chunks/chunk-YNG4C3ZS.js +0 -2
  150. package/dist-cli/chunks/cli-version-TQHZOK4L.js +0 -2
  151. package/dist-cli/chunks/control-I7YBDRJT.js +0 -2
  152. package/dist-cli/chunks/daemon-4R3SZLZY.js +0 -2
  153. package/dist-cli/chunks/disk-cleanup-2COWZWBC.js +0 -2
  154. package/dist-cli/chunks/drivers-RRZM6E72.js +0 -2
  155. package/dist-cli/chunks/flow-VH6DFDQ4.js +0 -2
  156. package/dist-cli/chunks/help-3HQ2RINO.js +0 -2
  157. package/dist-cli/chunks/inspect-PKMJGXDH.js +0 -2
  158. package/dist-cli/chunks/install-desktop-K5TP3ZHJ.js +0 -2
  159. package/dist-cli/chunks/logout-E3UCJAMC.js +0 -2
  160. package/dist-cli/chunks/optional-demo-registry-AIWOBAAA.js +0 -2
  161. package/dist-cli/chunks/runtime-HOGETVVD.js +0 -2
  162. package/dist-cli/chunks/store-YLVHPKG7.js +0 -2
  163. package/dist-cli/chunks/telemetry-MQKB6PFX.js +0 -2
  164. package/dist-cli/chunks/upload-RBH4XGJ2.js +0 -2
  165. package/dist-cli/chunks/web-46ZPQCAL.js +0 -2
@@ -1,8 +1,10 @@
1
- /*! sootsim v0.1.293 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as K,b as ne,c as re,d as Pe,e as Ie,g as I,h as Ee}from"./chunk-WP3TFHFL.js";import{m as R}from"./chunk-B7TX4WFB.js";import{b as Ce,l as ce}from"./chunk-7B6RGFTM.js";import{a as O,b as ae}from"./chunk-LA5DIO33.js";import{m as Re,o as Oe}from"./chunk-RKXHQ2Q3.js";import{a as _e,b as Ue}from"./chunk-ACSTEPSD.js";import{a as Me,b as se,c as Te}from"./chunk-MOU2WLO4.js";import{d as le}from"./chunk-JOPKZVOW.js";import{a as Be,b as De,c as ie,e as Le,f as Ae,g as E,h as v,i as M}from"./chunk-J6P2UPXH.js";import{b as oe,d as xe}from"./chunk-YNG4C3ZS.js";import{d as ke,e as _,f as b,g as U}from"./chunk-K5JEUI5G.js";import{H as $e,K as te,M as j,l as Se}from"./chunk-WOWLO4LL.js";import{spawn as qe,spawnSync as ze}from"node:child_process";import L from"node:fs";import ft from"node:os";import T from"node:path";import{WebSocket as ht}from"ws";function Ne(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 at(e,o){return e?.includes("/one/metro-entry.bundle")?"one":typeof o=="string"&&o?"expo":"unknown"}function He(e,o,t){return`${e}//${o}:${t}`}function lt(e){if(typeof window>"u")return!1;try{let o=new URL(e);return I(o.hostname)&&I(window.location.hostname)&&o.origin!==window.location.origin}catch{return!1}}async function Fe(e,o){let t={...o,cache:o?.cache??"no-store"};return lt(e)?fetch(`/__fetch-proxy?url=${encodeURIComponent(e)}`,t):fetch(e,t)}function ct(e){return e==="https:"?443:80}function dt(e){let o=e.pathname||"/";return(o==="/"||o==="")&&!e.search&&!e.hash}async function mt(e){try{let o=await fetch("/__server-scan",{cache:"no-store"});if(!o.ok||!(o.headers.get("content-type")||"").toLowerCase().includes("json"))return null;let t=await o.json();if(!Array.isArray(t))return null;let n=t.find(r=>!!r&&typeof r=="object"&&r.port===e&&typeof r.bundleUrl=="string");return n?{bundleUrl:re(n.bundleUrl),port:e,framework:typeof n.framework=="string"?n.framework:"unknown",projectName:typeof n.projectName=="string"?n.projectName:void 0}:null}catch{return null}}async function We(e,o){let t=e.replace(/\/+$/,"");try{if(I(new URL(t).hostname)){let n=await mt(o);if(n)return n}}catch{}try{let n=await Fe(`${t}/`,{headers:{"expo-platform":"ios"}});if(n.ok){let r=await n.json(),s=r?.extra?.expoClient||r?.extra||{},i=typeof r?.launchAsset?.url=="string"?r.launchAsset.url:void 0;if(i||s.name)return{bundleUrl:re(i||`${t}${ne}`),port:o,framework:at(i,s.sdkVersion),projectName:s.name}}}catch{}try{let n=await Fe(`${t}/status`);if(n.ok&&(await n.text()).includes("packager-status:running"))return{bundleUrl:`${t}${ne}`,port:o,framework:"metro"}}catch{}return null}async function ut(e){return We(He("http:","localhost",e),e)}async function je(e){let o=e.trim();if(/^\d+$/.test(o)){let a=parseInt(o,10),l=await ut(a);if(l)return l;throw Ne(`localhost:${a}`)}let t=o.startsWith("http")?o:`http://${o}`,n;try{n=new URL(t)}catch{throw new Error(`could not parse "${e}". pass a dev-server port, a dev-server base URL, or a full bundle URL.`)}let r=n.protocol||"http:",s=n.port?parseInt(n.port,10):ct(r),i=He(r,n.hostname,s);if(dt(n)){let a=await We(i,s);if(a)return a;throw Ne(i)}return{bundleUrl:n.toString(),port:s,framework:"unknown"}}function lo(){console.error(" no sootsim desktop companion found."),console.error(""),console.error(" install the desktop app:"),console.error(" sootsim desktop install"),console.error(""),console.error(" or run setup to install the background daemon:"),console.error(" sootsim setup"),console.error("")}function Ke(e){let o=O();if(console.log(` note: no sootsim bridge detected on port ${e}`),o){console.log(" launch the installed companion with:"),console.log(" sootsim desktop");return}console.log(""),console.log(" run `sootsim setup` to install the background daemon,"),console.log(" or run `sootsim serve` in another shell for a foreground bridge.")}function pt(e){console.error(""),console.error(` no sim is connected to the sootsim bridge on port ${e}.`),console.error(""),console.error(" start your app dev server, then open it in sootsim:"),console.error(" npx expo start --localhost --port 8081"),console.error(" sootsim open 8081"),console.error(""),console.error(" then inspect the live app:"),console.error(" sootsim describe")}async function co(e,o,t){let n=[];try{n=await e.listSims()}catch{}if(console.error(""),n.length===0){pt(o);return}console.error(` no sim with id "${t}" is connected to the bridge on port ${o}.`),console.error(""),console.error(" connected sims:");for(let r of n){let s=[r.isPrimary?"primary":null,r.readyState,r.userVisible===!1?"hidden":r.userVisible===!0?"visible":null,r.userFocused?"focused":null].filter(Boolean).join(", ");console.error(` ${r.id} (${s})`)}console.error(""),console.error(" pass a valid --sim id, or run `sootsim list` to see all sessions.")}var gt=12e4,Ve=100,wt=5e3,Ge=1e4,bt={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 $(e){return new Promise(o=>setTimeout(o,e))}function Je(e){let o=process.env[e]?.trim();if(!o)return null;let t=Number(o);return Number.isInteger(t)&&t>0?t:null}function yt(){let e=Je("SOOTSIM_DRIVER_CONNECT_TIMEOUT_MS")??Je("SOOTSIM_PW_CONNECT_TIMEOUT_MS")??gt;return{timeoutMs:e,hostTimeoutMs:e+wt,intervalMs:Ve,attempts:Math.max(1,Math.ceil(e/Ve))}}function vt(e){return e==="chromium"||e==="electron"||e==="playwright"||e==="system"}function St(e,o){return e.includes("--headless")?!0:e.includes("--headed")?!1:o==="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 V(e){return e.trim()}var Xe=/^[A-Za-z][A-Za-z0-9+.-]*:/;function $t(e){let o=e.trim();if(!o)throw new Error("expected <url-or-route>");return Xe.test(o)||o.startsWith("/")?o:`/${o}`}function xt(e){return e!==null&&typeof e=="object"}function kt(e){let o=e.trim();return o?o.startsWith("/")?!0:Xe.test(o)?!/^https?:\/\//i.test(o):!1:!1}async function Pt(e){if(await q(e,250))return e;let o=te();if(o&&j(o)&&await q(o.bridgePort,500))return o.bridgePort;if(o&&j(o))throw new Error(`sootsim bridge lockfile is fresh (port ${o.bridgePort}) but the bridge is not reachable. run \`sootsim daemon restart\` or \`sootsim daemon uninstall\`.`);await It();let t=Ct(["serve","--quiet","--port",String(e)]),n=null;t.once("exit",(s,i)=>{n=String(s??i??"unknown")}),t.unref();let r=Date.now()+Ge;for(;Date.now()<r;){let s=te();if(s&&j(s)&&await q(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 q(e,250))return console.error(` started local bridge on port ${e}; run \`sootsim setup\` to install the background daemon`),e;if(n)throw new Error(`sootsim bridge exited before becoming ready (exit ${n})`);await $(150)}throw new Error(`sootsim bridge did not start within ${Math.round(Ge/1e3)}s`)}async function It(){let e=$e();if(e&&L.existsSync(Se(e)))return;console.error(" installing sootsim engine runtime...");let{runRuntime:o}=await import("./runtime-HOGETVVD.js");await o(["install"],{})}function Ct(e){let o=process.argv[1];return o&&L.existsSync(o)?qe(process.execPath,[o,...e],{detached:!0,stdio:"ignore",env:process.env}):qe("sootsim",e,{detached:!0,stdio:"ignore",env:process.env})}function q(e,o){return new Promise(t=>{let n=new ht(`ws://127.0.0.1:${e}`,{handshakeTimeout:o}),r=!1,s=i=>{if(!r){r=!0;try{n.close()}catch{}t(i)}};n.once("open",()=>s(!0)),n.once("error",()=>s(!1)),setTimeout(()=>s(!1),o)})}function ue(e){try{let o=new URL(e),t=o.pathname.replace(/\/+$/,"")||"/";return o.searchParams.has("open")||o.searchParams.has("port")||o.searchParams.has("bundle")||o.searchParams.has("demo")||o.pathname.includes("/sootsim/index.html")||t==="/sootsim"||o.pathname==="/__soot"||o.pathname==="/__soot/"||t==="/rn"||/^\/rn\/[^/]+$/i.test(t)||/^\/app\/[^/]+$/i.test(t)||t==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(t)||/^\/__soot\/app\/[^/]+$/i.test(t)}catch{return!1}}function Et(e){try{let o=new URL(e,"http://sootsim.local");if(o.origin!=="http://sootsim.local")return!1;let t=o.pathname.replace(/\/+$/,"")||"/";return t==="/rn"||/^\/rn\/[^/]+$/i.test(t)||/^\/app\/[^/]+$/i.test(t)||t==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(t)||/^\/__soot\/app\/[^/]+$/i.test(t)}catch{return!1}}function Mt(e,o){let t=new URL(e,"http://sootsim.local"),n=new URL(o),r=G(n.pathname),s=t.pathname.startsWith("/__soot/")?t.pathname.slice(7):t.pathname;return n.pathname=`${r}${s}`,n.search=t.search,n.hash=t.hash,n.toString()}function Tt(e){try{let o=new URL(e).pathname.replace(/\/+$/,"")||"/";return/^\/preview\/[^/]+$/.test(o)||/^\/build\/.+/.test(o)}catch{return!1}}async function Do(e){let o=V(e);return(await et(o)).bundleUrl}function _t(e){try{let o=new URL(e.startsWith("http")?e:`http://${e}`),t=o.pathname||"/";if(t!=="/"&&t!==""||o.search||o.hash||!I(o.hostname))return null;let n=o.port?Number(o.port):o.protocol==="https:"?443:80;return Number.isFinite(n)&&n>0?n:null}catch{return null}}async function et(e){let o=V(e),t=/^\d+$/.test(o)?Number(o):_t(o);if(t&&t>0){let n=await Ie(t);if(n)return{bundleUrl:n.bundleUrl,port:n.port,framework:n.framework,projectName:n.projectName}}return je(o)}function G(e){let o=e.replace(/\/+$/,"")||"/";return o==="/__soot"||o.startsWith("/__soot/")?"/__soot":""}function Ut(e,o){let t=V(e),n=new URL(o),r=G(n.pathname);return n.pathname=`${r}/rn`,n.searchParams.delete("bundle"),n.searchParams.delete("demo"),n.searchParams.delete("app"),n.searchParams.delete("open"),n.searchParams.delete("port"),/^\d+$/.test(t)?n.pathname=`${r}/rn/${t}`:(n.pathname=`${r}/rn`,n.searchParams.set("open",t)),n.toString()}function Rt(e){let o=V(e);return/^\d+$/.test(o)||/^https?:\/\//i.test(o)?!0:/^(localhost|127\.0\.0\.1|\[::1\]|[^/]+\.localhost):\d+(?:\/.*)?$/i.test(o)}async function Ot(e,o,t={}){let n=await et(e),r=new URL(o),s=G(r.pathname);r.pathname=`${s}/rn`,r.searchParams.delete("open"),r.searchParams.delete("port"),r.searchParams.delete("demo"),r.searchParams.delete("app");let i=t.hot===void 0?n.bundleUrl:Pe(n.bundleUrl,t.hot);return r.searchParams.set("bundle",i),r.toString()}function Bt(e){return e.startsWith("~/")?T.join(ft.homedir(),e.slice(2)):T.isAbsolute(e)?e:T.resolve(process.cwd(),e)}function Dt(e){let o={},t={};for(let r=0;r<e.length;r++){if(e[r]==="--replace"){let s=e[r+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=Bt(s.slice(i+1).trim());L.existsSync(l)||(console.error(` sootsim open: replacement file not found: ${l}`),process.exit(1)),o[a]={file:l},r++;continue}if(e[r]==="--remap"){let s=e[r+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)),t[s.slice(0,i).trim()]=s.slice(i+1).trim(),r++;continue}}let n={};return Object.keys(o).length>0&&(n.modules=o),Object.keys(t).length>0&&(n.network={remap:t}),n.modules||n.network?n:void 0}function tt(){return Be().shellBaseUrl}async function Lt(e){try{let o=new URL(e),t=o.searchParams.get("bundle")||"";if(!t)return e;let n=process.env.CONTRAST_REPO_DIR||await se(t)||void 0,r=Me({bundleUrl:t,repoDir:n});if(r.length===0)return e;let s=await At(r);return s.length===0?e:(o.searchParams.set("appFonts",Te(s)),o.toString())}catch{return e}}async function At(e){let o=await Promise.all(e.map(async n=>{let r=new AbortController,s=setTimeout(()=>r.abort(),1500);try{let i=await fetch(n.url,{method:"HEAD",signal:r.signal});return i.status>=200&&i.status<400?n:null}catch{return null}finally{clearTimeout(s)}})),t=[];for(let n of o)n!==null&&t.push(n);return t}async function Nt(e,o,t={}){if(!e)return new URL(o).toString();if(ue(e))return new URL(e).toString();if(Et(e))return Mt(e,o);let n=bt[e.toLowerCase()];if(n){let r=new URL(o),s=G(r.pathname);return r.pathname=`${s}${n}`,r.toString()}return Rt(e)?Ot(e,o,t):Ut(e,o)}async function Ft(e){try{let o=new URL(e),t=o.searchParams.get("bundle")||"";if(!t)return e;let n=process.env.CONTRAST_REPO_DIR||await se(t)||void 0,r=_e({bundleUrl:t,repoDir:n});return!r||r.imageUrl&&!await Ht(r.imageUrl)?e:(o.searchParams.set("appSplash",Ue(r)),o.toString())}catch{return e}}async function Ht(e){let o=new AbortController,t=setTimeout(()=>o.abort(),1500);try{let n=await fetch(e,{method:"HEAD",signal:o.signal});return n.status>=200&&n.status<400}catch{return!1}finally{clearTimeout(t)}}async function z(e,o=tt(),t={}){let n=await Nt(e,o,t),r=await Ft(await Lt(n));if(!t.device)return r;let s=new URL(r);return s.searchParams.set("device",t.device),s.toString()}function Qe(e,o){let t=e?.url||e?.origin||o;try{let n=new URL(t);return n.searchParams.delete("bundle"),n.searchParams.delete("demo"),n.searchParams.delete("app"),n.searchParams.delete("open"),n.searchParams.delete("port"),n.searchParams.delete("inspectOpen"),n.searchParams.delete("appFonts"),n.searchParams.delete("appSplash"),n.toString()}catch{return o}}async function Wt(e,o,t,n={}){let r=new URL(await z(e,o,n));return r.searchParams.set("inspectOpen",t),r.toString()}async function jt(e,o,t,n={}){let r=n.attempts??30,s=n.intervalMs??500,i=n.minNodeCount??10;for(let a=0;a<r;a++){let l=v(e,{commandTimeoutMs:o,simId:t,simIdSource:"flag"});try{let d=await l.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount()) || 0)()"});if(typeof d=="number"&&d>i)return{bridge:l,count:d}}catch{}l.close(),await $(s)}return null}function Kt(e){if(!e)return null;try{let o=new URL(e);if(o.searchParams.has("bundle")){let t=o.searchParams.get("bundle")||"";try{let n=new URL(t),r=n.pathname.length>36?`...${n.pathname.slice(-36)}`:n.pathname;return`bundle ${n.host}${r}`}catch{return"bundle"}}return o.searchParams.has("port")?`connect :${o.searchParams.get("port")||""}`:o.searchParams.has("open")?`connect ${o.searchParams.get("open")||""}`:o.searchParams.has("demo")?`demo ${o.searchParams.get("demo")||"default"}`:o.pathname.includes("/sootsim/index.html")||o.pathname==="/sootsim/"||o.pathname==="/sootsim"?"embedded sootsim":null}catch{return null}}function qt(e){let o=e.indexOf(":");if(o<=0)return e.length>24?`${e.slice(0,21)}\u2026`:e;let t=e.slice(0,o),n=e.slice(o+1),r=n.length>12?`${n.slice(0,8)}\u2026`:n;return t==="AGENTBUS_SESSION"||t==="CLAUDE_CODE_SESSION_ID"||t==="CODEX_THREAD_ID"?`agent ${r}`:`${t} ${r}`}function Lo(e,o){if(e.length===0){console.log(" no sims connected");return}console.log(` connected sims (${e.length}):
3
- `);for(let t of e){let n=t.lockedBy&&t.lockExpiresAt?`locked by ${qt(t.lockedBy)} (${Math.max(0,Math.round((t.lockExpiresAt-Date.now())/1e3))}s)`:"",r=[t.isPrimary?"primary":"",t.id===o?"selected":"",t.readyState,t.userVisible===!1?"hidden":t.userVisible===!0?"visible":"",t.attachedCliCount&&t.attachedCliCount>0?"in use":"",t.userFocused?"focused":"",n].filter(Boolean);console.log(` ${t.id}${r.length?` [${r.join(", ")}]`:""}`);let s=Kt(t.url);if(s)console.log(` loaded: ${s}`);else if(t.url){let a=t.url.length>96?`${t.url.slice(0,93)}\u2026`:t.url;console.log(` url: ${a}`)}else t.origin&&console.log(` origin: ${t.origin}`);let i=zt(t);i&&console.log(` engine: ${i}`),t.title&&console.log(` title: ${t.title}`),t.visibilityState&&t.visibilityState!=="visible"&&console.log(` visibility: ${t.visibilityState}`),console.log(` connected: ${Ye(Date.now()-t.connectedAt)}`),t.lastActiveAt&&t.lastActiveAt>0&&console.log(` last active: ${Ye(Date.now()-t.lastActiveAt)}`)}}function zt(e){let o=e.url||e.origin||"";if(!o)return null;try{let t=new URL(o).port;return t==="5173"?"dev \u2014 local source (:5173)":t==="3000"?"Contrast app embedded (:3000)":Ee()?`dev \u2014 local build (:${t||"?"})`:`runtime \u2014 published engine (:${t||"?"})`}catch{return null}}function Ye(e){let o=Math.max(0,Math.round(e/1e3));return o<60?`${o}s ago`:o<3600?`${Math.round(o/60)}m ago`:o<86400?`${Math.round(o/3600)}h ago`:`${Math.round(o/86400)}d ago`}async function de(e,o,t,n={}){let r=n.attempts??30,s=n.intervalMs??500;for(let i=0;i<r;i++){let a=v(e,{commandTimeoutMs:o});try{let d=(await a.listSims()).find(t);if(d)return d}catch{}finally{a.close()}await $(s)}return null}async function Vt(e,o,t,n,r={}){let s=r.attempts??30,i=r.intervalMs??500,a=!!n&&Number.isInteger(n)&&n>1,l=()=>a&&n!==void 0&&!pe(n);for(let d=0;d<s;d++){if(l())return{kind:"host-exit"};let m=v(e,{commandTimeoutMs:o});try{let g=(await m.listSims()).find(t);if(g)return l()?{kind:"host-exit"}:{kind:"match",sim:g}}catch{}finally{m.close()}if(l())return{kind:"host-exit"};await $(i)}return{kind:"timeout"}}async function Gt(e,o,t,n={}){let r=n.attempts??20,s=n.intervalMs??250;for(let i=0;i<r;i++){let a=v(e,{commandTimeoutMs:o});try{let d=(await a.listSims()).find(m=>m.id===t);if(!d||d.readyState!=="open")return!0}catch{return!0}finally{a.close()}await $(s)}return!1}function Jt(e){let o=e.meta;if(!o||o.sootsimHostDriver!=="playwright")return null;let t=Number(o.sootsimHostPid);return!Number.isInteger(t)||t<=1||t===process.pid?null:t}function Qt(e){if(!e.connectAckFile)return!1;try{return L.writeFileSync(e.connectAckFile,`${JSON.stringify({connectedAt:Date.now(),pid:e.pid??null})}
1
+ /*! sootsim v0.1.294 | (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 K,b as ne,c as re,d as Pe,e as Ie,g as I,h as Me}from"./chunk-XYFP466E.js";import{m as U}from"./chunk-RWUNC66S.js";import{b as Ce,l as ce}from"./chunk-KWIURH7N.js";import{a as O,b as ae}from"./chunk-AMKQUZA2.js";import{m as Ue,p as Oe}from"./chunk-AFLGWOX3.js";import{a as _e,b as Re}from"./chunk-6YN3IAWJ.js";import{a as Ee,b as se,c as Te}from"./chunk-37ZXWXM3.js";import{d as le}from"./chunk-VVVORIQI.js";import{a as Be,b as De,c as ie,e as Le,f as Ae,g as M,h as v,i as E}from"./chunk-PZTKQG6H.js";import{b as oe,d as xe}from"./chunk-VXGCZUX4.js";import{d as ke,e as _,f as b,g as R}from"./chunk-JUOQ4ZPA.js";import{H as $e,K as te,M as j,l as Se}from"./chunk-WQL3BLFD.js";import{spawn as qe,spawnSync as ze}from"node:child_process";import L from"node:fs";import ft from"node:os";import T from"node:path";import{WebSocket as ht}from"ws";function Ne(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 at(e,o){return e?.includes("/one/metro-entry.bundle")?"one":typeof o=="string"&&o?"expo":"unknown"}function He(e,o,t){return`${e}//${o}:${t}`}function lt(e){if(typeof window>"u")return!1;try{let o=new URL(e);return I(o.hostname)&&I(window.location.hostname)&&o.origin!==window.location.origin}catch{return!1}}async function Fe(e,o){let t={...o,cache:o?.cache??"no-store"};return lt(e)?fetch(`/__fetch-proxy?url=${encodeURIComponent(e)}`,t):fetch(e,t)}function ct(e){return e==="https:"?443:80}function dt(e){let o=e.pathname||"/";return(o==="/"||o==="")&&!e.search&&!e.hash}async function mt(e){try{let o=await fetch("/__server-scan",{cache:"no-store"});if(!o.ok||!(o.headers.get("content-type")||"").toLowerCase().includes("json"))return null;let t=await o.json();if(!Array.isArray(t))return null;let n=t.find(r=>!!r&&typeof r=="object"&&r.port===e&&typeof r.bundleUrl=="string");return n?{bundleUrl:re(n.bundleUrl),port:e,framework:typeof n.framework=="string"?n.framework:"unknown",projectName:typeof n.projectName=="string"?n.projectName:void 0}:null}catch{return null}}async function We(e,o){let t=e.replace(/\/+$/,"");try{if(I(new URL(t).hostname)){let n=await mt(o);if(n)return n}}catch{}try{let n=await Fe(`${t}/`,{headers:{"expo-platform":"ios"}});if(n.ok){let r=await n.json(),s=r?.extra?.expoClient||r?.extra||{},i=typeof r?.launchAsset?.url=="string"?r.launchAsset.url:void 0;if(i||s.name)return{bundleUrl:re(i||`${t}${ne}`),port:o,framework:at(i,s.sdkVersion),projectName:s.name}}}catch{}try{let n=await Fe(`${t}/status`);if(n.ok&&(await n.text()).includes("packager-status:running"))return{bundleUrl:`${t}${ne}`,port:o,framework:"metro"}}catch{}return null}async function ut(e){return We(He("http:","localhost",e),e)}async function je(e){let o=e.trim();if(/^\d+$/.test(o)){let a=parseInt(o,10),l=await ut(a);if(l)return l;throw Ne(`localhost:${a}`)}let t=o.startsWith("http")?o:`http://${o}`,n;try{n=new URL(t)}catch{throw new Error(`could not parse "${e}". pass a dev-server port, a dev-server base URL, or a full bundle URL.`)}let r=n.protocol||"http:",s=n.port?parseInt(n.port,10):ct(r),i=He(r,n.hostname,s);if(dt(n)){let a=await We(i,s);if(a)return a;throw Ne(i)}return{bundleUrl:n.toString(),port:s,framework:"unknown"}}function lo(){console.error(" no sootsim desktop companion found."),console.error(""),console.error(" install the desktop app:"),console.error(" sootsim desktop install"),console.error(""),console.error(" or run setup to install the background daemon:"),console.error(" sootsim setup"),console.error("")}function Ke(e){let o=O();if(console.log(` note: no sootsim bridge detected on port ${e}`),o){console.log(" launch the installed companion with:"),console.log(" sootsim desktop");return}console.log(""),console.log(" run `sootsim setup` to install the background daemon,"),console.log(" or run `sootsim serve` in another shell for a foreground bridge.")}function pt(e){console.error(""),console.error(` no sim is connected to the sootsim bridge on port ${e}.`),console.error(""),console.error(" start your app dev server, then open it in sootsim:"),console.error(" npx expo start --localhost --port 8081"),console.error(" sootsim open 8081"),console.error(""),console.error(" then inspect the live app:"),console.error(" sootsim describe")}async function co(e,o,t){let n=[];try{n=await e.listSims()}catch{}if(console.error(""),n.length===0){pt(o);return}console.error(` no sim with id "${t}" is connected to the bridge on port ${o}.`),console.error(""),console.error(" connected sims:");for(let r of n){let s=[r.isPrimary?"primary":null,r.readyState,r.userVisible===!1?"hidden":r.userVisible===!0?"visible":null,r.userFocused?"focused":null].filter(Boolean).join(", ");console.error(` ${r.id} (${s})`)}console.error(""),console.error(" pass a valid --sim id, or run `sootsim list` to see all sessions.")}var gt=12e4,Ve=100,wt=5e3,Ge=1e4,bt={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 $(e){return new Promise(o=>setTimeout(o,e))}function Je(e){let o=process.env[e]?.trim();if(!o)return null;let t=Number(o);return Number.isInteger(t)&&t>0?t:null}function yt(){let e=Je("SOOTSIM_DRIVER_CONNECT_TIMEOUT_MS")??Je("SOOTSIM_PW_CONNECT_TIMEOUT_MS")??gt;return{timeoutMs:e,hostTimeoutMs:e+wt,intervalMs:Ve,attempts:Math.max(1,Math.ceil(e/Ve))}}function vt(e){return e==="chromium"||e==="electron"||e==="playwright"||e==="system"}function St(e,o){return e.includes("--headless")?!0:e.includes("--headed")?!1:o==="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 V(e){return e.trim()}var Xe=/^[A-Za-z][A-Za-z0-9+.-]*:/;function $t(e){let o=e.trim();if(!o)throw new Error("expected <url-or-route>");return Xe.test(o)||o.startsWith("/")?o:`/${o}`}function xt(e){return e!==null&&typeof e=="object"}function kt(e){let o=e.trim();return o?o.startsWith("/")?!0:Xe.test(o)?!/^https?:\/\//i.test(o):!1:!1}async function Pt(e){if(await q(e,250))return e;let o=te();if(o&&j(o)&&await q(o.bridgePort,500))return o.bridgePort;if(o&&j(o))throw new Error(`sootsim bridge lockfile is fresh (port ${o.bridgePort}) but the bridge is not reachable. run \`sootsim daemon restart\` or \`sootsim daemon uninstall\`.`);await It();let t=Ct(["serve","--quiet","--port",String(e)]),n=null;t.once("exit",(s,i)=>{n=String(s??i??"unknown")}),t.unref();let r=Date.now()+Ge;for(;Date.now()<r;){let s=te();if(s&&j(s)&&await q(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 q(e,250))return console.error(` started local bridge on port ${e}; run \`sootsim setup\` to install the background daemon`),e;if(n)throw new Error(`sootsim bridge exited before becoming ready (exit ${n})`);await $(150)}throw new Error(`sootsim bridge did not start within ${Math.round(Ge/1e3)}s`)}async function It(){let e=$e();if(e&&L.existsSync(Se(e)))return;console.error(" installing sootsim engine runtime...");let{runRuntime:o}=await import("./runtime-SN2RWDES.js");await o(["install"],{})}function Ct(e){let o=process.argv[1];return o&&L.existsSync(o)?qe(process.execPath,[o,...e],{detached:!0,stdio:"ignore",env:process.env}):qe("sootsim",e,{detached:!0,stdio:"ignore",env:process.env})}function q(e,o){return new Promise(t=>{let n=new ht(`ws://127.0.0.1:${e}`,{handshakeTimeout:o}),r=!1,s=i=>{if(!r){r=!0;try{n.close()}catch{}t(i)}};n.once("open",()=>s(!0)),n.once("error",()=>s(!1)),setTimeout(()=>s(!1),o)})}function ue(e){try{let o=new URL(e),t=o.pathname.replace(/\/+$/,"")||"/";return o.searchParams.has("open")||o.searchParams.has("port")||o.searchParams.has("bundle")||o.searchParams.has("demo")||o.pathname.includes("/sootsim/index.html")||t==="/sootsim"||o.pathname==="/__soot"||o.pathname==="/__soot/"||t==="/rn"||/^\/rn\/[^/]+$/i.test(t)||/^\/app\/[^/]+$/i.test(t)||t==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(t)||/^\/__soot\/app\/[^/]+$/i.test(t)}catch{return!1}}function Mt(e){try{let o=new URL(e,"http://sootsim.local");if(o.origin!=="http://sootsim.local")return!1;let t=o.pathname.replace(/\/+$/,"")||"/";return t==="/rn"||/^\/rn\/[^/]+$/i.test(t)||/^\/app\/[^/]+$/i.test(t)||t==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(t)||/^\/__soot\/app\/[^/]+$/i.test(t)}catch{return!1}}function Et(e,o){let t=new URL(e,"http://sootsim.local"),n=new URL(o),r=G(n.pathname),s=t.pathname.startsWith("/__soot/")?t.pathname.slice(7):t.pathname;return n.pathname=`${r}${s}`,n.search=t.search,n.hash=t.hash,n.toString()}function Tt(e){try{let o=new URL(e).pathname.replace(/\/+$/,"")||"/";return/^\/preview\/[^/]+$/.test(o)||/^\/build\/.+/.test(o)}catch{return!1}}async function Do(e){let o=V(e);return(await et(o)).bundleUrl}function _t(e){try{let o=new URL(e.startsWith("http")?e:`http://${e}`),t=o.pathname||"/";if(t!=="/"&&t!==""||o.search||o.hash||!I(o.hostname))return null;let n=o.port?Number(o.port):o.protocol==="https:"?443:80;return Number.isFinite(n)&&n>0?n:null}catch{return null}}async function et(e){let o=V(e),t=/^\d+$/.test(o)?Number(o):_t(o);if(t&&t>0){let n=await Ie(t);if(n)return{bundleUrl:n.bundleUrl,port:n.port,framework:n.framework,projectName:n.projectName}}return je(o)}function G(e){let o=e.replace(/\/+$/,"")||"/";return o==="/__soot"||o.startsWith("/__soot/")?"/__soot":""}function Rt(e,o){let t=V(e),n=new URL(o),r=G(n.pathname);return n.pathname=`${r}/rn`,n.searchParams.delete("bundle"),n.searchParams.delete("demo"),n.searchParams.delete("app"),n.searchParams.delete("open"),n.searchParams.delete("port"),/^\d+$/.test(t)?n.pathname=`${r}/rn/${t}`:(n.pathname=`${r}/rn`,n.searchParams.set("open",t)),n.toString()}function Ut(e){let o=V(e);return/^\d+$/.test(o)||/^https?:\/\//i.test(o)?!0:/^(localhost|127\.0\.0\.1|\[::1\]|[^/]+\.localhost):\d+(?:\/.*)?$/i.test(o)}async function Ot(e,o,t={}){let n=await et(e),r=new URL(o),s=G(r.pathname);r.pathname=`${s}/rn`,r.searchParams.delete("open"),r.searchParams.delete("port"),r.searchParams.delete("demo"),r.searchParams.delete("app");let i=t.hot===void 0?n.bundleUrl:Pe(n.bundleUrl,t.hot);return r.searchParams.set("bundle",i),r.toString()}function Bt(e){return e.startsWith("~/")?T.join(ft.homedir(),e.slice(2)):T.isAbsolute(e)?e:T.resolve(process.cwd(),e)}function Dt(e){let o={},t={};for(let r=0;r<e.length;r++){if(e[r]==="--replace"){let s=e[r+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=Bt(s.slice(i+1).trim());L.existsSync(l)||(console.error(` sootsim open: replacement file not found: ${l}`),process.exit(1)),o[a]={file:l},r++;continue}if(e[r]==="--remap"){let s=e[r+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)),t[s.slice(0,i).trim()]=s.slice(i+1).trim(),r++;continue}}let n={};return Object.keys(o).length>0&&(n.modules=o),Object.keys(t).length>0&&(n.network={remap:t}),n.modules||n.network?n:void 0}function tt(){return Be().shellBaseUrl}async function Lt(e){try{let o=new URL(e),t=o.searchParams.get("bundle")||"";if(!t)return e;let n=await se(t)||process.env.CONTRAST_REPO_DIR||void 0,r=Ee({bundleUrl:t,repoDir:n});if(r.length===0)return e;let s=await At(r);return s.length===0?e:(o.searchParams.set("appFonts",Te(s)),o.toString())}catch{return e}}async function At(e){let o=await Promise.all(e.map(async n=>{let r=new AbortController,s=setTimeout(()=>r.abort(),1500);try{let i=await fetch(n.url,{method:"HEAD",signal:r.signal});return i.status>=200&&i.status<400?n:null}catch{return null}finally{clearTimeout(s)}})),t=[];for(let n of o)n!==null&&t.push(n);return t}async function Nt(e,o,t={}){if(!e)return new URL(o).toString();if(ue(e))return new URL(e).toString();if(Mt(e))return Et(e,o);let n=bt[e.toLowerCase()];if(n){let r=new URL(o),s=G(r.pathname);return r.pathname=`${s}${n}`,r.toString()}return Ut(e)?Ot(e,o,t):Rt(e,o)}async function Ft(e){try{let o=new URL(e),t=o.searchParams.get("bundle")||"";if(!t)return e;let n=await se(t)||process.env.CONTRAST_REPO_DIR||void 0,r=_e({bundleUrl:t,repoDir:n});return!r||r.imageUrl&&!await Ht(r.imageUrl)?e:(o.searchParams.set("appSplash",Re(r)),o.toString())}catch{return e}}async function Ht(e){let o=new AbortController,t=setTimeout(()=>o.abort(),1500);try{let n=await fetch(e,{method:"HEAD",signal:o.signal});return n.status>=200&&n.status<400}catch{return!1}finally{clearTimeout(t)}}async function z(e,o=tt(),t={}){let n=await Nt(e,o,t),r=await Ft(await Lt(n));if(!t.device)return r;let s=new URL(r);return s.searchParams.set("device",t.device),s.toString()}function Qe(e,o){let t=e?.url||e?.origin||o;try{let n=new URL(t);return n.searchParams.delete("bundle"),n.searchParams.delete("demo"),n.searchParams.delete("app"),n.searchParams.delete("open"),n.searchParams.delete("port"),n.searchParams.delete("inspectOpen"),n.searchParams.delete("appFonts"),n.searchParams.delete("appSplash"),n.toString()}catch{return o}}async function Wt(e,o,t,n={}){let r=new URL(await z(e,o,n));return r.searchParams.set("inspectOpen",t),r.toString()}async function jt(e,o,t,n={}){let r=n.attempts??30,s=n.intervalMs??500,i=n.minNodeCount??10;for(let a=0;a<r;a++){let l=v(e,{commandTimeoutMs:o,simId:t,simIdSource:"flag"});try{let d=await l.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount()) || 0)()"});if(typeof d=="number"&&d>i)return{bridge:l,count:d}}catch{}l.close(),await $(s)}return null}function Kt(e){if(!e)return null;try{let o=new URL(e);if(o.searchParams.has("bundle")){let t=o.searchParams.get("bundle")||"";try{let n=new URL(t),r=n.pathname.length>36?`...${n.pathname.slice(-36)}`:n.pathname;return`bundle ${n.host}${r}`}catch{return"bundle"}}return o.searchParams.has("port")?`connect :${o.searchParams.get("port")||""}`:o.searchParams.has("open")?`connect ${o.searchParams.get("open")||""}`:o.searchParams.has("demo")?`demo ${o.searchParams.get("demo")||"default"}`:o.pathname.includes("/sootsim/index.html")||o.pathname==="/sootsim/"||o.pathname==="/sootsim"?"embedded sootsim":null}catch{return null}}function qt(e){let o=e.indexOf(":");if(o<=0)return e.length>24?`${e.slice(0,21)}\u2026`:e;let t=e.slice(0,o),n=e.slice(o+1),r=n.length>12?`${n.slice(0,8)}\u2026`:n;return t==="TM_SESSION"||t==="CLAUDE_CODE_SESSION_ID"||t==="CODEX_THREAD_ID"?`agent ${r}`:`${t} ${r}`}function Lo(e,o){if(e.length===0){console.log(" no sims connected");return}console.log(` connected sims (${e.length}):
5
+ `);for(let t of e){let n=t.lockedBy&&t.lockExpiresAt?`locked by ${qt(t.lockedBy)} (${Math.max(0,Math.round((t.lockExpiresAt-Date.now())/1e3))}s)`:"",r=[t.isPrimary?"primary":"",t.id===o?"selected":"",t.readyState,t.userVisible===!1?"hidden":t.userVisible===!0?"visible":"",t.attachedCliCount&&t.attachedCliCount>0?"in use":"",t.userFocused?"focused":"",n].filter(Boolean);console.log(` ${t.id}${r.length?` [${r.join(", ")}]`:""}`);let s=Kt(t.url);if(s)console.log(` loaded: ${s}`);else if(t.url){let a=t.url.length>96?`${t.url.slice(0,93)}\u2026`:t.url;console.log(` url: ${a}`)}else t.origin&&console.log(` origin: ${t.origin}`);let i=zt(t);i&&console.log(` engine: ${i}`),t.title&&console.log(` title: ${t.title}`),t.visibilityState&&t.visibilityState!=="visible"&&console.log(` visibility: ${t.visibilityState}`),console.log(` connected: ${Ye(Date.now()-t.connectedAt)}`),t.lastActiveAt&&t.lastActiveAt>0&&console.log(` last active: ${Ye(Date.now()-t.lastActiveAt)}`)}}function zt(e){let o=e.url||e.origin||"";if(!o)return null;try{let t=new URL(o).port;return t==="5173"?"dev \u2014 local source (:5173)":t==="3000"?"Contrast app embedded (:3000)":Me()?`dev \u2014 local build (:${t||"?"})`:`runtime \u2014 published engine (:${t||"?"})`}catch{return null}}function Ye(e){let o=Math.max(0,Math.round(e/1e3));return o<60?`${o}s ago`:o<3600?`${Math.round(o/60)}m ago`:o<86400?`${Math.round(o/3600)}h ago`:`${Math.round(o/86400)}d ago`}async function de(e,o,t,n={}){let r=n.attempts??30,s=n.intervalMs??500;for(let i=0;i<r;i++){let a=v(e,{commandTimeoutMs:o});try{let d=(await a.listSims()).find(t);if(d)return d}catch{}finally{a.close()}await $(s)}return null}async function Vt(e,o,t,n,r={}){let s=r.attempts??30,i=r.intervalMs??500,a=!!n&&Number.isInteger(n)&&n>1,l=()=>a&&n!==void 0&&!pe(n);for(let d=0;d<s;d++){if(l())return{kind:"host-exit"};let m=v(e,{commandTimeoutMs:o});try{let g=(await m.listSims()).find(t);if(g)return l()?{kind:"host-exit"}:{kind:"match",sim:g}}catch{}finally{m.close()}if(l())return{kind:"host-exit"};await $(i)}return{kind:"timeout"}}async function Gt(e,o,t,n={}){let r=n.attempts??20,s=n.intervalMs??250;for(let i=0;i<r;i++){let a=v(e,{commandTimeoutMs:o});try{let d=(await a.listSims()).find(m=>m.id===t);if(!d||d.readyState!=="open")return!0}catch{return!0}finally{a.close()}await $(s)}return!1}function Jt(e){let o=e.meta;if(!o||o.sootsimHostDriver!=="playwright")return null;let t=Number(o.sootsimHostPid);return!Number.isInteger(t)||t<=1||t===process.pid?null:t}function Qt(e){if(!e.connectAckFile)return!1;try{return L.writeFileSync(e.connectAckFile,`${JSON.stringify({connectedAt:Date.now(),pid:e.pid??null})}
4
6
  `,{flag:"w"}),!0}catch{return!1}}function Ze(e){if(e.diagnosticLogPath)try{let o=L.readFileSync(e.diagnosticLogPath,"utf8").trim();if(!o){console.error(` ${T.basename(e.diagnosticLogPath)} was empty`);return}let t=o.length>4e3?`\u2026
5
- ${o.slice(-4e3)}`:o;console.error(` ${T.basename(e.diagnosticLogPath)}:`),console.error(t)}catch(o){let t=o instanceof Error?o.message:String(o);console.error(` failed to read ${T.basename(e.diagnosticLogPath)}: ${t}`)}}function pe(e){try{return process.kill(e,0),!0}catch(o){return o?.code==="EPERM"}}async function Yt(e,o=2500){let t=Date.now()+o;for(;Date.now()<t;){if(!pe(e))return!0;await $(100)}return!pe(e)}function Zt(e){let o=ze("ps",["-o","command=","-p",String(e)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),t=ze("ps",["eww","-o","command=","-p",String(e)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]});if(o.status!==0||t.status!==0)return!1;let n=(o.stdout||"").trimEnd(),r=(t.stdout||"").trimEnd();return(r.startsWith(n)?r.slice(n.length):r).includes("SOOTSIM_PW_URL=")}async function me(e,o){let t=new Set(o),n=new Set;for(let r of e){if(!t.has(r.id))continue;let s=Jt(r);s&&n.add(s)}for(let r of n){if(!Zt(r)){console.log(` skipped pid ${r}: not a sootsim playwright host (stale sim record)`);continue}try{process.kill(r,"SIGTERM")}catch{}if(await Yt(r)){console.log(` closed playwright host process ${r}`);continue}try{process.kill(r,"SIGKILL"),console.log(` force-closed playwright host process ${r}`)}catch{}}}function J(e,o){if(o){let r=o.trim(),s=e.find(i=>i.id===r);if(!s)throw new Error(`no sim connected with id ${r}`);return s}let t=e.find(r=>r.isPrimary&&r.readyState==="open");if(t)return t;let n=e.find(r=>r.readyState==="open");if(n)return n;throw new Error("no sim connected")}function B(e,o,t){console.log(` ${t==="current sim"?"loaded":"opened"}: ${e} [${t}]`),console.log(` current sim: ${o.id}`),console.log(JSON.stringify({simId:o.id,url:o.url},null,2))}async function D(e,o,t){if(t.includes("--no-describe"))return;let n=process.env.SOOTSIM_QUIET_TARGET_NOTICE;process.env.SOOTSIM_QUIET_TARGET_NOTICE="1";try{await Xt(e,o,{stableMs:150,maxMs:400});let r=v(e,{commandTimeoutMs:3e3,simId:o,cliLabel:"open --describe",simIdSource:"flag"});try{let s=null;try{s=await r.send({type:"evaluate",code:Re})}catch{}if(s&&!(s.flag===!0&&!s.loadingText&&Oe(s))){let m=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: ${m} (nodes: ${s.nodes}, targets: ${s.targets})`),console.log(" before interacting, run: sootsim wait ready --max-ms 120000")}let a=`(async () => {
7
+ ${o.slice(-4e3)}`:o;console.error(` ${T.basename(e.diagnosticLogPath)}:`),console.error(t)}catch(o){let t=o instanceof Error?o.message:String(o);console.error(` failed to read ${T.basename(e.diagnosticLogPath)}: ${t}`)}}function pe(e){try{return process.kill(e,0),!0}catch(o){return o?.code==="EPERM"}}async function Yt(e,o=2500){let t=Date.now()+o;for(;Date.now()<t;){if(!pe(e))return!0;await $(100)}return!pe(e)}function Zt(e){let o=ze("ps",["-o","command=","-p",String(e)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),t=ze("ps",["eww","-o","command=","-p",String(e)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]});if(o.status!==0||t.status!==0)return!1;let n=(o.stdout||"").trimEnd(),r=(t.stdout||"").trimEnd();return(r.startsWith(n)?r.slice(n.length):r).includes("SOOTSIM_PW_URL=")}async function me(e,o){let t=new Set(o),n=new Set;for(let r of e){if(!t.has(r.id))continue;let s=Jt(r);s&&n.add(s)}for(let r of n){if(!Zt(r)){console.log(` skipped pid ${r}: not a sootsim playwright host (stale sim record)`);continue}try{process.kill(r,"SIGTERM")}catch{}if(await Yt(r)){console.log(` closed playwright host process ${r}`);continue}try{process.kill(r,"SIGKILL"),console.log(` force-closed playwright host process ${r}`)}catch{}}}function J(e,o){if(o){let r=o.trim(),s=e.find(i=>i.id===r);if(!s)throw new Error(`no sim connected with id ${r}`);return s}let t=e.find(r=>r.isPrimary&&r.readyState==="open");if(t)return t;let n=e.find(r=>r.readyState==="open");if(n)return n;throw new Error("no sim connected")}function B(e,o,t){console.log(` ${t==="current sim"?"loaded":"opened"}: ${e} [${t}]`),console.log(` current sim: ${o.id}`),console.log(JSON.stringify({simId:o.id,url:o.url},null,2))}async function D(e,o,t){if(t.includes("--no-describe"))return;let n=process.env.SOOTSIM_QUIET_TARGET_NOTICE;process.env.SOOTSIM_QUIET_TARGET_NOTICE="1";try{await Xt(e,o,{stableMs:150,maxMs:400});let r=v(e,{commandTimeoutMs:3e3,simId:o,cliLabel:"open --describe",simIdSource:"flag"});try{let s=null;try{s=await r.send({type:"evaluate",code:Ue})}catch{}if(s&&!(s.flag===!0&&!s.loadingText&&Oe(s))){let m=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: ${m} (nodes: ${s.nodes}, targets: ${s.targets})`),console.log(" before interacting, run: sootsim wait ready --max-ms 120000")}let a=`(async () => {
6
8
  const t = window.__sootsimTest
7
9
  const ms = window.SootSim?.bridges?.mainShell
8
10
  if (!t) return null
@@ -10,4 +12,4 @@ ${o.slice(-4e3)}`:o;console.error(` ${T.basename(e.diagnosticLogPath)}:`),conso
10
12
  try { shell = ms?.getState ? await ms.getState() : null } catch {}
11
13
  const tree = await t.dumpTree(12, ${JSON.stringify({describe:!0,verbose:!1,filter:""})})
12
14
  return { tree, shell }
13
- })()`,l=await r.send({type:"evaluate",code:a});if(!l?.tree)return;if(console.log(""),l.shell?.state){let d=[`state=${l.shell.state}`,l.shell.activeApp?`app=${l.shell.activeApp}`:null].filter(Boolean);console.log(` shell: ${d.join(" ")}`)}console.log(l.tree)}finally{r.close()}}catch{}finally{n===void 0?delete process.env.SOOTSIM_QUIET_TARGET_NOTICE:process.env.SOOTSIM_QUIET_TARGET_NOTICE=n}}async function Xt(e,o,t){let n=Date.now()+t.maxMs,r="(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()",s=v(e,{commandTimeoutMs:2e3,simId:o,simIdSource:"flag"});try{let i=-1,a=0;for(;Date.now()<n;){let l=-1;try{let d=await s.send({type:"evaluate",code:r});typeof d=="number"&&(l=d)}catch{}if(l>=0&&l===i){if(Date.now()-a>=t.stableMs)return}else i=l,a=Date.now();await $(50)}}finally{s.close()}}async function eo(e,o={}){let t=E(e,{port:o.port,commandTimeoutMs:o.timeoutMs});t.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 n;try{n=$t(t.positional[0]??"")}catch(i){console.error(` sootsim open: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}let r=M(t),s=t.simId?` --sim ${t.simId}`:"";try{let i=await r.send({type:"call",path:"SootSim.bridges.test.openDeepLink",args:[n]});if(xt(i)&&i.ok===!1)throw new Error(typeof i.error=="string"?i.error:"deep-link dispatch failed");console.log(` opened deep link: ${n}`)}catch(i){console.error(` link failed: ${i instanceof Error?i.message:String(i)}`),await R(r,{errorsCommand:`sootsim get errors 5${s}`,warningsCommand:`sootsim get warnings 5${s}`,requestsCommand:`sootsim get requests 5${s}`}),process.exit(1)}finally{r.close()}}async function Ao(e,o={}){let t=E(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--new","--headless","--headed","--ephemeral","--hot","--no-hmr","--no-describe"],stripValueFlags:["--base-url","--replace","--driver","--profile","--cdp-port","--browser","--device"]}),n=e.find((c,p)=>e[p-1]==="--profile"),r=e.includes("--ephemeral"),s=e.find((c,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)),n&&r&&(console.error(" sootsim open: --profile cannot be combined with --ephemeral"),process.exit(1));let a=n?Ce(n).id:void 0,l=!!a||r,d=e.includes("--new")||l,m=Dt(e);d&&t.simIdSource==="flag"&&(console.error(" sootsim open: --new, --profile, and --ephemeral cannot be combined with --sim"),process.exit(1));let u=t.positional[0]||"";if(kt(u)){d&&(console.error(" sootsim open: deep links target the current app; remove --new, --profile, or --ephemeral"),process.exit(1)),await eo(e,o);return}if(Tt(u)){let c=(()=>{try{return I(new URL(u).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 le(u,{background:!1})}catch(p){console.error(` could not launch a browser: ${p instanceof Error?p.message:String(p)}`),console.error(` open it yourself: ${u}`),process.exit(1)}console.log(c?" 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 g=e.find((c,p)=>e[p-1]==="--base-url"),Q=o.port!==void 0||e.some(c=>c==="--port"||c==="-p"||c.startsWith("--port="));if(g&&!Q){let c=ie(g);c&&(t.wsPort=c)}t.wsPort=await Pt(t.wsPort);let y=e.find((c,p)=>e[p-1]==="--driver")||"",nt=St(e,y);i&&y!=="playwright"&&(console.error(" sootsim open: --cdp-port is only honored by the playwright driver \u2014 add `--driver playwright`"),process.exit(1));let x=e.find((c,p)=>e[p-1]==="--browser");x&&y!=="playwright"&&(console.error(" sootsim open: --browser is only honored by the playwright driver \u2014 add `--driver playwright`"),process.exit(1));let A=x==="chromium"||x==="webkit"||x==="firefox"?x:void 0;x&&!A&&(console.error(` sootsim open: --browser must be chromium, webkit, or firefox \u2014 got "${x}"`),process.exit(1)),i&&A&&A!=="chromium"&&(console.error(" sootsim open: --cdp-port requires the chromium engine"),process.exit(1));let fe=e.includes("--hot"),he=e.includes("--no-hmr");fe&&he&&(console.error(" sootsim open: --hot and --no-hmr cannot be combined"),process.exit(1));let rt=fe?!0:he?!1:y!=="playwright",k=e.find((c,p)=>e[p-1]==="--device");k&&!(k in oe)&&(console.error(` sootsim open: unknown device "${k}"`),console.error(` known devices: ${xe().join(", ")}`),process.exit(1));let Y=k?oe[k]:void 0,N={hot:rt,device:k},st=De(t.wsPort),P=g||st?.shellBaseUrl||tt(),ge=e.includes("--base-url");Le(t.wsPort,P);let we=_();if(!y&&!d&&(t.simIdSource==="flag"||t.simIdSource==="saved"&&!!we)){let c=M(t),p=t.simId?` --sim ${t.simId}`:"",f=!1;try{let h=null;try{let w=await c.listSims();if(t.simIdSource==="saved"?(h=w.find(C=>C.id===we&&C.readyState==="open")??null,h||U()):h=J(w,t.simId),!h)if(t.simIdSource==="saved")f=!0;else throw new Error("no sim connected");if(!f&&h){let C=ge||ue(u)?P:Qe(h,P),W=await z(u,K(C,m),N);c.send({type:"evaluate",simId:h.id,code:`window.location.href = ${JSON.stringify(W)}`}).catch(()=>{})}}catch(w){console.error(` open failed: ${w instanceof Error?w.message:String(w)}`),await R(c,{errorsCommand:`sootsim get errors 5${p}`,warningsCommand:`sootsim get warnings 5${p}`,requestsCommand:`sootsim get requests 5${p}`}),process.exit(1)}if(!f&&h){await $(1500);let w=await jt(t.wsPort,t.commandTimeoutMs,h.id);w||(console.error(" timed out waiting for current sim to load target"),process.exit(1)),w.bridge.close(),b(h.id);let C=ge||ue(u)?P:Qe(h,P),W=await z(u,K(C,m),N);B(W,{...h,url:W},"current sim"),await D(t.wsPort,h.id,e);return}}finally{c.close()}}let be=K(P,m),it=await z(u,be,N),ye=`cli-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,S=await Wt(u,be,ye,N),ve=ke()??void 0,Z={newWindow:!0},F=c=>c.url?.includes(`inspectOpen=${ye}`)??!1;if(y){vt(y)||(console.error(` unknown driver "${y}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let c=ce(y);c||(console.error(` unknown driver "${y}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let p=yt(),f=await c.launch({url:S,bridgePort:ie(P)??t.wsPort,headless:nt,newWindow:Z.newWindow,profileId:a,ephemeralProfile:r,cdpPort:i,browser:A,device:k,ownerPid:ve,viewport:Y?{width:Y.width+120,height:Y.height+60}:void 0,connectTimeoutMs:p.hostTimeoutMs});f.launched||(console.error(` ${c.name} driver: ${f.message}`),process.exit(1));let h=await Vt(t.wsPort,t.commandTimeoutMs,F,f.pid,{attempts:p.attempts,intervalMs:p.intervalMs});if(h.kind==="host-exit"&&(Ze(f),console.error(` ${c.name} host crashed \u2014 sim is no longer attached`),process.exit(1)),h.kind==="timeout"){if(f.pid)try{process.kill(f.pid,"SIGTERM"),console.error(` closed ${c.name} host process ${f.pid}`)}catch{}Ze(f),console.error(` timed out after ${p.timeoutMs}ms waiting for opened sim to connect`),process.exit(1)}let w=h.sim;b(w.id),Qt(f),B(S,w,`${c.name} driver`),await D(t.wsPort,w.id,e);return}if(l){let c=O();c||(console.error(" profiles require electron or playwright; install the desktop companion or use `--driver playwright`"),process.exit(1));try{(await ae(S,c,{profileId:a,ephemeralProfile:r,ownerPid:ve})).launched||(console.error(" desktop companion failed to start"),process.exit(1))}catch(f){console.error(` desktop companion failed: ${f instanceof Error?f.message:String(f)}`),process.exit(1)}let p=await de(t.wsPort,t.commandTimeoutMs,F,{attempts:40,intervalMs:500});p||(console.error(" timed out waiting for profiled sim to connect"),process.exit(1)),b(p.id),B(S,p,"desktop companion"),await D(t.wsPort,p.id,e);return}let X=!1,ee=!1;try{let c=v(t.wsPort,{commandTimeoutMs:2e3});try{await c.listSims(),X=!0}finally{c.close()}}catch{}if(X)try{let c=v(t.wsPort,{commandTimeoutMs:3e3});try{await c.openUrl(S,Z),ee=!0}finally{c.close()}}catch{}if(!ee){let c=O();if(c)try{if((await ae(S,c)).launched){let f=await de(t.wsPort,t.commandTimeoutMs,F,{attempts:20,intervalMs:500});if(f){b(f.id),B(S,f,"desktop companion"),await D(t.wsPort,f.id,e);return}}}catch{}try{await le(S,Z)}catch(p){console.error(` open failed: ${p instanceof Error?p.message:String(p)}`),ce("playwright")?.availability().available?console.error(" no system browser found \u2014 retry with `sootsim open \u2026 --driver playwright` for a headless sim."):console.error(" run `sootsim list --drivers` to see available drivers."),process.exit(1)}if(!X){console.log(` opened: ${it}`),Ke(t.wsPort);return}}let H=await de(t.wsPort,t.commandTimeoutMs,F,{attempts:30,intervalMs:500});H||(console.error(" timed out waiting for opened sim to connect"),process.exit(1)),b(H.id),B(S,H,ee?"bridge":"direct shell open"),await D(t.wsPort,H.id,e)}async function ot(e,o={}){let t=E(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--force"]}),n=e.includes("--force"),r=M(t),s=t.simId?` --sim ${t.simId}`:"";try{try{let i=await r.listSims(),a=J(i,t.positional[0]||t.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)),n||(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 r.focusSim(a.id),b(a.id),console.log(` using: ${a.id}`)}catch(i){console.error(` use failed: ${i instanceof Error?i.message:String(i)}`),await R(r,{errorsCommand:`sootsim get errors 5${s}`,warningsCommand:`sootsim get warnings 5${s}`,requestsCommand:`sootsim get requests 5${s}`}),process.exit(1)}}finally{r.close()}}async function No(e,o={}){await ot(e,o)}async function Fo(e,o={}){await ot(e,o)}async function Ho(e,o={}){let t=E(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--force"]}),n=e.includes("--force"),r=M(t);try{try{let s=await r.listSims(),i=J(s,t.positional[0]||t.simId),a=n&&i.lockedBy&&i.lockedByKind!=="user-active"?i.lockedBy:null,l=await r.claim(i.id,{force:n});b(i.id);let d=Math.max(0,Math.round((l.lockExpiresAt-Date.now())/1e3)),m=l.bootedCount>0?` (booted ${l.bootedCount})`:"";console.log(` claimed: ${l.simId} [${d}s]${m}`),a&&console.log(` took over from: ${a}`)}catch(s){if(s instanceof Ae){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{r.close()}}async function to(e,o,t,n){if(n.length===0)return{closed:[],remaining:[]};await Promise.all(n.map(s=>e.closeSim(s).catch(()=>{})));let r=new Set(n);for(let s=0;s<40;s++){let i=[];try{let a=v(o,{commandTimeoutMs:t});try{i=(await a.listSims()).filter(d=>r.has(d.id)&&d.readyState==="open").map(d=>d.id)}finally{a.close()}}catch{i=[]}if(i.length===0)return{closed:[...r],remaining:[]};if(s===39)return{closed:[...r].filter(a=>!i.includes(a)),remaining:i};await $(250)}return{closed:[...r],remaining:[]}}function oo(e,o){let t=e.filter(u=>u.readyState==="open"),n=t.map(u=>u.id),r=o.explicitKeepId?.trim()||"",s=o.savedKeepId?.trim()||"",i=s?t.some(u=>u.id===s):!1,a=s&&!i?s:null,l=null,d=null,m=null;if(o.closeOthers)if(r){let u=t.find(g=>g.id===r);u?l=u.id:d=r}else if(s&&i)l=s;else{let u=t.find(g=>g.isPrimary)??t[0]??null;u&&(l=u.id,s&&!i&&(m=u.id))}return{openIds:n,keepId:l,targets:d?[]:n.filter(u=>u!==l),staleSavedId:a,missingExplicitKeepId:d,fallbackKeepId:m}}async function Wo(e,o={}){let t=E(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--all","--others"]}),n=M(t),r=t.simId?` --sim ${t.simId}`:"",s=e.includes("--all"),i=e.includes("--others");if(s||i){try{let a=await n.listSims(),l=_(),d=t.positional[0]||(t.simIdSource==="flag"?t.simId:void 0),m=oo(a,{closeOthers:i,explicitKeepId:d,savedKeepId:l});if(m.staleSavedId&&U(),m.fallbackKeepId&&(b(m.fallbackKeepId),console.log(` saved sim ${m.staleSavedId} is gone \u2014 keeping primary ${m.fallbackKeepId}`)),m.missingExplicitKeepId&&(console.error(` close failed: keep sim ${m.missingExplicitKeepId} is not connected; not closing other sims`),process.exit(1)),m.targets.length===0){console.log(m.keepId?` nothing to close \u2014 only the kept sim ${m.keepId} is connected`:m.staleSavedId?` nothing to close \u2014 no sims connected (cleared stale current sim ${m.staleSavedId})`:" nothing to close \u2014 no sims connected");return}let u=await to(n,t.wsPort,t.commandTimeoutMs,m.targets);await me(a,m.targets);let g=_();g&&u.closed.includes(g)&&(m.keepId?b(m.keepId):U());let Q=` closed ${u.closed.length} sim(s)${m.keepId?` (kept ${m.keepId})`:""}`;console.log(Q),u.remaining.length>0&&(console.error(` close failed: still connected: ${u.remaining.join(", ")}`),process.exit(1))}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),process.exit(1)}finally{n.close()}return}try{try{let a=await n.listSims(),l=J(a,t.positional[0]||t.simId),d=a.find(u=>u.id!==l.id&&u.readyState==="open");await n.closeSim(l.id),await Gt(t.wsPort,t.commandTimeoutMs,l.id)||(await me(a,[l.id]),console.error(` close failed: ${l.id} is still connected`),process.exit(1)),await me(a,[l.id]),_()===l.id&&(d?b(d.id):U()),console.log(` closed: ${l.id}`)}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),await R(n,{errorsCommand:`sootsim get errors 5${r}`,warningsCommand:`sootsim get warnings 5${r}`,requestsCommand:`sootsim get requests 5${r}`}),process.exit(1)}}finally{n.close()}}export{lo as a,pt as b,co as c,yt as d,$t as e,Do as f,tt as g,z as h,Wt as i,Kt as j,Lo as k,de as l,Vt as m,Jt as n,Qt as o,me as p,eo as q,Ao as r,No as s,Fo as t,Ho as u,to as v,oo as w,Wo as x};
15
+ })()`,l=await r.send({type:"evaluate",code:a});if(!l?.tree)return;if(console.log(""),l.shell?.state){let d=[`state=${l.shell.state}`,l.shell.activeApp?`app=${l.shell.activeApp}`:null].filter(Boolean);console.log(` shell: ${d.join(" ")}`)}console.log(l.tree)}finally{r.close()}}catch{}finally{n===void 0?delete process.env.SOOTSIM_QUIET_TARGET_NOTICE:process.env.SOOTSIM_QUIET_TARGET_NOTICE=n}}async function Xt(e,o,t){let n=Date.now()+t.maxMs,r="(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()",s=v(e,{commandTimeoutMs:2e3,simId:o,simIdSource:"flag"});try{let i=-1,a=0;for(;Date.now()<n;){let l=-1;try{let d=await s.send({type:"evaluate",code:r});typeof d=="number"&&(l=d)}catch{}if(l>=0&&l===i){if(Date.now()-a>=t.stableMs)return}else i=l,a=Date.now();await $(50)}}finally{s.close()}}async function eo(e,o={}){let t=M(e,{port:o.port,commandTimeoutMs:o.timeoutMs});t.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 n;try{n=$t(t.positional[0]??"")}catch(i){console.error(` sootsim open: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}let r=E(t),s=t.simId?` --sim ${t.simId}`:"";try{let i=await r.send({type:"call",path:"SootSim.bridges.test.openDeepLink",args:[n]});if(xt(i)&&i.ok===!1)throw new Error(typeof i.error=="string"?i.error:"deep-link dispatch failed");console.log(` opened deep link: ${n}`)}catch(i){console.error(` link failed: ${i instanceof Error?i.message:String(i)}`),await U(r,{errorsCommand:`sootsim get errors 5${s}`,warningsCommand:`sootsim get warnings 5${s}`,requestsCommand:`sootsim get requests 5${s}`}),process.exit(1)}finally{r.close()}}async function Ao(e,o={}){let t=M(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--new","--headless","--headed","--ephemeral","--hot","--no-hmr","--no-describe"],stripValueFlags:["--base-url","--replace","--driver","--profile","--cdp-port","--browser","--device"]}),n=e.find((c,p)=>e[p-1]==="--profile"),r=e.includes("--ephemeral"),s=e.find((c,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)),n&&r&&(console.error(" sootsim open: --profile cannot be combined with --ephemeral"),process.exit(1));let a=n?Ce(n).id:void 0,l=!!a||r,d=e.includes("--new")||l,m=Dt(e);d&&t.simIdSource==="flag"&&(console.error(" sootsim open: --new, --profile, and --ephemeral cannot be combined with --sim"),process.exit(1));let u=t.positional[0]||"";if(kt(u)){d&&(console.error(" sootsim open: deep links target the current app; remove --new, --profile, or --ephemeral"),process.exit(1)),await eo(e,o);return}if(Tt(u)){let c=(()=>{try{return I(new URL(u).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 le(u,{background:!1})}catch(p){console.error(` could not launch a browser: ${p instanceof Error?p.message:String(p)}`),console.error(` open it yourself: ${u}`),process.exit(1)}console.log(c?" 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 g=e.find((c,p)=>e[p-1]==="--base-url"),Q=o.port!==void 0||e.some(c=>c==="--port"||c==="-p"||c.startsWith("--port="));if(g&&!Q){let c=ie(g);c&&(t.wsPort=c)}t.wsPort=await Pt(t.wsPort);let y=e.find((c,p)=>e[p-1]==="--driver")||"",nt=St(e,y);i&&y!=="playwright"&&(console.error(" sootsim open: --cdp-port is only honored by the playwright driver \u2014 add `--driver playwright`"),process.exit(1));let x=e.find((c,p)=>e[p-1]==="--browser");x&&y!=="playwright"&&(console.error(" sootsim open: --browser is only honored by the playwright driver \u2014 add `--driver playwright`"),process.exit(1));let A=x==="chromium"||x==="webkit"||x==="firefox"?x:void 0;x&&!A&&(console.error(` sootsim open: --browser must be chromium, webkit, or firefox \u2014 got "${x}"`),process.exit(1)),i&&A&&A!=="chromium"&&(console.error(" sootsim open: --cdp-port requires the chromium engine"),process.exit(1));let fe=e.includes("--hot"),he=e.includes("--no-hmr");fe&&he&&(console.error(" sootsim open: --hot and --no-hmr cannot be combined"),process.exit(1));let rt=fe?!0:he?!1:y!=="playwright",k=e.find((c,p)=>e[p-1]==="--device");k&&!(k in oe)&&(console.error(` sootsim open: unknown device "${k}"`),console.error(` known devices: ${xe().join(", ")}`),process.exit(1));let Y=k?oe[k]:void 0,N={hot:rt,device:k},st=De(t.wsPort),P=g||st?.shellBaseUrl||tt(),ge=e.includes("--base-url");Le(t.wsPort,P);let we=_();if(!y&&!d&&(t.simIdSource==="flag"||t.simIdSource==="saved"&&!!we)){let c=E(t),p=t.simId?` --sim ${t.simId}`:"",f=!1;try{let h=null;try{let w=await c.listSims();if(t.simIdSource==="saved"?(h=w.find(C=>C.id===we&&C.readyState==="open")??null,h||R()):h=J(w,t.simId),!h)if(t.simIdSource==="saved")f=!0;else throw new Error("no sim connected");if(!f&&h){let C=ge||ue(u)?P:Qe(h,P),W=await z(u,K(C,m),N);c.send({type:"evaluate",simId:h.id,code:`window.location.href = ${JSON.stringify(W)}`}).catch(()=>{})}}catch(w){console.error(` open failed: ${w instanceof Error?w.message:String(w)}`),await U(c,{errorsCommand:`sootsim get errors 5${p}`,warningsCommand:`sootsim get warnings 5${p}`,requestsCommand:`sootsim get requests 5${p}`}),process.exit(1)}if(!f&&h){await $(1500);let w=await jt(t.wsPort,t.commandTimeoutMs,h.id);w||(console.error(" timed out waiting for current sim to load target"),process.exit(1)),w.bridge.close(),b(h.id);let C=ge||ue(u)?P:Qe(h,P),W=await z(u,K(C,m),N);B(W,{...h,url:W},"current sim"),await D(t.wsPort,h.id,e);return}}finally{c.close()}}let be=K(P,m),it=await z(u,be,N),ye=`cli-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,S=await Wt(u,be,ye,N),ve=ke()??void 0,Z={newWindow:!0},F=c=>c.url?.includes(`inspectOpen=${ye}`)??!1;if(y){vt(y)||(console.error(` unknown driver "${y}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let c=ce(y);c||(console.error(` unknown driver "${y}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let p=yt(),f=await c.launch({url:S,bridgePort:ie(P)??t.wsPort,headless:nt,newWindow:Z.newWindow,profileId:a,ephemeralProfile:r,cdpPort:i,browser:A,device:k,ownerPid:ve,viewport:Y?{width:Y.width+120,height:Y.height+60}:void 0,connectTimeoutMs:p.hostTimeoutMs});f.launched||(console.error(` ${c.name} driver: ${f.message}`),process.exit(1));let h=await Vt(t.wsPort,t.commandTimeoutMs,F,f.pid,{attempts:p.attempts,intervalMs:p.intervalMs});if(h.kind==="host-exit"&&(Ze(f),console.error(` ${c.name} host crashed \u2014 sim is no longer attached`),process.exit(1)),h.kind==="timeout"){if(f.pid)try{process.kill(f.pid,"SIGTERM"),console.error(` closed ${c.name} host process ${f.pid}`)}catch{}Ze(f),console.error(` timed out after ${p.timeoutMs}ms waiting for opened sim to connect`),process.exit(1)}let w=h.sim;b(w.id),Qt(f),B(S,w,`${c.name} driver`),await D(t.wsPort,w.id,e);return}if(l){let c=O();c||(console.error(" profiles require electron or playwright; install the desktop companion or use `--driver playwright`"),process.exit(1));try{(await ae(S,c,{profileId:a,ephemeralProfile:r,ownerPid:ve})).launched||(console.error(" desktop companion failed to start"),process.exit(1))}catch(f){console.error(` desktop companion failed: ${f instanceof Error?f.message:String(f)}`),process.exit(1)}let p=await de(t.wsPort,t.commandTimeoutMs,F,{attempts:40,intervalMs:500});p||(console.error(" timed out waiting for profiled sim to connect"),process.exit(1)),b(p.id),B(S,p,"desktop companion"),await D(t.wsPort,p.id,e);return}let X=!1,ee=!1;try{let c=v(t.wsPort,{commandTimeoutMs:2e3});try{await c.listSims(),X=!0}finally{c.close()}}catch{}if(X)try{let c=v(t.wsPort,{commandTimeoutMs:3e3});try{await c.openUrl(S,Z),ee=!0}finally{c.close()}}catch{}if(!ee){let c=O();if(c)try{if((await ae(S,c)).launched){let f=await de(t.wsPort,t.commandTimeoutMs,F,{attempts:20,intervalMs:500});if(f){b(f.id),B(S,f,"desktop companion"),await D(t.wsPort,f.id,e);return}}}catch{}try{await le(S,Z)}catch(p){console.error(` open failed: ${p instanceof Error?p.message:String(p)}`),ce("playwright")?.availability().available?console.error(" no system browser found \u2014 retry with `sootsim open \u2026 --driver playwright` for a headless sim."):console.error(" run `sootsim list --drivers` to see available drivers."),process.exit(1)}if(!X){console.log(` opened: ${it}`),Ke(t.wsPort);return}}let H=await de(t.wsPort,t.commandTimeoutMs,F,{attempts:30,intervalMs:500});H||(console.error(" timed out waiting for opened sim to connect"),process.exit(1)),b(H.id),B(S,H,ee?"bridge":"direct shell open"),await D(t.wsPort,H.id,e)}async function ot(e,o={}){let t=M(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--force"]}),n=e.includes("--force"),r=E(t),s=t.simId?` --sim ${t.simId}`:"";try{try{let i=await r.listSims(),a=J(i,t.positional[0]||t.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)),n||(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 r.focusSim(a.id),b(a.id),console.log(` using: ${a.id}`)}catch(i){console.error(` use failed: ${i instanceof Error?i.message:String(i)}`),await U(r,{errorsCommand:`sootsim get errors 5${s}`,warningsCommand:`sootsim get warnings 5${s}`,requestsCommand:`sootsim get requests 5${s}`}),process.exit(1)}}finally{r.close()}}async function No(e,o={}){await ot(e,o)}async function Fo(e,o={}){await ot(e,o)}async function Ho(e,o={}){let t=M(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--force"]}),n=e.includes("--force"),r=E(t);try{try{let s=await r.listSims(),i=J(s,t.positional[0]||t.simId),a=n&&i.lockedBy&&i.lockedByKind!=="user-active"?i.lockedBy:null,l=await r.claim(i.id,{force:n});b(i.id);let d=Math.max(0,Math.round((l.lockExpiresAt-Date.now())/1e3)),m=l.bootedCount>0?` (booted ${l.bootedCount})`:"";console.log(` claimed: ${l.simId} [${d}s]${m}`),a&&console.log(` took over from: ${a}`)}catch(s){if(s instanceof Ae){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{r.close()}}async function to(e,o,t,n){if(n.length===0)return{closed:[],remaining:[]};await Promise.all(n.map(s=>e.closeSim(s).catch(()=>{})));let r=new Set(n);for(let s=0;s<40;s++){let i=[];try{let a=v(o,{commandTimeoutMs:t});try{i=(await a.listSims()).filter(d=>r.has(d.id)&&d.readyState==="open").map(d=>d.id)}finally{a.close()}}catch{i=[]}if(i.length===0)return{closed:[...r],remaining:[]};if(s===39)return{closed:[...r].filter(a=>!i.includes(a)),remaining:i};await $(250)}return{closed:[...r],remaining:[]}}function oo(e,o){let t=e.filter(u=>u.readyState==="open"),n=t.map(u=>u.id),r=o.explicitKeepId?.trim()||"",s=o.savedKeepId?.trim()||"",i=s?t.some(u=>u.id===s):!1,a=s&&!i?s:null,l=null,d=null,m=null;if(o.closeOthers)if(r){let u=t.find(g=>g.id===r);u?l=u.id:d=r}else if(s&&i)l=s;else{let u=t.find(g=>g.isPrimary)??t[0]??null;u&&(l=u.id,s&&!i&&(m=u.id))}return{openIds:n,keepId:l,targets:d?[]:n.filter(u=>u!==l),staleSavedId:a,missingExplicitKeepId:d,fallbackKeepId:m}}async function Wo(e,o={}){let t=M(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--all","--others"]}),n=E(t),r=t.simId?` --sim ${t.simId}`:"",s=e.includes("--all"),i=e.includes("--others");if(s||i){try{let a=await n.listSims(),l=_(),d=t.positional[0]||(t.simIdSource==="flag"?t.simId:void 0),m=oo(a,{closeOthers:i,explicitKeepId:d,savedKeepId:l});if(m.staleSavedId&&R(),m.fallbackKeepId&&(b(m.fallbackKeepId),console.log(` saved sim ${m.staleSavedId} is gone \u2014 keeping primary ${m.fallbackKeepId}`)),m.missingExplicitKeepId&&(console.error(` close failed: keep sim ${m.missingExplicitKeepId} is not connected; not closing other sims`),process.exit(1)),m.targets.length===0){console.log(m.keepId?` nothing to close \u2014 only the kept sim ${m.keepId} is connected`:m.staleSavedId?` nothing to close \u2014 no sims connected (cleared stale current sim ${m.staleSavedId})`:" nothing to close \u2014 no sims connected");return}let u=await to(n,t.wsPort,t.commandTimeoutMs,m.targets);await me(a,m.targets);let g=_();g&&u.closed.includes(g)&&(m.keepId?b(m.keepId):R());let Q=` closed ${u.closed.length} sim(s)${m.keepId?` (kept ${m.keepId})`:""}`;console.log(Q),u.remaining.length>0&&(console.error(` close failed: still connected: ${u.remaining.join(", ")}`),process.exit(1))}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),process.exit(1)}finally{n.close()}return}try{try{let a=await n.listSims(),l=J(a,t.positional[0]||t.simId),d=a.find(u=>u.id!==l.id&&u.readyState==="open");await n.closeSim(l.id),await Gt(t.wsPort,t.commandTimeoutMs,l.id)||(await me(a,[l.id]),console.error(` close failed: ${l.id} is still connected`),process.exit(1)),await me(a,[l.id]),_()===l.id&&(d?b(d.id):R()),console.log(` closed: ${l.id}`)}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),await U(n,{errorsCommand:`sootsim get errors 5${r}`,warningsCommand:`sootsim get warnings 5${r}`,requestsCommand:`sootsim get requests 5${r}`}),process.exit(1)}}finally{n.close()}}export{lo as a,pt as b,co as c,yt as d,$t as e,Do as f,tt as g,z as h,Wt as i,Kt as j,Lo as k,de as l,Vt as m,Jt as n,Qt as o,me as p,eo as q,Ao as r,No as s,Fo as t,Ho as u,to as v,oo as w,Wo as x};
@@ -1,5 +1,7 @@
1
- /*! sootsim v0.1.293 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- function G(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r){let o=t.indexOf(n);if(o>=0&&t[o+1]){let s=Number(t[o+1]);if(Number.isFinite(s))return Math.max(100,s)}}return e}var N=new Set(["tap","double-tap","tap-text","tap-id","long-press","touch"]);function P(t){return typeof t=="string"&&N.has(t)}async function M(t){return await t.send({type:"evaluate",code:"window.__sootsimEngineState?.inspectActive === true"})===!0}async function Q(t,e){if(!P(e))return!1;try{return await M(t)}catch{return!1}}async function X(t){let e=await t.send({type:"evaluate",code:"(async () => await window.__sootsimTest.getNodeCount())()"});return{nodes:typeof e=="number"?e:0}}async function Z(t,e=5,r){let n=r?.format?`, ${JSON.stringify(r)}`:"",o=await t.send({type:"evaluate",code:`(async () => await window.__sootsimTest.dumpTree(${e}${n}))()`});if(r?.format==="boxes"&&typeof o=="string")try{return{depth:e,tree:JSON.parse(o)}}catch{return{depth:e,tree:o}}return{depth:e,tree:o}}async function ee(t){let e=await t.send({type:"evaluate",code:"window.location.href"});return{url:typeof e=="string"?e:""}}async function te(t,e){let r=`(async () => {
1
+ /*! sootsim v0.1.294 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
4
+ function Q(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r){let o=t.indexOf(n);if(o>=0&&t[o+1]){let s=Number(t[o+1]);if(Number.isFinite(s))return Math.max(100,s)}}return e}var N=new Set(["tap","double-tap","tap-text","tap-id","long-press","touch"]);function P(t){return typeof t=="string"&&N.has(t)}async function M(t){return await t.send({type:"evaluate",code:"window.__sootsimEngineState?.inspectActive === true"})===!0}async function X(t,e){if(!P(e))return!1;try{return await M(t)}catch{return!1}}async function Z(t){let e=await t.send({type:"evaluate",code:"(async () => await window.__sootsimTest.getNodeCount())()"});return{nodes:typeof e=="number"?e:0}}async function ee(t,e=5,r){let n=r?.format?`, ${JSON.stringify(r)}`:"",o=await t.send({type:"evaluate",code:`(async () => await window.__sootsimTest.dumpTree(${e}${n}))()`});if(r?.format==="boxes"&&typeof o=="string")try{return{depth:e,tree:JSON.parse(o)}}catch{return{depth:e,tree:o}}return{depth:e,tree:o}}async function te(t){let e=await t.send({type:"evaluate",code:"window.location.href"});return{url:typeof e=="string"?e:""}}async function ne(t,e){let r=`(async () => {
3
5
  const t = window.__sootsimTest
4
6
  const mainShell = window.SootSim?.bridges?.mainShell
5
7
  const kb = window.__sootsimKeyboard
@@ -76,13 +78,13 @@ function G(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r
76
78
  const nodeCount = (await t.getNodeCount?.()) || 0
77
79
  const keyboard = kb && typeof kb.getLayout === 'function' ? kb.getLayout() : null
78
80
  return { tree, shell, nodeCount, keyboard }
79
- })()`;return await t.send({type:"evaluate",code:r})??{}}function C(t){let e=t.fontSize>=18||t.fontSize>=14&&(t.fontWeight??400)>=700?3:4.5,{normal:r,background:n}=t;if(r.width<=0||r.height<=0||r.width!==n.width||r.height!==n.height)return{ratio:null,required:e,reason:"capture dimensions do not match"};let o=Math.max(0,Math.floor(t.box.x)),s=Math.max(0,Math.floor(t.box.y)),i=Math.min(r.width,Math.ceil(t.box.x+t.box.w)),d=Math.min(r.height,Math.ceil(t.box.y+t.box.h));if(i<=o||d<=s)return{ratio:null,required:e,reason:"text is outside the captured frame"};let p=l=>{let u=l/255;return u<=.04045?u/12.92:Math.pow((u+.055)/1.055,2.4)},m=(l,u)=>{let c=.2126*p(l[0])+.7152*p(l[1])+.0722*p(l[2]),S=.2126*p(u[0])+.7152*p(u[1])+.0722*p(u[2]);return(Math.max(c,S)+.05)/(Math.min(c,S)+.05)},a=l=>`#${l.slice(0,3).map(u=>Math.round(u).toString(16).padStart(2,"0")).join("")}`,g=(i-o)*(d-s),b=Math.max(1,Math.floor(Math.sqrt(g/12e3))),f=(l,u)=>(u*r.width+l)*4,h=l=>Math.max(Math.abs(r.data[l]-n.data[l]),Math.abs(r.data[l+1]-n.data[l+1]),Math.abs(r.data[l+2]-n.data[l+2])),y=0,v=null,w=null;for(let l=s;l<d;l+=b)for(let u=o;u<i;u+=b){let c=f(u,l);if(n.data[c+3]<250)continue;let S=[n.data[c],n.data[c+1],n.data[c+2]];w??=S;let E=h(c);E<=y||(y=E,v=[r.data[c],r.data[c+1],r.data[c+2]])}let x=1/0,I=null,T=null,k=(l,u)=>{let c=m(l,u);c>=x||(x=c,I=l,T=u)};if(y>=2&&v)for(let l=s;l<d;l+=b)for(let u=o;u<i;u+=b){let c=f(u,l);n.data[c+3]<250||h(c)<2||k(v,[n.data[c],n.data[c+1],n.data[c+2]])}else w&&k(w,w);return!I||!T||!Number.isFinite(x)?{ratio:null,required:e,reason:"could not isolate opaque rendered text pixels"}:{ratio:Math.round(x*100)/100,required:e,foreground:a(I),background:a(T)}}function A(t={}){let e=t.styling===!0,r=t.filter?.trim().toLowerCase()??"";return`(async () => {
81
+ })()`;return await t.send({type:"evaluate",code:r})??{}}function D(t){let e=t.fontSize>=18||t.fontSize>=14&&(t.fontWeight??400)>=700?3:4.5,{normal:r,background:n}=t;if(r.width<=0||r.height<=0||r.width!==n.width||r.height!==n.height)return{ratio:null,required:e,reason:"capture dimensions do not match"};let o=Math.max(0,Math.floor(t.box.x)),s=Math.max(0,Math.floor(t.box.y)),i=Math.min(r.width,Math.ceil(t.box.x+t.box.w)),d=Math.min(r.height,Math.ceil(t.box.y+t.box.h));if(i<=o||d<=s)return{ratio:null,required:e,reason:"text is outside the captured frame"};let p=l=>{let u=l/255;return u<=.04045?u/12.92:Math.pow((u+.055)/1.055,2.4)},m=(l,u)=>{let c=.2126*p(l[0])+.7152*p(l[1])+.0722*p(l[2]),S=.2126*p(u[0])+.7152*p(u[1])+.0722*p(u[2]);return(Math.max(c,S)+.05)/(Math.min(c,S)+.05)},a=l=>`#${l.slice(0,3).map(u=>Math.round(u).toString(16).padStart(2,"0")).join("")}`,g=(i-o)*(d-s),b=Math.max(1,Math.floor(Math.sqrt(g/12e3))),f=(l,u)=>(u*r.width+l)*4,h=l=>Math.max(Math.abs(r.data[l]-n.data[l]),Math.abs(r.data[l+1]-n.data[l+1]),Math.abs(r.data[l+2]-n.data[l+2])),y=0,v=null,w=null;for(let l=s;l<d;l+=b)for(let u=o;u<i;u+=b){let c=f(u,l);if(n.data[c+3]<250)continue;let S=[n.data[c],n.data[c+1],n.data[c+2]];w??=S;let E=h(c);E<=y||(y=E,v=[r.data[c],r.data[c+1],r.data[c+2]])}let x=1/0,I=null,T=null,k=(l,u)=>{let c=m(l,u);c>=x||(x=c,I=l,T=u)};if(y>=2&&v)for(let l=s;l<d;l+=b)for(let u=o;u<i;u+=b){let c=f(u,l);n.data[c+3]<250||h(c)<2||k(v,[n.data[c],n.data[c+1],n.data[c+2]])}else w&&k(w,w);return!I||!T||!Number.isFinite(x)?{ratio:null,required:e,reason:"could not isolate opaque rendered text pixels"}:{ratio:Math.round(x*100)/100,required:e,foreground:a(I),background:a(T)}}function A(t={}){let e=t.styling===!0,r=t.filter?.trim().toLowerCase()??"";return`(async () => {
80
82
  const t = window.__sootsimTest
81
83
  if (!t || typeof t.listInspectable !== 'function') return []
82
84
  const list = await t.listInspectable({})
83
85
  if (!Array.isArray(list)) return []
84
86
  const includeStyle = ${JSON.stringify(e)}
85
- const scoreContrast = ${C.toString()}
87
+ const scoreContrast = ${D.toString()}
86
88
  // narrows by ELEMENT, not by style field: fewer rows, full detail on each.
87
89
  const filter = ${JSON.stringify(r)}
88
90
  const matchesFilter = (n, text) => {
@@ -260,8 +262,8 @@ function G(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r
260
262
  })
261
263
  }
262
264
  return elements
263
- })()`}var ne=A();async function re(t,e={}){let r=await t.send({type:"evaluate",code:A(e)});return Array.isArray(r)?r:[]}function oe(t,e){return t.length===0?" no visible elements found":t.map(n=>{let s=[n.testID?`#${n.testID}`:n.selector?n.selector:n.role?`[${n.role}]`:`<${n.type}>`,`@(${n.box.x},${n.box.y})`,`${n.box.w}x${n.box.h}`];n.borderRadius>0&&s.push(`radius:${n.borderRadius}`);let i=n.padding;if(i.t||i.r||i.b||i.l){let d=i.t===i.r&&i.r===i.b&&i.b===i.l;s.push(d?`pad:${i.t}`:`pad:${i.t},${i.r},${i.b},${i.l}`)}if(n.fontSize>0&&s.push(`font:${n.fontSize}`),e?.styling){if(n.fontWeight&&s.push(`weight:${n.fontWeight}`),n.color&&s.push(`color:${n.color}`),n.bg&&s.push(`bg:${n.bg}`),n.contrast){let d=n.contrast.ratio==null?`?/${n.contrast.required}`:`${n.contrast.ratio}/${n.contrast.required}${n.contrast.ratio<n.contrast.required?" FAIL":""}`;s.push(`contrast:${d}`),n.contrast.background&&s.push(`on:${n.contrast.background}`)}n.opacity!=null&&s.push(`opacity:${n.opacity}`),n.textDecoration&&s.push(`deco:${n.textDecoration}`),n.overflow&&s.push(`overflow:${n.overflow}`),n.borderWidth&&s.push(n.borderColor?`border:${n.borderWidth}/${n.borderColor}`:`border:${n.borderWidth}`)}if(n.text){let d=n.text.length>40?`${n.text.slice(0,39)}\u2026`:n.text;s.push(`"${d}"`)}return` ${s.join(" ")}`}).join(`
264
- `)}var D=`(async () => {
265
+ })()`}var re=A();async function oe(t,e={}){let r=await t.send({type:"evaluate",code:A(e)});return Array.isArray(r)?r:[]}function se(t,e){return t.length===0?" no visible elements found":t.map(n=>{let s=[n.testID?`#${n.testID}`:n.selector?n.selector:n.role?`[${n.role}]`:`<${n.type}>`,`@(${n.box.x},${n.box.y})`,`${n.box.w}x${n.box.h}`];n.borderRadius>0&&s.push(`radius:${n.borderRadius}`);let i=n.padding;if(i.t||i.r||i.b||i.l){let d=i.t===i.r&&i.r===i.b&&i.b===i.l;s.push(d?`pad:${i.t}`:`pad:${i.t},${i.r},${i.b},${i.l}`)}if(n.fontSize>0&&s.push(`font:${n.fontSize}`),e?.styling){if(n.fontWeight&&s.push(`weight:${n.fontWeight}`),n.color&&s.push(`color:${n.color}`),n.bg&&s.push(`bg:${n.bg}`),n.contrast){let d=n.contrast.ratio==null?`?/${n.contrast.required}`:`${n.contrast.ratio}/${n.contrast.required}${n.contrast.ratio<n.contrast.required?" FAIL":""}`;s.push(`contrast:${d}`),n.contrast.background&&s.push(`on:${n.contrast.background}`)}n.opacity!=null&&s.push(`opacity:${n.opacity}`),n.textDecoration&&s.push(`deco:${n.textDecoration}`),n.overflow&&s.push(`overflow:${n.overflow}`),n.borderWidth&&s.push(n.borderColor?`border:${n.borderWidth}/${n.borderColor}`:`border:${n.borderWidth}`)}if(n.text){let d=n.text.length>40?`${n.text.slice(0,39)}\u2026`:n.text;s.push(`"${d}"`)}return` ${s.join(" ")}`}).join(`
266
+ `)}var O=`(async () => {
265
267
  const t = window.__sootsimTest
266
268
  if (!t) return []
267
269
 
@@ -334,7 +336,7 @@ function G(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r
334
336
  return all
335
337
  .filter(n => isVisibleTarget(n) && hasAccessibleSignal(n))
336
338
  .map(normalize)
337
- })()`;async function se(t){let e=await t.send({type:"evaluate",code:D});return Array.isArray(e)?e:[]}var R=`
339
+ })()`;async function ae(t){let e=await t.send({type:"evaluate",code:O});return Array.isArray(e)?e:[]}var R=`
338
340
  const fromInspectable = async () => {
339
341
  if (typeof t.listInspectable !== 'function') return null
340
342
  const list = await t.listInspectable({})
@@ -406,7 +408,7 @@ function G(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r
406
408
  abs.y < screenH
407
409
  )
408
410
  }
409
- `;function O(t){return t.testId?{mode:"testid",code:`(async () => {
411
+ `;function C(t){return t.testId?{mode:"testid",code:`(async () => {
410
412
  const t = window.__sootsimTest
411
413
  if (!t) return null
412
414
  return (await t.findByTestId(${JSON.stringify(t.testId)})) || (await t.findById(${JSON.stringify(t.testId)}))
@@ -445,7 +447,7 @@ ${R}
445
447
  const t = window.__sootsimTest
446
448
  if (!t) return null
447
449
  return await t.findByText(${JSON.stringify(t.text)})
448
- })()`}:null}async function ae(t,e){let r=O(e);if(!r)return null;let n=await t.send({type:"evaluate",code:r.code});return{mode:r.mode,result:n}}function ie(t){return[...t].sort((e,r)=>$(r)-$(e))}function $(t){let e=0;t.testID&&(e+=100),typeof t.text=="string"&&t.text.trim().length>0&&(e+=60),typeof t.accessibilityLabel=="string"&&t.accessibilityLabel.trim().length>0&&(e+=30),t.accessibilityRole&&(e+=15);let r=t.layout?.width??0,n=t.layout?.height??0,o=r*n;return o>=400&&o<=6e4?e+=25:o>6e4&&(e-=20),(t.absolutePosition?.y??0)<0&&(e-=30),e}function le(t){if(t.testID)return`sootsim do tap-id ${_(t.testID)}`;let e=typeof t.text=="string"?t.text.trim():"";if(e.length>0&&e.length<=80)return`sootsim do tap-text ${_(e)}`;let r=Math.round(((t.absolutePosition?.x??0)+(t.layout?.width??0)/2)*10)/10,n=Math.round(((t.absolutePosition?.y??0)+(t.layout?.height??0)/2)*10)/10;return`sootsim do tap ${r} ${n}`}function _(t){return/^[A-Za-z0-9_./@:-]+$/.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}var F=`(async () => {
450
+ })()`}:null}async function ie(t,e){let r=C(e);if(!r)return null;let n=await t.send({type:"evaluate",code:r.code});return{mode:r.mode,result:n}}function le(t){return[...t].sort((e,r)=>$(r)-$(e))}function $(t){let e=0;t.testID&&(e+=100),typeof t.text=="string"&&t.text.trim().length>0&&(e+=60),typeof t.accessibilityLabel=="string"&&t.accessibilityLabel.trim().length>0&&(e+=30),t.accessibilityRole&&(e+=15);let r=t.layout?.width??0,n=t.layout?.height??0,o=r*n;return o>=400&&o<=6e4?e+=25:o>6e4&&(e-=20),(t.absolutePosition?.y??0)<0&&(e-=30),e}function ue(t){if(t.testID)return`sootsim do tap-id ${_(t.testID)}`;let e=typeof t.text=="string"?t.text.trim():"";if(e.length>0&&e.length<=80)return`sootsim do tap-text ${_(e)}`;let r=Math.round(((t.absolutePosition?.x??0)+(t.layout?.width??0)/2)*10)/10,n=Math.round(((t.absolutePosition?.y??0)+(t.layout?.height??0)/2)*10)/10;return`sootsim do tap ${r} ${n}`}function _(t){return/^[A-Za-z0-9_./@:-]+$/.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}var F=`(async () => {
449
451
  const t = window.__sootsimTest
450
452
  let nodes = 0
451
453
  try { nodes = (await t?.getNodeCount?.()) || 0 } catch {}
@@ -582,7 +584,7 @@ ${R}
582
584
  externalError,
583
585
  suppressedEntryError,
584
586
  }
585
- })()`,W=100,H=750,B=2e3;function z(t){return t.liveFrameActive||t.targets>0||t.nodes>=W}function j(t){return t.liveFrameActive||t.targets>0}function ue(t){if(t.bridgeError)return`sim unreachable: ${t.bridgeError} \u2014 the target tab is closed or no sim is connected (check \`sootsim list\`, reopen with \`sootsim open\`)`;let e=t.externalError?`guest app errored: ${t.externalError}`:t.loadingText?`still showing "${t.loadingText}"`:t.externalReady===!1?"guest app is still loading":t.flag!==!0&&t.targets>0?"native content is rendered but the ready signal has not settled":t.flag!==!0?"guest app has not emitted sootsim:externalAppReady":t.targets<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing";return!t.externalError&&t.suppressedEntryError?`${e} (suppressed entry error: ${t.suppressedEntryError})`:e}async function ce(t,e=2e4,r={}){let n=Date.now(),o=n+e,s=r.progressIntervalMs??B,i=n+s,d=-1,p=n,m="",a={flag:void 0,at:0,nodes:0,targets:0,liveFrameActive:!1,liveFrameChannels:0,liveFramePublishes:0,errors:0,loadingText:"",externalReady:null,externalStatus:"",externalError:"",suppressedEntryError:""};for(;Date.now()<o;){try{a=await t.send({type:"evaluate",code:F})??a,m=""}catch(y){if(m=y instanceof Error?y.message:String(y),m.startsWith("multiple sims are connected:")||m.startsWith("saved sim "))throw y}let g=Date.now(),b={ready:!1,elapsedMs:g-n,nodes:a.nodes,targets:a.targets,liveFrameActive:a.liveFrameActive,liveFrameChannels:a.liveFrameChannels,liveFramePublishes:a.liveFramePublishes,flag:a.flag,loadingText:a.loadingText,externalReady:a.externalReady,externalStatus:a.externalStatus,externalError:a.externalError,suppressedEntryError:a.suppressedEntryError,errors:a.errors,bridgeError:m};a.nodes!==d&&(d=a.nodes,p=g);let f=a.flag===!0&&z(a),h=a.flag!==!0&&j(a);if((f||h)&&a.externalReady!==!1&&!a.externalError&&!a.loadingText&&g-p>=H)return{...b,ready:!0};if(r.onProgress&&s>0&&g>=i){r.onProgress(b);do i+=s;while(g>=i)}await new Promise(y=>setTimeout(y,150))}return{ready:!1,elapsedMs:Date.now()-n,nodes:a.nodes,targets:a.targets,liveFrameActive:a.liveFrameActive,liveFrameChannels:a.liveFrameChannels,liveFramePublishes:a.liveFramePublishes,flag:a.flag,loadingText:a.loadingText,externalReady:a.externalReady,externalStatus:a.externalStatus,externalError:a.externalError,suppressedEntryError:a.suppressedEntryError,errors:a.errors,bridgeError:m}}async function de(t,e,r=5e3,n={}){let o=n.gone===!0;return await t.send({type:"evaluate",code:`(async () => {
587
+ })()`,W=100,H=750,B=2e3,z=150;function j(t){return t.liveFrameActive||t.targets>0||t.nodes>=W}function J(t){return t.liveFrameActive||t.targets>0}function ce(t){if(t.bridgeError)return`sim unreachable: ${t.bridgeError} \u2014 the target tab is closed or no sim is connected (check \`sootsim list\`, reopen with \`sootsim open\`)`;let e=t.externalError?`guest app errored: ${t.externalError}`:t.loadingText?`still showing "${t.loadingText}"`:t.externalReady===!1?"guest app is still loading":t.flag!==!0&&t.targets>0?"native content is rendered but the ready signal has not settled":t.flag!==!0?"guest app has not emitted sootsim:externalAppReady":t.targets<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing";return!t.externalError&&t.suppressedEntryError?`${e} (suppressed entry error: ${t.suppressedEntryError})`:e}async function de(t,e=2e4,r={}){let n=Date.now(),o=n+e,s=r.progressIntervalMs??B,i=n+s,d=-1,p=n,m="",a={flag:void 0,at:0,nodes:0,targets:0,liveFrameActive:!1,liveFrameChannels:0,liveFramePublishes:0,errors:0,loadingText:"",externalReady:null,externalStatus:"",externalError:"",suppressedEntryError:""};for(;Date.now()<o;){try{a=await t.send({type:"evaluate",code:F})??a,m=""}catch(y){if(m=y instanceof Error?y.message:String(y),m.startsWith("multiple sims are connected:")||m.startsWith("saved sim "))throw y}let g=Date.now(),b={ready:!1,elapsedMs:g-n,nodes:a.nodes,targets:a.targets,liveFrameActive:a.liveFrameActive,liveFrameChannels:a.liveFrameChannels,liveFramePublishes:a.liveFramePublishes,flag:a.flag,loadingText:a.loadingText,externalReady:a.externalReady,externalStatus:a.externalStatus,externalError:a.externalError,suppressedEntryError:a.suppressedEntryError,errors:a.errors,bridgeError:m};a.nodes!==d&&(d=a.nodes,p=g);let f=a.flag===!0&&j(a),h=a.flag!==!0&&J(a);if((f||h)&&a.externalReady!==!1&&!a.externalError&&!a.loadingText&&g-p>=H)return{...b,ready:!0};if(r.onProgress&&s>0&&g>=i){r.onProgress(b);do i+=s;while(g>=i)}await new Promise(y=>setTimeout(y,z))}return{ready:!1,elapsedMs:Date.now()-n,nodes:a.nodes,targets:a.targets,liveFrameActive:a.liveFrameActive,liveFrameChannels:a.liveFrameChannels,liveFramePublishes:a.liveFramePublishes,flag:a.flag,loadingText:a.loadingText,externalReady:a.externalReady,externalStatus:a.externalStatus,externalError:a.externalError,suppressedEntryError:a.suppressedEntryError,errors:a.errors,bridgeError:m}}async function pe(t,e,r=5e3,n={}){let o=n.gone===!0;return await t.send({type:"evaluate",code:`(async () => {
586
588
  const start = Date.now()
587
589
  const deadline = start + ${r}
588
590
  const gone = ${o}
@@ -647,7 +649,7 @@ ${R}
647
649
  for (const e of snap) if (e && e.level === ${JSON.stringify(t)}) push(e)
648
650
  } catch {}
649
651
  return out.sort((a, b) => (a.timestamp || 0) - (b.timestamp || 0)).slice(-${e})
650
- })()`}async function pe(t,e=20){let r=await t.send({type:"evaluate",code:L("error",e)});return Array.isArray(r)?r:[]}async function ye(t,e=20){let r=await t.send({type:"evaluate",code:L("warn",e)});return Array.isArray(r)?r:[]}var me=`(() => {
652
+ })()`}async function ye(t,e=20){let r=await t.send({type:"evaluate",code:L("error",e)});return Array.isArray(r)?r:[]}async function me(t,e=20){let r=await t.send({type:"evaluate",code:L("warn",e)});return Array.isArray(r)?r:[]}var ge=`(() => {
651
653
  const norm = (s) => (typeof s === 'string' ? s : (() => { try { return JSON.stringify(s) } catch { return String(s) } })())
652
654
  const key = (lvl, ts, args) => lvl + '|' + Math.round((ts || 0) / 250) + '|' + (Array.isArray(args) ? args.map(norm).join(' ') : norm(args))
653
655
  const seen = new Set()
@@ -672,17 +674,17 @@ ${R}
672
674
  for (const e of snap) if (e) add(e.level, e.ts, e.args)
673
675
  } catch {}
674
676
  return { errors, warnings, total: errors + warnings }
675
- })()`;async function ge(t){await t.send({type:"evaluate",code:'window.__sootsimConsole?.clear(); window.__sootsimObservability?.logs?.clear?.(); "cleared"'})}async function be(t,e={}){let r=e.limit??20,n=e.failed===!1?"getRequests":"getFailedRequests",o=await t.send({type:"call",path:`__sootsimTest.${n}`,args:[r]});return Array.isArray(o)?o:[]}async function fe(t){await t.send({type:"call",path:"__sootsimTest.clearRequests",args:[]})}async function he(t){let e=await t.send({type:"evaluate",code:`(() => {
677
+ })()`;async function be(t){await t.send({type:"evaluate",code:'window.__sootsimConsole?.clear(); window.__sootsimObservability?.logs?.clear?.(); "cleared"'})}async function fe(t,e={}){let r=e.limit??20,n=e.failed===!1?"getRequests":"getFailedRequests",o=await t.send({type:"call",path:`__sootsimTest.${n}`,args:[r]});return Array.isArray(o)?o:[]}async function he(t){await t.send({type:"call",path:"__sootsimTest.clearRequests",args:[]})}async function we(t){let e=await t.send({type:"evaluate",code:`(() => {
676
678
  const obs = window.__sootsimObservability;
677
679
  if (!obs) return { ok: false };
678
680
  return { ok: true, entries: obs.logs.getSnapshot() };
679
- })()`});return!e||!e.ok?[]:e.entries??[]}async function we(t){await t.send({type:"evaluate",code:'window.__sootsimObservability?.logs.clear(); "cleared"'})}function J(t,e){if(t.source===e.source||t.level!==e.level||Math.abs(t.ts-e.ts)>1e3||t.args.length!==e.args.length)return!1;let r=new Set([t.source,e.source]);return!r.has("sootsim-worker")||!r.has("render-worker")&&!r.has("forwarded-render-worker")?!1:t.args.every((n,o)=>n===e.args[o])}function xe(t,e={}){let r=[];for(let n of t)r.some(o=>J(o,n))||r.push(n);if(e.showInternal||(r=r.filter(n=>{let o=n.args[0];return!(typeof o=="string"&&o.startsWith("[sootsim]"))})),e.level&&(r=r.filter(n=>e.level.has(n.level))),e.filter){let n=e.filter.toLowerCase();r=r.filter(o=>o.args.join(" ").toLowerCase().includes(n))}return r}async function Se(t,e){return await t.send({type:"call",path:"SootSim.bridges.timeline.summary",args:[e]})}async function K(t,e){return await t.send({type:"call",path:"SootSim.bridges.timeline.recent",args:[e]})}async function ve(t){let e;try{e=(await K(t,{kinds:["alert","actionsheet"],limit:80})).events}catch{return[]}let r=new Map;for(let s of e)r.set(s.kind,s);let n=[],o=(s,i)=>{let d=r.get(s);if(!d||!d.data||typeof d.data!="object")return;let p=d.data;p.phase==="show"&&n.push({label:i,title:typeof p.title=="string"?p.title:null})};return o("alert","Alert"),o("actionsheet","ActionSheet"),n}async function Ie(t,e,r){await t.send({type:"call",path:"SootSim.bridges.timeline.cursorAdvance",args:[e,r]})}async function Te(t){return await t.send({type:"evaluate",code:`(() => {
681
+ })()`});return!e||!e.ok?[]:e.entries??[]}async function xe(t){await t.send({type:"evaluate",code:'window.__sootsimObservability?.logs.clear(); "cleared"'})}function K(t,e){if(t.source===e.source||t.level!==e.level||Math.abs(t.ts-e.ts)>1e3||t.args.length!==e.args.length)return!1;let r=new Set([t.source,e.source]);return!r.has("sootsim-worker")||!r.has("render-worker")&&!r.has("forwarded-render-worker")?!1:t.args.every((n,o)=>n===e.args[o])}function Se(t,e={}){let r=[];for(let n of t)r.some(o=>K(o,n))||r.push(n);if(e.showInternal||(r=r.filter(n=>{let o=n.args[0];return!(typeof o=="string"&&o.startsWith("[sootsim]"))})),e.level&&(r=r.filter(n=>e.level.has(n.level))),e.filter){let n=e.filter.toLowerCase();r=r.filter(o=>o.args.join(" ").toLowerCase().includes(n))}return r}async function ve(t,e){return await t.send({type:"call",path:"SootSim.bridges.timeline.summary",args:[e]})}async function V(t,e){return await t.send({type:"call",path:"SootSim.bridges.timeline.recent",args:[e]})}async function Ie(t){let e;try{e=(await V(t,{kinds:["alert","actionsheet"],limit:80})).events}catch{return[]}let r=new Map;for(let s of e)r.set(s.kind,s);let n=[],o=(s,i)=>{let d=r.get(s);if(!d||!d.data||typeof d.data!="object")return;let p=d.data;p.phase==="show"&&n.push({label:i,title:typeof p.title=="string"?p.title:null})};return o("alert","Alert"),o("actionsheet","ActionSheet"),n}async function Te(t,e,r){await t.send({type:"call",path:"SootSim.bridges.timeline.cursorAdvance",args:[e,r]})}async function ke(t){return await t.send({type:"evaluate",code:`(() => {
680
682
  const kb = window.__sootsimKeyboard
681
683
  if (!kb || typeof kb.getLayout !== 'function') {
682
684
  return { error: 'keyboard bridge getLayout() not available' }
683
685
  }
684
686
  return kb.getLayout()
685
- })()`})??{error:"keyboard bridge returned no result"}}function V(t){let e=t instanceof Error?t.message:String(t);return e.includes("call target not found: SootSim.bridges.mainShell")||e.includes("test bridge unavailable before app-in-worker boot")}async function q(t,e=0){let r=Date.now()+Math.max(0,e);for(;;)try{return await t.send({type:"call",path:"SootSim.bridges.mainShell.getState",args:[]})}catch(n){if(!V(n)||Date.now()>=r)throw n;await new Promise(o=>setTimeout(o,50))}}async function ke(t){let e=await t.send({type:"evaluate",code:`(async () => {
687
+ })()`})??{error:"keyboard bridge returned no result"}}function q(t){let e=t instanceof Error?t.message:String(t);return e.includes("call target not found: SootSim.bridges.mainShell")||e.includes("test bridge unavailable before app-in-worker boot")}async function Y(t,e=0){let r=Date.now()+Math.max(0,e);for(;;)try{return await t.send({type:"call",path:"SootSim.bridges.mainShell.getState",args:[]})}catch(n){if(!q(n)||Date.now()>=r)throw n;await new Promise(o=>setTimeout(o,50))}}async function Ee(t){let e=await t.send({type:"evaluate",code:`(async () => {
686
688
  const test = window.__sootsimTest
687
689
  const kb = window.__sootsimKeyboard
688
690
  const navSnap =
@@ -710,7 +712,7 @@ ${R}
710
712
  })()
711
713
  : null
712
714
  return { nav: navSnap, route, keyboard }
713
- })()`});return{shell:await q(t,500).catch(()=>null),nav:e?.nav??null,route:e?.route??null,keyboard:e?.keyboard??null}}async function Ee(t){return t.send({type:"evaluate",code:"window.__sootsimDebug.status()"})}async function Re(t){return t.send({type:"evaluate",code:"window.__sootsimDebug.flags()"})}async function $e(t,e){return t.send({type:"evaluate",code:`window.__sootsimTest.debugFind(${JSON.stringify(e)})`})}async function _e(t,e,r=50){let n=e&&e!=="all"?`window.__sootsimDebug.recent(${JSON.stringify(e)}, ${r})`:`window.__sootsimDebug.recent(undefined, ${r})`;return t.send({type:"evaluate",code:n})}async function Ae(t,e,r){let n=r.length>0?r.map(o=>JSON.stringify(o)).join(", "):e==="disable"?"'all'":"";return t.send({type:"evaluate",code:`window.__sootsimDebug.${e}(${n})`})}async function Le(t){return await t.send({type:"evaluate",code:`(async () => {
715
+ })()`});return{shell:await Y(t,500).catch(()=>null),nav:e?.nav??null,route:e?.route??null,keyboard:e?.keyboard??null}}async function Re(t){return t.send({type:"evaluate",code:"window.__sootsimDebug.status()"})}async function $e(t){return t.send({type:"evaluate",code:"window.__sootsimDebug.flags()"})}async function _e(t,e){return t.send({type:"evaluate",code:`window.__sootsimTest.debugFind(${JSON.stringify(e)})`})}async function Ae(t,e,r=50){let n=e&&e!=="all"?`window.__sootsimDebug.recent(${JSON.stringify(e)}, ${r})`:`window.__sootsimDebug.recent(undefined, ${r})`;return t.send({type:"evaluate",code:n})}async function Le(t,e,r){let n=r.length>0?r.map(o=>JSON.stringify(o)).join(", "):e==="disable"?"'all'":"";return t.send({type:"evaluate",code:`window.__sootsimDebug.${e}(${n})`})}async function Ne(t){return await t.send({type:"evaluate",code:`(async () => {
714
716
  const host = window.__sootsimRenderHost
715
717
  const stats = host?.queryStats ? await host.queryStats() : null
716
718
  const shellRaw = window.__sootsimShellMemory
@@ -750,4 +752,4 @@ ${R}
750
752
  compositor: normalize(compositor),
751
753
  hostHeap: hostMem,
752
754
  }
753
- })()`})??{tenant:null,shell:null,compositor:null,hostHeap:null}}function Ne(t){if(t.total===0)return"nothing recorded";let e=[],r=["error","warning","console","fetch","toast","alert","actionsheet","picker","notification","screen","route","keyboard","app-launch","shell","scroll","gesture","text-input","react-commit","animation","reanimated"],n=new Set;for(let o of r){let s=t.byKind[o];s&&(e.push(`${s} ${o}${s===1?"":"s"}`),n.add(o))}for(let[o,s]of Object.entries(t.byKind))!n.has(o)&&s&&e.push(`${s} ${o}${s===1?"":"s"}`);return e.join(" \xB7 ")}var Pe=new Set(["react-commit","layout","scroll"]);function U(t,e){if(e===null)return new Date(t).toLocaleTimeString();let r=(t-e)/1e3;return`${r>=0?"+":""}${r.toFixed(2)}s`}function Y(t,e){switch(t){case"app-launch":return e.phase==="launch"?`launch ${e.appName??e.toAppId??""}`:`dismiss ${e.appName??e.fromAppId??""} \u2192 ${e.toAppId??""}`;case"toast":return`"${e.text??""}"${e.durationMs?` (${e.durationMs}ms)`:""}`;case"keyboard":return`${e.phase??"?"}${e.heightPx?` h=${e.heightPx}`:""}${e.mode?` ${e.mode}`:""}`;case"screen":return`${e.phase??"?"} ${e.name??e.activeName??""}`;case"flow-step":return`${e.status??"?"} ${e.stepName??"step"}${e.durationMs?` ${e.durationMs}ms`:""}`;case"route":return`${e.phase??"?"} ${e.path??e.pathname??""}`;case"alert":case"actionsheet":case"picker":return`${e.phase??"?"} ${e.title??e.message??""}`;case"notification":return`${e.title??""}${e.body?` \u2014 ${e.body}`:""}`;case"fetch":return`${e.method??"GET"} ${e.url??""}${e.status?` -> ${e.status}`:""}`;case"console":case"console-log":return`${e.level??"log"}: ${(e.message??"").toString().slice(0,120)}`;case"shell":return`${e.event??e.type??e.phase??""}`;case"scroll":return`${e.phase??"?"} ${e.target??""}`;case"gesture":return`${e.phase??"?"} ${e.type??""}`;case"text-input":return`${e.phase??"?"}${e.value!==void 0?` "${String(e.value).slice(0,40)}"`:""}`;case"layout":return`${e.kind??"?"} ${e.testID??e.type??""}${e.skipped?` skipped:${e.reason??"unknown"}`:""}`;case"react-commit":{let r=e.slowest;return`${e.fiberCount??"?"} fibers ${e.durationMs??"?"}ms${r?.displayName?` \xB7 ${r.displayName} ${r.durationMs??"?"}ms`:""}`}case"frame":return`${e.totalMs??"?"}ms${e.renderMs?` \xB7 render ${e.renderMs}ms`:""}${e.layoutMs?` \xB7 layout ${e.layoutMs}ms`:""}${e.copyMs?` \xB7 copy ${e.copyMs}ms`:""}`;case"reanimated":case"animation":return`${e.kind??""} ${e.target??""}${e.durationMs?` ${e.durationMs}ms`:""}`}return""}function Me(t,e){let r=U(t.t,e).padStart(8),n=t.context.padEnd(6),o=`[${t.kind}]`.padEnd(15),s=t.data,i=s&&typeof s=="object"?Y(t.kind,s):"";return` ${r} ${n} ${o} ${i}`}export{G as a,Q as b,X as c,Z as d,ee as e,te as f,re as g,oe as h,se as i,ae as j,ie as k,le as l,F as m,H as n,z as o,j as p,ue as q,ce as r,de as s,pe as t,ye as u,me as v,ge as w,be as x,fe as y,he as z,we as A,xe as B,Se as C,K as D,ve as E,Ie as F,Te as G,V as H,q as I,ke as J,Ee as K,Re as L,$e as M,_e as N,Ae as O,Le as P,Ne as Q,Pe as R,Me as S};
755
+ })()`})??{tenant:null,shell:null,compositor:null,hostHeap:null}}function Pe(t){if(t.total===0)return"nothing recorded";let e=[],r=["error","warning","console","fetch","toast","alert","actionsheet","picker","notification","screen","route","keyboard","app-launch","shell","scroll","gesture","text-input","react-commit","animation","reanimated"],n=new Set;for(let o of r){let s=t.byKind[o];s&&(e.push(`${s} ${o}${s===1?"":"s"}`),n.add(o))}for(let[o,s]of Object.entries(t.byKind))!n.has(o)&&s&&e.push(`${s} ${o}${s===1?"":"s"}`);return e.join(" \xB7 ")}var Me=new Set(["react-commit","layout","scroll"]);function U(t,e){if(e===null)return new Date(t).toLocaleTimeString();let r=(t-e)/1e3;return`${r>=0?"+":""}${r.toFixed(2)}s`}function G(t,e){switch(t){case"app-launch":return e.phase==="launch"?`launch ${e.appName??e.toAppId??""}`:`dismiss ${e.appName??e.fromAppId??""} \u2192 ${e.toAppId??""}`;case"toast":return`"${e.text??""}"${e.durationMs?` (${e.durationMs}ms)`:""}`;case"keyboard":return`${e.phase??"?"}${e.heightPx?` h=${e.heightPx}`:""}${e.mode?` ${e.mode}`:""}`;case"screen":return`${e.phase??"?"} ${e.name??e.activeName??""}`;case"flow-step":return`${e.status??"?"} ${e.stepName??"step"}${e.durationMs?` ${e.durationMs}ms`:""}`;case"route":return`${e.phase??"?"} ${e.path??e.pathname??""}`;case"alert":case"actionsheet":case"picker":return`${e.phase??"?"} ${e.title??e.message??""}`;case"notification":return`${e.title??""}${e.body?` \u2014 ${e.body}`:""}`;case"fetch":return`${e.method??"GET"} ${e.url??""}${e.status?` -> ${e.status}`:""}`;case"console":case"console-log":return`${e.level??"log"}: ${(e.message??"").toString().slice(0,120)}`;case"shell":return`${e.event??e.type??e.phase??""}`;case"scroll":return`${e.phase??"?"} ${e.target??""}`;case"gesture":return`${e.phase??"?"} ${e.type??""}`;case"text-input":return`${e.phase??"?"}${e.value!==void 0?` "${String(e.value).slice(0,40)}"`:""}`;case"layout":return`${e.kind??"?"} ${e.testID??e.type??""}${e.skipped?` skipped:${e.reason??"unknown"}`:""}`;case"react-commit":{let r=e.slowest;return`${e.fiberCount??"?"} fibers ${e.durationMs??"?"}ms${r?.displayName?` \xB7 ${r.displayName} ${r.durationMs??"?"}ms`:""}`}case"frame":return`${e.totalMs??"?"}ms${e.renderMs?` \xB7 render ${e.renderMs}ms`:""}${e.layoutMs?` \xB7 layout ${e.layoutMs}ms`:""}${e.copyMs?` \xB7 copy ${e.copyMs}ms`:""}`;case"reanimated":case"animation":return`${e.kind??""} ${e.target??""}${e.durationMs?` ${e.durationMs}ms`:""}`}return""}function De(t,e){let r=U(t.t,e).padStart(8),n=t.context.padEnd(6),o=`[${t.kind}]`.padEnd(15),s=t.data,i=s&&typeof s=="object"?G(t.kind,s):"";return` ${r} ${n} ${o} ${i}`}export{Q as a,X as b,Z as c,ee as d,te as e,ne as f,oe as g,se as h,ae as i,ie as j,le as k,ue as l,F as m,H as n,z as o,j as p,J as q,ce as r,de as s,pe as t,ye as u,me as v,ge as w,be as x,fe as y,he as z,we as A,xe as B,Se as C,ve as D,V as E,Ie as F,Te as G,ke as H,q as I,Y as J,Ee as K,Re as L,$e as M,_e as N,Ae as O,Le as P,Ne as Q,Pe as R,Me as S,De as T};
@@ -1,4 +1,6 @@
1
- /*! sootsim v0.1.293 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.294 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
2
4
  import{execFileSync as h,spawn as g}from"child_process";import{existsSync as s,readdirSync as k}from"fs";import{dirname as m,join as l,resolve as a}from"path";import{fileURLToPath as w}from"url";var c;function p(){if(c!==void 0)return c;try{c=m(w(import.meta.resolve("sootsim-engine/package.json")))}catch{c=null}return c}var v="dev.sootsim.simulator";function I(){let e=p();if(!e)return null;let n=l(e,"dist-electron/main.cjs");if(!s(n))return null;let i=P(e);return i?{path:i,platform:process.platform,kind:"dev-electron",engineDir:e}:null}function x(){let e=p();return e?s(l(e,"src-electron/main.ts")):!1}function P(e){let n=e;for(let i=0;i<6;i++){let t=l(n,"node_modules/.bin/electron");if(s(t))return t;let r=m(n);if(r===n)break;n=r}return null}function b(){let e=p(),i=["/Applications/sootsim.app",a(process.env.HOME||"","Applications/sootsim.app"),...e?[a(e,"app/sootsim.app")]:[]].find(t=>s(t));if(i)return{path:i,platform:"darwin",kind:"mac-app"};try{let t=h("mdfind",[`kMDItemCFBundleIdentifier == "${v}"`],{encoding:"utf8",timeout:3e3}).trim();if(t)return{path:t.split(`
3
5
  `)[0],platform:"darwin",kind:"mac-app"}}catch{}return null}function f(e){if(!s(e))return null;let n=k(e).filter(i=>i.startsWith("sootsim")&&i.endsWith(".AppImage")).sort().reverse()[0];return n?l(e,n):null}function D(){let e=p(),i=[a(process.env.HOME||"","Applications/sootsim.AppImage"),a(process.env.HOME||"",".local/bin/sootsim.AppImage"),"/opt/sootsim/sootsim.AppImage","/opt/sootsim/sootsim",...e?[a(e,"app/sootsim.AppImage"),a(e,"release/linux-unpacked/sootsim")]:[]].find(r=>s(r));if(i)return{path:i,platform:"linux",kind:i.endsWith(".AppImage")?"linux-appimage":"linux-binary"};let t=e?f(a(e,"app"))||f(a(e,"release")):null;return t?{path:t,platform:"linux",kind:"linux-appimage"}:null}function C(){let e=I();if(e)return e;if(x()){let n=p(),i=l(n,"dist-electron/main.cjs");return s(i)?console.error(` no node_modules/.bin/electron found near ${n}. run \`bun install\`.`):console.error(` dist-electron/main.cjs missing in ${n}.
4
6
  run: bun run --cwd packages/sootsim-engine build:electron-main
@@ -1,2 +1,4 @@
1
- /*! sootsim v0.1.293 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.294 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
2
4
  var a=["Cache","Code Cache","DawnCache","DawnGraphiteCache","DawnWebGPUCache","GPUCache","GrShaderCache","ShaderCache"],r=new Set(a);function s(e){return r.has(e)}export{a,s as b};
@@ -1,5 +1,7 @@
1
- /*! sootsim v0.1.293 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{d as R}from"./chunk-J6P2UPXH.js";import{a as w,b as y,c as b,d as r}from"./chunk-2VKTOZQ5.js";import{G as d,H as u,I as $,l as p,z as g}from"./chunk-WOWLO4LL.js";import k from"fs";import{WebSocket as x}from"ws";async function H(t,e={}){let[s,...n]=t;if(!s||s==="--help"||s==="-h"){I();return}switch(s){case"install":return S(n,e);case"list":case"ls":return D(n);case"use":return N(n);case"remove":case"rm":return T(n);case"which":case"active":return L();case"pin":return _(n);case"unpin":return C();case"notes":case"changelog":return P(n);default:console.error(` unknown runtime subcommand: ${s}`),I(),process.exit(1)}}function I(){console.log(`
1
+ /*! sootsim v0.1.294 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
4
+ import{d as R}from"./chunk-PZTKQG6H.js";import{a as w,b as y,c as b,d as r}from"./chunk-CTMPC5DN.js";import{G as d,H as u,I as $,l as p,z as g}from"./chunk-WQL3BLFD.js";import k from"fs";import{WebSocket as x}from"ws";async function H(t,e={}){let[s,...n]=t;if(!s||s==="--help"||s==="-h"){I();return}switch(s){case"install":return S(n,e);case"list":case"ls":return D(n);case"use":return N(n);case"remove":case"rm":return T(n);case"which":case"active":return L();case"pin":return _(n);case"unpin":return C();case"notes":case"changelog":return P(n);default:console.error(` unknown runtime subcommand: ${s}`),I(),process.exit(1)}}function I(){console.log(`
3
5
  sootsim runtime \u2014 manage engine runtimes under ~/.sootsim/runtimes/
4
6
 
5
7
  usage:
@@ -26,4 +28,4 @@ examples:
26
28
  sootsim runtime install --channel beta
27
29
  sootsim runtime use 1.2.3
28
30
  sootsim runtime notes
29
- `)}async function S(t,e){let{version:s,flags:n}=U(t),o=n.channel??e.channel??"stable",c=n.force===!0,l=n.setActive!==!1;d(),console.log("sootsim runtime install"),console.log(` cdn: ${r.resolveCdnOrigin()}`);try{let i=await r.install({version:s,channel:o,force:c,setActive:l});console.log(` version: ${i.version} (channel: ${i.channel})`),i.installed?console.log(` installed ${i.version}`):console.log(` already installed at ${i.runtimeDir}`),l&&await m(i.version)}catch(i){console.error(` ${v(i)}`),process.exit(1)}}async function m(t){$(t),console.log(` active: ${t}`),await A(t)||console.log(` (no daemon running \u2014 next sootsim/electron launch will pick up ${t})`)}async function A(t){let{isDaemonLockfileFresh:e,readDaemonLockfile:s}=await import("./home-paths-O4CGYVHF.js"),n=s();if(!e(n))return!1;let o=R();return new Promise(c=>{let l=!1,i=!1,f=O=>{l||(l=!0,c(O))},a=new x(`ws://127.0.0.1:${o}`,{handshakeTimeout:800}),h=setTimeout(()=>{try{a.close()}catch{}f(i)},1500);a.on("open",()=>{try{a.send(JSON.stringify({type:"runtime:use",version:t,id:0})),i=!0}catch{}setTimeout(()=>{try{a.close()}catch{}},100)}),a.on("close",()=>{clearTimeout(h),f(i)}),a.on("error",()=>{clearTimeout(h),f(!1)})})}async function D(t){d();let e=r.listInstalled(),s=u(),n=r.resolvePin();if(console.log("installed:"),e.length===0)console.log(" (none)");else for(let o of e)console.log(` ${o===s?"*":" "} ${o}${o===n?" (pinned)":""}`);n&&!e.includes(n)&&console.log(`pinned: ${n} (not installed \u2014 run \`sootsim runtime install\`)`);try{let o=await r.fetchManifest();console.log("available (latest per channel):");for(let[l,i]of Object.entries(o.channels))console.log(` ${l.padEnd(8)} ${i.latest}`);let c=Object.keys(o.versions).sort(w).reverse();if(c.length>1){console.log("hosted versions:");for(let l of c)console.log(` ${l}`)}}catch(o){console.log(`available: (could not fetch manifest: ${v(o)})`)}}async function N(t){let e=t[0];e||(console.error(" usage: sootsim runtime use <version>"),process.exit(1));let s=r.listInstalled();s.includes(e)||(console.error(` version ${e} is not installed`),console.error(` installed: ${s.join(", ")||"(none)"}`),console.error(` run \`sootsim runtime install ${e}\` first`),process.exit(1)),await m(e)}async function T(t){let e=t[0];e||(console.error(" usage: sootsim runtime remove <version>"),process.exit(1)),u()===e&&(console.error(` cannot remove active runtime ${e}`),console.error(" switch with `sootsim runtime use <other>` first, or install another version"),process.exit(1));let n=p(e);if(!k.existsSync(n)){console.error(` ${e} is not installed`);return}k.rmSync(n,{recursive:!0,force:!0}),console.log(` removed ${e}`)}async function L(){let t=u();if(!t){console.log(" no active runtime");return}console.log(t)}async function _(t){let e=t[0];if(!e){let n=r.resolvePin();n?console.log(` runtime pinned to ${n}`):(console.log(" no pin \u2014 runtime follows channel latest"),console.log(" usage: sootsim runtime pin <version>"));return}if(g({runtimeVersion:e}),console.log(` pinned runtime to ${e}`),r.listInstalled().includes(e)){u()!==e&&await m(e);return}try{let n=await r.install({version:e,setActive:!1});console.log(n.installed?` installed ${n.version}`:` already installed at ${n.runtimeDir}`),await m(e)}catch(n){console.error(` ${v(n)}`),console.error(` pin saved, but ${e} could not be installed \u2014 check \`sootsim runtime list\` for hosted versions`),process.exit(1)}}async function C(){let t=r.resolvePin();if(!t){console.log(" no pin set");return}g({runtimeVersion:void 0}),console.log(` unpinned (was ${t}) \u2014 runtime follows channel latest again`),console.log(" run `sootsim upgrade` to move to the latest now")}async function P(t){t.length>0&&(console.error(" usage: sootsim runtime notes"),process.exit(1));let e=u();e&&console.log(` active runtime: v${e}`),console.log(` release notes: ${b}`)}function U(t){let e={},s=[];for(let n=0;n<t.length;n++){let o=t[n];if(o==="--channel"&&n+1<t.length){e.channel=t[n+1],n++;continue}if(o.startsWith("--channel=")){e.channel=o.slice(10);continue}if(o==="--force"){e.force=!0;continue}if(o==="--set-active=false"||o==="--no-set-active"){e.setActive=!1;continue}s.push(o)}return{version:s[0]??null,flags:e}}function v(t){return t instanceof Error?t.message:String(t)}export{H as a};
31
+ `)}async function S(t,e){let{version:s,flags:n}=U(t),o=n.channel??e.channel??"stable",c=n.force===!0,l=n.setActive!==!1;d(),console.log("sootsim runtime install"),console.log(` cdn: ${r.resolveCdnOrigin()}`);try{let i=await r.install({version:s,channel:o,force:c,setActive:l});console.log(` version: ${i.version} (channel: ${i.channel})`),i.installed?console.log(` installed ${i.version}`):console.log(` already installed at ${i.runtimeDir}`),l&&await m(i.version)}catch(i){console.error(` ${v(i)}`),process.exit(1)}}async function m(t){$(t),console.log(` active: ${t}`),await A(t)||console.log(` (no daemon running \u2014 next sootsim/electron launch will pick up ${t})`)}async function A(t){let{isDaemonLockfileFresh:e,readDaemonLockfile:s}=await import("./home-paths-5L7N2FLS.js"),n=s();if(!e(n))return!1;let o=R();return new Promise(c=>{let l=!1,i=!1,f=O=>{l||(l=!0,c(O))},a=new x(`ws://127.0.0.1:${o}`,{handshakeTimeout:800}),h=setTimeout(()=>{try{a.close()}catch{}f(i)},1500);a.on("open",()=>{try{a.send(JSON.stringify({type:"runtime:use",version:t,id:0})),i=!0}catch{}setTimeout(()=>{try{a.close()}catch{}},100)}),a.on("close",()=>{clearTimeout(h),f(i)}),a.on("error",()=>{clearTimeout(h),f(!1)})})}async function D(t){d();let e=r.listInstalled(),s=u(),n=r.resolvePin();if(console.log("installed:"),e.length===0)console.log(" (none)");else for(let o of e)console.log(` ${o===s?"*":" "} ${o}${o===n?" (pinned)":""}`);n&&!e.includes(n)&&console.log(`pinned: ${n} (not installed \u2014 run \`sootsim runtime install\`)`);try{let o=await r.fetchManifest();console.log("available (latest per channel):");for(let[l,i]of Object.entries(o.channels))console.log(` ${l.padEnd(8)} ${i.latest}`);let c=Object.keys(o.versions).sort(w).reverse();if(c.length>1){console.log("hosted versions:");for(let l of c)console.log(` ${l}`)}}catch(o){console.log(`available: (could not fetch manifest: ${v(o)})`)}}async function N(t){let e=t[0];e||(console.error(" usage: sootsim runtime use <version>"),process.exit(1));let s=r.listInstalled();s.includes(e)||(console.error(` version ${e} is not installed`),console.error(` installed: ${s.join(", ")||"(none)"}`),console.error(` run \`sootsim runtime install ${e}\` first`),process.exit(1)),await m(e)}async function T(t){let e=t[0];e||(console.error(" usage: sootsim runtime remove <version>"),process.exit(1)),u()===e&&(console.error(` cannot remove active runtime ${e}`),console.error(" switch with `sootsim runtime use <other>` first, or install another version"),process.exit(1));let n=p(e);if(!k.existsSync(n)){console.error(` ${e} is not installed`);return}k.rmSync(n,{recursive:!0,force:!0}),console.log(` removed ${e}`)}async function L(){let t=u();if(!t){console.log(" no active runtime");return}console.log(t)}async function _(t){let e=t[0];if(!e){let n=r.resolvePin();n?console.log(` runtime pinned to ${n}`):(console.log(" no pin \u2014 runtime follows channel latest"),console.log(" usage: sootsim runtime pin <version>"));return}if(g({runtimeVersion:e}),console.log(` pinned runtime to ${e}`),r.listInstalled().includes(e)){u()!==e&&await m(e);return}try{let n=await r.install({version:e,setActive:!1});console.log(n.installed?` installed ${n.version}`:` already installed at ${n.runtimeDir}`),await m(e)}catch(n){console.error(` ${v(n)}`),console.error(` pin saved, but ${e} could not be installed \u2014 check \`sootsim runtime list\` for hosted versions`),process.exit(1)}}async function C(){let t=r.resolvePin();if(!t){console.log(" no pin set");return}g({runtimeVersion:void 0}),console.log(` unpinned (was ${t}) \u2014 runtime follows channel latest again`),console.log(" run `sootsim upgrade` to move to the latest now")}async function P(t){t.length>0&&(console.error(" usage: sootsim runtime notes"),process.exit(1));let e=u();e&&console.log(` active runtime: v${e}`),console.log(` release notes: ${b}`)}function U(t){let e={},s=[];for(let n=0;n<t.length;n++){let o=t[n];if(o==="--channel"&&n+1<t.length){e.channel=t[n+1],n++;continue}if(o.startsWith("--channel=")){e.channel=o.slice(10);continue}if(o==="--force"){e.force=!0;continue}if(o==="--set-active=false"||o==="--no-set-active"){e.setActive=!1;continue}s.push(o)}return{version:s[0]??null,flags:e}}function v(t){return t instanceof Error?t.message:String(t)}export{H as a};
@@ -1,5 +1,7 @@
1
- /*! sootsim v0.1.293 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as K,b as V,c as Ne}from"./chunk-DE4ZA3NL.js";import{c as Pe}from"./chunk-ACSTEPSD.js";import{d as _e}from"./chunk-MOU2WLO4.js";import{d as Oe}from"./chunk-JOPKZVOW.js";import{g as $e,i as Fe,k as B}from"./chunk-J6P2UPXH.js";import{c as Ue,d as E}from"./chunk-7H5G4HUK.js";import{a as Ae}from"./chunk-547W23BB.js";import{createHash as St}from"crypto";import{readFileSync as M}from"fs";import je from"path";import{gzipSync as ge,gunzipSync as vt}from"zlib";function Ce(e){let t=(e||"").toLowerCase().split(";")[0].trim();return t?!(t.startsWith("image/")||t.startsWith("video/")||t.startsWith("audio/")||t==="font/woff2"||t==="application/font-woff2"||t==="application/zip"||t==="application/gzip"):!0}import{brotliCompressSync as ut,constants as ct}from"node:zlib";var dt=9;function Le(e){return ut(e,{params:{[ct.BROTLI_PARAM_QUALITY]:dt}})}function ce(e,t){let r=new AbortController,s=setTimeout(()=>r.abort(new Error(`${t} timed out after ${e/1e3}s`)),e);return{signal:r.signal,cancel:()=>clearTimeout(s)}}async function pt(e){let t=ce(12e4,`PUT ${e.url}`),r;try{r=await fetch(e.url,{method:"PUT",headers:{"content-type":e.contentType},body:e.bytes,signal:t.signal})}finally{t.cancel()}if(!r.ok){let s=await r.text().catch(()=>"");throw new Error(`PUT ${e.url} failed ${r.status}: ${s.slice(0,200)}`)}}async function mt(e,t=8,r){let s=0,o=0,i=e.length;await Promise.all(Array.from({length:Math.min(t,i)},async()=>{for(;s<i;){let l=e[s++];await pt(l),o++,r?.(o,i)}}))}function ft(e,t,r,s){let o=[];o.push({url:e.bundle.putUrl,contentType:e.bundle.contentType,bytes:t});for(let i of e.files){let l=r.get(i.urlhash);l&&o.push({url:i.putUrl,contentType:i.contentType,bytes:l})}e.events&&s?.eventsBytes&&o.push({url:e.events.putUrl,contentType:e.events.contentType,bytes:s.eventsBytes}),e.timeline&&s?.timelineBytes&&o.push({url:e.timeline.putUrl,contentType:e.timeline.contentType,bytes:s.timelineBytes}),e.flowVideo&&s?.videoBytes&&o.push({url:e.flowVideo.putUrl,contentType:e.flowVideo.contentType,bytes:s.videoBytes}),e.storage&&s?.storageBytes&&o.push({url:e.storage.putUrl,contentType:e.storage.contentType,bytes:s.storageBytes}),e.failureBundle&&s?.failureBundleBytes&&o.push({url:e.failureBundle.putUrl,contentType:e.failureBundle.contentType,bytes:s.failureBundleBytes});for(let i of e.snapshots??[]){let l=s?.snapshotBytes?.get(i.id);l&&o.push({url:i.putUrl,contentType:i.contentType,bytes:l})}return o}function gt(e){return e.replace(/\/+$/,"")}var W=class extends Error{constructor(r,s,o,i=""){super(r);this.status=s;this.phase=o;this.responseText=i;this.name="PresignedUploadError"}};async function ze(e){let t=gt(e.originBase),r={"content-type":"application/json"};e.authHeader&&(r.authorization=e.authHeader),e.adminBypassToken&&(r["x-contrast-admin-upload-bypass"]=e.adminBypassToken);let s=ce(3e4,"init"),o;try{o=await fetch(`${t}/api/preview/upload/init`,{method:"POST",headers:r,body:JSON.stringify(e.initBody),signal:s.signal})}finally{s.cancel()}if(!o.ok){let T=await o.text().catch(()=>"");throw new W(`init failed: ${o.status} ${T.slice(0,200)}`,o.status,"init",T)}let i=await o.json(),l=ft(i,e.bundleBytes,e.filesByHash,e.extras);await mt(l,e.concurrency??8,e.onPutProgress);let m=ce(3e4,"finalize"),c;try{c=await fetch(`${t}/api/preview/upload/finalize`,{method:"POST",headers:r,body:JSON.stringify({token:i.token}),signal:m.signal})}finally{m.cancel()}if(!c.ok){let T=await c.text().catch(()=>"");throw new W(`finalize failed: ${c.status} ${T.slice(0,200)}`,c.status,"finalize",T)}let h=await c.json();return{init:i,finalize:h}}function ht(e){return e!==null&&typeof e=="object"?e:null}function De(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function de(e){let t=ht(e);return t?t.schemaVersion===1&&De(t.t)!==void 0&&De(t.seq)!==void 0&&typeof t.context=="string"&&typeof t.kind=="string"&&"data"in t:!1}function yt(e,t){let r=[];for(let s of e.split(`
1
+ /*! sootsim v0.1.294 | (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 K,b as V,c as Ne}from"./chunk-FSRRJGYC.js";import{c as Pe}from"./chunk-6YN3IAWJ.js";import{d as _e}from"./chunk-37ZXWXM3.js";import{d as Oe}from"./chunk-VVVORIQI.js";import{g as $e,i as Fe,k as B}from"./chunk-PZTKQG6H.js";import{c as Ue,d as E}from"./chunk-ZFMJFX27.js";import{a as Ae}from"./chunk-SLMUW2WU.js";import{createHash as St}from"crypto";import{readFileSync as M}from"fs";import je from"path";import{gzipSync as ge,gunzipSync as vt}from"zlib";function Ce(e){let t=(e||"").toLowerCase().split(";")[0].trim();return t?!(t.startsWith("image/")||t.startsWith("video/")||t.startsWith("audio/")||t==="font/woff2"||t==="application/font-woff2"||t==="application/zip"||t==="application/gzip"):!0}import{brotliCompressSync as ut,constants as ct}from"node:zlib";var dt=9;function Le(e){return ut(e,{params:{[ct.BROTLI_PARAM_QUALITY]:dt}})}function ce(e,t){let r=new AbortController,s=setTimeout(()=>r.abort(new Error(`${t} timed out after ${e/1e3}s`)),e);return{signal:r.signal,cancel:()=>clearTimeout(s)}}async function pt(e){let t=ce(12e4,`PUT ${e.url}`),r;try{r=await fetch(e.url,{method:"PUT",headers:{"content-type":e.contentType},body:e.bytes,signal:t.signal})}finally{t.cancel()}if(!r.ok){let s=await r.text().catch(()=>"");throw new Error(`PUT ${e.url} failed ${r.status}: ${s.slice(0,200)}`)}}async function mt(e,t=8,r){let s=0,o=0,i=e.length;await Promise.all(Array.from({length:Math.min(t,i)},async()=>{for(;s<i;){let l=e[s++];await pt(l),o++,r?.(o,i)}}))}function ft(e,t,r,s){let o=[];o.push({url:e.bundle.putUrl,contentType:e.bundle.contentType,bytes:t});for(let i of e.files){let l=r.get(i.urlhash);l&&o.push({url:i.putUrl,contentType:i.contentType,bytes:l})}e.events&&s?.eventsBytes&&o.push({url:e.events.putUrl,contentType:e.events.contentType,bytes:s.eventsBytes}),e.timeline&&s?.timelineBytes&&o.push({url:e.timeline.putUrl,contentType:e.timeline.contentType,bytes:s.timelineBytes}),e.flowVideo&&s?.videoBytes&&o.push({url:e.flowVideo.putUrl,contentType:e.flowVideo.contentType,bytes:s.videoBytes}),e.storage&&s?.storageBytes&&o.push({url:e.storage.putUrl,contentType:e.storage.contentType,bytes:s.storageBytes}),e.failureBundle&&s?.failureBundleBytes&&o.push({url:e.failureBundle.putUrl,contentType:e.failureBundle.contentType,bytes:s.failureBundleBytes});for(let i of e.snapshots??[]){let l=s?.snapshotBytes?.get(i.id);l&&o.push({url:i.putUrl,contentType:i.contentType,bytes:l})}return o}function gt(e){return e.replace(/\/+$/,"")}var W=class extends Error{constructor(r,s,o,i=""){super(r);this.status=s;this.phase=o;this.responseText=i;this.name="PresignedUploadError"}};async function ze(e){let t=gt(e.originBase),r={"content-type":"application/json"};e.authHeader&&(r.authorization=e.authHeader),e.adminBypassToken&&(r["x-contrast-admin-upload-bypass"]=e.adminBypassToken);let s=ce(3e4,"init"),o;try{o=await fetch(`${t}/api/preview/upload/init`,{method:"POST",headers:r,body:JSON.stringify(e.initBody),signal:s.signal})}finally{s.cancel()}if(!o.ok){let T=await o.text().catch(()=>"");throw new W(`init failed: ${o.status} ${T.slice(0,200)}`,o.status,"init",T)}let i=await o.json(),l=ft(i,e.bundleBytes,e.filesByHash,e.extras);await mt(l,e.concurrency??8,e.onPutProgress);let m=ce(3e4,"finalize"),c;try{c=await fetch(`${t}/api/preview/upload/finalize`,{method:"POST",headers:r,body:JSON.stringify({token:i.token}),signal:m.signal})}finally{m.cancel()}if(!c.ok){let T=await c.text().catch(()=>"");throw new W(`finalize failed: ${c.status} ${T.slice(0,200)}`,c.status,"finalize",T)}let h=await c.json();return{init:i,finalize:h}}function ht(e){return e!==null&&typeof e=="object"?e:null}function De(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function de(e){let t=ht(e);return t?t.schemaVersion===1&&De(t.t)!==void 0&&De(t.seq)!==void 0&&typeof t.context=="string"&&typeof t.kind=="string"&&"data"in t:!1}function yt(e,t){let r=[];for(let s of e.split(`
3
5
  `)){let o=s.trim();if(o)try{let i=JSON.parse(o);t(i)&&r.push(i)}catch{}}return r}function He(e){return yt(e,de)}import{execSync as bt}from"child_process";function me(e){try{return bt(e,{stdio:["ignore","pipe","ignore"],timeout:3e3,encoding:"utf8"}).trim()||null}catch{return null}}function pe(e){let t=e?.trim();return!t||!/^\d+$/.test(t)?null:Number(t)}function wt(){let e=me("git remote get-url origin");if(!e)return null;let t=e.match(/github\.com[/:]([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/i);return t?{owner:t[1],repo:t[2]}:null}function fe(){let e=process.env.GITHUB_ACTIONS==="true",t=process.env.CONTRAST_BRANCH?.trim()||null,r=process.env.CONTRAST_SHA?.trim()||null,s=process.env.CONTRAST_PR_TITLE?.trim()||null,o=(process.env.CONTRAST_REPO||process.env.GITHUB_REPOSITORY||"").trim(),[i,l]=o.includes("/")?o.split("/",2):[null,null];if(e){let h=process.env.GITHUB_REF?.match(/^refs\/pull\/(\d+)\//)?.[1];return{owner:i,repo:l,branch:t||process.env.GITHUB_HEAD_REF?.trim()||process.env.GITHUB_REF_NAME?.trim()||null,commitSha:r||process.env.GITHUB_SHA?.trim()||null,githubUsername:process.env.GITHUB_ACTOR?.trim()||null,pullRequestNumber:pe(process.env.CONTRAST_PR_NUMBER)??pe(h),pullRequestTitle:s,githubRunId:process.env.GITHUB_RUN_ID?.trim()||null,source:"ci"}}let m=t??me("git rev-parse --abbrev-ref HEAD"),c=i?null:wt();return{owner:i??c?.owner??null,repo:l??c?.repo??null,branch:m==="HEAD"?null:m,commitSha:r??me("git rev-parse HEAD"),githubUsername:null,pullRequestNumber:pe(process.env.CONTRAST_PR_NUMBER),pullRequestTitle:s,githubRunId:null,source:"cli"}}function Yt(e){if(e.length===0)return{stepCount:null,failedStepIndex:null};let t=e.find(r=>r.status==="failure");return{stepCount:e.length,failedStepIndex:t?t.stepIndex:null}}function Qt(e){return e.auth?e.uploadedShare?!0:e.auth.kind==="github"||process.env.GITHUB_ACTIONS==="true":!1}async function Xt(e){let t=e.auth??K();if(!t)return null;let r=fe(),s=e.owner??(t.kind==="github"?t.owner:null)??r.owner,o=e.repo??(t.kind==="github"?t.repo:null)??r.repo;try{let i=await fetch(`${e.origin.replace(/\/$/,"")}/api/sootsim/test-runs`,{method:"POST",headers:{"content-type":"application/json",authorization:V(t)},body:JSON.stringify({kind:e.kind,source:r.source,name:e.name??void 0,prompt:e.prompt??void 0,summary:e.summary??void 0,status:e.status,failureMessage:e.failureMessage??void 0,previewShareId:e.previewShareId??void 0,owner:s??void 0,repo:o??void 0,branch:r.branch??void 0,commitSha:r.commitSha??void 0,githubUsername:r.githubUsername??void 0,pullRequestNumber:r.pullRequestNumber??void 0,githubRunId:r.githubRunId??void 0,stepCount:e.stepCount??void 0,failedStepIndex:e.failedStepIndex??void 0,durationMs:e.durationMs??void 0,flowYamlSizeBytes:e.flowYamlSizeBytes??void 0})});if(!i.ok){let m=await i.text().catch(()=>"");return console.warn(` warn: run registration failed: /api/sootsim/test-runs ${i.status}${m?`: ${m.slice(0,200)}`:""}`),null}let l=await i.json();return l.run?.id?{id:l.run.id,previewUrl:l.run.previewUrl??null,traceUrl:l.run.traceUrl??null}:(console.warn(" warn: run registration returned no id"),null)}catch(i){return console.warn(` warn: run registration failed: ${i instanceof Error?i.message:String(i)}`),null}}function Rt(e){if(!e)return null;try{let t=JSON.parse(e);return typeof t.message=="string"&&t.message?t.message:null}catch{return null}}function xt(e){let t=JSON.parse(M(e,"utf8"));if(!Array.isArray(t))throw new Error("snapshot manifest must be an array");let r=new Set;return t.map((s,o)=>{if(s===null||typeof s!="object")throw new Error(`snapshot manifest entry ${o} must be an object`);let i=Reflect.get(s,"id"),l=Reflect.get(s,"label"),m=Reflect.get(s,"path"),c=Reflect.get(s,"t");if(typeof i!="string"||!i||r.has(i))throw new Error(`snapshot manifest entry ${o} has an invalid or duplicate id`);if(typeof m!="string"||!m)throw new Error(`snapshot manifest entry ${o} has no PNG path`);if(typeof c!="number"||!Number.isFinite(c)||c<0)throw new Error(`snapshot manifest entry ${o} has an invalid capture time`);r.add(i);let h=M(m);return{meta:{id:i,label:typeof l=="string"&&l?l:i,kind:"interaction",t:Math.round(c),contentType:"image/png",sizeBytes:h.byteLength},bytes:h}})}var Ve=process.env.SOOTSIM_UPLOAD_ORIGIN||"https://contrast.dev",We=process.env.SOOTSIM_PREVIEW_ORIGIN||"https://sootsim.com",ye="https://contrast.localhost:3000",kt=2e3;async function Et(e){if(e)return e;if(process.env.SOOTSIM_UPLOAD_ORIGIN)return process.env.SOOTSIM_UPLOAD_ORIGIN;try{let t=await fetch(`${ye}/api/preview/upload/init`,{method:"OPTIONS",signal:AbortSignal.timeout(kt)});if(t.ok||t.status===204||t.status===405)return ye}catch{}return Ve}function N(e){return e.replace(/\/$/,"")}function Bt(e){try{let r=new URL(e).hostname.replace(/^\[|\]$/g,"").toLowerCase();return r==="localhost"||r.endsWith(".localhost")||r==="0.0.0.0"||r==="::1"||/^127(?:\.\d{1,3}){3}$/.test(r)}catch{return!1}}function It(e){try{let t=new URL(e).hostname.toLowerCase();return t==="contrast.dev"||t.endsWith(".contrast.dev")}catch{return!1}}function At(e,t){return t?N(t):process.env.SOOTSIM_PREVIEW_ORIGIN?N(process.env.SOOTSIM_PREVIEW_ORIGIN):Bt(e)?N(e):It(e)?N(We):N(e)}function Ut(){console.log(`
4
6
  sootsim record upload \u2014 publish the current recorded bundle as a /preview/<id> link
5
7
 
@@ -1,4 +1,6 @@
1
- /*! sootsim v0.1.293 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{G as _,H as E,I as F,k as N,l as U,u as L,x as A}from"./chunk-WOWLO4LL.js";import W from"node:fs";import z from"node:path";function T(e){try{return W.readdirSync(e.runtimesDir(),{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name).sort(k)}catch{return[]}}function D(e,a){return z.posix.basename(e.tarballPath(a))}function k(e,a){let o=f=>{let p=f.indexOf("-"),P=p>=0?f.slice(0,p):f,C=p>=0?f.slice(p+1):"",M=P.split(".").map(b=>Number.parseInt(b,10));return M.some(b=>!Number.isFinite(b))?[[Number.POSITIVE_INFINITY],f]:[M,C]},[m,u]=o(e),[R,S]=o(a);for(let f=0;f<Math.max(m.length,R.length);f++){let p=m[f]??0,P=R[f]??0;if(p!==P)return p-P}return u===S?0:u?S?u<S?-1:1:-1:1}import{spawn as G}from"node:child_process";import J from"node:crypto";import l from"node:fs";import w from"node:path";import{Readable as Y}from"node:stream";import{pipeline as q}from"node:stream/promises";var B=2;function j(e){function a(){try{let t=JSON.parse(l.readFileSync(e.configFile(),"utf8"));return t&&typeof t=="object"?t:{}}catch{return{}}}function o(t){let n=a();return(t||process.env[e.env.cdnOrigin]||n.cdnOrigin||e.defaultCdnOrigin).replace(/\/+$/,"")}function m(t){let n=a();return t||process.env[e.env.channel]||n.runtimeChannel||"stable"}function u(){let t=process.env[e.env.pin];if(t&&t.trim())return t.trim();let n=a();return typeof n.runtimeVersion=="string"&&n.runtimeVersion.trim()?n.runtimeVersion.trim():null}function R(t){let n=new URL(`${o(t)}${e.manifestPath}`);return n.searchParams.set("t",String(Date.now())),n.toString()}function S(t,n){return`${o(n)}${e.tarballPath(t)}`}async function f(t){let n=R(t),r=await fetch(n,{headers:{Accept:"application/json"}});if(!r.ok)throw new Error(`manifest fetch failed: ${r.status} ${r.statusText} (${n})`);return await r.json()}function p(t,n={}){let r=m(n.channel),i=n.version||u()||t.channels[r]?.latest;if(!i)throw new Error(`no version specified and channel '${r}' has no latest entry in the manifest`);let h=t.versions[i];if(!h)throw new Error(`version ${i} not found in manifest; available: ${Object.keys(t.versions).slice(-10).join(", ")||"(none)"}`);return{version:i,channel:r,entry:h}}async function P(t={}){e.ensureHome();let n=o(t.cdnOrigin),r=await f(n),{version:i,channel:h,entry:s}=p(r,t),d=e.runtimeDir(i),g=t.setActive!==!1;if(x({protectVersions:[i]}),!t.force&&l.existsSync(w.join(d,e.installedMarker)))return g&&e.writeActiveRuntime(i),x({protectVersions:[i]}),{version:i,channel:h,cdnOrigin:n,runtimeDir:d,installed:!1,activated:g,manifest:r};let I=s.tarball||S(i,n),v=w.join(e.cacheDir(),D(e,i));process.stderr.write(`${e.id}: downloading runtime ${i}\u2026
1
+ /*! sootsim v0.1.294 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
4
+ import{G as _,H as E,I as F,k as N,l as U,u as L,x as A}from"./chunk-WQL3BLFD.js";import W from"node:fs";import z from"node:path";function T(e){try{return W.readdirSync(e.runtimesDir(),{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name).sort(k)}catch{return[]}}function D(e,a){return z.posix.basename(e.tarballPath(a))}function k(e,a){let o=f=>{let p=f.indexOf("-"),P=p>=0?f.slice(0,p):f,C=p>=0?f.slice(p+1):"",M=P.split(".").map(b=>Number.parseInt(b,10));return M.some(b=>!Number.isFinite(b))?[[Number.POSITIVE_INFINITY],f]:[M,C]},[m,u]=o(e),[R,S]=o(a);for(let f=0;f<Math.max(m.length,R.length);f++){let p=m[f]??0,P=R[f]??0;if(p!==P)return p-P}return u===S?0:u?S?u<S?-1:1:-1:1}import{spawn as G}from"node:child_process";import J from"node:crypto";import l from"node:fs";import w from"node:path";import{Readable as Y}from"node:stream";import{pipeline as q}from"node:stream/promises";var B=2;function j(e){function a(){try{let t=JSON.parse(l.readFileSync(e.configFile(),"utf8"));return t&&typeof t=="object"?t:{}}catch{return{}}}function o(t){let n=a();return(t||process.env[e.env.cdnOrigin]||n.cdnOrigin||e.defaultCdnOrigin).replace(/\/+$/,"")}function m(t){let n=a();return t||process.env[e.env.channel]||n.runtimeChannel||"stable"}function u(){let t=process.env[e.env.pin];if(t&&t.trim())return t.trim();let n=a();return typeof n.runtimeVersion=="string"&&n.runtimeVersion.trim()?n.runtimeVersion.trim():null}function R(t){let n=new URL(`${o(t)}${e.manifestPath}`);return n.searchParams.set("t",String(Date.now())),n.toString()}function S(t,n){return`${o(n)}${e.tarballPath(t)}`}async function f(t){let n=R(t),r=await fetch(n,{headers:{Accept:"application/json"}});if(!r.ok)throw new Error(`manifest fetch failed: ${r.status} ${r.statusText} (${n})`);return await r.json()}function p(t,n={}){let r=m(n.channel),i=n.version||u()||t.channels[r]?.latest;if(!i)throw new Error(`no version specified and channel '${r}' has no latest entry in the manifest`);let h=t.versions[i];if(!h)throw new Error(`version ${i} not found in manifest; available: ${Object.keys(t.versions).slice(-10).join(", ")||"(none)"}`);return{version:i,channel:r,entry:h}}async function P(t={}){e.ensureHome();let n=o(t.cdnOrigin),r=await f(n),{version:i,channel:h,entry:s}=p(r,t),d=e.runtimeDir(i),g=t.setActive!==!1;if(x({protectVersions:[i]}),!t.force&&l.existsSync(w.join(d,e.installedMarker)))return g&&e.writeActiveRuntime(i),x({protectVersions:[i]}),{version:i,channel:h,cdnOrigin:n,runtimeDir:d,installed:!1,activated:g,manifest:r};let I=s.tarball||S(i,n),v=w.join(e.cacheDir(),D(e,i));process.stderr.write(`${e.id}: downloading runtime ${i}\u2026
3
5
  `),await K(I,v),process.stderr.write(`${e.id}: extracting runtime ${i}\u2026
4
6
  `);let O=w.join(w.dirname(d),`.installing-${i}-${process.pid}`);l.rmSync(O,{recursive:!0,force:!0});try{let y=await Q(v);if(y!==s.sha256)throw new Error(`sha256 mismatch for runtime ${i}: expected ${s.sha256}, actual ${y}`);if(l.mkdirSync(O,{recursive:!0}),await X(v,O),!l.existsSync(w.join(O,e.installedMarker)))throw new Error(`extracted tarball for runtime ${i} is missing ${e.installedMarker}`);l.rmSync(d,{recursive:!0,force:!0}),l.renameSync(O,d)}catch(y){throw l.rmSync(O,{recursive:!0,force:!0}),y}finally{l.rmSync(v,{force:!0})}return g&&e.writeActiveRuntime(i),x({protectVersions:[i]}),{version:i,channel:h,cdnOrigin:n,runtimeDir:d,installed:!0,activated:g,manifest:r}}async function C(t={}){e.ensureHome(),x();let n=o(t.cdnOrigin),r=m(t.channel),i=u();if(i){let V=e.readActiveRuntime(),c=l.existsSync(w.join(e.runtimeDir(i),e.installedMarker));if(V===i&&c)return{checked:!0,updated:!1,reason:`runtime is pinned to ${i}`,activeVersion:V,latestVersion:i};let $=await P({version:i,channel:r,cdnOrigin:n,setActive:!1});return{checked:!0,updated:!0,reason:`runtime is pinned to ${i}`,activeVersion:i,latestVersion:i,install:$}}let h=await f(n),s=h.channels[r]?.latest;if(!s)return{checked:!0,updated:!1,reason:`channel '${r}' has no latest runtime`,activeVersion:e.readActiveRuntime()};if(!h.versions[s])return{checked:!0,updated:!1,reason:`manifest is missing version ${s}`,activeVersion:e.readActiveRuntime(),latestVersion:s};let g=e.readActiveRuntime(),I=g?e.runtimeDir(g):null,v=I?l.existsSync(w.join(I,e.installedMarker)):!1;if(!(!g||!v||k(s,g)>0))return{checked:!0,updated:!1,reason:"active runtime is current",activeVersion:g,latestVersion:s};let y=await P({version:s,channel:r,cdnOrigin:n,setActive:!1});return{checked:!0,updated:!0,activeVersion:s,latestVersion:s,install:y}}async function M(t={}){let n=e.readActiveRuntime(),r=u();if(r)return{active:n,latest:r,pinned:r,outdated:n!==r};try{let i=await f(o(t.cdnOrigin)),h=m(t.channel),s=i.channels[h]?.latest??null,d=!!(s&&(!n||k(s,n)>0));return{active:n,latest:s,pinned:null,outdated:d}}catch{return{active:n,latest:null,pinned:null,outdated:!1}}}function b(t={}){e.ensureHome();let n=Math.max(1,Math.floor(t.retainVersions??B)),r=T(e),i=new Set(r),h=e.readActiveRuntime(),s=u(),d=new Set;for(let c of[h,s,...t.protectVersions??[]])c&&i.has(c)&&d.add(c);for(let c of[...r].reverse()){if(d.size>=n)break;d.add(c)}let g="__RUNTIME_VERSION__",I=D(e,g),v=I.indexOf(g),O=I.slice(0,v),y=I.slice(v+g.length),V=[];if(v>=0)try{V=l.readdirSync(e.cacheDir(),{withFileTypes:!0}).filter(c=>{if(!c.isFile())return!1;let $=c.name.startsWith(O)&&c.name.endsWith(y),H=c.name.startsWith(O)&&c.name.endsWith(`${y}.partial`);return $||H}).map(c=>w.join(e.cacheDir(),c.name)).sort()}catch{}return{activeVersion:h,pinnedVersion:s,keepVersions:r.filter(c=>d.has(c)),removeVersions:r.filter(c=>!d.has(c)),removeCacheFiles:V}}function x(t={}){let n=b(t);for(let r of n.removeVersions)l.rmSync(e.runtimeDir(r),{recursive:!0,force:!0});for(let r of n.removeCacheFiles)l.rmSync(r,{force:!0});return n}return{product:e,resolveCdnOrigin:o,resolveChannel:m,resolvePin:u,manifestUrl:R,tarballUrl:S,fetchManifest:f,resolveVersion:p,install:P,updateToLatest:C,checkUpToDate:M,planLocalRetention:b,pruneLocalRetention:x,listInstalled:()=>T(e)}}async function K(e,a){let o=await fetch(e);if(!o.ok||!o.body)throw new Error(`download failed: ${o.status} ${o.statusText} (${e})`);l.mkdirSync(w.dirname(a),{recursive:!0});let m=`${a}.partial`;try{await q(Y.fromWeb(o.body),l.createWriteStream(m)),l.renameSync(m,a)}catch(u){try{l.unlinkSync(m)}catch{}throw u}}function Q(e){return new Promise((a,o)=>{let m=J.createHash("sha256"),u=l.createReadStream(e);u.on("data",R=>m.update(R)),u.on("error",o),u.on("end",()=>a(m.digest("hex")))})}function X(e,a){return new Promise((o,m)=>{let u=G("tar",["-xzf",e,"-C",a],{stdio:["ignore","inherit","inherit"]});u.on("error",m),u.on("exit",R=>{R===0?o():m(new Error(`tar exited with code ${R}`))})})}var Z="https://contrast.dev",he="https://sootsim.com/changelog",ee={id:"sootsim",defaultCdnOrigin:Z,manifestPath:"/runtimes/manifest.json",tarballPath:e=>`/runtimes/sootsim-runtime-${e}.tar.gz`,installedMarker:"index.html",env:{cdnOrigin:"SOOTSIM_CDN_ORIGIN",channel:"SOOTSIM_RUNTIME_CHANNEL",pin:"SOOTSIM_RUNTIME_VERSION"},ensureHome:_,configFile:A,runtimesDir:N,runtimeDir:U,cacheDir:L,readActiveRuntime:E,writeActiveRuntime:F},Re=j(ee);export{k as a,Z as b,he as c,Re as d};
@@ -1,2 +1,4 @@
1
- /*! sootsim v0.1.293 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.294 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
2
4
  var g=Object.create;var e=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var m=(a=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(a,{get:(b,c)=>(typeof require<"u"?require:b)[c]}):a)(function(a){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});var n=(a,b)=>()=>(b||a((b={exports:{}}).exports,b),b.exports),o=(a,b)=>{for(var c in b)e(a,c,{get:b[c],enumerable:!0})},l=(a,b,c,f)=>{if(b&&typeof b=="object"||typeof b=="function")for(let d of i(b))!k.call(a,d)&&d!==c&&e(a,d,{get:()=>b[d],enumerable:!(f=h(b,d))||f.enumerable});return a};var p=(a,b,c)=>(c=a!=null?g(j(a)):{},l(b||!a||!a.__esModule?e(c,"default",{value:a,enumerable:!0}):c,a));export{m as a,n as b,o as c,p as d};
@@ -1,3 +1,5 @@
1
- /*! sootsim v0.1.293 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{k as n}from"./chunk-YNG4C3ZS.js";var i=[];for(let[t,e]of Object.entries(n))e.cliFlag&&i.push({name:`--${e.cliFlag}`,short:e.cliFlagShort?`-${e.cliFlagShort}`:void 0,key:t,type:e.type==="enum"?"string":e.type,description:e.description,options:e.options,default:e.default});var a=i;function g(){let t=[];for(let e of a){let s=e.short?`${e.short}, ${e.name}`:` ${e.name}`,o=e.options?` [${e.options.join("|")}]`:"",r=e.default!==void 0?` (default: ${e.default})`:"";t.push(` ${s.padEnd(24)}${e.description}${o}${r}`)}return t.join(`
1
+ /*! sootsim v0.1.294 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
4
+ import{k as n}from"./chunk-VXGCZUX4.js";var i=[];for(let[t,e]of Object.entries(n))e.cliFlag&&i.push({name:`--${e.cliFlag}`,short:e.cliFlagShort?`-${e.cliFlagShort}`:void 0,key:t,type:e.type==="enum"?"string":e.type,description:e.description,options:e.options,default:e.default});var a=i;function g(){let t=[];for(let e of a){let s=e.short?`${e.short}, ${e.name}`:` ${e.name}`,o=e.options?` [${e.options.join("|")}]`:"",r=e.default!==void 0?` (default: ${e.default})`:"";t.push(` ${s.padEnd(24)}${e.description}${o}${r}`)}return t.join(`
3
5
  `)}export{g as a};
@@ -0,0 +1,4 @@
1
+ /*! sootsim v0.1.294 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
4
+ var o=!0,e="public beta",t=e,n="we send anonymous error and dependency data while you use it";export{o as a,e as b,t as c,n as d};