sootsim 0.1.218 → 0.1.220

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 (150) hide show
  1. package/README.md +5 -3
  2. package/detox/index.ts +6 -7
  3. package/dist-cli/bin.js +4 -4
  4. package/dist-cli/chunks/{agent-TQJDQNML.js → agent-LCKEPMVH.js} +2 -2
  5. package/dist-cli/chunks/{agent-wrapper-OAOFXHX2.js → agent-wrapper-ND5JHQSI.js} +2 -2
  6. package/dist-cli/chunks/{app-fonts-4VPAP3RZ.js → app-fonts-N2W5BQXE.js} +2 -2
  7. package/dist-cli/chunks/{assert-DKNRGH4M.js → assert-O3QO4ZFV.js} +2 -2
  8. package/dist-cli/chunks/{auth-ZYOAQEI2.js → auth-7VXPQOZP.js} +2 -2
  9. package/dist-cli/chunks/beta-ZIOECOJB.js +2 -0
  10. package/dist-cli/chunks/{camera-BJCRYG27.js → camera-OROQGFMH.js} +2 -2
  11. package/dist-cli/chunks/chunk-3HJXCSYI.js +119 -0
  12. package/dist-cli/chunks/{chunk-SXS5SPIZ.js → chunk-3ZWOQPLC.js} +1 -1
  13. package/dist-cli/chunks/{chunk-Q7U5TPQN.js → chunk-4JSQTD75.js} +1 -1
  14. package/dist-cli/chunks/{chunk-RZMI7IKL.js → chunk-64GMEXIP.js} +2 -2
  15. package/dist-cli/chunks/{chunk-JDCABF7Y.js → chunk-6HBN4KIM.js} +2 -2
  16. package/dist-cli/chunks/{chunk-B4KB5TBV.js → chunk-7TOHX4IF.js} +1 -1
  17. package/dist-cli/chunks/chunk-AMUOGO6F.js +1 -0
  18. package/dist-cli/chunks/{chunk-YMFQOXT4.js → chunk-BI3I5X3U.js} +1 -1
  19. package/dist-cli/chunks/{chunk-XB6FCXX3.js → chunk-BXNMPK4X.js} +2 -2
  20. package/dist-cli/chunks/{chunk-OTCJCVFR.js → chunk-EFLOJBBN.js} +3 -3
  21. package/dist-cli/chunks/{chunk-T2NAWDMZ.js → chunk-F5XBOFGK.js} +2 -2
  22. package/dist-cli/chunks/{chunk-FEMAFOUH.js → chunk-FRQOTDD6.js} +2 -2
  23. package/dist-cli/chunks/{chunk-F5H6XTMN.js → chunk-GBALEYV4.js} +1 -1
  24. package/dist-cli/chunks/{chunk-Q7K5GJR4.js → chunk-GWQWCFMR.js} +2 -2
  25. package/dist-cli/chunks/{chunk-IKZ4Z6ND.js → chunk-H7EGEWCF.js} +1 -1
  26. package/dist-cli/chunks/{chunk-AY5S4CWZ.js → chunk-HAXE5SZL.js} +1 -1
  27. package/dist-cli/chunks/{chunk-FAUOGIHF.js → chunk-J3QE2UZI.js} +1 -1
  28. package/dist-cli/chunks/{chunk-NN7XOWXY.js → chunk-JMXBQ4RD.js} +3 -3
  29. package/dist-cli/chunks/{chunk-CMGPYPUE.js → chunk-KJVNP5B5.js} +2 -2
  30. package/dist-cli/chunks/{chunk-24FHNNST.js → chunk-KZUGDZ3Q.js} +6 -6
  31. package/dist-cli/chunks/{chunk-MW3G72KG.js → chunk-NPK2TDEV.js} +91 -14
  32. package/dist-cli/chunks/{chunk-73WAFGRP.js → chunk-NRHZHQOH.js} +2 -2
  33. package/dist-cli/chunks/{chunk-6WWKUDWP.js → chunk-OBWXIGPP.js} +2 -2
  34. package/dist-cli/chunks/{chunk-AK4CONMS.js → chunk-OCEYXYKG.js} +2 -2
  35. package/dist-cli/chunks/{chunk-ZJI2JP7F.js → chunk-PJ76I3KZ.js} +1 -1
  36. package/dist-cli/chunks/{chunk-V64N734Y.js → chunk-PWLK4BGI.js} +2 -2
  37. package/dist-cli/chunks/{chunk-TGXLBFTC.js → chunk-RIB5CQ34.js} +1 -1
  38. package/dist-cli/chunks/{chunk-CRPOEKYT.js → chunk-RTZNRPD4.js} +3 -3
  39. package/dist-cli/chunks/{chunk-7NP5BWIH.js → chunk-RWJM23VH.js} +1 -1
  40. package/dist-cli/chunks/{chunk-EEUNNW2P.js → chunk-S6XSCI45.js} +1 -1
  41. package/dist-cli/chunks/{chunk-QWJG2WVA.js → chunk-TEFCJZH5.js} +1 -1
  42. package/dist-cli/chunks/{chunk-LIR2VPPJ.js → chunk-TH7ODXC5.js} +9 -9
  43. package/dist-cli/chunks/{chunk-4DLUGQXQ.js → chunk-U3OSSCTT.js} +3 -3
  44. package/dist-cli/chunks/{chunk-AHTGZMT4.js → chunk-UHEKB33X.js} +2 -2
  45. package/dist-cli/chunks/{chunk-DVZVP32W.js → chunk-UODAA57Q.js} +2 -2
  46. package/dist-cli/chunks/{chunk-Z4QP44SI.js → chunk-UXLMOEFU.js} +2 -2
  47. package/dist-cli/chunks/{chunk-TNEHHCMZ.js → chunk-VCLV5GYE.js} +2 -2
  48. package/dist-cli/chunks/chunk-VQ4VGI36.js +1 -0
  49. package/dist-cli/chunks/{chunk-2HJU3NAO.js → chunk-XHPOQKUA.js} +1 -1
  50. package/dist-cli/chunks/{chunk-VOZZ62OJ.js → chunk-XKOYH7ES.js} +1 -1
  51. package/dist-cli/chunks/{chunk-L5HYRG4P.js → chunk-YRHLQY6J.js} +2 -2
  52. package/dist-cli/chunks/{chunk-CJHPCUUV.js → chunk-ZU6ECPCC.js} +1 -1
  53. package/dist-cli/chunks/{chunk-KLBOD2JL.js → chunk-ZW5IAKXC.js} +2 -2
  54. package/dist-cli/chunks/cli-version-MY4N7YDM.js +2 -0
  55. package/dist-cli/chunks/{compat-IETPHSZ3.js → compat-NRYECFCC.js} +3 -3
  56. package/dist-cli/chunks/{config-BOOBJ25W.js → config-4KKKEHH2.js} +2 -2
  57. package/dist-cli/chunks/{control-U52Q4YES.js → control-ZH7X66II.js} +2 -2
  58. package/dist-cli/chunks/daemon-6QQWVRFD.js +2 -0
  59. package/dist-cli/chunks/{debug-X4AW6CXJ.js → debug-Z66GNDYA.js} +3 -3
  60. package/dist-cli/chunks/{desktop-HHREMDE2.js → desktop-DO2BQKM4.js} +3 -3
  61. package/dist-cli/chunks/{detox-AXETJDTZ.js → detox-66YMXFQ5.js} +2 -2
  62. package/dist-cli/chunks/{device-B7PBIMER.js → device-KPQXKN5R.js} +2 -2
  63. package/dist-cli/chunks/{diagnose-7YEDF42J.js → diagnose-OMCHVX2X.js} +2 -2
  64. package/dist-cli/chunks/drivers-T2AZY5KL.js +2 -0
  65. package/dist-cli/chunks/{film-XQMAOELQ.js → film-PV6DPBRX.js} +3 -3
  66. package/dist-cli/chunks/flow-BCJH7MUK.js +2 -0
  67. package/dist-cli/chunks/help-KRIPS56R.js +2 -0
  68. package/dist-cli/chunks/{home-paths-I3NOFS6P.js → home-paths-LGQZZOPD.js} +2 -2
  69. package/dist-cli/chunks/inspect-3XG2QTVU.js +2 -0
  70. package/dist-cli/chunks/install-desktop-SH73YM3O.js +2 -0
  71. package/dist-cli/chunks/{login-O4ZPWWEU.js → login-QQH2UU2S.js} +4 -4
  72. package/dist-cli/chunks/{logout-REEPRXWZ.js → logout-KMGAWWAS.js} +2 -2
  73. package/dist-cli/chunks/{maestro-OCUCS5DY.js → maestro-IKINYBBR.js} +3 -3
  74. package/dist-cli/chunks/{maestro-generate-VHUHJFHR.js → maestro-generate-NWVVHDBL.js} +3 -3
  75. package/dist-cli/chunks/{mode-T24V4RZ4.js → mode-T576L6ZK.js} +2 -2
  76. package/dist-cli/chunks/optional-demo-registry-2F3PLJXV.js +2 -0
  77. package/dist-cli/chunks/{perf-ZUER6TVQ.js → perf-TRPZNIQH.js} +2 -2
  78. package/dist-cli/chunks/{record-XDKPMUBK.js → record-O5HUQAK4.js} +3 -3
  79. package/dist-cli/chunks/runtime-RLXYAF2A.js +2 -0
  80. package/dist-cli/chunks/{screenshot-command-MMUGPJ4I.js → screenshot-command-5FI7RD5L.js} +3 -3
  81. package/dist-cli/chunks/screenshots-capture-RLEAPJ45.js +41 -0
  82. package/dist-cli/chunks/{serve-BCATAS4S.js → serve-4SIWGY4S.js} +3 -3
  83. package/dist-cli/chunks/{setup-LXPQLQ6I.js → setup-LDHVGPS2.js} +9 -9
  84. package/dist-cli/chunks/{skills-OOPLWNI2.js → skills-CCIOVHHV.js} +2 -2
  85. package/dist-cli/chunks/{storage-E7MGHPIG.js → storage-HV7PNB7R.js} +2 -2
  86. package/dist-cli/chunks/store-DF56QJJG.js +2 -0
  87. package/dist-cli/chunks/telemetry-OFJVUJ34.js +2 -0
  88. package/dist-cli/chunks/{timeline-4AN6A5CV.js → timeline-NZY4TIYS.js} +2 -2
  89. package/dist-cli/chunks/upgrade-3SRHX5MN.js +4 -0
  90. package/dist-cli/chunks/upload-ZKKGG3CU.js +2 -0
  91. package/dist-cli/chunks/{version-LI2X5HLA.js → version-EWVUUOUL.js} +2 -2
  92. package/dist-cli/chunks/web-OT6OKUVX.js +2 -0
  93. package/dist-cli/chunks/{what-happened-2NTKQ4AT.js → what-happened-K2NQG7LZ.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 +53 -7
  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 +14 -2
  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 +1 -1
  123. package/dist-lib/sdk.mjs +1 -1
  124. package/dist-lib/skills.cjs +178 -22
  125. package/dist-lib/vite.cjs +1 -1
  126. package/package.json +1 -1
  127. package/src/host/bridge-host.ts +21 -1
  128. package/src/skills/builtin/a11y-review.ts +4 -1
  129. package/src/skills/builtin/perf-profile.ts +4 -1
  130. package/src/skills/builtin/screenshot-all.ts +4 -1
  131. package/src/skills/builtin/visual-diff.ts +4 -1
  132. package/dist-cli/chunks/beta-HL46FNX3.js +0 -2
  133. package/dist-cli/chunks/chunk-BZRIJJIK.js +0 -1
  134. package/dist-cli/chunks/chunk-FP3DRAKI.js +0 -119
  135. package/dist-cli/chunks/chunk-OUZAVYUG.js +0 -1
  136. package/dist-cli/chunks/cli-version-5FG6LIHX.js +0 -2
  137. package/dist-cli/chunks/daemon-EJDBU2UY.js +0 -2
  138. package/dist-cli/chunks/drivers-325S27FC.js +0 -2
  139. package/dist-cli/chunks/flow-V2SWGBAR.js +0 -2
  140. package/dist-cli/chunks/help-F4VH4LXF.js +0 -2
  141. package/dist-cli/chunks/inspect-NY5VGZNC.js +0 -2
  142. package/dist-cli/chunks/install-desktop-X7SXH7IN.js +0 -2
  143. package/dist-cli/chunks/optional-demo-registry-HPLGNZCO.js +0 -2
  144. package/dist-cli/chunks/runtime-4A24ALGX.js +0 -2
  145. package/dist-cli/chunks/screenshots-capture-OM6BE572.js +0 -41
  146. package/dist-cli/chunks/store-3DU64I7C.js +0 -2
  147. package/dist-cli/chunks/telemetry-AKRLP3AR.js +0 -2
  148. package/dist-cli/chunks/upgrade-FRBWFDPI.js +0 -4
  149. package/dist-cli/chunks/upload-XGUWNMYV.js +0 -2
  150. package/dist-cli/chunks/web-UDCVLGPU.js +0 -2
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as l}from"./chunk-TNEHHCMZ.js";import{A as o,B as s}from"./chunk-YMFQOXT4.js";function c(){let e=process.env.DO_NOT_TRACK;return e==="1"||e==="true"||!o()}function p(){if(c())return null;let e=process.env.VITE_POSTHOG_API_KEY||"";if(!e)return null;let t=process.env.SOOT_POSTHOG_HOST||process.env.VITE_POSTHOG_HOST||"https://us.i.posthog.com";return{apiKey:e,host:t.replace(/\/+$/,"")}}function u(){try{return s()}catch{return"anonymous-cli"}}function d(e){return e?e.userId?e.userId:e.installationId!=null?`install:${e.installationId}`:e.repoId?`repo:${e.repoId}`:e.shareId?`share:${e.shareId}`:u():u()}function f(e){let t=e.identity??{},n={$lib:"soot-cli",source:t.source??"cli",...e.properties};return t.userId&&(n.userId=t.userId),t.repoId&&(n.repoId=t.repoId),t.installationId!=null&&(n.installationId=String(t.installationId)),t.shareId&&(n.shareId=t.shareId),t.plan&&(n.plan=t.plan),{event:e.event,distinct_id:d(t),properties:n,timestamp:new Date().toISOString()}}var r=[],a=!1;async function i(){if(r.length===0)return;let e=p();if(!e){r.length=0;return}let t=r.splice(0,r.length).map(f);try{await fetch(`${e.host}/batch/`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({api_key:e.apiKey,batch:t}),signal:AbortSignal.timeout(2e3)})}catch{}}function I(){a||(a=!0,process.on("beforeExit",()=>void i()),process.on("exit",()=>void i()))}function y(e){if(c())return;I();let t=null;try{t=l()?.user?.id??null}catch{t=null}r.push({...e,identity:{source:"cli",userId:t,...e.identity}})}async function m(){await i()}export{y as a,m as b};
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as l}from"./chunk-VCLV5GYE.js";import{A as o,B as s}from"./chunk-BI3I5X3U.js";function c(){let e=process.env.DO_NOT_TRACK;return e==="1"||e==="true"||!o()}function p(){if(c())return null;let e=process.env.VITE_POSTHOG_API_KEY||"";if(!e)return null;let t=process.env.SOOT_POSTHOG_HOST||process.env.VITE_POSTHOG_HOST||"https://us.i.posthog.com";return{apiKey:e,host:t.replace(/\/+$/,"")}}function u(){try{return s()}catch{return"anonymous-cli"}}function d(e){return e?e.userId?e.userId:e.installationId!=null?`install:${e.installationId}`:e.repoId?`repo:${e.repoId}`:e.shareId?`share:${e.shareId}`:u():u()}function f(e){let t=e.identity??{},n={$lib:"soot-cli",source:t.source??"cli",...e.properties};return t.userId&&(n.userId=t.userId),t.repoId&&(n.repoId=t.repoId),t.installationId!=null&&(n.installationId=String(t.installationId)),t.shareId&&(n.shareId=t.shareId),t.plan&&(n.plan=t.plan),{event:e.event,distinct_id:d(t),properties:n,timestamp:new Date().toISOString()}}var r=[],a=!1;async function i(){if(r.length===0)return;let e=p();if(!e){r.length=0;return}let t=r.splice(0,r.length).map(f);try{await fetch(`${e.host}/batch/`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({api_key:e.apiKey,batch:t}),signal:AbortSignal.timeout(2e3)})}catch{}}function I(){a||(a=!0,process.on("beforeExit",()=>void i()),process.on("exit",()=>void i()))}function y(e){if(c())return;I();let t=null;try{t=l()?.user?.id??null}catch{t=null}r.push({...e,identity:{source:"cli",userId:t,...e.identity}})}async function m(){await i()}export{y as a,m as b};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  function o(e,r,n,i){return{width:3,ringToggle:{top:e[0],height:e[1]},volumeUp:{top:r[0],height:r[1]},volumeDown:{top:n[0],height:n[1]},lock:{top:i[0],height:i[1]}}}var b={width:2.5,lock:{top:188.7,height:68.1},ringToggle:{top:113.2,height:36},volumeUp:{top:188.2,height:68.1},volumeDown:{top:269,height:68.1}},d={width:3,lock:{top:238,height:78},ringToggle:{top:-1e3,height:0},volumeUp:{top:336,height:62},volumeDown:{top:408,height:62}},g={width:3,lock:{top:248,height:72},ringToggle:{top:-1e3,height:0},volumeUp:{top:144,height:62},volumeDown:{top:216,height:62}},a=48;function t(e){return{...e,platform:"ios",navigationBarHeight:0,navigationBarMode:e.homeIndicatorHeight>0?"gesture":"none",displayCutout:{top:e.dynamicIsland?e.statusBarHeight:0,bottom:0,left:0,right:0},cameraCutout:null,osVersion:e.iosVersion,androidApiLevel:null,systemName:"iOS",manufacturer:"Apple",brand:"Apple",modelName:e.name}}var p={"canvas-workspace":t({name:"Canvas Workspace",width:1440,height:900,scale:1,statusBarHeight:0,homeIndicatorHeight:0,cornerRadius:0,bezelWidth:16,dynamicIsland:null,safeAreaInsets:{top:0,bottom:0,left:0,right:0},iosVersion:"26.4",physicalPPI:110,hardwareButtons:o([185.8,41.7],[258.2,67.6],[344,67.6],[281.5,106.9]),experimental:!0}),"iphone-se":t({name:"iPhone SE",width:375,height:667,scale:2,statusBarHeight:20,homeIndicatorHeight:0,cornerRadius:0,bezelWidth:28.7,dynamicIsland:null,safeAreaInsets:{top:20,bottom:0,left:0,right:0},iosVersion:"15.8",physicalPPI:326,hardwareButtons:b}),"iphone-14":t({name:"iPhone 14",width:390,height:844,scale:3,statusBarHeight:47,homeIndicatorHeight:34,cornerRadius:46.2,bezelWidth:20,dynamicIsland:null,safeAreaInsets:{top:47,bottom:34,left:0,right:0},iosVersion:"17.6",physicalPPI:460,hardwareButtons:o([141.7,29.7],[205.9,69.6],[289.5,69.6],[228.9,114.5])}),"iphone-15":t({name:"iPhone 15",width:393,height:852,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,bezelWidth:18.7,dynamicIsland:{width:126,height:37.3,top:14.1},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"17.6",physicalPPI:460,hardwareButtons:o([171.7,32],[235.8,65.3],[320.5,65.3],[280.6,105.2])}),"iphone-15-plus":t({name:"iPhone 15 Plus",width:430,height:932,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,bezelWidth:17.8,dynamicIsland:{width:126,height:37.3,top:11.4},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"17.6",physicalPPI:460,hardwareButtons:o([172.1,33],[236.1,66.6],[321.2,66.6],[281,106.8])}),"iphone-15-pro":t({name:"iPhone 15 Pro",width:393,height:852,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,bezelWidth:15.8,dynamicIsland:{width:126,height:38,top:13.4},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"18.2",physicalPPI:460,hardwareButtons:o([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-15-pro-max":t({name:"iPhone 15 Pro Max",width:430,height:932,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,bezelWidth:15.8,dynamicIsland:{width:126,height:38,top:13.3},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"18.2",physicalPPI:460,hardwareButtons:o([173.3,32.2],[253.4,61.7],[343.3,61.7],[268.5,98.5])}),"iphone-16":t({name:"iPhone 16",width:393,height:852,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,bezelWidth:15.8,dynamicIsland:{width:126,height:37.3,top:11},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-16-plus":t({name:"iPhone 16 Plus",width:430,height:932,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,bezelWidth:15.8,dynamicIsland:{width:126,height:37.3,top:11.4},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([173.3,32.2],[253.4,61.7],[343.3,61.7],[268.5,98.5])}),"iphone-16-pro":t({name:"iPhone 16 Pro",width:402,height:874,scale:3,statusBarHeight:62,homeIndicatorHeight:34,cornerRadius:61,bezelWidth:15.8,dynamicIsland:{width:126,height:38,top:13.5},safeAreaInsets:{top:62,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-16-pro-max":t({name:"iPhone 16 Pro Max",width:440,height:956,scale:3,statusBarHeight:62,homeIndicatorHeight:34,cornerRadius:61.3,bezelWidth:15.9,dynamicIsland:{width:126,height:38,top:14},safeAreaInsets:{top:62,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([178.8,32.2],[266.8,61.8],[352.7,61.8],[292.2,98.3])}),"iphone-17":t({name:"iPhone 17",width:402,height:874,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:61,bezelWidth:15.8,dynamicIsland:{width:126,height:37.3,top:14},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-17-air":t({name:"iPhone Air",width:420,height:912,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:64.6,bezelWidth:15.9,dynamicIsland:{width:126,height:38,top:20},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([178.8,32.2],[266.8,61.8],[352.7,61.8],[292.2,98.3])}),"iphone-17-pro":t({name:"iPhone 17 Pro",width:402,height:874,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:61,bezelWidth:15.8,dynamicIsland:{width:126,height:38,top:14},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-17-pro-max":t({name:"iPhone 17 Pro Max",width:440,height:956,scale:3,statusBarHeight:62,homeIndicatorHeight:34,cornerRadius:61.3,bezelWidth:15.9,dynamicIsland:{width:126,height:38,top:14},safeAreaInsets:{top:62,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([178.8,32.2],[266.8,61.8],[352.7,61.8],[292.2,98.3])}),"pixel-8":{platform:"android",name:"Pixel 8",width:412,height:915,scale:2.625,statusBarHeight:40,homeIndicatorHeight:0,navigationBarHeight:a,navigationBarMode:"gesture",displayCutout:{top:40,bottom:0,left:0,right:0},cornerRadius:39,bezelWidth:13,dynamicIsland:null,cameraCutout:{diameter:24},safeAreaInsets:{top:40,bottom:a,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 8",physicalPPI:428,hardwareButtons:d},"pixel-8-three-button":{platform:"android",name:"Pixel 8 (3-button)",width:412,height:915,scale:2.625,statusBarHeight:40,homeIndicatorHeight:0,navigationBarHeight:48,navigationBarMode:"three-button",displayCutout:{top:40,bottom:0,left:0,right:0},cornerRadius:39,bezelWidth:13,dynamicIsland:null,cameraCutout:{diameter:24},safeAreaInsets:{top:40,bottom:48,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 8",physicalPPI:428,hardwareButtons:d},"pixel-9-pro-xl":{platform:"android",name:"Pixel 9 Pro XL",width:448,height:997,scale:3,statusBarHeight:40,homeIndicatorHeight:0,navigationBarHeight:a,navigationBarMode:"gesture",displayCutout:{top:40,bottom:0,left:0,right:0},cornerRadius:41,bezelWidth:12,dynamicIsland:null,cameraCutout:{diameter:24},safeAreaInsets:{top:40,bottom:a,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 9 Pro XL",physicalPPI:486,hardwareButtons:d},"galaxy-s24":{platform:"android",name:"Galaxy S24",width:360,height:780,scale:3,statusBarHeight:36,homeIndicatorHeight:0,navigationBarHeight:a,navigationBarMode:"gesture",displayCutout:{top:36,bottom:0,left:0,right:0},cornerRadius:36,bezelWidth:8,dynamicIsland:null,cameraCutout:{diameter:18},safeAreaInsets:{top:36,bottom:a,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Samsung",brand:"samsung",modelName:"SM-S921B",physicalPPI:416,hardwareButtons:g},"galaxy-s24-ultra":{platform:"android",name:"Galaxy S24 Ultra",width:384,height:824,scale:3.75,statusBarHeight:36,homeIndicatorHeight:0,navigationBarHeight:a,navigationBarMode:"gesture",displayCutout:{top:36,bottom:0,left:0,right:0},cornerRadius:24,bezelWidth:9,dynamicIsland:null,cameraCutout:{diameter:18},safeAreaInsets:{top:36,bottom:a,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Samsung",brand:"samsung",modelName:"SM-S928B",physicalPPI:505,hardwareButtons:g}},m="iphone-17-pro";function P(e){return p[e]}function h(){return Object.keys(p)}function v(){return h().filter(e=>!p[e].experimental)}var l={"iphone-6-9":{name:"iphone-6-9",label:'iPhone 6.7"',width:1284,height:2778,store:"apple"},"iphone-6-1":{name:"iphone-6-1",label:'iPhone 6.5"',width:1242,height:2688,store:"apple"},"android-phone":{name:"android-phone",label:"Google Play phone",width:1080,height:1920,store:"google"},"android-tablet-7":{name:"android-tablet-7",label:'Google Play 7" tablet',width:1200,height:1920,store:"google"},"android-tablet-10":{name:"android-tablet-10",label:'Google Play 10" tablet',width:1600,height:2560,store:"google"}},c={dark:{type:"gradient",direction:180,glow:"#4caeff",stops:[{offset:0,color:"#111827"},{offset:40,color:"#101725"},{offset:100,color:"#06080d"}]},cyan:{type:"gradient",direction:180,glow:"#25c3ec",stops:[{offset:0,color:"#1b465c"},{offset:32,color:"#122336"},{offset:100,color:"#05070b"}]},gold:{type:"gradient",direction:180,glow:"#ffc25a",stops:[{offset:0,color:"#3b2f1a"},{offset:34,color:"#18140d"},{offset:100,color:"#050505"}]},red:{type:"gradient",direction:180,glow:"#ff6178",stops:[{offset:0,color:"#3e1018"},{offset:35,color:"#17080c"},{offset:100,color:"#050405"}]}},B={color:"#25c3ec",blur:120,spread:52,opacity:.34},I="iphone-17-pro";var y=[{name:"white",value:"#ffffff"},{name:"gray-light",value:"#d1d5db"},{name:"gray",value:"#6b7280"},{name:"gray-dark",value:"#3b4350"},{name:"slate",value:"#2a3644"},{name:"black",value:"#000000"},{name:"cyan",value:"#25c3ec"},{name:"blue",value:"#3f7cff"},{name:"teal",value:"#1fc7b4"},{name:"green",value:"#42c95d"},{name:"lime",value:"#92d21b"},{name:"gold",value:"#f5c518"},{name:"orange",value:"#ff912e"},{name:"coral",value:"#ff6f5b"},{name:"red",value:"#ff4f6f"},{name:"berry",value:"#d054ff"},{name:"magenta",value:"#ff4eb8"}],f=Object.fromEntries(y.map(e=>[e.name,e.value]));function T(e){return f[e]??f.gray}function R(e){return Object.prototype.hasOwnProperty.call(l,e)?l[e]:null}function S(e){return{type:e.type,color:e.color,direction:e.direction,glow:e.glow,stops:e.stops?.map(r=>({...r}))}}function A(e){return Object.prototype.hasOwnProperty.call(c,e)?S(c[e]):null}var u={deviceModel:{type:"enum",default:m,description:"device model to simulate",cliFlag:"device",cliFlagShort:"d",options:h(),group:"device"},orientation:{type:"enum",default:"portrait",description:"screen orientation",cliFlag:"orientation",options:["portrait","landscape"],group:"device"},colorScheme:{type:"enum",default:"auto",description:"color scheme (auto follows system preference)",cliFlag:"theme",cliFlagShort:"t",options:["light","dark","auto"],group:"appearance"},reduceMotion:{type:"boolean",default:!1,description:"reduce motion",group:"appearance"},boldText:{type:"boolean",default:!1,description:"bold text",group:"appearance"},fontSize:{type:"number",default:1,description:"font size multiplier (1.0 = default)",group:"appearance",validate:e=>e>=.5&&e<=2},networkCondition:{type:"enum",default:"wifi",description:"simulated network condition",cliFlag:"network",options:["wifi","lte","fast-3g","slow-3g","offline"],group:"network"},language:{type:"string",default:"en",description:"language code (ISO 639-1)",cliFlag:"language",group:"locale"},region:{type:"string",default:"US",description:"region code (ISO 3166-1)",cliFlag:"region",group:"locale"},showTouches:{type:"boolean",default:!1,description:"show touch indicators",group:"simulator"},showFrame:{type:"boolean",default:!0,description:"show device frame",cliFlag:"frame",group:"simulator"},showTopBar:{type:"boolean",default:!0,description:"show simulator top bar",group:"simulator"},screenshotMode:{type:"boolean",default:!1,description:"show screenshot composition mode in the browser shell",group:"simulator"},threeMode:{type:"boolean",default:!1,description:"show the experimental 3d device stage in the browser shell",group:"simulator"},threeRecordingEditor:{type:"boolean",default:!1,description:"dock the 3d recording editor in the 3d stage (toggled from its rail)",group:"simulator"},screenshotCanvas:{type:"enum",default:"iphone-6-9",description:"target app-store canvas preset for screenshot mode",options:Object.keys(l),group:"simulator"},screenshotBackground:{type:"enum",default:"dark",description:"background preset rendered inside the screenshot canvas",options:Object.keys(c),group:"simulator"},screenshotText:{type:"enum",default:"bold-top",description:"text layout preset for the screenshot canvas",options:["bold-top","editorial-left","minimal-bottom","none"],group:"simulator"},screenshotPose:{type:"enum",default:"straight",description:"device pose preset inside the screenshot canvas",options:["straight","tilted-left","tilted-right","cut-bottom","cut-top"],group:"simulator"},screenshotDynamicSize:{type:"boolean",default:!1,description:"let the screenshot canvas rect fit available space (off = pin to exact preset pixels)",group:"simulator"},showStatusBar:{type:"boolean",default:!0,description:"show status bar",group:"simulator"},showHomeIndicator:{type:"boolean",default:!0,description:"show home indicator",group:"simulator"},alwaysShowLiveWebViews:{type:"boolean",default:!1,description:"always render WebViews as live browser views",group:"simulator"},a11yMode:{type:"enum",default:"delayed",description:"accessibility tree sync mode (off, delayed=100ms, active=30ms)",options:["off","delayed","active"],group:"simulator"},a11yDepth:{type:"enum",default:"deep",description:"accessibility tree structure depth (shallow or deep)",options:["shallow","deep"],group:"simulator"},inspectMode:{type:"boolean",default:!1,description:"inspect mode",group:"simulator"},errorReporting:{type:"boolean",default:!1,description:"send anonymous crash reports",group:"privacy"},agentProvider:{type:"enum",default:"codex",description:"ai agent used by the sootsim agent prompt bar",options:["codex","claude"],group:"agent"},onboardingComplete:{type:"boolean",default:!1,description:"first-run onboarding completed",group:"beta"},betaConsentVersion:{type:"number",default:0,description:"last accepted beta telemetry policy version",group:"beta"},detailedTelemetry:{type:"boolean",default:!0,description:"send detailed usage telemetry (sessions, perf samples)",group:"beta"}};function w(){if(typeof window>"u")return{};let e={};try{let r=new URLSearchParams(window.location.search),n=r.get("device");n&&u.deviceModel.options?.includes(n)&&(e.deviceModel=n);let i=r.get("colorScheme")??r.get("theme");i&&u.colorScheme.options?.includes(i)&&(e.colorScheme=i);let s=r.get("alwaysShowLiveWebViews");s==="1"||s==="true"?e.alwaysShowLiveWebViews=!0:(s==="0"||s==="false")&&(e.alwaysShowLiveWebViews=!1)}catch{}return e}function H(){let e={};for(let[r,n]of Object.entries(u))e[r]=n.default;return Object.assign(e,w()),e}export{B as a,I as b,T as c,R as d,S as e,A as f,p as g,P as h,v as i,u as j,w as k,H as l};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import{createHash as D}from"node:crypto";import y from"node:fs";import{createRequire as I}from"node:module";import h from"node:path";var w=/(^|\/)expo-splash-screen$/,R=/(^|\/)react-native-bootsplash$/;function U(n,e){let r=e.replace(/\/+$/,""),o=n.replace(/^\.\//,"").replace(/^\/+/,"");if(o)return`${r}/assets/${o}`}function d(n,e,r){return r?r(n):U(n,e)}function b(n){if(n==="cover")return"cover";if(n==="contain"||n==="native")return"contain"}function p(n){return typeof n=="string"&&n.length>0?n:void 0}function k(n){return typeof n=="number"&&Number.isFinite(n)?n:void 0}function v(n,e,r){if(!n||typeof n!="object")return null;let o=n,s={source:"expo-splash-screen",backgroundColor:p(o.backgroundColor)??"#ffffff"},l=p(o.image);l&&(s.imageUrl=d(l,e,r));let t=k(o.imageWidth);t!=null&&(s.imageWidthPx=t);let c=b(o.resizeMode);c&&(s.resizeMode=c);let i=o.dark;if(i&&typeof i=="object"){let g=i,u=p(g.backgroundColor),f=p(g.image);(u||f)&&(s.dark={},u&&(s.dark.backgroundColor=u),f&&(s.dark.imageUrl=d(f,e,r)))}return s}function j(n,e,r,o){let a=n[e],s=a&&typeof a=="object"?a.splash:void 0,l=n.splash,t=s&&typeof s=="object"?s:l;if(!t||typeof t!="object")return null;let i={source:"expo-legacy",backgroundColor:p(t.backgroundColor)??"#ffffff",imageWidthPx:k(t.imageWidth)??200,resizeMode:b(t.resizeMode)??"contain"},g=p(t.image);g&&(i.imageUrl=d(g,r,o));let u=t.dark;if(u&&typeof u=="object"){let f=u,S=p(f.backgroundColor),m=p(f.image);(S||m)&&(i.dark={},S&&(i.dark.backgroundColor=S),m&&(i.dark.imageUrl=d(m,r,o)))}return i}function _(n,e,r){if(!n||typeof n!="object")return null;let o=n,a=p(o.logo);if(!a)return null;let s={source:"react-native-bootsplash",backgroundColor:p(o.background)??"#fff",imageUrl:d(a,e,r),imageWidthPx:k(o.logoWidth)??100,resizeMode:"contain"},l=p(o.darkBackground),t=p(o.darkLogo);return(l||t)&&(s.dark={},l&&(s.dark.backgroundColor=l),t&&(s.dark.imageUrl=d(t,e,r))),s}function C(n,e,r,o={}){if(!n||typeof n!="object")return null;let a=n,s=a.plugins,l=null,t=null;if(Array.isArray(s))for(let i of s){let g=Array.isArray(i)?i[0]:i;if(typeof g!="string")continue;let u=Array.isArray(i)?i[1]??{}:{};!l&&w.test(g)?l=v(u,r,o.resolveAssetUrl):!t&&R.test(g)&&(t=_(u,r,o.resolveAssetUrl))}if(l)return l;let c=j(a,e,r,o.resolveAssetUrl);return c||t}var x=I(import.meta.url);function E(n){try{let e=new URL(n),r=e.hostname.replace(/^\[|\]$/g,"").toLowerCase();if(r==="localhost"||r.endsWith(".localhost")||r==="0.0.0.0"||r==="::1"||/^127(?:\.\d{1,3}){3}$/.test(r))return e.origin}catch{}return null}var L=["app.config.js","app.config.ts","app.config.cjs","app.config.mjs","app.json"];function P(n){for(let e of L)try{if(y.statSync(h.join(n,e)).isFile())return!0}catch{}return!1}var F=new Set(["node_modules","artifacts","dist","build","out","coverage","tmp","public","ios","android","macos","windows","__fixtures__","__tests__","examples","example"]);function A(n,e){P(n)&&e.push(n);let r;try{r=y.readdirSync(n,{withFileTypes:!0})}catch{return}for(let o of r)o.isDirectory()&&(o.name.startsWith(".")||F.has(o.name)||A(h.join(n,o.name),e))}function M(n){try{return y.statSync(h.join(n,"package.json")).isFile()}catch{return!1}}function H(n){let e=E(n.bundleUrl);if(!e)return null;let r=n.repoDir||process.env.SOOT_REPO_DIR,o=r?h.resolve(r):process.cwd();if(!r&&!M(o))return null;let a=[];if(r)A(o,a),a.includes(o)||a.push(o);else{if(!P(o))return null;a.push(o)}if(a.length===0)return null;let s=(n.platform||process.env.SOOT_PLATFORM||"ios").toLowerCase(),l=null;try{let c=x.resolve("@expo/config",{paths:[...a,o]}),i=x(c);typeof i.getConfig=="function"&&(l=i.getConfig)}catch{}if(!l)return null;let t;for(let c of a)try{let i=l(c,{skipSDKVersionRequirement:!0});if(i?.exp&&typeof i.exp=="object"){t=i.exp;break}}catch{}return!t||typeof t!="object"?null:C(t,s==="android"?"android":"ios",e)}function J(n){return encodeURIComponent(JSON.stringify(n))}function z(n){if(!n)return null;try{let e=JSON.parse(decodeURIComponent(n));if(!e||typeof e!="object")return null;let r=e;return r.source!=="expo-splash-screen"&&r.source!=="expo-legacy"&&r.source!=="react-native-bootsplash"||typeof r.backgroundColor!="string"?null:e}catch{return null}}function W(n){let e=new Set;return n.imageUrl&&e.add(n.imageUrl),n.dark?.imageUrl&&e.add(n.dark.imageUrl),[...e]}function O(n){let e=(n.split("?")[0].split(".").pop()||"").toLowerCase();return e==="png"?"image/png":e==="jpg"||e==="jpeg"?"image/jpeg":e==="webp"?"image/webp":e==="gif"?"image/gif":e==="svg"?"image/svg+xml":"application/octet-stream"}async function K(n,e){let r=z(n);if(!r)return[];let o=[],a=new Set;for(let s of W(r)){let l=D("sha256").update(s).digest("hex");if(!a.has(l)){a.add(l);try{let t=await fetch(s);if(!t.ok){e?.onError?.(s,new Error(`${t.status} ${t.statusText}`));continue}let c=new Uint8Array(await t.arrayBuffer());o.push({url:s,urlhash:l,contentType:O(s),bytes:c}),e?.onStaged?.({url:s,byteLength:c.byteLength})}catch(t){e?.onError?.(s,t)}}}return o}export{H as a,J as b,K as c};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var t="./demo-app-registry.ts",o=null;async function n(){if(o)return o;try{let r=await import(t);o=Array.isArray(r.APPS)?r.APPS:[]}catch{o=[]}return o}function e(){return o??[]}export{n as a,e as b};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as ce}from"./chunk-V64N734Y.js";import{b as Et,c as Rt,k as Pt}from"./chunk-L5HYRG4P.js";import{a as oe,b as P,c as D,d as Ie,e as ie,f as V,g as de,h as ge,i as Mt,j as Ft,k as Te,l as Ot}from"./chunk-CMGPYPUE.js";import{A as wt,B as xt,E as $t,G as St,I as ue,J as vt,P as We,a as ve,b as nt,c as rt,d as it,e as at,f as lt,g as ct,h as ut,i as dt,j as pt,k as Be,l as Ce,q as je,r as mt,s as ft,t as fe,u as gt,v as ke,w as Le,x as yt,y as ht,z as bt}from"./chunk-7NP5BWIH.js";import{e as kt,g as _t,i as It,j as Tt,k as Nt,l as _e}from"./chunk-AHTGZMT4.js";import{a as tt}from"./chunk-QWJG2WVA.js";import{a as Ae,c as De,d as Q}from"./chunk-FP3DRAKI.js";import{c as ot}from"./chunk-Q7U5TPQN.js";import{b as st}from"./chunk-CJHPCUUV.js";function qe(e){return`(async () => {
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as ce}from"./chunk-PWLK4BGI.js";import{b as Et,c as Rt,k as Pt}from"./chunk-YRHLQY6J.js";import{a as oe,b as P,c as D,d as Ie,e as ie,f as V,g as de,h as ge,i as Mt,j as Ft,k as Te,l as Ot}from"./chunk-KJVNP5B5.js";import{A as wt,B as xt,E as $t,G as St,I as ue,J as vt,P as We,a as ve,b as nt,c as rt,d as it,e as at,f as lt,g as ct,h as ut,i as dt,j as pt,k as Be,l as Ce,q as je,r as mt,s as ft,t as fe,u as gt,v as ke,w as Le,x as yt,y as ht,z as bt}from"./chunk-RWJM23VH.js";import{e as kt,g as _t,i as It,j as Tt,k as Nt,l as _e}from"./chunk-UHEKB33X.js";import{a as tt}from"./chunk-TEFCJZH5.js";import{a as Ae,c as De,d as Q}from"./chunk-3HJXCSYI.js";import{c as ot}from"./chunk-4JSQTD75.js";import{b as st}from"./chunk-ZU6ECPCC.js";function qe(e){return`(async () => {
3
3
  const bridge = globalThis.SootSim && globalThis.SootSim.bridges && globalThis.SootSim.bridges.hotRemount
4
4
  if (!bridge || typeof bridge.reloadExternalApp !== 'function') return false
5
5
  await bridge.reloadExternalApp({ resetStorage: ${e?"true":"false"} })
@@ -547,7 +547,7 @@ import{a as ce}from"./chunk-V64N734Y.js";import{b as Et,c as Rt,k as Pt}from"./c
547
547
  `);console.log(`${t??""}
548
548
 
549
549
  ${n}
550
- `),process.exit(0)}let F=c.wsPort,N=c.simId,L=c.simIdSource,M=c.commandTimeoutMs;if(y==="get"&&p==="diagnosis"){let x=a.indexOf("diagnosis"),t=x>=0?[...a.slice(0,x),...a.slice(x+1)]:a,{runDiagnose:n}=await import("./diagnose-7YEDF42J.js"),r=await n(["recent",...t],o);process.exitCode=r;return}if(y==="do"&&p==="scan"){let{runCamera:x}=await import("./camera-BJCRYG27.js");await x(a,{port:o.port});return}if(p==="list"&&a.some(x=>x==="--drivers"||x==="-D")){let{buildDriverListRows:x}=await import("./drivers-325S27FC.js"),t=x();console.log(` available drivers (${t.length}):
550
+ `),process.exit(0)}let F=c.wsPort,N=c.simId,L=c.simIdSource,M=c.commandTimeoutMs;if(y==="get"&&p==="diagnosis"){let x=a.indexOf("diagnosis"),t=x>=0?[...a.slice(0,x),...a.slice(x+1)]:a,{runDiagnose:n}=await import("./diagnose-OMCHVX2X.js"),r=await n(["recent",...t],o);process.exitCode=r;return}if(y==="do"&&p==="scan"){let{runCamera:x}=await import("./camera-OROQGFMH.js");await x(a,{port:o.port});return}if(p==="list"&&a.some(x=>x==="--drivers"||x==="-D")){let{buildDriverListRows:x}=await import("./drivers-T2AZY5KL.js"),t=x();console.log(` available drivers (${t.length}):
551
551
  `);let n=Math.max(...t.map(i=>i.id.length),6),r=Math.max(...t.map(i=>i.kind.length),4);for(let i of t){let d=i.available?"\u2713":"\u2717",m=i.id.padEnd(n),f=i.kind.padEnd(r);console.log(` ${d} ${m} ${f} ${i.description}`),i.available&&i.detail?console.log(` ${i.detail}`):!i.available&&i.reason&&console.log(` unavailable: ${i.reason}`)}return}let u=It(c),j=N||"default",A=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","storage-clear","list","wait","sleep"]),R=200;function K(x){let t=x.replace(/\s+/g," ").trim();if(!t)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(t)){let r=/<title[^>]*>([^<]+)<\/title>/i.exec(x)?.[1]?.trim(),i=/<body[^>]*>([\s\S]*?)<\//i.exec(x)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),d=r||i||"html error page";return`<html ${x.length}B> "${d}" (body elided \u2014 add --json for the full payload)`}return t.length<=R?t:`${t.slice(0,R)}\u2026 (+${t.length-R} more bytes)`}function U(x){let t=x.displayUrl||x.url;return x.status!=null?`${x.method} ${t} -> ${x.status}${x.statusText?` ${x.statusText}`:""}`:x.error?`${x.method} ${t} -> ${x.error}`:`${x.method} ${t}`}async function v(x){let t=me()?400:200;try{let{settled:n,elapsed:r}=await se({bridge:x,maxMs:t,pollMs:32,stablePolls:2});n||process.stderr.write(` \u26A0 auto-wait timed out after ${r??t}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
552
552
  `)}catch{}}function O(x,t){if(t.result?.reason==="offscreen"){let{x:n,y:r,screen:i}=t.result;console.error(` tap failed: ${x} resolved to (${Math.round(n)},${Math.round(r)}), outside the ${i?.width}x${i?.height} screen`),console.error(" the node exists but is scrolled out of view \u2014 scroll it on-screen first (sootsim do scroll / swipe), then tap.");return}console.error(` tap failed: ${x} stayed visible but did not receive a hittable press after ${t.attempts} attempt${t.attempts===1?"":"s"}`),t.result&&console.error(` last result: ${JSON.stringify(t.result)}`)}async function J(){try{return await u.send({type:"evaluate",code:`(() => ({
553
553
  console: ${ke},
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{H as I,m as B,n as E,o as y,t as v,v as A}from"./chunk-7NP5BWIH.js";import{h,l as N,m as P}from"./chunk-AHTGZMT4.js";var q={timeoutMs:1800,settleMs:48,startWindowMs:64};function w(e){return new Promise(t=>setTimeout(t,e))}function U(e){return e.includes("--json")}function Y(e){process.stdout.write(`${JSON.stringify(e??null,null,2)}
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{H as I,m as B,n as E,o as y,t as v,v as A}from"./chunk-RWJM23VH.js";import{h,l as N,m as P}from"./chunk-UHEKB33X.js";var q={timeoutMs:1800,settleMs:48,startWindowMs:64};function w(e){return new Promise(t=>setTimeout(t,e))}function U(e){return e.includes("--json")}function Y(e){process.stdout.write(`${JSON.stringify(e??null,null,2)}
3
3
  `)}function V(e){process.stderr.write(`${e}
4
4
  `)}function b(e,t=Date.now()){let r=new Date(e),n=`${S(r.getHours())}:${S(r.getMinutes())}:${S(r.getSeconds())}`,s=t-e;if(s<0)return n;let o=Math.round(s/1e3);return o<60?`${n} +${o}s`:o<3600?`${n} +${Math.round(o/60)}m`:o<86400?`${n} +${Math.round(o/3600)}h`:`${n} +${Math.round(o/86400)}d`}function S(e){return e<10?`0${e}`:String(e)}async function D(e,t,...r){return N(e,`__sootsimTest.${t}`,...r)}async function k(e,t,...r){return P(e,`SootSim.bridges.mainShell.${t}`,...r)}async function z(e,t={}){try{let r=await D(e,"waitForScreenTransitions",q);if(!t.verbose||!r?.started)return;if(r.timedOut){console.log(` screen transition still active after ${r.waitedMs}ms; continuing`);return}r.waitedMs>0&&console.log(` waited ${r.waitedMs}ms for screen transition settle`)}catch{}}async function K(e,t,r,...n){let s=Date.now()+Math.max(0,r);for(;;)try{return await k(e,t,...n)}catch(o){if(!I(o)||Date.now()>=s)throw o;await w(50)}}async function Q(e,t,r,n={}){let s=n.attempts??30,o=n.intervalMs??500,l=n.minNodeCount??10;for(let a=0;a<s;a++){let u=h(e,{commandTimeoutMs:t,simId:r,simIdSource:n.simIdSource});try{let c=await u.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount()) || 0)()"});if(typeof c=="number"&&c>l)return{bridge:u,count:c}}catch{}u.close(),await w(o)}return null}async function X(e,t,r,n={}){let s=n.timeoutMs??8e3,o=n.intervalMs??250,l=Date.now()+s;for(;Date.now()<l;){let a=h(e,{commandTimeoutMs:t,simId:r,simIdSource:n.simIdSource});try{return await a.send({type:"evaluate",code:"1"}),a}catch{a.close()}await w(o)}return null}async function Z(e,t={}){let r=t.timeoutMs??1e4,n=t.errorGraceMs??3e3,s=t.pollIntervalMs??200,o=Date.now(),l=o+r,a=-1,u=o,c=null,d=!1,m={ready:!1,source:"timeout",elapsedMs:0,nodes:0,targets:0,flag:void 0,loadingText:"",externalReady:null,externalStatus:"",externalError:"",errors:0};for(;Date.now()<l;){try{let i=await e.send({type:"evaluate",code:B}),g=Date.now()-o,f=Number(i?.nodes)||0,$=Number(i?.targets)||0,x=Number(i?.errors)||0,C=i?.flag===!0,p=i?.externalReady,T=typeof i?.loadingText=="string"?i.loadingText.trim():"",W=typeof i?.externalStatus=="string"?i.externalStatus.trim():"",M=typeof i?.externalError=="string"?i.externalError.trim():"",R=typeof i?.externalError=="string"&&M.length>0;if(c=p,d=R,f!==a&&(a=f,u=g),m={ready:!1,source:"timeout",elapsedMs:g,nodes:f,targets:$,flag:i?.flag,loadingText:T,externalReady:typeof p=="boolean"?p:null,externalStatus:W,externalError:M,errors:x},C&&p!==!1&&!R&&!T&&y({nodes:f,targets:$})&&g-u>=E)return{...m,ready:!0,source:"flag"};if(g>=n&&x>0&&!C)return{...m,ready:!1,source:"error-bail"}}catch{}await w(s)}return c!==!1&&!d&&!m.loadingText&&y(m)?{...m,ready:!0,source:"nodes-fallback"}:{...m,ready:!1,source:"timeout",elapsedMs:Date.now()-o}}function O(e){let t=e.displayUrl||e.url;return e.status!=null?`${e.method} ${t} -> ${e.status}${e.statusText?` ${e.statusText}`:""}`:e.error?`${e.method} ${t} -> ${e.error}`:`${e.method} ${t}`}async function _(e,t,...r){return e.send({type:"call",path:`__sootsimTest.${t}`,args:r})}async function F(e,t={}){let r=await e.send({type:"evaluate",code:A});if(!r||typeof r!="object")return;let n=Math.max(0,Number(r.errors)||0),s=Math.max(0,Number(r.warnings)||0);if(n===0&&s===0)return;let o=[];if(n>0&&o.push(`${n} console error${n===1?"":"s"}`),s>0&&o.push(`${s} console warning${s===1?"":"s"}`),console.log(`
5
5
  console: ${o.join(", ")}`),t.errorsCommand&&console.log(` inspect: ${t.errorsCommand}`),s>0&&t.warningsCommand&&console.log(` inspect: ${t.warningsCommand}`),!t.includeTail||n===0)return;let l=await v(e,5);if(!(!Array.isArray(l)||l.length===0)){console.log(`
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as R,b as U}from"./chunk-Q7K5GJR4.js";import{c as F}from"./chunk-RZMI7IKL.js";import{g as N,j as E,r as _,s as v,t as B}from"./chunk-YMFQOXT4.js";import{a as O}from"./chunk-SXS5SPIZ.js";import{execFileSync as W,spawnSync as s}from"child_process";import{existsSync as a,mkdirSync as x,readFileSync as nt,realpathSync as ot,rmSync as $,writeFileSync as H}from"fs";import{homedir as P}from"os";import{basename as st,dirname as T,resolve as f,sep as Y}from"path";import{execFileSync as X}from"child_process";import{chmodSync as Q,mkdirSync as I,rmSync as z,writeFileSync as A}from"fs";import{dirname as L}from"path";var J="dev.sootsim.daemon",j="SootSim Daemon",M="0.1.36";function V(t,e,r){let n=v(),o=B(),c=L(L(o)),l=L(o),u=`${c}/Resources`;z(n,{recursive:!0,force:!0}),I(_(),{recursive:!0}),I(l,{recursive:!0}),I(u,{recursive:!0}),A(`${c}/Info.plist`,Z()),A(`${c}/PkgInfo`,"APPL????"),A(o,tt(t,e,r)),Q(o,493);try{X("codesign",["--force","--sign","-","--deep",n],{stdio:"pipe"})}catch(i){let p=i instanceof Error?i.message:String(i);console.warn(` warning: ad-hoc codesign of ${n} failed: ${p}
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as R,b as U}from"./chunk-GWQWCFMR.js";import{c as F}from"./chunk-64GMEXIP.js";import{g as N,j as E,r as _,s as v,t as B}from"./chunk-BI3I5X3U.js";import{a as O}from"./chunk-3ZWOQPLC.js";import{execFileSync as W,spawnSync as s}from"child_process";import{existsSync as a,mkdirSync as x,readFileSync as nt,realpathSync as ot,rmSync as $,writeFileSync as H}from"fs";import{homedir as P}from"os";import{basename as st,dirname as T,resolve as f,sep as Y}from"path";import{execFileSync as X}from"child_process";import{chmodSync as Q,mkdirSync as I,rmSync as z,writeFileSync as A}from"fs";import{dirname as L}from"path";var J="dev.sootsim.daemon",j="SootSim Daemon",M="0.1.36";function V(t,e,r){let n=v(),o=B(),c=L(L(o)),l=L(o),u=`${c}/Resources`;z(n,{recursive:!0,force:!0}),I(_(),{recursive:!0}),I(l,{recursive:!0}),I(u,{recursive:!0}),A(`${c}/Info.plist`,Z()),A(`${c}/PkgInfo`,"APPL????"),A(o,tt(t,e,r)),Q(o,493);try{X("codesign",["--force","--sign","-","--deep",n],{stdio:"pipe"})}catch(i){let p=i instanceof Error?i.message:String(i);console.warn(` warning: ad-hoc codesign of ${n} failed: ${p}
3
3
  the daemon will still run, but Login Items may show a generic name.`)}return{bundlePath:n,launcherPath:o}}function Z(){return`<?xml version="1.0" encoding="UTF-8"?>
4
4
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
5
5
  <plist version="1.0">
@@ -28,7 +28,7 @@ import{a as R,b as U}from"./chunk-Q7K5GJR4.js";import{c as F}from"./chunk-RZMI7I
28
28
  # stdout: ${r.stdout}
29
29
  # stderr: ${r.stderr}
30
30
  exec ${o}
31
- `}function et(t){return`'${t.replace(/'/g,"'\\''")}'`}var K=60,y="dev.sootsim.daemon",m="sootsim-daemon",g=f(P(),"Library/Logs/sootsim"),b=f(P(),".local/state/sootsim");async function Ft(t,e={}){let[r,...n]=t,o=e.port??7668;if(!r||r==="--help"||r==="-h"){q();return}new Set(["uninstall","restart","start","stop","logs"]).has(r)&&R({event:`daemon_${r}`,properties:{platform:process.platform,subsource:"daemon"}});try{switch(r){case"uninstall":return await ht();case"status":return await $t();case"restart":return await St();case"start":return await wt();case"stop":return await kt();case"logs":return await vt(n);default:console.error(` unknown daemon subcommand: ${r}`),q(),process.exit(1)}}finally{await U()}}function q(){F("daemon")}function it(){let t=at();if(t)return t;let e=ut();return{executable:process.execPath,prefixArgs:[e]}}function at(){if(!ct())return null;let t=lt();if(!t)return null;let e=O(),r=e==="0.0.0"?"sootsim":`sootsim@${e}`;return{executable:process.execPath,prefixArgs:[t,"exec","--yes","--package",r,"--","sootsim"]}}function ct(){let t=process.argv[1];return process.env.npm_command==="exec"?!0:t?D(t).includes(`${Y}_npx${Y}`):!1}function lt(){try{let e=W("which",["npm"],{encoding:"utf8"}).trim();if(e&&a(e))return G(e)}catch{}let t=process.env.npm_execpath;return t&&a(t)?G(t):null}function G(t){let e=D(t);if(st(e)==="npx-cli.js"){let r=f(T(e),"npm-cli.js");if(a(r))return r}return e}function ut(){try{let e=W("which",["sootsim"],{encoding:"utf8"}).trim();if(e&&a(e))return D(e)}catch{}let t=process.argv[1];if(t&&a(t))return D(t);throw new Error("could not locate the sootsim binary")}function D(t){try{return ot(t)}catch{return t}}function pt(t,e){x(g,{recursive:!0});let r=f(g,"bridge.out.log"),n=f(g,"bridge.err.log"),{launcherPath:o}=V(t,e,{stdout:r,stderr:n}),c=` <string>${mt(o)}</string>`;return`<?xml version="1.0" encoding="UTF-8"?>
31
+ `}function et(t){return`'${t.replace(/'/g,"'\\''")}'`}var K=60,y="dev.sootsim.daemon",m="sootsim-daemon",g=f(P(),"Library/Logs/sootsim"),b=f(P(),".local/state/sootsim");async function jt(t,e={}){let[r,...n]=t,o=e.port??7668;if(!r||r==="--help"||r==="-h"){q();return}new Set(["install","uninstall","restart","start","stop","logs"]).has(r)&&R({event:`daemon_${r}`,properties:{platform:process.platform,subsource:"daemon"}});try{switch(r){case"install":return await ft({port:o,force:n.includes("--force")});case"uninstall":return await $t();case"status":return await St();case"restart":return await wt();case"start":return await kt();case"stop":return await vt();case"logs":return await bt(n);default:console.error(` unknown daemon subcommand: ${r}`),q(),process.exit(1)}}finally{await U()}}function q(){F("daemon")}function it(){let t=at();if(t)return t;let e=ut();return{executable:process.execPath,prefixArgs:[e]}}function at(){if(!ct())return null;let t=lt();if(!t)return null;let e=O(),r=e==="0.0.0"?"sootsim":`sootsim@${e}`;return{executable:process.execPath,prefixArgs:[t,"exec","--yes","--package",r,"--","sootsim"]}}function ct(){let t=process.argv[1];return process.env.npm_command==="exec"?!0:t?D(t).includes(`${Y}_npx${Y}`):!1}function lt(){try{let e=W("which",["npm"],{encoding:"utf8"}).trim();if(e&&a(e))return G(e)}catch{}let t=process.env.npm_execpath;return t&&a(t)?G(t):null}function G(t){let e=D(t);if(st(e)==="npx-cli.js"){let r=f(T(e),"npm-cli.js");if(a(r))return r}return e}function ut(){try{let e=W("which",["sootsim"],{encoding:"utf8"}).trim();if(e&&a(e))return D(e)}catch{}let t=process.argv[1];if(t&&a(t))return D(t);throw new Error("could not locate the sootsim binary")}function D(t){try{return ot(t)}catch{return t}}function pt(t,e){x(g,{recursive:!0});let r=f(g,"bridge.out.log"),n=f(g,"bridge.err.log"),{launcherPath:o}=V(t,e,{stdout:r,stderr:n}),c=` <string>${mt(o)}</string>`;return`<?xml version="1.0" encoding="UTF-8"?>
32
32
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
33
  <plist version="1.0">
34
34
  <dict>
@@ -57,6 +57,6 @@ RestartSec=${K}
57
57
 
58
58
  [Install]
59
59
  WantedBy=default.target
60
- `}function mt(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function gt(t){return/[^\w@%+=:,./-]/.test(t)?`'${t.replace(/'/g,"'\\''")}'`:t}function S(){return f(P(),"Library/LaunchAgents",`${y}.plist`)}function w(){return f(P(),".config/systemd/user",`${m}.service`)}function jt(){if(E())return{supported:!1,installed:!1};if(process.platform==="darwin"){let t=S();return{supported:!0,installed:a(t),path:t}}if(process.platform==="linux"){let t=w();return{supported:!0,installed:a(t),path:t}}return{supported:!1,installed:!1}}async function Mt({port:t,force:e}){if(E())throw new Error("background daemon setup is unavailable in this environment");let r=it();if(console.log(` binary: ${[r.executable,...r.prefixArgs].join(" ")}`),console.log(` port: ${t}`),process.platform==="darwin"){let n=S();if(a(n)&&!e){console.log(` already installed at ${n}`),console.log(" pass --force to overwrite, or use 'sootsim daemon restart' to reload");return}x(T(n),{recursive:!0}),H(n,pt(r,t)),console.log(` wrote ${n}`);let o=`gui/${process.getuid()}`,c=`${o}/${y}`,l=()=>{let d=s("launchctl",["bootstrap",o,n],{stdio:"pipe",encoding:"utf8"}),k=(d.stderr||d.stdout||"").trim();if(d.status!==0)return{ok:!1,reason:`bootstrap exit ${d.status}${k?`: ${k}`:""}`};let C=s("launchctl",["print",c],{encoding:"utf8"});return C.status!==0?{ok:!1,reason:`bootstrap returned 0 but service not registered (print exit ${C.status})`}:{ok:!0}},u=l();if(!u.ok){let d=u.reason;if(s("launchctl",["bootout",c],{stdio:"ignore"}),u=l(),!u.ok)throw new Error(`launchctl bootstrap failed: ${u.reason}`+(d!==u.reason?` (initial: ${d})`:"")+" \u2014 try `sootsim daemon uninstall` then retry, or reboot if launchd state is stuck.")}let i=Date.now()+4e3,p,h;for(;Date.now()<i;){let d=s("launchctl",["print",c],{encoding:"utf8"});if(d.status===0&&(p=d.stdout?.match(/state\s*=\s*(\w+)/)?.[1],h=d.stdout?.match(/pid\s*=\s*(\d+)/)?.[1],p==="running"||h))break;await new Promise(k=>setTimeout(k,150))}if(p!=="running"&&!h)throw new Error(`daemon registered but did not reach running state within 4s (last state: ${p||"unknown"}). check ${f(g,"bridge.err.log")} \u2014 typically a stale runtime or a port already bound by another process.`);console.log(` registered (state: ${p||"unknown"}${h?`, pid ${h}`:""}, log: ${f(g,"bridge.err.log")})`);return}if(process.platform==="linux"){let n=w();if(a(n)&&!e){console.log(` already installed at ${n}`),console.log(" pass --force to overwrite, or use 'sootsim daemon restart' to reload");return}x(T(n),{recursive:!0}),H(n,dt(r,t)),console.log(` wrote ${n}`);let o=s("systemctl",["--user","daemon-reload"],{stdio:"pipe",encoding:"utf8"});if(o.status!==0){let i=(o.stderr||o.stdout||"").trim();throw new Error(`systemctl daemon-reload failed${i?`: ${i}`:""}`)}let c=s("systemctl",["--user","enable","--now",m],{stdio:"pipe",encoding:"utf8"});if(c.status!==0){let i=(c.stderr||c.stdout||"").trim();throw new Error(`systemctl enable --now failed${i?`: ${i}`:""} \u2014 try \`sootsim daemon uninstall\` then retry.`)}let u=(s("systemctl",["--user","is-active",m],{encoding:"utf8"}).stdout||"").trim()||"unknown";console.log(` registered (state: ${u}, journalctl --user -u ${m} to tail logs)`);try{let i=process.env.USER||process.env.LOGNAME||"";if(i){let p=s("loginctl",["show-user",i,"--property=Linger","--value"],{encoding:"utf8"});!((p.stdout||"").trim().toLowerCase()==="yes")&&p.status===0&&console.log(` note: linger is not enabled for "${i}". the daemon will exit at logout.
61
- enable persistence with: sudo loginctl enable-linger ${i}`)}}catch{}return}console.error(` background daemon is not supported on ${process.platform}`),console.error(" run 'sootsim serve' in a persistent shell instead"),process.exit(1)}function ft(){let t=[];if(process.platform==="darwin"){let e=S();a(e)&&(s("launchctl",["bootout",`gui/${process.getuid()}/${y}`],{stdio:"ignore"}),$(e,{force:!0}),t.push(e));let r=v();return a(r)&&($(r,{recursive:!0,force:!0}),t.push(r)),a(g)&&($(g,{recursive:!0,force:!0}),t.push(g)),{removed:t,missing:t.length===0}}if(process.platform==="linux"){let e=w();return a(e)&&(s("systemctl",["--user","disable","--now",m],{stdio:"ignore"}),$(e,{force:!0}),s("systemctl",["--user","daemon-reload"],{stdio:"ignore"}),s("systemctl",["--user","reset-failed",m],{stdio:"ignore"}),t.push(e)),a(b)&&($(b,{recursive:!0,force:!0}),t.push(b)),{removed:t,missing:t.length===0}}return{removed:t,missing:!0}}function yt(){let t=[],e=N();return a(e)&&($(e,{recursive:!0,force:!0}),t.push(e)),{removed:t,missing:t.length===0}}async function ht(){let t=ft();for(let r of t.removed)console.log(` removed ${r}`);let e=yt();for(let r of e.removed)console.log(` removed ${r}`);t.missing&&e.missing&&console.log(" not installed")}async function $t(){if(process.platform==="darwin"){let t=S();if(!a(t)){console.log(" installed: no");return}console.log(` installed: yes (${t})`);let e=bt(t);e&&console.log(` binary: ${e}`);let r=s("launchctl",["print",`gui/${process.getuid()}/${y}`],{encoding:"utf8"});if(r.status===0){let n=r.stdout.match(/state\s*=\s*(\w+)/)?.[1],o=r.stdout.match(/pid\s*=\s*(\d+)/)?.[1];console.log(` state: ${n||"unknown"}${o?` (pid ${o})`:""}`)}else console.log(" state: not running");return}if(process.platform==="linux"){let t=w();if(!a(t)){console.log(" installed: no");return}console.log(` installed: yes (${t})`);let e=s("systemctl",["--user","is-active",m],{encoding:"utf8"});console.log(` state: ${e.stdout.trim()||"unknown"}`);return}console.error(` unsupported platform: ${process.platform}`),process.exit(1)}async function St(){if(process.platform==="darwin"){let t=S();a(t)||(console.error(" daemon not registered \u2014 run `sootsim setup`"),process.exit(1));let e=s("launchctl",["kickstart","-k",`gui/${process.getuid()}/${y}`],{stdio:"pipe",encoding:"utf8"});e.status!==0&&(console.error(` kickstart failed: ${e.stderr?.trim()}`),process.exit(1)),console.log(" restarted");return}if(process.platform==="linux"){let t=w();a(t)||(console.error(" daemon not registered \u2014 run `sootsim setup`"),process.exit(1));let e=s("systemctl",["--user","restart",m],{stdio:"pipe",encoding:"utf8"});e.status!==0&&(console.error(` restart failed: ${e.stderr?.trim()}`),process.exit(1)),console.log(" restarted");return}console.error(` unsupported platform: ${process.platform}`),process.exit(1)}async function wt(){if(process.platform==="darwin"){s("launchctl",["kickstart",`gui/${process.getuid()}/${y}`],{stdio:"inherit"});return}if(process.platform==="linux"){s("systemctl",["--user","start",m],{stdio:"inherit"});return}console.error(` unsupported platform: ${process.platform}`),process.exit(1)}async function kt(){if(process.platform==="darwin"){s("launchctl",["bootout",`gui/${process.getuid()}/${y}`],{stdio:"inherit"});return}if(process.platform==="linux"){s("systemctl",["--user","stop",m],{stdio:"inherit"});return}console.error(` unsupported platform: ${process.platform}`),process.exit(1)}async function vt(t){let e=t.find(o=>/^-n\d+$|^--lines=\d+$|^\d+$/.test(o)),r=e?Number(e.replace(/\D/g,"")):200,n=t.includes("-f")||t.includes("--follow");if(process.platform==="darwin"){let o=f(g,"bridge.out.log"),c=f(g,"bridge.err.log"),l=[o,c].filter(i=>a(i));l.length===0&&(console.error(` no daemon logs yet at ${g} \u2014 run \`sootsim setup\` to install the daemon`),process.exit(1));let u=n?["-n",String(r),"-F",...l]:["-n",String(r),...l];s("tail",u,{stdio:"inherit"});return}if(process.platform==="linux"){let o=`${m}.service`,c=["--user","-u",o,"-n",String(r),"--no-pager"],l=s("journalctl",n?[...c,"-f"]:c,{encoding:"utf8",stdio:n?"inherit":"pipe"});if(n)return;let u=`${l.stdout||""}${l.stderr||""}`,i=/insufficient permissions|No journal files were opened/i.test(u);if(l.status===0&&!i){process.stdout.write(l.stdout||"");return}let p=s("journalctl",[`_SYSTEMD_USER_UNIT=${o}`,"-n",String(r),"--no-pager"],{encoding:"utf8"});if(p.status===0&&(p.stdout||"").trim()){process.stdout.write(p.stdout);return}console.error(` could not read --user journal for ${o} (this user isn't in the systemd-journal group yet).
62
- run: sudo journalctl _SYSTEMD_USER_UNIT=${o} -n ${r} --no-pager`),process.exit(1)}console.error(` unsupported platform: ${process.platform}`),process.exit(1)}function bt(t){try{return nt(t,"utf8").match(/<array>\s*<string>([^<]+)<\/string>/)?.[1]||null}catch{return null}}export{Ft as a,jt as b,Mt as c,ft as d,yt as e};
60
+ `}function mt(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function gt(t){return/[^\w@%+=:,./-]/.test(t)?`'${t.replace(/'/g,"'\\''")}'`:t}function S(){return f(P(),"Library/LaunchAgents",`${y}.plist`)}function w(){return f(P(),".config/systemd/user",`${m}.service`)}function Mt(){if(E())return{supported:!1,installed:!1};if(process.platform==="darwin"){let t=S();return{supported:!0,installed:a(t),path:t}}if(process.platform==="linux"){let t=w();return{supported:!0,installed:a(t),path:t}}return{supported:!1,installed:!1}}async function ft({port:t,force:e}){if(E())throw new Error("background daemon setup is unavailable in this environment");let r=it();if(console.log(` binary: ${[r.executable,...r.prefixArgs].join(" ")}`),console.log(` port: ${t}`),process.platform==="darwin"){let n=S();if(a(n)&&!e){console.log(` already installed at ${n}`),console.log(" pass --force to overwrite, or use 'sootsim daemon restart' to reload");return}x(T(n),{recursive:!0}),H(n,pt(r,t)),console.log(` wrote ${n}`);let o=`gui/${process.getuid()}`,c=`${o}/${y}`,l=()=>{let d=s("launchctl",["bootstrap",o,n],{stdio:"pipe",encoding:"utf8"}),k=(d.stderr||d.stdout||"").trim();if(d.status!==0)return{ok:!1,reason:`bootstrap exit ${d.status}${k?`: ${k}`:""}`};let C=s("launchctl",["print",c],{encoding:"utf8"});return C.status!==0?{ok:!1,reason:`bootstrap returned 0 but service not registered (print exit ${C.status})`}:{ok:!0}},u=l();if(!u.ok){let d=u.reason;if(s("launchctl",["bootout",c],{stdio:"ignore"}),u=l(),!u.ok)throw new Error(`launchctl bootstrap failed: ${u.reason}`+(d!==u.reason?` (initial: ${d})`:"")+" \u2014 try `sootsim daemon uninstall` then retry, or reboot if launchd state is stuck.")}let i=Date.now()+4e3,p,h;for(;Date.now()<i;){let d=s("launchctl",["print",c],{encoding:"utf8"});if(d.status===0&&(p=d.stdout?.match(/state\s*=\s*(\w+)/)?.[1],h=d.stdout?.match(/pid\s*=\s*(\d+)/)?.[1],p==="running"||h))break;await new Promise(k=>setTimeout(k,150))}if(p!=="running"&&!h)throw new Error(`daemon registered but did not reach running state within 4s (last state: ${p||"unknown"}). check ${f(g,"bridge.err.log")} \u2014 typically a stale runtime or a port already bound by another process.`);console.log(` registered (state: ${p||"unknown"}${h?`, pid ${h}`:""}, log: ${f(g,"bridge.err.log")})`);return}if(process.platform==="linux"){let n=w();if(a(n)&&!e){console.log(` already installed at ${n}`),console.log(" pass --force to overwrite, or use 'sootsim daemon restart' to reload");return}x(T(n),{recursive:!0}),H(n,dt(r,t)),console.log(` wrote ${n}`);let o=s("systemctl",["--user","daemon-reload"],{stdio:"pipe",encoding:"utf8"});if(o.status!==0){let i=(o.stderr||o.stdout||"").trim();throw new Error(`systemctl daemon-reload failed${i?`: ${i}`:""}`)}let c=s("systemctl",["--user","enable","--now",m],{stdio:"pipe",encoding:"utf8"});if(c.status!==0){let i=(c.stderr||c.stdout||"").trim();throw new Error(`systemctl enable --now failed${i?`: ${i}`:""} \u2014 try \`sootsim daemon uninstall\` then retry.`)}let u=(s("systemctl",["--user","is-active",m],{encoding:"utf8"}).stdout||"").trim()||"unknown";console.log(` registered (state: ${u}, journalctl --user -u ${m} to tail logs)`);try{let i=process.env.USER||process.env.LOGNAME||"";if(i){let p=s("loginctl",["show-user",i,"--property=Linger","--value"],{encoding:"utf8"});!((p.stdout||"").trim().toLowerCase()==="yes")&&p.status===0&&console.log(` note: linger is not enabled for "${i}". the daemon will exit at logout.
61
+ enable persistence with: sudo loginctl enable-linger ${i}`)}}catch{}return}console.error(` background daemon is not supported on ${process.platform}`),console.error(" run 'sootsim serve' in a persistent shell instead"),process.exit(1)}function yt(){let t=[];if(process.platform==="darwin"){let e=S();a(e)&&(s("launchctl",["bootout",`gui/${process.getuid()}/${y}`],{stdio:"ignore"}),$(e,{force:!0}),t.push(e));let r=v();return a(r)&&($(r,{recursive:!0,force:!0}),t.push(r)),a(g)&&($(g,{recursive:!0,force:!0}),t.push(g)),{removed:t,missing:t.length===0}}if(process.platform==="linux"){let e=w();return a(e)&&(s("systemctl",["--user","disable","--now",m],{stdio:"ignore"}),$(e,{force:!0}),s("systemctl",["--user","daemon-reload"],{stdio:"ignore"}),s("systemctl",["--user","reset-failed",m],{stdio:"ignore"}),t.push(e)),a(b)&&($(b,{recursive:!0,force:!0}),t.push(b)),{removed:t,missing:t.length===0}}return{removed:t,missing:!0}}function ht(){let t=[],e=N();return a(e)&&($(e,{recursive:!0,force:!0}),t.push(e)),{removed:t,missing:t.length===0}}async function $t(){let t=yt();for(let r of t.removed)console.log(` removed ${r}`);let e=ht();for(let r of e.removed)console.log(` removed ${r}`);t.missing&&e.missing&&console.log(" not installed")}async function St(){if(process.platform==="darwin"){let t=S();if(!a(t)){console.log(" installed: no");return}console.log(` installed: yes (${t})`);let e=xt(t);e&&console.log(` binary: ${e}`);let r=s("launchctl",["print",`gui/${process.getuid()}/${y}`],{encoding:"utf8"});if(r.status===0){let n=r.stdout.match(/state\s*=\s*(\w+)/)?.[1],o=r.stdout.match(/pid\s*=\s*(\d+)/)?.[1];console.log(` state: ${n||"unknown"}${o?` (pid ${o})`:""}`)}else console.log(" state: not running");return}if(process.platform==="linux"){let t=w();if(!a(t)){console.log(" installed: no");return}console.log(` installed: yes (${t})`);let e=s("systemctl",["--user","is-active",m],{encoding:"utf8"});console.log(` state: ${e.stdout.trim()||"unknown"}`);return}console.error(` unsupported platform: ${process.platform}`),process.exit(1)}async function wt(){if(process.platform==="darwin"){let t=S();a(t)||(console.error(" daemon not registered \u2014 run `sootsim setup`"),process.exit(1));let e=s("launchctl",["kickstart","-k",`gui/${process.getuid()}/${y}`],{stdio:"pipe",encoding:"utf8"});e.status!==0&&(console.error(` kickstart failed: ${e.stderr?.trim()}`),process.exit(1)),console.log(" restarted");return}if(process.platform==="linux"){let t=w();a(t)||(console.error(" daemon not registered \u2014 run `sootsim setup`"),process.exit(1));let e=s("systemctl",["--user","restart",m],{stdio:"pipe",encoding:"utf8"});e.status!==0&&(console.error(` restart failed: ${e.stderr?.trim()}`),process.exit(1)),console.log(" restarted");return}console.error(` unsupported platform: ${process.platform}`),process.exit(1)}async function kt(){if(process.platform==="darwin"){s("launchctl",["kickstart",`gui/${process.getuid()}/${y}`],{stdio:"inherit"});return}if(process.platform==="linux"){s("systemctl",["--user","start",m],{stdio:"inherit"});return}console.error(` unsupported platform: ${process.platform}`),process.exit(1)}async function vt(){if(process.platform==="darwin"){s("launchctl",["bootout",`gui/${process.getuid()}/${y}`],{stdio:"inherit"});return}if(process.platform==="linux"){s("systemctl",["--user","stop",m],{stdio:"inherit"});return}console.error(` unsupported platform: ${process.platform}`),process.exit(1)}async function bt(t){let e=t.find(o=>/^-n\d+$|^--lines=\d+$|^\d+$/.test(o)),r=e?Number(e.replace(/\D/g,"")):200,n=t.includes("-f")||t.includes("--follow");if(process.platform==="darwin"){let o=f(g,"bridge.out.log"),c=f(g,"bridge.err.log"),l=[o,c].filter(i=>a(i));l.length===0&&(console.error(` no daemon logs yet at ${g} \u2014 run \`sootsim setup\` to install the daemon`),process.exit(1));let u=n?["-n",String(r),"-F",...l]:["-n",String(r),...l];s("tail",u,{stdio:"inherit"});return}if(process.platform==="linux"){let o=`${m}.service`,c=["--user","-u",o,"-n",String(r),"--no-pager"],l=s("journalctl",n?[...c,"-f"]:c,{encoding:"utf8",stdio:n?"inherit":"pipe"});if(n)return;let u=`${l.stdout||""}${l.stderr||""}`,i=/insufficient permissions|No journal files were opened/i.test(u);if(l.status===0&&!i){process.stdout.write(l.stdout||"");return}let p=s("journalctl",[`_SYSTEMD_USER_UNIT=${o}`,"-n",String(r),"--no-pager"],{encoding:"utf8"});if(p.status===0&&(p.stdout||"").trim()){process.stdout.write(p.stdout);return}console.error(` could not read --user journal for ${o} (this user isn't in the systemd-journal group yet).
62
+ run: sudo journalctl _SYSTEMD_USER_UNIT=${o} -n ${r} --no-pager`),process.exit(1)}console.error(` unsupported platform: ${process.platform}`),process.exit(1)}function xt(t){try{return nt(t,"utf8").match(/<array>\s*<string>([^<]+)<\/string>/)?.[1]||null}catch{return null}}export{jt as a,Mt as b,ft as c,yt as d,ht as e};
@@ -1,6 +1,6 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as m,b as I}from"./chunk-2HJU3NAO.js";import{a as w,b as _,c as T}from"./chunk-ZJI2JP7F.js";import{c as k}from"./chunk-CJHPCUUV.js";import{G as O,o as D,q as f}from"./chunk-YMFQOXT4.js";import h from"fs";import v from"path";var c="default",U="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(),U)}function G(e){return`sootsim-profile-${s(e)}`}function B(e){return v.join(D(),"Partitions",G(e))}function y(e){return v.join(f(),"playwright",s(e))}function b(){try{let e=JSON.parse(h.readFileSync(g(),"utf8"));if(!e||e.version!==a)return{version:a,profiles:[]};let r=Array.isArray(e.profiles)?e.profiles.filter(t=>!!t&&typeof t.id=="string"&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string").map(t=>({id:s(t.id),createdAt:t.createdAt,updatedAt:t.updatedAt})):[];return{version:a,profiles:r}}catch{return{version:a,profiles:[]}}}function A(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:A(e.profiles)};let r=new Date().toISOString();return{version:a,profiles:A([{id:c,createdAt:r,updatedAt:r},...e.profiles])}}function S(e){O();let r=P(e),t=`${g()}.tmp`;return h.writeFileSync(t,`${JSON.stringify(r,null,2)}
3
- `,"utf8"),h.renameSync(t,g()),r}function H(){return S(b()).profiles}function j(e){let r=s(e);return H().find(t=>t.id===r)??null}function E(e=c){let r=s(e),t=j(r);return t||q(r)}function q(e){let r=s(e),t=P(b());if(t.profiles.some(n=>n.id===r))throw new Error(`profile already exists: ${r}`);let o=new Date().toISOString(),i={id:r,createdAt:o,updatedAt:o};return S({version:a,profiles:[...t.profiles,i]}),i}function pe(e){let r=s(e);if(r===c)throw new Error("the default profile cannot be deleted; clear it instead");let t=P(b()),o=t.profiles.find(i=>i.id===r);if(!o)throw new Error(`profile not found: ${r}`);return S({version:a,profiles:t.profiles.filter(i=>i.id!==r)}),z(r),o}function z(e){let r=s(e);for(let t of[B(r),y(r)])try{h.rmSync(t,{recursive:!0,force:!0})}catch{}}function Y(){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 K(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 T(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 M={id:"chromium",name:"chromium",description:"system chrome / chromium / edge \u2014 visible window (headless: use playwright)",kind:"browser",availability:Y,launch:K};function V(){let e=m();return e?{available:!0,reason:null,detail:`${e.kind} @ ${e.path}`}:{available:!1,reason:"sootsim desktop app not installed (run `sootsim desktop install`)"}}async function J(e){let r=m();if(!r)return{launched:!1,message:"sootsim desktop app not installed"};try{let t=await I(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 C={id:"electron",name:"electron",description:"sootsim desktop companion app (native window, menu bar)",kind:"native",availability:V,launch:J};import{spawn as X}from"child_process";import{closeSync as Z,mkdtempSync as Q,openSync as ee,readFileSync as re}from"fs";import{createRequire as te}from"module";import{tmpdir as L}from"os";import{join as W}from"path";var oe=`
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as m,b as I}from"./chunk-XHPOQKUA.js";import{a as w,b as _,c as E}from"./chunk-PJ76I3KZ.js";import{c as O}from"./chunk-ZU6ECPCC.js";import{G as k,o as D,q as f}from"./chunk-BI3I5X3U.js";import h from"fs";import v from"path";var c="default",$="profiles.json",a=1;function s(e){let r=e.trim();if(!r)throw new Error("profile id is required");if(!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(r))throw new Error("profile ids must start with a letter or number and contain only letters, numbers, dot, dash, or underscore");if(r==="."||r==="..")throw new Error(`invalid profile id: ${r}`);return r}function g(){return v.join(f(),$)}function F(e){return`sootsim-profile-${s(e)}`}function B(e){return v.join(D(),"Partitions",F(e))}function b(e){return v.join(f(),"playwright",s(e))}function y(){try{let e=JSON.parse(h.readFileSync(g(),"utf8"));if(!e||e.version!==a)return{version:a,profiles:[]};let r=Array.isArray(e.profiles)?e.profiles.filter(t=>!!t&&typeof t.id=="string"&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string").map(t=>({id:s(t.id),createdAt:t.createdAt,updatedAt:t.updatedAt})):[];return{version:a,profiles:r}}catch{return{version:a,profiles:[]}}}function T(e){return[...e].sort((r,t)=>r.id===c?-1:t.id===c?1:r.id.localeCompare(t.id))}function P(e){if(e.profiles.some(t=>t.id===c))return{...e,profiles:T(e.profiles)};let r=new Date().toISOString();return{version:a,profiles:T([{id:c,createdAt:r,updatedAt:r},...e.profiles])}}function S(e){k();let r=P(e),t=`${g()}.tmp`;return h.writeFileSync(t,`${JSON.stringify(r,null,2)}
3
+ `,"utf8"),h.renameSync(t,g()),r}function q(){return S(y()).profiles}function j(e){let r=s(e);return q().find(t=>t.id===r)??null}function C(e=c){let r=s(e),t=j(r);return t||H(r)}function H(e){let r=s(e),t=P(y());if(t.profiles.some(i=>i.id===r))throw new Error(`profile already exists: ${r}`);let n=new Date().toISOString(),o={id:r,createdAt:n,updatedAt:n};return S({version:a,profiles:[...t.profiles,o]}),o}function pe(e){let r=s(e);if(r===c)throw new Error("the default profile cannot be deleted; clear it instead");let t=P(y()),n=t.profiles.find(o=>o.id===r);if(!n)throw new Error(`profile not found: ${r}`);return S({version:a,profiles:t.profiles.filter(o=>o.id!==r)}),z(r),n}function z(e){let r=s(e);for(let t of[B(r),b(r)])try{h.rmSync(t,{recursive:!0,force:!0})}catch{}}function K(){let e=w();return e?{available:!0,reason:null,detail:e}:{available:!1,reason:"no chromium-family browser found (chrome, chromium, edge, brave, arc)"}}async function Y(e){if(e.headless)return{launched:!1,message:"the chromium driver launches a visible browser window and cannot run headless \u2014 a headless `chrome --headless=new` process exits immediately and the sim never connects. for headless automation use `--driver playwright`."};let r=w();if(!r)return{launched:!1,message:"chromium not found \u2014 install chrome or run `sootsim list --drivers`"};if(!e.url)return{launched:!1,message:"chromium driver requires a target url"};if(e.profileId||e.ephemeralProfile)return{launched:!1,message:"profiles require electron or playwright; browser tabs use your current Chrome profile"};try{let t=await E(e.url,{detached:e.detached??!0});return{launched:!0,message:`chromium launched \u2192 ${e.url}`,pid:t.pid,target:t.target??r,attachUrl:e.url}}catch(t){return{launched:!1,message:`chromium spawn failed: ${t instanceof Error?t.message:String(t)}`}}}var A={id:"chromium",name:"chromium",description:"system chrome / chromium / edge \u2014 visible window (headless: use playwright)",kind:"browser",availability:K,launch:Y};function V(){let e=m();return e?{available:!0,reason:null,detail:`${e.kind} @ ${e.path}`}:{available:!1,reason:"sootsim desktop app not installed (run `sootsim desktop install`)"}}async function J(e){let r=m();if(!r)return{launched:!1,message:"sootsim desktop app not installed"};try{let t=await I(e.url,r,{device:e.device,profileId:e.profileId,ephemeralProfile:e.ephemeralProfile});return t.launched?{launched:!0,message:e.url?`electron launched via ${t.via} \u2192 ${e.url}`:`electron launched via ${t.via}`,target:t.target,attachUrl:e.url}:{launched:!1,message:"desktop companion failed to start"}}catch(t){return{launched:!1,message:`electron launch failed: ${t instanceof Error?t.message:String(t)}`}}}var M={id:"electron",name:"electron",description:"sootsim desktop companion app (native window, menu bar)",kind:"native",availability:V,launch:J};import{spawn as X}from"child_process";import{closeSync as Z,mkdtempSync as Q,openSync as ee,readFileSync as re}from"fs";import{createRequire as te}from"module";import{tmpdir as L}from"os";import{join as R}from"path";var ne=`
4
4
  const modulePath = process.env.SOOTSIM_PW_MODULE;
5
5
  const url = process.env.SOOTSIM_PW_URL;
6
6
  // the WS bridge port the sim page must register with, injected below as
@@ -31,6 +31,15 @@ const extraChromeArgs = (process.env.SOOTSIM_PW_CHROME_ARGS || '')
31
31
  // iOS Safari proxy \u2014 headless webkit keeps the real Apple GPU while headless
32
32
  // chromium falls back to SwiftShader software rendering for canvas/WebGL.
33
33
  const browserEngine = process.env.SOOTSIM_PW_BROWSER || 'chromium';
34
+ // Local CanvasKit/WebGL work must never fall back to Playwright's software
35
+ // renderer. CI may use the bundled browser for non-interactive coverage, but
36
+ // local test drives fail closed unless a hardware-backed branded browser is
37
+ // proven after launch.
38
+ const hardwareGpuRequired =
39
+ browserEngine === 'chromium' &&
40
+ process.env.CI !== '1' &&
41
+ process.env.CI !== 'true';
42
+ const softwareRendererPattern = /swiftshader|software(?: rasterizer)?|llvmpipe|lavapipe|softpipe/i;
34
43
  // page viewport as '<w>x<h>'. the caller sizes it from the device profile;
35
44
  // the fallback is phone-shaped because the page hosts a phone sim \u2014 the
36
45
  // playwright default (1280x720 desktop) letterboxes the device frame.
@@ -82,6 +91,28 @@ const chromePidsByProfile = () => {
82
91
  .filter((p) => p && p !== process.pid);
83
92
  } catch { return []; }
84
93
  };
94
+ const chromeCommandsByProfile = () => {
95
+ if (!reapEnabled) return [];
96
+ const pids = chromePidsByProfile();
97
+ if (pids.length === 0) return [];
98
+ try {
99
+ return execSync('ps -p ' + pids.join(',') + ' -o command=', {
100
+ stdio: ['ignore', 'pipe', 'ignore'],
101
+ }).toString().split('\\n').filter(Boolean);
102
+ } catch { return []; }
103
+ };
104
+ const assertNoUnsafeSwiftShaderFlag = () => {
105
+ if (!hardwareGpuRequired) return;
106
+ const unsafe = chromeCommandsByProfile().find((command) =>
107
+ command.includes('--enable-unsafe-swiftshader') ||
108
+ /--use-angle=(?:swiftshader|swiftshader-webgl)(?:\\s|$)/i.test(command)
109
+ );
110
+ if (unsafe) {
111
+ throw new Error(
112
+ '[playwright-driver] refused software-rendering Chrome: launched process contains a SwiftShader flag'
113
+ );
114
+ }
115
+ };
85
116
  const killTree = (pid) => {
86
117
  let kids = [];
87
118
  try {
@@ -228,13 +259,11 @@ const cleanupProfile = () => {
228
259
  if (typeof ownerWatch.unref === 'function') ownerWatch.unref();
229
260
  };
230
261
  startOwnerWatch();
231
- // prefer real Google Chrome (looks like the user's browser, no leftover
232
- // "Chrome for Testing" processes). on platforms where Chrome can't be
233
- // installed (notably linux arm64, where \`npx playwright install chrome\`
234
- // errors with "not supported on Linux Arm64"), fall back to Playwright's
235
- // bundled chromium so the driver still works rather than crashing the
236
- // sim out entirely. set SOOTSIM_PW_CHANNEL=chrome|chromium|msedge|... to
237
- // pin the channel. NOTE: this is NOT enough to make \`sootsim perf cpu\`
262
+ // Prefer real Google Chrome (looks like the user's browser, no leftover
263
+ // "Chrome for Testing" processes). Local rendering is fail-closed: bundled
264
+ // Chromium is allowed only under CI because its headless shell commonly has
265
+ // no GPU and silently chooses SwiftShader. Set SOOTSIM_PW_CHANNEL to pin a
266
+ // branded Chrome/Edge channel. NOTE: this is NOT enough to make \`sootsim perf cpu\`
238
267
  // work \u2014 that profiles the tenant *worker*, and the JS Self-Profiler API
239
268
  // cannot be constructed in a dedicated worker (see
240
269
  // worker-handlers/cpu-profile.ts). cpu-profile needs a CDP-based profiler
@@ -248,9 +277,26 @@ const cleanupProfile = () => {
248
277
  process.stderr.write('[playwright-driver] launched ' + browserEngine + '\\n');
249
278
  } else {
250
279
  const pinnedChannel = process.env.SOOTSIM_PW_CHANNEL || '';
280
+ const brandedChannel = /^(?:chrome(?:-beta|-dev|-canary)?|msedge(?:-beta|-dev|-canary)?)$/;
281
+ if (hardwareGpuRequired && pinnedChannel && !brandedChannel.test(pinnedChannel)) {
282
+ throw new Error(
283
+ '[playwright-driver] local GPU rendering requires a branded Chrome/Edge channel; refused "' + pinnedChannel + '"'
284
+ );
285
+ }
286
+ if (
287
+ hardwareGpuRequired &&
288
+ extraChromeArgs.some((arg) =>
289
+ arg === '--enable-unsafe-swiftshader' ||
290
+ /^--use-angle=(?:swiftshader|swiftshader-webgl)$/i.test(arg)
291
+ )
292
+ ) {
293
+ throw new Error('[playwright-driver] refused SwiftShader launch arguments');
294
+ }
251
295
  const channelsToTry = pinnedChannel
252
296
  ? [pinnedChannel]
253
- : ['chrome', null]; // null = bundled chromium
297
+ : hardwareGpuRequired
298
+ ? ['chrome']
299
+ : ['chrome', null]; // null = bundled chromium, CI only
254
300
  const launchWith = async (channel) => {
255
301
  const opts = channel
256
302
  ? { headless, channel, viewport, deviceScaleFactor }
@@ -318,7 +364,10 @@ const cleanupProfile = () => {
318
364
  /Chromium distribution/i.test(msg);
319
365
  if (!isMissingChannel) throw err; // unexpected failure: bubble up
320
366
  if (channel) {
321
- process.stderr.write('[playwright-driver] channel "' + channel + '" not available, falling back to bundled chromium\\n');
367
+ const next = hardwareGpuRequired
368
+ ? '; bundled Chromium is disabled for local GPU work\\n'
369
+ : ', falling back to bundled chromium\\n';
370
+ process.stderr.write('[playwright-driver] channel "' + channel + '" not available' + next);
322
371
  }
323
372
  }
324
373
  }
@@ -366,6 +415,34 @@ const cleanupProfile = () => {
366
415
  }, Number.isFinite(connectTimeoutMs) && connectTimeoutMs > 0 ? connectTimeoutMs : 120000);
367
416
  if (typeof connectTimer.unref === 'function') connectTimer.unref();
368
417
  const page = await context.newPage();
418
+ if (hardwareGpuRequired) {
419
+ assertNoUnsafeSwiftShaderFlag();
420
+ const gpu = await page.evaluate(() => {
421
+ const canvas = document.createElement('canvas');
422
+ const gl =
423
+ canvas.getContext('webgl2', { powerPreference: 'high-performance' }) ||
424
+ canvas.getContext('webgl', { powerPreference: 'high-performance' });
425
+ if (!gl) return { renderer: null, vendor: null };
426
+ const info = gl.getExtension('WEBGL_debug_renderer_info');
427
+ return {
428
+ renderer: info ? String(gl.getParameter(info.UNMASKED_RENDERER_WEBGL)) : null,
429
+ vendor: info ? String(gl.getParameter(info.UNMASKED_VENDOR_WEBGL)) : null,
430
+ };
431
+ });
432
+ if (!gpu.renderer) {
433
+ throw new Error(
434
+ '[playwright-driver] could not prove a hardware WebGL renderer; refusing local render-heavy launch'
435
+ );
436
+ }
437
+ if (softwareRendererPattern.test(gpu.renderer)) {
438
+ throw new Error('[playwright-driver] refused software WebGL renderer: ' + gpu.renderer);
439
+ }
440
+ assertNoUnsafeSwiftShaderFlag();
441
+ process.stderr.write(
442
+ '[playwright-driver] hardware WebGL renderer: ' + gpu.renderer +
443
+ (gpu.vendor ? ' (' + gpu.vendor + ')' : '') + '\\n'
444
+ );
445
+ }
369
446
  // surface page-side failures (engine boot crash, failed WS registration)
370
447
  // to stderr so a sim that never connects produces a real diagnostic
371
448
  // instead of a silent "timed out waiting for opened sim to connect".
@@ -396,6 +473,6 @@ const cleanupProfile = () => {
396
473
  process.stderr.write(String((err && err.stack) || err) + '\\n');
397
474
  process.exit(1);
398
475
  });
399
- `;function R(){let e=[process.cwd()+"/"];try{process.argv[1]&&e.push(process.argv[1])}catch{}for(let r of e)try{let t=te(r);for(let o of["playwright","playwright-chromium","playwright-core"])try{return{spec:o,modulePath:t.resolve(o)}}catch{}}catch{}return null}function ie(){let e=R();return e?{available:!0,reason:null,detail:`resolved via ${e.spec}`}:{available:!1,reason:"playwright not installed in the current workspace"}}function ne(e,r){return process.platform!=="linux"||e.headless||process.env.DISPLAY||process.env.WAYLAND_DISPLAY||!/missing x server|cannot open display|x server|x11/i.test(r)?null:" hint: linux without DISPLAY/WAYLAND_DISPLAY \u2014 rerun without --headed (or add --headless) to run playwright headless."}function se(e){return e.profileId?y(E(e.profileId).id):e.ephemeralProfile?Q(W(L(),"sootsim-playwright-profile-")):""}async function ae(e){let r=R();if(!r)return{launched:!1,message:"playwright not installed \u2014 run `bun add -D playwright` first"};if(!e.url)return{launched:!1,message:"playwright driver requires a target url"};let t=W(L(),`sootsim-playwright-host-${Date.now().toString(36)}-${process.pid}.log`),o=`${t}.connected`,i=ee(t,"a");try{let n=k(),p=X(process.execPath,["-e",oe],{detached:!0,stdio:["ignore","ignore",i],env:{...process.env,SOOTSIM_PW_MODULE:r.modulePath,SOOTSIM_PW_URL:e.url,SOOTSIM_PW_BRIDGE_PORT:e.bridgePort?String(e.bridgePort):"",SOOTSIM_PW_HEADLESS:e.headless??!0?"1":"0",SOOTSIM_PW_USERDATADIR:se(e),SOOTSIM_PW_CDP_PORT:e.cdpPort?String(e.cdpPort):"",SOOTSIM_PW_BROWSER:e.browser??"",SOOTSIM_PW_VIEWPORT:e.viewport?`${e.viewport.width}x${e.viewport.height}`:"",SOOTSIM_PW_CONNECTED_ACK_FILE:o,SOOTSIM_PW_CONNECT_TIMEOUT_MS:String(e.connectTimeoutMs??12e4),SOOTSIM_PW_OWNER_PID:n&&n>1?String(n):""}});p.unref();let x=await new Promise(l=>{let u=setTimeout(()=>l(null),4e3);p.once("exit",F=>{clearTimeout(u),l(F??0)})});if(x!==null){let l=re(t,"utf8").trim(),u=ne(e,l);return{launched:!1,message:`playwright host exited early (code ${x}) \u2014 host log ${t}${l?`:
476
+ `;function W(){let e=[process.cwd()+"/"];try{process.argv[1]&&e.push(process.argv[1])}catch{}for(let r of e)try{let t=te(r);for(let n of["playwright","playwright-chromium","playwright-core"])try{return{spec:n,modulePath:t.resolve(n)}}catch{}}catch{}return null}function oe(){let e=W();return e?{available:!0,reason:null,detail:`resolved via ${e.spec}`}:{available:!1,reason:"playwright not installed in the current workspace"}}function ie(e,r){return process.platform!=="linux"||e.headless||process.env.DISPLAY||process.env.WAYLAND_DISPLAY||!/missing x server|cannot open display|x server|x11/i.test(r)?null:" hint: linux without DISPLAY/WAYLAND_DISPLAY \u2014 rerun without --headed (or add --headless) to run playwright headless."}function se(e){return e.profileId?b(C(e.profileId).id):e.ephemeralProfile?Q(R(L(),"sootsim-playwright-profile-")):""}async function ae(e){let r=W();if(!r)return{launched:!1,message:"playwright not installed \u2014 run `bun add -D playwright` first"};if(!e.url)return{launched:!1,message:"playwright driver requires a target url"};let t=R(L(),`sootsim-playwright-host-${Date.now().toString(36)}-${process.pid}.log`),n=`${t}.connected`,o=ee(t,"a");try{let i=O(),p=X(process.execPath,["-e",ne],{detached:!0,stdio:["ignore","ignore",o],env:{...process.env,SOOTSIM_PW_MODULE:r.modulePath,SOOTSIM_PW_URL:e.url,SOOTSIM_PW_BRIDGE_PORT:e.bridgePort?String(e.bridgePort):"",SOOTSIM_PW_HEADLESS:e.headless??!0?"1":"0",SOOTSIM_PW_USERDATADIR:se(e),SOOTSIM_PW_CDP_PORT:e.cdpPort?String(e.cdpPort):"",SOOTSIM_PW_BROWSER:e.browser??"",SOOTSIM_PW_VIEWPORT:e.viewport?`${e.viewport.width}x${e.viewport.height}`:"",SOOTSIM_PW_CONNECTED_ACK_FILE:n,SOOTSIM_PW_CONNECT_TIMEOUT_MS:String(e.connectTimeoutMs??12e4),SOOTSIM_PW_OWNER_PID:i&&i>1?String(i):""}});p.unref();let x=await new Promise(l=>{let u=setTimeout(()=>l(null),4e3);p.once("exit",U=>{clearTimeout(u),l(U??0)})});if(x!==null){let l=re(t,"utf8").trim(),u=ie(e,l);return{launched:!1,message:`playwright host exited early (code ${x}) \u2014 host log ${t}${l?`:
400
477
  ${l}`:""}${u?`
401
- ${u}`:""}`}}return{launched:!0,message:`playwright chrome launched \u2192 ${e.url}`,pid:p.pid,target:r.spec,attachUrl:e.url,connectAckFile:o,diagnosticLogPath:t}}catch(n){return{launched:!1,message:`playwright launch failed: ${n instanceof Error?n.message:String(n)}`}}finally{Z(i)}}var N={id:"playwright",name:"playwright",description:"programmatic chromium via the playwright package \u2014 headless default",kind:"automation",availability:ie,launch:ae};function le(){return process.platform!=="darwin"&&process.platform!=="linux"&&process.platform!=="win32"?{available:!1,reason:`unsupported platform: ${process.platform}`}:{available:!0,reason:null,detail:process.platform==="darwin"?"open(1)":process.platform==="win32"?"cmd /c start":"xdg-open(1)"}}async function ce(e){if(e.headless)return{launched:!1,message:"system driver does not support --headless; use chromium or playwright"};if(!e.url)return{launched:!1,message:"system driver requires a target url"};if(e.profileId||e.ephemeralProfile)return{launched:!1,message:"profiles require electron or playwright; browser tabs use your current browser profile"};try{let r=await _(e.url,{detached:e.detached??!0,newWindow:e.newWindow});return{launched:!0,message:`${r.via} launch \u2192 ${e.url}`,pid:r.pid,target:r.target,attachUrl:e.url}}catch(r){return{launched:!1,message:`system launch failed: ${r instanceof Error?r.message:String(r)}`}}}var $={id:"system",name:"system",description:"shared browser launcher \u2014 system default or chromium window",kind:"delegate",availability:le,launch:ce};var d=[M,C,N,$];function Ce(){return d}function Le(e){return d.find(r=>r.id===e)??null}function We(e,r){if(e)return d.find(o=>o.id===e)??null;for(let t of r){let o=d.find(i=>i.id===t);if(o&&o.availability().available)return o}return null}function Re(){return d.map(e=>{let r=e.availability();return{id:e.id,name:e.name,kind:e.kind,description:e.description,available:r.available,reason:r.reason,detail:r.detail??null}})}export{H as a,E as b,q as c,pe as d,z as e,M as f,C as g,N as h,$ as i,d as j,Ce as k,Le as l,We as m,Re as n};
478
+ ${u}`:""}`}}return{launched:!0,message:`playwright chrome launched \u2192 ${e.url}`,pid:p.pid,target:r.spec,attachUrl:e.url,connectAckFile:n,diagnosticLogPath:t}}catch(i){return{launched:!1,message:`playwright launch failed: ${i instanceof Error?i.message:String(i)}`}}finally{Z(o)}}var N={id:"playwright",name:"playwright",description:"programmatic chromium via the playwright package \u2014 headless default",kind:"automation",availability:oe,launch:ae};function le(){return process.platform!=="darwin"&&process.platform!=="linux"&&process.platform!=="win32"?{available:!1,reason:`unsupported platform: ${process.platform}`}:{available:!0,reason:null,detail:process.platform==="darwin"?"open(1)":process.platform==="win32"?"cmd /c start":"xdg-open(1)"}}async function ce(e){if(e.headless)return{launched:!1,message:"system driver does not support --headless; use chromium or playwright"};if(!e.url)return{launched:!1,message:"system driver requires a target url"};if(e.profileId||e.ephemeralProfile)return{launched:!1,message:"profiles require electron or playwright; browser tabs use your current browser profile"};try{let r=await _(e.url,{detached:e.detached??!0,newWindow:e.newWindow});return{launched:!0,message:`${r.via} launch \u2192 ${e.url}`,pid:r.pid,target:r.target,attachUrl:e.url}}catch(r){return{launched:!1,message:`system launch failed: ${r instanceof Error?r.message:String(r)}`}}}var G={id:"system",name:"system",description:"shared browser launcher \u2014 system default or chromium window",kind:"delegate",availability:le,launch:ce};var d=[A,M,N,G];function Me(){return d}function Le(e){return d.find(r=>r.id===e)??null}function Re(e,r){if(e)return d.find(n=>n.id===e)??null;for(let t of r){let n=d.find(o=>o.id===t);if(n&&n.availability().available)return n}return null}function We(){return d.map(e=>{let r=e.availability();return{id:e.id,name:e.name,kind:e.kind,description:e.description,available:r.available,reason:r.reason,detail:r.detail??null}})}export{q as a,C as b,H as c,pe as d,z as e,A as f,M as g,N as h,G as i,d as j,Me as k,Le as l,Re as m,We as n};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{H as t,N as n,P as l,j as r}from"./chunk-YMFQOXT4.js";function m(){let e=t(),i=r()?n():null;return i&&l(i)?{primary:`engine dev source (:${i.bridgePort})`,installedRuntime:e?`installed runtime v${e}`:null,isDevBridge:!0}:{primary:e?`runtime v${e}`:"runtime not installed",installedRuntime:null,isDevBridge:!1}}export{m as a};
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{H as t,N as n,P as l,j as r}from"./chunk-BI3I5X3U.js";function m(){let e=t(),i=r()?n():null;return i&&l(i)?{primary:`engine dev source (:${i.bridgePort})`,installedRuntime:e?`installed runtime v${e}`:null,isDevBridge:!0}:{primary:e?`runtime v${e}`:"runtime not installed",installedRuntime:null,isDevBridge:!1}}export{m as a};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{h as w,j as u,k as m,l}from"./chunk-IKZ4Z6ND.js";var p="sootsim:settings",v=["errorReporting","colorScheme","a11yMode","a11yDepth","screenshotCanvas","screenshotBackground","screenshotText","screenshotPose","screenshotDynamicSize","alwaysShowLiveWebViews","agentProvider","onboardingComplete","betaConsentVersion","detailedTelemetry"];function S(){if(typeof window>"u")return null;let e=window.sootsimElectron;return e&&typeof e=="object"?e:null}function g(e){let t={};for(let n of v){if(!(n in e))continue;let r=e[n],o=u[n];o.validate&&!o.validate(r)||o.options&&!o.options.includes(r)||(t[n]=r)}return t}function h(e){let t={};for(let n of v)t[n]=e[n];return t}function _(){if(typeof localStorage>"u")return{};try{let e=localStorage.getItem(p);return e?g(JSON.parse(e)):{}}catch{return{}}}function V(e){if(!(typeof localStorage>"u"))try{localStorage.setItem(p,JSON.stringify(h(e)))}catch{}}function E(){let t=S()?.sharedConfig?.settings;return!t||typeof t!="object"?{}:g(t)}function K(e){let t=S();if(t?.writeSharedConfig)try{t.writeSharedConfig({settings:h(e)})}catch{}}function b(){if(typeof window>"u")return null;let e=window.__sootsimSharedConfig;return e&&typeof e=="object"?e:null}function j(){let e=b()?.settings;return!e||typeof e!="object"?{}:g(e)}function D(e){if(!b())return;let t={settings:h(e)};try{if(globalThis.__sootsimBridgeRequest?.writeSharedConfig?.(t))return}catch{}if(!(typeof fetch>"u"))try{fetch("/__sootsim/shared-config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),keepalive:!0}).catch(()=>{})}catch{}}function k(){let e=_(),t=j(),n=E();return{...e,...t,...n}}function R(e){V(e),K(e),D(e)}function C(e){if(typeof window>"u")return()=>{};let t=i=>{if(!(i.key!==p||i.newValue==null))try{e(g(JSON.parse(i.newValue)))}catch{}};window.addEventListener("storage",t);let n=S(),r;n?.onSharedConfigChanged&&(r=n.onSharedConfigChanged(i=>{let d=i?.settings;!d||typeof d!="object"||e(g(d))}));let c=globalThis.__sootsimBridgeRequest?.subscribeSharedConfig?.(i=>{let d=i?.settings;!d||typeof d!="object"||e(g(d))});return()=>{window.removeEventListener("storage",t),r?.(),c?.()}}var M=l(),P=k();for(let e of Object.keys(m()))delete P[e];var s={...M,...P},f=[],a=null;function y(){for(let e of f)e();R(s)}C(e=>{let t={...s},n=!1;for(let[r,o]of Object.entries(e)){let c=r;t[c]!==o&&(t[c]=o,n=!0)}if(n){s=t,a=null;for(let r of f)r()}});var L={get(e){return s[e]},set(e,t){let n=u[e];n.validate&&!n.validate(t)||n.options&&!n.options.includes(t)||s[e]!==t&&(s={...s,[e]:t},e==="deviceModel"&&(a=null),y())},getAll(){return s},apply(e){let t=!1,n={...s};for(let[r,o]of Object.entries(e)){if(o===void 0)continue;let c=r,i=u[c];i&&(i.validate&&!i.validate(o)||i.options&&!i.options.includes(o)||n[c]!==o&&(n[c]=o,t=!0))}t&&(s=n,a=null,y())},reset(){s=l(),a=null,y()},subscribe(e){return f.push(e),()=>{f=f.filter(t=>t!==e)}},getDeviceSpec(){return a||(a=w(s.deviceModel)),a},getA11yMode(){return s.a11yMode},setA11yMode(e){this.set("a11yMode",e)},getInspectMode(){return s.inspectMode},setInspectMode(e){this.set("inspectMode",e)}};export{L as a};
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{h as w,j as u,k as m,l}from"./chunk-H7EGEWCF.js";var p="sootsim:settings",v=["errorReporting","colorScheme","a11yMode","a11yDepth","screenshotCanvas","screenshotBackground","screenshotText","screenshotPose","screenshotDynamicSize","alwaysShowLiveWebViews","agentProvider","onboardingComplete","betaConsentVersion","detailedTelemetry"];function S(){if(typeof window>"u")return null;let e=window.sootsimElectron;return e&&typeof e=="object"?e:null}function g(e){let t={};for(let n of v){if(!(n in e))continue;let r=e[n],o=u[n];o.validate&&!o.validate(r)||o.options&&!o.options.includes(r)||(t[n]=r)}return t}function h(e){let t={};for(let n of v)t[n]=e[n];return t}function _(){if(typeof localStorage>"u")return{};try{let e=localStorage.getItem(p);return e?g(JSON.parse(e)):{}}catch{return{}}}function V(e){if(!(typeof localStorage>"u"))try{localStorage.setItem(p,JSON.stringify(h(e)))}catch{}}function E(){let t=S()?.sharedConfig?.settings;return!t||typeof t!="object"?{}:g(t)}function K(e){let t=S();if(t?.writeSharedConfig)try{t.writeSharedConfig({settings:h(e)})}catch{}}function b(){if(typeof window>"u")return null;let e=window.__sootsimSharedConfig;return e&&typeof e=="object"?e:null}function j(){let e=b()?.settings;return!e||typeof e!="object"?{}:g(e)}function D(e){if(!b())return;let t={settings:h(e)};try{if(globalThis.__sootsimBridgeRequest?.writeSharedConfig?.(t))return}catch{}if(!(typeof fetch>"u"))try{fetch("/__sootsim/shared-config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),keepalive:!0}).catch(()=>{})}catch{}}function k(){let e=_(),t=j(),n=E();return{...e,...t,...n}}function R(e){V(e),K(e),D(e)}function C(e){if(typeof window>"u")return()=>{};let t=i=>{if(!(i.key!==p||i.newValue==null))try{e(g(JSON.parse(i.newValue)))}catch{}};window.addEventListener("storage",t);let n=S(),r;n?.onSharedConfigChanged&&(r=n.onSharedConfigChanged(i=>{let d=i?.settings;!d||typeof d!="object"||e(g(d))}));let c=globalThis.__sootsimBridgeRequest?.subscribeSharedConfig?.(i=>{let d=i?.settings;!d||typeof d!="object"||e(g(d))});return()=>{window.removeEventListener("storage",t),r?.(),c?.()}}var M=l(),P=k();for(let e of Object.keys(m()))delete P[e];var s={...M,...P},f=[],a=null;function y(){for(let e of f)e();R(s)}C(e=>{let t={...s},n=!1;for(let[r,o]of Object.entries(e)){let c=r;t[c]!==o&&(t[c]=o,n=!0)}if(n){s=t,a=null;for(let r of f)r()}});var L={get(e){return s[e]},set(e,t){let n=u[e];n.validate&&!n.validate(t)||n.options&&!n.options.includes(t)||s[e]!==t&&(s={...s,[e]:t},e==="deviceModel"&&(a=null),y())},getAll(){return s},apply(e){let t=!1,n={...s};for(let[r,o]of Object.entries(e)){if(o===void 0)continue;let c=r,i=u[c];i&&(i.validate&&!i.validate(o)||i.options&&!i.options.includes(o)||n[c]!==o&&(n[c]=o,t=!0))}t&&(s=n,a=null,y())},reset(){s=l(),a=null,y()},subscribe(e){return f.push(e),()=>{f=f.filter(t=>t!==e)}},getDeviceSpec(){return a||(a=w(s.deviceModel)),a},getA11yMode(){return s.a11yMode},setA11yMode(e){this.set("a11yMode",e)},getInspectMode(){return s.inspectMode},setInspectMode(e){this.set("inspectMode",e)}};export{L as a};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as r}from"./chunk-TNEHHCMZ.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.SOOT_INSTALLATION_TOKEN?.trim(),t=process.env.GITHUB_TOKEN?.trim(),e=n||t;if(!d(e))return null;let o=(process.env.SOOT_REPO||process.env.GITHUB_REPOSITORY||"").trim();if(!o)return null;let[i,s]=o.includes("/")?o.split("/",2):[null,null],u=(process.env.SOOT_REPO_ID||process.env.GITHUB_REPOSITORY_ID||"").trim(),l=(process.env.SOOT_INSTALLATION_ID||process.env.GITHUB_APP_INSTALLATION_ID||"").trim();return{kind:"github",token:e,repoId:o,repositoryId:u||null,owner:i||null,repo:s||null,installationId:l||null,source:n?"soot-runner":"github-actions"}}function g(){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=r();return e?.token?{kind:"session",token:e.token,origin:e.origin}:null}function a(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{g as a,a as b,_ as c};
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as r}from"./chunk-VCLV5GYE.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.SOOT_INSTALLATION_TOKEN?.trim(),t=process.env.GITHUB_TOKEN?.trim(),e=n||t;if(!d(e))return null;let o=(process.env.SOOT_REPO||process.env.GITHUB_REPOSITORY||"").trim();if(!o)return null;let[i,s]=o.includes("/")?o.split("/",2):[null,null],u=(process.env.SOOT_REPO_ID||process.env.GITHUB_REPOSITORY_ID||"").trim(),l=(process.env.SOOT_INSTALLATION_ID||process.env.GITHUB_APP_INSTALLATION_ID||"").trim();return{kind:"github",token:e,repoId:o,repositoryId:u||null,owner:i||null,repo:s||null,installationId:l||null,source:n?"soot-runner":"github-actions"}}function g(){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=r();return e?.token?{kind:"session",token:e.token,origin:e.origin}:null}function a(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{g as a,a as b,_ as c};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.220 | (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,5 +1,5 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{b as ms}from"./chunk-EEUNNW2P.js";var hs={};ms(hs,{Alias:()=>ee,CST:()=>cs,Composer:()=>be,Document:()=>se,Lexer:()=>Be,LineCounter:()=>De,Pair:()=>v,Parser:()=>we,Scalar:()=>y,Schema:()=>ve,YAMLError:()=>_e,YAMLMap:()=>$,YAMLParseError:()=>R,YAMLSeq:()=>B,YAMLWarning:()=>Pe,isAlias:()=>F,isCollection:()=>L,isDocument:()=>x,isMap:()=>U,isNode:()=>I,isPair:()=>T,isScalar:()=>E,isSeq:()=>V,parse:()=>un,parseAllDocuments:()=>fn,parseDocument:()=>us,stringify:()=>hn,visit:()=>Q,visitAsync:()=>je});var tt=Symbol.for("yaml.alias"),st=Symbol.for("yaml.document"),Y=Symbol.for("yaml.map"),qt=Symbol.for("yaml.pair"),q=Symbol.for("yaml.scalar"),re=Symbol.for("yaml.seq"),K=Symbol.for("yaml.node.type"),F=s=>!!s&&typeof s=="object"&&s[K]===tt,x=s=>!!s&&typeof s=="object"&&s[K]===st,U=s=>!!s&&typeof s=="object"&&s[K]===Y,T=s=>!!s&&typeof s=="object"&&s[K]===qt,E=s=>!!s&&typeof s=="object"&&s[K]===q,V=s=>!!s&&typeof s=="object"&&s[K]===re;function L(s){if(s&&typeof s=="object")switch(s[K]){case Y:case re:return!0}return!1}function I(s){if(s&&typeof s=="object")switch(s[K]){case tt:case Y:case q:case re:return!0}return!1}var nt=s=>(E(s)||L(s))&&!!s.anchor;var j=Symbol("break visit"),ds=Symbol("skip children"),z=Symbol("remove node");function Q(s,e){let t=gs(e);x(s)?ke(null,s.contents,t,Object.freeze([s]))===z&&(s.contents=null):ke(null,s,t,Object.freeze([]))}Q.BREAK=j;Q.SKIP=ds;Q.REMOVE=z;function ke(s,e,t,n){let i=ys(s,e,t,n);if(I(i)||T(i))return bs(s,n,i),ke(s,i,t,n);if(typeof i!="symbol"){if(L(e)){n=Object.freeze(n.concat(e));for(let r=0;r<e.items.length;++r){let o=ke(r,e.items[r],t,n);if(typeof o=="number")r=o-1;else{if(o===j)return j;o===z&&(e.items.splice(r,1),r-=1)}}}else if(T(e)){n=Object.freeze(n.concat(e));let r=ke("key",e.key,t,n);if(r===j)return j;r===z&&(e.key=null);let o=ke("value",e.value,t,n);if(o===j)return j;o===z&&(e.value=null)}}return i}async function je(s,e){let t=gs(e);x(s)?await Ne(null,s.contents,t,Object.freeze([s]))===z&&(s.contents=null):await Ne(null,s,t,Object.freeze([]))}je.BREAK=j;je.SKIP=ds;je.REMOVE=z;async function Ne(s,e,t,n){let i=await ys(s,e,t,n);if(I(i)||T(i))return bs(s,n,i),Ne(s,i,t,n);if(typeof i!="symbol"){if(L(e)){n=Object.freeze(n.concat(e));for(let r=0;r<e.items.length;++r){let o=await Ne(r,e.items[r],t,n);if(typeof o=="number")r=o-1;else{if(o===j)return j;o===z&&(e.items.splice(r,1),r-=1)}}}else if(T(e)){n=Object.freeze(n.concat(e));let r=await Ne("key",e.key,t,n);if(r===j)return j;r===z&&(e.key=null);let o=await Ne("value",e.value,t,n);if(o===j)return j;o===z&&(e.value=null)}}return i}function gs(s){return typeof s=="object"&&(s.Collection||s.Node||s.Value)?Object.assign({Alias:s.Node,Map:s.Node,Scalar:s.Node,Seq:s.Node},s.Value&&{Map:s.Value,Scalar:s.Value,Seq:s.Value},s.Collection&&{Map:s.Collection,Seq:s.Collection},s):s}function ys(s,e,t,n){if(typeof t=="function")return t(s,e,n);if(U(e))return t.Map?.(s,e,n);if(V(e))return t.Seq?.(s,e,n);if(T(e))return t.Pair?.(s,e,n);if(E(e))return t.Scalar?.(s,e,n);if(F(e))return t.Alias?.(s,e,n)}function bs(s,e,t){let n=e[e.length-1];if(L(n))n.items[s]=t;else if(T(n))s==="key"?n.key=t:n.value=t;else if(x(n))n.contents=t;else{let i=F(n)?"alias":"scalar";throw new Error(`Cannot replace node with ${i} parent`)}}var pn={"!":"%21",",":"%2C","[":"%5B","]":"%5D","{":"%7B","}":"%7D"},mn=s=>s.replace(/[!,[\]{}]/g,e=>pn[e]),Z=class s{constructor(e,t){this.docStart=null,this.docEnd=!1,this.yaml=Object.assign({},s.defaultYaml,e),this.tags=Object.assign({},s.defaultTags,t)}clone(){let e=new s(this.yaml,this.tags);return e.docStart=this.docStart,e}atDocument(){let e=new s(this.yaml,this.tags);switch(this.yaml.version){case"1.1":this.atNextDocument=!0;break;case"1.2":this.atNextDocument=!1,this.yaml={explicit:s.defaultYaml.explicit,version:"1.2"},this.tags=Object.assign({},s.defaultTags);break}return e}add(e,t){this.atNextDocument&&(this.yaml={explicit:s.defaultYaml.explicit,version:"1.1"},this.tags=Object.assign({},s.defaultTags),this.atNextDocument=!1);let n=e.trim().split(/[ \t]+/),i=n.shift();switch(i){case"%TAG":{if(n.length!==2&&(t(0,"%TAG directive should contain exactly two parts"),n.length<2))return!1;let[r,o]=n;return this.tags[r]=o,!0}case"%YAML":{if(this.yaml.explicit=!0,n.length!==1)return t(0,"%YAML directive should contain exactly one part"),!1;let[r]=n;if(r==="1.1"||r==="1.2")return this.yaml.version=r,!0;{let o=/^\d+\.\d+$/.test(r);return t(6,`Unsupported YAML version ${r}`,o),!1}}default:return t(0,`Unknown directive ${i}`,!0),!1}}tagName(e,t){if(e==="!")return"!";if(e[0]!=="!")return t(`Not a valid tag: ${e}`),null;if(e[1]==="<"){let o=e.slice(2,-1);return o==="!"||o==="!!"?(t(`Verbatim tags aren't resolved, so ${e} is invalid.`),null):(e[e.length-1]!==">"&&t("Verbatim tags must end with a >"),o)}let[,n,i]=e.match(/^(.*!)([^!]*)$/s);i||t(`The ${e} tag has no suffix`);let r=this.tags[n];if(r)try{return r+decodeURIComponent(i)}catch(o){return t(String(o)),null}return n==="!"?e:(t(`Could not resolve tag: ${e}`),null)}tagString(e){for(let[t,n]of Object.entries(this.tags))if(e.startsWith(n))return t+mn(e.substring(n.length));return e[0]==="!"?e:`!<${e}>`}toString(e){let t=this.yaml.explicit?[`%YAML ${this.yaml.version||"1.2"}`]:[],n=Object.entries(this.tags),i;if(e&&n.length>0&&I(e.contents)){let r={};Q(e.contents,(o,l)=>{I(l)&&l.tag&&(r[l.tag]=!0)}),i=Object.keys(r)}else i=[];for(let[r,o]of n)r==="!!"&&o==="tag:yaml.org,2002:"||(!e||i.some(l=>l.startsWith(o)))&&t.push(`%TAG ${r} ${o}`);return t.join(`
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{b as ms}from"./chunk-S6XSCI45.js";var hs={};ms(hs,{Alias:()=>ee,CST:()=>cs,Composer:()=>be,Document:()=>se,Lexer:()=>Be,LineCounter:()=>De,Pair:()=>v,Parser:()=>we,Scalar:()=>y,Schema:()=>ve,YAMLError:()=>_e,YAMLMap:()=>$,YAMLParseError:()=>R,YAMLSeq:()=>B,YAMLWarning:()=>Pe,isAlias:()=>F,isCollection:()=>L,isDocument:()=>x,isMap:()=>U,isNode:()=>I,isPair:()=>T,isScalar:()=>E,isSeq:()=>V,parse:()=>un,parseAllDocuments:()=>fn,parseDocument:()=>us,stringify:()=>hn,visit:()=>Q,visitAsync:()=>je});var tt=Symbol.for("yaml.alias"),st=Symbol.for("yaml.document"),Y=Symbol.for("yaml.map"),qt=Symbol.for("yaml.pair"),q=Symbol.for("yaml.scalar"),re=Symbol.for("yaml.seq"),K=Symbol.for("yaml.node.type"),F=s=>!!s&&typeof s=="object"&&s[K]===tt,x=s=>!!s&&typeof s=="object"&&s[K]===st,U=s=>!!s&&typeof s=="object"&&s[K]===Y,T=s=>!!s&&typeof s=="object"&&s[K]===qt,E=s=>!!s&&typeof s=="object"&&s[K]===q,V=s=>!!s&&typeof s=="object"&&s[K]===re;function L(s){if(s&&typeof s=="object")switch(s[K]){case Y:case re:return!0}return!1}function I(s){if(s&&typeof s=="object")switch(s[K]){case tt:case Y:case q:case re:return!0}return!1}var nt=s=>(E(s)||L(s))&&!!s.anchor;var j=Symbol("break visit"),ds=Symbol("skip children"),z=Symbol("remove node");function Q(s,e){let t=gs(e);x(s)?ke(null,s.contents,t,Object.freeze([s]))===z&&(s.contents=null):ke(null,s,t,Object.freeze([]))}Q.BREAK=j;Q.SKIP=ds;Q.REMOVE=z;function ke(s,e,t,n){let i=ys(s,e,t,n);if(I(i)||T(i))return bs(s,n,i),ke(s,i,t,n);if(typeof i!="symbol"){if(L(e)){n=Object.freeze(n.concat(e));for(let r=0;r<e.items.length;++r){let o=ke(r,e.items[r],t,n);if(typeof o=="number")r=o-1;else{if(o===j)return j;o===z&&(e.items.splice(r,1),r-=1)}}}else if(T(e)){n=Object.freeze(n.concat(e));let r=ke("key",e.key,t,n);if(r===j)return j;r===z&&(e.key=null);let o=ke("value",e.value,t,n);if(o===j)return j;o===z&&(e.value=null)}}return i}async function je(s,e){let t=gs(e);x(s)?await Ne(null,s.contents,t,Object.freeze([s]))===z&&(s.contents=null):await Ne(null,s,t,Object.freeze([]))}je.BREAK=j;je.SKIP=ds;je.REMOVE=z;async function Ne(s,e,t,n){let i=await ys(s,e,t,n);if(I(i)||T(i))return bs(s,n,i),Ne(s,i,t,n);if(typeof i!="symbol"){if(L(e)){n=Object.freeze(n.concat(e));for(let r=0;r<e.items.length;++r){let o=await Ne(r,e.items[r],t,n);if(typeof o=="number")r=o-1;else{if(o===j)return j;o===z&&(e.items.splice(r,1),r-=1)}}}else if(T(e)){n=Object.freeze(n.concat(e));let r=await Ne("key",e.key,t,n);if(r===j)return j;r===z&&(e.key=null);let o=await Ne("value",e.value,t,n);if(o===j)return j;o===z&&(e.value=null)}}return i}function gs(s){return typeof s=="object"&&(s.Collection||s.Node||s.Value)?Object.assign({Alias:s.Node,Map:s.Node,Scalar:s.Node,Seq:s.Node},s.Value&&{Map:s.Value,Scalar:s.Value,Seq:s.Value},s.Collection&&{Map:s.Collection,Seq:s.Collection},s):s}function ys(s,e,t,n){if(typeof t=="function")return t(s,e,n);if(U(e))return t.Map?.(s,e,n);if(V(e))return t.Seq?.(s,e,n);if(T(e))return t.Pair?.(s,e,n);if(E(e))return t.Scalar?.(s,e,n);if(F(e))return t.Alias?.(s,e,n)}function bs(s,e,t){let n=e[e.length-1];if(L(n))n.items[s]=t;else if(T(n))s==="key"?n.key=t:n.value=t;else if(x(n))n.contents=t;else{let i=F(n)?"alias":"scalar";throw new Error(`Cannot replace node with ${i} parent`)}}var pn={"!":"%21",",":"%2C","[":"%5B","]":"%5D","{":"%7B","}":"%7D"},mn=s=>s.replace(/[!,[\]{}]/g,e=>pn[e]),Z=class s{constructor(e,t){this.docStart=null,this.docEnd=!1,this.yaml=Object.assign({},s.defaultYaml,e),this.tags=Object.assign({},s.defaultTags,t)}clone(){let e=new s(this.yaml,this.tags);return e.docStart=this.docStart,e}atDocument(){let e=new s(this.yaml,this.tags);switch(this.yaml.version){case"1.1":this.atNextDocument=!0;break;case"1.2":this.atNextDocument=!1,this.yaml={explicit:s.defaultYaml.explicit,version:"1.2"},this.tags=Object.assign({},s.defaultTags);break}return e}add(e,t){this.atNextDocument&&(this.yaml={explicit:s.defaultYaml.explicit,version:"1.1"},this.tags=Object.assign({},s.defaultTags),this.atNextDocument=!1);let n=e.trim().split(/[ \t]+/),i=n.shift();switch(i){case"%TAG":{if(n.length!==2&&(t(0,"%TAG directive should contain exactly two parts"),n.length<2))return!1;let[r,o]=n;return this.tags[r]=o,!0}case"%YAML":{if(this.yaml.explicit=!0,n.length!==1)return t(0,"%YAML directive should contain exactly one part"),!1;let[r]=n;if(r==="1.1"||r==="1.2")return this.yaml.version=r,!0;{let o=/^\d+\.\d+$/.test(r);return t(6,`Unsupported YAML version ${r}`,o),!1}}default:return t(0,`Unknown directive ${i}`,!0),!1}}tagName(e,t){if(e==="!")return"!";if(e[0]!=="!")return t(`Not a valid tag: ${e}`),null;if(e[1]==="<"){let o=e.slice(2,-1);return o==="!"||o==="!!"?(t(`Verbatim tags aren't resolved, so ${e} is invalid.`),null):(e[e.length-1]!==">"&&t("Verbatim tags must end with a >"),o)}let[,n,i]=e.match(/^(.*!)([^!]*)$/s);i||t(`The ${e} tag has no suffix`);let r=this.tags[n];if(r)try{return r+decodeURIComponent(i)}catch(o){return t(String(o)),null}return n==="!"?e:(t(`Could not resolve tag: ${e}`),null)}tagString(e){for(let[t,n]of Object.entries(this.tags))if(e.startsWith(n))return t+mn(e.substring(n.length));return e[0]==="!"?e:`!<${e}>`}toString(e){let t=this.yaml.explicit?[`%YAML ${this.yaml.version||"1.2"}`]:[],n=Object.entries(this.tags),i;if(e&&n.length>0&&I(e.contents)){let r={};Q(e.contents,(o,l)=>{I(l)&&l.tag&&(r[l.tag]=!0)}),i=Object.keys(r)}else i=[];for(let[r,o]of n)r==="!!"&&o==="tag:yaml.org,2002:"||(!e||i.some(l=>l.startsWith(o)))&&t.push(`%TAG ${r} ${o}`);return t.join(`
3
3
  `)}};Z.defaultYaml={explicit:!1,version:"1.2"};Z.defaultTags={"!!":"tag:yaml.org,2002:"};function it(s){if(/[\x00-\x19\s,[\]{}]/.test(s)){let t=`Anchor must not contain whitespace or control characters: ${JSON.stringify(s)}`;throw new Error(t)}return!0}function Rt(s){let e=new Set;return Q(s,{Value(t,n){n.anchor&&e.add(n.anchor)}}),e}function Ft(s,e){for(let t=1;;++t){let n=`${s}${t}`;if(!e.has(n))return n}}function ws(s,e){let t=[],n=new Map,i=null;return{onAnchor:r=>{t.push(r),i??(i=Rt(s));let o=Ft(e,i);return i.add(o),o},setAnchors:()=>{for(let r of t){let o=n.get(r);if(typeof o=="object"&&o.anchor&&(E(o.node)||L(o.node)))o.node.anchor=o.anchor;else{let l=new Error("Failed to resolve repeated object (this should not happen)");throw l.source=r,l}}},sourceObjects:n}}function fe(s,e,t,n){if(n&&typeof n=="object")if(Array.isArray(n))for(let i=0,r=n.length;i<r;++i){let o=n[i],l=fe(s,n,String(i),o);l===void 0?delete n[i]:l!==o&&(n[i]=l)}else if(n instanceof Map)for(let i of Array.from(n.keys())){let r=n.get(i),o=fe(s,n,i,r);o===void 0?n.delete(i):o!==r&&n.set(i,o)}else if(n instanceof Set)for(let i of Array.from(n)){let r=fe(s,n,i,i);r===void 0?n.delete(i):r!==i&&(n.delete(i),n.add(r))}else for(let[i,r]of Object.entries(n)){let o=fe(s,n,i,r);o===void 0?delete n[i]:o!==r&&(n[i]=o)}return s.call(e,t,n)}function M(s,e,t){if(Array.isArray(s))return s.map((n,i)=>M(n,String(i),t));if(s&&typeof s.toJSON=="function"){if(!t||!nt(s))return s.toJSON(e,t);let n={aliasCount:0,count:1,res:void 0};t.anchors.set(s,n),t.onCreate=r=>{n.res=r,delete t.onCreate};let i=s.toJSON(e,t);return t.onCreate&&t.onCreate(i),i}return typeof s=="bigint"&&!t?.keep?Number(s):s}var ue=class{constructor(e){Object.defineProperty(this,K,{value:e})}clone(){let e=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return this.range&&(e.range=this.range.slice()),e}toJS(e,{mapAsMap:t,maxAliasCount:n,onAnchor:i,reviver:r}={}){if(!x(e))throw new TypeError("A document argument is required");let o={anchors:new Map,doc:e,keep:!0,mapAsMap:t===!0,mapKeyWarned:!1,maxAliasCount:typeof n=="number"?n:100},l=M(this,"",o);if(typeof i=="function")for(let{count:a,res:c}of o.anchors.values())i(c,a);return typeof r=="function"?fe(r,{"":l},"",l):l}};var ee=class extends ue{constructor(e){super(tt),this.source=e,Object.defineProperty(this,"tag",{set(){throw new Error("Alias nodes cannot have tags")}})}resolve(e,t){if(t?.maxAliasCount===0)throw new ReferenceError("Alias resolution is disabled");let n;t?.aliasResolveCache?n=t.aliasResolveCache:(n=[],Q(e,{Node:(r,o)=>{(F(o)||nt(o))&&n.push(o)}}),t&&(t.aliasResolveCache=n));let i;for(let r of n){if(r===this)break;r.anchor===this.source&&(i=r)}return i}toJSON(e,t){if(!t)return{source:this.source};let{anchors:n,doc:i,maxAliasCount:r}=t,o=this.resolve(i,t);if(!o){let a=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new ReferenceError(a)}let l=n.get(o);if(l||(M(o,null,t),l=n.get(o)),l?.res===void 0){let a="This should not happen: Alias anchor was not resolved?";throw new ReferenceError(a)}if(r>=0&&(l.count+=1,l.aliasCount===0&&(l.aliasCount=rt(i,o,n)),l.count*l.aliasCount>r)){let a="Excessive alias count indicates a resource exhaustion attack";throw new ReferenceError(a)}return l.res}toString(e,t,n){let i=`*${this.source}`;if(e){if(it(this.source),e.options.verifyAliasOrder&&!e.anchors.has(this.source)){let r=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new Error(r)}if(e.implicitKey)return`${i} `}return i}};function rt(s,e,t){if(F(e)){let n=e.resolve(s),i=t&&n&&t.get(n);return i?i.count*i.aliasCount:0}else if(L(e)){let n=0;for(let i of e.items){let r=rt(s,i,t);r>n&&(n=r)}return n}else if(T(e)){let n=rt(s,e.key,t),i=rt(s,e.value,t);return Math.max(n,i)}return 1}var ot=s=>!s||typeof s!="function"&&typeof s!="object",y=class extends ue{constructor(e){super(q),this.value=e}toJSON(e,t){return t?.keep?this.value:M(this.value,e,t)}toString(){return String(this.value)}};y.BLOCK_FOLDED="BLOCK_FOLDED";y.BLOCK_LITERAL="BLOCK_LITERAL";y.PLAIN="PLAIN";y.QUOTE_DOUBLE="QUOTE_DOUBLE";y.QUOTE_SINGLE="QUOTE_SINGLE";var dn="tag:yaml.org,2002:";function gn(s,e,t){if(e){let n=t.filter(r=>r.tag===e),i=n.find(r=>!r.format)??n[0];if(!i)throw new Error(`Tag ${e} not found`);return i}return t.find(n=>n.identify?.(s)&&!n.format)}function oe(s,e,t){if(x(s)&&(s=s.contents),I(s))return s;if(T(s)){let f=t.schema[Y].createNode?.(t.schema,null,t);return f.items.push(s),f}(s instanceof String||s instanceof Number||s instanceof Boolean||typeof BigInt<"u"&&s instanceof BigInt)&&(s=s.valueOf());let{aliasDuplicateObjects:n,onAnchor:i,onTagObj:r,schema:o,sourceObjects:l}=t,a;if(n&&s&&typeof s=="object"){if(a=l.get(s),a)return a.anchor??(a.anchor=i(s)),new ee(a.anchor);a={anchor:null,node:null},l.set(s,a)}e?.startsWith("!!")&&(e=dn+e.slice(2));let c=gn(s,e,o.tags);if(!c){if(s&&typeof s.toJSON=="function"&&(s=s.toJSON()),!s||typeof s!="object"){let f=new y(s);return a&&(a.node=f),f}c=s instanceof Map?o[Y]:Symbol.iterator in Object(s)?o[re]:o[Y]}r&&(r(c),delete t.onTagObj);let p=c?.createNode?c.createNode(t.schema,s,t):typeof c?.nodeClass?.from=="function"?c.nodeClass.from(t.schema,s,t):new y(s);return e?p.tag=e:c.default||(p.tag=c.tag),a&&(a.node=p),p}function qe(s,e,t){let n=t;for(let i=e.length-1;i>=0;--i){let r=e[i];if(typeof r=="number"&&Number.isInteger(r)&&r>=0){let o=[];o[r]=n,n=o}else n=new Map([[r,n]])}return oe(n,void 0,{aliasDuplicateObjects:!1,keepUndefined:!1,onAnchor:()=>{throw new Error("This should not happen, please report a bug.")},schema:s,sourceObjects:new Map})}var Ae=s=>s==null||typeof s=="object"&&!!s[Symbol.iterator]().next().done,Oe=class extends ue{constructor(e,t){super(e),Object.defineProperty(this,"schema",{value:t,configurable:!0,enumerable:!1,writable:!0})}clone(e){let t=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return e&&(t.schema=e),t.items=t.items.map(n=>I(n)||T(n)?n.clone(e):n),this.range&&(t.range=this.range.slice()),t}addIn(e,t){if(Ae(e))this.add(t);else{let[n,...i]=e,r=this.get(n,!0);if(L(r))r.addIn(i,t);else if(r===void 0&&this.schema)this.set(n,qe(this.schema,i,t));else throw new Error(`Expected YAML collection at ${n}. Remaining path: ${i}`)}}deleteIn(e){let[t,...n]=e;if(n.length===0)return this.delete(t);let i=this.get(t,!0);if(L(i))return i.deleteIn(n);throw new Error(`Expected YAML collection at ${t}. Remaining path: ${n}`)}getIn(e,t){let[n,...i]=e,r=this.get(n,!0);return i.length===0?!t&&E(r)?r.value:r:L(r)?r.getIn(i,t):void 0}hasAllNullValues(e){return this.items.every(t=>{if(!T(t))return!1;let n=t.value;return n==null||e&&E(n)&&n.value==null&&!n.commentBefore&&!n.comment&&!n.tag})}hasIn(e){let[t,...n]=e;if(n.length===0)return this.has(t);let i=this.get(t,!0);return L(i)?i.hasIn(n):!1}setIn(e,t){let[n,...i]=e;if(i.length===0)this.set(n,t);else{let r=this.get(n,!0);if(L(r))r.setIn(i,t);else if(r===void 0&&this.schema)this.set(n,qe(this.schema,i,t));else throw new Error(`Expected YAML collection at ${n}. Remaining path: ${i}`)}}};var Ss=s=>s.replace(/^(?!$)(?: $)?/gm,"#");function J(s,e){return/^\n+$/.test(s)?s.substring(1):e?s.replace(/^(?! *$)/gm,e):s}var te=(s,e,t)=>s.endsWith(`
4
4
  `)?J(t,e):t.includes(`
5
5
  `)?`
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var o=!0,e="public beta",t=e,n="we send anonymous error and dependency data while you use it";export{o as a,e as b,t as c,n as d};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as x}from"./chunk-F5H6XTMN.js";import{a as k}from"./chunk-2HJU3NAO.js";import{spawn as v,spawnSync as u}from"child_process";import{chmodSync as S,copyFileSync as T,createWriteStream as E,existsSync as w,mkdirSync as y,rmSync as g,statSync as P,unlinkSync as D}from"fs";import{tmpdir as M}from"os";import{dirname as A,join as f,resolve as b}from"path";var h="https://sootbean.com/api/electron-release";function O(){let n=process.arch;if(process.platform==="darwin"){let o=n==="arm64"?"mac-arm64":"mac-x64",e=`sootsim-latest-${o}.dmg`;return{platform:o,filename:e,url:`${h}/${e}`,install:L}}if(process.platform==="linux"){let o=n==="arm64"?"linux-arm64":"linux-x64",e=`sootsim-latest-${o}.AppImage`;return{platform:o,filename:e,url:`${h}/${e}`,install:C}}if(process.platform==="win32"){let o="sootsim-latest-win-x64.exe";return{platform:"win-x64",filename:o,url:`${h}/${o}`,install:B}}return null}async function I({url:n,dest:o,onProgress:e}){let s=await fetch(n,{redirect:"follow"});if(!s.ok)throw new Error(`${s.status} ${s.statusText} (${n})`);let t=s.headers.get("content-length"),a=t?Number(t):null;if(!s.body)throw new Error(`empty response body (${n})`);y(A(o),{recursive:!0});let i=E(o),d=s.body.getReader(),c=0;try{for(;;){let{done:l,value:p}=await d.read();if(l)break;i.write(Buffer.from(p)),c+=p.byteLength,e?.(c,a)}}finally{await new Promise((l,p)=>{i.end(r=>r?p(r):l())})}}function _(n,o){let e=(n/1048576).toFixed(1);if(!o)return` ${e} MB`;let s=Math.min(100,Math.round(n/o*100)),t=(o/(1024*1024)).toFixed(1),a=24,i=Math.round(s/100*a);return` ${"\u2588".repeat(i)+"\u2591".repeat(a-i)} ${s}% ${e} / ${t} MB`}async function L(n){let o=u("hdiutil",["attach","-nobrowse","-readonly",n],{encoding:"utf8"});if(o.status!==0)throw new Error(`hdiutil attach failed: ${o.stderr||o.stdout}`.trim());let e=o.stdout.trim().split(`
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as x}from"./chunk-GBALEYV4.js";import{a as k}from"./chunk-XHPOQKUA.js";import{spawn as v,spawnSync as u}from"child_process";import{chmodSync as S,copyFileSync as T,createWriteStream as E,existsSync as w,mkdirSync as y,rmSync as g,statSync as P,unlinkSync as D}from"fs";import{tmpdir as M}from"os";import{dirname as A,join as f,resolve as b}from"path";var h="https://sootbean.com/api/electron-release";function O(){let n=process.arch;if(process.platform==="darwin"){let o=n==="arm64"?"mac-arm64":"mac-x64",e=`sootsim-latest-${o}.dmg`;return{platform:o,filename:e,url:`${h}/${e}`,install:L}}if(process.platform==="linux"){let o=n==="arm64"?"linux-arm64":"linux-x64",e=`sootsim-latest-${o}.AppImage`;return{platform:o,filename:e,url:`${h}/${e}`,install:C}}if(process.platform==="win32"){let o="sootsim-latest-win-x64.exe";return{platform:"win-x64",filename:o,url:`${h}/${o}`,install:B}}return null}async function I({url:n,dest:o,onProgress:e}){let s=await fetch(n,{redirect:"follow"});if(!s.ok)throw new Error(`${s.status} ${s.statusText} (${n})`);let t=s.headers.get("content-length"),a=t?Number(t):null;if(!s.body)throw new Error(`empty response body (${n})`);y(A(o),{recursive:!0});let i=E(o),d=s.body.getReader(),c=0;try{for(;;){let{done:l,value:p}=await d.read();if(l)break;i.write(Buffer.from(p)),c+=p.byteLength,e?.(c,a)}}finally{await new Promise((l,p)=>{i.end(r=>r?p(r):l())})}}function _(n,o){let e=(n/1048576).toFixed(1);if(!o)return` ${e} MB`;let s=Math.min(100,Math.round(n/o*100)),t=(o/(1024*1024)).toFixed(1),a=24,i=Math.round(s/100*a);return` ${"\u2588".repeat(i)+"\u2591".repeat(a-i)} ${s}% ${e} / ${t} MB`}async function L(n){let o=u("hdiutil",["attach","-nobrowse","-readonly",n],{encoding:"utf8"});if(o.status!==0)throw new Error(`hdiutil attach failed: ${o.stderr||o.stdout}`.trim());let e=o.stdout.trim().split(`
3
3
  `),t=e[e.length-1].split(" ").pop()?.trim();if(!t||!w(t))throw new Error(`could not determine dmg mount point (output: ${o.stdout})`);let a=f(t,"sootsim.app");if(!w(a))throw u("hdiutil",["detach","-force",t]),new Error(`sootsim.app not found inside ${t}`);let i="/Applications",d=b(process.env.HOME||"","Applications"),c=i;try{let m=f(i,`.sootsim-write-probe-${process.pid}`);u("touch",[m]),w(m)?g(m,{force:!0}):c=d}catch{c=d}c===d&&y(c,{recursive:!0});let l=f(c,"sootsim.app");w(l)&&g(l,{recursive:!0,force:!0});let p=u("cp",["-R",a,l]),r=u("hdiutil",["detach","-force",t]);if(p.status!==0)throw new Error(`copy to ${l} failed: ${p.stderr?.toString()||""}`.trim());return r.status!==0&&console.warn(` warning: failed to unmount ${t} (${r.stderr?.toString().trim()||"unknown error"})`),u("xattr",["-dr","com.apple.quarantine",l]),l}async function C(n){let o=b(process.env.HOME||"","Applications");y(o,{recursive:!0});let e=f(o,"sootsim.AppImage");return w(e)&&g(e,{force:!0}),T(n,e),D(n),S(e,493),e}async function B(n){return await new Promise((o,e)=>{let s=v("cmd",["/c","start",'""',"/wait",n],{stdio:"inherit"});s.once("error",e),s.once("exit",t=>{t===0?o():e(new Error(`installer exited with code ${t}`))})}),n}async function q(n){(n.includes("--help")||n.includes("-h"))&&(console.log(`
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=n.includes("--yes")||n.includes("-y")||process.env.SOOTSIM_NO_PROMPT==="1"||process.env.CI==="1"||!process.stdin.isTTY,e=n.includes("--force"),s=k();if(s&&!e){console.log(` sootsim desktop already installed at: ${s.path}`),console.log(" pass --force to reinstall.");return}let t=O();if(t||(console.error(` no desktop build available for ${process.platform}/${process.arch}.`),console.error(" supported: darwin-arm64, darwin-x64, linux-x64, linux-arm64, win32-x64"),process.exit(1)),console.log(` platform: ${t.platform}`),console.log(` download: ${t.url}`),console.log(),!o){if(!await x("download and install now?",!0)){console.log(" cancelled.");return}console.log()}let a=f(M(),`sootsim-install-${Date.now()}`),i=f(a,t.filename),d=0;process.stdout.write(` downloading ${t.filename}...
21
21
  `);try{await I({url:t.url,dest:i,onProgress:(r,m)=>{let $=Date.now();$-d<100&&r<(m??1/0)||(d=$,process.stdout.isTTY&&process.stdout.write(`\r\x1B[2K${_(r,m)}`))}})}catch(r){g(a,{recursive:!0,force:!0});let m=r instanceof Error?r.message:String(r);console.error(`
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-AKRLP3AR.js");try{let r=await t.install(i);l({event:"cli_install_desktop_succeeded",properties:{platform:t.platform,size_bytes:c}}),console.log(` installed: ${r}`)}catch(r){l({event:"cli_install_desktop_failed",properties:{platform:t.platform,error:r instanceof Error?r.message:String(r)}}),await p(),console.error(` install failed: ${r instanceof Error?r.message:String(r)}`),console.error(` keeping download at ${i} for manual install.`),process.exit(1)}finally{g(a,{recursive:!0,force:!0})}console.log(),console.log(" next steps:"),console.log(" sootsim desktop launch the desktop app"),console.log(" sootsim open <target> open a demo or bundle in it")}export{q as a};
23
+ `);let c=P(i).size;console.log(` downloaded ${(c/(1024*1024)).toFixed(1)} MB`),console.log(),console.log(" installing...");let{trackCliEvent:l,flushCliTelemetry:p}=await import("./telemetry-OFJVUJ34.js");try{let r=await t.install(i);l({event:"cli_install_desktop_succeeded",properties:{platform:t.platform,size_bytes:c}}),console.log(` installed: ${r}`)}catch(r){l({event:"cli_install_desktop_failed",properties:{platform:t.platform,error:r instanceof Error?r.message:String(r)}}),await p(),console.error(` install failed: ${r instanceof Error?r.message:String(r)}`),console.error(` keeping download at ${i} for manual install.`),process.exit(1)}finally{g(a,{recursive:!0,force:!0})}console.log(),console.log(" next steps:"),console.log(" sootsim desktop launch the desktop app"),console.log(" sootsim open <target> open a demo or bundle in it")}export{q as a};
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.220 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  function C(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 w=new Set(["tap","double-tap","tap-text","tap-id","long-press","touch"]);function S(t){return typeof t=="string"&&w.has(t)}async function v(t){return await t.send({type:"evaluate",code:"window.__sootsimEngineState?.inspectActive === true"})===!0}async function H(t,e){if(!S(e))return!1;try{return await v(t)}catch{return!1}}async function W(t){let e=await t.send({type:"evaluate",code:"(async () => await window.__sootsimTest.getNodeCount())()"});return{nodes:typeof e=="number"?e:0}}async function B(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 F(t){let e=await t.send({type:"evaluate",code:"window.location.href"});return{url:typeof e=="string"?e:""}}async function j(t,e){let r=`(async () => {
3
3
  const t = window.__sootsimTest
4
4
  const mainShell = window.SootSim?.bridges?.mainShell
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.220 | (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};