sootsim 0.1.227 → 0.1.228

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 (175) hide show
  1. package/README.md +14 -14
  2. package/detox/element-types.ts +3 -3
  3. package/detox/expectations.ts +29 -24
  4. package/detox/gestures.ts +16 -16
  5. package/detox/index.ts +34 -32
  6. package/dist-cli/bin.js +4 -4
  7. package/dist-cli/chunks/{agent-HBVXCRJT.js → agent-6P5T2QHC.js} +2 -2
  8. package/dist-cli/chunks/{agent-wrapper-X376DPV2.js → agent-wrapper-SMEMJZXI.js} +2 -2
  9. package/dist-cli/chunks/{app-fonts-LIQTD5RP.js → app-fonts-6OQTLX3U.js} +2 -2
  10. package/dist-cli/chunks/{assert-X6PPLN72.js → assert-ZAYFOW6R.js} +2 -2
  11. package/dist-cli/chunks/{auth-INRWIM2C.js → auth-Y53UANSH.js} +2 -2
  12. package/dist-cli/chunks/beta-ZQCASJ7C.js +2 -0
  13. package/dist-cli/chunks/{camera-LGFHYCJ5.js → camera-AJQWSOO4.js} +2 -2
  14. package/dist-cli/chunks/{chunk-2BQOZATN.js → chunk-2I62CFYI.js} +3 -3
  15. package/dist-cli/chunks/{chunk-E3DLUOFK.js → chunk-34MFG4IM.js} +7 -7
  16. package/dist-cli/chunks/{chunk-J7IFVTWX.js → chunk-4A6HM2K3.js} +1 -1
  17. package/dist-cli/chunks/chunk-4QOY4T27.js +3 -0
  18. package/dist-cli/chunks/{chunk-HRYKZ5YY.js → chunk-6Q2B7QHC.js} +5 -5
  19. package/dist-cli/chunks/{chunk-F5HOYUD2.js → chunk-6U3GMNTP.js} +1 -1
  20. package/dist-cli/chunks/{chunk-RNWJQ4UR.js → chunk-72AQH53U.js} +1 -1
  21. package/dist-cli/chunks/{chunk-NIN75M5H.js → chunk-7HMRWJHH.js} +1 -1
  22. package/dist-cli/chunks/{chunk-YB2LM6VB.js → chunk-7TJVPCQA.js} +6 -6
  23. package/dist-cli/chunks/{chunk-LM544J6V.js → chunk-A5SO4OGE.js} +1 -1
  24. package/dist-cli/chunks/{chunk-D42IRY2Y.js → chunk-AJ3CDBW6.js} +2 -2
  25. package/dist-cli/chunks/chunk-ALE5MU5Z.js +2 -0
  26. package/dist-cli/chunks/{chunk-NHE3YHDU.js → chunk-AVS7RL73.js} +2 -2
  27. package/dist-cli/chunks/chunk-AWF575Y5.js +1 -0
  28. package/dist-cli/chunks/chunk-BHNOPI7I.js +2 -0
  29. package/dist-cli/chunks/{chunk-LCJSTEIR.js → chunk-D2QUTBZP.js} +2 -2
  30. package/dist-cli/chunks/{chunk-ESK7B2BQ.js → chunk-DEVNCWS4.js} +6 -6
  31. package/dist-cli/chunks/{chunk-GUCFICA4.js → chunk-E5FOMYR6.js} +1 -1
  32. package/dist-cli/chunks/{chunk-2XXPF6LP.js → chunk-EFMPSG7T.js} +2 -2
  33. package/dist-cli/chunks/{chunk-4J7BIXEB.js → chunk-EKWOBYJO.js} +2 -2
  34. package/dist-cli/chunks/{chunk-E75EBS77.js → chunk-EPQ5EZBJ.js} +2 -2
  35. package/dist-cli/chunks/{chunk-Q4FB222M.js → chunk-FDSFA7WL.js} +3 -3
  36. package/dist-cli/chunks/{chunk-UGWURWHN.js → chunk-FSKQZHM2.js} +2 -2
  37. package/dist-cli/chunks/{chunk-QWRYD2QV.js → chunk-G42TLJVQ.js} +18 -18
  38. package/dist-cli/chunks/{chunk-HXHB5A6R.js → chunk-JA52F67H.js} +2 -2
  39. package/dist-cli/chunks/chunk-JKZY5CPQ.js +2 -0
  40. package/dist-cli/chunks/{chunk-MG6JE3AM.js → chunk-JV43GSZB.js} +2 -2
  41. package/dist-cli/chunks/{chunk-7L5IKIHC.js → chunk-JWZMAJC7.js} +1 -1
  42. package/dist-cli/chunks/{chunk-F53C5HAB.js → chunk-KIL5F7KD.js} +1 -1
  43. package/dist-cli/chunks/chunk-KY2KLPYL.js +1 -0
  44. package/dist-cli/chunks/{chunk-DB3GMVOH.js → chunk-LBXHG4AU.js} +2 -2
  45. package/dist-cli/chunks/{chunk-SBIAPF6E.js → chunk-MCMMRIJV.js} +1 -1
  46. package/dist-cli/chunks/{chunk-A4BOYB55.js → chunk-MWZOCZ7J.js} +2 -2
  47. package/dist-cli/chunks/{chunk-HXSV263V.js → chunk-NCXHUU7N.js} +1 -1
  48. package/dist-cli/chunks/{chunk-HTVB3FW2.js → chunk-NME4QWJ3.js} +2 -2
  49. package/dist-cli/chunks/{chunk-J2JAOIMN.js → chunk-OETQYAI2.js} +2 -2
  50. package/dist-cli/chunks/chunk-PJBYZZWR.js +2 -0
  51. package/dist-cli/chunks/{chunk-NU755HCE.js → chunk-PNPH4JLS.js} +1 -1
  52. package/dist-cli/chunks/chunk-RT3OS624.js +118 -0
  53. package/dist-cli/chunks/{chunk-7LDHOQ7B.js → chunk-SACWV3LZ.js} +20 -20
  54. package/dist-cli/chunks/chunk-SPJSTRXX.js +24 -0
  55. package/dist-cli/chunks/{chunk-3L5EXWCP.js → chunk-UYLESZU3.js} +1 -1
  56. package/dist-cli/chunks/{chunk-XESYTWFM.js → chunk-WWZL7HNB.js} +29 -29
  57. package/dist-cli/chunks/{chunk-T6MEERRI.js → chunk-ZBJ5JMXM.js} +2 -2
  58. package/dist-cli/chunks/chunk-ZWJEJR73.js +4 -0
  59. package/dist-cli/chunks/cli-version-V4GJYM74.js +2 -0
  60. package/dist-cli/chunks/{compat-MH673TEJ.js → compat-W7E4744D.js} +3 -3
  61. package/dist-cli/chunks/{config-SSCDV5ZJ.js → config-N7G65EY2.js} +2 -2
  62. package/dist-cli/chunks/{control-54R2XDLV.js → control-7VDFEVWU.js} +2 -2
  63. package/dist-cli/chunks/daemon-UI3PQ47F.js +2 -0
  64. package/dist-cli/chunks/{debug-PFP646II.js → debug-ZKUCSCOU.js} +3 -3
  65. package/dist-cli/chunks/{desktop-BPYYJ3EM.js → desktop-L3OXTT45.js} +3 -3
  66. package/dist-cli/chunks/{detox-BIUVHXYH.js → detox-QG4IBZAG.js} +2 -2
  67. package/dist-cli/chunks/{device-BNSPNIP6.js → device-QC6MDI7W.js} +2 -2
  68. package/dist-cli/chunks/{diagnose-BPTDSGOB.js → diagnose-HTUDENJK.js} +2 -2
  69. package/dist-cli/chunks/drivers-L2BXXDI7.js +2 -0
  70. package/dist-cli/chunks/{film-ILA6VSOG.js → film-CT7FHNLE.js} +3 -3
  71. package/dist-cli/chunks/flow-XUBXWJHL.js +2 -0
  72. package/dist-cli/chunks/help-7CIGANJN.js +2 -0
  73. package/dist-cli/chunks/{hidden-runtime-alias-TD7IVAPF.js → hidden-runtime-alias-YTUEPZ3U.js} +2 -2
  74. package/dist-cli/chunks/{home-paths-H36JDTNO.js → home-paths-7K6HDXOP.js} +2 -2
  75. package/dist-cli/chunks/inspect-ZY3QI7VJ.js +2 -0
  76. package/dist-cli/chunks/install-desktop-CVPRYFFV.js +2 -0
  77. package/dist-cli/chunks/{login-5WGZX2ZD.js → login-XHOOXAOW.js} +4 -4
  78. package/dist-cli/chunks/{logout-V53WTVIZ.js → logout-7BISNC5F.js} +2 -2
  79. package/dist-cli/chunks/{maestro-HGKYRD54.js → maestro-YD3G7LSG.js} +3 -3
  80. package/dist-cli/chunks/{maestro-generate-6DNZSKDP.js → maestro-generate-WNOWZC5K.js} +3 -3
  81. package/dist-cli/chunks/{mode-YFMKORE5.js → mode-Y6JJMXU5.js} +2 -2
  82. package/dist-cli/chunks/optional-demo-registry-YUXURWKX.js +2 -0
  83. package/dist-cli/chunks/{perf-EOIGFDWM.js → perf-AY3ZKTDS.js} +2 -2
  84. package/dist-cli/chunks/{record-2F54QS6Y.js → record-ZC4W6QN6.js} +10 -10
  85. package/dist-cli/chunks/runtime-MVYAP3UX.js +2 -0
  86. package/dist-cli/chunks/screenshot-command-NRKTGTSJ.js +151 -0
  87. package/dist-cli/chunks/{screenshots-capture-DIICN24R.js → screenshots-capture-LZR3AHWN.js} +3 -3
  88. package/dist-cli/chunks/{serve-66NC6PPZ.js → serve-4X2WI5XF.js} +5 -5
  89. package/dist-cli/chunks/{setup-ZYN4BTBR.js → setup-KODPGJBJ.js} +3 -3
  90. package/dist-cli/chunks/{skills-MDBIER7U.js → skills-DEAUDOAN.js} +2 -2
  91. package/dist-cli/chunks/{storage-AQ3SEO4Y.js → storage-P7FQRH5T.js} +2 -2
  92. package/dist-cli/chunks/store-PTRXOHHV.js +2 -0
  93. package/dist-cli/chunks/telemetry-JHKOHSI2.js +2 -0
  94. package/dist-cli/chunks/{timeline-VEGHQZ36.js → timeline-7ISYXLR3.js} +2 -2
  95. package/dist-cli/chunks/{upgrade-RNDCRPLJ.js → upgrade-NZBJS5L2.js} +3 -3
  96. package/dist-cli/chunks/upload-J34H5SXV.js +2 -0
  97. package/dist-cli/chunks/{version-XUMPKQUM.js → version-J6BLGLTO.js} +2 -2
  98. package/dist-cli/chunks/{web-ESQGHVPD.js → web-Y6UVYM3Z.js} +2 -2
  99. package/dist-cli/chunks/{what-happened-6NJENKUF.js → what-happened-YKXXY6W2.js} +2 -2
  100. package/dist-lib/agent-daemon-client.cjs +1 -1
  101. package/dist-lib/agent-events.cjs +1 -1
  102. package/dist-lib/agent-identity.cjs +1 -1
  103. package/dist-lib/agent-sessions.cjs +1 -1
  104. package/dist-lib/attached-projects.cjs +1 -1
  105. package/dist-lib/auth/shared-session.cjs +2 -2
  106. package/dist-lib/backend-origin.cjs +18 -18
  107. package/dist-lib/beta.cjs +1 -1
  108. package/dist-lib/beta.mjs +1 -1
  109. package/dist-lib/bridge-constants.cjs +4 -4
  110. package/dist-lib/cli-constants.cjs +1 -1
  111. package/dist-lib/config.cjs +1 -1
  112. package/dist-lib/detox/index.cjs +321 -79
  113. package/dist-lib/dev-bundle-resolution.cjs +2 -2
  114. package/dist-lib/home-paths.cjs +1 -1
  115. package/dist-lib/host/bridge-host.cjs +18 -13
  116. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  117. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  118. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  119. package/dist-lib/host/websocket-proxy.cjs +1 -1
  120. package/dist-lib/index.cjs +1 -1
  121. package/dist-lib/jump-to-source-babel.cjs +1 -1
  122. package/dist-lib/menu.cjs +1 -1
  123. package/dist-lib/menu.mjs +1 -1
  124. package/dist-lib/metro.cjs +1 -1
  125. package/dist-lib/profiles.cjs +1 -1
  126. package/dist-lib/render-mode.cjs +1 -1
  127. package/dist-lib/scripts/dev-server-scanner.cjs +7 -7
  128. package/dist-lib/sdk.cjs +12 -4
  129. package/dist-lib/sdk.mjs +12 -4
  130. package/dist-lib/skills.cjs +425 -169
  131. package/dist-lib/vite.cjs +1 -1
  132. package/package.json +4 -4
  133. package/scripts/dev-server-scanner.ts +5 -5
  134. package/scripts/postinstall.cjs +1 -1
  135. package/scripts/preuninstall.cjs +1 -1
  136. package/skills/{soot → contrast}/SKILL.md +4 -4
  137. package/skills/sootsim-perf/SKILL.md +3 -1
  138. package/src/auth/shared-session.ts +1 -1
  139. package/src/backend-origin.ts +11 -11
  140. package/src/bridge-constants.ts +3 -3
  141. package/src/home-paths.ts +1 -1
  142. package/src/host/agent-host.ts +2 -2
  143. package/src/host/bridge-host.ts +21 -21
  144. package/src/native-dev-bundle-url.ts +3 -3
  145. package/src/runtime-assets.ts +3 -3
  146. package/src/runtime-delivery.ts +10 -4
  147. package/src/screenshots/compose.ts +4 -1
  148. package/src/screenshots/frame-compose.ts +4 -1
  149. package/src/screenshots/orchestrate.ts +7 -2
  150. package/src/vite-plugin-one.ts +3 -3
  151. package/src/vite-plugin.ts +3 -3
  152. package/dist-cli/chunks/beta-WLLSIVLW.js +0 -2
  153. package/dist-cli/chunks/chunk-35EAEAN4.js +0 -24
  154. package/dist-cli/chunks/chunk-44Z2X5R4.js +0 -2
  155. package/dist-cli/chunks/chunk-4BLOZ3AF.js +0 -2
  156. package/dist-cli/chunks/chunk-7K5K5NKB.js +0 -2
  157. package/dist-cli/chunks/chunk-7RWDQCIT.js +0 -1
  158. package/dist-cli/chunks/chunk-BVD2JFOX.js +0 -1
  159. package/dist-cli/chunks/chunk-HBEEYWK5.js +0 -2
  160. package/dist-cli/chunks/chunk-JNUGPBWC.js +0 -118
  161. package/dist-cli/chunks/chunk-KBSJA7HK.js +0 -3
  162. package/dist-cli/chunks/chunk-Z2E2DDIQ.js +0 -4
  163. package/dist-cli/chunks/cli-version-NNBCIQKL.js +0 -2
  164. package/dist-cli/chunks/daemon-GL5GQTWB.js +0 -2
  165. package/dist-cli/chunks/drivers-KBKJVF2Y.js +0 -2
  166. package/dist-cli/chunks/flow-L247VVBM.js +0 -2
  167. package/dist-cli/chunks/help-QIZEANNK.js +0 -2
  168. package/dist-cli/chunks/inspect-6OAVS27G.js +0 -2
  169. package/dist-cli/chunks/install-desktop-LKYAUUQY.js +0 -2
  170. package/dist-cli/chunks/optional-demo-registry-YGNESGBH.js +0 -2
  171. package/dist-cli/chunks/runtime-FYVV4DCQ.js +0 -2
  172. package/dist-cli/chunks/screenshot-command-R535TYXY.js +0 -151
  173. package/dist-cli/chunks/store-6ZGLOTZI.js +0 -2
  174. package/dist-cli/chunks/telemetry-V76UPVDV.js +0 -2
  175. package/dist-cli/chunks/upload-KRBS3Y7Q.js +0 -2
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{d as p}from"./chunk-7K5K5NKB.js";import"./chunk-F5HOYUD2.js";import{existsSync as h,mkdirSync as d,readFileSync as y,writeFileSync as g}from"node:fs";import{join as m}from"node:path";import{gzipSync as w}from"node:zlib";function f(t,e){let o=t.indexOf(`--${e}`);if(o!==-1&&o+1<t.length)return t[o+1];let i=t.find(r=>r.startsWith(`--${e}=`));return i?i.slice(e.length+3):void 0}async function S(t){let e=f(t,"wire")||"",o=f(t,"out-dir"),i=f(t,"manifest");if((!o||!i)&&(console.error(" usage: sootsim app-fonts stage --wire <wire> --out-dir <dir> --manifest <path>"),process.exit(1)),!e.trim()){console.log("no app fonts declared \u2014 nothing to stage");return}d(o,{recursive:!0});let r=await p(e,{onStaged:({url:n,byteLength:s})=>console.log(` staged app font: ${n} (${(s/1024).toFixed(1)} KiB)`),onError:(n,s)=>console.error(` warning: failed to fetch app font ${n}: ${s instanceof Error?s.message:s}`)}),a=[];for(let n of r){let s=w(n.bytes);g(m(o,n.urlhash),s),a.push({url:n.url,urlhash:n.urlhash,contentType:n.contentType,encoding:"gzip",sizeBytes:s.length,rawBytes:n.bytes.byteLength})}let c=[];if(h(i))try{let n=JSON.parse(y(i,"utf8"));Array.isArray(n)&&(c=n)}catch{}let u=new Set(c.map(n=>n.urlhash)),l=[...c,...a.filter(n=>!u.has(n.urlhash))];g(i,JSON.stringify(l)),console.log(`staged ${a.length} app font(s); manifest now has ${l.length} file(s)`)}async function E(t){let e=t[0];if(e==="stage"){await S(t.slice(1));return}console.error(` unknown app-fonts subcommand: ${e??"(none)"}`),console.error(" available: stage"),process.exit(1)}export{E as runAppFonts};
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{d as p}from"./chunk-PJBYZZWR.js";import"./chunk-6U3GMNTP.js";import{existsSync as h,mkdirSync as d,readFileSync as y,writeFileSync as g}from"node:fs";import{join as m}from"node:path";import{gzipSync as w}from"node:zlib";function f(t,e){let o=t.indexOf(`--${e}`);if(o!==-1&&o+1<t.length)return t[o+1];let i=t.find(r=>r.startsWith(`--${e}=`));return i?i.slice(e.length+3):void 0}async function S(t){let e=f(t,"wire")||"",o=f(t,"out-dir"),i=f(t,"manifest");if((!o||!i)&&(console.error(" usage: sootsim app-fonts stage --wire <wire> --out-dir <dir> --manifest <path>"),process.exit(1)),!e.trim()){console.log("no app fonts declared \u2014 nothing to stage");return}d(o,{recursive:!0});let r=await p(e,{onStaged:({url:n,byteLength:s})=>console.log(` staged app font: ${n} (${(s/1024).toFixed(1)} KiB)`),onError:(n,s)=>console.error(` warning: failed to fetch app font ${n}: ${s instanceof Error?s.message:s}`)}),a=[];for(let n of r){let s=w(n.bytes);g(m(o,n.urlhash),s),a.push({url:n.url,urlhash:n.urlhash,contentType:n.contentType,encoding:"gzip",sizeBytes:s.length,rawBytes:n.bytes.byteLength})}let c=[];if(h(i))try{let n=JSON.parse(y(i,"utf8"));Array.isArray(n)&&(c=n)}catch{}let u=new Set(c.map(n=>n.urlhash)),l=[...c,...a.filter(n=>!u.has(n.urlhash))];g(i,JSON.stringify(l)),console.log(`staged ${a.length} app font(s); manifest now has ${l.length} file(s)`)}async function E(t){let e=t[0];if(e==="stage"){await S(t.slice(1));return}console.error(` unknown app-fonts subcommand: ${e??"(none)"}`),console.error(" available: stage"),process.exit(1)}export{E as runAppFonts};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import"./chunk-F5HOYUD2.js";import{spawn as x}from"child_process";var w=new Set(["describe","find","list","network","logs","count","tree","url","a11y","node","layout","keyboard","errors","warnings","requests","animations","animation","state","sample-color"]),S=new Set(["--exists","--empty","--negate","--quiet","--allow-timeout","!"]),q=new Set(["--count","--count-at-least","--count-at-most","--contains","--not-contains","--matches","--not-matches","--equals","--jq","--has-path","--within"]),P=new Set(["--path-equals"]);function j(s){let r=[],u=[],n=0,e=!1,t=!1,i=!1;for(let o=0;o<s.length;o++){let a=s[o];if(a==="--within"){let c=Number(s[o+1]);if(!Number.isFinite(c)||c<0)return{error:`--within requires a non-negative number, got: ${s[o+1]}`};n=c,o++;continue}if(a==="--negate"||a==="!"){e=!0;continue}if(a==="--quiet"){t=!0;continue}if(a==="--allow-timeout"){i=!0;continue}if(S.has(a)){u.push({kind:a,args:[]});continue}if(q.has(a)){let c=s[o+1];if(c==null)return{error:`${a} requires a value`};u.push({kind:a,args:[c]}),o++;continue}if(P.has(a)){let c=s[o+1],f=s[o+2];if(c==null||f==null)return{error:`${a} requires <path> <value>`};u.push({kind:a,args:[c,f]}),o+=2;continue}r.push(a)}return r.length===0?{error:"assert requires a verb (e.g. find, describe, get errors)"}:{verbArgs:r,predicates:u,withinMs:n,negate:e,quiet:t,allowTimeout:i}}function N(s){return s[0]==="get"||s[0]==="debug"?w.has(s[1])?s[1]:null:s[0]==="do"||s[0]==="wait"?null:w.has(s[0])?s[0]:null}async function R(s){let u=[process.argv[1],...s,"--json"];return new Promise(n=>{let e=x(process.execPath,u,{stdio:["ignore","pipe","pipe"],env:process.env}),t="",i="";e.stdout.on("data",o=>t+=o.toString()),e.stderr.on("data",o=>i+=o.toString()),e.on("error",o=>{n({ok:!1,payload:null,reason:`spawn failed: ${o.message}`})}),e.on("close",o=>{if(o!==0){let a=i.trim().split(`
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import"./chunk-6U3GMNTP.js";import{spawn as x}from"child_process";var w=new Set(["describe","find","list","network","logs","count","tree","url","a11y","node","layout","keyboard","errors","warnings","requests","animations","animation","state","sample-color"]),S=new Set(["--exists","--empty","--negate","--quiet","--allow-timeout","!"]),q=new Set(["--count","--count-at-least","--count-at-most","--contains","--not-contains","--matches","--not-matches","--equals","--jq","--has-path","--within"]),P=new Set(["--path-equals"]);function j(s){let r=[],u=[],n=0,e=!1,t=!1,i=!1;for(let o=0;o<s.length;o++){let a=s[o];if(a==="--within"){let c=Number(s[o+1]);if(!Number.isFinite(c)||c<0)return{error:`--within requires a non-negative number, got: ${s[o+1]}`};n=c,o++;continue}if(a==="--negate"||a==="!"){e=!0;continue}if(a==="--quiet"){t=!0;continue}if(a==="--allow-timeout"){i=!0;continue}if(S.has(a)){u.push({kind:a,args:[]});continue}if(q.has(a)){let c=s[o+1];if(c==null)return{error:`${a} requires a value`};u.push({kind:a,args:[c]}),o++;continue}if(P.has(a)){let c=s[o+1],f=s[o+2];if(c==null||f==null)return{error:`${a} requires <path> <value>`};u.push({kind:a,args:[c,f]}),o+=2;continue}r.push(a)}return r.length===0?{error:"assert requires a verb (e.g. find, describe, get errors)"}:{verbArgs:r,predicates:u,withinMs:n,negate:e,quiet:t,allowTimeout:i}}function N(s){return s[0]==="get"||s[0]==="debug"?w.has(s[1])?s[1]:null:s[0]==="do"||s[0]==="wait"?null:w.has(s[0])?s[0]:null}async function R(s){let u=[process.argv[1],...s,"--json"];return new Promise(n=>{let e=x(process.execPath,u,{stdio:["ignore","pipe","pipe"],env:process.env}),t="",i="";e.stdout.on("data",o=>t+=o.toString()),e.stderr.on("data",o=>i+=o.toString()),e.on("error",o=>{n({ok:!1,payload:null,reason:`spawn failed: ${o.message}`})}),e.on("close",o=>{if(o!==0){let a=i.trim().split(`
3
3
  `).slice(-2).join(" | ").slice(0,200);n({ok:!1,payload:null,reason:`verb exited ${o}${a?`: ${a}`:""}`});return}if(!t.trim()){n({ok:!1,payload:null,reason:"verb produced no output"});return}try{let a=JSON.parse(t);n({ok:!0,payload:a})}catch{n({ok:!1,payload:null,reason:`verb output was not valid json: ${t.slice(0,120)}`})}})})}function y(s,r){let u=r.split(".").filter(e=>e.length>0),n=s;for(let e of u){if(n==null)return{found:!1};if(Array.isArray(n)){let t=Number(e);if(!Number.isInteger(t)||t<0||t>=n.length)return{found:!1};n=n[t];continue}if(typeof n=="object"){let t=n;if(!(e in t))return{found:!1};n=t[e];continue}return{found:!1}}return{found:!0,value:n}}function d(s){return Array.isArray(s)?s.length:s&&typeof s=="object"?Object.keys(s).length:null}async function A(s,r){let{kind:u,args:n}=s;switch(u){case"--exists":return r==null?{ok:!1,reason:"payload is null"}:d(r)===0?{ok:!1,reason:"payload is empty"}:{ok:!0,reason:"exists"};case"--empty":{if(r==null)return{ok:!0,reason:"payload is null"};let e=d(r);return e===0?{ok:!0,reason:"payload is empty"}:{ok:!1,reason:`payload has ${e} item(s)`}}case"--count":{let e=Number(n[0]),t=d(r);return t==null?{ok:!1,reason:`payload not countable (${typeof r})`}:{ok:t===e,reason:`count=${t}, want=${e}`}}case"--count-at-least":{let e=Number(n[0]),t=d(r);return t==null?{ok:!1,reason:"payload not countable"}:{ok:t>=e,reason:`count=${t}, want>=${e}`}}case"--count-at-most":{let e=Number(n[0]),t=d(r);return t==null?{ok:!1,reason:"payload not countable"}:{ok:t<=e,reason:`count=${t}, want<=${e}`}}case"--contains":{let e=n[0],t=JSON.stringify(r);return{ok:t.includes(e),reason:t.includes(e)?`contains "${e}"`:`missing "${e}"`}}case"--not-contains":{let e=n[0],t=JSON.stringify(r);return{ok:!t.includes(e),reason:t.includes(e)?`unexpected "${e}"`:`not contains "${e}"`}}case"--matches":{let e=new RegExp(n[0]),t=JSON.stringify(r),i=e.test(t);return{ok:i,reason:i?`matches /${n[0]}/`:`no match for /${n[0]}/`}}case"--not-matches":{let e=new RegExp(n[0]),t=JSON.stringify(r),i=!e.test(t);return{ok:i,reason:i?`not matches /${n[0]}/`:`unexpected /${n[0]}/`}}case"--equals":{let e=n[0],t=typeof r=="string"?r:typeof r=="number"||typeof r=="boolean"?String(r):JSON.stringify(r);return{ok:t===e,reason:`got=${JSON.stringify(t)}, want=${JSON.stringify(e)}`}}case"--has-path":{let e=y(r,n[0]);return{ok:e.found,reason:e.found?`path ${n[0]} present`:`path ${n[0]} missing`}}case"--path-equals":{let[e,t]=n,i=y(r,e);if(!i.found)return{ok:!1,reason:`path ${e} missing`};let o=typeof i.value=="string"||typeof i.value=="number"||typeof i.value=="boolean"?String(i.value):JSON.stringify(i.value);return{ok:o===t,reason:`${e}=${o}, want=${t}`}}case"--jq":{let e=n[0];try{let i=(await O(e,r)).trim();return{ok:i.length>0&&i!=="null"&&i!=="false"&&i!=='""',reason:`jq: ${i.slice(0,120)}`}}catch(t){throw new Error(`jq evaluation failed: ${t.message}`)}}default:return{ok:!1,reason:`unknown predicate ${u}`}}}function O(s,r){return new Promise((u,n)=>{let e=x("jq",[s],{stdio:["pipe","pipe","pipe"]}),t="",i="";e.stdout.on("data",o=>t+=o.toString()),e.stderr.on("data",o=>i+=o.toString()),e.on("error",n),e.on("close",o=>{if(o!==0){n(new Error(i.trim()||`jq exited ${o}`));return}u(t)}),e.stdin.end(JSON.stringify(r))})}async function T(s){(s[0]==="--help"||s[0]==="-h"||s.length===0)&&(J(),process.exit(s.length===0?2:0));let r=j(s);"error"in r&&(process.stderr.write(` assert: ${r.error}
4
4
  `),process.exit(2));let{verbArgs:u,predicates:n,withinMs:e,negate:t,quiet:i,allowTimeout:o}=r;N(u)||(process.stderr.write(` assert: unknown or non-read verb: ${u.join(" ")}
5
5
  supported: ${Array.from(w).sort().join(", ")}
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as t}from"./chunk-4BLOZ3AF.js";import{d as s}from"./chunk-2BQOZATN.js";import"./chunk-NU755HCE.js";import"./chunk-F5HOYUD2.js";function i(){console.log(`
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as t}from"./chunk-ALE5MU5Z.js";import{d as s}from"./chunk-2I62CFYI.js";import"./chunk-PNPH4JLS.js";import"./chunk-6U3GMNTP.js";function i(){console.log(`
3
3
  sootsim auth \u2014 inspect CLI auth
4
4
 
5
5
  usage:
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a,b,c,d}from"./chunk-MCMMRIJV.js";import"./chunk-6U3GMNTP.js";export{d as BETA_ASK_HEADLINE,b as BETA_LABEL,c as BETA_TAGLINE,a as IS_BETA};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{m as d}from"./chunk-DB3GMVOH.js";import"./chunk-QWRYD2QV.js";import{g as l,i as m,k as p}from"./chunk-35EAEAN4.js";import"./chunk-J7IFVTWX.js";import"./chunk-E75EBS77.js";import"./chunk-NU755HCE.js";import"./chunk-F5HOYUD2.js";function f(){console.log(`
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{m as d}from"./chunk-LBXHG4AU.js";import"./chunk-G42TLJVQ.js";import{g as l,i as m,k as p}from"./chunk-SPJSTRXX.js";import"./chunk-4A6HM2K3.js";import"./chunk-EPQ5EZBJ.js";import"./chunk-PNPH4JLS.js";import"./chunk-6U3GMNTP.js";function f(){console.log(`
3
3
  sootsim do scan \u2014 inject a barcode scan
4
4
 
5
5
  usage:
@@ -1,3 +1,3 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{o as d}from"./chunk-NU755HCE.js";import{chmodSync as S,existsSync as f,mkdirSync as k,readFileSync as A,rmSync as i,writeFileSync as y}from"node:fs";import{dirname as c,join as D,resolve as m}from"node:path";var s=1,p="SOOTSIM_SHARED_AUTH_FILE",u="https://sootbean.com";function w(){let t=process.env[p];return t?.trim()?c(m(t)):d()}function a(){let t=process.env[p];return t?.trim()?m(t):D(w(),"desktop-auth.json")}function g(t){if(!t||typeof t!="object")return null;let e=t;return typeof e.id!="string"||!e.id.trim()?null:{id:e.id.trim(),name:typeof e.name=="string"?e.name:void 0,email:typeof e.email=="string"?e.email:void 0,image:typeof e.image=="string"?e.image:void 0,githubUsername:typeof e.githubUsername=="string"?e.githubUsername:void 0,teams:Array.isArray(e.teams)?e.teams.map(r=>{if(!r||typeof r!="object")return null;let n=r;return typeof n.id!="string"||typeof n.name!="string"?null:{id:n.id,name:n.name,role:n.role==="owner"?"owner":"member",githubOrg:typeof n.githubOrg=="string"?n.githubOrg:null}}).filter(r=>!!r):void 0}}function v(t){if(!t||typeof t!="object")return null;let e=t;if(e.version!==s||typeof e.token!="string"||!e.token.trim())return null;let r=typeof e.origin=="string"&&e.origin.trim()?e.origin.trim():u,n=e.source==="cli"||e.source==="electron"||e.source==="browser"||e.source==="unknown"?e.source:"unknown",o=typeof e.updatedAt=="string"&&e.updatedAt?e.updatedAt:new Date().toISOString(),h=typeof e.validatedAt=="string"&&e.validatedAt?e.validatedAt:void 0;return{version:s,token:e.token.trim(),user:g(e.user),origin:r,source:n,updatedAt:o,validatedAt:h}}function b(){let t=a();if(!f(t))return null;try{let e=JSON.parse(A(t,"utf8")),r=v(e);return r||(i(t,{force:!0}),null)}catch{return i(t,{force:!0}),null}}function O(t){let e=a();k(c(e),{recursive:!0});let r={version:s,token:t.token.trim(),user:t.user?g(t.user):null,origin:t.origin?.trim()||u,source:t.source,updatedAt:t.updatedAt||new Date().toISOString(),validatedAt:t.validatedAt};y(e,JSON.stringify(r,null,2)+`
3
- `);try{S(e,384)}catch{}return r}function l(){i(a(),{force:!0})}async function E(t){let e=b();if(!e?.token)return null;let r=t||e.origin||u;try{let n=await fetch(`${r.replace(/\/$/,"")}/api/auth/me`,{headers:{authorization:`Bearer ${e.token}`}});if(n.status===401)return l(),null;if(!n.ok)return e;let o=await n.json();return o.user?.id?O({token:e.token,user:o.user,origin:r,source:e.source,validatedAt:new Date().toISOString()}):(l(),null)}catch{return e}}export{b as a,O as b,l as c,E as d};
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{o as d}from"./chunk-PNPH4JLS.js";import{chmodSync as S,existsSync as f,mkdirSync as k,readFileSync as A,rmSync as i,writeFileSync as y}from"node:fs";import{dirname as c,join as D,resolve as m}from"node:path";var s=1,p="SOOTSIM_SHARED_AUTH_FILE",u="https://contrast.dev";function w(){let t=process.env[p];return t?.trim()?c(m(t)):d()}function a(){let t=process.env[p];return t?.trim()?m(t):D(w(),"desktop-auth.json")}function g(t){if(!t||typeof t!="object")return null;let e=t;return typeof e.id!="string"||!e.id.trim()?null:{id:e.id.trim(),name:typeof e.name=="string"?e.name:void 0,email:typeof e.email=="string"?e.email:void 0,image:typeof e.image=="string"?e.image:void 0,githubUsername:typeof e.githubUsername=="string"?e.githubUsername:void 0,teams:Array.isArray(e.teams)?e.teams.map(r=>{if(!r||typeof r!="object")return null;let n=r;return typeof n.id!="string"||typeof n.name!="string"?null:{id:n.id,name:n.name,role:n.role==="owner"?"owner":"member",githubOrg:typeof n.githubOrg=="string"?n.githubOrg:null}}).filter(r=>!!r):void 0}}function v(t){if(!t||typeof t!="object")return null;let e=t;if(e.version!==s||typeof e.token!="string"||!e.token.trim())return null;let r=typeof e.origin=="string"&&e.origin.trim()?e.origin.trim():u,n=e.source==="cli"||e.source==="electron"||e.source==="browser"||e.source==="unknown"?e.source:"unknown",o=typeof e.updatedAt=="string"&&e.updatedAt?e.updatedAt:new Date().toISOString(),h=typeof e.validatedAt=="string"&&e.validatedAt?e.validatedAt:void 0;return{version:s,token:e.token.trim(),user:g(e.user),origin:r,source:n,updatedAt:o,validatedAt:h}}function O(){let t=a();if(!f(t))return null;try{let e=JSON.parse(A(t,"utf8")),r=v(e);return r||(i(t,{force:!0}),null)}catch{return i(t,{force:!0}),null}}function b(t){let e=a();k(c(e),{recursive:!0});let r={version:s,token:t.token.trim(),user:t.user?g(t.user):null,origin:t.origin?.trim()||u,source:t.source,updatedAt:t.updatedAt||new Date().toISOString(),validatedAt:t.validatedAt};y(e,JSON.stringify(r,null,2)+`
3
+ `);try{S(e,384)}catch{}return r}function l(){i(a(),{force:!0})}async function E(t){let e=O();if(!e?.token)return null;let r=t||e.origin||u;try{let n=await fetch(`${r.replace(/\/$/,"")}/api/auth/me`,{headers:{authorization:`Bearer ${e.token}`}});if(n.status===401)return l(),null;if(!n.ok)return e;let o=await n.json();return o.user?.id?b({token:e.token,user:o.user,origin:r,source:e.source,validatedAt:new Date().toISOString()}):(l(),null)}catch{return e}}export{O as a,b,l as c,E as d};
@@ -1,6 +1,6 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as Ue,b as _e,c as Pe}from"./chunk-4BLOZ3AF.js";import{c as Be}from"./chunk-UGWURWHN.js";import{d as Ee}from"./chunk-7K5K5NKB.js";import{d as Ae}from"./chunk-3L5EXWCP.js";import{g as Re,i as Ie,k as B}from"./chunk-35EAEAN4.js";import{a as ke,b as E}from"./chunk-44Z2X5R4.js";import{a as xe}from"./chunk-2BQOZATN.js";import{createHash as ht}from"crypto";import{readFileSync as w}from"fs";import Ce from"path";import{gzipSync as ue,gunzipSync as yt}from"zlib";function Le(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 ot,constants as it}from"node:zlib";var at=9;function $e(e){return ot(e,{params:{[it.BROTLI_PARAM_QUALITY]:at}})}function ae(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 lt(e){let t=ae(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 ut(e,t=8,r){let s=0,i=0,a=e.length;await Promise.all(Array.from({length:Math.min(t,a)},async()=>{for(;s<a;){let u=e[s++];await lt(u),i++,r?.(i,a)}}))}function ct(e,t,r,s){let i=[];i.push({url:e.bundle.putUrl,contentType:e.bundle.contentType,bytes:t});for(let a of e.files){let u=r.get(a.urlhash);u&&i.push({url:a.putUrl,contentType:a.contentType,bytes:u})}e.events&&s?.eventsBytes&&i.push({url:e.events.putUrl,contentType:e.events.contentType,bytes:s.eventsBytes}),e.timeline&&s?.timelineBytes&&i.push({url:e.timeline.putUrl,contentType:e.timeline.contentType,bytes:s.timelineBytes}),e.flowVideo&&s?.videoBytes&&i.push({url:e.flowVideo.putUrl,contentType:e.flowVideo.contentType,bytes:s.videoBytes}),e.storage&&s?.storageBytes&&i.push({url:e.storage.putUrl,contentType:e.storage.contentType,bytes:s.storageBytes}),e.failureBundle&&s?.failureBundleBytes&&i.push({url:e.failureBundle.putUrl,contentType:e.failureBundle.contentType,bytes:s.failureBundleBytes});for(let a of e.snapshots??[]){let u=s?.snapshotBytes?.get(a.id);u&&i.push({url:a.putUrl,contentType:a.contentType,bytes:u})}return i}function dt(e){return e.replace(/\/+$/,"")}var K=class extends Error{constructor(r,s,i,a=""){super(r);this.status=s;this.phase=i;this.responseText=a;this.name="PresignedUploadError"}};async function Fe(e){let t=dt(e.originBase),r={"content-type":"application/json"};e.authHeader&&(r.authorization=e.authHeader),e.adminBypassToken&&(r["x-soot-admin-upload-bypass"]=e.adminBypassToken);let s=ae(3e4,"init"),i;try{i=await fetch(`${t}/api/preview/upload/init`,{method:"POST",headers:r,body:JSON.stringify(e.initBody),signal:s.signal})}finally{s.cancel()}if(!i.ok){let M=await i.text().catch(()=>"");throw new K(`init failed: ${i.status} ${M.slice(0,200)}`,i.status,"init",M)}let a=await i.json(),u=ct(a,e.bundleBytes,e.filesByHash,e.extras);await ut(u,e.concurrency??8,e.onPutProgress);let g=ae(3e4,"finalize"),d;try{d=await fetch(`${t}/api/preview/upload/finalize`,{method:"POST",headers:r,body:JSON.stringify({token:a.token}),signal:g.signal})}finally{g.cancel()}if(!d.ok){let M=await d.text().catch(()=>"");throw new K(`finalize failed: ${d.status} ${M.slice(0,200)}`,d.status,"finalize",M)}let R=await d.json();return{init:a,finalize:R}}function pt(e){return e!==null&&typeof e=="object"?e:null}function Oe(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function le(e){let t=pt(e);return t?t.schemaVersion===1&&Oe(t.t)!==void 0&&Oe(t.seq)!==void 0&&typeof t.context=="string"&&typeof t.kind=="string"&&"data"in t:!1}function ft(e,t){let r=[];for(let s of e.split(`
3
- `)){let i=s.trim();if(i)try{let a=JSON.parse(i);t(a)&&r.push(a)}catch{}}return r}function Ne(e){return ft(e,le)}function bt(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 wt(e){let t=JSON.parse(w(e,"utf8"));if(!Array.isArray(t))throw new Error("snapshot manifest must be an array");let r=new Set;return t.map((s,i)=>{if(s===null||typeof s!="object")throw new Error(`snapshot manifest entry ${i} must be an object`);let a=Reflect.get(s,"id"),u=Reflect.get(s,"label"),g=Reflect.get(s,"path"),d=Reflect.get(s,"t");if(typeof a!="string"||!a||r.has(a))throw new Error(`snapshot manifest entry ${i} has an invalid or duplicate id`);if(typeof g!="string"||!g)throw new Error(`snapshot manifest entry ${i} has no PNG path`);if(typeof d!="number"||!Number.isFinite(d)||d<0)throw new Error(`snapshot manifest entry ${i} has an invalid capture time`);r.add(a);let R=w(g);return{meta:{id:a,label:typeof u=="string"&&u?u:a,kind:"interaction",t:Math.round(d),contentType:"image/png",sizeBytes:R.byteLength},bytes:R}})}var Je=process.env.SOOTSIM_UPLOAD_ORIGIN||"https://sootbean.com",qe=process.env.SOOTSIM_PREVIEW_ORIGIN||"https://sootsim.com",de="http://localhost:3000",Mt=2e3;async function Tt(e){if(e)return e;if(process.env.SOOTSIM_UPLOAD_ORIGIN)return process.env.SOOTSIM_UPLOAD_ORIGIN;try{let t=await fetch(`${de}/api/preview/upload/init`,{method:"OPTIONS",signal:AbortSignal.timeout(Mt)});if(t.ok||t.status===204||t.status===405)return de}catch{}return Je}function F(e){return e.replace(/\/$/,"")}function St(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 vt(e){try{let t=new URL(e).hostname.toLowerCase();return t==="sootbean.com"||t.endsWith(".sootbean.com")}catch{return!1}}function xt(e,t){return t?F(t):process.env.SOOTSIM_PREVIEW_ORIGIN?F(process.env.SOOTSIM_PREVIEW_ORIGIN):St(e)?F(e):vt(e)?F(qe):F(e)}function kt(){console.log(`
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as Ue,b as _e,c as Pe}from"./chunk-ALE5MU5Z.js";import{c as Be}from"./chunk-FSKQZHM2.js";import{d as Ee}from"./chunk-PJBYZZWR.js";import{d as Ae}from"./chunk-UYLESZU3.js";import{g as Re,i as Ie,k as B}from"./chunk-SPJSTRXX.js";import{a as ke,b as E}from"./chunk-BHNOPI7I.js";import{a as xe}from"./chunk-2I62CFYI.js";import{createHash as ht}from"crypto";import{readFileSync as w}from"fs";import Ne from"path";import{gzipSync as ue,gunzipSync as yt}from"zlib";function Le(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 ot,constants as it}from"node:zlib";var at=9;function $e(e){return ot(e,{params:{[it.BROTLI_PARAM_QUALITY]:at}})}function ae(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 lt(e){let t=ae(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 ut(e,t=8,r){let s=0,i=0,a=e.length;await Promise.all(Array.from({length:Math.min(t,a)},async()=>{for(;s<a;){let u=e[s++];await lt(u),i++,r?.(i,a)}}))}function ct(e,t,r,s){let i=[];i.push({url:e.bundle.putUrl,contentType:e.bundle.contentType,bytes:t});for(let a of e.files){let u=r.get(a.urlhash);u&&i.push({url:a.putUrl,contentType:a.contentType,bytes:u})}e.events&&s?.eventsBytes&&i.push({url:e.events.putUrl,contentType:e.events.contentType,bytes:s.eventsBytes}),e.timeline&&s?.timelineBytes&&i.push({url:e.timeline.putUrl,contentType:e.timeline.contentType,bytes:s.timelineBytes}),e.flowVideo&&s?.videoBytes&&i.push({url:e.flowVideo.putUrl,contentType:e.flowVideo.contentType,bytes:s.videoBytes}),e.storage&&s?.storageBytes&&i.push({url:e.storage.putUrl,contentType:e.storage.contentType,bytes:s.storageBytes}),e.failureBundle&&s?.failureBundleBytes&&i.push({url:e.failureBundle.putUrl,contentType:e.failureBundle.contentType,bytes:s.failureBundleBytes});for(let a of e.snapshots??[]){let u=s?.snapshotBytes?.get(a.id);u&&i.push({url:a.putUrl,contentType:a.contentType,bytes:u})}return i}function dt(e){return e.replace(/\/+$/,"")}var K=class extends Error{constructor(r,s,i,a=""){super(r);this.status=s;this.phase=i;this.responseText=a;this.name="PresignedUploadError"}};async function Fe(e){let t=dt(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=ae(3e4,"init"),i;try{i=await fetch(`${t}/api/preview/upload/init`,{method:"POST",headers:r,body:JSON.stringify(e.initBody),signal:s.signal})}finally{s.cancel()}if(!i.ok){let M=await i.text().catch(()=>"");throw new K(`init failed: ${i.status} ${M.slice(0,200)}`,i.status,"init",M)}let a=await i.json(),u=ct(a,e.bundleBytes,e.filesByHash,e.extras);await ut(u,e.concurrency??8,e.onPutProgress);let g=ae(3e4,"finalize"),d;try{d=await fetch(`${t}/api/preview/upload/finalize`,{method:"POST",headers:r,body:JSON.stringify({token:a.token}),signal:g.signal})}finally{g.cancel()}if(!d.ok){let M=await d.text().catch(()=>"");throw new K(`finalize failed: ${d.status} ${M.slice(0,200)}`,d.status,"finalize",M)}let R=await d.json();return{init:a,finalize:R}}function pt(e){return e!==null&&typeof e=="object"?e:null}function Oe(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function le(e){let t=pt(e);return t?t.schemaVersion===1&&Oe(t.t)!==void 0&&Oe(t.seq)!==void 0&&typeof t.context=="string"&&typeof t.kind=="string"&&"data"in t:!1}function ft(e,t){let r=[];for(let s of e.split(`
3
+ `)){let i=s.trim();if(i)try{let a=JSON.parse(i);t(a)&&r.push(a)}catch{}}return r}function Ce(e){return ft(e,le)}function bt(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 wt(e){let t=JSON.parse(w(e,"utf8"));if(!Array.isArray(t))throw new Error("snapshot manifest must be an array");let r=new Set;return t.map((s,i)=>{if(s===null||typeof s!="object")throw new Error(`snapshot manifest entry ${i} must be an object`);let a=Reflect.get(s,"id"),u=Reflect.get(s,"label"),g=Reflect.get(s,"path"),d=Reflect.get(s,"t");if(typeof a!="string"||!a||r.has(a))throw new Error(`snapshot manifest entry ${i} has an invalid or duplicate id`);if(typeof g!="string"||!g)throw new Error(`snapshot manifest entry ${i} has no PNG path`);if(typeof d!="number"||!Number.isFinite(d)||d<0)throw new Error(`snapshot manifest entry ${i} has an invalid capture time`);r.add(a);let R=w(g);return{meta:{id:a,label:typeof u=="string"&&u?u:a,kind:"interaction",t:Math.round(d),contentType:"image/png",sizeBytes:R.byteLength},bytes:R}})}var Je=process.env.SOOTSIM_UPLOAD_ORIGIN||"https://contrast.dev",qe=process.env.SOOTSIM_PREVIEW_ORIGIN||"https://sootsim.com",de="http://localhost:3000",Mt=2e3;async function Tt(e){if(e)return e;if(process.env.SOOTSIM_UPLOAD_ORIGIN)return process.env.SOOTSIM_UPLOAD_ORIGIN;try{let t=await fetch(`${de}/api/preview/upload/init`,{method:"OPTIONS",signal:AbortSignal.timeout(Mt)});if(t.ok||t.status===204||t.status===405)return de}catch{}return Je}function F(e){return e.replace(/\/$/,"")}function St(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 vt(e){try{let t=new URL(e).hostname.toLowerCase();return t==="contrast.dev"||t.endsWith(".contrast.dev")}catch{return!1}}function xt(e,t){return t?F(t):process.env.SOOTSIM_PREVIEW_ORIGIN?F(process.env.SOOTSIM_PREVIEW_ORIGIN):St(e)?F(e):vt(e)?F(qe):F(e)}function kt(){console.log(`
4
4
  sootsim record upload \u2014 publish the current recorded bundle as a /preview/<id> link
5
5
 
6
6
  usage:
@@ -52,8 +52,8 @@ options:
52
52
  examples:
53
53
  sootsim record upload --events ./my-session.jsonl.gz
54
54
  sootsim record upload --origin http://localhost:3000 --events ./my-session.jsonl.gz --open
55
- sootsim record upload --video /tmp/soot-flow.mp4 --video-duration-ms 12000
56
- `)}function p(e,t){let r=e.findIndex(i=>i===t);if(r<0)return;let s=e[r+1];return e.splice(r,2),s}function ze(e,t){let r=e.findIndex(s=>s===t);return r<0?!1:(e.splice(r,1),!0)}function De(e,t){if(!e)return;let r=Number(e);return(!Number.isFinite(r)||r<=0)&&(console.error(` invalid ${t}: ${e}`),process.exit(1)),Math.round(r)}function je(e){let t=(e||"").toLowerCase().split(";")[0].trim();return t?!!(t.startsWith("image/")||t.startsWith("font/")||t.startsWith("video/")||t.startsWith("audio/")||t.startsWith("model/")||t==="text/css"||t==="application/javascript"||t==="text/javascript"||t==="application/wasm"||t==="application/font-woff"||t==="application/font-woff2"||t==="application/octet-stream"):!1}async function He(e){let t=await fetch(e);if(!t.ok)throw new Error(`fetch ${e} -> ${t.status} ${t.statusText}`);return new Uint8Array(await t.arrayBuffer())}function Et(e){return/\.bundle($|\?)/.test(e)||/\.js($|\?)/.test(e)?"application/javascript":/\.zip($|\?)/.test(e)?"application/zip":"application/javascript"}function Bt(e){try{return new URL(e).searchParams.get("appFonts")||""}catch{return""}}function Rt(e){try{return new URL(e).searchParams.get("appSplash")||""}catch{return""}}function It(e){try{let t=new URL(e);return t.searchParams.get("lazy")==="true"?(t.searchParams.set("lazy","false"),t.toString()):e}catch{return e}}async function At(e,t){let s=[];for(let i=0;i<t;i+=15e5){let a=Math.min(i+15e5,t),u=await B(e,`(window.__sootsimLastTransformedBundle?.text || "").slice(${i}, ${a})`);if(typeof u!="string")return null;s.push(u)}return s.join("")}function Ut(e){return e.recordedDurationMs&&e.recordingStartedAtMs?{since:e.recordingStartedAtMs-1e4,until:e.recordingStartedAtMs+e.recordedDurationMs+5e3,limit:2e3}:{limit:2e3}}function _t(e){let t=w(e),s=(t[0]===31&&t[1]===139?yt(t):t).toString("utf8");return Ne(s)}function Pt(e){return JSON.parse(w(e,"utf8"))}function Lt(e){if(e===null||typeof e!="object")return[];let t=e,r=typeof t.startedAtEpochMs=="number"&&t.startedAtEpochMs>0?t.startedAtEpochMs:null;if(r===null||!Array.isArray(t.samples))return[];let s=[];for(let i of t.samples){if(!Array.isArray(i)||typeof i[0]!="number")continue;let a=u=>typeof u=="number"&&Number.isFinite(u)?Math.round(u*100)/100:0;s.push({schemaVersion:1,t:r+Math.round(i[0]),seq:s.length+1,context:"tenant",kind:"frame",data:{totalMs:a(i[1]),layoutMs:a(i[2]),renderMs:a(i[3]),copyMs:a(i[4])}})}return s}function $t(e){if(e===null||typeof e!="object")return e;let{samples:t,...r}=e;return r}function ce(e){let t=new Map;for(let r of e)t.set(r.urlhash||r.url,r);return Array.from(t.values())}async function rn(e,t){(e.includes("--help")||e.includes("-h"))&&(kt(),process.exit(0));let r=[...e],s=await Tt(p(r,"--origin")),i=xt(s,p(r,"--public-origin")),a=p(r,"--events"),u=p(r,"--screenshot"),g=p(r,"--snapshot-manifest"),d=p(r,"--video"),R=p(r,"--timeline-events"),M=p(r,"--trace-frame-stats"),V=p(r,"--failure-bundle"),G=p(r,"--video-duration-ms"),pe=De(p(r,"--recorded-duration-ms"),"--recorded-duration-ms"),fe=De(p(r,"--recording-started-at-ms"),"--recording-started-at-ms"),W=p(r,"--owner"),Y=p(r,"--repo"),z=p(r,"--billing-kind"),Ke=p(r,"--run-scope"),Ve=ze(r,"--open");(W&&!Y||!W&&Y)&&(console.error(" --owner and --repo must be provided together"),process.exit(1)),z&&z!=="test_run"&&(console.error(` invalid --billing-kind: ${z}`),process.exit(1)),!a&&!d&&(console.error(" preview uploads require playback data: pass --events or --video.\n for a normal local preview, use `sootsim record --mode combined --open`\n or `sootsim maestro test --preview` instead of uploading a bundle-only snapshot."),process.exit(1));let me=ze(r,"--assets-only"),Ge=Re(r,{stripBooleanFlags:[],stripValueFlags:[]}),T=Ie(Ge),c,ge=[],S=[],v=R?_t(R):[],he=M?Pt(M):null;v.push(...Lt(he));let ye=v.length,Q=null;try{if(c=await B(T,'(typeof window.__sootsimCaptureBundle === "function") ? window.__sootsimCaptureBundle() : null'),c?.bundleUrl){let l=new URL(c.bundleUrl).origin,[f,_]=await Promise.all([B(T,`(window.__sootsimPreviewRecorder?.list?.(${JSON.stringify(l)}) || [])`),B(T,`(async () => {
55
+ sootsim record upload --video /tmp/sootsim-flow.mp4 --video-duration-ms 12000
56
+ `)}function p(e,t){let r=e.findIndex(i=>i===t);if(r<0)return;let s=e[r+1];return e.splice(r,2),s}function ze(e,t){let r=e.findIndex(s=>s===t);return r<0?!1:(e.splice(r,1),!0)}function De(e,t){if(!e)return;let r=Number(e);return(!Number.isFinite(r)||r<=0)&&(console.error(` invalid ${t}: ${e}`),process.exit(1)),Math.round(r)}function je(e){let t=(e||"").toLowerCase().split(";")[0].trim();return t?!!(t.startsWith("image/")||t.startsWith("font/")||t.startsWith("video/")||t.startsWith("audio/")||t.startsWith("model/")||t==="text/css"||t==="application/javascript"||t==="text/javascript"||t==="application/wasm"||t==="application/font-woff"||t==="application/font-woff2"||t==="application/octet-stream"):!1}async function He(e){let t=await fetch(e);if(!t.ok)throw new Error(`fetch ${e} -> ${t.status} ${t.statusText}`);return new Uint8Array(await t.arrayBuffer())}function Et(e){return/\.bundle($|\?)/.test(e)||/\.js($|\?)/.test(e)?"application/javascript":/\.zip($|\?)/.test(e)?"application/zip":"application/javascript"}function Bt(e){try{return new URL(e).searchParams.get("appFonts")||""}catch{return""}}function Rt(e){try{return new URL(e).searchParams.get("appSplash")||""}catch{return""}}function It(e){try{let t=new URL(e);return t.searchParams.get("lazy")==="true"?(t.searchParams.set("lazy","false"),t.toString()):e}catch{return e}}async function At(e,t){let s=[];for(let i=0;i<t;i+=15e5){let a=Math.min(i+15e5,t),u=await B(e,`(window.__sootsimLastTransformedBundle?.text || "").slice(${i}, ${a})`);if(typeof u!="string")return null;s.push(u)}return s.join("")}function Ut(e){return e.recordedDurationMs&&e.recordingStartedAtMs?{since:e.recordingStartedAtMs-1e4,until:e.recordingStartedAtMs+e.recordedDurationMs+5e3,limit:2e3}:{limit:2e3}}function _t(e){let t=w(e),s=(t[0]===31&&t[1]===139?yt(t):t).toString("utf8");return Ce(s)}function Pt(e){return JSON.parse(w(e,"utf8"))}function Lt(e){if(e===null||typeof e!="object")return[];let t=e,r=typeof t.startedAtEpochMs=="number"&&t.startedAtEpochMs>0?t.startedAtEpochMs:null;if(r===null||!Array.isArray(t.samples))return[];let s=[];for(let i of t.samples){if(!Array.isArray(i)||typeof i[0]!="number")continue;let a=u=>typeof u=="number"&&Number.isFinite(u)?Math.round(u*100)/100:0;s.push({schemaVersion:1,t:r+Math.round(i[0]),seq:s.length+1,context:"tenant",kind:"frame",data:{totalMs:a(i[1]),layoutMs:a(i[2]),renderMs:a(i[3]),copyMs:a(i[4])}})}return s}function $t(e){if(e===null||typeof e!="object")return e;let{samples:t,...r}=e;return r}function ce(e){let t=new Map;for(let r of e)t.set(r.urlhash||r.url,r);return Array.from(t.values())}async function rn(e,t){(e.includes("--help")||e.includes("-h"))&&(kt(),process.exit(0));let r=[...e],s=await Tt(p(r,"--origin")),i=xt(s,p(r,"--public-origin")),a=p(r,"--events"),u=p(r,"--screenshot"),g=p(r,"--snapshot-manifest"),d=p(r,"--video"),R=p(r,"--timeline-events"),M=p(r,"--trace-frame-stats"),V=p(r,"--failure-bundle"),G=p(r,"--video-duration-ms"),pe=De(p(r,"--recorded-duration-ms"),"--recorded-duration-ms"),fe=De(p(r,"--recording-started-at-ms"),"--recording-started-at-ms"),W=p(r,"--owner"),Y=p(r,"--repo"),z=p(r,"--billing-kind"),Ke=p(r,"--run-scope"),Ve=ze(r,"--open");(W&&!Y||!W&&Y)&&(console.error(" --owner and --repo must be provided together"),process.exit(1)),z&&z!=="test_run"&&(console.error(` invalid --billing-kind: ${z}`),process.exit(1)),!a&&!d&&(console.error(" preview uploads require playback data: pass --events or --video.\n for a normal local preview, use `sootsim record --mode combined --open`\n or `sootsim maestro test --preview` instead of uploading a bundle-only snapshot."),process.exit(1));let me=ze(r,"--assets-only"),Ge=Re(r,{stripBooleanFlags:[],stripValueFlags:[]}),T=Ie(Ge),c,ge=[],S=[],v=R?_t(R):[],he=M?Pt(M):null;v.push(...Lt(he));let ye=v.length,Q=null;try{if(c=await B(T,'(typeof window.__sootsimCaptureBundle === "function") ? window.__sootsimCaptureBundle() : null'),c?.bundleUrl){let l=new URL(c.bundleUrl).origin,[f,_]=await Promise.all([B(T,`(window.__sootsimPreviewRecorder?.list?.(${JSON.stringify(l)}) || [])`),B(T,`(async () => {
57
57
  const list = window.__sootsimListWorkerFetchRecorder
58
58
  return typeof list === 'function'
59
59
  ? await list(${JSON.stringify(l)})
@@ -65,7 +65,7 @@ examples:
65
65
  main: rec?.list ? rec.list() : [],
66
66
  worker: typeof workerList === 'function' ? await workerList() : [],
67
67
  }
68
- })()`),C=($?ce([...$.main,...$.worker]):[]).filter(m=>{try{return new URL(m.url).origin!==l}catch{return!1}}),k=C.length>0?{count:C.length,totalBytes:C.reduce((m,oe)=>m+(oe.size||0),0)}:null;if(k&&k.count>0){console.log(` ${k.count} recorded cross-origin responses (${(k.totalBytes/1024).toFixed(1)} KiB)`);let m=await B(T,`(async () => {
68
+ })()`),N=($?ce([...$.main,...$.worker]):[]).filter(m=>{try{return new URL(m.url).origin!==l}catch{return!1}}),k=N.length>0?{count:N.length,totalBytes:N.reduce((m,oe)=>m+(oe.size||0),0)}:null;if(k&&k.count>0){console.log(` ${k.count} recorded cross-origin responses (${(k.totalBytes/1024).toFixed(1)} KiB)`);let m=await B(T,`(async () => {
69
69
  const rec = window.__sootsimPreviewRecorder
70
70
  const workerDump = window.__sootsimDumpWorkerFetchRecorder
71
71
  const bundleUrl = ${JSON.stringify(c.bundleUrl)}
@@ -95,5 +95,5 @@ examples:
95
95
  })()`).catch(l=>(console.warn(` warning: failed to capture trace timeline: ${l instanceof Error?l.message:String(l)}`),null)),o=Array.isArray(n?.events)?n.events:[];v=[...v,...o.filter(le)].sort((l,f)=>l.t-f.t||l.seq-f.seq)}finally{T.close()}c||(console.error(" could not read bundle snapshot \u2014 is sootsim running and is the bundle loaded?"),process.exit(2)),c.bundleUrl||(console.error(` no ?bundle= URL on the current sootsim tab.
96
96
  open the app you want to share first (e.g. sootsim open 8082), then run upload.`),process.exit(2));let h,X=!1;if(Q!==null)h=new TextEncoder().encode(Q),X=!0,console.log(` using post-transform bundle: ${(h.byteLength/1024).toFixed(1)} KiB`);else{let n=It(c.bundleUrl);n!==c.bundleUrl&&console.log(" forcing lazy=false for self-contained bundle"),console.log(` capturing: ${n}`),h=await He(n),console.log(` main bundle: ${(h.byteLength/1024).toFixed(1)} KiB`)}let D=ge.filter(n=>n.url!==c.bundleUrl);me&&(D=D.filter(n=>je(n.contentType))),console.log(` fetching ${D.length} extra files\u2026`);let j=(await Promise.all(D.map(async n=>{try{let o=await He(n.url);return{...n,bytes:o}}catch(o){return console.error(` warning: failed to re-fetch ${n.url}: ${o instanceof Error?o.message:o}`),null}}))).filter(n=>!!n),We=j.reduce((n,o)=>n+o.bytes.byteLength,0);console.log(` ${j.length} extra files: ${(We/1024).toFixed(1)} KiB`);let I;a&&(I=w(a)),v.sort((n,o)=>n.t-o.t||n.seq-o.seq);let be=v.map(n=>JSON.stringify(n)).join(`
97
97
  `),Z=ue(be?`${be}
98
- `:"");console.log(` trace timeline: ${v.length} events${ye?` (${ye} from runner sidecars)`:""}`);let y;u&&(y=w(u),console.log(` attaching screenshot: ${(y.byteLength/1024).toFixed(1)} KiB`));let O=g?wt(g):[];O.length>0&&console.log(` attaching ${O.length} interaction snapshots`);let A,U;if(V){let n=f=>{try{return w(Ce.join(V,f),"utf8")}catch{return null}},o=f=>{let _=n(f);if(_===null)return null;try{return JSON.parse(_)}catch{return _}},l={error:o("error.json"),describe:o("describe.json"),console:o("console.json"),a11y:n("a11y.txt"),tree:n("tree.txt")};Object.values(l).some(f=>f!==null)&&(A=ue(JSON.stringify(l)),console.log(` attaching failure bundle: ${(A.byteLength/1024).toFixed(1)} KiB gz`));try{U=w(Ce.join(V,"screenshot.png"))}catch{}}let x,N,we;if(d){if(x=w(d),N=d.endsWith(".mp4")?"video/mp4":d.endsWith(".gif")?"image/gif":void 0,N||(console.error(" preview flow videos must be mp4 or gif"),await E(),process.exit(1)),G){let n=Number(G);(!Number.isFinite(n)||n<=0)&&(console.error(` invalid --video-duration-ms: ${G}`),await E(),process.exit(1)),we=Math.round(n)}console.log(` attaching flow video: ${(x.byteLength/1024).toFixed(1)} KiB (${N})`)}let P=Ue(),L=Pe(P),Ye=xe();ke({event:"preview_upload_started",identity:{userId:P?.kind==="session"?Ye?.user?.id??null:null,repoId:L?.repoId??null,installationId:L?.installationId??null},properties:{origin:s,hasAuth:!!P,authMode:P?.kind??"none",bundleBytes:h.byteLength,isTransformed:X,extraFiles:j.length,recordedFetches:S.length,hasEvents:!!I,traceTimelineEvents:v.length,hasScreenshot:!!y,hasVideo:!!x}}),P||(console.error(" preview uploads need auth."),console.error(" set SOOTSIM_API_KEY=sk_sootsim_..., run `sootsim login`, or use the soot github runner."),await E(),process.exit(1));let Qe=_e(P),Xe=(()=>{try{return new URL(c.bundleUrl).origin}catch{return null}})(),H=(n,o,l,f,_,$,ve,C)=>{let k=Le($),m=k?ue(n):n;return{url:o,urlhash:l,method:f,bodyHash:_,requestVaryHash:C,contentType:$,responseHeaders:ve,bytes:m,encoding:k?"gzip":void 0}},Me=[],ee=Bt(c.pageHref)||"";if(ee){let n=await Ee(ee,{onStaged:({url:o,byteLength:l})=>console.log(` staged app font: ${o} (${(l/1024).toFixed(1)} KiB)`),onError:(o,l)=>console.error(` warning: failed to fetch app font ${o}: ${l instanceof Error?l.message:l}`)});for(let o of n)Me.push(H(Buffer.from(o.bytes),o.url,o.urlhash,"GET","-",o.contentType))}let Te=[],te=Rt(c.pageHref)||"";if(te){let n=await Be(te,{onStaged:({url:o,byteLength:l})=>console.log(` staged splash image: ${o} (${(l/1024).toFixed(1)} KiB)`),onError:(o,l)=>console.error(` warning: failed to fetch splash image ${o}: ${l instanceof Error?l.message:l}`)});for(let o of n)Te.push(H(Buffer.from(o.bytes),o.url,o.urlhash,"GET","-",o.contentType))}let ne=[...j.map(n=>H(n.bytes,n.url,n.urlhash,"GET","-",n.contentType,n.responseHeaders,n.requestVaryHash)),...S.map(n=>H(Buffer.from(n.bodyBase64,"base64"),n.url,n.urlhash,n.method||"GET",n.bodyHash||"-",n.contentType,n.responseHeaders,n.requestVaryHash)),...Me,...Te],re=$e(h),Ze=ht("sha256").update(h).digest("hex");console.log(` bundle raw=${(h.byteLength/1024).toFixed(1)} KiB br=${(re.byteLength/1024).toFixed(1)} KiB`);let et={contentHash:Ze,bundleSizeBytes:h.byteLength,bundleContentType:Et(c.bundleUrl),bundleEncoding:"br",bundleOrigin:Xe,runtimeVersion:c.runtimeVersion??void 0,appFonts:ee||void 0,appSplash:te||void 0,entry:c.entry,isTransformed:X,deviceSpec:c.deviceSpec,installationId:L?.installationId??void 0,repoId:L?.repoId,owner:W??L?.owner,repo:Y??L?.repo,billingKind:z==="test_run"?"test_run":void 0,runScope:Ke||void 0,files:ne.map(n=>({url:n.url,urlhash:n.urlhash,method:n.method,bodyHash:n.bodyHash,contentType:n.contentType,responseHeaders:n.responseHeaders,requestVaryHash:n.requestVaryHash,encoding:n.encoding,sizeBytes:n.bytes.byteLength})),events:I?{sizeBytes:I.byteLength}:void 0,timeline:{sizeBytes:Z.byteLength,encoding:"gzip"},traceFrameStats:$t(he),recordedDurationMs:pe,recordingStartedAtMs:fe,failureBundle:A?{sizeBytes:A.byteLength,encoding:"gzip"}:void 0,snapshots:(()=>{let n=[];y&&n.push({id:"landing",label:"Landing",kind:"landing",t:0,contentType:"image/png",sizeBytes:y.byteLength}),U&&n.push({id:"failure",label:"Failure",kind:"failure",contentType:"image/png",sizeBytes:U.byteLength});for(let o of O)n.push(o.meta);return n.length>0?n:void 0})(),flowVideo:x&&N?{sizeBytes:x.byteLength,contentType:N,durationMs:we}:void 0},Se=new Map;for(let n of ne)Se.set(n.urlhash,n.bytes);let J=new Map;y&&J.set("landing",y),U&&J.set("failure",U);for(let n of O)J.set(n.meta.id,n.bytes);let tt=Date.now(),b=re.byteLength;for(let n of ne)b+=n.bytes.byteLength;I&&(b+=I.byteLength),b+=Z.byteLength,y&&(b+=y.byteLength),U&&(b+=U.byteLength);for(let n of O)b+=n.bytes.byteLength;A&&(b+=A.byteLength),x&&(b+=x.byteLength);let nt=`${F(s)}/api/preview/upload/init`;console.log(` init: ${nt}`);let q;try{let n=await Fe({originBase:s,initBody:et,bundleBytes:re,filesByHash:Se,extras:{eventsBytes:I,timelineBytes:Z,videoBytes:x,failureBundleBytes:A,snapshotBytes:J},authHeader:Qe,concurrency:16});q=n.finalize;let o=1+n.init.files.length+(n.init.events?1:0)+(n.init.timeline?1:0)+n.init.snapshots.length+(n.init.flowVideo?1:0)+(n.init.failureBundle?1:0);console.log(` PUT ${o} objects in ${Date.now()-tt}ms (${(b/1024).toFixed(1)} KiB)`)}catch(n){let o=n;o.phase==="init"&&o.status===401&&(console.error(" preview upload requires a valid login."),console.error(" run `sootsim login` and retry."),await E(),process.exit(1)),o.status===402&&(console.error(` ${bt(o.responseText)??"preview uploads require Personal, Team, or an active trial \u2014 upgrade from the billing dialog."}`),await E(),process.exit(1)),console.error(` ${o.message??`${o.phase??"upload"} failed: ${String(n)}`}`),await E(),process.exit(1)}let se=`${i}${q.url}`;return console.log(`
98
+ `:"");console.log(` trace timeline: ${v.length} events${ye?` (${ye} from runner sidecars)`:""}`);let y;u&&(y=w(u),console.log(` attaching screenshot: ${(y.byteLength/1024).toFixed(1)} KiB`));let O=g?wt(g):[];O.length>0&&console.log(` attaching ${O.length} interaction snapshots`);let A,U;if(V){let n=f=>{try{return w(Ne.join(V,f),"utf8")}catch{return null}},o=f=>{let _=n(f);if(_===null)return null;try{return JSON.parse(_)}catch{return _}},l={error:o("error.json"),describe:o("describe.json"),console:o("console.json"),a11y:n("a11y.txt"),tree:n("tree.txt")};Object.values(l).some(f=>f!==null)&&(A=ue(JSON.stringify(l)),console.log(` attaching failure bundle: ${(A.byteLength/1024).toFixed(1)} KiB gz`));try{U=w(Ne.join(V,"screenshot.png"))}catch{}}let x,C,we;if(d){if(x=w(d),C=d.endsWith(".mp4")?"video/mp4":d.endsWith(".gif")?"image/gif":void 0,C||(console.error(" preview flow videos must be mp4 or gif"),await E(),process.exit(1)),G){let n=Number(G);(!Number.isFinite(n)||n<=0)&&(console.error(` invalid --video-duration-ms: ${G}`),await E(),process.exit(1)),we=Math.round(n)}console.log(` attaching flow video: ${(x.byteLength/1024).toFixed(1)} KiB (${C})`)}let P=Ue(),L=Pe(P),Ye=xe();ke({event:"preview_upload_started",identity:{userId:P?.kind==="session"?Ye?.user?.id??null:null,repoId:L?.repoId??null,installationId:L?.installationId??null},properties:{origin:s,hasAuth:!!P,authMode:P?.kind??"none",bundleBytes:h.byteLength,isTransformed:X,extraFiles:j.length,recordedFetches:S.length,hasEvents:!!I,traceTimelineEvents:v.length,hasScreenshot:!!y,hasVideo:!!x}}),P||(console.error(" preview uploads need auth."),console.error(" set SOOTSIM_API_KEY=sk_sootsim_..., run `sootsim login`, or use the Contrast github runner."),await E(),process.exit(1));let Qe=_e(P),Xe=(()=>{try{return new URL(c.bundleUrl).origin}catch{return null}})(),H=(n,o,l,f,_,$,ve,N)=>{let k=Le($),m=k?ue(n):n;return{url:o,urlhash:l,method:f,bodyHash:_,requestVaryHash:N,contentType:$,responseHeaders:ve,bytes:m,encoding:k?"gzip":void 0}},Me=[],ee=Bt(c.pageHref)||"";if(ee){let n=await Ee(ee,{onStaged:({url:o,byteLength:l})=>console.log(` staged app font: ${o} (${(l/1024).toFixed(1)} KiB)`),onError:(o,l)=>console.error(` warning: failed to fetch app font ${o}: ${l instanceof Error?l.message:l}`)});for(let o of n)Me.push(H(Buffer.from(o.bytes),o.url,o.urlhash,"GET","-",o.contentType))}let Te=[],te=Rt(c.pageHref)||"";if(te){let n=await Be(te,{onStaged:({url:o,byteLength:l})=>console.log(` staged splash image: ${o} (${(l/1024).toFixed(1)} KiB)`),onError:(o,l)=>console.error(` warning: failed to fetch splash image ${o}: ${l instanceof Error?l.message:l}`)});for(let o of n)Te.push(H(Buffer.from(o.bytes),o.url,o.urlhash,"GET","-",o.contentType))}let ne=[...j.map(n=>H(n.bytes,n.url,n.urlhash,"GET","-",n.contentType,n.responseHeaders,n.requestVaryHash)),...S.map(n=>H(Buffer.from(n.bodyBase64,"base64"),n.url,n.urlhash,n.method||"GET",n.bodyHash||"-",n.contentType,n.responseHeaders,n.requestVaryHash)),...Me,...Te],re=$e(h),Ze=ht("sha256").update(h).digest("hex");console.log(` bundle raw=${(h.byteLength/1024).toFixed(1)} KiB br=${(re.byteLength/1024).toFixed(1)} KiB`);let et={contentHash:Ze,bundleSizeBytes:h.byteLength,bundleContentType:Et(c.bundleUrl),bundleEncoding:"br",bundleOrigin:Xe,runtimeVersion:c.runtimeVersion??void 0,appFonts:ee||void 0,appSplash:te||void 0,entry:c.entry,isTransformed:X,deviceSpec:c.deviceSpec,installationId:L?.installationId??void 0,repoId:L?.repoId,owner:W??L?.owner,repo:Y??L?.repo,billingKind:z==="test_run"?"test_run":void 0,runScope:Ke||void 0,files:ne.map(n=>({url:n.url,urlhash:n.urlhash,method:n.method,bodyHash:n.bodyHash,contentType:n.contentType,responseHeaders:n.responseHeaders,requestVaryHash:n.requestVaryHash,encoding:n.encoding,sizeBytes:n.bytes.byteLength})),events:I?{sizeBytes:I.byteLength}:void 0,timeline:{sizeBytes:Z.byteLength,encoding:"gzip"},traceFrameStats:$t(he),recordedDurationMs:pe,recordingStartedAtMs:fe,failureBundle:A?{sizeBytes:A.byteLength,encoding:"gzip"}:void 0,snapshots:(()=>{let n=[];y&&n.push({id:"landing",label:"Landing",kind:"landing",t:0,contentType:"image/png",sizeBytes:y.byteLength}),U&&n.push({id:"failure",label:"Failure",kind:"failure",contentType:"image/png",sizeBytes:U.byteLength});for(let o of O)n.push(o.meta);return n.length>0?n:void 0})(),flowVideo:x&&C?{sizeBytes:x.byteLength,contentType:C,durationMs:we}:void 0},Se=new Map;for(let n of ne)Se.set(n.urlhash,n.bytes);let J=new Map;y&&J.set("landing",y),U&&J.set("failure",U);for(let n of O)J.set(n.meta.id,n.bytes);let tt=Date.now(),b=re.byteLength;for(let n of ne)b+=n.bytes.byteLength;I&&(b+=I.byteLength),b+=Z.byteLength,y&&(b+=y.byteLength),U&&(b+=U.byteLength);for(let n of O)b+=n.bytes.byteLength;A&&(b+=A.byteLength),x&&(b+=x.byteLength);let nt=`${F(s)}/api/preview/upload/init`;console.log(` init: ${nt}`);let q;try{let n=await Fe({originBase:s,initBody:et,bundleBytes:re,filesByHash:Se,extras:{eventsBytes:I,timelineBytes:Z,videoBytes:x,failureBundleBytes:A,snapshotBytes:J},authHeader:Qe,concurrency:16});q=n.finalize;let o=1+n.init.files.length+(n.init.events?1:0)+(n.init.timeline?1:0)+n.init.snapshots.length+(n.init.flowVideo?1:0)+(n.init.failureBundle?1:0);console.log(` PUT ${o} objects in ${Date.now()-tt}ms (${(b/1024).toFixed(1)} KiB)`)}catch(n){let o=n;o.phase==="init"&&o.status===401&&(console.error(" preview upload requires a valid login."),console.error(" run `sootsim login` and retry."),await E(),process.exit(1)),o.status===402&&(console.error(` ${bt(o.responseText)??"preview uploads require Personal, Team, or an active trial \u2014 upgrade from the billing dialog."}`),await E(),process.exit(1)),console.error(` ${o.message??`${o.phase??"upload"} failed: ${String(n)}`}`),await E(),process.exit(1)}let se=`${i}${q.url}`;return console.log(`
99
99
  stored ${q.filesStored??0} extra files`),console.log(` preview: ${se}`),Ve&&await Ae(se),await E(),{previewUrl:se,shareId:q.id}}export{Tt as a,xt as b,rn as c};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var t=4001,r="sootsim close";var o="http://localhost:5173/";export{t as a,r as b,o as c};
@@ -0,0 +1,3 @@
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ 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 C(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=C(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 S(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(`
3
+ `).filter(Boolean)}catch{}for(let n of r)h(Number(n));try{process.kill(e,"SIGKILL")}catch{}}function f(e){let r=e;if(!r||typeof r!="object")return null;if(typeof r.newBrowserCDPSession=="function"||typeof r.process=="function")return r;if(typeof r.browser!="function")return null;try{let n=r.browser();return n?f(n):null}catch{return null}}function m(e,r,n){e&&typeof e=="object"&&p.set(e,n),p.set(r,n),u.add(n),B()}async function N(e){let r=w(e);if(r!==null)return r;let n=f(e);if(!n||typeof n.newBrowserCDPSession!="function")return null;let o=await n.newBrowserCDPSession();try{let s=S(await o.send("SystemInfo.getProcessInfo"));return s===null?null:(m(e,n,s),s)}finally{await o.detach?.()}}async function j(e){let r=w(e);if(r!==null){u.delete(r),h(r);return}let n=e;if(n&&typeof n.close=="function")try{await n.close()}catch{}}async function T(e,r,n){if(g(r))return;let o=w(e),s=f(e);if(o!==null&&s&&m(e,s,o),o!==null&&(r.platform==="darwin"||r.platform==="linux")){let t=b("ps",["-p",String(o),"-o","command="],{encoding:"utf8"}).trim();P(t,r)}let a=n?await n(e):e,i=f(a);if(i&&typeof i.newBrowserCDPSession=="function"){let t=await i.newBrowserCDPSession();try{let c=S(await t.send("SystemInfo.getProcessInfo"));if(c===null)throw new Error("[reap-browser] Chrome did not report its browser process id");if(m(e,i,c),a&&typeof a=="object"&&p.set(a,c),r.platform==="darwin"||r.platform==="linux"){let l=b("ps",["-p",String(c),"-o","command="],{encoding:"utf8"}).trim();P(l,r)}L(await t.send("SystemInfo.getInfo"),r);return}finally{await t.detach?.()}}throw new Error("[reap-browser] could not validate the launched Chrome GPU renderer")}function B(){if(y)return;y=!0;let e=()=>{for(let r of u)h(r)};process.on("SIGTERM",()=>{e(),process.exit(0)}),process.on("SIGINT",()=>{e(),process.exit(0)}),process.on("exit",e)}async function R(e){let r=await e(),n=w(r);if(n===null)try{n=await N(r)}catch{n=null}let o=new Set;n!=null&&(o.add(n),u.add(n),B());let s=f(r)??r;if(typeof s.on=="function"){let i=typeof s.newBrowserCDPSession=="function"?"disconnected":"close";s.on(i,()=>{for(let t of o)u.delete(t)})}return{browser:r,reapNow:()=>{for(let i of o)h(i),u.delete(i);o.clear()}}}async function $(e){let{browser:r}=await R(e);return r}var k=!1;function D(e=process.platform){return[`--use-angle=${C(e)}`,"--enable-gpu","--enable-gpu-rasterization","--enable-zero-copy","--ignore-gpu-blocklist"]}function W(e={},r=d()){let n=Array.isArray(e.args)?e.args:[],o=n.find(I);if(o!==void 0)throw new Error(`[reap-browser] refused software-rendering Chrome launch argument ${String(o)}`);if(e.executablePath!==void 0)throw new Error("[reap-browser] executablePath bypasses Playwright Chrome for Testing and is not allowed");if(e.ignoreDefaultArgs===!0)throw new Error("[reap-browser] ignoreDefaultArgs=true bypasses required Chrome launch defaults");let s=new Set(["--enable-gpu","--enable-gpu-rasterization","--enable-zero-copy","--ignore-gpu-blocklist"]),a=n.filter(c=>{let l=String(c);return!s.has(l)&&!l.startsWith("--use-angle=")}),i=Array.isArray(e.ignoreDefaultArgs)?e.ignoreDefaultArgs:[],t=[...new Set([...i,"--disable-gpu","--enable-unsafe-swiftshader"])];return{...e,channel:"chromium",args:[...a,...D(r.platform)],ignoreDefaultArgs:t}}function x(e,r,n){return async()=>{let o=d(),s=g(o),a=W(r,o);if(!k){let i;try{i=await e(a)}catch(t){let c=t instanceof Error?t.message:String(t);if(!/not found at|not installed|Chromium distribution|Executable doesn't exist|No such file/i.test(c))throw t;if(!s)throw new Error("[reap-browser] Playwright Chrome for Testing is required for local GPU browser work; chromium_headless_shell fallback is disabled. Run `bunx playwright install chromium`.",{cause:t});return k=!0,console.warn("[reap-browser] GitHub Actions Linux Chrome for Testing not found, falling back to chromium_headless_shell software rendering."),e(v(r))}try{await T(i,o,n)}catch(t){throw await j(i),t}return i}return e(v(r))}}function v(e){let r={...e};return delete r.channel,delete r.executablePath,r}async function _(e,r={},n){return $(x(e,r,n))}async function z(e,r={},n){return R(x(e,r,n))}export{_ as a,z as b};
@@ -1,6 +1,6 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as m,b as _}from"./chunk-HXSV263V.js";import{a as w,b as I,c as E}from"./chunk-3L5EXWCP.js";import{c as k}from"./chunk-E75EBS77.js";import{G as O,o as D,q as f}from"./chunk-NU755HCE.js";import h from"fs";import v from"path";var c="default",$="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(),$)}function G(e){return`sootsim-profile-${s(e)}`}function B(e){return v.join(D(),"Partitions",G(e))}function b(e){return v.join(f(),"playwright",s(e))}function y(){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 T(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:T(e.profiles)};let r=new Date().toISOString();return{version:a,profiles:T([{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)}
3
- `,"utf8"),h.renameSync(t,g()),r}function q(){return S(y()).profiles}function j(e){let r=s(e);return q().find(t=>t.id===r)??null}function A(e=c){let r=s(e),t=j(r);return t||H(r)}function H(e){let r=s(e),t=P(y());if(t.profiles.some(n=>n.id===r))throw new Error(`profile already exists: ${r}`);let o=new Date().toISOString(),i={id:r,createdAt:o,updatedAt:o};return S({version:a,profiles:[...t.profiles,i]}),i}function pe(e){let r=s(e);if(r===c)throw new Error("the default profile cannot be deleted; clear it instead");let t=P(y()),o=t.profiles.find(i=>i.id===r);if(!o)throw new Error(`profile not found: ${r}`);return S({version:a,profiles:t.profiles.filter(i=>i.id!==r)}),z(r),o}function z(e){let r=s(e);for(let t of[B(r),b(r)])try{h.rmSync(t,{recursive:!0,force:!0})}catch{}}function K(){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 Y(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 E(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 C={id:"chromium",name:"chromium",description:"system chrome / chromium / edge \u2014 visible window (headless: use playwright)",kind:"browser",availability:K,launch:Y};function V(){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 J(e){let r=m();if(!r)return{launched:!1,message:"sootsim desktop app not installed"};try{let t=await _(e.url,r,{device:e.device,profileId:e.profileId,ephemeralProfile:e.ephemeralProfile});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 M={id:"electron",name:"electron",description:"sootsim desktop companion app (native window, menu bar)",kind:"native",availability:V,launch:J};import{spawn as X}from"child_process";import{closeSync as Z,mkdtempSync as Q,openSync as ee,readFileSync as re}from"fs";import{createRequire as te}from"module";import{tmpdir as L}from"os";import{join as R}from"path";var oe=`
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as m,b as E}from"./chunk-NCXHUU7N.js";import{a as w,b as T,c as A}from"./chunk-UYLESZU3.js";import{a as _,d as I}from"./chunk-EPQ5EZBJ.js";import{G as k,o as O,q as f}from"./chunk-PNPH4JLS.js";import h from"fs";import v from"path";var c="default",q="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(),q)}function j(e){return`sootsim-profile-${s(e)}`}function H(e){return v.join(O(),"Partitions",j(e))}function b(e){return v.join(f(),"playwright",s(e))}function y(){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 C(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:C(e.profiles)};let r=new Date().toISOString();return{version:a,profiles:C([{id:c,createdAt:r,updatedAt:r},...e.profiles])}}function S(e){k();let r=P(e),t=`${g()}.tmp`;return h.writeFileSync(t,`${JSON.stringify(r,null,2)}
3
+ `,"utf8"),h.renameSync(t,g()),r}function z(){return S(y()).profiles}function K(e){let r=s(e);return z().find(t=>t.id===r)??null}function M(e=c){let r=s(e),t=K(r);return t||Y(r)}function Y(e){let r=s(e),t=P(y());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 we(e){let r=s(e);if(r===c)throw new Error("the default profile cannot be deleted; clear it instead");let t=P(y()),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)}),V(r),o}function V(e){let r=s(e);for(let t of[H(r),b(r)])try{h.rmSync(t,{recursive:!0,force:!0})}catch{}}function J(){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 X(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 A(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 L={id:"chromium",name:"chromium",description:"system chrome / chromium / edge \u2014 visible window (headless: use playwright)",kind:"browser",availability:J,launch:X};function Z(){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 Q(e){let r=m();if(!r)return{launched:!1,message:"sootsim desktop app not installed"};try{let t=await E(e.url,r,{device:e.device,profileId:e.profileId,ephemeralProfile:e.ephemeralProfile});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 R={id:"electron",name:"electron",description:"sootsim desktop companion app (native window, menu bar)",kind:"native",availability:Z,launch:Q};import{spawn as ee}from"child_process";import{closeSync as re,mkdtempSync as te,openSync as oe,readFileSync as ie}from"fs";import{createRequire as ne}from"module";import{tmpdir as W}from"os";import{join as N}from"path";var se=`
4
4
  const modulePath = process.env.SOOTSIM_PW_MODULE;
5
5
  const url = process.env.SOOTSIM_PW_URL;
6
6
  // the WS bridge port the sim page must register with, injected below as
@@ -462,6 +462,6 @@ const cleanupProfile = () => {
462
462
  process.stderr.write(String((err && err.stack) || err) + '\\n');
463
463
  process.exit(1);
464
464
  });
465
- `;function W(){let e=[process.cwd()+"/"];try{process.argv[1]&&e.push(process.argv[1])}catch{}for(let r of e)try{let t=te(r);for(let o of["playwright","playwright-chromium","playwright-core"])try{return{spec:o,modulePath:t.resolve(o)}}catch{}}catch{}return null}function ie(){let e=W();return e?{available:!0,reason:null,detail:`resolved via ${e.spec}`}:{available:!1,reason:"playwright not installed in the current workspace"}}function ne(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 se(e){return e.profileId?b(A(e.profileId).id):e.ephemeralProfile?Q(R(L(),"sootsim-playwright-profile-")):""}async function ae(e){let r=W();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=R(L(),`sootsim-playwright-host-${Date.now().toString(36)}-${process.pid}.log`),o=`${t}.connected`,i=ee(t,"a");try{let n=k(),p=X(process.execPath,["-e",oe],{detached:!0,stdio:["ignore","ignore",i],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:se(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:n&&n>1?String(n):""}});p.unref();let x=await new Promise(l=>{let u=setTimeout(()=>l(null),4e3);p.once("exit",U=>{clearTimeout(u),l(U??0)})});if(x!==null){let l=re(t,"utf8").trim(),u=ne(e,l);return{launched:!1,message:`playwright host exited early (code ${x}) \u2014 host log ${t}${l?`:
465
+ `;function $(){let e=[process.cwd()+"/"];try{process.argv[1]&&e.push(process.argv[1])}catch{}for(let r of e)try{let t=ne(r);for(let o of["playwright","playwright-chromium","playwright-core"])try{return{spec:o,modulePath:t.resolve(o)}}catch{}}catch{}return null}function ae(){let e=$();return e?{available:!0,reason:null,detail:`resolved via ${e.spec}`}:{available:!1,reason:"playwright not installed in the current workspace"}}function le(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 ce(e){return e.profileId?b(M(e.profileId).id):e.ephemeralProfile?te(N(W(),"sootsim-playwright-profile-")):""}async function de(e){let r=$();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(W(),`sootsim-playwright-host-${Date.now().toString(36)}-${process.pid}.log`),o=`${t}.connected`,n=oe(t,"a");try{let i=I(),p=ee(process.execPath,["-e",se],{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:ce(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 x=await new Promise(l=>{let u=setTimeout(()=>l(null),4e3);p.once("exit",B=>{clearTimeout(u),l(B??0)})});if(x!==null){let l=ie(t,"utf8").trim(),u=le(e,l);return{launched:!1,message:`playwright host exited early (code ${x}) \u2014 host log ${t}${l?`:
466
466
  ${l}`:""}${u?`
467
- ${u}`:""}`}}return{launched:!0,message:`playwright chrome launched \u2192 ${e.url}`,pid:p.pid,target:r.spec,attachUrl:e.url,connectAckFile:o,diagnosticLogPath:t}}catch(n){return{launched:!1,message:`playwright launch failed: ${n instanceof Error?n.message:String(n)}`}}finally{Z(i)}}var N={id:"playwright",name:"playwright",description:"programmatic chromium via the playwright package \u2014 headless default",kind:"automation",availability:ie,launch:ae};function le(){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 ce(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 I(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 F={id:"system",name:"system",description:"shared browser launcher \u2014 system default or chromium window",kind:"delegate",availability:le,launch:ce};var d=[C,M,N,F];function Me(){return d}function Le(e){return d.find(r=>r.id===e)??null}function Re(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 We(){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{q as a,A as b,H as c,pe as d,z as e,C as f,M as g,N as h,F as i,d as j,Me as k,Le as l,Re as m,We as n};
467
+ ${u}`:""}`}}let D=i&&i>1?_(i):null,G=i&&i>1?` \u2014 browser closes when pid ${i}${D?` (${D})`:""} exits`:"";return{launched:!0,message:`playwright chrome launched \u2192 ${e.url}${G}`,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{re(n)}}var F={id:"playwright",name:"playwright",description:"programmatic chromium via the playwright package \u2014 headless default",kind:"automation",availability:ae,launch:de};function ue(){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 he(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 T(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 U={id:"system",name:"system",description:"shared browser launcher \u2014 system default or chromium window",kind:"delegate",availability:ue,launch:he};var d=[L,R,F,U];function Ne(){return d}function $e(e){return d.find(r=>r.id===e)??null}function Fe(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 Ue(){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{z as a,M as b,Y as c,we as d,V as e,L as f,R as g,F as h,U as i,d as j,Ne as k,$e as l,Fe as m,Ue as n};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var d=Object.defineProperty;var e=(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 f=(a,b)=>{for(var c in b)d(a,c,{get:b[c],enumerable:!0})};export{e as a,f as b};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var c="sootsim-agent-prompt-v1";function r(n){return typeof n=="string"?n.trim():""}function m(n){let e=r(n.text);if(!e)return"";let t=r(n.displayText),s=r(n.inspectSummary),o=r(n.inspectTrace);return!!s||!!o||/[\r\n]/.test(e)||!!t&&t!==e?JSON.stringify({__sootsimAgentPrompt:c,text:e,displayText:t,inspectSummary:s,inspectTrace:o}):e}function u(n){let e=r(n);if(!e)return null;try{let t=JSON.parse(e);if(t.__sootsimAgentPrompt!==c)return{text:e};let s=r(typeof t.text=="string"?t.text:void 0);if(!s)return null;let o=r(typeof t.displayText=="string"?t.displayText:void 0),i=r(typeof t.inspectSummary=="string"?t.inspectSummary:void 0),p=r(typeof t.inspectTrace=="string"?t.inspectTrace:void 0);return{text:s,...o?{displayText:o}:{},...i?{inspectSummary:i}:{},...p?{inspectTrace:p}:{}}}catch{return{text:e}}}export{m as a,u as b};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  function o(e,n,r,a){return{width:3,ringToggle:{top:e[0],height:e[1]},volumeUp:{top:n[0],height:n[1]},volumeDown:{top:r[0],height:r[1]},lock:{top:a[0],height:a[1]}}}var b={width:2.5,lock:{top:188.7,height:68.1},ringToggle:{top:113.2,height:36},volumeUp:{top:188.2,height:68.1},volumeDown:{top:269,height:68.1}},d={width:3,lock:{top:238,height:78},ringToggle:{top:-1e3,height:0},volumeUp:{top:336,height:62},volumeDown:{top:408,height:62}},g={width:3,lock:{top:248,height:72},ringToggle:{top:-1e3,height:0},volumeUp:{top:144,height:62},volumeDown:{top:216,height:62}},i=48;function t(e){return{...e,platform:"ios",navigationBarHeight:0,navigationBarMode:e.homeIndicatorHeight>0?"gesture":"none",displayCutout:{top:e.dynamicIsland?e.statusBarHeight:0,bottom:0,left:0,right:0},cameraCutout:null,osVersion:e.iosVersion,androidApiLevel:null,systemName:"iOS",manufacturer:"Apple",brand:"Apple",modelName:e.name}}var u={"canvas-workspace":t({name:"Canvas Workspace",width:1440,height:900,scale:1,statusBarHeight:0,homeIndicatorHeight:0,cornerRadius:0,continuousCornerRadius:0,bezelWidth:16,dynamicIsland:null,safeAreaInsets:{top:0,bottom:0,left:0,right:0},iosVersion:"26.4",physicalPPI:110,hardwareButtons:o([185.8,41.7],[258.2,67.6],[344,67.6],[281.5,106.9]),experimental:!0}),"iphone-se":t({name:"iPhone SE",width:375,height:667,scale:2,statusBarHeight:20,homeIndicatorHeight:0,cornerRadius:0,continuousCornerRadius:0,bezelWidth:28.7,dynamicIsland:null,safeAreaInsets:{top:20,bottom:0,left:0,right:0},iosVersion:"15.8",physicalPPI:326,hardwareButtons:b}),"iphone-14":t({name:"iPhone 14",width:390,height:844,scale:3,statusBarHeight:47,homeIndicatorHeight:34,cornerRadius:46.2,continuousCornerRadius:67.462,bezelWidth:19.5,dynamicIsland:null,safeAreaInsets:{top:47,bottom:34,left:0,right:0},iosVersion:"17.6",physicalPPI:460,hardwareButtons:o([141.7,29.7],[205.9,69.6],[289.5,69.6],[228.9,114.5])}),"iphone-15":t({name:"iPhone 15",width:393,height:852,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,continuousCornerRadius:73.402,bezelWidth:18.2,dynamicIsland:{width:126,height:37.3,top:14.1},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"17.6",physicalPPI:460,hardwareButtons:o([171.7,32],[235.8,65.3],[320.5,65.3],[280.6,105.2])}),"iphone-15-plus":t({name:"iPhone 15 Plus",width:430,height:932,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,continuousCornerRadius:74.654,bezelWidth:17.3,dynamicIsland:{width:126,height:37.3,top:11.4},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"17.6",physicalPPI:460,hardwareButtons:o([172.1,33],[236.1,66.6],[321.2,66.6],[281,106.8])}),"iphone-15-pro":t({name:"iPhone 15 Pro",width:393,height:852,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,continuousCornerRadius:73.402,bezelWidth:15.3,dynamicIsland:{width:126,height:38,top:13.4},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"18.2",physicalPPI:460,hardwareButtons:o([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-15-pro-max":t({name:"iPhone 15 Pro Max",width:430,height:932,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,continuousCornerRadius:74.654,bezelWidth:15.3,dynamicIsland:{width:126,height:38,top:13.3},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"18.2",physicalPPI:460,hardwareButtons:o([173.3,32.2],[253.4,61.7],[343.3,61.7],[268.5,98.5])}),"iphone-16":t({name:"iPhone 16",width:393,height:852,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,continuousCornerRadius:73.402,bezelWidth:15.3,dynamicIsland:{width:126,height:37.3,top:11},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-16-plus":t({name:"iPhone 16 Plus",width:430,height:932,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,continuousCornerRadius:74.654,bezelWidth:15.3,dynamicIsland:{width:126,height:37.3,top:11.4},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([173.3,32.2],[253.4,61.7],[343.3,61.7],[268.5,98.5])}),"iphone-16-pro":t({name:"iPhone 16 Pro",width:402,height:874,scale:3,statusBarHeight:62,homeIndicatorHeight:34,cornerRadius:61,continuousCornerRadius:84.661,bezelWidth:15.3,dynamicIsland:{width:126,height:38,top:13.5},safeAreaInsets:{top:62,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-16-pro-max":t({name:"iPhone 16 Pro Max",width:440,height:956,scale:3,statusBarHeight:62,homeIndicatorHeight:34,cornerRadius:61.3,continuousCornerRadius:85.163,bezelWidth:15.4,dynamicIsland:{width:126,height:38,top:14},safeAreaInsets:{top:62,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([178.8,32.2],[266.8,61.8],[352.7,61.8],[292.2,98.3])}),"iphone-17":t({name:"iPhone 17",width:402,height:874,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:61,continuousCornerRadius:84.661,bezelWidth:15.3,dynamicIsland:{width:126,height:37.3,top:14},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-17-air":t({name:"iPhone Air",width:420,height:912,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:64.6,continuousCornerRadius:88.313,bezelWidth:15.4,dynamicIsland:{width:126,height:38,top:20},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([178.8,32.2],[266.8,61.8],[352.7,61.8],[292.2,98.3])}),"iphone-17-pro":t({name:"iPhone 17 Pro",width:402,height:874,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:61,continuousCornerRadius:84.661,bezelWidth:15.3,dynamicIsland:{width:126,height:38,top:14},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-17-pro-max":t({name:"iPhone 17 Pro Max",width:440,height:956,scale:3,statusBarHeight:62,homeIndicatorHeight:34,cornerRadius:61.3,continuousCornerRadius:85.163,bezelWidth:15.4,dynamicIsland:{width:126,height:38,top:14},safeAreaInsets:{top:62,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([178.8,32.2],[266.8,61.8],[352.7,61.8],[292.2,98.3])}),"pixel-8":{platform:"android",name:"Pixel 8",width:412,height:915,scale:2.625,statusBarHeight:40,homeIndicatorHeight:0,navigationBarHeight:i,navigationBarMode:"gesture",displayCutout:{top:40,bottom:0,left:0,right:0},cornerRadius:39,continuousCornerRadius:39,bezelWidth:13,dynamicIsland:null,cameraCutout:{diameter:24},safeAreaInsets:{top:40,bottom:i,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 8",physicalPPI:428,hardwareButtons:d},"pixel-8-three-button":{platform:"android",name:"Pixel 8 (3-button)",width:412,height:915,scale:2.625,statusBarHeight:40,homeIndicatorHeight:0,navigationBarHeight:48,navigationBarMode:"three-button",displayCutout:{top:40,bottom:0,left:0,right:0},cornerRadius:39,continuousCornerRadius:39,bezelWidth:13,dynamicIsland:null,cameraCutout:{diameter:24},safeAreaInsets:{top:40,bottom:48,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 8",physicalPPI:428,hardwareButtons:d},"pixel-9-pro-xl":{platform:"android",name:"Pixel 9 Pro XL",width:448,height:997,scale:3,statusBarHeight:40,homeIndicatorHeight:0,navigationBarHeight:i,navigationBarMode:"gesture",displayCutout:{top:40,bottom:0,left:0,right:0},cornerRadius:41,continuousCornerRadius:41,bezelWidth:12,dynamicIsland:null,cameraCutout:{diameter:24},safeAreaInsets:{top:40,bottom:i,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 9 Pro XL",physicalPPI:486,hardwareButtons:d},"galaxy-s24":{platform:"android",name:"Galaxy S24",width:360,height:780,scale:3,statusBarHeight:36,homeIndicatorHeight:0,navigationBarHeight:i,navigationBarMode:"gesture",displayCutout:{top:36,bottom:0,left:0,right:0},cornerRadius:36,continuousCornerRadius:36,bezelWidth:8,dynamicIsland:null,cameraCutout:{diameter:18},safeAreaInsets:{top:36,bottom:i,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Samsung",brand:"samsung",modelName:"SM-S921B",physicalPPI:416,hardwareButtons:g},"galaxy-s24-ultra":{platform:"android",name:"Galaxy S24 Ultra",width:384,height:824,scale:3.75,statusBarHeight:36,homeIndicatorHeight:0,navigationBarHeight:i,navigationBarMode:"gesture",displayCutout:{top:36,bottom:0,left:0,right:0},cornerRadius:24,continuousCornerRadius:24,bezelWidth:9,dynamicIsland:null,cameraCutout:{diameter:18},safeAreaInsets:{top:36,bottom:i,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Samsung",brand:"samsung",modelName:"SM-S928B",physicalPPI:505,hardwareButtons:g}},m="iphone-17-pro";function P(e){return u[e]}function p(){return Object.keys(u)}function x(){return p().filter(e=>!u[e].experimental)}var l={"iphone-6-9":{name:"iphone-6-9",label:'iPhone 6.7"',width:1284,height:2778,store:"apple"},"iphone-6-1":{name:"iphone-6-1",label:'iPhone 6.5"',width:1242,height:2688,store:"apple"},"android-phone":{name:"android-phone",label:"Google Play phone",width:1080,height:1920,store:"google"},"android-tablet-7":{name:"android-tablet-7",label:'Google Play 7" tablet',width:1200,height:1920,store:"google"},"android-tablet-10":{name:"android-tablet-10",label:'Google Play 10" tablet',width:1600,height:2560,store:"google"}},c={dark:{type:"gradient",direction:180,glow:"#4caeff",stops:[{offset:0,color:"#111827"},{offset:40,color:"#101725"},{offset:100,color:"#06080d"}]},cyan:{type:"gradient",direction:180,glow:"#25c3ec",stops:[{offset:0,color:"#1b465c"},{offset:32,color:"#122336"},{offset:100,color:"#05070b"}]},gold:{type:"gradient",direction:180,glow:"#ffc25a",stops:[{offset:0,color:"#3b2f1a"},{offset:34,color:"#18140d"},{offset:100,color:"#050505"}]},red:{type:"gradient",direction:180,glow:"#ff6178",stops:[{offset:0,color:"#3e1018"},{offset:35,color:"#17080c"},{offset:100,color:"#050405"}]}},R={color:"#25c3ec",blur:120,spread:52,opacity:.34},B="iphone-17-pro";var y=[{name:"white",value:"#ffffff"},{name:"gray-light",value:"#d1d5db"},{name:"gray",value:"#6b7280"},{name:"gray-dark",value:"#3b4350"},{name:"slate",value:"#2a3644"},{name:"black",value:"#000000"},{name:"cyan",value:"#25c3ec"},{name:"blue",value:"#3f7cff"},{name:"teal",value:"#1fc7b4"},{name:"green",value:"#42c95d"},{name:"lime",value:"#92d21b"},{name:"gold",value:"#f5c518"},{name:"orange",value:"#ff912e"},{name:"coral",value:"#ff6f5b"},{name:"red",value:"#ff4f6f"},{name:"berry",value:"#d054ff"},{name:"magenta",value:"#ff4eb8"}],f=Object.fromEntries(y.map(e=>[e.name,e.value]));function C(e){return f[e]??f.gray}function I(e){return Object.prototype.hasOwnProperty.call(l,e)?l[e]:null}function S(e){return{type:e.type,color:e.color,direction:e.direction,glow:e.glow,stops:e.stops?.map(n=>({...n}))}}function T(e){return Object.prototype.hasOwnProperty.call(c,e)?S(c[e]):null}var h={deviceModel:{type:"enum",default:m,description:"device model to simulate",cliFlag:"device",cliFlagShort:"d",options:p(),group:"device"},orientation:{type:"enum",default:"portrait",description:"screen orientation",cliFlag:"orientation",options:["portrait","landscape"],group:"device"},colorScheme:{type:"enum",default:"auto",description:"color scheme (auto follows system preference)",cliFlag:"theme",cliFlagShort:"t",options:["light","dark","auto"],group:"appearance"},reduceMotion:{type:"boolean",default:!1,description:"reduce motion",group:"appearance"},boldText:{type:"boolean",default:!1,description:"bold text",group:"appearance"},fontSize:{type:"number",default:1,description:"font size multiplier (1.0 = default)",group:"appearance",validate:e=>e>=.5&&e<=2},networkCondition:{type:"enum",default:"wifi",description:"simulated network condition",cliFlag:"network",options:["wifi","lte","fast-3g","slow-3g","offline"],group:"network"},language:{type:"string",default:"en",description:"language code (ISO 639-1)",cliFlag:"language",group:"locale"},region:{type:"string",default:"US",description:"region code (ISO 3166-1)",cliFlag:"region",group:"locale"},showTouches:{type:"boolean",default:!1,description:"show touch indicators",group:"simulator"},showFrame:{type:"boolean",default:!0,description:"show device frame",cliFlag:"frame",group:"simulator"},showTopBar:{type:"boolean",default:!0,description:"show simulator top bar",group:"simulator"},screenshotMode:{type:"boolean",default:!1,description:"show screenshot composition mode in the browser shell",group:"simulator"},threeMode:{type:"boolean",default:!1,description:"show the experimental 3d device stage in the browser shell",group:"simulator"},threeRecordingEditor:{type:"boolean",default:!1,description:"dock the 3d recording editor in the 3d stage (toggled from its rail)",group:"simulator"},screenshotCanvas:{type:"enum",default:"iphone-6-9",description:"target app-store canvas preset for screenshot mode",options:Object.keys(l),group:"simulator"},screenshotBackground:{type:"enum",default:"dark",description:"background preset rendered inside the screenshot canvas",options:Object.keys(c),group:"simulator"},screenshotText:{type:"enum",default:"bold-top",description:"text layout preset for the screenshot canvas",options:["bold-top","editorial-left","minimal-bottom","none"],group:"simulator"},screenshotPose:{type:"enum",default:"straight",description:"device pose preset inside the screenshot canvas",options:["straight","tilted-left","tilted-right","cut-bottom","cut-top"],group:"simulator"},screenshotDynamicSize:{type:"boolean",default:!1,description:"let the screenshot canvas rect fit available space (off = pin to exact preset pixels)",group:"simulator"},showStatusBar:{type:"boolean",default:!0,description:"show status bar",group:"simulator"},showHomeIndicator:{type:"boolean",default:!0,description:"show home indicator",group:"simulator"},alwaysShowLiveWebViews:{type:"boolean",default:!1,description:"always render WebViews as live browser views",group:"simulator"},a11yMode:{type:"enum",default:"delayed",description:"accessibility tree sync mode (off, delayed=100ms, active=30ms)",options:["off","delayed","active"],group:"simulator"},a11yDepth:{type:"enum",default:"deep",description:"accessibility tree structure depth (shallow or deep)",options:["shallow","deep"],group:"simulator"},inspectMode:{type:"boolean",default:!1,description:"inspect mode",group:"simulator"},errorReporting:{type:"boolean",default:!1,description:"send anonymous crash reports",group:"privacy"},agentProvider:{type:"enum",default:"codex",description:"ai agent used by the sootsim agent prompt bar",options:["codex","claude"],group:"agent"},onboardingComplete:{type:"boolean",default:!1,description:"first-run onboarding completed",group:"beta"},betaConsentVersion:{type:"number",default:0,description:"last accepted beta telemetry policy version",group:"beta"},detailedTelemetry:{type:"boolean",default:!0,description:"send detailed usage telemetry (sessions, perf samples)",group:"beta"}};function w(){if(typeof window>"u")return{};let e={};try{let n=new URLSearchParams(window.location.search),r=n.get("device");r&&h.deviceModel.options?.includes(r)&&(e.deviceModel=r);let a=n.get("colorScheme")??n.get("theme");a&&h.colorScheme.options?.includes(a)&&(e.colorScheme=a);let s=n.get("alwaysShowLiveWebViews");s==="1"||s==="true"?e.alwaysShowLiveWebViews=!0:(s==="0"||s==="false")&&(e.alwaysShowLiveWebViews=!1)}catch{}return e}function H(){let e={};for(let[n,r]of Object.entries(h))e[n]=r.default;return Object.assign(e,w()),e}export{R as a,B as b,C as c,I as d,S as e,T as f,u as g,P as h,x as i,h as j,w as k,H as l};
@@ -1,6 +1,6 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as k}from"./chunk-HXSV263V.js";import{a as x}from"./chunk-GUCFICA4.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://sootbean.com/api/electron-release";function O(){let n=process.arch;if(process.platform==="darwin"){let o=n==="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=n==="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:n,dest:o,onProgress:e}){let s=await fetch(n,{redirect:"follow"});if(!s.ok)throw new Error(`${s.status} ${s.statusText} (${n})`);let t=s.headers.get("content-length"),a=t?Number(t):null;if(!s.body)throw new Error(`empty response body (${n})`);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(r=>r?p(r):l())})}}function _(n,o){let e=(n/1048576).toFixed(1);if(!o)return` ${e} MB`;let s=Math.min(100,Math.round(n/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(n){let o=u("hdiutil",["attach","-nobrowse","-readonly",n],{encoding:"utf8"});if(o.status!==0)throw new Error(`hdiutil attach failed: ${o.stderr||o.stdout}`.trim());let e=o.stdout.trim().split(`
3
- `),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]),r=u("hdiutil",["detach","-force",t]);if(p.status!==0)throw new Error(`copy to ${l} failed: ${p.stderr?.toString()||""}`.trim());return r.status!==0&&console.warn(` warning: failed to unmount ${t} (${r.stderr?.toString().trim()||"unknown error"})`),u("xattr",["-dr","com.apple.quarantine",l]),l}async function C(n){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(n,e),D(n),S(e,493),e}async function B(n){return await new Promise((o,e)=>{let s=v("cmd",["/c","start",'""',"/wait",n],{stdio:"inherit"});s.once("error",e),s.once("exit",t=>{t===0?o():e(new Error(`installer exited with code ${t}`))})}),n}async function q(n){(n.includes("--help")||n.includes("-h"))&&(console.log(`
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as k}from"./chunk-NCXHUU7N.js";import{a as x}from"./chunk-E5FOMYR6.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(`
3
+ `),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(`
4
4
  sootsim desktop install \u2014 download and install the optional desktop GUI
5
5
 
6
6
  the CLI + daemon are the canonical sootsim surface; the GUI is optional.
@@ -17,7 +17,7 @@ options:
17
17
  examples:
18
18
  sootsim desktop install
19
19
  sootsim desktop install --yes
20
- `),process.exit(0));let o=n.includes("--yes")||n.includes("-y")||process.env.SOOTSIM_NO_PROMPT==="1"||process.env.CI==="1"||!process.stdin.isTTY,e=n.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}...
21
- `);try{await I({url:t.url,dest:i,onProgress:(r,m)=>{let $=Date.now();$-d<100&&r<(m??1/0)||(d=$,process.stdout.isTTY&&process.stdout.write(`\r\x1B[2K${_(r,m)}`))}})}catch(r){g(a,{recursive:!0,force:!0});let m=r instanceof Error?r.message:String(r);console.error(`
20
+ `),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}...
21
+ `);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(`
22
22
  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(`
23
- `);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-V76UPVDV.js");try{let r=await t.install(i);l({event:"cli_install_desktop_succeeded",properties:{platform:t.platform,size_bytes:c}}),console.log(` installed: ${r}`)}catch(r){l({event:"cli_install_desktop_failed",properties:{platform:t.platform,error:r instanceof Error?r.message:String(r)}}),await p(),console.error(` install failed: ${r instanceof Error?r.message:String(r)}`),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};
23
+ `);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-JHKOHSI2.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,2 +1,2 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var t="./demo-app-registry.ts",o=null;async function n(){if(o)return o;try{let r=await import(t);o=Array.isArray(r.APPS)?r.APPS:[]}catch{o=[]}return o}function e(){return o??[]}export{n as a,e as b};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{b as ms}from"./chunk-F5HOYUD2.js";var hs={};ms(hs,{Alias:()=>ee,CST:()=>cs,Composer:()=>be,Document:()=>se,Lexer:()=>Be,LineCounter:()=>De,Pair:()=>v,Parser:()=>we,Scalar:()=>y,Schema:()=>ve,YAMLError:()=>_e,YAMLMap:()=>$,YAMLParseError:()=>R,YAMLSeq:()=>B,YAMLWarning:()=>Pe,isAlias:()=>F,isCollection:()=>L,isDocument:()=>x,isMap:()=>U,isNode:()=>I,isPair:()=>T,isScalar:()=>E,isSeq:()=>V,parse:()=>un,parseAllDocuments:()=>fn,parseDocument:()=>us,stringify:()=>hn,visit:()=>Q,visitAsync:()=>je});var tt=Symbol.for("yaml.alias"),st=Symbol.for("yaml.document"),Y=Symbol.for("yaml.map"),qt=Symbol.for("yaml.pair"),q=Symbol.for("yaml.scalar"),re=Symbol.for("yaml.seq"),K=Symbol.for("yaml.node.type"),F=s=>!!s&&typeof s=="object"&&s[K]===tt,x=s=>!!s&&typeof s=="object"&&s[K]===st,U=s=>!!s&&typeof s=="object"&&s[K]===Y,T=s=>!!s&&typeof s=="object"&&s[K]===qt,E=s=>!!s&&typeof s=="object"&&s[K]===q,V=s=>!!s&&typeof s=="object"&&s[K]===re;function L(s){if(s&&typeof s=="object")switch(s[K]){case Y:case re:return!0}return!1}function I(s){if(s&&typeof s=="object")switch(s[K]){case tt:case Y:case q:case re:return!0}return!1}var nt=s=>(E(s)||L(s))&&!!s.anchor;var j=Symbol("break visit"),ds=Symbol("skip children"),z=Symbol("remove node");function Q(s,e){let t=gs(e);x(s)?ke(null,s.contents,t,Object.freeze([s]))===z&&(s.contents=null):ke(null,s,t,Object.freeze([]))}Q.BREAK=j;Q.SKIP=ds;Q.REMOVE=z;function ke(s,e,t,n){let i=ys(s,e,t,n);if(I(i)||T(i))return bs(s,n,i),ke(s,i,t,n);if(typeof i!="symbol"){if(L(e)){n=Object.freeze(n.concat(e));for(let r=0;r<e.items.length;++r){let o=ke(r,e.items[r],t,n);if(typeof o=="number")r=o-1;else{if(o===j)return j;o===z&&(e.items.splice(r,1),r-=1)}}}else if(T(e)){n=Object.freeze(n.concat(e));let r=ke("key",e.key,t,n);if(r===j)return j;r===z&&(e.key=null);let o=ke("value",e.value,t,n);if(o===j)return j;o===z&&(e.value=null)}}return i}async function je(s,e){let t=gs(e);x(s)?await Ne(null,s.contents,t,Object.freeze([s]))===z&&(s.contents=null):await Ne(null,s,t,Object.freeze([]))}je.BREAK=j;je.SKIP=ds;je.REMOVE=z;async function Ne(s,e,t,n){let i=await ys(s,e,t,n);if(I(i)||T(i))return bs(s,n,i),Ne(s,i,t,n);if(typeof i!="symbol"){if(L(e)){n=Object.freeze(n.concat(e));for(let r=0;r<e.items.length;++r){let o=await Ne(r,e.items[r],t,n);if(typeof o=="number")r=o-1;else{if(o===j)return j;o===z&&(e.items.splice(r,1),r-=1)}}}else if(T(e)){n=Object.freeze(n.concat(e));let r=await Ne("key",e.key,t,n);if(r===j)return j;r===z&&(e.key=null);let o=await Ne("value",e.value,t,n);if(o===j)return j;o===z&&(e.value=null)}}return i}function gs(s){return typeof s=="object"&&(s.Collection||s.Node||s.Value)?Object.assign({Alias:s.Node,Map:s.Node,Scalar:s.Node,Seq:s.Node},s.Value&&{Map:s.Value,Scalar:s.Value,Seq:s.Value},s.Collection&&{Map:s.Collection,Seq:s.Collection},s):s}function ys(s,e,t,n){if(typeof t=="function")return t(s,e,n);if(U(e))return t.Map?.(s,e,n);if(V(e))return t.Seq?.(s,e,n);if(T(e))return t.Pair?.(s,e,n);if(E(e))return t.Scalar?.(s,e,n);if(F(e))return t.Alias?.(s,e,n)}function bs(s,e,t){let n=e[e.length-1];if(L(n))n.items[s]=t;else if(T(n))s==="key"?n.key=t:n.value=t;else if(x(n))n.contents=t;else{let i=F(n)?"alias":"scalar";throw new Error(`Cannot replace node with ${i} parent`)}}var pn={"!":"%21",",":"%2C","[":"%5B","]":"%5D","{":"%7B","}":"%7D"},mn=s=>s.replace(/[!,[\]{}]/g,e=>pn[e]),Z=class s{constructor(e,t){this.docStart=null,this.docEnd=!1,this.yaml=Object.assign({},s.defaultYaml,e),this.tags=Object.assign({},s.defaultTags,t)}clone(){let e=new s(this.yaml,this.tags);return e.docStart=this.docStart,e}atDocument(){let e=new s(this.yaml,this.tags);switch(this.yaml.version){case"1.1":this.atNextDocument=!0;break;case"1.2":this.atNextDocument=!1,this.yaml={explicit:s.defaultYaml.explicit,version:"1.2"},this.tags=Object.assign({},s.defaultTags);break}return e}add(e,t){this.atNextDocument&&(this.yaml={explicit:s.defaultYaml.explicit,version:"1.1"},this.tags=Object.assign({},s.defaultTags),this.atNextDocument=!1);let n=e.trim().split(/[ \t]+/),i=n.shift();switch(i){case"%TAG":{if(n.length!==2&&(t(0,"%TAG directive should contain exactly two parts"),n.length<2))return!1;let[r,o]=n;return this.tags[r]=o,!0}case"%YAML":{if(this.yaml.explicit=!0,n.length!==1)return t(0,"%YAML directive should contain exactly one part"),!1;let[r]=n;if(r==="1.1"||r==="1.2")return this.yaml.version=r,!0;{let o=/^\d+\.\d+$/.test(r);return t(6,`Unsupported YAML version ${r}`,o),!1}}default:return t(0,`Unknown directive ${i}`,!0),!1}}tagName(e,t){if(e==="!")return"!";if(e[0]!=="!")return t(`Not a valid tag: ${e}`),null;if(e[1]==="<"){let o=e.slice(2,-1);return o==="!"||o==="!!"?(t(`Verbatim tags aren't resolved, so ${e} is invalid.`),null):(e[e.length-1]!==">"&&t("Verbatim tags must end with a >"),o)}let[,n,i]=e.match(/^(.*!)([^!]*)$/s);i||t(`The ${e} tag has no suffix`);let r=this.tags[n];if(r)try{return r+decodeURIComponent(i)}catch(o){return t(String(o)),null}return n==="!"?e:(t(`Could not resolve tag: ${e}`),null)}tagString(e){for(let[t,n]of Object.entries(this.tags))if(e.startsWith(n))return t+mn(e.substring(n.length));return e[0]==="!"?e:`!<${e}>`}toString(e){let t=this.yaml.explicit?[`%YAML ${this.yaml.version||"1.2"}`]:[],n=Object.entries(this.tags),i;if(e&&n.length>0&&I(e.contents)){let r={};Q(e.contents,(o,l)=>{I(l)&&l.tag&&(r[l.tag]=!0)}),i=Object.keys(r)}else i=[];for(let[r,o]of n)r==="!!"&&o==="tag:yaml.org,2002:"||(!e||i.some(l=>l.startsWith(o)))&&t.push(`%TAG ${r} ${o}`);return t.join(`
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{b as ms}from"./chunk-6U3GMNTP.js";var hs={};ms(hs,{Alias:()=>ee,CST:()=>cs,Composer:()=>be,Document:()=>se,Lexer:()=>Be,LineCounter:()=>De,Pair:()=>v,Parser:()=>we,Scalar:()=>y,Schema:()=>ve,YAMLError:()=>_e,YAMLMap:()=>$,YAMLParseError:()=>R,YAMLSeq:()=>B,YAMLWarning:()=>Pe,isAlias:()=>F,isCollection:()=>L,isDocument:()=>x,isMap:()=>U,isNode:()=>I,isPair:()=>T,isScalar:()=>E,isSeq:()=>V,parse:()=>un,parseAllDocuments:()=>fn,parseDocument:()=>us,stringify:()=>hn,visit:()=>Q,visitAsync:()=>je});var tt=Symbol.for("yaml.alias"),st=Symbol.for("yaml.document"),Y=Symbol.for("yaml.map"),qt=Symbol.for("yaml.pair"),q=Symbol.for("yaml.scalar"),re=Symbol.for("yaml.seq"),K=Symbol.for("yaml.node.type"),F=s=>!!s&&typeof s=="object"&&s[K]===tt,x=s=>!!s&&typeof s=="object"&&s[K]===st,U=s=>!!s&&typeof s=="object"&&s[K]===Y,T=s=>!!s&&typeof s=="object"&&s[K]===qt,E=s=>!!s&&typeof s=="object"&&s[K]===q,V=s=>!!s&&typeof s=="object"&&s[K]===re;function L(s){if(s&&typeof s=="object")switch(s[K]){case Y:case re:return!0}return!1}function I(s){if(s&&typeof s=="object")switch(s[K]){case tt:case Y:case q:case re:return!0}return!1}var nt=s=>(E(s)||L(s))&&!!s.anchor;var j=Symbol("break visit"),ds=Symbol("skip children"),z=Symbol("remove node");function Q(s,e){let t=gs(e);x(s)?ke(null,s.contents,t,Object.freeze([s]))===z&&(s.contents=null):ke(null,s,t,Object.freeze([]))}Q.BREAK=j;Q.SKIP=ds;Q.REMOVE=z;function ke(s,e,t,n){let i=ys(s,e,t,n);if(I(i)||T(i))return bs(s,n,i),ke(s,i,t,n);if(typeof i!="symbol"){if(L(e)){n=Object.freeze(n.concat(e));for(let r=0;r<e.items.length;++r){let o=ke(r,e.items[r],t,n);if(typeof o=="number")r=o-1;else{if(o===j)return j;o===z&&(e.items.splice(r,1),r-=1)}}}else if(T(e)){n=Object.freeze(n.concat(e));let r=ke("key",e.key,t,n);if(r===j)return j;r===z&&(e.key=null);let o=ke("value",e.value,t,n);if(o===j)return j;o===z&&(e.value=null)}}return i}async function je(s,e){let t=gs(e);x(s)?await Ne(null,s.contents,t,Object.freeze([s]))===z&&(s.contents=null):await Ne(null,s,t,Object.freeze([]))}je.BREAK=j;je.SKIP=ds;je.REMOVE=z;async function Ne(s,e,t,n){let i=await ys(s,e,t,n);if(I(i)||T(i))return bs(s,n,i),Ne(s,i,t,n);if(typeof i!="symbol"){if(L(e)){n=Object.freeze(n.concat(e));for(let r=0;r<e.items.length;++r){let o=await Ne(r,e.items[r],t,n);if(typeof o=="number")r=o-1;else{if(o===j)return j;o===z&&(e.items.splice(r,1),r-=1)}}}else if(T(e)){n=Object.freeze(n.concat(e));let r=await Ne("key",e.key,t,n);if(r===j)return j;r===z&&(e.key=null);let o=await Ne("value",e.value,t,n);if(o===j)return j;o===z&&(e.value=null)}}return i}function gs(s){return typeof s=="object"&&(s.Collection||s.Node||s.Value)?Object.assign({Alias:s.Node,Map:s.Node,Scalar:s.Node,Seq:s.Node},s.Value&&{Map:s.Value,Scalar:s.Value,Seq:s.Value},s.Collection&&{Map:s.Collection,Seq:s.Collection},s):s}function ys(s,e,t,n){if(typeof t=="function")return t(s,e,n);if(U(e))return t.Map?.(s,e,n);if(V(e))return t.Seq?.(s,e,n);if(T(e))return t.Pair?.(s,e,n);if(E(e))return t.Scalar?.(s,e,n);if(F(e))return t.Alias?.(s,e,n)}function bs(s,e,t){let n=e[e.length-1];if(L(n))n.items[s]=t;else if(T(n))s==="key"?n.key=t:n.value=t;else if(x(n))n.contents=t;else{let i=F(n)?"alias":"scalar";throw new Error(`Cannot replace node with ${i} parent`)}}var pn={"!":"%21",",":"%2C","[":"%5B","]":"%5D","{":"%7B","}":"%7D"},mn=s=>s.replace(/[!,[\]{}]/g,e=>pn[e]),Z=class s{constructor(e,t){this.docStart=null,this.docEnd=!1,this.yaml=Object.assign({},s.defaultYaml,e),this.tags=Object.assign({},s.defaultTags,t)}clone(){let e=new s(this.yaml,this.tags);return e.docStart=this.docStart,e}atDocument(){let e=new s(this.yaml,this.tags);switch(this.yaml.version){case"1.1":this.atNextDocument=!0;break;case"1.2":this.atNextDocument=!1,this.yaml={explicit:s.defaultYaml.explicit,version:"1.2"},this.tags=Object.assign({},s.defaultTags);break}return e}add(e,t){this.atNextDocument&&(this.yaml={explicit:s.defaultYaml.explicit,version:"1.1"},this.tags=Object.assign({},s.defaultTags),this.atNextDocument=!1);let n=e.trim().split(/[ \t]+/),i=n.shift();switch(i){case"%TAG":{if(n.length!==2&&(t(0,"%TAG directive should contain exactly two parts"),n.length<2))return!1;let[r,o]=n;return this.tags[r]=o,!0}case"%YAML":{if(this.yaml.explicit=!0,n.length!==1)return t(0,"%YAML directive should contain exactly one part"),!1;let[r]=n;if(r==="1.1"||r==="1.2")return this.yaml.version=r,!0;{let o=/^\d+\.\d+$/.test(r);return t(6,`Unsupported YAML version ${r}`,o),!1}}default:return t(0,`Unknown directive ${i}`,!0),!1}}tagName(e,t){if(e==="!")return"!";if(e[0]!=="!")return t(`Not a valid tag: ${e}`),null;if(e[1]==="<"){let o=e.slice(2,-1);return o==="!"||o==="!!"?(t(`Verbatim tags aren't resolved, so ${e} is invalid.`),null):(e[e.length-1]!==">"&&t("Verbatim tags must end with a >"),o)}let[,n,i]=e.match(/^(.*!)([^!]*)$/s);i||t(`The ${e} tag has no suffix`);let r=this.tags[n];if(r)try{return r+decodeURIComponent(i)}catch(o){return t(String(o)),null}return n==="!"?e:(t(`Could not resolve tag: ${e}`),null)}tagString(e){for(let[t,n]of Object.entries(this.tags))if(e.startsWith(n))return t+mn(e.substring(n.length));return e[0]==="!"?e:`!<${e}>`}toString(e){let t=this.yaml.explicit?[`%YAML ${this.yaml.version||"1.2"}`]:[],n=Object.entries(this.tags),i;if(e&&n.length>0&&I(e.contents)){let r={};Q(e.contents,(o,l)=>{I(l)&&l.tag&&(r[l.tag]=!0)}),i=Object.keys(r)}else i=[];for(let[r,o]of n)r==="!!"&&o==="tag:yaml.org,2002:"||(!e||i.some(l=>l.startsWith(o)))&&t.push(`%TAG ${r} ${o}`);return t.join(`
3
3
  `)}};Z.defaultYaml={explicit:!1,version:"1.2"};Z.defaultTags={"!!":"tag:yaml.org,2002:"};function it(s){if(/[\x00-\x19\s,[\]{}]/.test(s)){let t=`Anchor must not contain whitespace or control characters: ${JSON.stringify(s)}`;throw new Error(t)}return!0}function Rt(s){let e=new Set;return Q(s,{Value(t,n){n.anchor&&e.add(n.anchor)}}),e}function Ft(s,e){for(let t=1;;++t){let n=`${s}${t}`;if(!e.has(n))return n}}function ws(s,e){let t=[],n=new Map,i=null;return{onAnchor:r=>{t.push(r),i??(i=Rt(s));let o=Ft(e,i);return i.add(o),o},setAnchors:()=>{for(let r of t){let o=n.get(r);if(typeof o=="object"&&o.anchor&&(E(o.node)||L(o.node)))o.node.anchor=o.anchor;else{let l=new Error("Failed to resolve repeated object (this should not happen)");throw l.source=r,l}}},sourceObjects:n}}function fe(s,e,t,n){if(n&&typeof n=="object")if(Array.isArray(n))for(let i=0,r=n.length;i<r;++i){let o=n[i],l=fe(s,n,String(i),o);l===void 0?delete n[i]:l!==o&&(n[i]=l)}else if(n instanceof Map)for(let i of Array.from(n.keys())){let r=n.get(i),o=fe(s,n,i,r);o===void 0?n.delete(i):o!==r&&n.set(i,o)}else if(n instanceof Set)for(let i of Array.from(n)){let r=fe(s,n,i,i);r===void 0?n.delete(i):r!==i&&(n.delete(i),n.add(r))}else for(let[i,r]of Object.entries(n)){let o=fe(s,n,i,r);o===void 0?delete n[i]:o!==r&&(n[i]=o)}return s.call(e,t,n)}function M(s,e,t){if(Array.isArray(s))return s.map((n,i)=>M(n,String(i),t));if(s&&typeof s.toJSON=="function"){if(!t||!nt(s))return s.toJSON(e,t);let n={aliasCount:0,count:1,res:void 0};t.anchors.set(s,n),t.onCreate=r=>{n.res=r,delete t.onCreate};let i=s.toJSON(e,t);return t.onCreate&&t.onCreate(i),i}return typeof s=="bigint"&&!t?.keep?Number(s):s}var ue=class{constructor(e){Object.defineProperty(this,K,{value:e})}clone(){let e=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return this.range&&(e.range=this.range.slice()),e}toJS(e,{mapAsMap:t,maxAliasCount:n,onAnchor:i,reviver:r}={}){if(!x(e))throw new TypeError("A document argument is required");let o={anchors:new Map,doc:e,keep:!0,mapAsMap:t===!0,mapKeyWarned:!1,maxAliasCount:typeof n=="number"?n:100},l=M(this,"",o);if(typeof i=="function")for(let{count:a,res:c}of o.anchors.values())i(c,a);return typeof r=="function"?fe(r,{"":l},"",l):l}};var ee=class extends ue{constructor(e){super(tt),this.source=e,Object.defineProperty(this,"tag",{set(){throw new Error("Alias nodes cannot have tags")}})}resolve(e,t){if(t?.maxAliasCount===0)throw new ReferenceError("Alias resolution is disabled");let n;t?.aliasResolveCache?n=t.aliasResolveCache:(n=[],Q(e,{Node:(r,o)=>{(F(o)||nt(o))&&n.push(o)}}),t&&(t.aliasResolveCache=n));let i;for(let r of n){if(r===this)break;r.anchor===this.source&&(i=r)}return i}toJSON(e,t){if(!t)return{source:this.source};let{anchors:n,doc:i,maxAliasCount:r}=t,o=this.resolve(i,t);if(!o){let a=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new ReferenceError(a)}let l=n.get(o);if(l||(M(o,null,t),l=n.get(o)),l?.res===void 0){let a="This should not happen: Alias anchor was not resolved?";throw new ReferenceError(a)}if(r>=0&&(l.count+=1,l.aliasCount===0&&(l.aliasCount=rt(i,o,n)),l.count*l.aliasCount>r)){let a="Excessive alias count indicates a resource exhaustion attack";throw new ReferenceError(a)}return l.res}toString(e,t,n){let i=`*${this.source}`;if(e){if(it(this.source),e.options.verifyAliasOrder&&!e.anchors.has(this.source)){let r=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new Error(r)}if(e.implicitKey)return`${i} `}return i}};function rt(s,e,t){if(F(e)){let n=e.resolve(s),i=t&&n&&t.get(n);return i?i.count*i.aliasCount:0}else if(L(e)){let n=0;for(let i of e.items){let r=rt(s,i,t);r>n&&(n=r)}return n}else if(T(e)){let n=rt(s,e.key,t),i=rt(s,e.value,t);return Math.max(n,i)}return 1}var ot=s=>!s||typeof s!="function"&&typeof s!="object",y=class extends ue{constructor(e){super(q),this.value=e}toJSON(e,t){return t?.keep?this.value:M(this.value,e,t)}toString(){return String(this.value)}};y.BLOCK_FOLDED="BLOCK_FOLDED";y.BLOCK_LITERAL="BLOCK_LITERAL";y.PLAIN="PLAIN";y.QUOTE_DOUBLE="QUOTE_DOUBLE";y.QUOTE_SINGLE="QUOTE_SINGLE";var dn="tag:yaml.org,2002:";function gn(s,e,t){if(e){let n=t.filter(r=>r.tag===e),i=n.find(r=>!r.format)??n[0];if(!i)throw new Error(`Tag ${e} not found`);return i}return t.find(n=>n.identify?.(s)&&!n.format)}function oe(s,e,t){if(x(s)&&(s=s.contents),I(s))return s;if(T(s)){let f=t.schema[Y].createNode?.(t.schema,null,t);return f.items.push(s),f}(s instanceof String||s instanceof Number||s instanceof Boolean||typeof BigInt<"u"&&s instanceof BigInt)&&(s=s.valueOf());let{aliasDuplicateObjects:n,onAnchor:i,onTagObj:r,schema:o,sourceObjects:l}=t,a;if(n&&s&&typeof s=="object"){if(a=l.get(s),a)return a.anchor??(a.anchor=i(s)),new ee(a.anchor);a={anchor:null,node:null},l.set(s,a)}e?.startsWith("!!")&&(e=dn+e.slice(2));let c=gn(s,e,o.tags);if(!c){if(s&&typeof s.toJSON=="function"&&(s=s.toJSON()),!s||typeof s!="object"){let f=new y(s);return a&&(a.node=f),f}c=s instanceof Map?o[Y]:Symbol.iterator in Object(s)?o[re]:o[Y]}r&&(r(c),delete t.onTagObj);let p=c?.createNode?c.createNode(t.schema,s,t):typeof c?.nodeClass?.from=="function"?c.nodeClass.from(t.schema,s,t):new y(s);return e?p.tag=e:c.default||(p.tag=c.tag),a&&(a.node=p),p}function qe(s,e,t){let n=t;for(let i=e.length-1;i>=0;--i){let r=e[i];if(typeof r=="number"&&Number.isInteger(r)&&r>=0){let o=[];o[r]=n,n=o}else n=new Map([[r,n]])}return oe(n,void 0,{aliasDuplicateObjects:!1,keepUndefined:!1,onAnchor:()=>{throw new Error("This should not happen, please report a bug.")},schema:s,sourceObjects:new Map})}var Ae=s=>s==null||typeof s=="object"&&!!s[Symbol.iterator]().next().done,Oe=class extends ue{constructor(e,t){super(e),Object.defineProperty(this,"schema",{value:t,configurable:!0,enumerable:!1,writable:!0})}clone(e){let t=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return e&&(t.schema=e),t.items=t.items.map(n=>I(n)||T(n)?n.clone(e):n),this.range&&(t.range=this.range.slice()),t}addIn(e,t){if(Ae(e))this.add(t);else{let[n,...i]=e,r=this.get(n,!0);if(L(r))r.addIn(i,t);else if(r===void 0&&this.schema)this.set(n,qe(this.schema,i,t));else throw new Error(`Expected YAML collection at ${n}. Remaining path: ${i}`)}}deleteIn(e){let[t,...n]=e;if(n.length===0)return this.delete(t);let i=this.get(t,!0);if(L(i))return i.deleteIn(n);throw new Error(`Expected YAML collection at ${t}. Remaining path: ${n}`)}getIn(e,t){let[n,...i]=e,r=this.get(n,!0);return i.length===0?!t&&E(r)?r.value:r:L(r)?r.getIn(i,t):void 0}hasAllNullValues(e){return this.items.every(t=>{if(!T(t))return!1;let n=t.value;return n==null||e&&E(n)&&n.value==null&&!n.commentBefore&&!n.comment&&!n.tag})}hasIn(e){let[t,...n]=e;if(n.length===0)return this.has(t);let i=this.get(t,!0);return L(i)?i.hasIn(n):!1}setIn(e,t){let[n,...i]=e;if(i.length===0)this.set(n,t);else{let r=this.get(n,!0);if(L(r))r.setIn(i,t);else if(r===void 0&&this.schema)this.set(n,qe(this.schema,i,t));else throw new Error(`Expected YAML collection at ${n}. Remaining path: ${i}`)}}};var Ss=s=>s.replace(/^(?!$)(?: $)?/gm,"#");function J(s,e){return/^\n+$/.test(s)?s.substring(1):e?s.replace(/^(?! *$)/gm,e):s}var te=(s,e,t)=>s.endsWith(`
4
4
  `)?J(t,e):t.includes(`
5
5
  `)?`
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as o}from"./chunk-2I62CFYI.js";var c=["ghs_","ghp_","gho_","ghu_","github_pat_"];function d(n){return!!(n&&n.length>=20&&c.some(t=>n.startsWith(t)))}function p(){let n=process.env.CONTRAST_INSTALLATION_TOKEN?.trim(),t=process.env.GITHUB_TOKEN?.trim(),e=n||t;if(!d(e))return null;let r=(process.env.CONTRAST_REPO||process.env.GITHUB_REPOSITORY||"").trim();if(!r)return null;let[i,s]=r.includes("/")?r.split("/",2):[null,null],u=(process.env.CONTRAST_REPO_ID||process.env.GITHUB_REPOSITORY_ID||"").trim(),l=(process.env.CONTRAST_INSTALLATION_ID||process.env.GITHUB_APP_INSTALLATION_ID||"").trim();return{kind:"github",token:e,repoId:r,repositoryId:u||null,owner:i||null,repo:s||null,installationId:l||null,source:n?"contrast-runner":"github-actions"}}function a(){let n=process.env.SOOTSIM_API_KEY?.trim();if(n&&n.startsWith("sk_sootsim_"))return{kind:"api-key",secret:n,source:"env"};let t=p();if(t)return t;let e=o();return e?.token?{kind:"session",token:e.token,origin:e.origin}:null}function g(n){return n.kind==="api-key"?`Bearer ${n.secret}`:`Bearer ${n.token}`}function _(n){return!n||n.kind!=="github"?null:{repoId:n.repoId,owner:n.owner??void 0,repo:n.repo??void 0,installationId:n.installationId}}export{a,g as b,_ as c};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{g as k,i as x,l as P,m as v}from"./chunk-35EAEAN4.js";import{createHash as q}from"node:crypto";import{mkdirSync as G,readFileSync as J,readdirSync as H,unlinkSync as Y,writeFileSync as z}from"node:fs";import{dirname as Q,extname as X,resolve as T}from"node:path";function W(e){let t=e[0]?.toLowerCase()??"toggle";return t!=="on"&&t!=="off"&&t!=="toggle"&&(console.error(` unknown argument: "${t}" (expected on | off | toggle)`),process.exit(1)),t}async function D(e,t,o){let n=k(e,{port:t.port}),r=W(n.positional),d=x({...n,commandTimeoutMs:5e3});try{let l=!!(await P(d,"SootSim.bridges.settings.get"))?.[o.modeKey],m=r==="on"?!0:r==="off"?!1:!l;if(l===m)return console.log(` ${o.displayName}: already ${m?"on":"off"}`),{current:l,target:m,changed:!1};if(!await d.send({type:"evaluate",acquireLock:!0,code:`(async () => {
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{g as k,i as x,l as P,m as v}from"./chunk-SPJSTRXX.js";import{createHash as q}from"node:crypto";import{mkdirSync as G,readFileSync as J,readdirSync as H,unlinkSync as Y,writeFileSync as z}from"node:fs";import{dirname as Q,extname as X,resolve as T}from"node:path";function W(e){let t=e[0]?.toLowerCase()??"toggle";return t!=="on"&&t!=="off"&&t!=="toggle"&&(console.error(` unknown argument: "${t}" (expected on | off | toggle)`),process.exit(1)),t}async function D(e,t,o){let n=k(e,{port:t.port}),r=W(n.positional),d=x({...n,commandTimeoutMs:5e3});try{let l=!!(await P(d,"SootSim.bridges.settings.get"))?.[o.modeKey],m=r==="on"?!0:r==="off"?!1:!l;if(l===m)return console.log(` ${o.displayName}: already ${m?"on":"off"}`),{current:l,target:m,changed:!1};if(!await d.send({type:"evaluate",acquireLock:!0,code:`(async () => {
3
3
  const modeKey = ${JSON.stringify(o.modeKey)}
4
4
  const target = ${JSON.stringify(m)}
5
5
  window.dispatchEvent(new CustomEvent('sootsim:shell-command', {
@@ -0,0 +1 @@
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as l}from"./chunk-2I62CFYI.js";import{A as o,B as s}from"./chunk-PNPH4JLS.js";function c(){let e=process.env.DO_NOT_TRACK;return e==="1"||e==="true"||!o()}function p(){if(c())return null;let e=process.env.VITE_POSTHOG_API_KEY||"";if(!e)return null;let t=process.env.CONTRAST_POSTHOG_HOST||process.env.VITE_POSTHOG_HOST||"https://us.i.posthog.com";return{apiKey:e,host:t.replace(/\/+$/,"")}}function u(){try{return s()}catch{return"anonymous-cli"}}function d(e){return e?e.userId?e.userId:e.installationId!=null?`install:${e.installationId}`:e.repoId?`repo:${e.repoId}`:e.shareId?`share:${e.shareId}`:u():u()}function f(e){let t=e.identity??{},n={$lib:"sootsim-cli",source:t.source??"cli",...e.properties};return t.userId&&(n.userId=t.userId),t.repoId&&(n.repoId=t.repoId),t.installationId!=null&&(n.installationId=String(t.installationId)),t.shareId&&(n.shareId=t.shareId),t.plan&&(n.plan=t.plan),{event:e.event,distinct_id:d(t),properties:n,timestamp:new Date().toISOString()}}var r=[],a=!1;async function i(){if(r.length===0)return;let e=p();if(!e){r.length=0;return}let t=r.splice(0,r.length).map(f);try{await fetch(`${e.host}/batch/`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({api_key:e.apiKey,batch:t}),signal:AbortSignal.timeout(2e3)})}catch{}}function I(){a||(a=!0,process.on("beforeExit",()=>void i()),process.on("exit",()=>void i()))}function y(e){if(c())return;I();let t=null;try{t=l()?.user?.id??null}catch{t=null}r.push({...e,identity:{source:"cli",userId:t,...e.identity}})}async function m(){await i()}export{y as a,m as b};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.227 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{H as t,N as n,P as l,j as r}from"./chunk-NU755HCE.js";function m(){let e=t(),i=r()?n():null;return i&&l(i)?{primary:`engine dev source (:${i.bridgePort})`,installedRuntime:e?`installed runtime v${e}`:null,isDevBridge:!0}:{primary:e?`runtime v${e}`:"runtime not installed",installedRuntime:null,isDevBridge:!1}}export{m as a};
1
+ /*! sootsim v0.1.228 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{H as t,N as n,P as l,j as r}from"./chunk-PNPH4JLS.js";function m(){let e=t(),i=r()?n():null;return i&&l(i)?{primary:`engine dev source (:${i.bridgePort})`,installedRuntime:e?`installed runtime v${e}`:null,isDevBridge:!0}:{primary:e?`runtime v${e}`:"runtime not installed",installedRuntime:null,isDevBridge:!1}}export{m as a};