sootsim 0.1.118 → 0.1.119

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist-cli/bin.js +3 -3
  2. package/dist-cli/chunks/{agent-NJPQWWOB.js → agent-HMYFFW3K.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-XY2KLHD5.js → agent-wrapper-L5TRN5OW.js} +2 -2
  4. package/dist-cli/chunks/{app-fonts-VVWZHR3V.js → app-fonts-G5L5BPHX.js} +2 -2
  5. package/dist-cli/chunks/{assert-WCZYRGGS.js → assert-MN4TCTKK.js} +2 -2
  6. package/dist-cli/chunks/auto-bootstrap-QJ5PP7KT.js +2 -0
  7. package/dist-cli/chunks/beta-LAPRQ3TP.js +2 -0
  8. package/dist-cli/chunks/{chunk-SCAOPMDY.js → chunk-3MWC6EE2.js} +2 -2
  9. package/dist-cli/chunks/{chunk-WYQOR72S.js → chunk-475TNRB7.js} +2 -2
  10. package/dist-cli/chunks/{chunk-FXARAPTS.js → chunk-47SB3JEW.js} +3 -3
  11. package/dist-cli/chunks/{chunk-4YCHWQKG.js → chunk-4EQ5V4CA.js} +1 -1
  12. package/dist-cli/chunks/{chunk-BJGF7NGV.js → chunk-4KU7AIP7.js} +1 -1
  13. package/dist-cli/chunks/chunk-5AL4WWUG.js +1 -0
  14. package/dist-cli/chunks/{chunk-EGAVQVNQ.js → chunk-5OZHLK4L.js} +2 -2
  15. package/dist-cli/chunks/{chunk-XEWSIOAB.js → chunk-APWX6YCC.js} +2 -2
  16. package/dist-cli/chunks/{chunk-UPSFFGWI.js → chunk-AUKEEPZT.js} +1 -1
  17. package/dist-cli/chunks/{chunk-FPUW7ZDL.js → chunk-AV6YDPVF.js} +2 -2
  18. package/dist-cli/chunks/{chunk-QDBFZQ2P.js → chunk-BBLE5DMP.js} +1 -1
  19. package/dist-cli/chunks/{chunk-3OU23VHJ.js → chunk-BZH7FKZZ.js} +73 -12
  20. package/dist-cli/chunks/{chunk-5YSLVAQO.js → chunk-C3VO2MSV.js} +2 -2
  21. package/dist-cli/chunks/{chunk-2KH3XP25.js → chunk-CHHBZJBH.js} +1 -1
  22. package/dist-cli/chunks/{chunk-W3XLQMHS.js → chunk-DE6JMHEW.js} +2 -2
  23. package/dist-cli/chunks/{chunk-VCYQZSOW.js → chunk-EIAYJLBW.js} +2 -2
  24. package/dist-cli/chunks/{chunk-MAFA2R2B.js → chunk-FCRJNHIA.js} +1 -1
  25. package/dist-cli/chunks/{chunk-WGFN4X7U.js → chunk-FUUXRMXG.js} +2 -2
  26. package/dist-cli/chunks/{chunk-QK5KDLOL.js → chunk-GEPWAAGG.js} +2 -2
  27. package/dist-cli/chunks/{chunk-A3RAHXFP.js → chunk-H4F45EGT.js} +2 -2
  28. package/dist-cli/chunks/{chunk-RRGMPOCZ.js → chunk-HPTOFA3Y.js} +3 -3
  29. package/dist-cli/chunks/chunk-IKVDJYRI.js +2 -0
  30. package/dist-cli/chunks/{chunk-YW6R4AZS.js → chunk-J6UPVQ37.js} +2 -2
  31. package/dist-cli/chunks/{chunk-5PU4UF46.js → chunk-JFHETXYV.js} +1 -1
  32. package/dist-cli/chunks/{chunk-WETDSNVK.js → chunk-JP3PNWTD.js} +1 -1
  33. package/dist-cli/chunks/{chunk-QBRJUGX4.js → chunk-LB7BYFMF.js} +2 -2
  34. package/dist-cli/chunks/{chunk-UFM5KZV5.js → chunk-MJQXUHDS.js} +2 -2
  35. package/dist-cli/chunks/{chunk-2R6ISGHK.js → chunk-MNILEOSP.js} +1 -1
  36. package/dist-cli/chunks/{chunk-L2353XE5.js → chunk-O552XDE7.js} +2 -2
  37. package/dist-cli/chunks/{chunk-U6CXSNU5.js → chunk-O7SJH4E7.js} +2 -2
  38. package/dist-cli/chunks/{chunk-UNGEGYXQ.js → chunk-OS62SSOF.js} +2 -2
  39. package/dist-cli/chunks/{chunk-LP46VFFE.js → chunk-QMU4MAG3.js} +1 -1
  40. package/dist-cli/chunks/{chunk-GJB3233O.js → chunk-RAWQNHKI.js} +1 -1
  41. package/dist-cli/chunks/{chunk-6YPNZR54.js → chunk-RF2STDGD.js} +2 -2
  42. package/dist-cli/chunks/chunk-RIMNMM3O.js +1 -0
  43. package/dist-cli/chunks/{chunk-JSIQX4RC.js → chunk-SSQWBV2F.js} +2 -2
  44. package/dist-cli/chunks/{chunk-IIPXHHCA.js → chunk-TGLPBQ4D.js} +2 -2
  45. package/dist-cli/chunks/{chunk-JH3UHLET.js → chunk-TUJWNKG4.js} +1 -1
  46. package/dist-cli/chunks/{chunk-GF3PTYUG.js → chunk-WNK5XRWG.js} +2 -2
  47. package/dist-cli/chunks/{chunk-PC6MD7KR.js → chunk-XYT2OO4N.js} +2 -2
  48. package/dist-cli/chunks/{chunk-D2HFLNQK.js → chunk-YBRJSW5C.js} +3 -3
  49. package/dist-cli/chunks/chunk-YPLXVVG4.js +1 -0
  50. package/dist-cli/chunks/{chunk-N6A3DLGD.js → chunk-YZ6MQTDJ.js} +2 -2
  51. package/dist-cli/chunks/{chunk-SLBI37WD.js → chunk-ZX4FJNIW.js} +1 -1
  52. package/dist-cli/chunks/cli-version-JKOW3OL3.js +2 -0
  53. package/dist-cli/chunks/{compat-3RY7MNRD.js → compat-3C3O2TKY.js} +3 -3
  54. package/dist-cli/chunks/{config-3B4KNHNB.js → config-TEO7DXWJ.js} +2 -2
  55. package/dist-cli/chunks/control-UUSQA7VO.js +2 -0
  56. package/dist-cli/chunks/{cpu-profile-ZH2TY3EB.js → cpu-profile-QSFGY7HA.js} +2 -2
  57. package/dist-cli/chunks/{daemon-IUAIVTIM.js → daemon-R2TQX4HR.js} +2 -2
  58. package/dist-cli/chunks/{debug-BEFVOWIO.js → debug-UMLASBX2.js} +3 -3
  59. package/dist-cli/chunks/{detox-HPNYBEKZ.js → detox-Y6TFEKQU.js} +2 -2
  60. package/dist-cli/chunks/{device-ZBDEEYN6.js → device-4NBQC4LP.js} +2 -2
  61. package/dist-cli/chunks/{diagnose-D5CLXJP7.js → diagnose-DKXPE4P6.js} +2 -2
  62. package/dist-cli/chunks/drivers-TFUZRRDZ.js +2 -0
  63. package/dist-cli/chunks/{electron-HDDFR27N.js → electron-3AZTVV3N.js} +3 -3
  64. package/dist-cli/chunks/flow-744L27RP.js +2 -0
  65. package/dist-cli/chunks/help-JUP3UEFR.js +2 -0
  66. package/dist-cli/chunks/{hints-NOGPSCHT.js → hints-K323Q4NQ.js} +2 -2
  67. package/dist-cli/chunks/{home-paths-IQNPKC6L.js → home-paths-H7GUBJAB.js} +2 -2
  68. package/dist-cli/chunks/{inspect-EGBGTKVK.js → inspect-UJFYMPE5.js} +52 -51
  69. package/dist-cli/chunks/install-D5J5LA2V.js +2 -0
  70. package/dist-cli/chunks/{install-desktop-SVGXW4NS.js → install-desktop-NT5QJIPD.js} +3 -3
  71. package/dist-cli/chunks/{keys-6ZOTMI56.js → keys-OJVAQQK5.js} +2 -2
  72. package/dist-cli/chunks/{launch-IQGYTPQM.js → launch-VMMQENF6.js} +3 -3
  73. package/dist-cli/chunks/{login-J4U23Q3R.js → login-CRJE2OZK.js} +4 -4
  74. package/dist-cli/chunks/{logout-H6K35NLA.js → logout-3DXVRPLM.js} +2 -2
  75. package/dist-cli/chunks/{maestro-QO2LITVQ.js → maestro-FPDCZ3NO.js} +2 -2
  76. package/dist-cli/chunks/{preview-Q4W6QO7P.js → preview-7WLF767D.js} +2 -2
  77. package/dist-cli/chunks/{profile-2QJPFSDY.js → profile-DE5LJZ5Y.js} +2 -2
  78. package/dist-cli/chunks/{react-DXK7ST5T.js → react-HLRPZFFH.js} +2 -2
  79. package/dist-cli/chunks/{record-UG6W5IME.js → record-VQAG2YYZ.js} +2 -2
  80. package/dist-cli/chunks/runtime-LBAJOT4M.js +2 -0
  81. package/dist-cli/chunks/{runtime-delivery-RAZ445Y5.js → runtime-delivery-O2WD2RT6.js} +2 -2
  82. package/dist-cli/chunks/{screenshot-Q44UHEGZ.js → screenshot-HYSJVWYN.js} +2 -2
  83. package/dist-cli/chunks/{screenshot-mode-I2TYYAON.js → screenshot-mode-ME7WKY7S.js} +2 -2
  84. package/dist-cli/chunks/{screenshots-GGLAOVD7.js → screenshots-5MY3SHOW.js} +2 -2
  85. package/dist-cli/chunks/{server-3IPGETBZ.js → server-LRSX4VKM.js} +2 -2
  86. package/dist-cli/chunks/setup-repo-5FHT7B6J.js +2 -0
  87. package/dist-cli/chunks/{skills-BCFKQBDG.js → skills-SHJHDYYU.js} +2 -2
  88. package/dist-cli/chunks/{start-WVYUD6CH.js → start-FBIHKRWV.js} +4 -4
  89. package/dist-cli/chunks/store-ZSAUNVP6.js +2 -0
  90. package/dist-cli/chunks/telemetry-E2ZAX2C6.js +2 -0
  91. package/dist-cli/chunks/{test-ZATFIL25.js → test-W5VLOO6C.js} +3 -3
  92. package/dist-cli/chunks/{three-mode-B7MYORNU.js → three-mode-OILRSRAU.js} +2 -2
  93. package/dist-cli/chunks/{timeline-SDEOHHGZ.js → timeline-H4SFNSBA.js} +2 -2
  94. package/dist-cli/chunks/{upgrade-MMU63PN3.js → upgrade-4SYAHMAP.js} +2 -2
  95. package/dist-cli/chunks/upload-NPGWC7E5.js +2 -0
  96. package/dist-cli/chunks/{web-BXAEFDAJ.js → web-UXTXQNYW.js} +2 -2
  97. package/dist-cli/chunks/{what-happened-7PASTCPU.js → what-happened-SNC6DEIJ.js} +2 -2
  98. package/dist-cli/chunks/{whoami-26VWXEUX.js → whoami-QDFN5LHP.js} +2 -2
  99. package/dist-lib/agent-daemon-client.cjs +1 -1
  100. package/dist-lib/agent-events.cjs +1 -1
  101. package/dist-lib/agent-sessions.cjs +1 -1
  102. package/dist-lib/attached-projects.cjs +1 -1
  103. package/dist-lib/auth/shared-session.cjs +1 -1
  104. package/dist-lib/backend-origin.cjs +1 -1
  105. package/dist-lib/beta.cjs +1 -1
  106. package/dist-lib/beta.mjs +1 -1
  107. package/dist-lib/bridge-constants.cjs +1 -1
  108. package/dist-lib/cli-constants.cjs +1 -1
  109. package/dist-lib/config.cjs +1 -1
  110. package/dist-lib/detox/index.cjs +1 -1
  111. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  112. package/dist-lib/home-paths.cjs +1 -1
  113. package/dist-lib/host/bridge-host.cjs +1 -1
  114. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  115. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  116. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  117. package/dist-lib/host/websocket-proxy.cjs +1 -1
  118. package/dist-lib/index.cjs +1 -1
  119. package/dist-lib/metro.cjs +1 -1
  120. package/dist-lib/profiles.cjs +1 -1
  121. package/dist-lib/render-mode.cjs +1 -1
  122. package/dist-lib/scripts/demo-app-registry.cjs +1 -1
  123. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  124. package/dist-lib/sdk.cjs +92 -1
  125. package/dist-lib/sdk.mjs +89 -1
  126. package/dist-lib/skills.cjs +1 -1
  127. package/dist-lib/vite.cjs +1 -1
  128. package/package.json +1 -1
  129. package/dist-cli/chunks/auto-bootstrap-4T7P2AEZ.js +0 -2
  130. package/dist-cli/chunks/beta-XPL4OA73.js +0 -2
  131. package/dist-cli/chunks/chunk-2TJIYYD6.js +0 -1
  132. package/dist-cli/chunks/chunk-JAR6ZK7S.js +0 -2
  133. package/dist-cli/chunks/chunk-JWC43Q7G.js +0 -1
  134. package/dist-cli/chunks/chunk-RHTOXVIQ.js +0 -1
  135. package/dist-cli/chunks/cli-version-5RR6YSLC.js +0 -2
  136. package/dist-cli/chunks/control-NE52GBD2.js +0 -2
  137. package/dist-cli/chunks/drivers-GTB2MH7E.js +0 -2
  138. package/dist-cli/chunks/flow-QYL7HHKN.js +0 -2
  139. package/dist-cli/chunks/help-LMXH2UHV.js +0 -2
  140. package/dist-cli/chunks/install-Q2JJJBNC.js +0 -2
  141. package/dist-cli/chunks/runtime-72QZY6P4.js +0 -2
  142. package/dist-cli/chunks/setup-repo-UR2N2LUC.js +0 -2
  143. package/dist-cli/chunks/store-7NUGDP6M.js +0 -2
  144. package/dist-cli/chunks/telemetry-PXZEDDM5.js +0 -2
  145. package/dist-cli/chunks/upload-SLNXXIBH.js +0 -2
@@ -1,6 +1,6 @@
1
- /*! sootsim v0.1.118 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6ISGHK.js";import{a as Ke,h as we,k as ee}from"./chunk-SCAOPMDY.js";import{b as bt,c as wt,j as xt}from"./chunk-YW6R4AZS.js";import"./chunk-EGAVQVNQ.js";import{a as Z,b as R,c as E,d as Ae,e as re,f as Y,g as be,h as me,i as pt,j as ft,k as Oe,l as gt}from"./chunk-UNGEGYXQ.js";import{B as dt,D as le,E as ut,K as mt,a as he,b as ze,c as Ye,d as Ge,e as Xe,f as Ve,g as Qe,h as Ze,i as Ne,j as Fe,n as _e,o as et,p as tt,q as ot,r as st,s as nt,t as rt,u as it,v as at,w as lt,x as ct}from"./chunk-3OU23VHJ.js";import"./chunk-A3RAHXFP.js";import{c as We,e as qe,f as He,g as Ue,h as Ie}from"./chunk-GF3PTYUG.js";import"./chunk-5YSLVAQO.js";import"./chunk-WETDSNVK.js";import"./chunk-JWC43Q7G.js";import"./chunk-IIPXHHCA.js";import"./chunk-2KH3XP25.js";import{b as Le}from"./chunk-GJB3233O.js";import{a as je}from"./chunk-BJGF7NGV.js";import{a as Te,c as Me}from"./chunk-PC6MD7KR.js";import{a as Je}from"./chunk-JAR6ZK7S.js";import"./chunk-LP46VFFE.js";import"./chunk-SLBI37WD.js";import"./chunk-UPSFFGWI.js";import{existsSync as ro,mkdirSync as io,readFileSync as ao,rmSync as $t,writeFileSync as lo}from"fs";import{tmpdir as co}from"os";import{dirname as uo,join as mo,resolve as po}from"path";var pe=1,fo="SOOTSIM_INSPECT_NOTICE_PATH",go=300*1e3,yo=15e3;function St(){return po(process.env[fo]||mo(co(),"sootsim-inspect-notice-state.json"))}function ho(e,c){return Object.fromEntries(Object.entries(e).filter(([,n])=>typeof n?.signature=="string"&&Number.isFinite(n?.updatedAt)&&c-n.updatedAt<=go))}function bo(e){let c=St();if(!ro(c))return{version:pe,entries:{}};try{let n=JSON.parse(ao(c,"utf8"));return n.version!==pe||!n.entries||typeof n.entries!="object"?($t(c,{force:!0}),{version:pe,entries:{}}):{version:pe,entries:ho(n.entries,e)}}catch{return $t(c,{force:!0}),{version:pe,entries:{}}}}function wo(e){let c=St();io(uo(c),{recursive:!0}),lo(c,JSON.stringify(e,null,2)+`
3
- `)}function xo(e,c){let n=c.trim()||"default";return`${e}:${n}`}function Pe(e,c,n,l={}){let m=l.nowMs??Date.now(),a=l.cooldownMs??yo,g=bo(m),y=xo(e,c),T=g.entries[y];return T&&T.signature===n&&m-T.updatedAt<a?!1:(g.entries[y]={signature:n,updatedAt:m},wo(g),!0)}var $o={initialWaitMs:3e3,deadlineMs:5e3,retryWaitMs:700},So={initialWaitMs:1200,deadlineMs:2500,retryWaitMs:700};function vo(e,c={}){return{...e?$o:So,...c}}function ce(e){return!(!e||e.hit===!1||e.ok===!1||e.pointerTapHandled===!1&&!e.keyboardOpened&&!e.isTextInput)}function ko(e,c){return{id:e.target?.id??e.match?.id??e.node?.id??null,testID:e.target?.testID??e.match?.testID??e.node?.testID??null,text:e.target?.text??e.target?.accessibilityLabel??e.match?.text??e.match?.accessibilityLabel??e.node?.text??c??null,type:e.target?.type??e.match?.type??e.node?.type??null}}async function fe(e,c){let n=vo(!!c.agent,c.timing),l=0,m=null,a=null;try{await ee({bridge:e,maxMs:n.initialWaitMs,pollMs:32,stablePolls:2})}catch{}let g=Date.now()+n.deadlineMs;for(;Date.now()<=g||l===0;){l++;let y=await c.resolve();if(m=y,y?.error==="bridge-not-ready"||y?.ambiguous||y?.nthOutOfRange)return{payload:y,result:null,attempts:l,failure:"special"};if(y&&typeof y.cx=="number"&&typeof y.cy=="number"){let M=await e.send({type:"tap",x:y.cx,y:y.cy,target:ko(y,c.textFallback)});if(a=M,ce(M))return{payload:y,result:M,attempts:l}}let T=g-Date.now();if(T<=0)break;try{await ee({bridge:e,maxMs:Math.min(T,n.retryWaitMs),pollMs:32,stablePolls:2})}catch{await new Promise(M=>setTimeout(M,Math.min(120,T)))}}return{payload:m,result:a,attempts:l,failure:m&&typeof m.cx=="number"?"missed":"not-found"}}async function vt(e,c,n,l){return e.send({type:"tap",x:c,y:n,...l?{target:l}:{}})}async function kt(e,c,n={}){let l=JSON.stringify(c);return fe(e,{agent:n.agent,timing:n.timing,resolve:()=>e.send({type:"evaluate",code:`(async () => {
1
+ /*! sootsim v0.1.119 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as G}from"./chunk-MJQXUHDS.js";import{a as bt,b as wt}from"./chunk-MNILEOSP.js";import{a as Ke,h as we,k as ee}from"./chunk-3MWC6EE2.js";import{b as xt,c as $t,j as St}from"./chunk-J6UPVQ37.js";import"./chunk-5OZHLK4L.js";import{a as Z,b as A,c as P,d as Oe,e as re,f as Y,g as ce,h as pe,i as gt,j as yt,k as Ae,l as ht}from"./chunk-OS62SSOF.js";import{D as mt,F as le,G as pt,M as ft,a as be,b as ze,c as Ye,d as Ge,e as Xe,f as Ve,g as Qe,h as Ze,i as et,j as tt,k as Ne,l as Fe,p as _e,q as ot,r as st,s as nt,t as rt,u as it,v as at,w as lt,x as ct,y as dt,z as ut}from"./chunk-BZH7FKZZ.js";import"./chunk-H4F45EGT.js";import{c as We,e as qe,f as He,g as Ue,h as Ie}from"./chunk-WNK5XRWG.js";import"./chunk-C3VO2MSV.js";import"./chunk-JP3PNWTD.js";import"./chunk-RIMNMM3O.js";import"./chunk-TGLPBQ4D.js";import"./chunk-CHHBZJBH.js";import{b as Le}from"./chunk-RAWQNHKI.js";import{a as je}from"./chunk-4KU7AIP7.js";import{a as Te,c as Me}from"./chunk-XYT2OO4N.js";import{a as Je}from"./chunk-IKVDJYRI.js";import"./chunk-QMU4MAG3.js";import"./chunk-ZX4FJNIW.js";import"./chunk-AUKEEPZT.js";import{existsSync as lo,mkdirSync as co,readFileSync as uo,rmSync as vt,writeFileSync as mo}from"fs";import{tmpdir as po}from"os";import{dirname as fo,join as go,resolve as yo}from"path";var fe=1,ho="SOOTSIM_INSPECT_NOTICE_PATH",bo=300*1e3,wo=15e3;function kt(){return yo(process.env[ho]||go(po(),"sootsim-inspect-notice-state.json"))}function xo(e,c){return Object.fromEntries(Object.entries(e).filter(([,n])=>typeof n?.signature=="string"&&Number.isFinite(n?.updatedAt)&&c-n.updatedAt<=bo))}function $o(e){let c=kt();if(!lo(c))return{version:fe,entries:{}};try{let n=JSON.parse(uo(c,"utf8"));return n.version!==fe||!n.entries||typeof n.entries!="object"?(vt(c,{force:!0}),{version:fe,entries:{}}):{version:fe,entries:xo(n.entries,e)}}catch{return vt(c,{force:!0}),{version:fe,entries:{}}}}function So(e){let c=kt();co(fo(c),{recursive:!0}),mo(c,JSON.stringify(e,null,2)+`
3
+ `)}function vo(e,c){let n=c.trim()||"default";return`${e}:${n}`}function Pe(e,c,n,l={}){let m=l.nowMs??Date.now(),a=l.cooldownMs??wo,g=$o(m),y=vo(e,c),T=g.entries[y];return T&&T.signature===n&&m-T.updatedAt<a?!1:(g.entries[y]={signature:n,updatedAt:m},So(g),!0)}var ko={initialWaitMs:3e3,deadlineMs:5e3,retryWaitMs:700},To={initialWaitMs:1200,deadlineMs:2500,retryWaitMs:700};function Mo(e,c={}){return{...e?ko:To,...c}}function de(e){return!(!e||e.hit===!1||e.ok===!1||e.pointerTapHandled===!1&&!e.keyboardOpened&&!e.isTextInput)}function Io(e,c){return{id:e.target?.id??e.match?.id??e.node?.id??null,testID:e.target?.testID??e.match?.testID??e.node?.testID??null,text:e.target?.text??e.target?.accessibilityLabel??e.match?.text??e.match?.accessibilityLabel??e.node?.text??c??null,type:e.target?.type??e.match?.type??e.node?.type??null}}async function ge(e,c){let n=Mo(!!c.agent,c.timing),l=0,m=null,a=null;try{await ee({bridge:e,maxMs:n.initialWaitMs,pollMs:32,stablePolls:2})}catch{}let g=Date.now()+n.deadlineMs;for(;Date.now()<=g||l===0;){l++;let y=await c.resolve();if(m=y,y?.error==="bridge-not-ready"||y?.ambiguous||y?.nthOutOfRange)return{payload:y,result:null,attempts:l,failure:"special"};if(y&&typeof y.cx=="number"&&typeof y.cy=="number"){let M=await e.send({type:"tap",x:y.cx,y:y.cy,target:Io(y,c.textFallback)});if(a=M,de(M))return{payload:y,result:M,attempts:l}}let T=g-Date.now();if(T<=0)break;try{await ee({bridge:e,maxMs:Math.min(T,n.retryWaitMs),pollMs:32,stablePolls:2})}catch{await new Promise(M=>setTimeout(M,Math.min(120,T)))}}return{payload:m,result:a,attempts:l,failure:m&&typeof m.cx=="number"?"missed":"not-found"}}async function Tt(e,c,n,l){return e.send({type:"tap",x:c,y:n,...l?{target:l}:{}})}async function Mt(e,c,n={}){let l=JSON.stringify(c);return ge(e,{agent:n.agent,timing:n.timing,resolve:()=>e.send({type:"evaluate",code:`(async () => {
4
4
  const t = window.__sootsimTest
5
5
  if (!t) return null
6
6
  const n = (await t.findByTestId(${l})) || (await t.findById(${l}))
@@ -42,7 +42,7 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
42
42
  },
43
43
  strategy: (resolved && resolved.strategy) || 'matched-node',
44
44
  }
45
- })()`})})}async function Tt(e,c,n={},l={}){let m=JSON.stringify({query:c,exact:!!n.exact,role:n.role??null,within:n.within??null,minX:n.minX??null,maxX:n.maxX??null,minY:n.minY??null,maxY:n.maxY??null,near:n.near??null,nth:n.nth??null,first:!!n.first});return fe(e,{agent:l.agent,timing:l.timing,textFallback:c,resolve:()=>e.send({type:"evaluate",code:`(async () => {
45
+ })()`})})}async function It(e,c,n={},l={}){let m=JSON.stringify({query:c,exact:!!n.exact,role:n.role??null,within:n.within??null,minX:n.minX??null,maxX:n.maxX??null,minY:n.minY??null,maxY:n.maxY??null,near:n.near??null,nth:n.nth??null,first:!!n.first});return ge(e,{agent:l.agent,timing:l.timing,textFallback:c,resolve:()=>e.send({type:"evaluate",code:`(async () => {
46
46
  const t = window.__sootsimTest
47
47
  if (!t) return { error: 'bridge-not-ready' }
48
48
  const F = ${m}
@@ -162,7 +162,7 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
162
162
  total,
163
163
  idx,
164
164
  }
165
- })()`})})}async function Mt(e,c,n={}){let l=JSON.stringify(c);return fe(e,{agent:n.agent,timing:n.timing,textFallback:c,resolve:async()=>{let m=await e.send({type:"evaluate",code:`(async () => {
165
+ })()`})})}async function Nt(e,c,n={}){let l=JSON.stringify(c);return ge(e,{agent:n.agent,timing:n.timing,textFallback:c,resolve:async()=>{let m=await e.send({type:"evaluate",code:`(async () => {
166
166
  const t = window.__sootsimTest
167
167
  if (!t) return { error: 'bridge-not-ready' }
168
168
  const byTestId =
@@ -197,15 +197,16 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
197
197
  }
198
198
  }
199
199
  return { strategy: 'none' }
200
- })()`});if(!m||!("node"in m))return m;let a=m.node,g=a.absolutePosition.x+a.layout.width/2,y=a.absolutePosition.y+a.layout.height/2;return{...m,cx:g,cy:y,target:{id:a.id,testID:a.testID,text:m.strategy==="text"?c:a.text,type:a.type}}}})}async function It(e,c={args:[]}){let n=await Ye(e);if(R(c.args)){E(n);return}console.log(` nodes: ${n.nodes}`)}function Re(e,c){let n=e.indexOf(c);return n>=0&&n+1<e.length?e[n+1]:null}async function Nt(e){let{bridge:c,args:n,positional:l}=e,m=n.includes("--verbose")||n.includes("-v"),a=R(n),g=m&&!a,y=n.includes("--watch")||n.includes("-w"),T=1e3,M=n.includes("--compact"),h=n.includes("--no-xy"),k=n.includes("--no-clipped"),_=n.includes("--include-occluded"),I=Re(n,"--testid-like"),O=Re(n,"--only"),j=Re(n,"--subtree"),d=l[1]&&!l[1].startsWith("-")?l[1]:void 0,z=d?/[*?]/.test(d):!1,B=!z&&!O?d:void 0,C=O??(z?d:void 0),V=async()=>{await be(c,{verbose:g});let S=await Ve(c,{describe:!0,verbose:m,filter:B||"",testIdLike:I||void 0,onlyGlob:C||void 0,subtreeRoot:j||void 0,compact:M,hideXy:h,includeOccluded:_}),N=S?.tree,L=S?.shell,W=S?.keyboard;if(a){E({shell:L,tree:N??"",keyboard:W});return}if(L&&typeof L=="object"){let D=[L.state?`state=${L.state}`:null,L.activeApp?`app=${L.activeApp}`:null,L.showSwitcher?"switcher":null,L.switcherPhase&&L.switcherPhase!=="idle"?`phase=${L.switcherPhase}`:null].filter(Boolean);D.length>0&&console.log(` shell: ${D.join(" ")}`)}if(typeof N=="string"&&N.startsWith("__SUBTREE_NOT_FOUND__:")){let D=N.slice(22);console.log(` subtree root not found: ${D}`),G("subtree-root-not-found",D);return}if(!N){let D=S?.nodeCount??0;console.log(" no matching nodes found"),!(B||I||C||j)&&D<10&&G("app-still-loading",D);return}let X=N,Q=0;if(k&&typeof X=="string"){let D=X.split(`
200
+ })()`});if(!m||!("node"in m))return m;let a=m.node,g=a.absolutePosition.x+a.layout.width/2,y=a.absolutePosition.y+a.layout.height/2;return{...m,cx:g,cy:y,target:{id:a.id,testID:a.testID,text:m.strategy==="text"?c:a.text,type:a.type}}}})}async function Ft(e,c={args:[]}){let n=await Ye(e);if(A(c.args)){P(n);return}console.log(` nodes: ${n.nodes}`)}function Re(e,c){let n=e.indexOf(c);return n>=0&&n+1<e.length?e[n+1]:null}async function _t(e){let{bridge:c,args:n,positional:l}=e,m=n.includes("--verbose")||n.includes("-v"),a=A(n),g=m&&!a,y=n.includes("--watch")||n.includes("-w"),T=1e3,M=n.includes("--compact"),h=n.includes("--no-xy"),k=n.includes("--no-clipped"),_=n.includes("--include-occluded"),I=Re(n,"--testid-like"),R=Re(n,"--only"),j=Re(n,"--subtree"),d=l[1]&&!l[1].startsWith("-")?l[1]:void 0,z=d?/[*?]/.test(d):!1,B=!z&&!R?d:void 0,C=R??(z?d:void 0),V=async()=>{await ce(c,{verbose:g});let S=await Ve(c,{describe:!0,verbose:m,filter:B||"",testIdLike:I||void 0,onlyGlob:C||void 0,subtreeRoot:j||void 0,compact:M,hideXy:h,includeOccluded:_}),N=S?.tree,L=S?.shell,W=S?.keyboard;if(a){P({shell:L,tree:N??"",keyboard:W});return}if(L&&typeof L=="object"){let D=[L.state?`state=${L.state}`:null,L.activeApp?`app=${L.activeApp}`:null,L.showSwitcher?"switcher":null,L.switcherPhase&&L.switcherPhase!=="idle"?`phase=${L.switcherPhase}`:null].filter(Boolean);D.length>0&&console.log(` shell: ${D.join(" ")}`)}if(typeof N=="string"&&N.startsWith("__SUBTREE_NOT_FOUND__:")){let D=N.slice(22);console.log(` subtree root not found: ${D}`),G("subtree-root-not-found",D);return}if(!N){let D=S?.nodeCount??0;console.log(" no matching nodes found"),!(B||I||C||j)&&D<10&&G("app-still-loading",D);return}let X=N,Q=0;if(k&&typeof X=="string"){let D=X.split(`
201
201
  `),ae=[];for(let o of D){if(o.includes("(clipped:")){Q+=1;continue}ae.push(o)}X=ae.join(`
202
202
  `)}console.log(X),Q>0&&console.log(` ${Q} clipped row(s) hidden (omit --no-clipped to see)`);let ne=B||I||C||j;if((B||I||C)&&!y&&G("describe-filter-context"),!ne&&!y&&N.split(`
203
203
  `).length>=80&&G("describe-use-filters"),W&&W.visible){let D=W.spec,ae=[D?.keyboardType?`type=${D.keyboardType}`:null,D?.returnKeyType&&D.returnKeyType!=="default"?`return=${D.returnKeyType}`:null,W.mode!=="letters"?`mode=${W.mode}`:null,W.shifted?"shift":null,W.capsLock?"caps":null,D?.autoCapitalize&&D.autoCapitalize!=="sentences"?`autoCap=${D.autoCapitalize}`:null,W.accessoryBarId?`accessory=${W.accessoryBarId}`:null].filter(Boolean);console.log(`
204
204
  keyboard: ${ae.join(" ")||"visible"}`)}};if(y)for(console.log(` watching... (Ctrl+C to stop)
205
- `);;)console.clear(),await V(),await Z(T);else await V()}var To=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function de(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let e of To){let c=process.env[e];if(c&&c.trim()&&c!=="0")return!0}return!1}async function Ft(e){let{bridge:c,args:n,effectiveArgs:l,positional:m,inspectUsage:a}=e,g=S=>{let N=l.indexOf(S);return N>=0&&N+1<l.length?l[N+1]:null},y=S=>l.includes(S),T=g("--testid")||g("--test-id"),M=g("--role"),h=g("--type"),k=g("--text"),_=y("--pressable"),I=y("--visible"),O=y("--interactive-targets")||y("--actions"),j=!T&&!M&&!h&&!k&&!_&&!I&&!O?m[1]:null,d=k??j,z=await Ze(c,{testId:T,role:M,type:h,text:d,pressable:_,visible:I,interactive:O});z||(console.error(a("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:B,result:C}=z,V=R(n),te=n.includes("--verbose")||n.includes("--dump");if(V)B==="interactive-targets"&&Array.isArray(C)?E(Ne(C).map(S=>({...S,tap:Fe(S)}))):E(C??null);else if(Array.isArray(C))if(C.length===0){console.log(` no ${B} nodes found`);let S=await c.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof S=="number"&&S<10&&G("app-still-loading",S)}else if(B==="interactive-targets"){let S=Ne(C);console.log(` found ${S.length} interactive target${S.length===1?"":"s"} (sorted by score):`);for(let N of S.slice(0,20)){let L=N.absolutePosition?`@(${Math.round(N.absolutePosition.x)},${Math.round(N.absolutePosition.y)})`:"",W=N.layout?`${Math.round(N.layout.width)}x${Math.round(N.layout.height)}`:"?x?",X=N.text?` "${N.text.slice(0,30)}"`:"",Q=N.testID?` #${N.testID}`:"",ne=N.accessibilityLabel?` \u24D8"${String(N.accessibilityLabel).slice(0,24)}"`:"",ue=N.accessibilityRole?`[${N.accessibilityRole}]`:N.type,D=Fe(N);console.log(` ${ue}${X}${ne}${Q} ${W} ${L}`),console.log(` \u2192 ${D}`),te&&console.log(Ee(JSON.stringify(N,null,2)," "))}S.length>20&&console.log(` ... and ${S.length-20} more`)}else{console.log(` found ${C.length} node${C.length===1?"":"s"} (${B}):`);for(let S of C.slice(0,20)){let N=S.absolutePosition?`@(${Math.round(S.absolutePosition.x)},${Math.round(S.absolutePosition.y)})`:"",L=S.layout?`${Math.round(S.layout.width)}x${Math.round(S.layout.height)}`:"?x?",W=S.text?` "${S.text.slice(0,30)}"`:"",X=S.testID?` #${S.testID}`:"",Q=S.pressable?" (tap)":"",ne=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${ne}${W}${X} ${L} ${N}${Q}`),te&&console.log(Ee(JSON.stringify(S,null,2)," "))}C.length>20&&console.log(` ... and ${C.length-20} more`)}else if(C==null)console.log(` not found: ${d||T||M||h||""||B}`),T&&G("wait-selector-for-missing-testid",T);else{let S=C;if(S.type&&S.absolutePosition){let N=`@(${Math.round(S.absolutePosition.x)},${Math.round(S.absolutePosition.y)})`,L=S.layout?`${Math.round(S.layout.width)}x${Math.round(S.layout.height)}`:"?x?",W=S.text?` "${S.text.slice(0,40)}"`:"",X=S.testID?` #${S.testID}`:"",Q=S.pressable?" (tap)":"",ne=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${ne}${W}${X} ${L} ${N}${Q}`),te&&console.log(Ee(JSON.stringify(S,null,2)," "))}else console.log(JSON.stringify(C,null,2))}}function Ee(e,c){return e.split(`
205
+ `);;)console.clear(),await V(),await Z(T);else await V()}var No=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function ue(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let e of No){let c=process.env[e];if(c&&c.trim()&&c!=="0")return!0}return!1}async function Ot(e){let{bridge:c,args:n,effectiveArgs:l,positional:m,inspectUsage:a}=e,g=S=>{let N=l.indexOf(S);return N>=0&&N+1<l.length?l[N+1]:null},y=S=>l.includes(S),T=g("--testid")||g("--test-id"),M=g("--role"),h=g("--type"),k=g("--text"),_=y("--pressable"),I=y("--visible"),R=y("--interactive-targets")||y("--actions"),j=!T&&!M&&!h&&!k&&!_&&!I&&!R?m[1]:null,d=k??j,z=await tt(c,{testId:T,role:M,type:h,text:d,pressable:_,visible:I,interactive:R});z||(console.error(a("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:B,result:C}=z,V=A(n),te=n.includes("--verbose")||n.includes("--dump");if(V)B==="interactive-targets"&&Array.isArray(C)?P(Ne(C).map(S=>({...S,tap:Fe(S)}))):P(C??null);else if(Array.isArray(C))if(C.length===0){console.log(` no ${B} nodes found`);let S=await c.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof S=="number"&&S<10&&G("app-still-loading",S)}else if(B==="interactive-targets"){let S=Ne(C);console.log(` found ${S.length} interactive target${S.length===1?"":"s"} (sorted by score):`);for(let N of S.slice(0,20)){let L=N.absolutePosition?`@(${Math.round(N.absolutePosition.x)},${Math.round(N.absolutePosition.y)})`:"",W=N.layout?`${Math.round(N.layout.width)}x${Math.round(N.layout.height)}`:"?x?",X=N.text?` "${N.text.slice(0,30)}"`:"",Q=N.testID?` #${N.testID}`:"",ne=N.accessibilityLabel?` \u24D8"${String(N.accessibilityLabel).slice(0,24)}"`:"",me=N.accessibilityRole?`[${N.accessibilityRole}]`:N.type,D=Fe(N);console.log(` ${me}${X}${ne}${Q} ${W} ${L}`),console.log(` \u2192 ${D}`),te&&console.log(Ee(JSON.stringify(N,null,2)," "))}S.length>20&&console.log(` ... and ${S.length-20} more`)}else{console.log(` found ${C.length} node${C.length===1?"":"s"} (${B}):`);for(let S of C.slice(0,20)){let N=S.absolutePosition?`@(${Math.round(S.absolutePosition.x)},${Math.round(S.absolutePosition.y)})`:"",L=S.layout?`${Math.round(S.layout.width)}x${Math.round(S.layout.height)}`:"?x?",W=S.text?` "${S.text.slice(0,30)}"`:"",X=S.testID?` #${S.testID}`:"",Q=S.pressable?" (tap)":"",ne=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${ne}${W}${X} ${L} ${N}${Q}`),te&&console.log(Ee(JSON.stringify(S,null,2)," "))}C.length>20&&console.log(` ... and ${C.length-20} more`)}else if(C==null)console.log(` not found: ${d||T||M||h||""||B}`),T&&G("wait-selector-for-missing-testid",T);else{let S=C;if(S.type&&S.absolutePosition){let N=`@(${Math.round(S.absolutePosition.x)},${Math.round(S.absolutePosition.y)})`,L=S.layout?`${Math.round(S.layout.width)}x${Math.round(S.layout.height)}`:"?x?",W=S.text?` "${S.text.slice(0,40)}"`:"",X=S.testID?` #${S.testID}`:"",Q=S.pressable?" (tap)":"",ne=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${ne}${W}${X} ${L} ${N}${Q}`),te&&console.log(Ee(JSON.stringify(S,null,2)," "))}else console.log(JSON.stringify(C,null,2))}}function Ee(e,c){return e.split(`
206
206
  `).map(n=>c+n).join(`
207
- `)}async function _t(e,c={}){let n=await dt(e);if("error"in n&&(console.error(n.error),process.exit(1)),c.json){console.log(JSON.stringify(n,null,2));return}let{visible:l,spec:m,mode:a,shifted:g,capsLock:y,accessoryBarId:T}=n,M=[];M.push(`keyboard: ${l?"visible":"hidden"}`),m?(M.push(` type: ${m.keyboardType}`),M.push(` returnKey: ${m.returnKeyType}`),M.push(` autoCap: ${m.autoCapitalize}`),M.push(` autoCorrect: ${m.autoCorrect?"on":"off"}`),M.push(` appearance: ${m.keyboardAppearance}`),m.secureTextEntry&&M.push(" secureTextEntry: true"),m.enablesReturnKeyAutomatically&&M.push(` return: ${m.currentTextIsEmpty?"disabled (empty)":"enabled"}`)):M.push(" spec: <none> (shown via dev-tools with no TextInput)"),M.push(` mode: ${a}${g?" (shifted)":""}${y?" (caps)":""}`),T&&M.push(` accessoryBar: ${T}`),console.log(M.join(`
208
- `))}async function At(e){let c=await e.bridge.listSims(),n=e.args.includes("--all"),l=e.args.find((y,T)=>e.args[T-1]==="--bundle"),m=e.args.find((y,T)=>e.args[T-1]==="--app-port"),a=e.args.includes("--primary"),g=c.filter(y=>!(a&&!y.isPrimary||l&&!(y.url??"").includes(l)||m&&!(y.url??"").includes(`/rn/${m}`)||!n&&!l&&!m&&!a&&!(y.url&&(y.url.includes("bundle=")||y.url.includes("/index.bundle")))&&y.id!==e.simId));if(R(e.args)){E(g.map(y=>({...y,active:y.id===e.simId})));return}xt(g,e.simId),g.length<c.length&&!R(e.args)&&console.log(` (${c.length-g.length} more hidden \u2014 pass --all to show)`)}function ie(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/1024/1024).toFixed(1)}MB`}function xe(e,c){return c<=0?"?":`${(e/c*100).toFixed(0)}%`}async function Ot(e,c={args:[]}){let n=await mt(e);if(R(c.args)){E(n);return}if(console.log(" memory:"),n.imageLoader){let l=n.imageLoader;console.log(" image-loader cache"),console.log(` entries: ${l.cacheEntries} / ${l.cacheMaxEntries} (${xe(l.cacheEntries,l.cacheMaxEntries)})`),console.log(` pixel bytes: ${ie(l.cachePixelBytes)} / ${ie(l.cachePixelBudget)} (${xe(l.cachePixelBytes,l.cachePixelBudget)})`),console.log(` pending: ${l.pendingFetches} fetches, ${l.pendingBytes} bytes`),console.log(` failed uris: ${l.failedUris}`),console.log(` snapshots: ${l.snapshots}`),console.log(` camera frames: ${l.cameraFrames}`)}else console.log(" image-loader cache: not available (engine pre-rebuild?)");if(n.workerHeap){let l=n.workerHeap;console.log(" worker heap (chrome only)"),console.log(` used: ${ie(l.usedJSHeapSize)} / ${ie(l.jsHeapSizeLimit)} (${xe(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${ie(l.totalJSHeapSize)}`)}if(n.hostHeap){let l=n.hostHeap;console.log(" host heap (chrome only)"),console.log(` used: ${ie(l.usedJSHeapSize)} / ${ie(l.jsHeapSizeLimit)} (${xe(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${ie(l.totalJSHeapSize)}`)}}function ge(e){let c=e.indexOf("--testid");if(c>=0&&e[c+1])return{mode:"testid",value:e[c+1]};let n=e.indexOf("--test-id");if(n>=0&&e[n+1])return{mode:"testid",value:e[n+1]};let l=e.indexOf("--text");return l>=0&&e[l+1]?{mode:"text",value:e[l+1]}:null}async function $e(e,c){let n=JSON.stringify(c.value),l=c.mode==="testid"?`(await t.findByTestId(${n})) || (await t.findById(${n}))`:`await t.findByText(${n})`;return await e.send({type:"evaluate",code:`(async () => {
207
+ `)}async function At(e){let{bridge:c,args:n}=e,l=A(n);await ce(c,{verbose:!l});let m=await Qe(c);if(l){P({count:m.length,elements:m});return}console.log(` layout (${m.length} element${m.length===1?"":"s"}):
208
+ `),console.log(Ze(m))}async function Pt(e,c={}){let n=await mt(e);if("error"in n&&(console.error(n.error),process.exit(1)),c.json){console.log(JSON.stringify(n,null,2));return}let{visible:l,spec:m,mode:a,shifted:g,capsLock:y,accessoryBarId:T}=n,M=[];M.push(`keyboard: ${l?"visible":"hidden"}`),m?(M.push(` type: ${m.keyboardType}`),M.push(` returnKey: ${m.returnKeyType}`),M.push(` autoCap: ${m.autoCapitalize}`),M.push(` autoCorrect: ${m.autoCorrect?"on":"off"}`),M.push(` appearance: ${m.keyboardAppearance}`),m.secureTextEntry&&M.push(" secureTextEntry: true"),m.enablesReturnKeyAutomatically&&M.push(` return: ${m.currentTextIsEmpty?"disabled (empty)":"enabled"}`)):M.push(" spec: <none> (shown via dev-tools with no TextInput)"),M.push(` mode: ${a}${g?" (shifted)":""}${y?" (caps)":""}`),T&&M.push(` accessoryBar: ${T}`),console.log(M.join(`
209
+ `))}async function Rt(e){let c=await e.bridge.listSims(),n=e.args.includes("--all"),l=e.args.find((y,T)=>e.args[T-1]==="--bundle"),m=e.args.find((y,T)=>e.args[T-1]==="--app-port"),a=e.args.includes("--primary"),g=c.filter(y=>!(a&&!y.isPrimary||l&&!(y.url??"").includes(l)||m&&!(y.url??"").includes(`/rn/${m}`)||!n&&!l&&!m&&!a&&!(y.url&&(y.url.includes("bundle=")||y.url.includes("/index.bundle")))&&y.id!==e.simId));if(A(e.args)){P(g.map(y=>({...y,active:y.id===e.simId})));return}St(g,e.simId),g.length<c.length&&!A(e.args)&&console.log(` (${c.length-g.length} more hidden \u2014 pass --all to show)`)}function ie(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/1024/1024).toFixed(1)}MB`}function xe(e,c){return c<=0?"?":`${(e/c*100).toFixed(0)}%`}async function Et(e,c={args:[]}){let n=await ft(e);if(A(c.args)){P(n);return}if(console.log(" memory:"),n.imageLoader){let l=n.imageLoader;console.log(" image-loader cache"),console.log(` entries: ${l.cacheEntries} / ${l.cacheMaxEntries} (${xe(l.cacheEntries,l.cacheMaxEntries)})`),console.log(` pixel bytes: ${ie(l.cachePixelBytes)} / ${ie(l.cachePixelBudget)} (${xe(l.cachePixelBytes,l.cachePixelBudget)})`),console.log(` pending: ${l.pendingFetches} fetches, ${l.pendingBytes} bytes`),console.log(` failed uris: ${l.failedUris}`),console.log(` snapshots: ${l.snapshots}`),console.log(` camera frames: ${l.cameraFrames}`)}else console.log(" image-loader cache: not available (engine pre-rebuild?)");if(n.workerHeap){let l=n.workerHeap;console.log(" worker heap (chrome only)"),console.log(` used: ${ie(l.usedJSHeapSize)} / ${ie(l.jsHeapSizeLimit)} (${xe(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${ie(l.totalJSHeapSize)}`)}if(n.hostHeap){let l=n.hostHeap;console.log(" host heap (chrome only)"),console.log(` used: ${ie(l.usedJSHeapSize)} / ${ie(l.jsHeapSizeLimit)} (${xe(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${ie(l.totalJSHeapSize)}`)}}function ye(e){let c=e.indexOf("--testid");if(c>=0&&e[c+1])return{mode:"testid",value:e[c+1]};let n=e.indexOf("--test-id");if(n>=0&&e[n+1])return{mode:"testid",value:e[n+1]};let l=e.indexOf("--text");return l>=0&&e[l+1]?{mode:"text",value:e[l+1]}:null}async function $e(e,c){let n=JSON.stringify(c.value),l=c.mode==="testid"?`(await t.findByTestId(${n})) || (await t.findById(${n}))`:`await t.findByText(${n})`;return await e.send({type:"evaluate",code:`(async () => {
209
210
  const t = window.__sootsimTest
210
211
  if (!t) return null
211
212
  const n = ${l}
@@ -230,15 +231,15 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
230
231
  text: ${JSON.stringify(c.mode==="text")} ? ${n} : (n.text ?? n.accessibilityLabel ?? null),
231
232
  type: n.type ?? null,
232
233
  }
233
- })()`})??null}async function Pt(e,c={}){let{nav:n,keyboard:l,shell:m}=await ut(e);if(c.json){console.log(JSON.stringify({shell:m??null,nav:n,keyboard:l},null,2));return}let a=[];if(m){let g=m.activeApp??m.state??"<none>",y=m.showSwitcher?" (app switcher open)":"",T=typeof m.launchProgress=="number"&&m.launchProgress<.98?` launching (${Math.round(m.launchProgress*100)}%)`:"";a.push(`shell: ${g}${y}${T}`)}else a.push("shell: <unavailable>");if(n){let g=n.transitionPhase!=="idle"?` (${n.transitionPhase}, ${n.activeTransitionCount} active)`:"";if(a.push(`nav: phase=${n.transitionPhase}${g}`),n.screens.length===0)a.push(" <no registered screens \u2014 app may not use react-native-screens>");else for(let y of n.screens){let T=y.isActive?"\u25B6":" ",M=y.routeName?` ${y.routeName}`:"",h=y.headerHeight>0?` header=${y.headerHeight}`:"",k=y.largeTitleState&&y.largeTitleState!=="expanded"?` large-title=${y.largeTitleState}`:"";a.push(` ${T} #${y.id}${M}${h}${k}`)}}else a.push("nav: <runtime not available>");if(l&&l.visible){let g=l.spec?.keyboardType??"default",y=l.spec?.returnKeyType??"default";a.push(`keyboard: visible (${g}, return=${y}, mode=${l.mode??"?"})`)}else a.push("keyboard: hidden");console.log(a.join(`
234
- `))}async function Rt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1])*1e3:3e3,a=n.includes("--strict"),{elapsed:g,settled:y}=await ee({bridge:c,maxMs:m,strict:a});console.log(y?` settled in ${g}ms`:` timed out after ${g}ms (may still be animating)`)}async function Et(e){let c=e.positional[1]?Number(e.positional[1]):.5;(!Number.isFinite(c)||c<0)&&(console.error(e.inspectUsage("sleep","[seconds]")),process.exit(1)),await Z(c*1e3),console.log(` slept ${c}s`)}async function Ct(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1]):5,{tree:a}=await Ge(c,m);if(R(n)){E({depth:m,tree:a??null});return}console.log(typeof a=="string"?a:JSON.stringify(a,null,2))}async function Dt(e,c={args:[]}){let n=await Xe(e);if(R(c.args)){E(n);return}console.log(n.url)}async function Bt(e){let{wsPort:c,commandTimeoutMs:n,simId:l,simIdSource:m,positional:a}=e,g=a[1]?Number(a[1]):30,y=Math.max(1e3,(Number.isFinite(g)?g:30)*1e3),T=Math.max(1,Math.ceil(y/500));console.log(" waiting for sim reconnect...");let M=await pt(c,n,l,{attempts:T,simIdSource:m});M||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),M.bridge.close(),we({source:"inspect wait",step:{wait:y},summary:`wait ${Math.round(y/1e3)}s`}),console.log(` ready: ${M.count} nodes`)}var jt=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function Se(e,c){let n=e.indexOf(c);if(n>=0&&n+1<e.length)return e[n+1]}function Mo(e,c){if(!c.filter&&!c.equals)return!0;let n=e.data,l=[];if(n&&typeof n=="object")for(let a of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let g=n[a];typeof g=="string"&&g.length>0&&l.push(g)}let m=l.join(" ");return c.equals?l.some(a=>a===c.equals):c.filter?m.toLowerCase().includes(c.filter.toLowerCase()):!0}async function Jt(e){let{bridge:c,args:n,positional:l,inspectUsage:m}=e,a=l[1];a||(console.error(m("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),jt.has(a)||console.error(` warning: '${a}' is not a known timeline kind \u2014 waiting anyway. known: ${[...jt].sort().join(", ")}`);let g=Se(n,"--max-ms"),y=g&&Number.isFinite(Number(g))?Math.max(100,Number(g)):5e3,T=Se(n,"--filter"),M=Se(n,"--equals"),h=Se(n,"--since")??"now",k=n.includes("--json"),_=Date.now(),I=_+y,O=200,j=_;for(;Date.now()<I;){let z={kinds:[a],since:h==="cursor"?void 0:j,limit:50},B=await c.send({type:"evaluate",code:`(async () => {
234
+ })()`})??null}async function Ct(e,c={}){let{nav:n,keyboard:l,shell:m}=await pt(e);if(c.json){console.log(JSON.stringify({shell:m??null,nav:n,keyboard:l},null,2));return}let a=[];if(m){let g=m.activeApp??m.state??"<none>",y=m.showSwitcher?" (app switcher open)":"",T=typeof m.launchProgress=="number"&&m.launchProgress<.98?` launching (${Math.round(m.launchProgress*100)}%)`:"";a.push(`shell: ${g}${y}${T}`)}else a.push("shell: <unavailable>");if(n){let g=n.transitionPhase!=="idle"?` (${n.transitionPhase}, ${n.activeTransitionCount} active)`:"";if(a.push(`nav: phase=${n.transitionPhase}${g}`),n.screens.length===0)a.push(" <no registered screens \u2014 app may not use react-native-screens>");else for(let y of n.screens){let T=y.isActive?"\u25B6":" ",M=y.routeName?` ${y.routeName}`:"",h=y.headerHeight>0?` header=${y.headerHeight}`:"",k=y.largeTitleState&&y.largeTitleState!=="expanded"?` large-title=${y.largeTitleState}`:"";a.push(` ${T} #${y.id}${M}${h}${k}`)}}else a.push("nav: <runtime not available>");if(l&&l.visible){let g=l.spec?.keyboardType??"default",y=l.spec?.returnKeyType??"default";a.push(`keyboard: visible (${g}, return=${y}, mode=${l.mode??"?"})`)}else a.push("keyboard: hidden");console.log(a.join(`
235
+ `))}async function Dt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1])*1e3:3e3,a=n.includes("--strict"),{elapsed:g,settled:y}=await ee({bridge:c,maxMs:m,strict:a});console.log(y?` settled in ${g}ms`:` timed out after ${g}ms (may still be animating)`)}async function Bt(e){let c=e.positional[1]?Number(e.positional[1]):.5;(!Number.isFinite(c)||c<0)&&(console.error(e.inspectUsage("sleep","[seconds]")),process.exit(1)),await Z(c*1e3),console.log(` slept ${c}s`)}async function jt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1]):5,{tree:a}=await Ge(c,m);if(A(n)){P({depth:m,tree:a??null});return}console.log(typeof a=="string"?a:JSON.stringify(a,null,2))}async function Jt(e,c={args:[]}){let n=await Xe(e);if(A(c.args)){P(n);return}console.log(n.url)}async function Lt(e){let{wsPort:c,commandTimeoutMs:n,simId:l,simIdSource:m,positional:a}=e,g=a[1]?Number(a[1]):30,y=Math.max(1e3,(Number.isFinite(g)?g:30)*1e3),T=Math.max(1,Math.ceil(y/500));console.log(" waiting for sim reconnect...");let M=await gt(c,n,l,{attempts:T,simIdSource:m});M||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),M.bridge.close(),we({source:"inspect wait",step:{wait:y},summary:`wait ${Math.round(y/1e3)}s`}),console.log(` ready: ${M.count} nodes`)}var Wt=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function Se(e,c){let n=e.indexOf(c);if(n>=0&&n+1<e.length)return e[n+1]}function Fo(e,c){if(!c.filter&&!c.equals)return!0;let n=e.data,l=[];if(n&&typeof n=="object")for(let a of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let g=n[a];typeof g=="string"&&g.length>0&&l.push(g)}let m=l.join(" ");return c.equals?l.some(a=>a===c.equals):c.filter?m.toLowerCase().includes(c.filter.toLowerCase()):!0}async function qt(e){let{bridge:c,args:n,positional:l,inspectUsage:m}=e,a=l[1];a||(console.error(m("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),Wt.has(a)||console.error(` warning: '${a}' is not a known timeline kind \u2014 waiting anyway. known: ${[...Wt].sort().join(", ")}`);let g=Se(n,"--max-ms"),y=g&&Number.isFinite(Number(g))?Math.max(100,Number(g)):5e3,T=Se(n,"--filter"),M=Se(n,"--equals"),h=Se(n,"--since")??"now",k=n.includes("--json"),_=Date.now(),I=_+y,R=200,j=_;for(;Date.now()<I;){let z={kinds:[a],since:h==="cursor"?void 0:j,limit:50},B=await c.send({type:"evaluate",code:`(async () => {
235
236
  const t = window.SootSim?.bridges?.timeline
236
237
  if (!t) return { ok: false, error: 'timeline bridge missing' }
237
238
  return { ok: true, result: await t.recent(${JSON.stringify(z)}) }
238
- })()`});(!B||!B.ok)&&(console.error(` could not query timeline: ${B&&"error"in B?B.error:"unknown"}`),process.exit(1));let C=B.result.events??[];for(let V of C)if(Mo(V,{filter:T,equals:M})){let te=Date.now()-_;console.log(k?JSON.stringify({found:!0,elapsedMs:te,event:V}):` ${a} event after ${te}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`);return}B.result.watermark&&B.result.watermark>j&&(j=B.result.watermark),await new Promise(V=>setTimeout(V,O))}let d=Date.now()-_;k?console.log(JSON.stringify({found:!1,elapsedMs:d,kind:a,filter:T,equals:M})):console.error(` \u26A0 wait event ${a} timed out after ${d}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`),process.exit(1)}async function Lt(e){let{bridge:c,args:n}=e,l=n.includes("--strict"),m=he(n,3e3),{elapsed:a,settled:g}=await ee({bridge:c,maxMs:m,strict:l});g?console.log(` idle in ${a}ms`):(console.error(` \u26A0 wait idle timed out after ${a}ms (may still be animating)`),process.exit(1))}async function Wt(e){let{bridge:c,args:n}=e,l=he(n,2e4),{ready:m,elapsedMs:a,nodes:g,targets:y,flag:T,loadingText:M,externalReady:h,externalError:k,errors:_}=await et(c,l,{onProgress(O){console.error(` still waiting after ${O.elapsedMs}ms \u2014 ${_e(O)} (nodes: ${O.nodes}, targets: ${O.targets}, errors: ${O.errors})`)}});if(m){let O=l-a,j=Math.max(100,Math.min(1e4,O)),d=await ee({bridge:c,maxMs:j,pollMs:32,stablePolls:2});d.settled||(console.error(` \u26A0 wait ready timed out after ${a+d.elapsed}ms \u2014 app mounted but did not settle (nodes: ${g}, targets: ${y})`),process.exit(1)),console.log(` ready in ${a+d.elapsed}ms: ${g} nodes, ${y} targets`);return}let I=_e({externalError:k,loadingText:M,externalReady:h,flag:T,targets:y});console.error(` \u26A0 wait ready timed out after ${a}ms \u2014 ${I} (nodes: ${g}, targets: ${y}, errors: ${_})`),process.exit(1)}async function qt(e){let{bridge:c,args:n,positional:l,inspectUsage:m}=e,a=l[1];a||(console.error(m("wait selector","<testid> [--max-ms 5000] [--gone]")),process.exit(1));let g=n.indexOf("--max-ms"),y=g>=0&&n[g+1]?Math.max(100,Number(n[g+1])):5e3,T=n.includes("--gone"),{found:M,node:h,elapsed:k}=await tt(c,a,y,{gone:T});if(T){M?console.log(` #${a} gone after ${k}ms`):(console.error(` \u26A0 wait selector #${a} --gone timed out after ${k??y}ms (still present)`),process.exit(1));return}if(M&&h){let _=h.absolutePosition?`@(${Math.round(h.absolutePosition.x)},${Math.round(h.absolutePosition.y)})`:"",I=h.layout?`${Math.round(h.layout.width)}x${Math.round(h.layout.height)}`:"?x?";console.log(` found #${a} in ${k}ms ${I} ${_}`)}else console.error(` \u26A0 wait selector #${a} timed out after ${k??y}ms`),process.exit(1)}function Vt(e){return e==null?"\u2014":e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}K`:`${(e/1024/1024).toFixed(1)}M`}function Qt(e){return e==null?" \u2026":e<1e3?`${e}ms`.padStart(5):`${(e/1e3).toFixed(2)}s`.padStart(5)}function Ht(){process.stderr.write(` the sim is not responding. recover it with:
239
+ })()`});(!B||!B.ok)&&(console.error(` could not query timeline: ${B&&"error"in B?B.error:"unknown"}`),process.exit(1));let C=B.result.events??[];for(let V of C)if(Fo(V,{filter:T,equals:M})){let te=Date.now()-_;console.log(k?JSON.stringify({found:!0,elapsedMs:te,event:V}):` ${a} event after ${te}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`);return}B.result.watermark&&B.result.watermark>j&&(j=B.result.watermark),await new Promise(V=>setTimeout(V,R))}let d=Date.now()-_;k?console.log(JSON.stringify({found:!1,elapsedMs:d,kind:a,filter:T,equals:M})):console.error(` \u26A0 wait event ${a} timed out after ${d}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`),process.exit(1)}async function Ht(e){let{bridge:c,args:n}=e,l=n.includes("--strict"),m=be(n,3e3),{elapsed:a,settled:g}=await ee({bridge:c,maxMs:m,strict:l});g?console.log(` idle in ${a}ms`):(console.error(` \u26A0 wait idle timed out after ${a}ms (may still be animating)`),process.exit(1))}async function Ut(e){let{bridge:c,args:n}=e,l=be(n,2e4),{ready:m,elapsedMs:a,nodes:g,targets:y,flag:T,loadingText:M,externalReady:h,externalError:k,errors:_}=await ot(c,l,{onProgress(R){console.error(` still waiting after ${R.elapsedMs}ms \u2014 ${_e(R)} (nodes: ${R.nodes}, targets: ${R.targets}, errors: ${R.errors})`)}});if(m){let R=l-a,j=Math.max(100,Math.min(1e4,R)),d=await ee({bridge:c,maxMs:j,pollMs:32,stablePolls:2});d.settled||(console.error(` \u26A0 wait ready timed out after ${a+d.elapsed}ms \u2014 app mounted but did not settle (nodes: ${g}, targets: ${y})`),process.exit(1)),console.log(` ready in ${a+d.elapsed}ms: ${g} nodes, ${y} targets`);return}let I=_e({externalError:k,loadingText:M,externalReady:h,flag:T,targets:y});console.error(` \u26A0 wait ready timed out after ${a}ms \u2014 ${I} (nodes: ${g}, targets: ${y}, errors: ${_})`),process.exit(1)}async function Kt(e){let{bridge:c,args:n,positional:l,inspectUsage:m}=e,a=l[1];a||(console.error(m("wait selector","<testid> [--max-ms 5000] [--gone]")),process.exit(1));let g=n.indexOf("--max-ms"),y=g>=0&&n[g+1]?Math.max(100,Number(n[g+1])):5e3,T=n.includes("--gone"),{found:M,node:h,elapsed:k}=await st(c,a,y,{gone:T});if(T){M?console.log(` #${a} gone after ${k}ms`):(console.error(` \u26A0 wait selector #${a} --gone timed out after ${k??y}ms (still present)`),process.exit(1));return}if(M&&h){let _=h.absolutePosition?`@(${Math.round(h.absolutePosition.x)},${Math.round(h.absolutePosition.y)})`:"",I=h.layout?`${Math.round(h.layout.width)}x${Math.round(h.layout.height)}`:"?x?";console.log(` found #${a} in ${k}ms ${I} ${_}`)}else console.error(` \u26A0 wait selector #${a} timed out after ${k??y}ms`),process.exit(1)}function eo(e){return e==null?"\u2014":e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}K`:`${(e/1024/1024).toFixed(1)}M`}function to(e){return e==null?" \u2026":e<1e3?`${e}ms`.padStart(5):`${(e/1e3).toFixed(2)}s`.padStart(5)}function zt(){process.stderr.write(` the sim is not responding. recover it with:
239
240
  sootsim close --sim <id> # force-close the wedged sim
240
241
  sootsim list # confirm it's gone
241
- `)}async function No(e){try{return await e.send({type:"evaluate",code:"1"},{timeoutMs:3e3}),!0}catch{return!1}}async function Fo(e,c){try{let n=await e.send({type:"evaluate",code:`(async () => {
242
+ `)}async function Oo(e){try{return await e.send({type:"evaluate",code:"1"},{timeoutMs:3e3}),!0}catch{return!1}}async function Ao(e,c){try{let n=await e.send({type:"evaluate",code:`(async () => {
242
243
  const t = window.__sootsimTest
243
244
  if (!t || typeof t.queryAll !== 'function') return []
244
245
  try {
@@ -257,8 +258,8 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
257
258
  } catch {
258
259
  return []
259
260
  }
260
- })()`});if(!Array.isArray(n)||n.length===0)return;let l=c.toLowerCase(),m=n.map(a=>({id:a,score:_o(l,a.toLowerCase())})).filter(a=>a.score<l.length+4).sort((a,g)=>a.score-g.score).slice(0,5);if(m.length===0)return;console.error(" similar testIDs:");for(let a of m)console.error(` ${a.id}`)}catch{}}function _o(e,c){if(c===e)return 0;if(c.includes(e))return 1;if(e.includes(c))return 2;let n=0;for(;n<e.length&&n<c.length&&e[n]===c[n];)n+=1;return Ao(e,c)-n}function Ao(e,c){if(e===c)return 0;if(!e.length)return c.length;if(!c.length)return e.length;let n=new Array(c.length+1),l=new Array(c.length+1);for(let m=0;m<=c.length;m++)n[m]=m;for(let m=1;m<=e.length;m++){l[0]=m;for(let g=1;g<=c.length;g++)l[g]=Math.min(n[g]+1,l[g-1]+1,n[g-1]+(e[m-1]===c[g-1]?0:1));let a=n;n=l,l=a}return n[c.length]}function Oo(e){return e.error?"err":e.status==null?" \u2026 ":String(e.status)}function Po(e){return e.externalError?`guest app errored: ${e.externalError}`:e.loadingText?`still showing "${e.loadingText}"`:e.externalReady===!1?"guest app is still loading":e.flag!==!0?"guest app has not emitted sootsim:externalAppReady":e.targets<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing"}function Ut(e){let c=re(e.startTs),n=Oo(e).padEnd(3),l=e.method.padEnd(5),m=Vt(e.size).padStart(6),a=Qt(e.durationMs);console.log(` [${c}] ${n} ${l} ${m} ${a} ${e.displayUrl}`),e.error&&console.log(` error: ${e.error}`)}function Ro(e){let c=[["id",e.id],["source",e.source],["kind",e.kind],["method",e.method],["status",e.error?`error: ${e.error}`:`${e.status??"\u2014"} ${e.statusText??""}`.trim()],["url",e.url],["started",re(e.startTs)],["duration",Qt(e.durationMs).trim()],["size",Vt(e.size)],["content-type",e.type??"\u2014"]];for(let[n,l]of c)console.log(` ${n.padEnd(13)} ${l}`)}var Eo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Kt="\x1B[0m",Co="\x1B[2m";function zt(e,c){let n=re(e.ts),l=e.level.toUpperCase().padEnd(5),m=e.args.join(" ");if(c){let a=Eo[e.level];console.log(` ${Co}[${n}]${Kt} ${a}${l}${Kt} ${m}`)}else console.log(` [${n}] ${l} ${m}`);if(e.stack&&e.level==="error"){let a=e.stack.split(`
261
- `).slice(0,5);for(let g of a)console.log(` ${g.trim()}`)}}var se="__sootsimCliPerf",Do=120;async function Yt(e,c){let n=e.find((_,I)=>e[I-1]==="--id"),l=e.find((_,I)=>e[I-1]==="--text");if(n||l){let _=await c.send({type:"evaluate",code:yt({id:n,text:l})});if(!_)throw new Error(n?`no node with id "${n}"`:`no node matching text "${l}"`);let{x:I,y:O,w:j,h:d}=_;return{x:I,y:O,w:j,h:d}}let m=e.find((_,I)=>e[I-1]==="--area");if(m){let _=m.split(",").map(z=>Number(z.trim()));if(_.length!==4||_.some(z=>!Number.isFinite(z)))throw new Error(`--area expects x,y,w,h (got "${m}")`);let[I,O,j,d]=_;return{x:I,y:O,w:j,h:d}}let a=_=>{let I=e.find((j,d)=>e[d-1]===_);if(I==null)return null;let O=Number(I);return Number.isFinite(O)?O:null},g=a("--x"),y=a("--y"),T=a("--w"),M=a("--h");if(g!=null||y!=null||T!=null||M!=null)return{x:g??0,y:y??0,w:T??1,h:M??1};let k=e.filter((_,I)=>I>0&&!_.startsWith("-")&&e[I-1]!=="--output"&&e[I-1]!=="--area"&&e[I-1]!=="--id"&&e[I-1]!=="--text"&&e[I-1]!=="--x"&&e[I-1]!=="--y"&&e[I-1]!=="--w"&&e[I-1]!=="--h").map(Number).filter(_=>Number.isFinite(_));if(k.length>=2){let[_,I,O=1,j=1]=k;return{x:_,y:I,w:O,h:j}}return null}function Ce(e){let c={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let n of e)n<8?c["<8"]++:n<12?c["8-12"]++:n<16?c["12-16"]++:n<20?c["16-20"]++:n<33?c["20-33"]++:c[">33"]++;console.log(" histogram:");for(let[n,l]of Object.entries(c)){let m="\u2588".repeat(Math.ceil(l/e.length*40));console.log(` ${n.padEnd(6)} ${m} ${l}`)}}async function ve(e,c,n){let l=Date.now()+c,m=await le(e,c);for(;;){if(n(m))return{settled:!0,state:m};if(Date.now()>=l)return{settled:!1,state:m};await Z(16),m=await le(e)}}async function Be(e){return e.send({type:"evaluate",code:`(async () => {
261
+ })()`});if(!Array.isArray(n)||n.length===0)return;let l=c.toLowerCase(),m=n.map(a=>({id:a,score:Po(l,a.toLowerCase())})).filter(a=>a.score<l.length+4).sort((a,g)=>a.score-g.score).slice(0,5);if(m.length===0)return;console.error(" similar testIDs:");for(let a of m)console.error(` ${a.id}`)}catch{}}function Po(e,c){if(c===e)return 0;if(c.includes(e))return 1;if(e.includes(c))return 2;let n=0;for(;n<e.length&&n<c.length&&e[n]===c[n];)n+=1;return Ro(e,c)-n}function Ro(e,c){if(e===c)return 0;if(!e.length)return c.length;if(!c.length)return e.length;let n=new Array(c.length+1),l=new Array(c.length+1);for(let m=0;m<=c.length;m++)n[m]=m;for(let m=1;m<=e.length;m++){l[0]=m;for(let g=1;g<=c.length;g++)l[g]=Math.min(n[g]+1,l[g-1]+1,n[g-1]+(e[m-1]===c[g-1]?0:1));let a=n;n=l,l=a}return n[c.length]}function Eo(e){return e.error?"err":e.status==null?" \u2026 ":String(e.status)}function Co(e){return e.externalError?`guest app errored: ${e.externalError}`:e.loadingText?`still showing "${e.loadingText}"`:e.externalReady===!1?"guest app is still loading":e.flag!==!0?"guest app has not emitted sootsim:externalAppReady":e.targets<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing"}function Yt(e){let c=re(e.startTs),n=Eo(e).padEnd(3),l=e.method.padEnd(5),m=eo(e.size).padStart(6),a=to(e.durationMs);console.log(` [${c}] ${n} ${l} ${m} ${a} ${e.displayUrl}`),e.error&&console.log(` error: ${e.error}`)}function Do(e){let c=[["id",e.id],["source",e.source],["kind",e.kind],["method",e.method],["status",e.error?`error: ${e.error}`:`${e.status??"\u2014"} ${e.statusText??""}`.trim()],["url",e.url],["started",re(e.startTs)],["duration",to(e.durationMs).trim()],["size",eo(e.size)],["content-type",e.type??"\u2014"]];for(let[n,l]of c)console.log(` ${n.padEnd(13)} ${l}`)}var Bo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Gt="\x1B[0m",jo="\x1B[2m";function Xt(e,c){let n=re(e.ts),l=e.level.toUpperCase().padEnd(5),m=e.args.join(" ");if(c){let a=Bo[e.level];console.log(` ${jo}[${n}]${Gt} ${a}${l}${Gt} ${m}`)}else console.log(` [${n}] ${l} ${m}`);if(e.stack&&e.level==="error"){let a=e.stack.split(`
262
+ `).slice(0,5);for(let g of a)console.log(` ${g.trim()}`)}}var se="__sootsimCliPerf",Jo=120;async function Vt(e,c){let n=e.find((_,I)=>e[I-1]==="--id"),l=e.find((_,I)=>e[I-1]==="--text");if(n||l){let _=await c.send({type:"evaluate",code:bt({id:n,text:l})});if(!_)throw new Error(n?`no node with id "${n}"`:`no node matching text "${l}"`);let{x:I,y:R,w:j,h:d}=_;return{x:I,y:R,w:j,h:d}}let m=e.find((_,I)=>e[I-1]==="--area");if(m){let _=m.split(",").map(z=>Number(z.trim()));if(_.length!==4||_.some(z=>!Number.isFinite(z)))throw new Error(`--area expects x,y,w,h (got "${m}")`);let[I,R,j,d]=_;return{x:I,y:R,w:j,h:d}}let a=_=>{let I=e.find((j,d)=>e[d-1]===_);if(I==null)return null;let R=Number(I);return Number.isFinite(R)?R:null},g=a("--x"),y=a("--y"),T=a("--w"),M=a("--h");if(g!=null||y!=null||T!=null||M!=null)return{x:g??0,y:y??0,w:T??1,h:M??1};let k=e.filter((_,I)=>I>0&&!_.startsWith("-")&&e[I-1]!=="--output"&&e[I-1]!=="--area"&&e[I-1]!=="--id"&&e[I-1]!=="--text"&&e[I-1]!=="--x"&&e[I-1]!=="--y"&&e[I-1]!=="--w"&&e[I-1]!=="--h").map(Number).filter(_=>Number.isFinite(_));if(k.length>=2){let[_,I,R=1,j=1]=k;return{x:_,y:I,w:R,h:j}}return null}function Ce(e){let c={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let n of e)n<8?c["<8"]++:n<12?c["8-12"]++:n<16?c["12-16"]++:n<20?c["16-20"]++:n<33?c["20-33"]++:c[">33"]++;console.log(" histogram:");for(let[n,l]of Object.entries(c)){let m="\u2588".repeat(Math.ceil(l/e.length*40));console.log(` ${n.padEnd(6)} ${m} ${l}`)}}async function ve(e,c,n){let l=Date.now()+c,m=await le(e,c);for(;;){if(n(m))return{settled:!0,state:m};if(Date.now()>=l)return{settled:!1,state:m};await Z(16),m=await le(e)}}async function Be(e){return e.send({type:"evaluate",code:`(async () => {
262
263
  const kb = window.__sootsimKeyboard
263
264
  const test = window.__sootsimTest
264
265
  if (!kb) return { error: 'keyboard bridge not available' }
@@ -290,7 +291,7 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
290
291
  frame: runtimeSnapshot?.keyboard?.frame ?? null,
291
292
  focusedRect: runtimeSnapshot?.focused?.rect ?? null,
292
293
  }
293
- })()`})}async function Bo(e,c=600){let n=Date.now()+c;for(;Date.now()<=n;){let l=await Be(e);if(l.visible)return l;await Z(30)}return Be(e)}async function ke(e,c){let n=await Be(e);if(n.visible)return n;console.error(` ${c} requires the iOS keyboard to be visible. focus an input first with sootsim do tap-id/tap-text or sootsim do type-into.`),process.exit(1)}async function Gt(e,c,n){return c==="appearance"?e.send({type:"evaluate",code:`(async () => {
294
+ })()`})}async function Lo(e,c=600){let n=Date.now()+c;for(;Date.now()<=n;){let l=await Be(e);if(l.visible)return l;await Z(30)}return Be(e)}async function ke(e,c){let n=await Be(e);if(n.visible)return n;console.error(` ${c} requires the iOS keyboard to be visible. focus an input first with sootsim do tap-id/tap-text or sootsim do type-into.`),process.exit(1)}async function Qt(e,c,n){return c==="appearance"?e.send({type:"evaluate",code:`(async () => {
294
295
  const requested = ${JSON.stringify(n??"toggle")}
295
296
  const rootBg = (document.documentElement?.style?.background || '').toLowerCase()
296
297
  const inferredCurrent = rootBg.includes('33') ? 'dark' : 'light'
@@ -307,15 +308,15 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
307
308
  })()`}):e.send({type:"evaluate",code:`(async () => {
308
309
  window.dispatchEvent(new CustomEvent(${JSON.stringify(c==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
309
310
  return { ok: true, action: ${JSON.stringify(c)} }
310
- })()`})}function jo(e){let c={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(c[e])return c[e];let n=e.match(/^Digit([0-9])$/);if(n)return n[1];let l=e.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function Jo(e){if(typeof e!="string")return null;let c=e.replace(/\s+/g," ").trim();return c?c.slice(0,80):null}function Zt(...e){for(let c of e){if(typeof c!="string")continue;let n=c.trim();if(n)return n}return null}function Lo(e){let c=e.indexOf("--node-id");if(c<0)return null;let n=e[c+1];if(!n)return null;let l=Number(n);return Number.isInteger(l)&&l>0?l:null}async function J(e,c,n){let l=we({source:e,step:c,summary:n});l.active&&(l.replaced?console.error(` draft: replaced unkept action "${l.replaced.summary}" \u2014 \`flow keep\` commits one action at a time`):console.error(" draft: action pending \u2014 `sootsim flow keep` to commit"))}function Xt(e,c,n){if(!n||n.hit===!1)return null;let l=Zt(n.responderTestID,n.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let m=Jo(n.text);return m?{step:{tapOn:m},summary:`tap "${m}"`}:{step:{tapAtCoords:{x:e,y:c}},summary:`tap @${Math.round(e)},${Math.round(c)}`}}function De(e,c,n){let l=Zt(c?.testID,c?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:n==="id"?{step:{tapOn:{id:e}},summary:`tap #${e}`}:{step:{tapOn:e},summary:`tap "${e}"`}}async function Mn(e,c){let n=e[0]==="get"||e[0]==="do"||e[0]==="debug"||e[0]==="wait"?e[0]:null,l=n?e.slice(1):e,m=We(l,{port:c.port,commandTimeoutMs:c.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--slow","--tail","-f","--interactive-targets","--actions","--internal","--compact","--no-xy","--no-clipped","--include-occluded"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--node-id","--max-ms","--filter","--limit","--level","--threshold","--equals","--since","--testid-like","--only","--subtree"]}),a=m.positional,g=a[0],y=n==="get"||n==="do"||n==="debug"||n==="wait"?n:"inspect",T=typeof l[0]=="string"&&je.has(l[0]),M=T?l[0]:null,h=o=>T&&o===l[0]?`sootsim ${o}`:`sootsim ${y} ${o}`,k=(o,t)=>` usage: ${h(o)}${t?` ${t}`:""}`;if(!g||e.includes("--help")||e.includes("-h")){let o={bridgePort:7668,defaultShellUrl:Je};if(y==="do"||y==="get"||y==="debug"||y==="wait"){let r=Te(y,o);r&&(console.log(`${r}
311
+ })()`})}function Wo(e){let c={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(c[e])return c[e];let n=e.match(/^Digit([0-9])$/);if(n)return n[1];let l=e.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function qo(e){if(typeof e!="string")return null;let c=e.replace(/\s+/g," ").trim();return c?c.slice(0,80):null}function oo(...e){for(let c of e){if(typeof c!="string")continue;let n=c.trim();if(n)return n}return null}function Ho(e){let c=e.indexOf("--node-id");if(c<0)return null;let n=e[c+1];if(!n)return null;let l=Number(n);return Number.isInteger(l)&&l>0?l:null}async function J(e,c,n){let l=we({source:e,step:c,summary:n});l.active&&(l.replaced?console.error(` draft: replaced unkept action "${l.replaced.summary}" \u2014 \`flow keep\` commits one action at a time`):console.error(" draft: action pending \u2014 `sootsim flow keep` to commit"))}function Zt(e,c,n){if(!n||n.hit===!1)return null;let l=oo(n.responderTestID,n.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let m=qo(n.text);return m?{step:{tapOn:m},summary:`tap "${m}"`}:{step:{tapAtCoords:{x:e,y:c}},summary:`tap @${Math.round(e)},${Math.round(c)}`}}function De(e,c,n){let l=oo(c?.testID,c?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:n==="id"?{step:{tapOn:{id:e}},summary:`tap #${e}`}:{step:{tapOn:e},summary:`tap "${e}"`}}async function Pn(e,c){let n=e[0]==="get"||e[0]==="do"||e[0]==="debug"||e[0]==="wait"?e[0]:null,l=n?e.slice(1):e,m=We(l,{port:c.port,commandTimeoutMs:c.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--slow","--tail","-f","--interactive-targets","--actions","--internal","--compact","--no-xy","--no-clipped","--include-occluded"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--node-id","--max-ms","--filter","--limit","--level","--threshold","--equals","--since","--testid-like","--only","--subtree"]}),a=m.positional,g=a[0],y=n==="get"||n==="do"||n==="debug"||n==="wait"?n:"inspect",T=typeof l[0]=="string"&&je.has(l[0]),M=T?l[0]:null,h=o=>T&&o===l[0]?`sootsim ${o}`:`sootsim ${y} ${o}`,k=(o,t)=>` usage: ${h(o)}${t?` ${t}`:""}`;if(!g||e.includes("--help")||e.includes("-h")){let o={bridgePort:7668,defaultShellUrl:Je};if(y==="do"||y==="get"||y==="debug"||y==="wait"){let r=Te(y,o);r&&(console.log(`${r}
311
312
  `),process.exit(0))}if(M==="shell"){let r=Me("shell",o);r&&(console.log(`${r}
312
313
  `),process.exit(0))}let t=Me("inspect",o),s=["do","get","debug","wait"].map(r=>Te(r,o)).filter(r=>r!=null).join(`
313
314
 
314
315
  `);console.log(`${t??""}
315
316
 
316
317
  ${s}
317
- `),process.exit(0)}let _=m.wsPort,I=m.simId,O=m.simIdSource,j=m.commandTimeoutMs;if(g==="list"&&l.some(o=>o==="--drivers"||o==="-D")){let{buildDriverListRows:o}=await import("./drivers-GTB2MH7E.js"),t=o();console.log(` available drivers (${t.length}):
318
- `);let s=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 u=i.available?"\u2713":"\u2717",p=i.id.padEnd(s),w=i.kind.padEnd(r);console.log(` ${u} ${p} ${w} ${i.description}`),i.available&&i.detail?console.log(` ${i.detail}`):!i.available&&i.reason&&console.log(` unavailable: ${i.reason}`)}return}let d=qe(m),z=I||"default",B=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),C=200;function V(o){let t=o.replace(/\s+/g," ").trim();if(!t)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(t)){let r=/<title[^>]*>([^<]+)<\/title>/i.exec(o)?.[1]?.trim(),i=/<body[^>]*>([\s\S]*?)<\//i.exec(o)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=r||i||"html error page";return`<html ${o.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return t.length<=C?t:`${t.slice(0,C)}\u2026 (+${t.length-C} more bytes)`}function te(o){let t=o.displayUrl||o.url;return o.status!=null?`${o.method} ${t} -> ${o.status}${o.statusText?` ${o.statusText}`:""}`:o.error?`${o.method} ${t} -> ${o.error}`:`${o.method} ${t}`}async function S(o){let t=de()?5e3:1500;try{let{settled:s,elapsed:r}=await ee({bridge:o,maxMs:t,pollMs:32,stablePolls:2});s||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.
318
+ `),process.exit(0)}let _=m.wsPort,I=m.simId,R=m.simIdSource,j=m.commandTimeoutMs;if(g==="list"&&l.some(o=>o==="--drivers"||o==="-D")){let{buildDriverListRows:o}=await import("./drivers-TFUZRRDZ.js"),t=o();console.log(` available drivers (${t.length}):
319
+ `);let s=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 u=i.available?"\u2713":"\u2717",p=i.id.padEnd(s),w=i.kind.padEnd(r);console.log(` ${u} ${p} ${w} ${i.description}`),i.available&&i.detail?console.log(` ${i.detail}`):!i.available&&i.reason&&console.log(` unavailable: ${i.reason}`)}return}let d=qe(m),z=I||"default",B=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),C=200;function V(o){let t=o.replace(/\s+/g," ").trim();if(!t)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(t)){let r=/<title[^>]*>([^<]+)<\/title>/i.exec(o)?.[1]?.trim(),i=/<body[^>]*>([\s\S]*?)<\//i.exec(o)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=r||i||"html error page";return`<html ${o.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return t.length<=C?t:`${t.slice(0,C)}\u2026 (+${t.length-C} more bytes)`}function te(o){let t=o.displayUrl||o.url;return o.status!=null?`${o.method} ${t} -> ${o.status}${o.statusText?` ${o.statusText}`:""}`:o.error?`${o.method} ${t} -> ${o.error}`:`${o.method} ${t}`}async function S(o){let t=ue()?5e3:1500;try{let{settled:s,elapsed:r}=await ee({bridge:o,maxMs:t,pollMs:32,stablePolls:2});s||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.
319
320
  `)}catch{}}function N(o,t){console.error(` tap failed: ${o} 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 L(){try{return await d.send({type:"evaluate",code:`(() => ({
320
321
  console: window.__sootsimConsole?.count?.() || null,
321
322
  requests: window.__sootsimTest?.getRequestCounts?.() || null,
@@ -325,7 +326,7 @@ ${s}
325
326
  `);for(let i of r){let u=re(i.timestamp);console.log(` [${u}] ${te(i)}`),i.responseBody?console.log(` ${V(i.responseBody)}`):i.error&&console.log(` ${i.error}`)}}}async function X(o={}){let t=o.counts!==void 0?o.counts:await d.send({type:"evaluate",code:"window.__sootsimConsole?.count?.() || { errors: 0, warnings: 0, total: 0 }"});if(!t||typeof t!="object")return;let s=t,r=Math.max(0,Number(s.errors)||0),i=Math.max(0,Number(s.warnings)||0);if(r===0&&i===0||!o.includeTail&&!Pe("console",z,`${r}:${i}`))return;let u=[];if(r>0&&u.push(`${r} console error${r===1?"":"s"}`),i>0&&u.push(`${i} console warning${i===1?"":"s"}`),console.log(`
326
327
  console: ${u.join(", ")}`),console.log(` inspect: ${h("errors")} 5`),i>0&&console.log(` inspect: ${h("warnings")} 5`),!o.includeTail||r===0)return;let p=await d.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors?.(5) || []"});if(!(!Array.isArray(p)||p.length===0)){console.log(`
327
328
  recent console errors:
328
- `);for(let w of p){let f=re(w.timestamp),x=Array.isArray(w.args)?w.args.map(A=>typeof A=="object"?JSON.stringify(A):String(A)).join(" "):String(w);console.log(` [${f}] ${x}`)}}}let Q=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function ne(o){let t=Le(),s=null;try{s=await Ue(o,`(() => {
329
+ `);for(let w of p){let f=re(w.timestamp),x=Array.isArray(w.args)?w.args.map(O=>typeof O=="object"?JSON.stringify(O):String(O)).join(" "):String(w);console.log(` [${f}] ${x}`)}}}let Q=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function ne(o){let t=Le(),s=null;try{s=await Ue(o,`(() => {
329
330
  const tl = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.timeline
330
331
  if (!tl || typeof tl.summary !== 'function') return null
331
332
  const cursorKey = ${JSON.stringify(t)}
@@ -342,8 +343,8 @@ ${s}
342
343
  }
343
344
  return summary ? { summary, consoleSplit } : null
344
345
  })()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let r=s.summary.byKind??{},i=[],u=new Set;for(let p of Q){let w=r[p];if(w)if(u.add(p),p==="console"&&s.consoleSplit){let{error:f,warn:x}=s.consoleSplit;f>0&&i.push(`${f} error${f===1?"":"s"}`),x>0&&i.push(`${x} warning${x===1?"":"s"}`)}else i.push(`${w} ${p}${w===1?"":"s"}`)}for(let[p,w]of Object.entries(r))!u.has(p)&&w&&i.push(`${w} ${p}${w===1?"":"s"}`);if(i.length!==0&&(console.log(`
345
- since last: ${i.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await Ie(o,"SootSim.bridges.timeline.cursorAdvance",t,s.summary.lastAt)}catch{}}let ue=new Set(["tap","double-tap","tap-text","tap-id","type","type-into","key","key-sequence","keycode","drag","swipe","long-press","touch","gesture","pinch","scroll","shell"]),D=new Set(["a11y","capture","count","double-tap","drag","find","gesture","layout","long-press","node","pinch","sample-color","scroll","screenshot","swipe","tap","tap-id","tap-text","touch","tree","type-into"]),ae=(e.includes("--verbose")||e.includes("-v"))&&!e.includes("--json");y==="do"&&g==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),ue.has(g)&&await He(d),D.has(g)&&await be(d,{verbose:ae});try{switch(g){case"list":{await At({bridge:d,simId:I,args:l});break}case"tree":{await Ct({bridge:d,args:l,positional:a});break}case"a11y":{let o=await Qe(d);if(!Array.isArray(o)||o.length===0){console.log(" no accessible nodes found");break}if(e.includes("--json"))console.log(JSON.stringify(o,null,2));else{console.log(` accessibility tree (${o.length} nodes):
346
- `);for(let t of o){let s=[];if(s.push(`[${t.role}]`),t.label){let r=t.label.length>50?t.label.slice(0,47)+"...":t.label;s.push(`"${r}"`)}if(t.hint&&s.push(`(hint: "${t.hint}")`),t.testID&&s.push(`#${t.testID}`),t.state){let r=[];t.state.disabled&&r.push("disabled"),t.state.selected&&r.push("selected"),t.state.checked===!0&&r.push("checked"),t.state.checked==="mixed"&&r.push("mixed"),t.state.busy&&r.push("busy"),t.state.expanded===!0&&r.push("expanded"),t.state.expanded===!1&&r.push("collapsed"),r.length&&s.push(`{${r.join(", ")}}`)}t.position&&s.push(`@(${t.position.x},${t.position.y})`),t.size&&s.push(`${t.size.w}x${t.size.h}`),console.log(" "+s.join(" "))}}break}case"find":{await Ft({bridge:d,args:e,effectiveArgs:l,positional:a,inspectUsage:k});break}case"count":{await It(d,{args:l});break}case"keyboard":{await _t(d,{json:e.includes("--json")});break}case"screens":{await Pt(d,{json:e.includes("--json")});break}case"memory":{await Ot(d,{args:l});break}case"wait":{await Bt({wsPort:_,commandTimeoutMs:j,simId:I,simIdSource:O,positional:a});break}case"sleep":{await Et({positional:a,inspectUsage:k});break}case"settle":{await Rt({bridge:d,args:e,positional:a});break}case"ready":{await Wt({bridge:d,args:e});break}case"idle":{await Lt({bridge:d,args:e,positional:a});break}case"selector":{await qt({bridge:d,args:e,positional:a,inspectUsage:k});break}case"event":{await Jt({bridge:d,args:e,positional:a,inspectUsage:k});break}case"layout":{let o=a[1];o||(console.error(k("layout","<id>")),process.exit(1));let t=await d.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(o)}))()`});console.log(JSON.stringify(t,null,2));break}case"capture":case"screenshot":{let t=e.find((w,f)=>e[f-1]==="--output")||"/tmp/sootsim-inspect.png",s=await Yt(e,d),r={type:"screenshot"};s&&(r.crop=s);let u=(await d.send(r)).replace(/^data:image\/png;base64,/,"");s&&console.log(` area: x=${s.x} y=${s.y} w=${s.w} h=${s.h}`),(await import("fs")).writeFileSync(t,Buffer.from(u,"base64")),console.log(` saved: ${t}`);break}case"sample-color":{let o=await Yt(e,d);o||(console.error(k("sample-color","<x> <y> [w] [h] | --id <testID> | --text <text>")),console.error(" samples an averaged color from the canvas. coords are logical sootsim units."),process.exit(1));let t=await d.send({type:"evaluate",code:ht(o)});if(e.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:r,b:i,a:u,hex:p,samples:w}=t,f=o.w===1&&o.h===1?`@(${o.x},${o.y})`:`@(${o.x},${o.y}) ${o.w}x${o.h}`;console.log(` ${p} rgba(${s}, ${r}, ${i}, ${u}) ${f} ${w} samples`)}break}case"node":{let o=a[1];o||(console.error(k("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let t=await d.send({type:"evaluate",code:`(async () => {
346
+ since last: ${i.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await Ie(o,"SootSim.bridges.timeline.cursorAdvance",t,s.summary.lastAt)}catch{}}let me=new Set(["tap","double-tap","tap-text","tap-id","type","type-into","key","key-sequence","keycode","drag","swipe","long-press","touch","gesture","pinch","scroll","shell"]),D=new Set(["a11y","capture","count","double-tap","drag","find","gesture","layout","long-press","node","pinch","sample-color","scroll","screenshot","swipe","tap","tap-id","tap-text","touch","tree","type-into"]),ae=(e.includes("--verbose")||e.includes("-v"))&&!e.includes("--json");y==="do"&&g==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),me.has(g)&&await He(d),D.has(g)&&await ce(d,{verbose:ae});try{switch(g){case"list":{await Rt({bridge:d,simId:I,args:l});break}case"tree":{await jt({bridge:d,args:l,positional:a});break}case"a11y":{let o=await et(d);if(!Array.isArray(o)||o.length===0){console.log(" no accessible nodes found");break}if(e.includes("--json"))console.log(JSON.stringify(o,null,2));else{console.log(` accessibility tree (${o.length} nodes):
347
+ `);for(let t of o){let s=[];if(s.push(`[${t.role}]`),t.label){let r=t.label.length>50?t.label.slice(0,47)+"...":t.label;s.push(`"${r}"`)}if(t.hint&&s.push(`(hint: "${t.hint}")`),t.testID&&s.push(`#${t.testID}`),t.state){let r=[];t.state.disabled&&r.push("disabled"),t.state.selected&&r.push("selected"),t.state.checked===!0&&r.push("checked"),t.state.checked==="mixed"&&r.push("mixed"),t.state.busy&&r.push("busy"),t.state.expanded===!0&&r.push("expanded"),t.state.expanded===!1&&r.push("collapsed"),r.length&&s.push(`{${r.join(", ")}}`)}t.position&&s.push(`@(${t.position.x},${t.position.y})`),t.size&&s.push(`${t.size.w}x${t.size.h}`),console.log(" "+s.join(" "))}}break}case"find":{await Ot({bridge:d,args:e,effectiveArgs:l,positional:a,inspectUsage:k});break}case"count":{await Ft(d,{args:l});break}case"keyboard":{await Pt(d,{json:e.includes("--json")});break}case"screens":{await Ct(d,{json:e.includes("--json")});break}case"memory":{await Et(d,{args:l});break}case"wait":{await Lt({wsPort:_,commandTimeoutMs:j,simId:I,simIdSource:R,positional:a});break}case"sleep":{await Bt({positional:a,inspectUsage:k});break}case"settle":{await Dt({bridge:d,args:e,positional:a});break}case"ready":{await Ut({bridge:d,args:e});break}case"idle":{await Ht({bridge:d,args:e,positional:a});break}case"selector":{await Kt({bridge:d,args:e,positional:a,inspectUsage:k});break}case"event":{await qt({bridge:d,args:e,positional:a,inspectUsage:k});break}case"layout":{let o=a[1];if(!o){await At({bridge:d,args:l});break}let t=await d.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(o)}))()`});console.log(JSON.stringify(t,null,2));break}case"capture":case"screenshot":{let t=e.find((w,f)=>e[f-1]==="--output")||"/tmp/sootsim-inspect.png",s=await Vt(e,d),r={type:"screenshot"};s&&(r.crop=s);let u=(await d.send(r)).replace(/^data:image\/png;base64,/,"");s&&console.log(` area: x=${s.x} y=${s.y} w=${s.w} h=${s.h}`),(await import("fs")).writeFileSync(t,Buffer.from(u,"base64")),console.log(` saved: ${t}`);break}case"sample-color":{let o=await Vt(e,d);o||(console.error(k("sample-color","<x> <y> [w] [h] | --id <testID> | --text <text>")),console.error(" samples an averaged color from the canvas. coords are logical sootsim units."),process.exit(1));let t=await d.send({type:"evaluate",code:wt(o)});if(e.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:r,b:i,a:u,hex:p,samples:w}=t,f=o.w===1&&o.h===1?`@(${o.x},${o.y})`:`@(${o.x},${o.y}) ${o.w}x${o.h}`;console.log(` ${p} rgba(${s}, ${r}, ${i}, ${u}) ${f} ${w} samples`)}break}case"node":{let o=a[1];o||(console.error(k("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let t=await d.send({type:"evaluate",code:`(async () => {
347
348
  const t = window.__sootsimTest
348
349
  const q = ${JSON.stringify(o)}
349
350
  let node = null
@@ -399,17 +400,17 @@ ${s}
399
400
  transform,
400
401
  parentChain,
401
402
  }
402
- })()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let o=Number(a[1]),t=Number(a[2]),s=ge(e);if(s){let u=await fe(d,{agent:de(),textFallback:s.mode==="text"?s.value:void 0,resolve:async()=>{let f=await $e(d,s);return f?{cx:f.x,cy:f.y,match:{id:s.mode==="testid"?s.value:f.id??null,testID:s.mode==="testid"?s.value:f.testID??null,text:s.mode==="text"?s.value:f.text??null,type:f.type??null},target:{id:f.id??null,testID:f.testID??null,text:f.text??null,type:f.type??null}}:null}}),p=u.payload;(!p||typeof p.cx!="number")&&(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),ce(u.result)||(N(`${s.mode} "${s.value}"`,u),process.exit(1));let w=Xt(p.cx,p.cy,u.result);w&&await J("inspect tap",w.step,w.summary),console.log(JSON.stringify({...u.attempts>1?{attempts:u.attempts}:{},...u.result},null,2));break}(!Number.isFinite(o)||!Number.isFinite(t))&&(console.error(k("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let r=await vt(d,o,t),i=Xt(o,t,r);i&&await J("inspect tap",i.step,i.summary),console.log(JSON.stringify(r,null,2));break}case"drag":case"swipe":{let o=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),i=g==="swipe"?10:12,u=g==="swipe"?8:16,p=a[5]?Number(a[5]):i,w=a[6]?Number(a[6]):u;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(p)||!Number.isFinite(w))&&(console.error(k(g,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await d.send({type:"evaluate",code:`(async () => {
403
+ })()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let o=Number(a[1]),t=Number(a[2]),s=ye(e);if(s){let u=await ge(d,{agent:ue(),textFallback:s.mode==="text"?s.value:void 0,resolve:async()=>{let f=await $e(d,s);return f?{cx:f.x,cy:f.y,match:{id:s.mode==="testid"?s.value:f.id??null,testID:s.mode==="testid"?s.value:f.testID??null,text:s.mode==="text"?s.value:f.text??null,type:f.type??null},target:{id:f.id??null,testID:f.testID??null,text:f.text??null,type:f.type??null}}:null}}),p=u.payload;(!p||typeof p.cx!="number")&&(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),de(u.result)||(N(`${s.mode} "${s.value}"`,u),process.exit(1));let w=Zt(p.cx,p.cy,u.result);w&&await J("inspect tap",w.step,w.summary),console.log(JSON.stringify({...u.attempts>1?{attempts:u.attempts}:{},...u.result},null,2));break}(!Number.isFinite(o)||!Number.isFinite(t))&&(console.error(k("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let r=await Tt(d,o,t),i=Zt(o,t,r);i&&await J("inspect tap",i.step,i.summary),console.log(JSON.stringify(r,null,2));break}case"drag":case"swipe":{let o=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),i=g==="swipe"?10:12,u=g==="swipe"?8:16,p=a[5]?Number(a[5]):i,w=a[6]?Number(a[6]):u;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(p)||!Number.isFinite(w))&&(console.error(k(g,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await d.send({type:"evaluate",code:`(async () => {
403
404
  const interact = window.__sootsimInteract
404
405
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
405
406
  const value = await interact.drag(${o}, ${t}, ${s}, ${r}, ${Math.max(1,Math.round(p))}, ${Math.max(0,Math.round(w))})
406
407
  return { ok: !!value, value }
407
- })()`});if(f?.ok){let x=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,w)));await J(`inspect ${g}`,{swipe:{start:`${o}, ${t}`,end:`${s}, ${r}`,duration:x}},`${g} ${o},${t} -> ${s},${r}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let o=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),i=Number(a[5]),u=Number(a[6]),p=Number(a[7]),w=Number(a[8]),f=a[9]?Number(a[9]):12,x=a[10]?Number(a[10]):16;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(i)||!Number.isFinite(u)||!Number.isFinite(p)||!Number.isFinite(w)||!Number.isFinite(f)||!Number.isFinite(x))&&(console.error(k("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let A=await d.send({type:"evaluate",code:`(async () => {
408
+ })()`});if(f?.ok){let x=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,w)));await J(`inspect ${g}`,{swipe:{start:`${o}, ${t}`,end:`${s}, ${r}`,duration:x}},`${g} ${o},${t} -> ${s},${r}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let o=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),i=Number(a[5]),u=Number(a[6]),p=Number(a[7]),w=Number(a[8]),f=a[9]?Number(a[9]):12,x=a[10]?Number(a[10]):16;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(i)||!Number.isFinite(u)||!Number.isFinite(p)||!Number.isFinite(w)||!Number.isFinite(f)||!Number.isFinite(x))&&(console.error(k("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let O=await d.send({type:"evaluate",code:`(async () => {
408
409
  const interact = window.__sootsimInteract
409
410
  if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
410
411
  const value = await interact.pinch(${o}, ${t}, ${s}, ${r}, ${i}, ${u}, ${p}, ${w}, ${Math.max(1,Math.round(f))}, ${Math.max(0,Math.round(x))})
411
412
  return { ok: !!value, value }
412
- })()`});A?.ok&&await J("inspect pinch",{pinch:{from:[o,t,s,r],to:[i,u,p,w],steps:Math.max(1,Math.round(f)),stepMs:Math.max(0,Math.round(x))}},`pinch (${o},${t}) (${s},${r}) -> (${i},${u}) (${p},${w})`),console.log(JSON.stringify(A,null,2));break}case"tap-text":{let o=a[1];o||(console.error(k("tap-text","<text>")),process.exit(1));let t=K=>{let P=e.indexOf(K);return P>=0&&P+1<e.length?e[P+1]:null},s=K=>e.includes(K),r=t("--nth")??t("--index"),i=r!==null?Number(r):null;i!==null&&!Number.isFinite(i)&&(console.error(` --nth/--index requires an integer, got: ${r}`),process.exit(1));let u=t("--within"),p=t("--role"),w=s("--exact"),f=s("--first"),x=t("--min-y"),A=t("--max-y"),q=t("--min-x"),H=t("--max-x");for(let[K,P]of[["--min-y",x],["--max-y",A],["--min-x",q],["--max-x",H]])P!==null&&!Number.isFinite(Number(P))&&(console.error(` ${K} requires a number, got: ${P}`),process.exit(1));let U=e.indexOf("--near"),F=null;if(U>=0){let K=Number(e[U+1]),P=Number(e[U+2]);(!Number.isFinite(K)||!Number.isFinite(P))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),F={x:K,y:P}}let b={exact:w,role:p,within:u,minX:q!==null?Number(q):null,maxX:H!==null?Number(H):null,minY:x!==null?Number(x):null,maxY:A!==null?Number(A):null,near:F,nth:i,first:f},$=await Tt(d,o,b,{agent:de()}),v=$.payload;if(v?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),v?.ambiguous){let K=v.candidates;console.error(` ambiguous: ${v.total} matches for "${o}"`);for(let P of K){let ye=P.abs?`@(${Math.round(P.abs.x)},${Math.round(P.abs.y)})`:"",eo=P.layout?` ${P.layout.width}x${P.layout.height}`:"",to=P.testID?` #${P.testID}`:"",oo=P.text?` "${P.text}"`:"",so=P.ancestorTestIDs.length>0?` within ${P.ancestorTestIDs.slice(0,3).map(no=>`#${no}`).join(" > ")}`:"";console.error(` [${P.idx}] <${P.type}>${oo}${to} ${ye}${eo}${so}`)}v.total>K.length&&console.error(` ... and ${v.total-K.length} more`),console.error(" pick one:"),console.error(" --nth <index> pick the nth match (top-to-bottom, left-to-right; negatives from end)"),console.error(" --within <testID> narrow to descendants of a node"),console.error(" --min-y / --max-y geometric filter (pixels, absolute)"),console.error(" --min-x / --max-x geometric filter (pixels, absolute)"),console.error(" --near <x> <y> pick the closest match to a point"),console.error(" --exact exact text match (default is substring)"),console.error(" --role <role> narrow to accessibilityRole"),console.error(" --first keep the old pick-first-silently behavior"),process.exit(2)}v?.nthOutOfRange&&(console.error(` not found: nth ${v.nth} of ${v.total} match${v.total===1?"":"es"} for "${o}"`),process.exit(1)),(!v||typeof v.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),ce($.result)||(N(`text "${o}"`,$),process.exit(1));let oe=De(o,{id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},"text");await J("inspect tap-text",oe.step,oe.summary),console.log(JSON.stringify({matched:v.match,tapped:{nodeId:v.target?.nodeId??null,id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},...v.strategy&&v.strategy!=="matched-node"?{strategy:v.strategy}:{},...v.total>1||i!==null?{nth:{index:v.idx,total:v.total}}:{},...$.attempts>1?{attempts:$.attempts}:{},result:$.result},null,2));break}case"tap-best":{let o=a[1];o||(console.error(k("tap-best","<query>")),process.exit(1));let t=await Mt(d,o,{agent:de()}),s=t.payload;s||(console.error(` tap-best: no testID or visible text matched "${o}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1)),"error"in s&&(console.error(` ${s.error}`),process.exit(1)),s.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${o}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1));let r=s.node;ce(t.result)||(N(`best "${o}"`,t),process.exit(1));let i=De(o,{id:r.id,testID:r.testID,type:r.type,cx:s.cx,cy:s.cy},s.strategy==="testid"?"id":"text");await J("inspect tap-best",i.step,i.summary),console.log(JSON.stringify({matched:{strategy:s.strategy,nodeId:r.nodeId,id:r.id,testID:r.testID,type:r.type,text:r.text},tapped:{cx:s.cx,cy:s.cy},...t.attempts>1?{attempts:t.attempts}:{},result:t.result},null,2));break}case"tap-id":{let o=a[1];o||(console.error(k("tap-id","<id>")),process.exit(1));let t=await kt(d,o,{agent:de()}),s=t.payload;(!s||typeof s.cx!="number")&&(console.error(` not found: ${o}`),await Fo(d,o),process.exit(1)),ce(t.result)||(N(`id "${o}"`,t),process.exit(1));let r=De(o,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await J("inspect tap-id",r.step,r.summary),console.log(JSON.stringify({matched:s.match,tapped:{nodeId:s.target?.nodeId??null,id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},...s.strategy&&s.strategy!=="matched-node"?{strategy:s.strategy}:{},...t.attempts>1?{attempts:t.attempts}:{},result:t.result},null,2));break}case"type-into":{let o=a[1],t=a.slice(2).join(" ");(!o||!t)&&(console.error(k("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(o),r=await d.send({type:"evaluate",code:`(async () => {
413
+ })()`});O?.ok&&await J("inspect pinch",{pinch:{from:[o,t,s,r],to:[i,u,p,w],steps:Math.max(1,Math.round(f)),stepMs:Math.max(0,Math.round(x))}},`pinch (${o},${t}) (${s},${r}) -> (${i},${u}) (${p},${w})`),console.log(JSON.stringify(O,null,2));break}case"tap-text":{let o=a[1];o||(console.error(k("tap-text","<text>")),process.exit(1));let t=K=>{let E=e.indexOf(K);return E>=0&&E+1<e.length?e[E+1]:null},s=K=>e.includes(K),r=t("--nth")??t("--index"),i=r!==null?Number(r):null;i!==null&&!Number.isFinite(i)&&(console.error(` --nth/--index requires an integer, got: ${r}`),process.exit(1));let u=t("--within"),p=t("--role"),w=s("--exact"),f=s("--first"),x=t("--min-y"),O=t("--max-y"),q=t("--min-x"),H=t("--max-x");for(let[K,E]of[["--min-y",x],["--max-y",O],["--min-x",q],["--max-x",H]])E!==null&&!Number.isFinite(Number(E))&&(console.error(` ${K} requires a number, got: ${E}`),process.exit(1));let U=e.indexOf("--near"),F=null;if(U>=0){let K=Number(e[U+1]),E=Number(e[U+2]);(!Number.isFinite(K)||!Number.isFinite(E))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),F={x:K,y:E}}let b={exact:w,role:p,within:u,minX:q!==null?Number(q):null,maxX:H!==null?Number(H):null,minY:x!==null?Number(x):null,maxY:O!==null?Number(O):null,near:F,nth:i,first:f},$=await It(d,o,b,{agent:ue()}),v=$.payload;if(v?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),v?.ambiguous){let K=v.candidates;console.error(` ambiguous: ${v.total} matches for "${o}"`);for(let E of K){let he=E.abs?`@(${Math.round(E.abs.x)},${Math.round(E.abs.y)})`:"",so=E.layout?` ${E.layout.width}x${E.layout.height}`:"",no=E.testID?` #${E.testID}`:"",ro=E.text?` "${E.text}"`:"",io=E.ancestorTestIDs.length>0?` within ${E.ancestorTestIDs.slice(0,3).map(ao=>`#${ao}`).join(" > ")}`:"";console.error(` [${E.idx}] <${E.type}>${ro}${no} ${he}${so}${io}`)}v.total>K.length&&console.error(` ... and ${v.total-K.length} more`),console.error(" pick one:"),console.error(" --nth <index> pick the nth match (top-to-bottom, left-to-right; negatives from end)"),console.error(" --within <testID> narrow to descendants of a node"),console.error(" --min-y / --max-y geometric filter (pixels, absolute)"),console.error(" --min-x / --max-x geometric filter (pixels, absolute)"),console.error(" --near <x> <y> pick the closest match to a point"),console.error(" --exact exact text match (default is substring)"),console.error(" --role <role> narrow to accessibilityRole"),console.error(" --first keep the old pick-first-silently behavior"),process.exit(2)}v?.nthOutOfRange&&(console.error(` not found: nth ${v.nth} of ${v.total} match${v.total===1?"":"es"} for "${o}"`),process.exit(1)),(!v||typeof v.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),de($.result)||(N(`text "${o}"`,$),process.exit(1));let oe=De(o,{id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},"text");await J("inspect tap-text",oe.step,oe.summary),console.log(JSON.stringify({matched:v.match,tapped:{nodeId:v.target?.nodeId??null,id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},...v.strategy&&v.strategy!=="matched-node"?{strategy:v.strategy}:{},...v.total>1||i!==null?{nth:{index:v.idx,total:v.total}}:{},...$.attempts>1?{attempts:$.attempts}:{},result:$.result},null,2));break}case"tap-best":{let o=a[1];o||(console.error(k("tap-best","<query>")),process.exit(1));let t=await Nt(d,o,{agent:ue()}),s=t.payload;s||(console.error(` tap-best: no testID or visible text matched "${o}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1)),"error"in s&&(console.error(` ${s.error}`),process.exit(1)),s.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${o}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1));let r=s.node;de(t.result)||(N(`best "${o}"`,t),process.exit(1));let i=De(o,{id:r.id,testID:r.testID,type:r.type,cx:s.cx,cy:s.cy},s.strategy==="testid"?"id":"text");await J("inspect tap-best",i.step,i.summary),console.log(JSON.stringify({matched:{strategy:s.strategy,nodeId:r.nodeId,id:r.id,testID:r.testID,type:r.type,text:r.text},tapped:{cx:s.cx,cy:s.cy},...t.attempts>1?{attempts:t.attempts}:{},result:t.result},null,2));break}case"tap-id":{let o=a[1];o||(console.error(k("tap-id","<id>")),process.exit(1));let t=await Mt(d,o,{agent:ue()}),s=t.payload;(!s||typeof s.cx!="number")&&(console.error(` not found: ${o}`),await Ao(d,o),process.exit(1)),de(t.result)||(N(`id "${o}"`,t),process.exit(1));let r=De(o,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await J("inspect tap-id",r.step,r.summary),console.log(JSON.stringify({matched:s.match,tapped:{nodeId:s.target?.nodeId??null,id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},...s.strategy&&s.strategy!=="matched-node"?{strategy:s.strategy}:{},...t.attempts>1?{attempts:t.attempts}:{},result:t.result},null,2));break}case"type-into":{let o=a[1],t=a.slice(2).join(" ");(!o||!t)&&(console.error(k("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(o),r=await d.send({type:"evaluate",code:`(async () => {
413
414
  const t = window.__sootsimTest
414
415
  if (!t) return null
415
416
  const n = await (t.findByTestId(${s}) || t.findById(${s}))
@@ -423,7 +424,7 @@ ${s}
423
424
  isTextInput: !!n.isTextInput,
424
425
  placeholder: n.placeholder || null,
425
426
  }
426
- })()`});(!r||typeof r.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),r.isTextInput||console.error(` warning: ${o} is not a text input (isTextInput: false)`);let i=await d.send({type:"tap",x:r.cx,y:r.cy,target:{id:r.id??o,testID:r.testID??o,text:null,type:r.type??null}}),u=await Bo(d);u.visible||(console.error(` keyboard did not open after tapping ${o}`),process.exit(1));let p=u.focusedInput;p&&(p.testID===o||p.id===o||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(o)} but focus is on ${JSON.stringify(p.testID??p.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await d.send({type:"keyboard",action:"type",text:t}),await J("inspect type-into",{tapOn:{id:o},inputText:t},`type-into #${o} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:o,isTextInput:r.isTextInput,keyboardOpened:u.visible??i?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:t},null,2));break}case"type":{let o=a.slice(1).join(" ");o||(console.error(k("type","<text>")),process.exit(1)),await ke(d,"type"),await d.send({type:"keyboard",action:"type",text:o}),await J("inspect type",{inputText:o},`type ${JSON.stringify(o)}`),console.log(` typed: ${JSON.stringify(o)}`);break}case"key":{let o=a[1];o||(console.error(k("key","<name>")),process.exit(1)),await ke(d,"key"),await d.send({type:"keyboard",action:"press",text:o}),await J("inspect key",{pressKey:o},`key ${o}`),console.log(` pressed: ${o}`);break}case"key-sequence":{let o=a.slice(1);o.length===0&&(console.error(k("key-sequence","<key> [<key> ...]")),process.exit(1)),await ke(d,"key-sequence");for(let t of o)await d.send({type:"keyboard",action:"press",text:t});await J("inspect key-sequence",{pressKey:o.join(" ")},`key-sequence ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"keycode":{let o=a.slice(1);o.length===0&&(console.error(k("keycode","<code> [<code> ...]")),process.exit(1));let t=o.map(r=>({code:r,key:jo(r)})),s=t.filter(r=>!r.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(r=>r.code).join(", ")}`),process.exit(1)),await ke(d,"keycode");for(let r of t)await d.send({type:"keyboard",action:"press",text:r.key});await J("inspect keycode",{pressKey:t.map(r=>r.key).join(" ")},`keycode ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"dispatch":{let o=a[1];o||(console.error(k("dispatch","<char>")),process.exit(1)),await d.send({type:"keyboard",action:"dispatchKey",text:o}),await J("inspect dispatch",{dispatchKey:o},`dispatch ${JSON.stringify(o)}`),console.log(` dispatched: ${o}`);break}case"dismiss":{await d.send({type:"keyboard",action:"dismiss"}),await J("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let o=Number(a[1]),t=Number(a[2]),s=ge(e);if(s){let p=await $e(d,s);p||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),o=p.x,t=p.y}let r=a[3]?Number(a[3]):80;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(r))&&(console.error(k("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let i=Math.max(0,Math.round(r)),u=await d.send({type:"evaluate",code:`(async () => {
427
+ })()`});(!r||typeof r.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),r.isTextInput||console.error(` warning: ${o} is not a text input (isTextInput: false)`);let i=await d.send({type:"tap",x:r.cx,y:r.cy,target:{id:r.id??o,testID:r.testID??o,text:null,type:r.type??null}}),u=await Lo(d);u.visible||(console.error(` keyboard did not open after tapping ${o}`),process.exit(1));let p=u.focusedInput;p&&(p.testID===o||p.id===o||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(o)} but focus is on ${JSON.stringify(p.testID??p.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await d.send({type:"keyboard",action:"type",text:t}),await J("inspect type-into",{tapOn:{id:o},inputText:t},`type-into #${o} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:o,isTextInput:r.isTextInput,keyboardOpened:u.visible??i?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:t},null,2));break}case"type":{let o=a.slice(1).join(" ");o||(console.error(k("type","<text>")),process.exit(1)),await ke(d,"type"),await d.send({type:"keyboard",action:"type",text:o}),await J("inspect type",{inputText:o},`type ${JSON.stringify(o)}`),console.log(` typed: ${JSON.stringify(o)}`);break}case"key":{let o=a[1];o||(console.error(k("key","<name>")),process.exit(1)),await ke(d,"key"),await d.send({type:"keyboard",action:"press",text:o}),await J("inspect key",{pressKey:o},`key ${o}`),console.log(` pressed: ${o}`);break}case"key-sequence":{let o=a.slice(1);o.length===0&&(console.error(k("key-sequence","<key> [<key> ...]")),process.exit(1)),await ke(d,"key-sequence");for(let t of o)await d.send({type:"keyboard",action:"press",text:t});await J("inspect key-sequence",{pressKey:o.join(" ")},`key-sequence ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"keycode":{let o=a.slice(1);o.length===0&&(console.error(k("keycode","<code> [<code> ...]")),process.exit(1));let t=o.map(r=>({code:r,key:Wo(r)})),s=t.filter(r=>!r.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(r=>r.code).join(", ")}`),process.exit(1)),await ke(d,"keycode");for(let r of t)await d.send({type:"keyboard",action:"press",text:r.key});await J("inspect keycode",{pressKey:t.map(r=>r.key).join(" ")},`keycode ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"dispatch":{let o=a[1];o||(console.error(k("dispatch","<char>")),process.exit(1)),await d.send({type:"keyboard",action:"dispatchKey",text:o}),await J("inspect dispatch",{dispatchKey:o},`dispatch ${JSON.stringify(o)}`),console.log(` dispatched: ${o}`);break}case"dismiss":{await d.send({type:"keyboard",action:"dismiss"}),await J("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let o=Number(a[1]),t=Number(a[2]),s=ye(e);if(s){let p=await $e(d,s);p||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),o=p.x,t=p.y}let r=a[3]?Number(a[3]):80;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(r))&&(console.error(k("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let i=Math.max(0,Math.round(r)),u=await d.send({type:"evaluate",code:`(async () => {
427
428
  const interact = window.__sootsimInteract
428
429
  if (interact?.doubleTap) {
429
430
  return {
@@ -446,7 +447,7 @@ ${s}
446
447
  first,
447
448
  second,
448
449
  }
449
- })()`});u?.ok&&await J("inspect double-tap",{doubleTapAtCoords:{x:o,y:t,gapMs:i}},`double-tap @${o},${t}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let o=Number(a[1]),t=Number(a[2]),s=ge(e);if(s){let u=await $e(d,s);u||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),o=u.x,t=u.y}let r=a[3]?Number(a[3]):600;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(r))&&(console.error(k("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let i=await d.send({type:"evaluate",code:`(async () => {
450
+ })()`});u?.ok&&await J("inspect double-tap",{doubleTapAtCoords:{x:o,y:t,gapMs:i}},`double-tap @${o},${t}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let o=Number(a[1]),t=Number(a[2]),s=ye(e);if(s){let u=await $e(d,s);u||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),o=u.x,t=u.y}let r=a[3]?Number(a[3]):600;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(r))&&(console.error(k("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let i=await d.send({type:"evaluate",code:`(async () => {
450
451
  const interact = window.__sootsimInteract
451
452
  if (!interact?.longPress) return { ok: false, reason: 'no interact.longPress' }
452
453
  const value = await interact.longPress(${o}, ${t}, ${Math.max(0,Math.round(r))})
@@ -465,12 +466,12 @@ ${s}
465
466
  statusBarHeight: spec.statusBarHeight || 0,
466
467
  homeIndicatorHeight: spec.homeIndicatorHeight || 0,
467
468
  }
468
- })()`}),i=Number(r?.width)||393,u=Number(r?.height)||852,p=Number(r?.statusBarHeight)||0,w=Number(r?.homeIndicatorHeight)||0,f=Math.round(i/2),x=Math.round(u/2),A=Math.max(24,p+18),q=Math.max(24,w+18),H=18,U=Math.min(220,Math.round(u*.24)),F=Math.min(180,Math.round(i*.32)),b=f,$=x,v=f,oe=x;switch(t){case"scroll-up":$=x+Math.round(U/2),oe=x-Math.round(U/2);break;case"scroll-down":$=x-Math.round(U/2),oe=x+Math.round(U/2);break;case"scroll-left":b=f+Math.round(F/2),v=f-Math.round(F/2);break;case"scroll-right":b=f-Math.round(F/2),v=f+Math.round(F/2);break;case"swipe-from-left-edge":b=H,$=x,v=Math.min(i-H,H+F);break;case"swipe-from-right-edge":b=i-H,$=x,v=Math.max(H,i-H-F);break;case"swipe-from-top-edge":b=f,$=A,oe=Math.min(u-q,A+U);break;case"swipe-from-bottom-edge":b=f,$=u-q,oe=Math.max(A,u-q-U);break}let K=Math.max(8,Math.round(s/16)),P=Math.max(1,Math.round(s/K)),ye=await d.send({type:"evaluate",code:`(async () => {
469
+ })()`}),i=Number(r?.width)||393,u=Number(r?.height)||852,p=Number(r?.statusBarHeight)||0,w=Number(r?.homeIndicatorHeight)||0,f=Math.round(i/2),x=Math.round(u/2),O=Math.max(24,p+18),q=Math.max(24,w+18),H=18,U=Math.min(220,Math.round(u*.24)),F=Math.min(180,Math.round(i*.32)),b=f,$=x,v=f,oe=x;switch(t){case"scroll-up":$=x+Math.round(U/2),oe=x-Math.round(U/2);break;case"scroll-down":$=x-Math.round(U/2),oe=x+Math.round(U/2);break;case"scroll-left":b=f+Math.round(F/2),v=f-Math.round(F/2);break;case"scroll-right":b=f-Math.round(F/2),v=f+Math.round(F/2);break;case"swipe-from-left-edge":b=H,$=x,v=Math.min(i-H,H+F);break;case"swipe-from-right-edge":b=i-H,$=x,v=Math.max(H,i-H-F);break;case"swipe-from-top-edge":b=f,$=O,oe=Math.min(u-q,O+U);break;case"swipe-from-bottom-edge":b=f,$=u-q,oe=Math.max(O,u-q-U);break}let K=Math.max(8,Math.round(s/16)),E=Math.max(1,Math.round(s/K)),he=await d.send({type:"evaluate",code:`(async () => {
469
470
  const interact = window.__sootsimInteract
470
471
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
471
- const value = await interact.drag(${b}, ${$}, ${v}, ${oe}, ${K}, ${P})
472
+ const value = await interact.drag(${b}, ${$}, ${v}, ${oe}, ${K}, ${E})
472
473
  return { ok: !!value, value }
473
- })()`});ye?.ok&&await J("inspect gesture",{swipe:{start:`${b}, ${$}`,end:`${v}, ${oe}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:b,y:$},to:{x:v,y:oe},result:ye},null,2));break}case"scroll":{let o=ge(e),t=Lo(e),s=o?.mode==="testid"?o.value:t==null?a[1]:null,r=o||t!=null?1:2,i=Number(a[r]),u=Number(a[r+1]);(!s&&t==null||!Number.isFinite(i)||!Number.isFinite(u))&&(console.error(k("scroll","<id> <x> <y> | --testid <id> <x> <y> | --node-id <nodeId> <x> <y>")),process.exit(1));let p=await d.send({type:"evaluate",code:`(async () => {
474
+ })()`});he?.ok&&await J("inspect gesture",{swipe:{start:`${b}, ${$}`,end:`${v}, ${oe}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:b,y:$},to:{x:v,y:oe},result:he},null,2));break}case"scroll":{let o=ye(e),t=Ho(e),s=o?.mode==="testid"?o.value:t==null?a[1]:null,r=o||t!=null?1:2,i=Number(a[r]),u=Number(a[r+1]);(!s&&t==null||!Number.isFinite(i)||!Number.isFinite(u))&&(console.error(k("scroll","<id> <x> <y> | --testid <id> <x> <y> | --node-id <nodeId> <x> <y>")),process.exit(1));let p=await d.send({type:"evaluate",code:`(async () => {
474
475
  const t = window.__sootsimTest
475
476
  if (!t) return null
476
477
  const n = ${t!=null?`await t.inspectByNodeId(${JSON.stringify(t)})`:`await t.findByTestId(${JSON.stringify(s)})
@@ -561,7 +562,7 @@ ${s}
561
562
  ${h("shell")} open-card clock 800
562
563
  ${h("shell")} appearance dark
563
564
  ${h("shell")} lock
564
- `);break}let t=o==="launch"||o==="open-card"||o==="home"||o==="switcher",s=o==="launch"||o==="open-card"?a[3]:a[2],r=s?Number(s):350;t&&(!Number.isFinite(r)||r<0)&&(console.error(k("shell",o==="launch"||o==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let i=!1,u=!1,p=null,w=e.includes("--clear-state");if(o==="launch"){let f=a[2];f||(console.error(k("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),w&&await d.send({type:"evaluate",code:Ke}),i=!!await me(d,"launchApp",r,f),{settled:u,state:p}=await ve(d,Math.round(r),x=>!!x&&x.state==="app"&&x.activeApp===f&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.launchProgress=="number"&&x.launchProgress>=.98),i&&await J("inspect shell launch",w?{launchApp:{clearState:!0}}:{launchApp:{}},w?"launch app (clear state)":"launch app")}else if(o==="home")i=!!await me(d,"goHome",r),{settled:u,state:p}=await ve(d,Math.round(r),f=>!!f&&f.state==="home"&&f.activeApp==null&&f.showSwitcher===!1&&f.switcherPhase==="idle"&&typeof f.launchProgress=="number"&&f.launchProgress>=.98);else if(o==="switcher")i=!!await me(d,"openSwitcher",r),{settled:u,state:p}=await ve(d,Math.round(r),f=>!!f&&f.state==="app"&&f.showSwitcher===!0&&f.switcherPhase==="idle"&&typeof f.zoomLevel=="number"&&Math.abs(f.zoomLevel)<=.02&&typeof f.horizontalZoom=="number"&&Math.abs(f.horizontalZoom)<=.02),u&&(await Z(Do),p=await le(d));else if(o==="open-card"){let f=a[2];f||(console.error(k("shell","open-card <appId> [settleMs]")),process.exit(1)),i=!!await me(d,"openSwitcherCard",r,f),{settled:u,state:p}=await ve(d,Math.round(r),x=>!!x&&x.state==="app"&&x.activeApp===f&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.zoomLevel=="number"&&x.zoomLevel>=.98&&typeof x.horizontalZoom=="number"&&x.horizontalZoom>=.98),i&&await J("inspect shell open-card",{openSwitcherCard:{appId:f}},`open switcher card ${f}`)}else if(o==="appearance"){let f=a[2];(!f||!["light","dark","auto","toggle"].includes(f))&&(console.error(k("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let x=await Gt(d,"appearance",f);if(i=!!x?.ok,p={appearance:x},i){let A=x?.applied??f;console.log(` appearance: ${A}`)}}else if(o==="lock"||o==="shake"){let f=await Gt(d,o);i=!!f?.ok,p={[o]:f}}else console.error(` unknown shell subcommand: ${o}`),process.exit(1);console.log(JSON.stringify({ok:i,settled:u,state:p},null,2));break}case"url":{await Dt(d,{args:l});break}case"reload":{let s=!1,r=!1;try{await d.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let p=await d.send({type:"evaluate",code:`;(() => {
565
+ `);break}let t=o==="launch"||o==="open-card"||o==="home"||o==="switcher",s=o==="launch"||o==="open-card"?a[3]:a[2],r=s?Number(s):350;t&&(!Number.isFinite(r)||r<0)&&(console.error(k("shell",o==="launch"||o==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let i=!1,u=!1,p=null,w=e.includes("--clear-state");if(o==="launch"){let f=a[2];f||(console.error(k("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),w&&await d.send({type:"evaluate",code:Ke}),i=!!await pe(d,"launchApp",r,f),{settled:u,state:p}=await ve(d,Math.round(r),x=>!!x&&x.state==="app"&&x.activeApp===f&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.launchProgress=="number"&&x.launchProgress>=.98),i&&await J("inspect shell launch",w?{launchApp:{clearState:!0}}:{launchApp:{}},w?"launch app (clear state)":"launch app")}else if(o==="home")i=!!await pe(d,"goHome",r),{settled:u,state:p}=await ve(d,Math.round(r),f=>!!f&&f.state==="home"&&f.activeApp==null&&f.showSwitcher===!1&&f.switcherPhase==="idle"&&typeof f.launchProgress=="number"&&f.launchProgress>=.98);else if(o==="switcher")i=!!await pe(d,"openSwitcher",r),{settled:u,state:p}=await ve(d,Math.round(r),f=>!!f&&f.state==="app"&&f.showSwitcher===!0&&f.switcherPhase==="idle"&&typeof f.zoomLevel=="number"&&Math.abs(f.zoomLevel)<=.02&&typeof f.horizontalZoom=="number"&&Math.abs(f.horizontalZoom)<=.02),u&&(await Z(Jo),p=await le(d));else if(o==="open-card"){let f=a[2];f||(console.error(k("shell","open-card <appId> [settleMs]")),process.exit(1)),i=!!await pe(d,"openSwitcherCard",r,f),{settled:u,state:p}=await ve(d,Math.round(r),x=>!!x&&x.state==="app"&&x.activeApp===f&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.zoomLevel=="number"&&x.zoomLevel>=.98&&typeof x.horizontalZoom=="number"&&x.horizontalZoom>=.98),i&&await J("inspect shell open-card",{openSwitcherCard:{appId:f}},`open switcher card ${f}`)}else if(o==="appearance"){let f=a[2];(!f||!["light","dark","auto","toggle"].includes(f))&&(console.error(k("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let x=await Qt(d,"appearance",f);if(i=!!x?.ok,p={appearance:x},i){let O=x?.applied??f;console.log(` appearance: ${O}`)}}else if(o==="lock"||o==="shake"){let f=await Qt(d,o);i=!!f?.ok,p={[o]:f}}else console.error(` unknown shell subcommand: ${o}`),process.exit(1);console.log(JSON.stringify({ok:i,settled:u,state:p},null,2));break}case"url":{await Jt(d,{args:l});break}case"reload":{let s=!1,r=!1;try{await d.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let p=await d.send({type:"evaluate",code:`;(() => {
565
566
  const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
566
567
  if (typeof reloadExternalApp === 'function') {
567
568
  reloadExternalApp()
@@ -569,10 +570,10 @@ ${s}
569
570
  }
570
571
  window.location.reload()
571
572
  return { kind: 'page' }
572
- })()`});r=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let i=d,u=null;if(r)u=await Oe(d,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await Z(300);let p=await ft(_,j,I,{timeoutMs:1e4,simIdSource:O});p?(i=p,u=await Oe(p,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),i=null)}if(u)if(u.ready){let p=u.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${u.elapsedMs}ms: ${u.nodes} nodes${p}`)}else if(u.source==="error-bail")console.log(` \u26A0 reload bailed after ${u.elapsedMs}ms: ${u.errors} console error(s), ready signal never fired`);else{let p=Po(u);console.log(` \u26A0 reload timed out after ${u.elapsedMs}ms \u2014 ${p} (nodes: ${u.nodes}, targets: ${u.targets}, errors: ${u.errors})`)}if(i)try{let p=await i.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors(10) || []"});if(i!==d&&i.close(),Array.isArray(p)&&p.length>0){console.log(`
573
+ })()`});r=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let i=d,u=null;if(r)u=await Ae(d,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await Z(300);let p=await yt(_,j,I,{timeoutMs:1e4,simIdSource:R});p?(i=p,u=await Ae(p,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),i=null)}if(u)if(u.ready){let p=u.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${u.elapsedMs}ms: ${u.nodes} nodes${p}`)}else if(u.source==="error-bail")console.log(` \u26A0 reload bailed after ${u.elapsedMs}ms: ${u.errors} console error(s), ready signal never fired`);else{let p=Co(u);console.log(` \u26A0 reload timed out after ${u.elapsedMs}ms \u2014 ${p} (nodes: ${u.nodes}, targets: ${u.targets}, errors: ${u.errors})`)}if(i)try{let p=await i.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors(10) || []"});if(i!==d&&i.close(),Array.isArray(p)&&p.length>0){console.log(`
573
574
  \u26A0 ${p.length} error(s) during mount:
574
575
  `);for(let w of p){let f=w.args.map(x=>typeof x=="object"?JSON.stringify(x):x).join(" ");if(console.log(` ${f}`),w.stack){let x=w.stack.split(`
575
- `).slice(0,2);for(let A of x)console.log(` ${A.trim()}`)}}}}catch{}u&&!u.ready&&(process.exitCode=1);break}case"eval":case"js":{let o=a.slice(1).join(" ");o||(console.error(k("js","<javascript>")),console.error(""),console.error(" runs the snippet in the engine realm. SootSim is the"),console.error(" canonical state surface \u2014 reach into it directly."),console.error(""),console.error(" examples:"),console.error(` ${h("js")} SootSim.bridges.test.findByText("Sign in")`),console.error(` ${h("js")} SootSim.bridges.debug.snapshot("before")`),console.error(` ${h("js")} SootSim.bridges.keyboard.type("hello")`),console.error(` ${h("js")} SootSim.state.root.children.length`),process.exit(1));let t=o;t.startsWith("(async")||(t=`(async () => ${t})()`);let s=await d.send({type:"evaluate",code:t});console.log(JSON.stringify(s,null,2));let r=o.toLowerCase(),i=[];(r.includes("sootsim:gohome")||r.includes("gohome"))&&i.push("sootsim shell home"),(r.includes("sootsim:appswitcher")||r.includes("appswitcher"))&&i.push("sootsim shell switcher"),(r.includes("keyboard.isvisible")||r.includes("keyboard.getmode"))&&i.push("sootsim debug state keyboard"),r.includes("interact.tap")&&i.push("sootsim do tap <x> <y>"),r.includes("keyboard.type")&&i.push("sootsim do type <text>"),(r.includes("keyboard.press")||r.includes("keyboard.dispatchkey"))&&i.push("sootsim do key <name>"),r.includes("keyboard.dismiss")&&i.push("sootsim do dismiss"),r.includes("dumptree")&&i.push("sootsim get tree"),r.includes("dumpaccessibilitytree")&&i.push("sootsim get a11y"),r.includes("getnodecount")&&i.push("sootsim get count"),r.includes("findbytext")&&i.push("sootsim find <text>"),(r.includes("findbytestid")||r.includes("findbyid"))&&i.push("sootsim find --testid <id>"),r.includes("document.hidden")&&i.push("sootsim debug state keyboard (includes tab health)"),i.length>0&&G("prefer-cli-over-eval",i);break}case"globals":{let o=await d.send({type:"evaluate",code:`(async () => {
576
+ `).slice(0,2);for(let O of x)console.log(` ${O.trim()}`)}}}}catch{}u&&!u.ready&&(process.exitCode=1);break}case"eval":case"js":{let o=a.slice(1).join(" ");o||(console.error(k("js","<javascript>")),console.error(""),console.error(" runs the snippet in the engine realm. SootSim is the"),console.error(" canonical state surface \u2014 reach into it directly."),console.error(""),console.error(" examples:"),console.error(` ${h("js")} SootSim.bridges.test.findByText("Sign in")`),console.error(` ${h("js")} SootSim.bridges.debug.snapshot("before")`),console.error(` ${h("js")} SootSim.bridges.keyboard.type("hello")`),console.error(` ${h("js")} SootSim.state.root.children.length`),process.exit(1));let t=o;t.startsWith("(async")||(t=`(async () => ${t})()`);let s=await d.send({type:"evaluate",code:t});console.log(JSON.stringify(s,null,2));let r=o.toLowerCase(),i=[];(r.includes("sootsim:gohome")||r.includes("gohome"))&&i.push("sootsim shell home"),(r.includes("sootsim:appswitcher")||r.includes("appswitcher"))&&i.push("sootsim shell switcher"),(r.includes("keyboard.isvisible")||r.includes("keyboard.getmode"))&&i.push("sootsim debug state keyboard"),r.includes("interact.tap")&&i.push("sootsim do tap <x> <y>"),r.includes("keyboard.type")&&i.push("sootsim do type <text>"),(r.includes("keyboard.press")||r.includes("keyboard.dispatchkey"))&&i.push("sootsim do key <name>"),r.includes("keyboard.dismiss")&&i.push("sootsim do dismiss"),r.includes("dumptree")&&i.push("sootsim get tree"),r.includes("dumpaccessibilitytree")&&i.push("sootsim get a11y"),r.includes("getnodecount")&&i.push("sootsim get count"),r.includes("findbytext")&&i.push("sootsim find <text>"),(r.includes("findbytestid")||r.includes("findbyid"))&&i.push("sootsim find --testid <id>"),r.includes("document.hidden")&&i.push("sootsim debug state keyboard (includes tab health)"),i.length>0&&G("prefer-cli-over-eval",i);break}case"globals":{let o=await d.send({type:"evaluate",code:`(async () => {
576
577
  const globals = {}
577
578
 
578
579
  // test bridge (proxy in worker mode)
@@ -610,7 +611,7 @@ ${s}
610
611
 
611
612
  return globals
612
613
  })()`});console.log(` sootsim JS API:
613
- `);for(let[t,s]of Object.entries(o)){console.log(` ${t}:`);for(let r of s)console.log(` .${r}`);console.log("")}console.log(` use: ${h("js")} <expression>`),console.log(` example: ${h("js")} test.findByText("Sign in")`);break}case"describe":{await Nt({bridge:d,args:e,positional:a});break}case"perf":{let o=a[1];if(!o||o==="--help"||o==="-h"){console.log(`
614
+ `);for(let[t,s]of Object.entries(o)){console.log(` ${t}:`);for(let r of s)console.log(` .${r}`);console.log("")}console.log(` use: ${h("js")} <expression>`),console.log(` example: ${h("js")} test.findByText("Sign in")`);break}case"describe":{await _t({bridge:d,args:e,positional:a});break}case"perf":{let o=a[1];if(!o||o==="--help"||o==="-h"){console.log(`
614
615
  ${h("perf")} \u2014 performance profiling
615
616
 
616
617
  subcommands:
@@ -656,7 +657,7 @@ ${s}
656
657
  jankFrames: frameStats.recentFrames?.filter(f => f > 16.67).length || 0,
657
658
  recentCount: frameStats.recentFrames?.length || 0,
658
659
  }
659
- })()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),R(l)){E(t);break}let s=t.avgMs==="?"&&t.maxMs==="?",r=t.avgMs!=="?"?(1e3/parseFloat(t.avgMs)).toFixed(1):"?";console.log(" perf stats:"),console.log(` frames: ${t.frames}`),console.log(` avg: ${t.avgMs}ms (${r} fps)`),console.log(` max: ${t.maxMs}ms`),console.log(` layout: ${t.layoutMs}ms total`),console.log(` nodes: ${t.nodeCount}`),t.recentCount>0&&console.log(` jank: ${t.jankFrames}/${t.recentCount} frames >16.67ms`),s&&process.stderr.write(`
660
+ })()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),A(l)){P(t);break}let s=t.avgMs==="?"&&t.maxMs==="?",r=t.avgMs!=="?"?(1e3/parseFloat(t.avgMs)).toFixed(1):"?";console.log(" perf stats:"),console.log(` frames: ${t.frames}`),console.log(` avg: ${t.avgMs}ms (${r} fps)`),console.log(` max: ${t.maxMs}ms`),console.log(` layout: ${t.layoutMs}ms total`),console.log(` nodes: ${t.nodeCount}`),t.recentCount>0&&console.log(` jank: ${t.jankFrames}/${t.recentCount} frames >16.67ms`),s&&process.stderr.write(`
660
661
  \u26A0 frame timings are zero \u2014 enable them first:
661
662
  sootsim debug perf start # begin recording
662
663
  # \u2026 interact / run a flow / wait for the transition \u2026
@@ -778,7 +779,7 @@ ${s}
778
779
  jankFrames: recent.filter(f => f > 16.67).length,
779
780
  sampleCount: recent.length,
780
781
  }
781
- })()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),R(l)){E(t);break}let s=t.avgMs>0?(1e3/t.avgMs).toFixed(1):"?",r=t.sampleCount>0?(t.jankFrames/t.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
782
+ })()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),A(l)){P(t);break}let s=t.avgMs>0?(1e3/t.avgMs).toFixed(1):"?",r=t.sampleCount>0?(t.jankFrames/t.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
782
783
  `),console.log(` frames: ${t.frames}`),console.log(` total: ${t.totalMs.toFixed(1)}ms`),console.log(` avg: ${t.avgMs.toFixed(2)}ms (${s} fps)`),console.log(` max: ${t.maxMs.toFixed(2)}ms`),console.log(""),t.layoutAvgMs!==void 0&&(console.log(" breakdown (avg per frame):"),console.log(` layout: ${t.layoutAvgMs.toFixed(2)}ms`),console.log(` render: ${t.renderAvgMs.toFixed(2)}ms`),console.log(` copy: ${t.copyAvgMs.toFixed(2)}ms`),t.auxAvgMs!==void 0&&console.log(` aux: ${t.auxAvgMs.toFixed(2)}ms`),t.otherAvgMs!==void 0&&console.log(` other: ${t.otherAvgMs.toFixed(2)}ms`),console.log("")),console.log(` distribution (${t.sampleCount} samples):`),console.log(` p50: ${t.p50.toFixed(2)}ms`),console.log(` p95: ${t.p95.toFixed(2)}ms`),console.log(` p99: ${t.p99.toFixed(2)}ms`),console.log(` jank: ${t.jankFrames} frames (${r}%) >16.67ms`);break}case"frames":{let t=a[2]?Number(a[2]):50;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await d.send({type:"evaluate",code:`(async () => {
783
784
  if (window.__sootsimRenderHost) {
784
785
  const session = window.${se} || {}
@@ -814,7 +815,7 @@ ${s}
814
815
  mode: 'main-thread',
815
816
  frames: (stats.recentFrames || []).slice(-${t}),
816
817
  }
817
- })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),R(l)){E(s);break}if(s.mode==="render-worker"){let i=Array.isArray(s.samples)?s.samples:[];if(i.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${i.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,p,w,f,x,A,q]of i)console.log(` ${p.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${A.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);console.log(""),Ce(i.map(u=>u[1])),s.live&&console.log(" sampling continues");break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${r.length} frame times (ms):`),console.log(` ${r.map(i=>i.toFixed(2)).join(", ")}`),Ce(r);break}case"worst":{let t=a[2]?Number(a[2]):20;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await d.send({type:"evaluate",code:`(async () => {
818
+ })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),A(l)){P(s);break}if(s.mode==="render-worker"){let i=Array.isArray(s.samples)?s.samples:[];if(i.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${i.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,p,w,f,x,O,q]of i)console.log(` ${p.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);console.log(""),Ce(i.map(u=>u[1])),s.live&&console.log(" sampling continues");break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${r.length} frame times (ms):`),console.log(` ${r.map(i=>i.toFixed(2)).join(", ")}`),Ce(r);break}case"worst":{let t=a[2]?Number(a[2]):20;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await d.send({type:"evaluate",code:`(async () => {
818
819
  if (window.__sootsimRenderHost) {
819
820
  const session = window.${se} || {}
820
821
  if (session.active) {
@@ -856,7 +857,7 @@ ${s}
856
857
  mode: 'main-thread',
857
858
  frames: recent.slice().sort((a, b) => b - a).slice(0, ${t}),
858
859
  }
859
- })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),R(l)){E(s);break}if(s.mode==="render-worker"){let i=Array.isArray(s.samples)?s.samples:[];if(i.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${i.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,p,w,f,x,A,q]of i)console.log(` ${p.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${A.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);s.live&&(console.log(""),console.log(" sampling continues"));break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${r.length} frame times (ms):`),console.log(` ${r.map(i=>i.toFixed(2)).join(", ")}`);break}case"transition":{let t=a[2];if(!t||!["goHome","appSwitcher","lockScreen"].includes(t)){console.log(`
860
+ })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),A(l)){P(s);break}if(s.mode==="render-worker"){let i=Array.isArray(s.samples)?s.samples:[];if(i.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${i.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,p,w,f,x,O,q]of i)console.log(` ${p.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);s.live&&(console.log(""),console.log(" sampling continues"));break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${r.length} frame times (ms):`),console.log(` ${r.map(i=>i.toFixed(2)).join(", ")}`);break}case"transition":{let t=a[2];if(!t||!["goHome","appSwitcher","lockScreen"].includes(t)){console.log(`
860
861
  ${h("perf")} transition <event> \u2014 profile a shell transition
861
862
 
862
863
  events:
@@ -869,7 +870,7 @@ ${s}
869
870
  examples:
870
871
  ${h("perf")} transition goHome --timeout 10000
871
872
  ${h("perf")} transition appSwitcher
872
- `);break}let r=`sootsim:${t}`;Ae(` profiling ${t} transition...`),Ae(" (use --timeout 10000 if this times out)");let i=await d.send({type:"evaluate",code:`(async () => {
873
+ `);break}let r=`sootsim:${t}`;Oe(` profiling ${t} transition...`),Oe(" (use --timeout 10000 if this times out)");let i=await d.send({type:"evaluate",code:`(async () => {
873
874
  // only supported in render-worker mode
874
875
  if (!window.__sootsimRenderHost) {
875
876
  return { error: 'transition profiling requires render-worker mode' }
@@ -928,7 +929,7 @@ ${s}
928
929
  jankFrames: frameTimes.filter(f => f > 16.67).length,
929
930
  samples,
930
931
  }
931
- })()`});if(i.error&&(console.error(` error: ${i.error}`),process.exit(1)),R(l)){E(i);break}if(i.warning&&console.log(` warning: ${i.warning}`),i.frames===0){console.log(" no frames captured");break}let u=i.avgMs>0?(1e3/i.avgMs).toFixed(1):"?",p=i.frames>0?(i.jankFrames/i.frames*100).toFixed(1):"0";console.log(` ${t} transition profiled:
932
+ })()`});if(i.error&&(console.error(` error: ${i.error}`),process.exit(1)),A(l)){P(i);break}if(i.warning&&console.log(` warning: ${i.warning}`),i.frames===0){console.log(" no frames captured");break}let u=i.avgMs>0?(1e3/i.avgMs).toFixed(1):"?",p=i.frames>0?(i.jankFrames/i.frames*100).toFixed(1):"0";console.log(` ${t} transition profiled:
932
933
 
933
934
  frames: ${i.frames}
934
935
  total: ${i.totalMs.toFixed(1)}ms
@@ -946,29 +947,29 @@ ${s}
946
947
  p50: ${i.p50.toFixed(2)}ms
947
948
  p95: ${i.p95.toFixed(2)}ms
948
949
  p99: ${i.p99.toFixed(2)}ms
949
- jank: ${i.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(i.samples)&&i.samples.length>0&&(console.log(""),Ce(i.samples.map(w=>w[1])));break}default:console.error(` unknown perf subcommand: ${o}`),console.error(" valid: stats, start, stop, frames, worst, transition"),/^--?reset$/.test(o)&&console.error(" note: 'perf start' already clears prior frames \u2014 no reset needed"),process.exit(1)}break}case"errors":{let o=a[1];if(o==="clear"){await nt(d),R(l)?E({cleared:!0}):console.log(" error buffer cleared");break}let t=o?Number(o):20,s=await ot(d,t);if(R(l)){E(s);break}if(s.length===0){console.log(" no errors captured");break}console.log(` ${s.length} error(s):
950
+ jank: ${i.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(i.samples)&&i.samples.length>0&&(console.log(""),Ce(i.samples.map(w=>w[1])));break}default:console.error(` unknown perf subcommand: ${o}`),console.error(" valid: stats, start, stop, frames, worst, transition"),/^--?reset$/.test(o)&&console.error(" note: 'perf start' already clears prior frames \u2014 no reset needed"),process.exit(1)}break}case"errors":{let o=a[1];if(o==="clear"){await it(d),A(l)?P({cleared:!0}):console.log(" error buffer cleared");break}let t=o?Number(o):20,s=await nt(d,t);if(A(l)){P(s);break}if(s.length===0){console.log(" no errors captured");break}console.log(` ${s.length} error(s):
950
951
  `);for(let r of s){let i=re(r.timestamp),u=r.args.map(p=>typeof p=="object"?JSON.stringify(p):p).join(" ");if(console.log(` [${i}] ${u}`),r.stack){let p=r.stack.split(`
951
- `).slice(0,3);for(let w of p)console.log(` ${w.trim()}`)}}break}case"warnings":{let o=a[1]?Number(a[1]):20,t=await st(d,o);if(R(l)){E(t);break}if(t.length===0){console.log(" no warnings captured");break}console.log(` ${t.length} warning(s):
952
+ `).slice(0,3);for(let w of p)console.log(` ${w.trim()}`)}}break}case"warnings":{let o=a[1]?Number(a[1]):20,t=await rt(d,o);if(A(l)){P(t);break}if(t.length===0){console.log(" no warnings captured");break}console.log(` ${t.length} warning(s):
952
953
  `);for(let s of t){let r=re(s.timestamp),i=s.args.map(u=>typeof u=="object"?JSON.stringify(u):u).join(" ");console.log(` [${r}] ${i}`)}break}case"animations":{let o=await Y(d,"listAnimations")??[];if(e.includes("--json")){console.log(JSON.stringify(o,null,2));break}if(o.length===0){console.log(" no active animations");break}console.log(` ${o.length} active animation(s):
953
- `);for(let t of o){let s=String(t.kind).padEnd(6),r=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,i=Number(t.current??0).toFixed(2),u=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,w=t.loop?" loop":"",f=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${r.padEnd(14)} cur=${i.padEnd(7)} ${u.padStart(4)} ${p}${w}${f}`)}break}case"animation":{let o=a[1];(!o||o==="--help"||o==="-h")&&(console.error(` usage: ${h("animation")} <id>`),process.exit(1));let t=Number(o);Number.isFinite(t)||(console.error(` invalid id: ${o}`),process.exit(1));let s=await Y(d,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let o=a[1];(!o||o==="--help"||o==="-h")&&(console.error(` usage: ${h("stop-animation")} <id|all>`),process.exit(1));let t=o==="all"?"all":Number(o);t!=="all"&&!Number.isFinite(t)&&(console.error(` invalid id: ${o}`),process.exit(1));let s=await Y(d,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let o=a[1];if(o==="clear"){await it(d),R(l)?E({cleared:!0}):console.log(" request buffer cleared");break}let t=o==="all",s=t?a[2]:o,r=s?Number(s):20,i=await rt(d,{failed:!t,limit:r});if(R(l)){E(i);break}if(i.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${i.length} ${t?"request(s)":"failed request(s)"}:
954
+ `);for(let t of o){let s=String(t.kind).padEnd(6),r=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,i=Number(t.current??0).toFixed(2),u=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,w=t.loop?" loop":"",f=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${r.padEnd(14)} cur=${i.padEnd(7)} ${u.padStart(4)} ${p}${w}${f}`)}break}case"animation":{let o=a[1];(!o||o==="--help"||o==="-h")&&(console.error(` usage: ${h("animation")} <id>`),process.exit(1));let t=Number(o);Number.isFinite(t)||(console.error(` invalid id: ${o}`),process.exit(1));let s=await Y(d,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let o=a[1];(!o||o==="--help"||o==="-h")&&(console.error(` usage: ${h("stop-animation")} <id|all>`),process.exit(1));let t=o==="all"?"all":Number(o);t!=="all"&&!Number.isFinite(t)&&(console.error(` invalid id: ${o}`),process.exit(1));let s=await Y(d,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let o=a[1];if(o==="clear"){await lt(d),A(l)?P({cleared:!0}):console.log(" request buffer cleared");break}let t=o==="all",s=t?a[2]:o,r=s?Number(s):20,i=await at(d,{failed:!t,limit:r});if(A(l)){P(i);break}if(i.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${i.length} ${t?"request(s)":"failed request(s)"}:
954
955
  `);for(let u of i){let p=re(u.timestamp);console.log(` [${p}] ${te(u)}`),u.responseBody?console.log(` ${u.responseBody}`):u.error&&console.log(` ${u.error}`)}break}case"network":{let o=a[1],t=null,s=null,r=!1,i=!1,u=1e3,p=!1,w=!1;for(let F=0;F<l.length;F++){let b=l[F];if(b==="--filter")t=l[F+1]??null,F++;else if(b==="--limit"){let $=Number(l[F+1]);Number.isFinite($)&&(s=$),F++}else if(b==="--threshold"){let $=Number(l[F+1]);Number.isFinite($)&&$>0&&(u=$),F++}else b==="--failed"?r=!0:b==="--slow"?i=!0:b==="--tail"||b==="-f"?p=!0:b==="--json"&&(w=!0)}if(o==="clear"){await d.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(o==="get"){let F=a[2];F||(console.error(" usage: sootsim network get <id>"),process.exit(1));let b=await d.send({type:"evaluate",code:`(() => {
955
956
  const obs = window.__sootsimObservability;
956
957
  if (!obs) return null;
957
958
  return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(F)}) || null;
958
- })()`});b||(console.error(` no entry with id ${F}`),process.exit(1)),w?console.log(JSON.stringify(b,null,2)):Ro(b);break}let f=s??(p?200:o?Number(o):20);Number.isFinite(f)||(console.error(` invalid limit: ${o} \u2014 \`network\` takes a numeric count (e.g. ${h("network")} 100).
959
+ })()`});b||(console.error(` no entry with id ${F}`),process.exit(1)),w?console.log(JSON.stringify(b,null,2)):Do(b);break}let f=s??(p?200:o?Number(o):20);Number.isFinite(f)||(console.error(` invalid limit: ${o} \u2014 \`network\` takes a numeric count (e.g. ${h("network")} 100).
959
960
  to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let x=async()=>{let F=await d.send({type:"evaluate",code:`(() => {
960
961
  const obs = window.__sootsimObservability;
961
962
  if (!obs) return { ok: false };
962
963
  return { ok: true, entries: obs.network.getSnapshot() };
963
- })()`});if(!F||!F.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return F.entries??[]},A=F=>{let b=F;if(r&&(b=b.filter($=>!!$.error||$.status!=null&&$.status>=400)),i&&(b=b.filter($=>$.durationMs!=null&&$.durationMs>=u)),t){let $=t.toLowerCase();b=b.filter(v=>(v.displayUrl||v.url).toLowerCase().includes($))}return i&&!p&&(b=[...b].sort(($,v)=>(v.durationMs??0)-($.durationMs??0))),b};if(!p){let F=await x(),b=A(F).slice(-f);if(w){console.log(JSON.stringify(b,null,2));break}if(b.length===0){F.length===0?console.log(" no network requests captured"):console.log(i?` no requests slower than ${u}ms (${F.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(i?` ${b.length} request(s) slower than ${u}ms (sorted by duration desc):
964
+ })()`});if(!F||!F.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return F.entries??[]},O=F=>{let b=F;if(r&&(b=b.filter($=>!!$.error||$.status!=null&&$.status>=400)),i&&(b=b.filter($=>$.durationMs!=null&&$.durationMs>=u)),t){let $=t.toLowerCase();b=b.filter(v=>(v.displayUrl||v.url).toLowerCase().includes($))}return i&&!p&&(b=[...b].sort(($,v)=>(v.durationMs??0)-($.durationMs??0))),b};if(!p){let F=await x(),b=O(F).slice(-f);if(w){console.log(JSON.stringify(b,null,2));break}if(b.length===0){F.length===0?console.log(" no network requests captured"):console.log(i?` no requests slower than ${u}ms (${F.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(i?` ${b.length} request(s) slower than ${u}ms (sorted by duration desc):
964
965
  `:` ${b.length} request(s):
965
- `);for(let $ of b)Ut($);break}console.log(` tailing network (ctrl-c to stop)...
966
- `);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let F=await x(),b=A(F);for(let $ of b)$.durationMs!=null&&(q.has($.id)||(q.add($.id),w?console.log(JSON.stringify($)):Ut($)));await Z(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let o=a[1],t=null,s=null,r=null,i=!1,u=!1,p=!1;for(let b=0;b<l.length;b++){let $=l[b];if($==="--filter")t=l[b+1]??null,b++;else if($==="--limit"){let v=Number(l[b+1]);Number.isFinite(v)&&(s=v),b++}else $==="--level"?(r=l[b+1]??null,b++):$==="--tail"||$==="-f"?i=!0:$==="--json"?u=!0:($==="--internal"||$==="--all")&&(p=!0)}let w=r?new Set(r.split(",").map(b=>b.trim()).filter(b=>b==="log"||b==="info"||b==="warn"||b==="error"||b==="debug")):null;if(o==="clear"){await lt(d),console.log(" log buffer cleared");break}let f=!u&&process.stdout.isTTY===!0,x=s??(i?500:o?Number(o):50);Number.isFinite(x)||(console.error(` invalid limit: ${o} \u2014 \`logs\` takes a numeric count (e.g. ${h("logs")} 100).
967
- to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let A=()=>at(d),q=b=>ct(b,{level:w,filter:t,showInternal:p});if(!i){let b=await A(),$=q(b).slice(-x);if(u){console.log(JSON.stringify($,null,2));break}if($.length===0){console.log(b.length===0?" no logs captured":" no matching logs");break}console.log(` ${$.length} log(s):
968
- `);for(let v of $)zt(v,f);break}console.log(` tailing logs (ctrl-c to stop)...
969
- `);let H=new Set,U=!0,F=()=>{U=!1};process.on("SIGINT",F);try{for(;U;){let b=await A(),$=q(b);for(let v of $)H.has(v.id)||(H.add(v.id),u?console.log(JSON.stringify(v)):zt(v,f));await Z(250)}}finally{process.off("SIGINT",F)}break}default:console.error(` unknown subcommand: ${g}`),process.exit(1)}if(ue.has(g)&&!e.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&!await ze(d,g)&&await S(d),!B.has(g)&&!R(l))try{await ne(d)}catch{}}catch(o){let t=o instanceof Error?o.message:String(o);console.error(` ${g??"inspect"} failed: ${t}`);let s=/^no sim connected with id (.+)$/.exec(t),r=/^command timed out after (\d+)s$/.exec(t),i=t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("could not connect to ws://");if(s)await wt(d,_,s[1]);else if(/^no sim connected$/.test(t))bt(_);else if(r)if(await No(d)){let p=g??"describe";process.stderr.write(` the sim is still responsive \u2014 '${p}' just exceeded the ${r[1]}s command budget.
966
+ `);for(let $ of b)Yt($);break}console.log(` tailing network (ctrl-c to stop)...
967
+ `);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let F=await x(),b=O(F);for(let $ of b)$.durationMs!=null&&(q.has($.id)||(q.add($.id),w?console.log(JSON.stringify($)):Yt($)));await Z(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let o=a[1],t=null,s=null,r=null,i=!1,u=!1,p=!1;for(let b=0;b<l.length;b++){let $=l[b];if($==="--filter")t=l[b+1]??null,b++;else if($==="--limit"){let v=Number(l[b+1]);Number.isFinite(v)&&(s=v),b++}else $==="--level"?(r=l[b+1]??null,b++):$==="--tail"||$==="-f"?i=!0:$==="--json"?u=!0:($==="--internal"||$==="--all")&&(p=!0)}let w=r?new Set(r.split(",").map(b=>b.trim()).filter(b=>b==="log"||b==="info"||b==="warn"||b==="error"||b==="debug")):null;if(o==="clear"){await dt(d),console.log(" log buffer cleared");break}let f=!u&&process.stdout.isTTY===!0,x=s??(i?500:o?Number(o):50);Number.isFinite(x)||(console.error(` invalid limit: ${o} \u2014 \`logs\` takes a numeric count (e.g. ${h("logs")} 100).
968
+ to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let O=()=>ct(d),q=b=>ut(b,{level:w,filter:t,showInternal:p});if(!i){let b=await O(),$=q(b).slice(-x);if(u){console.log(JSON.stringify($,null,2));break}if($.length===0){console.log(b.length===0?" no logs captured":" no matching logs");break}console.log(` ${$.length} log(s):
969
+ `);for(let v of $)Xt(v,f);break}console.log(` tailing logs (ctrl-c to stop)...
970
+ `);let H=new Set,U=!0,F=()=>{U=!1};process.on("SIGINT",F);try{for(;U;){let b=await O(),$=q(b);for(let v of $)H.has(v.id)||(H.add(v.id),u?console.log(JSON.stringify(v)):Xt(v,f));await Z(250)}}finally{process.off("SIGINT",F)}break}default:console.error(` unknown subcommand: ${g}`),process.exit(1)}if(me.has(g)&&!e.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&!await ze(d,g)&&await S(d),!B.has(g)&&!A(l))try{await ne(d)}catch{}}catch(o){let t=o instanceof Error?o.message:String(o);console.error(` ${g??"inspect"} failed: ${t}`);let s=/^no sim connected with id (.+)$/.exec(t),r=/^command timed out after (\d+)s$/.exec(t),i=t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("could not connect to ws://");if(s)await $t(d,_,s[1]);else if(/^no sim connected$/.test(t))xt(_);else if(r)if(await Oo(d)){let p=g??"describe";process.stderr.write(` the sim is still responsive \u2014 '${p}' just exceeded the ${r[1]}s command budget.
970
971
  the screen's node tree is large; narrow the query or raise the budget:
971
972
  sootsim ${p} --testid <id> # scope to one subtree
972
973
  sootsim find --testid <id> # targeted single-node lookup
973
974
  sootsim ${p} --timeout 60000 # raise per-command budget (ms)
974
- `)}else Ht();else if(i)Ht();else{try{await gt(d)}catch{}try{await X({includeTail:!0})}catch{}try{await W({includeTail:!0})}catch{}}process.exit(1)}finally{d.close()}}export{Mn as runInspect};
975
+ `)}else zt();else if(i)zt();else{try{await ht(d)}catch{}try{await X({includeTail:!0})}catch{}try{await W({includeTail:!0})}catch{}}process.exit(1)}finally{d.close()}}export{Pn as runInspect};