sootsim 0.1.305 → 0.1.306

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 (171) hide show
  1. package/README.md +10 -4
  2. package/dist-cli/bin.js +5 -5
  3. package/dist-cli/chunks/{agent-OJP4VF2K.js → agent-43LRLQBS.js} +2 -2
  4. package/dist-cli/chunks/{agent-wrapper-HMVFZKH3.js → agent-wrapper-QYKQDC2Y.js} +2 -2
  5. package/dist-cli/chunks/{app-fonts-INFYQMIN.js → app-fonts-IHE34DCY.js} +2 -2
  6. package/dist-cli/chunks/{assert-YSFBCP5P.js → assert-LAXNLFZ6.js} +2 -2
  7. package/dist-cli/chunks/{auth-M7RKDYQV.js → auth-CFTFPYKX.js} +2 -2
  8. package/dist-cli/chunks/{beta-4NRMM37T.js → beta-YPZFX3DF.js} +2 -2
  9. package/dist-cli/chunks/{camera-MHLM35MB.js → camera-FHHHH6GY.js} +2 -2
  10. package/dist-cli/chunks/{chunk-LOF3WUKB.js → chunk-2UC72ZR6.js} +1 -1
  11. package/dist-cli/chunks/{chunk-SLCYXISJ.js → chunk-3XUXMKKJ.js} +2 -2
  12. package/dist-cli/chunks/{chunk-R6MBDR56.js → chunk-4735ZG3S.js} +1 -1
  13. package/dist-cli/chunks/{chunk-AJCL7DHI.js → chunk-4KABOHME.js} +2 -2
  14. package/dist-cli/chunks/chunk-4MLH5CMV.js +125 -0
  15. package/dist-cli/chunks/chunk-4TN4CD7M.js +15 -0
  16. package/dist-cli/chunks/{chunk-H5D6E3DR.js → chunk-4XGRVAXA.js} +2 -2
  17. package/dist-cli/chunks/{chunk-R5TBMYGH.js → chunk-6PIGQNS4.js} +1 -1
  18. package/dist-cli/chunks/{chunk-BDNZULU7.js → chunk-6SBFFSXO.js} +2 -2
  19. package/dist-cli/chunks/chunk-6SIWYEK5.js +4 -0
  20. package/dist-cli/chunks/{chunk-54AINFEF.js → chunk-6WCW6PES.js} +2 -2
  21. package/dist-cli/chunks/{chunk-EWVEUNRO.js → chunk-74Z7ENQL.js} +81 -37
  22. package/dist-cli/chunks/{chunk-TRV5K6D2.js → chunk-7RZYUZEK.js} +1 -1
  23. package/dist-cli/chunks/{chunk-J653UMCU.js → chunk-7VVWOKJE.js} +2 -2
  24. package/dist-cli/chunks/chunk-B3CXF3EF.js +5 -0
  25. package/dist-cli/chunks/{chunk-6EXIYEOQ.js → chunk-BPNVJLGT.js} +2 -2
  26. package/dist-cli/chunks/{chunk-4Q42Y64Y.js → chunk-C6TKPNCZ.js} +2 -2
  27. package/dist-cli/chunks/{chunk-HMOYEM6V.js → chunk-CLN6VD2I.js} +2 -2
  28. package/dist-cli/chunks/{chunk-XI6CPN53.js → chunk-FXC6BYKX.js} +1 -1
  29. package/dist-cli/chunks/{chunk-UUKUKTV3.js → chunk-G73JPCHX.js} +11 -11
  30. package/dist-cli/chunks/{chunk-3PREBGTH.js → chunk-HMW7QKJV.js} +2 -2
  31. package/dist-cli/chunks/{chunk-IJ64Z77P.js → chunk-HPCKCWSQ.js} +2 -2
  32. package/dist-cli/chunks/{chunk-WQYUHDBU.js → chunk-HTR4DSA5.js} +2 -2
  33. package/dist-cli/chunks/{chunk-HHLH4TWF.js → chunk-IGKZOI2V.js} +1 -1
  34. package/dist-cli/chunks/{chunk-POIK3AHY.js → chunk-IXPUTLYO.js} +2 -2
  35. package/dist-cli/chunks/{chunk-2D7NF3XK.js → chunk-JPQSUHXW.js} +2 -2
  36. package/dist-cli/chunks/chunk-KNPXTXMI.js +4 -0
  37. package/dist-cli/chunks/{chunk-JQRRJIMT.js → chunk-LHCC656T.js} +1 -1
  38. package/dist-cli/chunks/{chunk-SWBTXTEO.js → chunk-LOXCEKKF.js} +2 -2
  39. package/dist-cli/chunks/{chunk-2UKSI3VX.js → chunk-MBF4LLVB.js} +1 -1
  40. package/dist-cli/chunks/{chunk-NNR3BU5O.js → chunk-MCGRZYAP.js} +7 -7
  41. package/dist-cli/chunks/chunk-NH2KYSY7.js +4 -0
  42. package/dist-cli/chunks/{chunk-KSZRLJPA.js → chunk-NOLQ4UEP.js} +2 -2
  43. package/dist-cli/chunks/chunk-NQ56D5JF.js +4 -0
  44. package/dist-cli/chunks/{chunk-KG2WUKD2.js → chunk-OYFRTYRJ.js} +2 -2
  45. package/dist-cli/chunks/{chunk-6YE25EJB.js → chunk-QHGQTHHD.js} +3 -3
  46. package/dist-cli/chunks/{chunk-HKPJYMJC.js → chunk-RYXC27XV.js} +15 -12
  47. package/dist-cli/chunks/{chunk-CWDEDUOZ.js → chunk-TCB56ABT.js} +1 -1
  48. package/dist-cli/chunks/{chunk-QVH276LI.js → chunk-TR4FKAKQ.js} +1 -1
  49. package/dist-cli/chunks/{chunk-JKIPNRAK.js → chunk-U6NDLMBM.js} +24 -25
  50. package/dist-cli/chunks/{chunk-VKBCGFOU.js → chunk-UAYFVJ7N.js} +2 -2
  51. package/dist-cli/chunks/{chunk-W3M4676V.js → chunk-UBLLWSSF.js} +3 -3
  52. package/dist-cli/chunks/{chunk-KVLXMWV5.js → chunk-UTE2W4WC.js} +2 -2
  53. package/dist-cli/chunks/{chunk-DTHOMSAA.js → chunk-UTHRVXG5.js} +2 -2
  54. package/dist-cli/chunks/{chunk-EPZG2F4I.js → chunk-V5PJXD2O.js} +1 -1
  55. package/dist-cli/chunks/{chunk-43SNLCXR.js → chunk-VLKENZFJ.js} +1 -1
  56. package/dist-cli/chunks/{chunk-EBCXFB3K.js → chunk-VTPICQDM.js} +1 -1
  57. package/dist-cli/chunks/{chunk-B65RMI7A.js → chunk-XZSXFV33.js} +1 -1
  58. package/dist-cli/chunks/chunk-YBO7SFWN.js +6 -0
  59. package/dist-cli/chunks/{chunk-DHDSGBZB.js → chunk-YVWYARHY.js} +1 -1
  60. package/dist-cli/chunks/{cleanup-ZJ7FQKED.js → cleanup-GYDCGNEJ.js} +2 -2
  61. package/dist-cli/chunks/{cli-version-5LGCFOAC.js → cli-version-3HG7ILRV.js} +2 -2
  62. package/dist-cli/chunks/{compat-EQACACVP.js → compat-GS3SVTB4.js} +2 -2
  63. package/dist-cli/chunks/{config-ADGNCDG5.js → config-W5LN7HWO.js} +2 -2
  64. package/dist-cli/chunks/control-BE55SA2W.js +4 -0
  65. package/dist-cli/chunks/daemon-3YMH272E.js +4 -0
  66. package/dist-cli/chunks/{debug-PU73W33T.js → debug-2BBR66MJ.js} +3 -3
  67. package/dist-cli/chunks/desktop-PPB66SZO.js +31 -0
  68. package/dist-cli/chunks/{detox-SHVVEPPX.js → detox-P7SDHLB4.js} +2 -2
  69. package/dist-cli/chunks/{device-NMRUACB4.js → device-JB4NSOZV.js} +2 -2
  70. package/dist-cli/chunks/{diagnose-S2AVGABT.js → diagnose-M662DIPM.js} +2 -2
  71. package/dist-cli/chunks/disk-cleanup-HN662P2U.js +4 -0
  72. package/dist-cli/chunks/drivers-ALHRJJGF.js +4 -0
  73. package/dist-cli/chunks/{film-UB7N4EKB.js → film-QZMDVCZI.js} +3 -3
  74. package/dist-cli/chunks/flow-BHSACBQ5.js +4 -0
  75. package/dist-cli/chunks/help-V2KS2AUT.js +4 -0
  76. package/dist-cli/chunks/{hidden-runtime-alias-M44SGZLM.js → hidden-runtime-alias-LJXH6WPY.js} +2 -2
  77. package/dist-cli/chunks/{home-paths-ZTEBHBUO.js → home-paths-TQ53NFW3.js} +2 -2
  78. package/dist-cli/chunks/inspect-6PW37GVK.js +4 -0
  79. package/dist-cli/chunks/install-desktop-VMVPZSXF.js +4 -0
  80. package/dist-cli/chunks/{login-YQ3HRPPS.js → login-7XXY5JP4.js} +4 -4
  81. package/dist-cli/chunks/{logout-XGBDWO4J.js → logout-UNARNKTJ.js} +2 -2
  82. package/dist-cli/chunks/{maestro-CESBE2SF.js → maestro-66RNLMLU.js} +3 -3
  83. package/dist-cli/chunks/{maestro-generate-4IHISKJL.js → maestro-generate-IO25AY3E.js} +3 -3
  84. package/dist-cli/chunks/{mode-BQGGZ737.js → mode-DPGASAG4.js} +2 -2
  85. package/dist-cli/chunks/optional-demo-registry-O5GGFNAI.js +4 -0
  86. package/dist-cli/chunks/{perf-TUR22UTE.js → perf-CBUP2ERS.js} +2 -2
  87. package/dist-cli/chunks/{permissions-POJIVSRV.js → permissions-3AOMCAT3.js} +2 -2
  88. package/dist-cli/chunks/{record-Q55SGXLU.js → record-Q7VRLH7A.js} +3 -3
  89. package/dist-cli/chunks/{report-issue-LRRX7VJV.js → report-issue-DTWZECYM.js} +2 -2
  90. package/dist-cli/chunks/runtime-VGYKLLTE.js +4 -0
  91. package/dist-cli/chunks/{screenshot-command-C7EU43J3.js → screenshot-command-SSWKZ4U3.js} +3 -3
  92. package/dist-cli/chunks/{screenshot-layers-NYVOJYUU.js → screenshot-layers-2ABSTF2O.js} +2 -2
  93. package/dist-cli/chunks/{screenshots-capture-AYKJKBLR.js → screenshots-capture-QA7T5DED.js} +2 -2
  94. package/dist-cli/chunks/{serve-EN3ZPJSA.js → serve-T4EQBJM6.js} +3 -3
  95. package/dist-cli/chunks/{setup-KKMKLJZE.js → setup-BXQI3YT4.js} +2 -2
  96. package/dist-cli/chunks/{skills-DR5DG2SK.js → skills-AYSO5FJB.js} +2 -2
  97. package/dist-cli/chunks/{storage-GMDBVTQ5.js → storage-KBHG5M5F.js} +2 -2
  98. package/dist-cli/chunks/store-GUNEQ4EC.js +4 -0
  99. package/dist-cli/chunks/telemetry-4VZ43AHH.js +4 -0
  100. package/dist-cli/chunks/{timeline-VY3444AZ.js → timeline-AB2R26RE.js} +2 -2
  101. package/dist-cli/chunks/{upgrade-EUYCW55F.js → upgrade-5XXQ7OCE.js} +2 -2
  102. package/dist-cli/chunks/upload-M55IQQHQ.js +4 -0
  103. package/dist-cli/chunks/{version-TEGM4WRU.js → version-PH3OUNPP.js} +2 -2
  104. package/dist-cli/chunks/{web-QF7LF4VB.js → web-XTOGNFZ7.js} +2 -2
  105. package/dist-cli/chunks/{what-happened-HDTJGNND.js → what-happened-JLI3NTEU.js} +2 -2
  106. package/dist-lib/agent-daemon-client.cjs +1 -1
  107. package/dist-lib/agent-events.cjs +1 -1
  108. package/dist-lib/agent-identity.cjs +1 -1
  109. package/dist-lib/agent-sessions.cjs +1 -1
  110. package/dist-lib/attached-projects.cjs +43 -21
  111. package/dist-lib/auth/shared-session.cjs +1 -1
  112. package/dist-lib/backend-origin.cjs +1 -1
  113. package/dist-lib/beta.cjs +1 -1
  114. package/dist-lib/beta.mjs +1 -1
  115. package/dist-lib/bridge-constants.cjs +8 -1
  116. package/dist-lib/cli-constants.cjs +1 -1
  117. package/dist-lib/config.cjs +1 -1
  118. package/dist-lib/detox/index.cjs +1 -1
  119. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  120. package/dist-lib/home-paths.cjs +1 -1
  121. package/dist-lib/host/bridge-host.cjs +222 -302
  122. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  123. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  124. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  125. package/dist-lib/host/websocket-proxy.cjs +1 -1
  126. package/dist-lib/index.cjs +1 -1
  127. package/dist-lib/jump-to-source-babel.cjs +1 -1
  128. package/dist-lib/menu.cjs +1 -1
  129. package/dist-lib/menu.mjs +1 -1
  130. package/dist-lib/metro.cjs +1 -1
  131. package/dist-lib/profiles.cjs +1 -1
  132. package/dist-lib/render-mode.cjs +1 -1
  133. package/dist-lib/scripts/dev-server-scanner.cjs +43 -13
  134. package/dist-lib/sdk.cjs +47 -10
  135. package/dist-lib/sdk.mjs +47 -10
  136. package/dist-lib/skills.cjs +5708 -1217
  137. package/dist-lib/vite.cjs +1 -1
  138. package/package.json +1 -1
  139. package/scripts/dev-server-scanner.ts +9 -15
  140. package/scripts/optional-demo-registry.ts +52 -10
  141. package/skills/sootsim-debug/SKILL.md +4 -5
  142. package/skills/sootsim-setup/SKILL.md +29 -49
  143. package/src/bridge-constants.ts +15 -0
  144. package/src/host/bridge-host.ts +0 -16
  145. package/src/host/open-url.ts +2 -147
  146. package/src/plist.ts +27 -0
  147. package/src/settings-bundle.ts +2 -23
  148. package/src/skills/builtin/maestro-test.ts +4 -1
  149. package/src/vite-plugin.ts +2 -1
  150. package/dist-cli/chunks/chunk-COD6QGS2.js +0 -125
  151. package/dist-cli/chunks/chunk-KVOY4Z2X.js +0 -4
  152. package/dist-cli/chunks/chunk-OCRL2VU4.js +0 -4
  153. package/dist-cli/chunks/chunk-PELXRGDN.js +0 -4
  154. package/dist-cli/chunks/chunk-QJUKXBH5.js +0 -15
  155. package/dist-cli/chunks/chunk-WIRBJTTU.js +0 -7
  156. package/dist-cli/chunks/chunk-XWMTLVCE.js +0 -4
  157. package/dist-cli/chunks/chunk-ZRQFYMTL.js +0 -4
  158. package/dist-cli/chunks/control-Y3E5IIMO.js +0 -4
  159. package/dist-cli/chunks/daemon-A6CWUYMR.js +0 -4
  160. package/dist-cli/chunks/desktop-V675PYF4.js +0 -34
  161. package/dist-cli/chunks/disk-cleanup-EJEZIIT4.js +0 -4
  162. package/dist-cli/chunks/drivers-PM4PVYHY.js +0 -4
  163. package/dist-cli/chunks/flow-XJRNL25V.js +0 -4
  164. package/dist-cli/chunks/help-2ZJHCVUZ.js +0 -4
  165. package/dist-cli/chunks/inspect-L76RUF62.js +0 -4
  166. package/dist-cli/chunks/install-desktop-UIXKNXKF.js +0 -4
  167. package/dist-cli/chunks/optional-demo-registry-LWYRXVIE.js +0 -4
  168. package/dist-cli/chunks/runtime-NHDHZJJN.js +0 -4
  169. package/dist-cli/chunks/store-QZEMKQDC.js +0 -4
  170. package/dist-cli/chunks/telemetry-TNX72J2B.js +0 -4
  171. package/dist-cli/chunks/upload-D43U7RGT.js +0 -4
@@ -1,7 +1,7 @@
1
- /*! sootsim v0.1.305 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.306 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
- import{a as K,b as V,c as Ne}from"./chunk-WQYUHDBU.js";import{c as Fe}from"./chunk-PELXRGDN.js";import{k as $e}from"./chunk-UUKUKTV3.js";import{d as Oe}from"./chunk-ZRQFYMTL.js";import{h as _e,j as Pe,l as B}from"./chunk-NNR3BU5O.js";import{c as Ue,d as E}from"./chunk-3PREBGTH.js";import{a as Ae}from"./chunk-KVLXMWV5.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(`
4
+ import{a as K,b as V,c as Ne}from"./chunk-HTR4DSA5.js";import{c as Fe,d as Oe}from"./chunk-6SIWYEK5.js";import{k as $e}from"./chunk-G73JPCHX.js";import{h as _e,j as Pe,l as B}from"./chunk-MCGRZYAP.js";import{c as Ue,d as E}from"./chunk-HMW7QKJV.js";import{a as Ae}from"./chunk-UTE2W4WC.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(`
5
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(`
6
6
  sootsim record upload \u2014 publish the current recorded bundle as a /preview/<id> link
7
7
 
@@ -0,0 +1,4 @@
1
+ /*! sootsim v0.1.306 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
4
+ import{existsSync as s}from"node:fs";import{basename as a,dirname as p,join as l}from"node:path";import{fileURLToPath as m,pathToFileURL as c}from"node:url";var u="packages/sootsim/scripts/demo-app-registry.ts",f=8;function A(o){let r=o;for(let e=0;e<f;e++){if(a(r)==="node_modules")return null;let n=l(r,u);if(s(n))return n;let i=p(r);if(i===r)return null;r=i}return null}var t=null;async function S(){if(t)return t;let o=A(p(m(import.meta.url)));if(!o)return t=[],t;try{let r=await import(c(o).href);t=Array.isArray(r.APPS)?r.APPS:[]}catch{t=[]}return t}function D(){return t??[]}function O(o){let r=t;return t=o,{restore:()=>{t=r}}}export{A as a,S as b,D as c,O as d};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.305 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.306 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
- import{l as n}from"./chunk-6EXIYEOQ.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(`
4
+ import{l as n}from"./chunk-BPNVJLGT.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(`
5
5
  `)}export{g as a};
@@ -1,7 +1,7 @@
1
- /*! sootsim v0.1.305 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.306 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
- import{a as x}from"./chunk-2UKSI3VX.js";import{a as k}from"./chunk-43SNLCXR.js";import{spawn as v,spawnSync as u}from"child_process";import{chmodSync as S,copyFileSync as T,createWriteStream as E,existsSync as w,mkdirSync as y,rmSync as g,statSync as P,unlinkSync as D}from"fs";import{tmpdir as M}from"os";import{dirname as A,join as f,resolve as b}from"path";var h="https://contrast.dev/api/electron-release";function O(){let r=process.arch;if(process.platform==="darwin"){let o=r==="arm64"?"mac-arm64":"mac-x64",e=`sootsim-latest-${o}.dmg`;return{platform:o,filename:e,url:`${h}/${e}`,install:L}}if(process.platform==="linux"){let o=r==="arm64"?"linux-arm64":"linux-x64",e=`sootsim-latest-${o}.AppImage`;return{platform:o,filename:e,url:`${h}/${e}`,install:C}}if(process.platform==="win32"){let o="sootsim-latest-win-x64.exe";return{platform:"win-x64",filename:o,url:`${h}/${o}`,install:B}}return null}async function I({url:r,dest:o,onProgress:e}){let s=await fetch(r,{redirect:"follow"});if(!s.ok)throw new Error(`${s.status} ${s.statusText} (${r})`);let t=s.headers.get("content-length"),a=t?Number(t):null;if(!s.body)throw new Error(`empty response body (${r})`);y(A(o),{recursive:!0});let i=E(o),d=s.body.getReader(),c=0;try{for(;;){let{done:l,value:p}=await d.read();if(l)break;i.write(Buffer.from(p)),c+=p.byteLength,e?.(c,a)}}finally{await new Promise((l,p)=>{i.end(n=>n?p(n):l())})}}function _(r,o){let e=(r/1048576).toFixed(1);if(!o)return` ${e} MB`;let s=Math.min(100,Math.round(r/o*100)),t=(o/(1024*1024)).toFixed(1),a=24,i=Math.round(s/100*a);return` ${"\u2588".repeat(i)+"\u2591".repeat(a-i)} ${s}% ${e} / ${t} MB`}async function L(r){let o=u("hdiutil",["attach","-nobrowse","-readonly",r],{encoding:"utf8"});if(o.status!==0)throw new Error(`hdiutil attach failed: ${o.stderr||o.stdout}`.trim());let e=o.stdout.trim().split(`
4
+ import{a as x}from"./chunk-MBF4LLVB.js";import{a as k}from"./chunk-VLKENZFJ.js";import{spawn as v,spawnSync as u}from"child_process";import{chmodSync as S,copyFileSync as T,createWriteStream as E,existsSync as w,mkdirSync as y,rmSync as g,statSync as P,unlinkSync as D}from"fs";import{tmpdir as M}from"os";import{dirname as A,join as f,resolve as b}from"path";var h="https://contrast.dev/api/electron-release";function O(){let r=process.arch;if(process.platform==="darwin"){let o=r==="arm64"?"mac-arm64":"mac-x64",e=`sootsim-latest-${o}.dmg`;return{platform:o,filename:e,url:`${h}/${e}`,install:L}}if(process.platform==="linux"){let o=r==="arm64"?"linux-arm64":"linux-x64",e=`sootsim-latest-${o}.AppImage`;return{platform:o,filename:e,url:`${h}/${e}`,install:C}}if(process.platform==="win32"){let o="sootsim-latest-win-x64.exe";return{platform:"win-x64",filename:o,url:`${h}/${o}`,install:B}}return null}async function I({url:r,dest:o,onProgress:e}){let s=await fetch(r,{redirect:"follow"});if(!s.ok)throw new Error(`${s.status} ${s.statusText} (${r})`);let t=s.headers.get("content-length"),a=t?Number(t):null;if(!s.body)throw new Error(`empty response body (${r})`);y(A(o),{recursive:!0});let i=E(o),d=s.body.getReader(),c=0;try{for(;;){let{done:l,value:p}=await d.read();if(l)break;i.write(Buffer.from(p)),c+=p.byteLength,e?.(c,a)}}finally{await new Promise((l,p)=>{i.end(n=>n?p(n):l())})}}function _(r,o){let e=(r/1048576).toFixed(1);if(!o)return` ${e} MB`;let s=Math.min(100,Math.round(r/o*100)),t=(o/(1024*1024)).toFixed(1),a=24,i=Math.round(s/100*a);return` ${"\u2588".repeat(i)+"\u2591".repeat(a-i)} ${s}% ${e} / ${t} MB`}async function L(r){let o=u("hdiutil",["attach","-nobrowse","-readonly",r],{encoding:"utf8"});if(o.status!==0)throw new Error(`hdiutil attach failed: ${o.stderr||o.stdout}`.trim());let e=o.stdout.trim().split(`
5
5
  `),t=e[e.length-1].split(" ").pop()?.trim();if(!t||!w(t))throw new Error(`could not determine dmg mount point (output: ${o.stdout})`);let a=f(t,"sootsim.app");if(!w(a))throw u("hdiutil",["detach","-force",t]),new Error(`sootsim.app not found inside ${t}`);let i="/Applications",d=b(process.env.HOME||"","Applications"),c=i;try{let m=f(i,`.sootsim-write-probe-${process.pid}`);u("touch",[m]),w(m)?g(m,{force:!0}):c=d}catch{c=d}c===d&&y(c,{recursive:!0});let l=f(c,"sootsim.app");w(l)&&g(l,{recursive:!0,force:!0});let p=u("cp",["-R",a,l]),n=u("hdiutil",["detach","-force",t]);if(p.status!==0)throw new Error(`copy to ${l} failed: ${p.stderr?.toString()||""}`.trim());return n.status!==0&&console.warn(` warning: failed to unmount ${t} (${n.stderr?.toString().trim()||"unknown error"})`),u("xattr",["-dr","com.apple.quarantine",l]),l}async function C(r){let o=b(process.env.HOME||"","Applications");y(o,{recursive:!0});let e=f(o,"sootsim.AppImage");return w(e)&&g(e,{force:!0}),T(r,e),D(r),S(e,493),e}async function B(r){return await new Promise((o,e)=>{let s=v("cmd",["/c","start",'""',"/wait",r],{stdio:"inherit"});s.once("error",e),s.once("exit",t=>{t===0?o():e(new Error(`installer exited with code ${t}`))})}),r}async function q(r){(r.includes("--help")||r.includes("-h"))&&(console.log(`
6
6
  sootsim desktop install \u2014 download and install the optional desktop GUI
7
7
 
@@ -22,4 +22,4 @@ examples:
22
22
  `),process.exit(0));let o=r.includes("--yes")||r.includes("-y")||process.env.SOOTSIM_NO_PROMPT==="1"||process.env.CI==="1"||!process.stdin.isTTY,e=r.includes("--force"),s=k();if(s&&!e){console.log(` sootsim desktop already installed at: ${s.path}`),console.log(" pass --force to reinstall.");return}let t=O();if(t||(console.error(` no desktop build available for ${process.platform}/${process.arch}.`),console.error(" supported: darwin-arm64, darwin-x64, linux-x64, linux-arm64, win32-x64"),process.exit(1)),console.log(` platform: ${t.platform}`),console.log(` download: ${t.url}`),console.log(),!o){if(!await x("download and install now?",!0)){console.log(" cancelled.");return}console.log()}let a=f(M(),`sootsim-install-${Date.now()}`),i=f(a,t.filename),d=0;process.stdout.write(` downloading ${t.filename}...
23
23
  `);try{await I({url:t.url,dest:i,onProgress:(n,m)=>{let $=Date.now();$-d<100&&n<(m??1/0)||(d=$,process.stdout.isTTY&&process.stdout.write(`\r\x1B[2K${_(n,m)}`))}})}catch(n){g(a,{recursive:!0,force:!0});let m=n instanceof Error?n.message:String(n);console.error(`
24
24
  download failed: ${m}`),console.error(` the ${t.platform} desktop build may not be published yet, or your`),console.error(" network blocked the request. check your connection and try again later;"),console.error(" the CLI + daemon work without the desktop app (run: sootsim --help)."),process.exit(1)}process.stdout.isTTY&&process.stdout.write(`
25
- `);let c=P(i).size;console.log(` downloaded ${(c/(1024*1024)).toFixed(1)} MB`),console.log(),console.log(" installing...");let{trackCliEvent:l,flushCliTelemetry:p}=await import("./telemetry-TNX72J2B.js");try{let n=await t.install(i);l({event:"cli_install_desktop_succeeded",properties:{platform:t.platform,size_bytes:c}}),console.log(` installed: ${n}`)}catch(n){l({event:"cli_install_desktop_failed",properties:{platform:t.platform,error:n instanceof Error?n.message:String(n)}}),await p(),console.error(` install failed: ${n instanceof Error?n.message:String(n)}`),console.error(` keeping download at ${i} for manual install.`),process.exit(1)}finally{g(a,{recursive:!0,force:!0})}console.log(),console.log(" next steps:"),console.log(" sootsim desktop launch the desktop app"),console.log(" sootsim open <target> open a demo or bundle in it")}export{q as a};
25
+ `);let c=P(i).size;console.log(` downloaded ${(c/(1024*1024)).toFixed(1)} MB`),console.log(),console.log(" installing...");let{trackCliEvent:l,flushCliTelemetry:p}=await import("./telemetry-4VZ43AHH.js");try{let n=await t.install(i);l({event:"cli_install_desktop_succeeded",properties:{platform:t.platform,size_bytes:c}}),console.log(` installed: ${n}`)}catch(n){l({event:"cli_install_desktop_failed",properties:{platform:t.platform,error:n instanceof Error?n.message:String(n)}}),await p(),console.error(` install failed: ${n instanceof Error?n.message:String(n)}`),console.error(` keeping download at ${i} for manual install.`),process.exit(1)}finally{g(a,{recursive:!0,force:!0})}console.log(),console.log(" next steps:"),console.log(" sootsim desktop launch the desktop app"),console.log(" sootsim open <target> open a demo or bundle in it")}export{q as a};
@@ -1,8 +1,8 @@
1
- /*! sootsim v0.1.305 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.306 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
- import{a as m,b as T}from"./chunk-43SNLCXR.js";import{a as w,b as A,c as C}from"./chunk-ZRQFYMTL.js";import{a as I}from"./chunk-XI6CPN53.js";import{a as _,d as E}from"./chunk-WIRBJTTU.js";import{G as O,o as x,q as f}from"./chunk-EBCXFB3K.js";import h from"fs";import v from"path";var c="default",j="profiles.json",a=1;function s(e){let r=e.trim();if(!r)throw new Error("profile id is required");if(!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(r))throw new Error("profile ids must start with a letter or number and contain only letters, numbers, dot, dash, or underscore");if(r==="."||r==="..")throw new Error(`invalid profile id: ${r}`);return r}function g(){return v.join(f(),j)}function H(e){return`sootsim-profile-${s(e)}`}function z(e){return v.join(x(),"Partitions",H(e))}function y(e){return v.join(f(),"playwright",s(e))}function b(){try{let e=JSON.parse(h.readFileSync(g(),"utf8"));if(!e||e.version!==a)return{version:a,profiles:[]};let r=Array.isArray(e.profiles)?e.profiles.filter(t=>!!t&&typeof t.id=="string"&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string").map(t=>({id:s(t.id),createdAt:t.createdAt,updatedAt:t.updatedAt})):[];return{version:a,profiles:r}}catch{return{version:a,profiles:[]}}}function M(e){return[...e].sort((r,t)=>r.id===c?-1:t.id===c?1:r.id.localeCompare(t.id))}function P(e){if(e.profiles.some(t=>t.id===c))return{...e,profiles:M(e.profiles)};let r=new Date().toISOString();return{version:a,profiles:M([{id:c,createdAt:r,updatedAt:r},...e.profiles])}}function S(e){O();let r=P(e),t=`${g()}.tmp`;return h.writeFileSync(t,`${JSON.stringify(r,null,2)}
5
- `,"utf8"),h.renameSync(t,g()),r}function K(){return S(b()).profiles}function Y(e){let r=s(e);return K().find(t=>t.id===r)??null}function L(e=c){let r=s(e),t=Y(r);return t||V(r)}function V(e){let r=s(e),t=P(b());if(t.profiles.some(i=>i.id===r))throw new Error(`profile already exists: ${r}`);let o=new Date().toISOString(),n={id:r,createdAt:o,updatedAt:o};return S({version:a,profiles:[...t.profiles,n]}),n}function ge(e){let r=s(e);if(r===c)throw new Error("the default profile cannot be deleted; clear it instead");let t=P(b()),o=t.profiles.find(n=>n.id===r);if(!o)throw new Error(`profile not found: ${r}`);return S({version:a,profiles:t.profiles.filter(n=>n.id!==r)}),J(r),o}function J(e){let r=s(e);for(let t of[z(r),y(r)])try{h.rmSync(t,{recursive:!0,force:!0})}catch{}}function X(){let e=w();return e?{available:!0,reason:null,detail:e}:{available:!1,reason:"no chromium-family browser found (chrome, chromium, edge, brave, arc)"}}async function Z(e){if(e.headless)return{launched:!1,message:"the chromium driver launches a visible browser window and cannot run headless \u2014 a headless `chrome --headless=new` process exits immediately and the sim never connects. for headless automation use `--driver playwright`."};let r=w();if(!r)return{launched:!1,message:"chromium not found \u2014 install chrome or run `sootsim list --drivers`"};if(!e.url)return{launched:!1,message:"chromium driver requires a target url"};if(e.profileId||e.ephemeralProfile)return{launched:!1,message:"profiles require electron or playwright; browser tabs use your current Chrome profile"};try{let t=await C(e.url,{detached:e.detached??!0});return{launched:!0,message:`chromium launched \u2192 ${e.url}`,pid:t.pid,target:t.target??r,attachUrl:e.url}}catch(t){return{launched:!1,message:`chromium spawn failed: ${t instanceof Error?t.message:String(t)}`}}}var R={id:"chromium",name:"chromium",description:"system chrome / chromium / edge \u2014 visible window (headless: use playwright)",kind:"browser",availability:X,launch:Z};function Q(){let e=m();return e?{available:!0,reason:null,detail:`${e.kind} @ ${e.path}`}:{available:!1,reason:"sootsim desktop app not installed (run `sootsim desktop install`)"}}async function ee(e){let r=m();if(!r)return{launched:!1,message:"sootsim desktop app not installed"};try{let t=await T(e.url,r,{device:e.device,profileId:e.profileId,ephemeralProfile:e.ephemeralProfile,ownerPid:e.ownerPid});return t.launched?{launched:!0,message:e.url?`electron launched via ${t.via} \u2192 ${e.url}`:`electron launched via ${t.via}`,target:t.target,attachUrl:e.url}:{launched:!1,message:"desktop companion failed to start"}}catch(t){return{launched:!1,message:`electron launch failed: ${t instanceof Error?t.message:String(t)}`}}}var W={id:"electron",name:"electron",description:"sootsim desktop companion app (native window, menu bar)",kind:"native",availability:Q,launch:ee};import{spawn as re}from"child_process";import{closeSync as te,mkdtempSync as oe,openSync as ie,readFileSync as ne}from"fs";import{createRequire as se}from"module";import{tmpdir as N}from"os";import{join as $}from"path";var ae=`
4
+ import{a as m,b as I}from"./chunk-VLKENZFJ.js";import{a as D}from"./chunk-FXC6BYKX.js";import{b as _}from"./chunk-YBO7SFWN.js";import{G as O,o as x,q as f}from"./chunk-VTPICQDM.js";import p from"fs";import g from"path";var c="default",F="profiles.json",a=1;function n(e){let r=e.trim();if(!r)throw new Error("profile id is required");if(!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(r))throw new Error("profile ids must start with a letter or number and contain only letters, numbers, dot, dash, or underscore");if(r==="."||r==="..")throw new Error(`invalid profile id: ${r}`);return r}function w(){return g.join(f(),F)}function $(e){return`sootsim-profile-${n(e)}`}function G(e){return g.join(x(),"Partitions",$(e))}function v(e){return g.join(f(),"playwright",n(e))}function b(){try{let e=JSON.parse(p.readFileSync(w(),"utf8"));if(!e||e.version!==a)return{version:a,profiles:[]};let r=Array.isArray(e.profiles)?e.profiles.filter(t=>!!t&&typeof t.id=="string"&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string").map(t=>({id:n(t.id),createdAt:t.createdAt,updatedAt:t.updatedAt})):[];return{version:a,profiles:r}}catch{return{version:a,profiles:[]}}}function E(e){return[...e].sort((r,t)=>r.id===c?-1:t.id===c?1:r.id.localeCompare(t.id))}function y(e){if(e.profiles.some(t=>t.id===c))return{...e,profiles:E(e.profiles)};let r=new Date().toISOString();return{version:a,profiles:E([{id:c,createdAt:r,updatedAt:r},...e.profiles])}}function P(e){O();let r=y(e),t=`${w()}.tmp`;return p.writeFileSync(t,`${JSON.stringify(r,null,2)}
5
+ `,"utf8"),p.renameSync(t,w()),r}function U(){return P(b()).profiles}function B(e){let r=n(e);return U().find(t=>t.id===r)??null}function T(e=c){let r=n(e),t=B(r);return t||j(r)}function j(e){let r=n(e),t=y(b());if(t.profiles.some(u=>u.id===r))throw new Error(`profile already exists: ${r}`);let o=new Date().toISOString(),i={id:r,createdAt:o,updatedAt:o};return P({version:a,profiles:[...t.profiles,i]}),i}function ae(e){let r=n(e);if(r===c)throw new Error("the default profile cannot be deleted; clear it instead");let t=y(b()),o=t.profiles.find(i=>i.id===r);if(!o)throw new Error(`profile not found: ${r}`);return P({version:a,profiles:t.profiles.filter(i=>i.id!==r)}),q(r),o}function q(e){let r=n(e);for(let t of[G(r),v(r)])try{p.rmSync(t,{recursive:!0,force:!0})}catch{}}function H(){let e=m();return e?{available:!0,reason:null,detail:`${e.kind} @ ${e.path}`}:{available:!1,reason:"sootsim desktop app not installed (run `sootsim desktop install`)"}}async function z(e){let r=m();if(!r)return{launched:!1,message:"sootsim desktop app not installed"};try{let t=await I(e.url,r,{device:e.device,profileId:e.profileId,ephemeralProfile:e.ephemeralProfile,ownerPid:e.ownerPid});return t.launched?{launched:!0,message:e.url?`electron launched via ${t.via} \u2192 ${e.url}`:`electron launched via ${t.via}`,target:t.target,attachUrl:e.url}:{launched:!1,message:"desktop companion failed to start"}}catch(t){return{launched:!1,message:`electron launch failed: ${t instanceof Error?t.message:String(t)}`}}}var C={id:"electron",name:"electron",description:"sootsim desktop companion app (native window, menu bar)",kind:"native",availability:H,launch:z};import{spawn as K}from"child_process";import{closeSync as Y,mkdtempSync as V,openSync as J,readFileSync as X}from"fs";import{createRequire as Z}from"module";import{tmpdir as A}from"os";import{join as M}from"path";var Q=`
6
6
  const modulePath = process.env.SOOTSIM_PW_MODULE;
7
7
  const url = process.env.SOOTSIM_PW_URL;
8
8
  // the WS bridge port the sim page must register with, injected below as
@@ -12,9 +12,10 @@ const bridgePort = process.env.SOOTSIM_PW_BRIDGE_PORT || '';
12
12
  const headless = process.env.SOOTSIM_PW_HEADLESS === '1';
13
13
  const callerUserDataDir = process.env.SOOTSIM_PW_USERDATADIR || '';
14
14
  // pid of the session that launched us (its topmost non-init ancestor). when
15
- // that process exits we tear Chrome down \u2014 see startOwnerWatch below. 0/unset
16
- // disables the watchdog. SOOTSIM_PW_OWNER_POLL_MS is a test-only override of
17
- // the 5s poll interval; production never sets it.
15
+ // that process exits we tear Chrome down \u2014 see startOwnerWatch below. it is a
16
+ // required lifetime bound: an invalid value aborts before Chrome launches.
17
+ // SOOTSIM_PW_OWNER_POLL_MS is a test-only override of the 5s poll interval;
18
+ // production never sets it.
18
19
  const ownerPid = Number(process.env.SOOTSIM_PW_OWNER_PID || 0);
19
20
  const ownerPollMs = Number(process.env.SOOTSIM_PW_OWNER_POLL_MS || 5000);
20
21
  // optional CDP port \u2014 exposes Chrome's remote-debugging endpoint so a
@@ -56,7 +57,7 @@ const viewport = viewportSpec
56
57
  const deviceScaleFactor = Number(process.env.SOOTSIM_PW_DSF || 2);
57
58
  const closeTimeoutMs = Number(process.env.SOOTSIM_PW_CLOSE_TIMEOUT_MS || 2500);
58
59
  const connectAckFile = process.env.SOOTSIM_PW_CONNECTED_ACK_FILE || '';
59
- const disposableBrowserCacheDirs = new Set(${JSON.stringify(I)});
60
+ const disposableBrowserCacheDirs = new Set(${JSON.stringify(D)});
60
61
  const { existsSync, mkdtempSync, readdirSync, rmSync, unlinkSync } = require('fs');
61
62
  const { execSync } = require('child_process');
62
63
  const { tmpdir } = require('os');
@@ -267,7 +268,9 @@ const cleanupProfile = () => {
267
268
  // down when it's gone. ESRCH (kill throws) = owner exited; EPERM = alive but
268
269
  // not signalable by us, which still counts as alive.
269
270
  const startOwnerWatch = () => {
270
- if (!Number.isInteger(ownerPid) || ownerPid <= 1) return;
271
+ if (!Number.isInteger(ownerPid) || ownerPid <= 1) {
272
+ throw new Error('[playwright-driver] missing valid owning process; refusing unsupervised browser host');
273
+ }
271
274
  const intervalMs = Number.isFinite(ownerPollMs) && ownerPollMs > 0 ? ownerPollMs : 5000;
272
275
  ownerWatch = setInterval(() => {
273
276
  try {
@@ -402,7 +405,7 @@ const cleanupProfile = () => {
402
405
  const hostMeta = {
403
406
  sootsimHostDriver: 'playwright',
404
407
  sootsimHostPid: process.pid,
405
- sootsimHostOwnerPid: ownerPid > 1 ? ownerPid : null,
408
+ sootsimHostOwnerPid: ownerPid,
406
409
  sootsimHostStartedAt: Date.now(),
407
410
  };
408
411
  // inject the resolved bridge port (numeric literal) BEFORE the page runs, so
@@ -496,6 +499,6 @@ const cleanupProfile = () => {
496
499
  process.stderr.write(String((err && err.stack) || err) + '\\n');
497
500
  process.exit(1);
498
501
  });
499
- `;function F(){let e=[process.cwd()+"/"];try{process.argv[1]&&e.push(process.argv[1])}catch{}for(let r of e)try{let t=se(r);for(let o of["playwright","playwright-chromium","playwright-core"])try{return{spec:o,modulePath:t.resolve(o)}}catch{}}catch{}return null}function le(){let e=F();return e?{available:!0,reason:null,detail:`resolved via ${e.spec}`}:{available:!1,reason:"playwright not installed in the current workspace"}}function ce(e,r){return process.platform!=="linux"||e.headless||process.env.DISPLAY||process.env.WAYLAND_DISPLAY||!/missing x server|cannot open display|x server|x11/i.test(r)?null:" hint: linux without DISPLAY/WAYLAND_DISPLAY \u2014 rerun without --headed (or add --headless) to run playwright headless."}function de(e){return e.profileId?y(L(e.profileId).id):e.ephemeralProfile?oe($(N(),"sootsim-playwright-profile-")):""}async function ue(e){let r=F();if(!r)return{launched:!1,message:"playwright not installed \u2014 run `bun add -D playwright` first"};if(!e.url)return{launched:!1,message:"playwright driver requires a target url"};let t=$(N(),`sootsim-playwright-host-${Date.now().toString(36)}-${process.pid}.log`),o=`${t}.connected`,n=ie(t,"a");try{let i=E(),p=re(process.execPath,["-e",ae],{detached:!0,stdio:["ignore","ignore",n],env:{...process.env,SOOTSIM_PW_MODULE:r.modulePath,SOOTSIM_PW_URL:e.url,SOOTSIM_PW_BRIDGE_PORT:e.bridgePort?String(e.bridgePort):"",SOOTSIM_PW_HEADLESS:e.headless??!0?"1":"0",SOOTSIM_PW_USERDATADIR:de(e),SOOTSIM_PW_CDP_PORT:e.cdpPort?String(e.cdpPort):"",SOOTSIM_PW_BROWSER:e.browser??"",SOOTSIM_PW_VIEWPORT:e.viewport?`${e.viewport.width}x${e.viewport.height}`:"",SOOTSIM_PW_CONNECTED_ACK_FILE:o,SOOTSIM_PW_CONNECT_TIMEOUT_MS:String(e.connectTimeoutMs??12e4),SOOTSIM_PW_OWNER_PID:i&&i>1?String(i):""}});p.unref();let D=await new Promise(l=>{let u=setTimeout(()=>l(null),4e3);p.once("exit",q=>{clearTimeout(u),l(q??0)})});if(D!==null){let l=ne(t,"utf8").trim(),u=ce(e,l);return{launched:!1,message:`playwright host exited early (code ${D}) \u2014 host log ${t}${l?`:
500
- ${l}`:""}${u?`
501
- ${u}`:""}`}}let k=i&&i>1?_(i):null,B=i&&i>1?` \u2014 browser closes when pid ${i}${k?` (${k})`:""} exits`:"";return{launched:!0,message:`playwright chrome launched \u2192 ${e.url}${B}`,pid:p.pid,target:r.spec,attachUrl:e.url,connectAckFile:o,diagnosticLogPath:t}}catch(i){return{launched:!1,message:`playwright launch failed: ${i instanceof Error?i.message:String(i)}`}}finally{te(n)}}var U={id:"playwright",name:"playwright",description:"programmatic chromium via the playwright package \u2014 headless default",kind:"automation",availability:le,launch:ue};function he(){return process.platform!=="darwin"&&process.platform!=="linux"&&process.platform!=="win32"?{available:!1,reason:`unsupported platform: ${process.platform}`}:{available:!0,reason:null,detail:process.platform==="darwin"?"open(1)":process.platform==="win32"?"cmd /c start":"xdg-open(1)"}}async function pe(e){if(e.headless)return{launched:!1,message:"system driver does not support --headless; use chromium or playwright"};if(!e.url)return{launched:!1,message:"system driver requires a target url"};if(e.profileId||e.ephemeralProfile)return{launched:!1,message:"profiles require electron or playwright; browser tabs use your current browser profile"};try{let r=await A(e.url,{detached:e.detached??!0,newWindow:e.newWindow});return{launched:!0,message:`${r.via} launch \u2192 ${e.url}`,pid:r.pid,target:r.target,attachUrl:e.url}}catch(r){return{launched:!1,message:`system launch failed: ${r instanceof Error?r.message:String(r)}`}}}var G={id:"system",name:"system",description:"shared browser launcher \u2014 system default or chromium window",kind:"delegate",availability:he,launch:pe};var d=[R,W,U,G];function Fe(){return d}function Ue(e){return d.find(r=>r.id===e)??null}function Ge(e,r){if(e)return d.find(o=>o.id===e)??null;for(let t of r){let o=d.find(n=>n.id===t);if(o&&o.availability().available)return o}return null}function Be(){return d.map(e=>{let r=e.availability();return{id:e.id,name:e.name,kind:e.kind,description:e.description,available:r.available,reason:r.reason,detail:r.detail??null}})}export{K as a,L as b,V as c,ge as d,J as e,R as f,W as g,U as h,G as i,d as j,Fe as k,Ue as l,Ge as m,Be as n};
502
+ `;function L(){let e=[process.cwd()+"/"];try{process.argv[1]&&e.push(process.argv[1])}catch{}for(let r of e)try{let t=Z(r);for(let o of["playwright","playwright-chromium","playwright-core"])try{return{spec:o,modulePath:t.resolve(o)}}catch{}}catch{}return null}function ee(){let e=L();return e?{available:!0,reason:null,detail:`resolved via ${e.spec}`}:{available:!1,reason:"playwright not installed in the current workspace"}}function re(e,r){return process.platform!=="linux"||e.headless||process.env.DISPLAY||process.env.WAYLAND_DISPLAY||!/missing x server|cannot open display|x server|x11/i.test(r)?null:" hint: linux without DISPLAY/WAYLAND_DISPLAY \u2014 rerun without --headed (or add --headless) to run playwright headless."}function te(e){return e.profileId?v(T(e.profileId).id):e.ephemeralProfile?V(M(A(),"sootsim-playwright-profile-")):""}async function oe(e){let r=L();if(!r)return{launched:!1,message:"playwright not installed \u2014 run `bun add -D playwright` first"};if(!e.url)return{launched:!1,message:"playwright driver requires a target url"};let t=e.ownerPid;if(t===void 0||!Number.isInteger(t)||t<=1)return{launched:!1,message:"playwright driver requires a valid owning session process"};let o=M(A(),`sootsim-playwright-host-${Date.now().toString(36)}-${process.pid}.log`),i=`${o}.connected`,u=J(o,"a");try{let s=K(process.execPath,["-e",Q],{detached:!0,stdio:["ignore","ignore",u],env:{...process.env,SOOTSIM_PW_MODULE:r.modulePath,SOOTSIM_PW_URL:e.url,SOOTSIM_PW_BRIDGE_PORT:e.bridgePort?String(e.bridgePort):"",SOOTSIM_PW_HEADLESS:e.headless??!0?"1":"0",SOOTSIM_PW_USERDATADIR:te(e),SOOTSIM_PW_CDP_PORT:e.cdpPort?String(e.cdpPort):"",SOOTSIM_PW_BROWSER:e.browser??"",SOOTSIM_PW_VIEWPORT:e.viewport?`${e.viewport.width}x${e.viewport.height}`:"",SOOTSIM_PW_CONNECTED_ACK_FILE:i,SOOTSIM_PW_CONNECT_TIMEOUT_MS:String(e.connectTimeoutMs??12e4),SOOTSIM_PW_OWNER_PID:String(t)}});s.unref();let S=await new Promise(l=>{let h=setTimeout(()=>l(null),4e3);s.once("exit",N=>{clearTimeout(h),l(N??0)})});if(S!==null){let l=X(o,"utf8").trim(),h=re(e,l);return{launched:!1,message:`playwright host exited early (code ${S}) \u2014 host log ${o}${l?`:
503
+ ${l}`:""}${h?`
504
+ ${h}`:""}`}}let k=_(t),W=` \u2014 browser closes when pid ${t}${k?` (${k})`:""} exits`;return{launched:!0,message:`playwright chrome launched \u2192 ${e.url}${W}`,pid:s.pid,target:r.spec,attachUrl:e.url,connectAckFile:i,diagnosticLogPath:o}}catch(s){return{launched:!1,message:`playwright launch failed: ${s instanceof Error?s.message:String(s)}`}}finally{Y(u)}}var R={id:"playwright",name:"playwright",description:"programmatic chromium via the playwright package \u2014 headless default",kind:"automation",availability:ee,launch:oe};var d=[C,R];function Se(){return d}function ke(e){return d.find(r=>r.id===e)??null}function xe(e,r){if(e)return d.find(o=>o.id===e)??null;for(let t of r){let o=d.find(i=>i.id===t);if(o&&o.availability().available)return o}return null}function Oe(){return d.map(e=>{let r=e.availability();return{id:e.id,name:e.name,kind:e.kind,description:e.description,available:r.available,reason:r.reason,detail:r.detail??null}})}export{U as a,T as b,j as c,ae as d,q as e,C as f,R as g,d as h,Se as i,ke as j,xe as k,Oe as l};
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.305 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.306 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
4
  import{readFileSync as i}from"node:fs";import{fileURLToPath as e}from"node:url";var r=null;function l(){if(r!=null)return r;let o=[()=>e(import.meta.resolve("sootsim/package.json")),()=>e(new URL("../package.json",import.meta.url))];for(let n of o)try{let t=JSON.parse(i(n(),"utf8")).version;if(typeof t=="string"&&t)return r=t,r}catch{}return r="0.0.0",r}export{l as a};
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.305 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.306 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
4
  import{execFileSync as b,execSync as A}from"node:child_process";var p=new WeakMap,u=new Set,y=!1;function d(){return{platform:process.platform,env:process.env}}function g(e=d()){return e.platform==="linux"&&e.env.GITHUB_ACTIONS==="true"&&e.env.RUNNER_OS==="Linux"}function I(e){let r=String(e);return/^--disable-gpu(?:=.*)?$/i.test(r)||/^--enable-unsafe-swiftshader(?:=.*)?$/i.test(r)||/^--use-angle=(?:swiftshader|swiftshader-webgl)$/i.test(r)||/^--use-gl=swiftshader$/i.test(r)}function E(e){return e.match(/(?:^|\s)(--disable-gpu(?:=[^\s]+)?|--enable-unsafe-swiftshader(?:=[^\s]+)?|--use-angle=(?:swiftshader|swiftshader-webgl)|--use-gl=swiftshader)(?=\s|$)/i)?.[1]??null}function v(e){return e==="darwin"?"metal":e==="linux"?"vulkan":"default"}function P(e,r=d()){if(g(r))return;let n=E(e);if(n)throw new Error(`[reap-browser] refused software-rendering Chrome process argument ${n}`);let o=v(r.platform),s=e.split(/\s+/);if(!s.includes(`--use-angle=${o}`)||!s.includes("--enable-gpu"))throw new Error(`[reap-browser] Chrome process did not retain the required ${o} GPU arguments`);if(r.platform==="darwin"&&e.includes("/Applications/Google Chrome.app/"))throw new Error("[reap-browser] refused the user's installed Google Chrome; use Playwright channel chromium")}function G(e){if(!e||typeof e!="object")return[];let n=e.gpu;if(!n||typeof n!="object")return[];let o=n,s=[],a=o.auxAttributes;if(a&&typeof a=="object")for(let t of Object.values(a))typeof t=="string"&&s.push(t);let i=o.devices;if(Array.isArray(i)){for(let t of i)if(!(!t||typeof t!="object"))for(let c of Object.values(t))typeof c=="string"&&s.push(c)}return s}function C(e){if(!e||typeof e!="object")return null;let r=e;if(!Array.isArray(r.processInfo))return null;for(let n of r.processInfo){if(!n||typeof n!="object")continue;let o=n;if(o.type==="browser"&&typeof o.id=="number"&&Number.isInteger(o.id)&&o.id>0)return o.id}return null}function L(e,r=d()){if(g(r))return;let o=G(e).join(" | ");if(!o||/swiftshader|llvmpipe|software rasterizer/i.test(o))throw new Error(`[reap-browser] Chrome reported a software renderer${o?`: ${o}`:""}`);if(r.platform==="darwin"&&!/metal/i.test(o))throw new Error(`[reap-browser] Chrome did not report an ANGLE Metal renderer: ${o}`)}function w(e){if(e&&typeof e=="object"){let n=p.get(e);if(n!==void 0)return n}let r=e;if(r&&typeof r.process=="function")try{let n=r.process();if(n&&typeof n.pid=="number"&&n.pid>0)return n.pid}catch{}if(r&&typeof r.browser=="function")try{let n=r.browser();if(n)return w(n)}catch{}return null}function h(e){let r=[];try{r=A(`pgrep -P ${e} || true`).toString().split(`