sootsim 0.1.240 → 0.1.242

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 (145) hide show
  1. package/dist-cli/bin.js +4 -4
  2. package/dist-cli/chunks/{agent-YS355M7O.js → agent-WRLD4GUR.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-DJJH2DE5.js → agent-wrapper-GZC4SCJC.js} +2 -2
  4. package/dist-cli/chunks/{app-fonts-2KURCNO7.js → app-fonts-CM4PFNCY.js} +2 -2
  5. package/dist-cli/chunks/{assert-Y7SV6LAY.js → assert-IXY4MMRH.js} +2 -2
  6. package/dist-cli/chunks/{auth-5VMBSD6F.js → auth-SYCH6PU3.js} +2 -2
  7. package/dist-cli/chunks/beta-3MJDXZZH.js +2 -0
  8. package/dist-cli/chunks/{camera-WCQNMZRH.js → camera-S3L45HX6.js} +2 -2
  9. package/dist-cli/chunks/{chunk-JDRG4T3G.js → chunk-253BJ7EG.js} +2 -2
  10. package/dist-cli/chunks/{chunk-M2OTE66X.js → chunk-2F3ZYD56.js} +2 -2
  11. package/dist-cli/chunks/{chunk-SW5HPJC7.js → chunk-2LXNSEPM.js} +2 -2
  12. package/dist-cli/chunks/{chunk-M3VY5LEN.js → chunk-2RSNHAI3.js} +1 -1
  13. package/dist-cli/chunks/{chunk-C4MSUAGM.js → chunk-2RWEXEE6.js} +1 -1
  14. package/dist-cli/chunks/{chunk-SFNTUDIP.js → chunk-4F5ASLFX.js} +2 -2
  15. package/dist-cli/chunks/chunk-5HZZ4LED.js +118 -0
  16. package/dist-cli/chunks/{chunk-ZYMOUSJC.js → chunk-6LOZ2IAS.js} +1 -1
  17. package/dist-cli/chunks/{chunk-LBOSTYWQ.js → chunk-6MOOHJ63.js} +1 -1
  18. package/dist-cli/chunks/{chunk-VU5WTUZJ.js → chunk-6UXBJVLW.js} +2 -2
  19. package/dist-cli/chunks/{chunk-4F63QBYN.js → chunk-6YSCOU6Q.js} +3 -3
  20. package/dist-cli/chunks/chunk-7GQUKXYW.js +1 -0
  21. package/dist-cli/chunks/{chunk-OUW757HM.js → chunk-C4O4U4D5.js} +52 -52
  22. package/dist-cli/chunks/{chunk-3ULI43M6.js → chunk-D53XZW7Q.js} +72 -23
  23. package/dist-cli/chunks/{chunk-H6GS5C4F.js → chunk-EHEVO2JB.js} +2 -2
  24. package/dist-cli/chunks/chunk-FFQPV4R5.js +1 -0
  25. package/dist-cli/chunks/{chunk-DEO54ZY3.js → chunk-G7225Q7A.js} +2 -2
  26. package/dist-cli/chunks/{chunk-7ZTOWAQF.js → chunk-GAMPO6T4.js} +2 -2
  27. package/dist-cli/chunks/{chunk-EJ6ULQFO.js → chunk-H7UA4DWW.js} +2 -2
  28. package/dist-cli/chunks/{chunk-GYWIGJB7.js → chunk-HBUOQ3Q2.js} +2 -2
  29. package/dist-cli/chunks/{chunk-OBQJXFV3.js → chunk-HHMQ42W5.js} +1 -1
  30. package/dist-cli/chunks/{chunk-DQEI7LOC.js → chunk-IZIEQFOD.js} +3 -3
  31. package/dist-cli/chunks/{chunk-BWR3AJZ3.js → chunk-JVDDW7YD.js} +1 -1
  32. package/dist-cli/chunks/{chunk-2QILUPQJ.js → chunk-K3Q6M3PJ.js} +1 -1
  33. package/dist-cli/chunks/{chunk-GI36DI2I.js → chunk-KIXYJHTM.js} +1 -1
  34. package/dist-cli/chunks/{chunk-KY2HHVDG.js → chunk-KRVUN5K3.js} +2 -2
  35. package/dist-cli/chunks/{chunk-TFXCEOCW.js → chunk-L62LIMAO.js} +1 -1
  36. package/dist-cli/chunks/{chunk-XSSTKHK7.js → chunk-LVVSGSYI.js} +2 -2
  37. package/dist-cli/chunks/{chunk-XV4VXQDA.js → chunk-LY3T7QK7.js} +2 -2
  38. package/dist-cli/chunks/{chunk-XVE2O2IR.js → chunk-M5AJYHMH.js} +2 -2
  39. package/dist-cli/chunks/{chunk-HIFBYPJK.js → chunk-MG4X25GT.js} +2 -2
  40. package/dist-cli/chunks/{chunk-OKHNWLZ7.js → chunk-MHO6EZBS.js} +2 -2
  41. package/dist-cli/chunks/{chunk-KENWUOKC.js → chunk-MKI346PV.js} +2 -2
  42. package/dist-cli/chunks/{chunk-M2MJXMTO.js → chunk-N2CW4ASW.js} +1 -1
  43. package/dist-cli/chunks/{chunk-4FUKKXDQ.js → chunk-NAST572Z.js} +2 -2
  44. package/dist-cli/chunks/{chunk-ILU6JNUJ.js → chunk-NO7HYN72.js} +1 -1
  45. package/dist-cli/chunks/{chunk-T7BLBFPG.js → chunk-O7L2OXRI.js} +2 -2
  46. package/dist-cli/chunks/{chunk-GW7REFUB.js → chunk-QXFSHX44.js} +1 -1
  47. package/dist-cli/chunks/{chunk-6XHVSTMH.js → chunk-RBUSKHI6.js} +2 -2
  48. package/dist-cli/chunks/{chunk-WYT6JDAV.js → chunk-RFYPY6RQ.js} +1 -1
  49. package/dist-cli/chunks/{chunk-NJYDI627.js → chunk-S4L7A6CA.js} +1 -1
  50. package/dist-cli/chunks/{chunk-5LCZXDDX.js → chunk-SMGV7GKR.js} +1 -1
  51. package/dist-cli/chunks/{chunk-AX56F2Z5.js → chunk-UPGZJEDV.js} +1 -1
  52. package/dist-cli/chunks/{chunk-2ZEVD46I.js → chunk-XYPHZRET.js} +3 -3
  53. package/dist-cli/chunks/cli-version-BZMMVK7K.js +2 -0
  54. package/dist-cli/chunks/{compat-LUERFKMW.js → compat-WO6SZWZM.js} +3 -3
  55. package/dist-cli/chunks/{config-U4Z6TYT6.js → config-GGWQLBMR.js} +2 -2
  56. package/dist-cli/chunks/{control-I5YB63IZ.js → control-JZD4UFUN.js} +2 -2
  57. package/dist-cli/chunks/daemon-4SB245M7.js +2 -0
  58. package/dist-cli/chunks/{debug-HXECWDLV.js → debug-T7EW5PLL.js} +3 -3
  59. package/dist-cli/chunks/{desktop-NZJLDJIO.js → desktop-YTTK2ZHX.js} +3 -3
  60. package/dist-cli/chunks/{detox-LUOT4TIA.js → detox-K5WPBE4F.js} +2 -2
  61. package/dist-cli/chunks/{device-7TZ7BD36.js → device-A4EL3CRS.js} +2 -2
  62. package/dist-cli/chunks/{diagnose-DW2ANEGF.js → diagnose-IA3C4MIC.js} +2 -2
  63. package/dist-cli/chunks/drivers-O5UYWTP6.js +2 -0
  64. package/dist-cli/chunks/{film-6MYMKZ3N.js → film-ILR7YDJI.js} +3 -3
  65. package/dist-cli/chunks/flow-HD7JQBI5.js +2 -0
  66. package/dist-cli/chunks/help-4B7DKFAR.js +2 -0
  67. package/dist-cli/chunks/{hidden-runtime-alias-FUDVEMFB.js → hidden-runtime-alias-XP6UIOBB.js} +2 -2
  68. package/dist-cli/chunks/{home-paths-KU4MY22X.js → home-paths-P42GRSQY.js} +2 -2
  69. package/dist-cli/chunks/inspect-2DIGODVM.js +2 -0
  70. package/dist-cli/chunks/install-desktop-6LIZLRKG.js +2 -0
  71. package/dist-cli/chunks/{login-EVS4SZQN.js → login-YZZ5E2JX.js} +4 -4
  72. package/dist-cli/chunks/{logout-K5MLSAWM.js → logout-5IQ5RPGO.js} +2 -2
  73. package/dist-cli/chunks/{maestro-OEDT2T7V.js → maestro-E7WHSRYO.js} +3 -3
  74. package/dist-cli/chunks/{maestro-generate-T4RZSVSM.js → maestro-generate-6RB32Y5P.js} +3 -3
  75. package/dist-cli/chunks/{mode-TZU7JML2.js → mode-2O2MNOLK.js} +2 -2
  76. package/dist-cli/chunks/optional-demo-registry-4W3FLQ5S.js +2 -0
  77. package/dist-cli/chunks/{perf-YNBU57WH.js → perf-DHQW6UCP.js} +2 -2
  78. package/dist-cli/chunks/{record-V6T2INPF.js → record-G2HOBNVZ.js} +3 -3
  79. package/dist-cli/chunks/runtime-GOROX5YB.js +2 -0
  80. package/dist-cli/chunks/{screenshot-command-CZZ6IXSD.js → screenshot-command-PLOLQTKV.js} +3 -3
  81. package/dist-cli/chunks/{screenshots-capture-WVR5FCHX.js → screenshots-capture-RMP2JI5W.js} +2 -2
  82. package/dist-cli/chunks/{serve-6I35UUFI.js → serve-3R7JKMT2.js} +17 -17
  83. package/dist-cli/chunks/{setup-O7GD6GME.js → setup-MORUIXQH.js} +3 -3
  84. package/dist-cli/chunks/{skills-GBTBS2OK.js → skills-J3YCPB42.js} +2 -2
  85. package/dist-cli/chunks/{storage-FI2YOPQE.js → storage-WIT27K32.js} +2 -2
  86. package/dist-cli/chunks/store-PXZDG6EY.js +2 -0
  87. package/dist-cli/chunks/telemetry-QEC64Z6W.js +2 -0
  88. package/dist-cli/chunks/{timeline-E5DVVATK.js → timeline-TQGNIYN5.js} +2 -2
  89. package/dist-cli/chunks/{upgrade-QKOI3Q4U.js → upgrade-QZ4UZRY6.js} +2 -2
  90. package/dist-cli/chunks/upload-SWQJWEVW.js +2 -0
  91. package/dist-cli/chunks/{version-UANAPNZM.js → version-FVUUQVEF.js} +2 -2
  92. package/dist-cli/chunks/{web-4LZ7DUUS.js → web-PBX2PV5P.js} +2 -2
  93. package/dist-cli/chunks/{what-happened-JOLNICMX.js → what-happened-YXRQP5YZ.js} +2 -2
  94. package/dist-lib/agent-daemon-client.cjs +1 -1
  95. package/dist-lib/agent-events.cjs +1 -1
  96. package/dist-lib/agent-identity.cjs +1 -1
  97. package/dist-lib/agent-sessions.cjs +1 -1
  98. package/dist-lib/attached-projects.cjs +1 -1
  99. package/dist-lib/auth/shared-session.cjs +1 -1
  100. package/dist-lib/backend-origin.cjs +1 -1
  101. package/dist-lib/beta.cjs +1 -1
  102. package/dist-lib/beta.mjs +1 -1
  103. package/dist-lib/bridge-constants.cjs +1 -1
  104. package/dist-lib/cli-constants.cjs +1 -1
  105. package/dist-lib/config.cjs +1 -1
  106. package/dist-lib/detox/index.cjs +1 -1
  107. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  108. package/dist-lib/home-paths.cjs +1 -1
  109. package/dist-lib/host/bridge-host.cjs +18 -1
  110. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  111. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  112. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  113. package/dist-lib/host/websocket-proxy.cjs +1 -1
  114. package/dist-lib/index.cjs +1 -1
  115. package/dist-lib/jump-to-source-babel.cjs +1 -1
  116. package/dist-lib/menu.cjs +1 -1
  117. package/dist-lib/menu.mjs +1 -1
  118. package/dist-lib/metro.cjs +1 -1
  119. package/dist-lib/profiles.cjs +1 -1
  120. package/dist-lib/render-mode.cjs +1 -1
  121. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  122. package/dist-lib/sdk.cjs +157 -5
  123. package/dist-lib/sdk.mjs +156 -5
  124. package/dist-lib/skills.cjs +161 -4
  125. package/dist-lib/vite.cjs +1 -1
  126. package/package.json +1 -1
  127. package/skills/contrast/SKILL.md +1 -1
  128. package/skills/sootsim-debug/SKILL.md +21 -12
  129. package/src/host/bridge-host.ts +10 -0
  130. package/dist-cli/chunks/beta-KMI4GCCN.js +0 -2
  131. package/dist-cli/chunks/chunk-3RYTIG4Y.js +0 -118
  132. package/dist-cli/chunks/chunk-R54EGANH.js +0 -1
  133. package/dist-cli/chunks/chunk-U3VMQUN6.js +0 -1
  134. package/dist-cli/chunks/cli-version-2BXTYTLJ.js +0 -2
  135. package/dist-cli/chunks/daemon-VTG3XKWA.js +0 -2
  136. package/dist-cli/chunks/drivers-RDXY5SDO.js +0 -2
  137. package/dist-cli/chunks/flow-KS77CBEA.js +0 -2
  138. package/dist-cli/chunks/help-H3ZD3LVG.js +0 -2
  139. package/dist-cli/chunks/inspect-ACDDO276.js +0 -2
  140. package/dist-cli/chunks/install-desktop-UQVXJAXS.js +0 -2
  141. package/dist-cli/chunks/optional-demo-registry-NIJ3MA5N.js +0 -2
  142. package/dist-cli/chunks/runtime-7XBSKGNO.js +0 -2
  143. package/dist-cli/chunks/store-FU7T5NPV.js +0 -2
  144. package/dist-cli/chunks/telemetry-REPVX6LA.js +0 -2
  145. package/dist-cli/chunks/upload-IFQM3FG4.js +0 -2
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- function W(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r){let s=t.indexOf(n);if(s>=0&&t[s+1]){let o=Number(t[s+1]);if(Number.isFinite(o))return Math.max(100,o)}}return e}var S=new Set(["tap","double-tap","tap-text","tap-id","long-press","touch"]);function v(t){return typeof t=="string"&&S.has(t)}async function I(t){return await t.send({type:"evaluate",code:"window.__sootsimEngineState?.inspectActive === true"})===!0}async function H(t,e){if(!v(e))return!1;try{return await I(t)}catch{return!1}}async function B(t){let e=await t.send({type:"evaluate",code:"(async () => await window.__sootsimTest.getNodeCount())()"});return{nodes:typeof e=="number"?e:0}}async function F(t,e=5,r){let n=r?.format?`, ${JSON.stringify(r)}`:"",s=await t.send({type:"evaluate",code:`(async () => await window.__sootsimTest.dumpTree(${e}${n}))()`});if(r?.format==="boxes"&&typeof s=="string")try{return{depth:e,tree:JSON.parse(s)}}catch{return{depth:e,tree:s}}return{depth:e,tree:s}}async function j(t){let e=await t.send({type:"evaluate",code:"window.location.href"});return{url:typeof e=="string"?e:""}}async function z(t,e){let r=`(async () => {
1
+ /*! sootsim v0.1.242 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ function G(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r){let o=t.indexOf(n);if(o>=0&&t[o+1]){let s=Number(t[o+1]);if(Number.isFinite(s))return Math.max(100,s)}}return e}var L=new Set(["tap","double-tap","tap-text","tap-id","long-press","touch"]);function M(t){return typeof t=="string"&&L.has(t)}async function P(t){return await t.send({type:"evaluate",code:"window.__sootsimEngineState?.inspectActive === true"})===!0}async function Q(t,e){if(!M(e))return!1;try{return await P(t)}catch{return!1}}async function X(t){let e=await t.send({type:"evaluate",code:"(async () => await window.__sootsimTest.getNodeCount())()"});return{nodes:typeof e=="number"?e:0}}async function Z(t,e=5,r){let n=r?.format?`, ${JSON.stringify(r)}`:"",o=await t.send({type:"evaluate",code:`(async () => await window.__sootsimTest.dumpTree(${e}${n}))()`});if(r?.format==="boxes"&&typeof o=="string")try{return{depth:e,tree:JSON.parse(o)}}catch{return{depth:e,tree:o}}return{depth:e,tree:o}}async function ee(t){let e=await t.send({type:"evaluate",code:"window.location.href"});return{url:typeof e=="string"?e:""}}async function te(t,e){let r=`(async () => {
3
3
  const t = window.__sootsimTest
4
4
  const mainShell = window.SootSim?.bridges?.mainShell
5
5
  const kb = window.__sootsimKeyboard
@@ -76,12 +76,13 @@ function W(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r
76
76
  const nodeCount = (await t.getNodeCount?.()) || 0
77
77
  const keyboard = kb && typeof kb.getLayout === 'function' ? kb.getLayout() : null
78
78
  return { tree, shell, nodeCount, keyboard }
79
- })()`;return await t.send({type:"evaluate",code:r})??{}}function m(t={}){let e=t.styling===!0,r=t.filter?.trim().toLowerCase()??"";return`(async () => {
79
+ })()`;return await t.send({type:"evaluate",code:r})??{}}function D(t){let e=t.fontSize>=18||t.fontSize>=14&&(t.fontWeight??400)>=700?3:4.5,{normal:r,background:n}=t;if(r.width<=0||r.height<=0||r.width!==n.width||r.height!==n.height)return{ratio:null,required:e,reason:"capture dimensions do not match"};let o=Math.max(0,Math.floor(t.box.x)),s=Math.max(0,Math.floor(t.box.y)),i=Math.min(r.width,Math.ceil(t.box.x+t.box.w)),d=Math.min(r.height,Math.ceil(t.box.y+t.box.h));if(i<=o||d<=s)return{ratio:null,required:e,reason:"text is outside the captured frame"};let p=l=>{let u=l/255;return u<=.04045?u/12.92:Math.pow((u+.055)/1.055,2.4)},f=(l,u)=>{let c=.2126*p(l[0])+.7152*p(l[1])+.0722*p(l[2]),S=.2126*p(u[0])+.7152*p(u[1])+.0722*p(u[2]);return(Math.max(c,S)+.05)/(Math.min(c,S)+.05)},a=l=>`#${l.slice(0,3).map(u=>Math.round(u).toString(16).padStart(2,"0")).join("")}`,g=(i-o)*(d-s),b=Math.max(1,Math.floor(Math.sqrt(g/12e3))),m=(l,u)=>(u*r.width+l)*4,h=l=>Math.max(Math.abs(r.data[l]-n.data[l]),Math.abs(r.data[l+1]-n.data[l+1]),Math.abs(r.data[l+2]-n.data[l+2])),y=0,v=null,x=null;for(let l=s;l<d;l+=b)for(let u=o;u<i;u+=b){let c=m(u,l);if(n.data[c+3]<250)continue;let S=[n.data[c],n.data[c+1],n.data[c+2]];x??=S;let E=h(c);E<=y||(y=E,v=[r.data[c],r.data[c+1],r.data[c+2]])}let w=1/0,I=null,T=null,k=(l,u)=>{let c=f(l,u);c>=w||(w=c,I=l,T=u)};if(y>=2&&v)for(let l=s;l<d;l+=b)for(let u=o;u<i;u+=b){let c=m(u,l);n.data[c+3]<250||h(c)<2||k(v,[n.data[c],n.data[c+1],n.data[c+2]])}else x&&k(x,x);return!I||!T||!Number.isFinite(w)?{ratio:null,required:e,reason:"could not isolate opaque rendered text pixels"}:{ratio:Math.round(w*100)/100,required:e,foreground:a(I),background:a(T)}}function N(t={}){let e=t.styling===!0,r=t.filter?.trim().toLowerCase()??"";return`(async () => {
80
80
  const t = window.__sootsimTest
81
81
  if (!t || typeof t.listInspectable !== 'function') return []
82
82
  const list = await t.listInspectable({})
83
83
  if (!Array.isArray(list)) return []
84
84
  const includeStyle = ${JSON.stringify(e)}
85
+ const scoreContrast = ${D.toString()}
85
86
  // narrows by ELEMENT, not by style field: fewer rows, full detail on each.
86
87
  const filter = ${JSON.stringify(r)}
87
88
  const matchesFilter = (n, text) => {
@@ -126,7 +127,7 @@ function W(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r
126
127
  }
127
128
  const weightOf = (style) => {
128
129
  const w = style && style.fontWeight
129
- const n = typeof w === 'number' ? w : (typeof w === 'string' ? parseInt(w, 10) : NaN)
130
+ const n = w === 'bold' ? 700 : (typeof w === 'number' ? w : (typeof w === 'string' ? parseInt(w, 10) : NaN))
130
131
  return Number.isFinite(n) && n >= 600 ? n : undefined
131
132
  }
132
133
  const decoOf = (style) => {
@@ -169,7 +170,7 @@ function W(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r
169
170
  return abs.x + layout.width > 0 && abs.y + layout.height > 0 && abs.x < screenW && abs.y < screenH
170
171
  }
171
172
 
172
- return list.filter(isVisible).filter((n) => {
173
+ const elements = list.filter(isVisible).filter((n) => {
173
174
  const t = typeof n.text === 'string' && n.text.trim() ? n.text.trim() : undefined
174
175
  return matchesFilter(n, t)
175
176
  }).map((n) => {
@@ -204,7 +205,7 @@ function W(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r
204
205
  ...base,
205
206
  borderRadius: radiusOf(style),
206
207
  padding: { t: round(pad.top), r: round(pad.right), b: round(pad.bottom), l: round(pad.left) },
207
- fontSize: fontSizeOf(style),
208
+ fontSize: text ? (fontSizeOf(style) || 14) : 0,
208
209
  color: text ? colorStr(style.color) : undefined,
209
210
  bg: colorStr(style.backgroundColor),
210
211
  opacity: opacityOf(style),
@@ -215,8 +216,52 @@ function W(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r
215
216
  borderColor: borderWidth ? borderColorOf(style) : undefined,
216
217
  }
217
218
  })
218
- })()`}var J=m();async function K(t,e={}){let r=await t.send({type:"evaluate",code:m(e)});return Array.isArray(r)?r:[]}function V(t,e){return t.length===0?" no visible elements found":t.map(n=>{let o=[n.testID?`#${n.testID}`:n.selector?n.selector:n.role?`[${n.role}]`:`<${n.type}>`,`@(${n.box.x},${n.box.y})`,`${n.box.w}x${n.box.h}`];n.borderRadius>0&&o.push(`radius:${n.borderRadius}`);let a=n.padding;if(a.t||a.r||a.b||a.l){let l=a.t===a.r&&a.r===a.b&&a.b===a.l;o.push(l?`pad:${a.t}`:`pad:${a.t},${a.r},${a.b},${a.l}`)}if(n.fontSize>0&&o.push(`font:${n.fontSize}`),e?.styling&&(n.fontWeight&&o.push(`weight:${n.fontWeight}`),n.color&&o.push(`color:${n.color}`),n.bg&&o.push(`bg:${n.bg}`),n.opacity!=null&&o.push(`opacity:${n.opacity}`),n.textDecoration&&o.push(`deco:${n.textDecoration}`),n.overflow&&o.push(`overflow:${n.overflow}`),n.borderWidth&&o.push(n.borderColor?`border:${n.borderWidth}/${n.borderColor}`:`border:${n.borderWidth}`)),n.text){let l=n.text.length>40?`${n.text.slice(0,39)}\u2026`:n.text;o.push(`"${l}"`)}return` ${o.join(" ")}`}).join(`
219
- `)}var T=`(async () => {
219
+ const textElements = elements.filter((element) => element.text && element.fontSize > 0)
220
+ if (!includeStyle || textElements.length === 0) return elements
221
+
222
+ const screenshot = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.screenshot
223
+ if (typeof screenshot !== 'function') {
224
+ throw new Error('styled native layout requires the SootSim capture bridge')
225
+ }
226
+ const device = list.find((node) => node && node.device)?.device || {}
227
+ const width = Math.round(Number(device.width) || window.innerWidth || 0)
228
+ const height = Math.round(Number(device.height) || window.innerHeight || 0)
229
+ if (!width || !height) throw new Error('native layout has no capture dimensions')
230
+ const capture = async (suppressText) => {
231
+ const dataUrl = await screenshot({
232
+ format: 'png',
233
+ outputWidth: width,
234
+ outputHeight: height,
235
+ ...(suppressText ? { suppressText: true } : {}),
236
+ })
237
+ const image = await new Promise((resolve, reject) => {
238
+ const next = new Image()
239
+ next.onload = () => resolve(next)
240
+ next.onerror = () => reject(new Error('could not decode native layout pixels'))
241
+ next.src = dataUrl
242
+ })
243
+ const canvas = document.createElement('canvas')
244
+ canvas.width = image.naturalWidth
245
+ canvas.height = image.naturalHeight
246
+ const context = canvas.getContext('2d', { willReadFrequently: true })
247
+ if (!context) throw new Error('could not read native layout pixels')
248
+ context.drawImage(image, 0, 0)
249
+ return context.getImageData(0, 0, canvas.width, canvas.height)
250
+ }
251
+ const normal = await capture(false)
252
+ const background = await capture(true)
253
+ for (const element of textElements) {
254
+ element.contrast = scoreContrast({
255
+ normal,
256
+ background,
257
+ box: element.box,
258
+ fontSize: element.fontSize,
259
+ fontWeight: element.fontWeight,
260
+ })
261
+ }
262
+ return elements
263
+ })()`}var ne=N();async function re(t,e={}){let r=await t.send({type:"evaluate",code:N(e)});return Array.isArray(r)?r:[]}function oe(t,e){return t.length===0?" no visible elements found":t.map(n=>{let s=[n.testID?`#${n.testID}`:n.selector?n.selector:n.role?`[${n.role}]`:`<${n.type}>`,`@(${n.box.x},${n.box.y})`,`${n.box.w}x${n.box.h}`];n.borderRadius>0&&s.push(`radius:${n.borderRadius}`);let i=n.padding;if(i.t||i.r||i.b||i.l){let d=i.t===i.r&&i.r===i.b&&i.b===i.l;s.push(d?`pad:${i.t}`:`pad:${i.t},${i.r},${i.b},${i.l}`)}if(n.fontSize>0&&s.push(`font:${n.fontSize}`),e?.styling){if(n.fontWeight&&s.push(`weight:${n.fontWeight}`),n.color&&s.push(`color:${n.color}`),n.bg&&s.push(`bg:${n.bg}`),n.contrast){let d=n.contrast.ratio==null?`?/${n.contrast.required}`:`${n.contrast.ratio}/${n.contrast.required}${n.contrast.ratio<n.contrast.required?" FAIL":""}`;s.push(`contrast:${d}`),n.contrast.background&&s.push(`on:${n.contrast.background}`)}n.opacity!=null&&s.push(`opacity:${n.opacity}`),n.textDecoration&&s.push(`deco:${n.textDecoration}`),n.overflow&&s.push(`overflow:${n.overflow}`),n.borderWidth&&s.push(n.borderColor?`border:${n.borderWidth}/${n.borderColor}`:`border:${n.borderWidth}`)}if(n.text){let d=n.text.length>40?`${n.text.slice(0,39)}\u2026`:n.text;s.push(`"${d}"`)}return` ${s.join(" ")}`}).join(`
264
+ `)}var O=`(async () => {
220
265
  const t = window.__sootsimTest
221
266
  if (!t) return []
222
267
 
@@ -289,7 +334,7 @@ function W(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r
289
334
  return all
290
335
  .filter(n => isVisibleTarget(n) && hasAccessibleSignal(n))
291
336
  .map(normalize)
292
- })()`;async function Y(t){let e=await t.send({type:"evaluate",code:T});return Array.isArray(e)?e:[]}var g=`
337
+ })()`;async function se(t){let e=await t.send({type:"evaluate",code:O});return Array.isArray(e)?e:[]}var R=`
293
338
  const fromInspectable = async () => {
294
339
  if (typeof t.listInspectable !== 'function') return null
295
340
  const list = await t.listInspectable({})
@@ -361,7 +406,7 @@ function W(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r
361
406
  abs.y < screenH
362
407
  )
363
408
  }
364
- `;function E(t){return t.testId?{mode:"testid",code:`(async () => {
409
+ `;function C(t){return t.testId?{mode:"testid",code:`(async () => {
365
410
  const t = window.__sootsimTest
366
411
  if (!t) return null
367
412
  return (await t.findByTestId(${JSON.stringify(t.testId)})) || (await t.findById(${JSON.stringify(t.testId)}))
@@ -376,7 +421,7 @@ function W(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r
376
421
  })()`}:t.pressable?{mode:"pressable",code:`(async () => {
377
422
  const t = window.__sootsimTest
378
423
  if (!t) return []
379
- ${g}
424
+ ${R}
380
425
  const inspectable = await fromInspectable()
381
426
  if (inspectable) return inspectable.filter(n => n.pressable && isVisibleTarget(n))
382
427
  const all = await t.queryAll({ pruneHidden: true })
@@ -384,7 +429,7 @@ ${g}
384
429
  })()`}:t.interactive?{mode:"interactive-targets",code:`(async () => {
385
430
  const t = window.__sootsimTest
386
431
  if (!t) return []
387
- ${g}
432
+ ${R}
388
433
  const inspectable = await fromInspectable()
389
434
  if (inspectable) {
390
435
  return inspectable.filter(n => n.pressable && isVisibleTarget(n))
@@ -400,7 +445,7 @@ ${g}
400
445
  const t = window.__sootsimTest
401
446
  if (!t) return null
402
447
  return await t.findByText(${JSON.stringify(t.text)})
403
- })()`}:null}async function G(t,e){let r=E(e);if(!r)return null;let n=await t.send({type:"evaluate",code:r.code});return{mode:r.mode,result:n}}function U(t){return[...t].sort((e,r)=>b(r)-b(e))}function b(t){let e=0;t.testID&&(e+=100),typeof t.text=="string"&&t.text.trim().length>0&&(e+=60),typeof t.accessibilityLabel=="string"&&t.accessibilityLabel.trim().length>0&&(e+=30),t.accessibilityRole&&(e+=15);let r=t.layout?.width??0,n=t.layout?.height??0,s=r*n;return s>=400&&s<=6e4?e+=25:s>6e4&&(e-=20),(t.absolutePosition?.y??0)<0&&(e-=30),e}function Q(t){if(t.testID)return`sootsim do tap-id ${f(t.testID)}`;let e=typeof t.text=="string"?t.text.trim():"";if(e.length>0&&e.length<=80)return`sootsim do tap-text ${f(e)}`;let r=Math.round(((t.absolutePosition?.x??0)+(t.layout?.width??0)/2)*10)/10,n=Math.round(((t.absolutePosition?.y??0)+(t.layout?.height??0)/2)*10)/10;return`sootsim do tap ${r} ${n}`}function f(t){return/^[A-Za-z0-9_./@:-]+$/.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}var k=`(async () => {
448
+ })()`}:null}async function ae(t,e){let r=C(e);if(!r)return null;let n=await t.send({type:"evaluate",code:r.code});return{mode:r.mode,result:n}}function ie(t){return[...t].sort((e,r)=>$(r)-$(e))}function $(t){let e=0;t.testID&&(e+=100),typeof t.text=="string"&&t.text.trim().length>0&&(e+=60),typeof t.accessibilityLabel=="string"&&t.accessibilityLabel.trim().length>0&&(e+=30),t.accessibilityRole&&(e+=15);let r=t.layout?.width??0,n=t.layout?.height??0,o=r*n;return o>=400&&o<=6e4?e+=25:o>6e4&&(e-=20),(t.absolutePosition?.y??0)<0&&(e-=30),e}function le(t){if(t.testID)return`sootsim do tap-id ${_(t.testID)}`;let e=typeof t.text=="string"?t.text.trim():"";if(e.length>0&&e.length<=80)return`sootsim do tap-text ${_(e)}`;let r=Math.round(((t.absolutePosition?.x??0)+(t.layout?.width??0)/2)*10)/10,n=Math.round(((t.absolutePosition?.y??0)+(t.layout?.height??0)/2)*10)/10;return`sootsim do tap ${r} ${n}`}function _(t){return/^[A-Za-z0-9_./@:-]+$/.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}var W=`(async () => {
404
449
  const t = window.__sootsimTest
405
450
  let nodes = 0
406
451
  try { nodes = (await t?.getNodeCount?.()) || 0 } catch {}
@@ -519,10 +564,10 @@ ${g}
519
564
  externalError,
520
565
  suppressedEntryError,
521
566
  }
522
- })()`,R=100,$=750,_=2e3;function N(t){return t.targets>0||t.nodes>=R}function A(t){return t.targets>0}function q(t){if(t.bridgeError)return`sim unreachable: ${t.bridgeError} \u2014 the target tab is closed or no sim is connected (check \`sootsim list\`, reopen with \`sootsim open\`)`;let e=t.externalError?`guest app errored: ${t.externalError}`:t.loadingText?`still showing "${t.loadingText}"`:t.externalReady===!1?"guest app is still loading":t.flag!==!0&&t.targets>0?"native content is rendered but the ready signal has not settled":t.flag!==!0?"guest app has not emitted sootsim:externalAppReady":t.targets<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing";return!t.externalError&&t.suppressedEntryError?`${e} (suppressed entry error: ${t.suppressedEntryError})`:e}async function X(t,e=2e4,r={}){let n=Date.now(),s=n+e,o=r.progressIntervalMs??_,a=n+o,l=-1,u=n,p="",i={flag:void 0,at:0,nodes:0,targets:0,errors:0,loadingText:"",externalReady:null,externalStatus:"",externalError:"",suppressedEntryError:""};for(;Date.now()<s;){try{i=await t.send({type:"evaluate",code:k})??i,p=""}catch(d){p=d instanceof Error?d.message:String(d)}let c=Date.now(),y={ready:!1,elapsedMs:c-n,nodes:i.nodes,targets:i.targets,flag:i.flag,loadingText:i.loadingText,externalReady:i.externalReady,externalStatus:i.externalStatus,externalError:i.externalError,suppressedEntryError:i.suppressedEntryError,errors:i.errors,bridgeError:p};i.nodes!==l&&(l=i.nodes,u=c);let w=i.flag===!0&&N(i),x=i.flag!==!0&&A(i);if((w||x)&&i.externalReady!==!1&&!i.externalError&&!i.loadingText&&c-u>=$)return{...y,ready:!0};if(r.onProgress&&o>0&&c>=a){r.onProgress(y);do a+=o;while(c>=a)}await new Promise(d=>setTimeout(d,150))}return{ready:!1,elapsedMs:Date.now()-n,nodes:i.nodes,targets:i.targets,flag:i.flag,loadingText:i.loadingText,externalReady:i.externalReady,externalStatus:i.externalStatus,externalError:i.externalError,suppressedEntryError:i.suppressedEntryError,errors:i.errors,bridgeError:p}}async function Z(t,e,r=5e3,n={}){let s=n.gone===!0;return await t.send({type:"evaluate",code:`(async () => {
567
+ })()`,H=100,B=750,F=2e3;function z(t){return t.targets>0||t.nodes>=H}function j(t){return t.targets>0}function ue(t){if(t.bridgeError)return`sim unreachable: ${t.bridgeError} \u2014 the target tab is closed or no sim is connected (check \`sootsim list\`, reopen with \`sootsim open\`)`;let e=t.externalError?`guest app errored: ${t.externalError}`:t.loadingText?`still showing "${t.loadingText}"`:t.externalReady===!1?"guest app is still loading":t.flag!==!0&&t.targets>0?"native content is rendered but the ready signal has not settled":t.flag!==!0?"guest app has not emitted sootsim:externalAppReady":t.targets<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing";return!t.externalError&&t.suppressedEntryError?`${e} (suppressed entry error: ${t.suppressedEntryError})`:e}async function ce(t,e=2e4,r={}){let n=Date.now(),o=n+e,s=r.progressIntervalMs??F,i=n+s,d=-1,p=n,f="",a={flag:void 0,at:0,nodes:0,targets:0,errors:0,loadingText:"",externalReady:null,externalStatus:"",externalError:"",suppressedEntryError:""};for(;Date.now()<o;){try{a=await t.send({type:"evaluate",code:W})??a,f=""}catch(y){f=y instanceof Error?y.message:String(y)}let g=Date.now(),b={ready:!1,elapsedMs:g-n,nodes:a.nodes,targets:a.targets,flag:a.flag,loadingText:a.loadingText,externalReady:a.externalReady,externalStatus:a.externalStatus,externalError:a.externalError,suppressedEntryError:a.suppressedEntryError,errors:a.errors,bridgeError:f};a.nodes!==d&&(d=a.nodes,p=g);let m=a.flag===!0&&z(a),h=a.flag!==!0&&j(a);if((m||h)&&a.externalReady!==!1&&!a.externalError&&!a.loadingText&&g-p>=B)return{...b,ready:!0};if(r.onProgress&&s>0&&g>=i){r.onProgress(b);do i+=s;while(g>=i)}await new Promise(y=>setTimeout(y,150))}return{ready:!1,elapsedMs:Date.now()-n,nodes:a.nodes,targets:a.targets,flag:a.flag,loadingText:a.loadingText,externalReady:a.externalReady,externalStatus:a.externalStatus,externalError:a.externalError,suppressedEntryError:a.suppressedEntryError,errors:a.errors,bridgeError:f}}async function de(t,e,r=5e3,n={}){let o=n.gone===!0;return await t.send({type:"evaluate",code:`(async () => {
523
568
  const start = Date.now()
524
569
  const deadline = start + ${r}
525
- const gone = ${s}
570
+ const gone = ${o}
526
571
  const ID = ${JSON.stringify(e)}
527
572
  const present = (node) => !!(node && node.layout && node.layout.width > 0 && node.layout.height > 0)
528
573
  const find = async () => {
@@ -562,7 +607,7 @@ ${g}
562
607
  await new Promise((r) => setTimeout(r, 80))
563
608
  }
564
609
  return { found: false, elapsed: Date.now() - start }
565
- })()`},{timeoutMs:r+1e3})??{found:!1,elapsed:r}}function h(t,e){return`(() => {
610
+ })()`},{timeoutMs:r+1e3})??{found:!1,elapsed:r}}function A(t,e){return`(() => {
566
611
  const out = []
567
612
  const seen = new Set()
568
613
  const norm = (s) => (typeof s === 'string' ? s : (() => { try { return JSON.stringify(s) } catch { return String(s) } })())
@@ -584,7 +629,7 @@ ${g}
584
629
  for (const e of snap) if (e && e.level === ${JSON.stringify(t)}) push(e)
585
630
  } catch {}
586
631
  return out.sort((a, b) => (a.timestamp || 0) - (b.timestamp || 0)).slice(-${e})
587
- })()`}async function ee(t,e=20){let r=await t.send({type:"evaluate",code:h("error",e)});return Array.isArray(r)?r:[]}async function te(t,e=20){let r=await t.send({type:"evaluate",code:h("warn",e)});return Array.isArray(r)?r:[]}var ne=`(() => {
632
+ })()`}async function pe(t,e=20){let r=await t.send({type:"evaluate",code:A("error",e)});return Array.isArray(r)?r:[]}async function ye(t,e=20){let r=await t.send({type:"evaluate",code:A("warn",e)});return Array.isArray(r)?r:[]}var ge=`(() => {
588
633
  const norm = (s) => (typeof s === 'string' ? s : (() => { try { return JSON.stringify(s) } catch { return String(s) } })())
589
634
  const key = (lvl, ts, args) => lvl + '|' + Math.round((ts || 0) / 250) + '|' + (Array.isArray(args) ? args.map(norm).join(' ') : norm(args))
590
635
  const seen = new Set()
@@ -609,23 +654,27 @@ ${g}
609
654
  for (const e of snap) if (e) add(e.level, e.ts, e.args)
610
655
  } catch {}
611
656
  return { errors, warnings, total: errors + warnings }
612
- })()`;async function re(t){await t.send({type:"evaluate",code:'window.__sootsimConsole?.clear(); window.__sootsimObservability?.logs?.clear?.(); "cleared"'})}async function se(t,e={}){let r=e.limit??20,n=e.failed===!1?"getRequests":"getFailedRequests",s=await t.send({type:"call",path:`__sootsimTest.${n}`,args:[r]});return Array.isArray(s)?s:[]}async function oe(t){await t.send({type:"call",path:"__sootsimTest.clearRequests",args:[]})}async function ie(t){let e=await t.send({type:"evaluate",code:`(() => {
657
+ })()`;async function be(t){await t.send({type:"evaluate",code:'window.__sootsimConsole?.clear(); window.__sootsimObservability?.logs?.clear?.(); "cleared"'})}async function fe(t,e={}){let r=e.limit??20,n=e.failed===!1?"getRequests":"getFailedRequests",o=await t.send({type:"call",path:`__sootsimTest.${n}`,args:[r]});return Array.isArray(o)?o:[]}async function me(t){await t.send({type:"call",path:"__sootsimTest.clearRequests",args:[]})}async function he(t){let e=await t.send({type:"evaluate",code:`(() => {
613
658
  const obs = window.__sootsimObservability;
614
659
  if (!obs) return { ok: false };
615
660
  return { ok: true, entries: obs.logs.getSnapshot() };
616
- })()`});return!e||!e.ok?[]:e.entries??[]}async function ae(t){await t.send({type:"evaluate",code:'window.__sootsimObservability?.logs.clear(); "cleared"'})}function L(t,e){if(t.source===e.source||t.level!==e.level||Math.abs(t.ts-e.ts)>1e3||t.args.length!==e.args.length)return!1;let r=new Set([t.source,e.source]);return!r.has("sootsim-worker")||!r.has("render-worker")&&!r.has("forwarded-render-worker")?!1:t.args.every((n,s)=>n===e.args[s])}function le(t,e={}){let r=[];for(let n of t)r.some(s=>L(s,n))||r.push(n);if(e.showInternal||(r=r.filter(n=>{let s=n.args[0];return!(typeof s=="string"&&s.startsWith("[sootsim]"))})),e.level&&(r=r.filter(n=>e.level.has(n.level))),e.filter){let n=e.filter.toLowerCase();r=r.filter(s=>s.args.join(" ").toLowerCase().includes(n))}return r}async function ue(t,e){return await t.send({type:"call",path:"SootSim.bridges.timeline.summary",args:[e]})}async function P(t,e){return await t.send({type:"call",path:"SootSim.bridges.timeline.recent",args:[e]})}async function ce(t){let e;try{e=(await P(t,{kinds:["alert","actionsheet"],limit:80})).events}catch{return[]}let r=new Map;for(let o of e)r.set(o.kind,o);let n=[],s=(o,a)=>{let l=r.get(o);if(!l||!l.data||typeof l.data!="object")return;let u=l.data;u.phase==="show"&&n.push({label:a,title:typeof u.title=="string"?u.title:null})};return s("alert","Alert"),s("actionsheet","ActionSheet"),n}async function de(t,e,r){await t.send({type:"call",path:"SootSim.bridges.timeline.cursorAdvance",args:[e,r]})}async function pe(t){return await t.send({type:"evaluate",code:`(() => {
661
+ })()`});return!e||!e.ok?[]:e.entries??[]}async function xe(t){await t.send({type:"evaluate",code:'window.__sootsimObservability?.logs.clear(); "cleared"'})}function J(t,e){if(t.source===e.source||t.level!==e.level||Math.abs(t.ts-e.ts)>1e3||t.args.length!==e.args.length)return!1;let r=new Set([t.source,e.source]);return!r.has("sootsim-worker")||!r.has("render-worker")&&!r.has("forwarded-render-worker")?!1:t.args.every((n,o)=>n===e.args[o])}function we(t,e={}){let r=[];for(let n of t)r.some(o=>J(o,n))||r.push(n);if(e.showInternal||(r=r.filter(n=>{let o=n.args[0];return!(typeof o=="string"&&o.startsWith("[sootsim]"))})),e.level&&(r=r.filter(n=>e.level.has(n.level))),e.filter){let n=e.filter.toLowerCase();r=r.filter(o=>o.args.join(" ").toLowerCase().includes(n))}return r}async function Se(t,e){return await t.send({type:"call",path:"SootSim.bridges.timeline.summary",args:[e]})}async function K(t,e){return await t.send({type:"call",path:"SootSim.bridges.timeline.recent",args:[e]})}async function ve(t){let e;try{e=(await K(t,{kinds:["alert","actionsheet"],limit:80})).events}catch{return[]}let r=new Map;for(let s of e)r.set(s.kind,s);let n=[],o=(s,i)=>{let d=r.get(s);if(!d||!d.data||typeof d.data!="object")return;let p=d.data;p.phase==="show"&&n.push({label:i,title:typeof p.title=="string"?p.title:null})};return o("alert","Alert"),o("actionsheet","ActionSheet"),n}async function Ie(t,e,r){await t.send({type:"call",path:"SootSim.bridges.timeline.cursorAdvance",args:[e,r]})}async function Te(t){return await t.send({type:"evaluate",code:`(() => {
617
662
  const kb = window.__sootsimKeyboard
618
663
  if (!kb || typeof kb.getLayout !== 'function') {
619
664
  return { error: 'keyboard bridge getLayout() not available' }
620
665
  }
621
666
  return kb.getLayout()
622
- })()`})??{error:"keyboard bridge returned no result"}}function D(t){let e=t instanceof Error?t.message:String(t);return e.includes("call target not found: SootSim.bridges.mainShell")||e.includes("test bridge unavailable before app-in-worker boot")}async function O(t,e=0){let r=Date.now()+Math.max(0,e);for(;;)try{return await t.send({type:"call",path:"SootSim.bridges.mainShell.getState",args:[]})}catch(n){if(!D(n)||Date.now()>=r)throw n;await new Promise(s=>setTimeout(s,50))}}async function ye(t){let e=await t.send({type:"evaluate",code:`(async () => {
667
+ })()`})??{error:"keyboard bridge returned no result"}}function V(t){let e=t instanceof Error?t.message:String(t);return e.includes("call target not found: SootSim.bridges.mainShell")||e.includes("test bridge unavailable before app-in-worker boot")}async function q(t,e=0){let r=Date.now()+Math.max(0,e);for(;;)try{return await t.send({type:"call",path:"SootSim.bridges.mainShell.getState",args:[]})}catch(n){if(!V(n)||Date.now()>=r)throw n;await new Promise(o=>setTimeout(o,50))}}async function ke(t){let e=await t.send({type:"evaluate",code:`(async () => {
623
668
  const test = window.__sootsimTest
624
669
  const kb = window.__sootsimKeyboard
625
670
  const navSnap =
626
671
  test && typeof test.getNavigationSnapshot === 'function'
627
672
  ? await test.getNavigationSnapshot()
628
673
  : null
674
+ const route =
675
+ test && typeof test.getRouteInfo === 'function'
676
+ ? await test.getRouteInfo()
677
+ : null
629
678
  const keyboard =
630
679
  kb && typeof kb.getLayout === 'function'
631
680
  ? (() => {
@@ -642,8 +691,8 @@ ${g}
642
691
  } : null
643
692
  })()
644
693
  : null
645
- return { nav: navSnap, keyboard }
646
- })()`});return{shell:await O(t,500).catch(()=>null),nav:e?.nav??null,keyboard:e?.keyboard??null}}async function ge(t){return t.send({type:"evaluate",code:"window.__sootsimDebug.status()"})}async function be(t){return t.send({type:"evaluate",code:"window.__sootsimDebug.flags()"})}async function fe(t,e){return t.send({type:"evaluate",code:`window.__sootsimTest.debugFind(${JSON.stringify(e)})`})}async function me(t,e,r=50){let n=e&&e!=="all"?`window.__sootsimDebug.recent(${JSON.stringify(e)}, ${r})`:`window.__sootsimDebug.recent(undefined, ${r})`;return t.send({type:"evaluate",code:n})}async function he(t,e,r){let n=r.length>0?r.map(s=>JSON.stringify(s)).join(", "):e==="disable"?"'all'":"";return t.send({type:"evaluate",code:`window.__sootsimDebug.${e}(${n})`})}async function we(t){return await t.send({type:"evaluate",code:`(async () => {
694
+ return { nav: navSnap, route, keyboard }
695
+ })()`});return{shell:await q(t,500).catch(()=>null),nav:e?.nav??null,route:e?.route??null,keyboard:e?.keyboard??null}}async function Ee(t){return t.send({type:"evaluate",code:"window.__sootsimDebug.status()"})}async function Re(t){return t.send({type:"evaluate",code:"window.__sootsimDebug.flags()"})}async function $e(t,e){return t.send({type:"evaluate",code:`window.__sootsimTest.debugFind(${JSON.stringify(e)})`})}async function _e(t,e,r=50){let n=e&&e!=="all"?`window.__sootsimDebug.recent(${JSON.stringify(e)}, ${r})`:`window.__sootsimDebug.recent(undefined, ${r})`;return t.send({type:"evaluate",code:n})}async function Ne(t,e,r){let n=r.length>0?r.map(o=>JSON.stringify(o)).join(", "):e==="disable"?"'all'":"";return t.send({type:"evaluate",code:`window.__sootsimDebug.${e}(${n})`})}async function Ae(t){return await t.send({type:"evaluate",code:`(async () => {
647
696
  const host = window.__sootsimRenderHost
648
697
  const stats = host?.queryStats ? await host.queryStats() : null
649
698
  const shellRaw = window.__sootsimShellMemory
@@ -674,4 +723,4 @@ ${g}
674
723
  shell: normalize(shell),
675
724
  hostHeap: hostMem,
676
725
  }
677
- })()`})??{tenant:null,shell:null,hostHeap:null}}function xe(t){if(t.total===0)return"nothing recorded";let e=[],r=["error","warning","console","fetch","toast","alert","actionsheet","picker","notification","screen","route","keyboard","app-launch","shell","scroll","gesture","text-input","react-commit","animation","reanimated"],n=new Set;for(let s of r){let o=t.byKind[s];o&&(e.push(`${o} ${s}${o===1?"":"s"}`),n.add(s))}for(let[s,o]of Object.entries(t.byKind))!n.has(s)&&o&&e.push(`${o} ${s}${o===1?"":"s"}`);return e.join(" \xB7 ")}var Se=new Set(["react-commit","layout","scroll"]);function M(t,e){if(e===null)return new Date(t).toLocaleTimeString();let r=(t-e)/1e3;return`${r>=0?"+":""}${r.toFixed(2)}s`}function C(t,e){switch(t){case"app-launch":return e.phase==="launch"?`launch ${e.appName??e.toAppId??""}`:`dismiss ${e.appName??e.fromAppId??""} \u2192 ${e.toAppId??""}`;case"toast":return`"${e.text??""}"${e.durationMs?` (${e.durationMs}ms)`:""}`;case"keyboard":return`${e.phase??"?"}${e.heightPx?` h=${e.heightPx}`:""}${e.mode?` ${e.mode}`:""}`;case"screen":return`${e.phase??"?"} ${e.name??e.activeName??""}`;case"flow-step":return`${e.status??"?"} ${e.stepName??"step"}${e.durationMs?` ${e.durationMs}ms`:""}`;case"route":return`${e.phase??"?"} ${e.path??e.pathname??""}`;case"alert":case"actionsheet":case"picker":return`${e.phase??"?"} ${e.title??e.message??""}`;case"notification":return`${e.title??""}${e.body?` \u2014 ${e.body}`:""}`;case"fetch":return`${e.method??"GET"} ${e.url??""}${e.status?` -> ${e.status}`:""}`;case"console":case"console-log":return`${e.level??"log"}: ${(e.message??"").toString().slice(0,120)}`;case"shell":return`${e.event??e.type??e.phase??""}`;case"scroll":return`${e.phase??"?"} ${e.target??""}`;case"gesture":return`${e.phase??"?"} ${e.type??""}`;case"text-input":return`${e.phase??"?"}${e.value!==void 0?` "${String(e.value).slice(0,40)}"`:""}`;case"layout":return`${e.kind??"?"} ${e.testID??e.type??""}${e.skipped?` skipped:${e.reason??"unknown"}`:""}`;case"react-commit":{let r=e.slowest;return`${e.fiberCount??"?"} fibers ${e.durationMs??"?"}ms${r?.displayName?` \xB7 ${r.displayName} ${r.durationMs??"?"}ms`:""}`}case"frame":return`${e.totalMs??"?"}ms${e.renderMs?` \xB7 render ${e.renderMs}ms`:""}${e.layoutMs?` \xB7 layout ${e.layoutMs}ms`:""}${e.copyMs?` \xB7 copy ${e.copyMs}ms`:""}`;case"reanimated":case"animation":return`${e.kind??""} ${e.target??""}${e.durationMs?` ${e.durationMs}ms`:""}`}return""}function ve(t,e){let r=M(t.t,e).padStart(8),n=t.context.padEnd(6),s=`[${t.kind}]`.padEnd(15),o=t.data,a=o&&typeof o=="object"?C(t.kind,o):"";return` ${r} ${n} ${s} ${a}`}export{W as a,H as b,B as c,F as d,j as e,z as f,K as g,V as h,Y as i,G as j,U as k,Q as l,k as m,$ as n,N as o,A as p,q,X as r,Z as s,ee as t,te as u,ne as v,re as w,se as x,oe as y,ie as z,ae as A,le as B,ue as C,P as D,ce as E,de as F,pe as G,D as H,O as I,ye as J,ge as K,be as L,fe as M,me as N,he as O,we as P,xe as Q,Se as R,ve as S};
726
+ })()`})??{tenant:null,shell:null,hostHeap:null}}function Le(t){if(t.total===0)return"nothing recorded";let e=[],r=["error","warning","console","fetch","toast","alert","actionsheet","picker","notification","screen","route","keyboard","app-launch","shell","scroll","gesture","text-input","react-commit","animation","reanimated"],n=new Set;for(let o of r){let s=t.byKind[o];s&&(e.push(`${s} ${o}${s===1?"":"s"}`),n.add(o))}for(let[o,s]of Object.entries(t.byKind))!n.has(o)&&s&&e.push(`${s} ${o}${s===1?"":"s"}`);return e.join(" \xB7 ")}var Me=new Set(["react-commit","layout","scroll"]);function U(t,e){if(e===null)return new Date(t).toLocaleTimeString();let r=(t-e)/1e3;return`${r>=0?"+":""}${r.toFixed(2)}s`}function Y(t,e){switch(t){case"app-launch":return e.phase==="launch"?`launch ${e.appName??e.toAppId??""}`:`dismiss ${e.appName??e.fromAppId??""} \u2192 ${e.toAppId??""}`;case"toast":return`"${e.text??""}"${e.durationMs?` (${e.durationMs}ms)`:""}`;case"keyboard":return`${e.phase??"?"}${e.heightPx?` h=${e.heightPx}`:""}${e.mode?` ${e.mode}`:""}`;case"screen":return`${e.phase??"?"} ${e.name??e.activeName??""}`;case"flow-step":return`${e.status??"?"} ${e.stepName??"step"}${e.durationMs?` ${e.durationMs}ms`:""}`;case"route":return`${e.phase??"?"} ${e.path??e.pathname??""}`;case"alert":case"actionsheet":case"picker":return`${e.phase??"?"} ${e.title??e.message??""}`;case"notification":return`${e.title??""}${e.body?` \u2014 ${e.body}`:""}`;case"fetch":return`${e.method??"GET"} ${e.url??""}${e.status?` -> ${e.status}`:""}`;case"console":case"console-log":return`${e.level??"log"}: ${(e.message??"").toString().slice(0,120)}`;case"shell":return`${e.event??e.type??e.phase??""}`;case"scroll":return`${e.phase??"?"} ${e.target??""}`;case"gesture":return`${e.phase??"?"} ${e.type??""}`;case"text-input":return`${e.phase??"?"}${e.value!==void 0?` "${String(e.value).slice(0,40)}"`:""}`;case"layout":return`${e.kind??"?"} ${e.testID??e.type??""}${e.skipped?` skipped:${e.reason??"unknown"}`:""}`;case"react-commit":{let r=e.slowest;return`${e.fiberCount??"?"} fibers ${e.durationMs??"?"}ms${r?.displayName?` \xB7 ${r.displayName} ${r.durationMs??"?"}ms`:""}`}case"frame":return`${e.totalMs??"?"}ms${e.renderMs?` \xB7 render ${e.renderMs}ms`:""}${e.layoutMs?` \xB7 layout ${e.layoutMs}ms`:""}${e.copyMs?` \xB7 copy ${e.copyMs}ms`:""}`;case"reanimated":case"animation":return`${e.kind??""} ${e.target??""}${e.durationMs?` ${e.durationMs}ms`:""}`}return""}function Pe(t,e){let r=U(t.t,e).padStart(8),n=t.context.padEnd(6),o=`[${t.kind}]`.padEnd(15),s=t.data,i=s&&typeof s=="object"?Y(t.kind,s):"";return` ${r} ${n} ${o} ${i}`}export{G as a,Q as b,X as c,Z as d,ee as e,te as f,re as g,oe as h,se as i,ae as j,ie as k,le as l,W as m,B as n,z as o,j as p,ue as q,ce as r,de as s,pe as t,ye as u,ge as v,be as w,fe as x,me as y,he as z,xe as A,we as B,Se as C,K as D,ve as E,Ie as F,Te as G,V as H,q as I,ke as J,Ee as K,Re as L,$e as M,_e as N,Ne as O,Ae as P,Le as Q,Me as R,Pe as S};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{c as h}from"./chunk-AX56F2Z5.js";import{b as A,e as k,g as L}from"./chunk-NJYDI627.js";import{M as w,N as S,O as I,P as B,g as F}from"./chunk-WYT6JDAV.js";import{WebSocket as T}from"ws";var W=null;function M(){let i=F();if(W?.homeDir===i)return W.world;let r=U();return W={homeDir:i,world:r},r}function U(){let i=S();if(i&&B(i))return{source:"dev-bridge",bridgePort:i.bridgePort,shellBaseUrl:i.shellPort?`http://localhost:${i.shellPort}/`:h};let r=w();return r&&I(r)?{source:"daemon",bridgePort:r.bridgePort,shellBaseUrl:r.runtimePort>0?`http://localhost:${r.runtimePort}/`:h}:{source:"default",bridgePort:7668,shellBaseUrl:h}}function _(i){let r=S();if(r&&B(r)&&r.bridgePort===i)return{source:"dev-bridge",shellBaseUrl:r.shellPort?`http://localhost:${r.shellPort}/`:h};let e=w();return e&&I(e)&&e.bridgePort===i?{source:"daemon",shellBaseUrl:e.runtimePort>0?`http://localhost:${e.runtimePort}/`:h}:null}function K(i){let r;try{let l=new URL(i);r=l.port?Number(l.port):l.protocol==="https:"?443:80}catch{return null}if(!Number.isFinite(r)||r<=0)return null;let e=S();if(e&&B(e)&&(e.shellPort===r||e.runtimePort===r||e.bridgePort===r))return e.bridgePort;let d=w();return d&&I(d)&&(d.runtimePort===r||d.bridgePort===r)?d.bridgePort:null}function D(){return M().bridgePort}function Q(i,r){let e=_(i),d=e?.source==="dev-bridge"?"dev bridge":e?.source==="daemon"?"daemon bridge":"bridge",l=e?`${e.source}.json`:"no lockfile",t=r??e?.shellBaseUrl;process.stderr.write(` \u2192 ${d} :${i} (${t?`shell ${t}, `:""}${l})
1
+ /*! sootsim v0.1.242 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{c as h}from"./chunk-UPGZJEDV.js";import{b as A,e as k,g as L}from"./chunk-S4L7A6CA.js";import{M as w,N as S,O as I,P as B,g as F}from"./chunk-RFYPY6RQ.js";import{WebSocket as T}from"ws";var W=null;function M(){let i=F();if(W?.homeDir===i)return W.world;let r=U();return W={homeDir:i,world:r},r}function U(){let i=S();if(i&&B(i))return{source:"dev-bridge",bridgePort:i.bridgePort,shellBaseUrl:i.shellPort?`http://localhost:${i.shellPort}/`:h};let r=w();return r&&I(r)?{source:"daemon",bridgePort:r.bridgePort,shellBaseUrl:r.runtimePort>0?`http://localhost:${r.runtimePort}/`:h}:{source:"default",bridgePort:7668,shellBaseUrl:h}}function _(i){let r=S();if(r&&B(r)&&r.bridgePort===i)return{source:"dev-bridge",shellBaseUrl:r.shellPort?`http://localhost:${r.shellPort}/`:h};let e=w();return e&&I(e)&&e.bridgePort===i?{source:"daemon",shellBaseUrl:e.runtimePort>0?`http://localhost:${e.runtimePort}/`:h}:null}function K(i){let r;try{let l=new URL(i);r=l.port?Number(l.port):l.protocol==="https:"?443:80}catch{return null}if(!Number.isFinite(r)||r<=0)return null;let e=S();if(e&&B(e)&&(e.shellPort===r||e.runtimePort===r||e.bridgePort===r))return e.bridgePort;let d=w();return d&&I(d)&&(d.runtimePort===r||d.bridgePort===r)?d.bridgePort:null}function D(){return M().bridgePort}function Q(i,r){let e=_(i),d=e?.source==="dev-bridge"?"dev bridge":e?.source==="daemon"?"daemon bridge":"bridge",l=e?`${e.source}.json`:"no lockfile",t=r??e?.shellBaseUrl;process.stderr.write(` \u2192 ${d} :${i} (${t?`shell ${t}, `:""}${l})
3
3
  `)}var $=class extends Error{lock;constructor(r,e){super(r),this.name="BridgeSimLockedError",this.lock=e}};function N(i){return i==="flag"?"via --sim":i==="saved"?"saved via `sootsim use`":"primary fallback \u2014 no sim pinned"}function z(i,r={}){let e=new Set,d=r.port??D(),l=r.commandTimeoutMs??15e3,t,u="none",P=new Set(r.stripBooleanFlags??[]),p=new Set(r.stripValueFlags??[]);for(let n=0;n<i.length;n++){let a=i[n];if(a==="--port"||a==="-p"){e.add(n),n+1<i.length&&(e.add(n+1),d=Number(i[n+1])),n++;continue}if(a.startsWith("--port=")){e.add(n),d=Number(a.slice(7));continue}if(a==="--timeout"){e.add(n),n+1<i.length&&(e.add(n+1),l=Number(i[n+1])),n++;continue}if(a==="--sim"||a==="--session"||a==="--tab"){e.add(n),n+1<i.length&&(e.add(n+1),t=i[n+1]?.trim()||void 0,u="flag"),n++;continue}let s=a.startsWith("--sim=")?a.slice(6):a.startsWith("--session=")?a.slice(10):a.startsWith("--tab=")?a.slice(6):void 0;if(s!==void 0){e.add(n),t=s.trim()||void 0,u="flag";continue}if(P.has(a)){e.add(n);continue}p.has(a)&&(e.add(n),n+1<i.length&&e.add(n+1),n++)}if(!t){let n=k();n&&(t=n.trim()||void 0,u="saved")}return{positional:i.filter((n,a)=>!e.has(a)),wsPort:d,simId:t,simIdSource:u,commandTimeoutMs:l}}function R(i,r={}){let e=1,d=r.commandTimeoutMs??15e3,l=new Map,t=new T(`ws://localhost:${i}`),u=A(),P=new Promise((s,o)=>{t.on("open",()=>{try{t.send(JSON.stringify({type:"bridge:hello",id:0,cliIdentityKey:u.key,cliIdentitySource:u.source,cliLabel:r.cliLabel}))}catch{}s()}),t.on("error",c=>{let m=c.message?`: ${c.message}`:"";o(new Error(`could not connect to ws://localhost:${i}${m}`))})}),p=!1,n=!1;function a(s,o){if(n||process.env.SOOTSIM_QUIET_TARGET_NOTICE==="1"||s.startsWith("bridge:")||s==="focus"||s==="close")return;n=!0;let c=o??"primary",m=N(o?r.simIdSource:"none");process.stderr.write(` \u2192 ${c} (${m})
4
4
  `)}return t.on("message",s=>{let o;try{o=JSON.parse(s.toString())}catch{return}if(o.id===0)return;let c=l.get(o.id);c&&(l.delete(o.id),o._otherCliCount>0&&!p&&(p=!0,process.stderr.write(`
5
5
  \u26A0 ${o._otherCliCount} other CLI identity/identities are driving this sim
@@ -0,0 +1 @@
1
+ /*! sootsim v0.1.242 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as o}from"./chunk-EJ6ULQFO.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
+ /*! sootsim v0.1.242 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as o}from"./chunk-H7UA4DWW.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.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as K,b as V,c as Ne}from"./chunk-DEO54ZY3.js";import{c as Pe}from"./chunk-ILU6JNUJ.js";import{d as _e}from"./chunk-M3VY5LEN.js";import{d as Oe}from"./chunk-BWR3AJZ3.js";import{g as $e,i as Fe,k as B}from"./chunk-H6GS5C4F.js";import{a as Ue,b as E}from"./chunk-4FUKKXDQ.js";import{a as Ae}from"./chunk-EJ6ULQFO.js";import{createHash as St}from"crypto";import{readFileSync as M}from"fs";import je from"path";import{gzipSync as ge,gunzipSync as vt}from"zlib";function Ce(e){let t=(e||"").toLowerCase().split(";")[0].trim();return t?!(t.startsWith("image/")||t.startsWith("video/")||t.startsWith("audio/")||t==="font/woff2"||t==="application/font-woff2"||t==="application/zip"||t==="application/gzip"):!0}import{brotliCompressSync as ut,constants as ct}from"node:zlib";var dt=9;function Le(e){return ut(e,{params:{[ct.BROTLI_PARAM_QUALITY]:dt}})}function ce(e,t){let r=new AbortController,s=setTimeout(()=>r.abort(new Error(`${t} timed out after ${e/1e3}s`)),e);return{signal:r.signal,cancel:()=>clearTimeout(s)}}async function pt(e){let t=ce(12e4,`PUT ${e.url}`),r;try{r=await fetch(e.url,{method:"PUT",headers:{"content-type":e.contentType},body:e.bytes,signal:t.signal})}finally{t.cancel()}if(!r.ok){let s=await r.text().catch(()=>"");throw new Error(`PUT ${e.url} failed ${r.status}: ${s.slice(0,200)}`)}}async function mt(e,t=8,r){let s=0,o=0,i=e.length;await Promise.all(Array.from({length:Math.min(t,i)},async()=>{for(;s<i;){let l=e[s++];await pt(l),o++,r?.(o,i)}}))}function ft(e,t,r,s){let o=[];o.push({url:e.bundle.putUrl,contentType:e.bundle.contentType,bytes:t});for(let i of e.files){let l=r.get(i.urlhash);l&&o.push({url:i.putUrl,contentType:i.contentType,bytes:l})}e.events&&s?.eventsBytes&&o.push({url:e.events.putUrl,contentType:e.events.contentType,bytes:s.eventsBytes}),e.timeline&&s?.timelineBytes&&o.push({url:e.timeline.putUrl,contentType:e.timeline.contentType,bytes:s.timelineBytes}),e.flowVideo&&s?.videoBytes&&o.push({url:e.flowVideo.putUrl,contentType:e.flowVideo.contentType,bytes:s.videoBytes}),e.storage&&s?.storageBytes&&o.push({url:e.storage.putUrl,contentType:e.storage.contentType,bytes:s.storageBytes}),e.failureBundle&&s?.failureBundleBytes&&o.push({url:e.failureBundle.putUrl,contentType:e.failureBundle.contentType,bytes:s.failureBundleBytes});for(let i of e.snapshots??[]){let l=s?.snapshotBytes?.get(i.id);l&&o.push({url:i.putUrl,contentType:i.contentType,bytes:l})}return o}function gt(e){return e.replace(/\/+$/,"")}var W=class extends Error{constructor(r,s,o,i=""){super(r);this.status=s;this.phase=o;this.responseText=i;this.name="PresignedUploadError"}};async function ze(e){let t=gt(e.originBase),r={"content-type":"application/json"};e.authHeader&&(r.authorization=e.authHeader),e.adminBypassToken&&(r["x-contrast-admin-upload-bypass"]=e.adminBypassToken);let s=ce(3e4,"init"),o;try{o=await fetch(`${t}/api/preview/upload/init`,{method:"POST",headers:r,body:JSON.stringify(e.initBody),signal:s.signal})}finally{s.cancel()}if(!o.ok){let T=await o.text().catch(()=>"");throw new W(`init failed: ${o.status} ${T.slice(0,200)}`,o.status,"init",T)}let i=await o.json(),l=ft(i,e.bundleBytes,e.filesByHash,e.extras);await mt(l,e.concurrency??8,e.onPutProgress);let m=ce(3e4,"finalize"),c;try{c=await fetch(`${t}/api/preview/upload/finalize`,{method:"POST",headers:r,body:JSON.stringify({token:i.token}),signal:m.signal})}finally{m.cancel()}if(!c.ok){let T=await c.text().catch(()=>"");throw new W(`finalize failed: ${c.status} ${T.slice(0,200)}`,c.status,"finalize",T)}let h=await c.json();return{init:i,finalize:h}}function ht(e){return e!==null&&typeof e=="object"?e:null}function De(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function de(e){let t=ht(e);return t?t.schemaVersion===1&&De(t.t)!==void 0&&De(t.seq)!==void 0&&typeof t.context=="string"&&typeof t.kind=="string"&&"data"in t:!1}function yt(e,t){let r=[];for(let s of e.split(`
1
+ /*! sootsim v0.1.242 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as K,b as V,c as Ne}from"./chunk-G7225Q7A.js";import{c as Pe}from"./chunk-NO7HYN72.js";import{d as _e}from"./chunk-2RSNHAI3.js";import{d as Oe}from"./chunk-JVDDW7YD.js";import{g as $e,i as Fe,k as B}from"./chunk-EHEVO2JB.js";import{a as Ue,b as E}from"./chunk-NAST572Z.js";import{a as Ae}from"./chunk-H7UA4DWW.js";import{createHash as St}from"crypto";import{readFileSync as M}from"fs";import je from"path";import{gzipSync as ge,gunzipSync as vt}from"zlib";function Ce(e){let t=(e||"").toLowerCase().split(";")[0].trim();return t?!(t.startsWith("image/")||t.startsWith("video/")||t.startsWith("audio/")||t==="font/woff2"||t==="application/font-woff2"||t==="application/zip"||t==="application/gzip"):!0}import{brotliCompressSync as ut,constants as ct}from"node:zlib";var dt=9;function Le(e){return ut(e,{params:{[ct.BROTLI_PARAM_QUALITY]:dt}})}function ce(e,t){let r=new AbortController,s=setTimeout(()=>r.abort(new Error(`${t} timed out after ${e/1e3}s`)),e);return{signal:r.signal,cancel:()=>clearTimeout(s)}}async function pt(e){let t=ce(12e4,`PUT ${e.url}`),r;try{r=await fetch(e.url,{method:"PUT",headers:{"content-type":e.contentType},body:e.bytes,signal:t.signal})}finally{t.cancel()}if(!r.ok){let s=await r.text().catch(()=>"");throw new Error(`PUT ${e.url} failed ${r.status}: ${s.slice(0,200)}`)}}async function mt(e,t=8,r){let s=0,o=0,i=e.length;await Promise.all(Array.from({length:Math.min(t,i)},async()=>{for(;s<i;){let l=e[s++];await pt(l),o++,r?.(o,i)}}))}function ft(e,t,r,s){let o=[];o.push({url:e.bundle.putUrl,contentType:e.bundle.contentType,bytes:t});for(let i of e.files){let l=r.get(i.urlhash);l&&o.push({url:i.putUrl,contentType:i.contentType,bytes:l})}e.events&&s?.eventsBytes&&o.push({url:e.events.putUrl,contentType:e.events.contentType,bytes:s.eventsBytes}),e.timeline&&s?.timelineBytes&&o.push({url:e.timeline.putUrl,contentType:e.timeline.contentType,bytes:s.timelineBytes}),e.flowVideo&&s?.videoBytes&&o.push({url:e.flowVideo.putUrl,contentType:e.flowVideo.contentType,bytes:s.videoBytes}),e.storage&&s?.storageBytes&&o.push({url:e.storage.putUrl,contentType:e.storage.contentType,bytes:s.storageBytes}),e.failureBundle&&s?.failureBundleBytes&&o.push({url:e.failureBundle.putUrl,contentType:e.failureBundle.contentType,bytes:s.failureBundleBytes});for(let i of e.snapshots??[]){let l=s?.snapshotBytes?.get(i.id);l&&o.push({url:i.putUrl,contentType:i.contentType,bytes:l})}return o}function gt(e){return e.replace(/\/+$/,"")}var W=class extends Error{constructor(r,s,o,i=""){super(r);this.status=s;this.phase=o;this.responseText=i;this.name="PresignedUploadError"}};async function ze(e){let t=gt(e.originBase),r={"content-type":"application/json"};e.authHeader&&(r.authorization=e.authHeader),e.adminBypassToken&&(r["x-contrast-admin-upload-bypass"]=e.adminBypassToken);let s=ce(3e4,"init"),o;try{o=await fetch(`${t}/api/preview/upload/init`,{method:"POST",headers:r,body:JSON.stringify(e.initBody),signal:s.signal})}finally{s.cancel()}if(!o.ok){let T=await o.text().catch(()=>"");throw new W(`init failed: ${o.status} ${T.slice(0,200)}`,o.status,"init",T)}let i=await o.json(),l=ft(i,e.bundleBytes,e.filesByHash,e.extras);await mt(l,e.concurrency??8,e.onPutProgress);let m=ce(3e4,"finalize"),c;try{c=await fetch(`${t}/api/preview/upload/finalize`,{method:"POST",headers:r,body:JSON.stringify({token:i.token}),signal:m.signal})}finally{m.cancel()}if(!c.ok){let T=await c.text().catch(()=>"");throw new W(`finalize failed: ${c.status} ${T.slice(0,200)}`,c.status,"finalize",T)}let h=await c.json();return{init:i,finalize:h}}function ht(e){return e!==null&&typeof e=="object"?e:null}function De(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function de(e){let t=ht(e);return t?t.schemaVersion===1&&De(t.t)!==void 0&&De(t.seq)!==void 0&&typeof t.context=="string"&&typeof t.kind=="string"&&"data"in t:!1}function yt(e,t){let r=[];for(let s of e.split(`
3
3
  `)){let o=s.trim();if(o)try{let i=JSON.parse(o);t(i)&&r.push(i)}catch{}}return r}function He(e){return yt(e,de)}import{execSync as bt}from"child_process";function me(e){try{return bt(e,{stdio:["ignore","pipe","ignore"],timeout:3e3,encoding:"utf8"}).trim()||null}catch{return null}}function pe(e){let t=e?.trim();return!t||!/^\d+$/.test(t)?null:Number(t)}function wt(){let e=me("git remote get-url origin");if(!e)return null;let t=e.match(/github\.com[/:]([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/i);return t?{owner:t[1],repo:t[2]}:null}function fe(){let e=process.env.GITHUB_ACTIONS==="true",t=process.env.CONTRAST_BRANCH?.trim()||null,r=process.env.CONTRAST_SHA?.trim()||null,s=process.env.CONTRAST_PR_TITLE?.trim()||null,o=(process.env.CONTRAST_REPO||process.env.GITHUB_REPOSITORY||"").trim(),[i,l]=o.includes("/")?o.split("/",2):[null,null];if(e){let h=process.env.GITHUB_REF?.match(/^refs\/pull\/(\d+)\//)?.[1];return{owner:i,repo:l,branch:t||process.env.GITHUB_HEAD_REF?.trim()||process.env.GITHUB_REF_NAME?.trim()||null,commitSha:r||process.env.GITHUB_SHA?.trim()||null,githubUsername:process.env.GITHUB_ACTOR?.trim()||null,pullRequestNumber:pe(process.env.CONTRAST_PR_NUMBER)??pe(h),pullRequestTitle:s,githubRunId:process.env.GITHUB_RUN_ID?.trim()||null,source:"ci"}}let m=t??me("git rev-parse --abbrev-ref HEAD"),c=i?null:wt();return{owner:i??c?.owner??null,repo:l??c?.repo??null,branch:m==="HEAD"?null:m,commitSha:r??me("git rev-parse HEAD"),githubUsername:null,pullRequestNumber:pe(process.env.CONTRAST_PR_NUMBER),pullRequestTitle:s,githubRunId:null,source:"cli"}}function Yt(e){if(e.length===0)return{stepCount:null,failedStepIndex:null};let t=e.find(r=>r.status==="failure");return{stepCount:e.length,failedStepIndex:t?t.stepIndex:null}}function Qt(e){return e.auth?e.uploadedShare?!0:e.auth.kind==="github"||process.env.GITHUB_ACTIONS==="true":!1}async function Xt(e){let t=e.auth??K();if(!t)return null;let r=fe(),s=e.owner??(t.kind==="github"?t.owner:null)??r.owner,o=e.repo??(t.kind==="github"?t.repo:null)??r.repo;try{let i=await fetch(`${e.origin.replace(/\/$/,"")}/api/sootsim/test-runs`,{method:"POST",headers:{"content-type":"application/json",authorization:V(t)},body:JSON.stringify({kind:e.kind,source:r.source,name:e.name??void 0,prompt:e.prompt??void 0,summary:e.summary??void 0,status:e.status,failureMessage:e.failureMessage??void 0,previewShareId:e.previewShareId??void 0,owner:s??void 0,repo:o??void 0,branch:r.branch??void 0,commitSha:r.commitSha??void 0,githubUsername:r.githubUsername??void 0,pullRequestNumber:r.pullRequestNumber??void 0,githubRunId:r.githubRunId??void 0,stepCount:e.stepCount??void 0,failedStepIndex:e.failedStepIndex??void 0,durationMs:e.durationMs??void 0,flowYamlSizeBytes:e.flowYamlSizeBytes??void 0})});if(!i.ok){let m=await i.text().catch(()=>"");return console.warn(` warn: run registration failed: /api/sootsim/test-runs ${i.status}${m?`: ${m.slice(0,200)}`:""}`),null}let l=await i.json();return l.run?.id?{id:l.run.id,previewUrl:l.run.previewUrl??null,traceUrl:l.run.traceUrl??null}:(console.warn(" warn: run registration returned no id"),null)}catch(i){return console.warn(` warn: run registration failed: ${i instanceof Error?i.message:String(i)}`),null}}function Rt(e){if(!e)return null;try{let t=JSON.parse(e);return typeof t.message=="string"&&t.message?t.message:null}catch{return null}}function xt(e){let t=JSON.parse(M(e,"utf8"));if(!Array.isArray(t))throw new Error("snapshot manifest must be an array");let r=new Set;return t.map((s,o)=>{if(s===null||typeof s!="object")throw new Error(`snapshot manifest entry ${o} must be an object`);let i=Reflect.get(s,"id"),l=Reflect.get(s,"label"),m=Reflect.get(s,"path"),c=Reflect.get(s,"t");if(typeof i!="string"||!i||r.has(i))throw new Error(`snapshot manifest entry ${o} has an invalid or duplicate id`);if(typeof m!="string"||!m)throw new Error(`snapshot manifest entry ${o} has no PNG path`);if(typeof c!="number"||!Number.isFinite(c)||c<0)throw new Error(`snapshot manifest entry ${o} has an invalid capture time`);r.add(i);let h=M(m);return{meta:{id:i,label:typeof l=="string"&&l?l:i,kind:"interaction",t:Math.round(c),contentType:"image/png",sizeBytes:h.byteLength},bytes:h}})}var Ve=process.env.SOOTSIM_UPLOAD_ORIGIN||"https://contrast.dev",We=process.env.SOOTSIM_PREVIEW_ORIGIN||"https://sootsim.com",ye="http://localhost:3000",kt=2e3;async function Et(e){if(e)return e;if(process.env.SOOTSIM_UPLOAD_ORIGIN)return process.env.SOOTSIM_UPLOAD_ORIGIN;try{let t=await fetch(`${ye}/api/preview/upload/init`,{method:"OPTIONS",signal:AbortSignal.timeout(kt)});if(t.ok||t.status===204||t.status===405)return ye}catch{}return Ve}function N(e){return e.replace(/\/$/,"")}function Bt(e){try{let r=new URL(e).hostname.replace(/^\[|\]$/g,"").toLowerCase();return r==="localhost"||r.endsWith(".localhost")||r==="0.0.0.0"||r==="::1"||/^127(?:\.\d{1,3}){3}$/.test(r)}catch{return!1}}function It(e){try{let t=new URL(e).hostname.toLowerCase();return t==="contrast.dev"||t.endsWith(".contrast.dev")}catch{return!1}}function At(e,t){return t?N(t):process.env.SOOTSIM_PREVIEW_ORIGIN?N(process.env.SOOTSIM_PREVIEW_ORIGIN):Bt(e)?N(e):It(e)?N(We):N(e)}function Ut(){console.log(`
4
4
  sootsim record upload \u2014 publish the current recorded bundle as a /preview/<id> link
5
5
 
@@ -1,3 +1,3 @@
1
- /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{o as d}from"./chunk-WYT6JDAV.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)+`
1
+ /*! sootsim v0.1.242 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{o as d}from"./chunk-RFYPY6RQ.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
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,5 +1,5 @@
1
- /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{e as p}from"./chunk-7ZTOWAQF.js";import{a as c,b as l}from"./chunk-DEO54ZY3.js";import{a}from"./chunk-EJ6ULQFO.js";async function g(e,t){if(t)return t.replace(/\/$/,"");if(e.kind==="session"&&e.origin)return e.origin.replace(/\/$/,"");let i=a();return i?.origin?i.origin.replace(/\/$/,""):(await p()).replace(/\/$/,"")}async function m(e,t={}){let i=c();if(i||(process.stderr.write(`
1
+ /*! sootsim v0.1.242 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{e as p}from"./chunk-GAMPO6T4.js";import{a as c,b as l}from"./chunk-G7225Q7A.js";import{a}from"./chunk-H7UA4DWW.js";async function g(e,t){if(t)return t.replace(/\/$/,"");if(e.kind==="session"&&e.origin)return e.origin.replace(/\/$/,"");let i=a();return i?.origin?i.origin.replace(/\/$/,""):(await p()).replace(/\/$/,"")}async function m(e,t={}){let i=c();if(i||(process.stderr.write(`
3
3
  sootsim ${e} needs auth before it can check recording access.
4
4
 
5
5
  pick one:
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.242 | (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,5 +1,5 @@
1
- /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as k}from"./chunk-TFXCEOCW.js";import{a as x}from"./chunk-M2MJXMTO.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(`
1
+ /*! sootsim v0.1.242 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as k}from"./chunk-L62LIMAO.js";import{a as x}from"./chunk-N2CW4ASW.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
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
 
@@ -20,4 +20,4 @@ examples:
20
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
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-REPVX6LA.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};
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-QEC64Z6W.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.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.242 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import{execFileSync as d,spawn as g}from"child_process";import{existsSync as m}from"fs";import{homedir as h}from"os";import{join as C}from"path";var f=["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Chromium.app/Contents/MacOS/Chromium","~/Applications/Chromium.app/Contents/MacOS/Chromium","/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge","~/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge","/Applications/Brave Browser.app/Contents/MacOS/Brave Browser","~/Applications/Brave Browser.app/Contents/MacOS/Brave Browser","/Applications/Arc.app/Contents/MacOS/Arc","~/Applications/Arc.app/Contents/MacOS/Arc"],O=["/usr/bin/google-chrome","/usr/bin/chromium","/usr/bin/chromium-browser","/usr/bin/microsoft-edge","/usr/bin/brave-browser","/snap/bin/chromium"],w=["C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe","C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe","C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe","C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe","C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe","C:\\Program Files (x86)\\BraveSoftware\\Brave-Browser\\Application\\brave.exe"],U=["google-chrome","chromium","chromium-browser","microsoft-edge","brave-browser"],M=["chrome","msedge","brave"];function A(r){return r.startsWith("~/")?C(h(),r.slice(2)):r}function a(r){for(let n of r){let o=A(n);if(m(o))return o}return null}function x(r,n){try{let e=d(n==="win32"?"where":"which",[r],{encoding:"utf8",timeout:1500,stdio:["ignore","pipe","ignore"]}).trim();return e?e.split(/\r?\n/)[0]:null}catch{return null}}function c(r=process.platform){let n=process.env.CHROME_PATH||process.env.CHROMIUM_PATH;if(n&&m(n))return n;let o=a(r==="darwin"?f:r==="win32"?w:O);if(o)return o;let e=r==="win32"?M:U;for(let t of e){let i=x(t,r);if(i)return i}return null}function p(r,n={}){if(!r)throw new Error("openUrl requires a url");let o=n.platform??process.platform;return n.newWindow?s(r,{...n,platform:o,newWindow:!0}):o==="darwin"?{command:"open",args:n.background===!1?[r]:["-g",r],via:"system"}:o==="win32"?{command:"cmd",args:["/c","start","",r],via:"system"}:{command:"xdg-open",args:[r],via:"system"}}function s(r,n={}){if(!r)throw new Error("openUrl requires a url");let o=n.platform??process.platform,e="chromiumBinary"in n?n.chromiumBinary:c(o);if(!e)throw new Error("browser launch requires Chrome, Chromium, Edge, Brave, or Arc");let t=[];return n.newWindow!==!1&&t.push("--new-window"),t.push(r),{command:e,args:t,via:"chromium",target:e}}async function l(r,n,o){return new Promise((e,t)=>{let i=g(r,n,{detached:o,stdio:"ignore"});i.once("error",t),i.once("spawn",()=>{o&&i.unref(),e(i.pid)})})}async function u(r,n={}){let o=p(r,n),e=await l(o.command,o.args,n.detached??!0);return{...o,pid:e,attachUrl:r}}async function b(r,n={}){let o=s(r,n),e=await l(o.command,o.args,n.detached??!0);return{...o,pid:e,attachUrl:r}}async function v(r,n={}){await u(r,n)}export{c as a,u as b,b as c,v as d};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.242 | (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,3 +1,3 @@
1
- /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.242 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
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
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,5 +1,5 @@
1
- /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as m,b as E}from"./chunk-TFXCEOCW.js";import{a as w,b as T,c as A}from"./chunk-BWR3AJZ3.js";import{a as _,d as I}from"./chunk-NJYDI627.js";import{G as O,o as k,q as f}from"./chunk-WYT6JDAV.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(k(),"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){O();let r=P(e),t=`${g()}.tmp`;return h.writeFileSync(t,`${JSON.stringify(r,null,2)}
1
+ /*! sootsim v0.1.242 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as m,b as E}from"./chunk-L62LIMAO.js";import{a as w,b as T,c as A}from"./chunk-JVDDW7YD.js";import{a as _,d as I}from"./chunk-S4L7A6CA.js";import{G as O,o as k,q as f}from"./chunk-RFYPY6RQ.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(k(),"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){O();let r=P(e),t=`${g()}.tmp`;return h.writeFileSync(t,`${JSON.stringify(r,null,2)}
3
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;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.242 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import{execFileSync as h,spawn as g}from"child_process";import{existsSync as s,readdirSync as k}from"fs";import{dirname as m,join as l,resolve as a}from"path";import{fileURLToPath as v}from"url";var c;function p(){if(c!==void 0)return c;try{c=m(v(import.meta.resolve("sootsim-engine/package.json")))}catch{c=null}return c}var I="dev.sootsim.simulator";function x(){let n=p();if(!n)return null;let e=l(n,"dist-electron/main.cjs");if(!s(e))return null;let i=D(n);return i?{path:i,platform:process.platform,kind:"dev-electron",engineDir:n}:null}function b(){let n=p();return n?s(l(n,"src-electron/main.ts")):!1}function D(n){let e=n;for(let i=0;i<6;i++){let t=l(e,"node_modules/.bin/electron");if(s(t))return t;let r=m(e);if(r===e)break;e=r}return null}function C(){let n=p(),i=["/Applications/sootsim.app",a(process.env.HOME||"","Applications/sootsim.app"),...n?[a(n,"app/sootsim.app")]:[]].find(t=>s(t));if(i)return{path:i,platform:"darwin",kind:"mac-app"};try{let t=h("mdfind",[`kMDItemCFBundleIdentifier == "${I}"`],{encoding:"utf8",timeout:3e3}).trim();if(t)return{path:t.split(`
3
3
  `)[0],platform:"darwin",kind:"mac-app"}}catch{}return null}function f(n){if(!s(n))return null;let e=k(n).filter(i=>i.startsWith("sootsim")&&i.endsWith(".AppImage")).sort().reverse()[0];return e?l(n,e):null}function w(){let n=p(),i=[a(process.env.HOME||"","Applications/sootsim.AppImage"),a(process.env.HOME||"",".local/bin/sootsim.AppImage"),"/opt/sootsim/sootsim.AppImage","/opt/sootsim/sootsim",...n?[a(n,"app/sootsim.AppImage"),a(n,"release/linux-unpacked/sootsim")]:[]].find(r=>s(r));if(i)return{path:i,platform:"linux",kind:i.endsWith(".AppImage")?"linux-appimage":"linux-binary"};let t=n?f(a(n,"app"))||f(a(n,"release")):null;return t?{path:t,platform:"linux",kind:"linux-appimage"}:null}function A(){let n=x();if(n)return n;if(b()){let e=p(),i=l(e,"dist-electron/main.cjs");return s(i)?console.error(` no node_modules/.bin/electron found near ${e}. run \`bun install\`.`):console.error(` dist-electron/main.cjs missing in ${e}.
4
4
  run: bun run --cwd packages/sootsim-engine build:electron-main