sootsim 0.1.119 → 0.1.121

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 (146) hide show
  1. package/dist-cli/bin.js +3 -3
  2. package/dist-cli/chunks/{agent-HMYFFW3K.js → agent-NZ4A6JKO.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-L5TRN5OW.js → agent-wrapper-CYQ5L2YH.js} +2 -2
  4. package/dist-cli/chunks/{app-fonts-G5L5BPHX.js → app-fonts-2DF4NW5D.js} +2 -2
  5. package/dist-cli/chunks/{assert-MN4TCTKK.js → assert-PASM5PLL.js} +2 -2
  6. package/dist-cli/chunks/auto-bootstrap-IPNK6GF7.js +2 -0
  7. package/dist-cli/chunks/beta-RG7JT6HD.js +2 -0
  8. package/dist-cli/chunks/chunk-2FTVPI7F.js +2 -0
  9. package/dist-cli/chunks/{chunk-XYT2OO4N.js → chunk-2U4CGOD6.js} +1 -1
  10. package/dist-cli/chunks/{chunk-TGLPBQ4D.js → chunk-3A7SRWSQ.js} +2 -2
  11. package/dist-cli/chunks/{chunk-LB7BYFMF.js → chunk-3DDNLPIH.js} +2 -2
  12. package/dist-cli/chunks/{chunk-4KU7AIP7.js → chunk-3WDN2S2A.js} +1 -1
  13. package/dist-cli/chunks/{chunk-ZX4FJNIW.js → chunk-4BXESMZ7.js} +1 -1
  14. package/dist-cli/chunks/{chunk-H4F45EGT.js → chunk-4UQMPWDA.js} +1 -1
  15. package/dist-cli/chunks/{chunk-RF2STDGD.js → chunk-5OA35LZX.js} +2 -2
  16. package/dist-cli/chunks/{chunk-JFHETXYV.js → chunk-7CA63OS4.js} +1 -1
  17. package/dist-cli/chunks/{chunk-MNILEOSP.js → chunk-7RXO4KKF.js} +1 -1
  18. package/dist-cli/chunks/{chunk-O552XDE7.js → chunk-B77PWTHR.js} +2 -2
  19. package/dist-cli/chunks/chunk-BTWXWUDB.js +1 -0
  20. package/dist-cli/chunks/{chunk-3MWC6EE2.js → chunk-CGB6KRKN.js} +2 -2
  21. package/dist-cli/chunks/{chunk-EIAYJLBW.js → chunk-DORQQNP4.js} +2 -2
  22. package/dist-cli/chunks/{chunk-TUJWNKG4.js → chunk-GU3MWKJY.js} +1 -1
  23. package/dist-cli/chunks/{chunk-BBLE5DMP.js → chunk-I26R4PE2.js} +1 -1
  24. package/dist-cli/chunks/{chunk-GEPWAAGG.js → chunk-IQNZPHGD.js} +2 -2
  25. package/dist-cli/chunks/{chunk-47SB3JEW.js → chunk-KTE2VIXH.js} +3 -3
  26. package/dist-cli/chunks/chunk-KXLYXKMA.js +1 -0
  27. package/dist-cli/chunks/{chunk-QMU4MAG3.js → chunk-KY6NY6WN.js} +1 -1
  28. package/dist-cli/chunks/{chunk-C3VO2MSV.js → chunk-LT2X5ISU.js} +2 -2
  29. package/dist-cli/chunks/{chunk-J6UPVQ37.js → chunk-MSU27JEW.js} +2 -2
  30. package/dist-cli/chunks/{chunk-475TNRB7.js → chunk-MUTDER75.js} +2 -2
  31. package/dist-cli/chunks/{chunk-WNK5XRWG.js → chunk-NQ4EDJV4.js} +2 -2
  32. package/dist-cli/chunks/{chunk-DE6JMHEW.js → chunk-OBYYAT4F.js} +2 -2
  33. package/dist-cli/chunks/{chunk-APWX6YCC.js → chunk-OEV7EOMC.js} +2 -2
  34. package/dist-cli/chunks/{chunk-O7SJH4E7.js → chunk-PMAKUYYK.js} +2 -2
  35. package/dist-cli/chunks/{chunk-OS62SSOF.js → chunk-QNQO5VHO.js} +9 -9
  36. package/dist-cli/chunks/chunk-QUEATUWT.js +1 -0
  37. package/dist-cli/chunks/{chunk-5OZHLK4L.js → chunk-RVWJ3TAE.js} +2 -2
  38. package/dist-cli/chunks/{chunk-AV6YDPVF.js → chunk-SA5RP334.js} +2 -2
  39. package/dist-cli/chunks/{chunk-RAWQNHKI.js → chunk-SF6W3FRS.js} +1 -1
  40. package/dist-cli/chunks/{chunk-AUKEEPZT.js → chunk-SRA2TVCG.js} +1 -1
  41. package/dist-cli/chunks/{chunk-JP3PNWTD.js → chunk-VALW4SKE.js} +1 -1
  42. package/dist-cli/chunks/{chunk-FUUXRMXG.js → chunk-VJPN6DQU.js} +2 -2
  43. package/dist-cli/chunks/{chunk-MJQXUHDS.js → chunk-VSKLWCFM.js} +2 -2
  44. package/dist-cli/chunks/{chunk-CHHBZJBH.js → chunk-VSRV5LFU.js} +1 -1
  45. package/dist-cli/chunks/{chunk-SSQWBV2F.js → chunk-VX5CAWLC.js} +2 -2
  46. package/dist-cli/chunks/{chunk-YZ6MQTDJ.js → chunk-W3FBNBTX.js} +2 -2
  47. package/dist-cli/chunks/{chunk-BZH7FKZZ.js → chunk-WHL7FMLG.js} +84 -27
  48. package/dist-cli/chunks/{chunk-FCRJNHIA.js → chunk-X4LYRBLZ.js} +1 -1
  49. package/dist-cli/chunks/{chunk-4EQ5V4CA.js → chunk-Y7ZMV3PG.js} +1 -1
  50. package/dist-cli/chunks/{chunk-YBRJSW5C.js → chunk-YQIFU3PB.js} +3 -3
  51. package/dist-cli/chunks/{chunk-HPTOFA3Y.js → chunk-Z47GWZMZ.js} +3 -3
  52. package/dist-cli/chunks/cli-version-DPV7EKFK.js +2 -0
  53. package/dist-cli/chunks/{compat-3C3O2TKY.js → compat-FMBQL2CX.js} +3 -3
  54. package/dist-cli/chunks/{config-TEO7DXWJ.js → config-JD23SW7N.js} +2 -2
  55. package/dist-cli/chunks/control-IAHPU5HD.js +2 -0
  56. package/dist-cli/chunks/{cpu-profile-QSFGY7HA.js → cpu-profile-2Z4KGCAE.js} +2 -2
  57. package/dist-cli/chunks/{daemon-R2TQX4HR.js → daemon-NDO6JPDH.js} +2 -2
  58. package/dist-cli/chunks/{debug-UMLASBX2.js → debug-RBVMEH33.js} +3 -3
  59. package/dist-cli/chunks/{detox-Y6TFEKQU.js → detox-TBJAZEBB.js} +2 -2
  60. package/dist-cli/chunks/{device-4NBQC4LP.js → device-26YM4HM7.js} +2 -2
  61. package/dist-cli/chunks/{diagnose-DKXPE4P6.js → diagnose-PW7FGUOI.js} +2 -2
  62. package/dist-cli/chunks/drivers-L6UY2JC6.js +2 -0
  63. package/dist-cli/chunks/{electron-3AZTVV3N.js → electron-TBMZ3C5I.js} +3 -3
  64. package/dist-cli/chunks/flow-QSDMMKNZ.js +2 -0
  65. package/dist-cli/chunks/help-OC7HYZ5F.js +2 -0
  66. package/dist-cli/chunks/{hints-K323Q4NQ.js → hints-Q3I4PXMT.js} +2 -2
  67. package/dist-cli/chunks/{home-paths-H7GUBJAB.js → home-paths-P5GMZADH.js} +2 -2
  68. package/dist-cli/chunks/{inspect-UJFYMPE5.js → inspect-UTHL2UK4.js} +55 -58
  69. package/dist-cli/chunks/install-3UWGXX6F.js +2 -0
  70. package/dist-cli/chunks/{install-desktop-NT5QJIPD.js → install-desktop-XQYE3QYC.js} +3 -3
  71. package/dist-cli/chunks/{keys-OJVAQQK5.js → keys-75OBQ7OF.js} +2 -2
  72. package/dist-cli/chunks/{launch-VMMQENF6.js → launch-TFE3CZZ3.js} +3 -3
  73. package/dist-cli/chunks/{login-CRJE2OZK.js → login-EIL5PLK4.js} +4 -4
  74. package/dist-cli/chunks/{logout-3DXVRPLM.js → logout-2DXPOPWE.js} +2 -2
  75. package/dist-cli/chunks/{maestro-FPDCZ3NO.js → maestro-Q27CNJGT.js} +2 -2
  76. package/dist-cli/chunks/{preview-7WLF767D.js → preview-ZGVCXKQZ.js} +2 -2
  77. package/dist-cli/chunks/{profile-DE5LJZ5Y.js → profile-TCX6GYV5.js} +2 -2
  78. package/dist-cli/chunks/{react-HLRPZFFH.js → react-24D26RLU.js} +2 -2
  79. package/dist-cli/chunks/{record-VQAG2YYZ.js → record-3MODR5RQ.js} +2 -2
  80. package/dist-cli/chunks/runtime-5MJPHLRZ.js +2 -0
  81. package/dist-cli/chunks/{runtime-delivery-O2WD2RT6.js → runtime-delivery-NWSDCFAI.js} +2 -2
  82. package/dist-cli/chunks/{screenshot-HYSJVWYN.js → screenshot-4A6JTLUV.js} +2 -2
  83. package/dist-cli/chunks/{screenshot-mode-ME7WKY7S.js → screenshot-mode-KVMXLFJ4.js} +2 -2
  84. package/dist-cli/chunks/{screenshots-5MY3SHOW.js → screenshots-XGG6PNXW.js} +2 -2
  85. package/dist-cli/chunks/{server-LRSX4VKM.js → server-MRLLYDV7.js} +2 -2
  86. package/dist-cli/chunks/setup-repo-OUMNEC36.js +2 -0
  87. package/dist-cli/chunks/{skills-SHJHDYYU.js → skills-COR2GQRN.js} +2 -2
  88. package/dist-cli/chunks/{start-FBIHKRWV.js → start-SD27AJ7E.js} +4 -4
  89. package/dist-cli/chunks/store-JVV7G7VY.js +2 -0
  90. package/dist-cli/chunks/telemetry-BMJNBZT6.js +2 -0
  91. package/dist-cli/chunks/{test-W5VLOO6C.js → test-4N6K3C5R.js} +3 -3
  92. package/dist-cli/chunks/{three-mode-OILRSRAU.js → three-mode-PJQGXIP4.js} +2 -2
  93. package/dist-cli/chunks/{timeline-H4SFNSBA.js → timeline-C7JSMHCV.js} +2 -2
  94. package/dist-cli/chunks/{upgrade-4SYAHMAP.js → upgrade-SFUV6KPW.js} +2 -2
  95. package/dist-cli/chunks/upload-XQLVCUKI.js +2 -0
  96. package/dist-cli/chunks/{web-UXTXQNYW.js → web-GK27H4NM.js} +2 -2
  97. package/dist-cli/chunks/what-happened-GAY54LBV.js +22 -0
  98. package/dist-cli/chunks/{whoami-QDFN5LHP.js → whoami-C2WULTLS.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 +143 -5
  125. package/dist-lib/sdk.mjs +138 -5
  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-QJ5PP7KT.js +0 -2
  130. package/dist-cli/chunks/beta-LAPRQ3TP.js +0 -2
  131. package/dist-cli/chunks/chunk-5AL4WWUG.js +0 -1
  132. package/dist-cli/chunks/chunk-IKVDJYRI.js +0 -2
  133. package/dist-cli/chunks/chunk-RIMNMM3O.js +0 -1
  134. package/dist-cli/chunks/chunk-YPLXVVG4.js +0 -1
  135. package/dist-cli/chunks/cli-version-JKOW3OL3.js +0 -2
  136. package/dist-cli/chunks/control-UUSQA7VO.js +0 -2
  137. package/dist-cli/chunks/drivers-TFUZRRDZ.js +0 -2
  138. package/dist-cli/chunks/flow-744L27RP.js +0 -2
  139. package/dist-cli/chunks/help-JUP3UEFR.js +0 -2
  140. package/dist-cli/chunks/install-D5J5LA2V.js +0 -2
  141. package/dist-cli/chunks/runtime-LBAJOT4M.js +0 -2
  142. package/dist-cli/chunks/setup-repo-5FHT7B6J.js +0 -2
  143. package/dist-cli/chunks/store-ZSAUNVP6.js +0 -2
  144. package/dist-cli/chunks/telemetry-E2ZAX2C6.js +0 -2
  145. package/dist-cli/chunks/upload-NPGWC7E5.js +0 -2
  146. package/dist-cli/chunks/what-happened-SNC6DEIJ.js +0 -22
@@ -1,6 +1,6 @@
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 () => {
1
+ /*! sootsim v0.1.121 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as G}from"./chunk-VSKLWCFM.js";import{a as wt,b as xt}from"./chunk-7RXO4KKF.js";import{a as Ye,h as $e,k as ee}from"./chunk-CGB6KRKN.js";import{b as $t,c as St,j as vt}from"./chunk-MSU27JEW.js";import"./chunk-RVWJ3TAE.js";import{a as Z,b as A,c as P,d as Pe,e as re,f as Y,g as ce,h as pe,i as yt,j as ht,k as Re,l as bt}from"./chunk-QNQO5VHO.js";import{A as mt,E as pt,G as le,H as ft,N as gt,a as be,b as Ge,c as Xe,d as Ve,e as Qe,f as Ze,g as et,h as tt,i as ot,j as st,k as _e,l as Oe,p as Ae,q as nt,r as rt,s as we,t as it,u as xe,v as at,w as lt,x as ct,y as dt,z as ut}from"./chunk-WHL7FMLG.js";import"./chunk-4UQMPWDA.js";import{c as He,e as Ue,f as Ke,g as ze,h as Fe}from"./chunk-NQ4EDJV4.js";import"./chunk-LT2X5ISU.js";import"./chunk-VALW4SKE.js";import"./chunk-QUEATUWT.js";import"./chunk-3A7SRWSQ.js";import"./chunk-VSRV5LFU.js";import{b as qe}from"./chunk-SF6W3FRS.js";import{a as Je}from"./chunk-3WDN2S2A.js";import{a as Ie,c as Ne}from"./chunk-2U4CGOD6.js";import{a as We}from"./chunk-2FTVPI7F.js";import"./chunk-KY6NY6WN.js";import"./chunk-4BXESMZ7.js";import"./chunk-SRA2TVCG.js";import{existsSync as co,mkdirSync as uo,readFileSync as mo,rmSync as kt,writeFileSync as po}from"fs";import{tmpdir as fo}from"os";import{dirname as go,join as yo,resolve as ho}from"path";var fe=1,bo="SOOTSIM_INSPECT_NOTICE_PATH",wo=300*1e3,xo=15e3;function Tt(){return ho(process.env[bo]||yo(fo(),"sootsim-inspect-notice-state.json"))}function $o(e,c){return Object.fromEntries(Object.entries(e).filter(([,n])=>typeof n?.signature=="string"&&Number.isFinite(n?.updatedAt)&&c-n.updatedAt<=wo))}function So(e){let c=Tt();if(!co(c))return{version:fe,entries:{}};try{let n=JSON.parse(mo(c,"utf8"));return n.version!==fe||!n.entries||typeof n.entries!="object"?(kt(c,{force:!0}),{version:fe,entries:{}}):{version:fe,entries:$o(n.entries,e)}}catch{return kt(c,{force:!0}),{version:fe,entries:{}}}}function vo(e){let c=Tt();uo(go(c),{recursive:!0}),po(c,JSON.stringify(e,null,2)+`
3
+ `)}function ko(e,c){let n=c.trim()||"default";return`${e}:${n}`}function Ee(e,c,n,l={}){let m=l.nowMs??Date.now(),a=l.cooldownMs??xo,g=So(m),y=ko(e,c),T=g.entries[y];return T&&T.signature===n&&m-T.updatedAt<a?!1:(g.entries[y]={signature:n,updatedAt:m},vo(g),!0)}var To={initialWaitMs:3e3,deadlineMs:5e3,retryWaitMs:700},Mo={initialWaitMs:1200,deadlineMs:2500,retryWaitMs:700};function Io(e,c={}){return{...e?To:Mo,...c}}function de(e){return!(!e||e.hit===!1||e.ok===!1||e.pointerTapHandled===!1&&!e.keyboardOpened&&!e.isTextInput)}function No(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=Io(!!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:No(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 Mt(e,c,n,l){return e.send({type:"tap",x:c,y:n,...l?{target:l}:{}})}async function It(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-MJQXUHDS.js";import{a as bt,b as wt}from"./chunk-MNIL
42
42
  },
43
43
  strategy: (resolved && resolved.strategy) || 'matched-node',
44
44
  }
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 () => {
45
+ })()`})})}async function Nt(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-MJQXUHDS.js";import{a as bt,b as wt}from"./chunk-MNIL
162
162
  total,
163
163
  idx,
164
164
  }
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 () => {
165
+ })()`})})}async function Ft(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,16 +197,16 @@ import{a as G}from"./chunk-MJQXUHDS.js";import{a as bt,b as wt}from"./chunk-MNIL
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 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(`
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 _t(e,c={args:[]}){let n=await Xe(e);if(A(c.args)){P(n);return}console.log(` nodes: ${n.nodes}`)}function Ce(e,c){let n=e.indexOf(c);return n>=0&&n+1<e.length?e[n+1]:null}async function Ot(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=Ce(n,"--testid-like"),R=Ce(n,"--only"),j=Ce(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 Ze(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,J=S?.shell,W=S?.keyboard;if(a){P({shell:J,tree:N??"",keyboard:W});return}if(J&&typeof J=="object"){let D=[J.state?`state=${J.state}`:null,J.activeApp?`app=${J.activeApp}`:null,J.showSwitcher?"switcher":null,J.switcherPhase&&J.switcherPhase!=="idle"?`phase=${J.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 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(`
205
+ `);;)console.clear(),await V(),await Z(T);else await V()}var Fo=["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 Fo){let c=process.env[e];if(c&&c.trim()&&c!=="0")return!0}return!1}async function At(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 st(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(_e(C).map(S=>({...S,tap:Oe(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=_e(C);console.log(` found ${S.length} interactive target${S.length===1?"":"s"} (sorted by score):`);for(let N of S.slice(0,20)){let J=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=Oe(N);console.log(` ${me}${X}${ne}${Q} ${W} ${J}`),console.log(` \u2192 ${D}`),te&&console.log(De(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)})`:"",J=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} ${J} ${N}${Q}`),te&&console.log(De(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)})`,J=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} ${J} ${N}${Q}`),te&&console.log(De(JSON.stringify(S,null,2)," "))}else console.log(JSON.stringify(C,null,2))}}function De(e,c){return e.split(`
206
206
  `).map(n=>c+n).join(`
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 () => {
207
+ `)}async function Pt(e){let{bridge:c,args:n}=e,l=A(n);await ce(c,{verbose:!l});let m=await et(c);if(l){P({count:m.length,elements:m});return}console.log(` layout (${m.length} element${m.length===1?"":"s"}):
208
+ `),console.log(tt(m))}async function Rt(e,c={}){let n=await pt(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 Et(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}vt(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 Se(e,c){return c<=0?"?":`${(e/c*100).toFixed(0)}%`}async function Ct(e,c={args:[]}){let n=await gt(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} (${Se(l.cacheEntries,l.cacheMaxEntries)})`),console.log(` pixel bytes: ${ie(l.cachePixelBytes)} / ${ie(l.cachePixelBudget)} (${Se(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)} (${Se(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)} (${Se(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 ve(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 () => {
210
210
  const t = window.__sootsimTest
211
211
  if (!t) return null
212
212
  const n = ${l}
@@ -231,15 +231,15 @@ import{a as G}from"./chunk-MJQXUHDS.js";import{a as bt,b as wt}from"./chunk-MNIL
231
231
  text: ${JSON.stringify(c.mode==="text")} ? ${n} : (n.text ?? n.accessibilityLabel ?? null),
232
232
  type: n.type ?? null,
233
233
  }
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 () => {
234
+ })()`})??null}async function Dt(e,c={}){let{nav:n,keyboard:l,shell:m}=await ft(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 Bt(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 jt(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 Lt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1]):5,{tree:a}=await Ve(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 Qe(e);if(A(c.args)){P(n);return}console.log(n.url)}async function Wt(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 yt(c,n,l,{attempts:T,simIdSource:m});M||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),M.bridge.close(),$e({source:"inspect wait",step:{wait:y},summary:`wait ${Math.round(y/1e3)}s`}),console.log(` ready: ${M.count} nodes`)}var qt=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function ke(e,c){let n=e.indexOf(c);if(n>=0&&n+1<e.length)return e[n+1]}function _o(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 Ht(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)),qt.has(a)||console.error(` warning: '${a}' is not a known timeline kind \u2014 waiting anyway. known: ${[...qt].sort().join(", ")}`);let g=ke(n,"--max-ms"),y=g&&Number.isFinite(Number(g))?Math.max(100,Number(g)):5e3,T=ke(n,"--filter"),M=ke(n,"--equals"),h=ke(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 () => {
236
236
  const t = window.SootSim?.bridges?.timeline
237
237
  if (!t) return { ok: false, error: 'timeline bridge missing' }
238
238
  return { ok: true, result: await t.recent(${JSON.stringify(z)}) }
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
+ })()`});(!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(_o(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 Ut(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 Kt(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 nt(c,l,{onProgress(R){console.error(` still waiting after ${R.elapsedMs}ms \u2014 ${Ae(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=Ae({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 zt(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 rt(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 to(e){return e==null?"\u2014":e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}K`:`${(e/1024/1024).toFixed(1)}M`}function oo(e){return e==null?" \u2026":e<1e3?`${e}ms`.padStart(5):`${(e/1e3).toFixed(2)}s`.padStart(5)}function Yt(){process.stderr.write(` the sim is not responding. recover it with:
240
240
  sootsim close --sim <id> # force-close the wedged sim
241
241
  sootsim list # confirm it's gone
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
+ `)}async function Ao(e){try{return await e.send({type:"evaluate",code:"1"},{timeoutMs:3e3}),!0}catch{return!1}}async function Po(e,c){try{let n=await e.send({type:"evaluate",code:`(async () => {
243
243
  const t = window.__sootsimTest
244
244
  if (!t || typeof t.queryAll !== 'function') return []
245
245
  try {
@@ -258,8 +258,8 @@ import{a as G}from"./chunk-MJQXUHDS.js";import{a as bt,b as wt}from"./chunk-MNIL
258
258
  } catch {
259
259
  return []
260
260
  }
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 () => {
261
+ })()`});if(!Array.isArray(n)||n.length===0)return;let l=c.toLowerCase(),m=n.map(a=>({id:a,score:Ro(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 Ro(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 Eo(e,c)-n}function Eo(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 Co(e){return e.error?"err":e.status==null?" \u2026 ":String(e.status)}function Do(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 Gt(e){let c=re(e.startTs),n=Co(e).padEnd(3),l=e.method.padEnd(5),m=to(e.size).padStart(6),a=oo(e.durationMs);console.log(` [${c}] ${n} ${l} ${m} ${a} ${e.displayUrl}`),e.error&&console.log(` error: ${e.error}`)}function Bo(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",oo(e.durationMs).trim()],["size",to(e.size)],["content-type",e.type??"\u2014"]];for(let[n,l]of c)console.log(` ${n.padEnd(13)} ${l}`)}var jo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Xt="\x1B[0m",Lo="\x1B[2m";function Vt(e,c){let n=re(e.ts),l=e.level.toUpperCase().padEnd(5),m=e.args.join(" ");if(c){let a=jo[e.level];console.log(` ${Lo}[${n}]${Xt} ${a}${l}${Xt} ${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 Qt(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:wt({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 Be(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 Te(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 Le(e){return e.send({type:"evaluate",code:`(async () => {
263
263
  const kb = window.__sootsimKeyboard
264
264
  const test = window.__sootsimTest
265
265
  if (!kb) return { error: 'keyboard bridge not available' }
@@ -291,7 +291,7 @@ import{a as G}from"./chunk-MJQXUHDS.js";import{a as bt,b as wt}from"./chunk-MNIL
291
291
  frame: runtimeSnapshot?.keyboard?.frame ?? null,
292
292
  focusedRect: runtimeSnapshot?.focused?.rect ?? null,
293
293
  }
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
+ })()`})}async function Wo(e,c=600){let n=Date.now()+c;for(;Date.now()<=n;){let l=await Le(e);if(l.visible)return l;await Z(30)}return Le(e)}async function Me(e,c){let n=await Le(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 Zt(e,c,n){return c==="appearance"?e.send({type:"evaluate",code:`(async () => {
295
295
  const requested = ${JSON.stringify(n??"toggle")}
296
296
  const rootBg = (document.documentElement?.style?.background || '').toLowerCase()
297
297
  const inferredCurrent = rootBg.includes('33') ? 'dark' : 'light'
@@ -308,25 +308,25 @@ import{a as G}from"./chunk-MJQXUHDS.js";import{a as bt,b as wt}from"./chunk-MNIL
308
308
  })()`}):e.send({type:"evaluate",code:`(async () => {
309
309
  window.dispatchEvent(new CustomEvent(${JSON.stringify(c==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
310
310
  return { ok: true, action: ${JSON.stringify(c)} }
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}
312
- `),process.exit(0))}if(M==="shell"){let r=Me("shell",o);r&&(console.log(`${r}
313
- `),process.exit(0))}let t=Me("inspect",o),s=["do","get","debug","wait"].map(r=>Te(r,o)).filter(r=>r!=null).join(`
311
+ })()`})}function qo(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 Ho(e){if(typeof e!="string")return null;let c=e.replace(/\s+/g," ").trim();return c?c.slice(0,80):null}function so(...e){for(let c of e){if(typeof c!="string")continue;let n=c.trim();if(n)return n}return null}function Uo(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 L(e,c,n){let l=$e({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 eo(e,c,n){if(!n||n.hit===!1)return null;let l=so(n.responderTestID,n.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let m=Ho(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 je(e,c,n){let l=so(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 Rn(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=He(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:We};if(y==="do"||y==="get"||y==="debug"||y==="wait"){let r=Ie(y,o);r&&(console.log(`${r}
312
+ `),process.exit(0))}if(M==="shell"){let r=Ne("shell",o);r&&(console.log(`${r}
313
+ `),process.exit(0))}let t=Ne("inspect",o),s=["do","get","debug","wait"].map(r=>Ie(r,o)).filter(r=>r!=null).join(`
314
314
 
315
315
  `);console.log(`${t??""}
316
316
 
317
317
  ${s}
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.
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:`(() => ({
321
- console: window.__sootsimConsole?.count?.() || null,
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-L6UY2JC6.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=Ue(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.
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 J(){try{return await d.send({type:"evaluate",code:`(() => ({
321
+ console: ${xe},
322
322
  requests: window.__sootsimTest?.getRequestCounts?.() || null,
323
- }))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function W(o={}){let t=o.counts!==void 0?o.counts:await Y(d,"getRequestCounts");if(!t||typeof t!="object")return;let s=Math.max(0,Number(t.failed)||0);if(s===0||!o.includeTail&&!Pe("requests",z,String(s))||(console.log(`
323
+ }))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function W(o={}){let t=o.counts!==void 0?o.counts:await Y(d,"getRequestCounts");if(!t||typeof t!="object")return;let s=Math.max(0,Number(t.failed)||0);if(s===0||!o.includeTail&&!Ee("requests",z,String(s))||(console.log(`
324
324
  network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${h("requests")} 5`),!o.includeTail))return;let r=await Y(d,"getFailedRequests",5);if(!(!Array.isArray(r)||r.length===0)){console.log(`
325
325
  recent failed requests:
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(`
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(`
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:xe});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&&!Ee("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(`
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 we(d,5);if(!(!Array.isArray(p)||p.length===0)){console.log(`
328
328
  recent console errors:
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
+ `);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=qe(),s=null;try{s=await ze(o,`(() => {
330
330
  const tl = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.timeline
331
331
  if (!tl || typeof tl.summary !== 'function') return null
332
332
  const cursorKey = ${JSON.stringify(t)}
@@ -343,8 +343,8 @@ ${s}
343
343
  }
344
344
  return summary ? { summary, consoleSplit } : null
345
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(`
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 () => {
346
+ since last: ${i.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await Fe(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 Ke(d),D.has(g)&&await ce(d,{verbose:ae});try{switch(g){case"list":{await Et({bridge:d,simId:I,args:l});break}case"tree":{await Lt({bridge:d,args:l,positional:a});break}case"a11y":{let o=await ot(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 At({bridge:d,args:e,effectiveArgs:l,positional:a,inspectUsage:k});break}case"count":{await _t(d,{args:l});break}case"keyboard":{await Rt(d,{json:e.includes("--json")});break}case"screens":{await Dt(d,{json:e.includes("--json")});break}case"memory":{await Ct(d,{args:l});break}case"wait":{await Wt({wsPort:_,commandTimeoutMs:j,simId:I,simIdSource:R,positional:a});break}case"sleep":{await jt({positional:a,inspectUsage:k});break}case"settle":{await Bt({bridge:d,args:e,positional:a});break}case"ready":{await Kt({bridge:d,args:e});break}case"idle":{await Ut({bridge:d,args:e,positional:a});break}case"selector":{await zt({bridge:d,args:e,positional:a,inspectUsage:k});break}case"event":{await Ht({bridge:d,args:e,positional:a,inspectUsage:k});break}case"layout":{let o=a[1];if(!o){await Pt({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 Qt(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 Qt(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:xt(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 () => {
348
348
  const t = window.__sootsimTest
349
349
  const q = ${JSON.stringify(o)}
350
350
  let node = null
@@ -400,17 +400,17 @@ ${s}
400
400
  transform,
401
401
  parentChain,
402
402
  }
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
+ })()`});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 ve(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=eo(p.cx,p.cy,u.result);w&&await L("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 Mt(d,o,t),i=eo(o,t,r);i&&await L("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 () => {
404
404
  const interact = window.__sootsimInteract
405
405
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
406
406
  const value = await interact.drag(${o}, ${t}, ${s}, ${r}, ${Math.max(1,Math.round(p))}, ${Math.max(0,Math.round(w))})
407
407
  return { ok: !!value, value }
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
+ })()`});if(f?.ok){let x=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,w)));await L(`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 () => {
409
409
  const interact = window.__sootsimInteract
410
410
  if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
411
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))})
412
412
  return { ok: !!value, value }
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
+ })()`});O?.ok&&await L("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 Nt(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)})`:"",no=E.layout?` ${E.layout.width}x${E.layout.height}`:"",ro=E.testID?` #${E.testID}`:"",io=E.text?` "${E.text}"`:"",ao=E.ancestorTestIDs.length>0?` within ${E.ancestorTestIDs.slice(0,3).map(lo=>`#${lo}`).join(" > ")}`:"";console.error(` [${E.idx}] <${E.type}>${io}${ro} ${he}${no}${ao}`)}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=je(o,{id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},"text");await L("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 Ft(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=je(o,{id:r.id,testID:r.testID,type:r.type,cx:s.cx,cy:s.cy},s.strategy==="testid"?"id":"text");await L("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 It(d,o,{agent:ue()}),s=t.payload;(!s||typeof s.cx!="number")&&(console.error(` not found: ${o}`),await Po(d,o),process.exit(1)),de(t.result)||(N(`id "${o}"`,t),process.exit(1));let r=je(o,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await L("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 () => {
414
414
  const t = window.__sootsimTest
415
415
  if (!t) return null
416
416
  const n = await (t.findByTestId(${s}) || t.findById(${s}))
@@ -424,7 +424,7 @@ ${s}
424
424
  isTextInput: !!n.isTextInput,
425
425
  placeholder: n.placeholder || null,
426
426
  }
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
+ })()`});(!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 Wo(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 L("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 Me(d,"type"),await d.send({type:"keyboard",action:"type",text:o}),await L("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 Me(d,"key"),await d.send({type:"keyboard",action:"press",text:o}),await L("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 Me(d,"key-sequence");for(let t of o)await d.send({type:"keyboard",action:"press",text:t});await L("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:qo(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 Me(d,"keycode");for(let r of t)await d.send({type:"keyboard",action:"press",text:r.key});await L("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 L("inspect dispatch",{dispatchKey:o},`dispatch ${JSON.stringify(o)}`),console.log(` dispatched: ${o}`);break}case"dismiss":{await d.send({type:"keyboard",action:"dismiss"}),await L("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 ve(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 () => {
428
428
  const interact = window.__sootsimInteract
429
429
  if (interact?.doubleTap) {
430
430
  return {
@@ -447,18 +447,18 @@ ${s}
447
447
  first,
448
448
  second,
449
449
  }
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
+ })()`});u?.ok&&await L("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 ve(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 () => {
451
451
  const interact = window.__sootsimInteract
452
452
  if (!interact?.longPress) return { ok: false, reason: 'no interact.longPress' }
453
453
  const value = await interact.longPress(${o}, ${t}, ${Math.max(0,Math.round(r))})
454
454
  return { ok: !!value, value }
455
- })()`});i?.ok&&await J("inspect long-press",{tapAtCoords:{x:o,y:t}},`long-press @${o},${t}`),console.log(JSON.stringify(i,null,2));break}case"touch":{let o=a[1],t=Number(a[2]),s=Number(a[3]),r=a[4]?Number(a[4]):999,i=o==="down"?"touchDown":o==="move"?"touchMove":o==="up"?"touchUp":o==="cancel"?"touchCancel":null;i||(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),o!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(s))&&(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let u=o==="down"?"tap":o==="move"?"move":null,p=u&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${t}, y: ${s} } }));`:"",w=await d.send({type:"evaluate",code:`(async () => {
455
+ })()`});i?.ok&&await L("inspect long-press",{tapAtCoords:{x:o,y:t}},`long-press @${o},${t}`),console.log(JSON.stringify(i,null,2));break}case"touch":{let o=a[1],t=Number(a[2]),s=Number(a[3]),r=a[4]?Number(a[4]):999,i=o==="down"?"touchDown":o==="move"?"touchMove":o==="up"?"touchUp":o==="cancel"?"touchCancel":null;i||(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),o!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(s))&&(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let u=o==="down"?"tap":o==="move"?"move":null,p=u&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${t}, y: ${s} } }));`:"",w=await d.send({type:"evaluate",code:`(async () => {
456
456
  ${p}
457
457
  const interact = window.__sootsimInteract
458
458
  if (!interact?.${i}) return { ok: false, reason: 'no interact.${i}' }
459
459
  const value = ${o==="cancel"?`await interact.${i}(${Math.max(1,Math.round(r))})`:`await interact.${i}(${t}, ${s}, ${Math.max(1,Math.round(r))})`}
460
460
  return { ok: !!value, value }
461
- })()`});w?.ok&&o!=="cancel"&&await J("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${o} @${t},${s}`),console.log(JSON.stringify(w,null,2));break}case"gesture":{let o=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],t=a[1],s=a[2]?Number(a[2]):220;(!t||!Number.isFinite(s))&&(console.error(k("gesture","<preset> [durationMs]")),console.error(` presets: ${o.join(", ")}`),process.exit(1)),o.includes(t)||(console.error(` unknown gesture preset: ${t}`),console.error(` presets: ${o.join(", ")}`),process.exit(1));let r=await d.send({type:"evaluate",code:`(async () => {
461
+ })()`});w?.ok&&o!=="cancel"&&await L("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${o} @${t},${s}`),console.log(JSON.stringify(w,null,2));break}case"gesture":{let o=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],t=a[1],s=a[2]?Number(a[2]):220;(!t||!Number.isFinite(s))&&(console.error(k("gesture","<preset> [durationMs]")),console.error(` presets: ${o.join(", ")}`),process.exit(1)),o.includes(t)||(console.error(` unknown gesture preset: ${t}`),console.error(` presets: ${o.join(", ")}`),process.exit(1));let r=await d.send({type:"evaluate",code:`(async () => {
462
462
  const spec = globalThis.__sootsimDeviceSpec || {}
463
463
  return {
464
464
  width: spec.width || window.innerWidth || 393,
@@ -471,7 +471,7 @@ ${s}
471
471
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
472
472
  const value = await interact.drag(${b}, ${$}, ${v}, ${oe}, ${K}, ${E})
473
473
  return { ok: !!value, value }
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
+ })()`});he?.ok&&await L("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=Uo(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 () => {
475
475
  const t = window.__sootsimTest
476
476
  if (!t) return null
477
477
  const n = ${t!=null?`await t.inspectByNodeId(${JSON.stringify(t)})`:`await t.findByTestId(${JSON.stringify(s)})
@@ -481,10 +481,7 @@ ${s}
481
481
  cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
482
482
  cy: n.absolutePosition.y + (n.layout.height || 0) / 2,
483
483
  }
484
- })()`}),w=await Y(d,"scrollTo",t!=null?{nodeId:t}:s,i,u,!1);if(w?.ok){let f=t!=null?`node ${t}`:`#${s}`;await J("inspect scroll",{scrollTo:{...t!=null?{nodeId:t}:{id:s},x:i,y:u}},`scroll ${f} -> ${i},${u}`)}console.log(JSON.stringify({...w,...p?{at:{x:p.cx,y:p.cy}}:{}},null,2));break}case"state":{let o=a[1];if(n==="get"&&!o){let s=await Y(d,"getRuntimeState"),r=await d.send({type:"evaluate",code:`({
485
- errors: window.__sootsimConsole?.getErrors?.()?.length ?? 0,
486
- warnings: window.__sootsimConsole?.getWarnings?.()?.length ?? 0,
487
- })`});if(s&&typeof s=="object"&&s.diagnostics&&(s.diagnostics.errors=r?.errors??0,s.diagnostics.warnings=r?.warnings??0),s&&typeof s=="object"&&s.shell==null)try{let i=await le(d);i&&(s.shell=i)}catch{}console.log(JSON.stringify(s,null,2));break}if(!o||o==="--help"||o==="-h"){console.log(`
484
+ })()`}),w=await Y(d,"scrollTo",t!=null?{nodeId:t}:s,i,u,!1);if(w?.ok){let f=t!=null?`node ${t}`:`#${s}`;await L("inspect scroll",{scrollTo:{...t!=null?{nodeId:t}:{id:s},x:i,y:u}},`scroll ${f} -> ${i},${u}`)}console.log(JSON.stringify({...w,...p?{at:{x:p.cx,y:p.cy}}:{}},null,2));break}case"state":{let o=a[1];if(n==="get"&&!o){let s=await Y(d,"getRuntimeState"),r=await d.send({type:"evaluate",code:xe});if(s&&typeof s=="object"&&s.diagnostics&&(s.diagnostics.errors=r?.errors??0,s.diagnostics.warnings=r?.warnings??0),s&&typeof s=="object"&&s.shell==null)try{let i=await le(d);i&&(s.shell=i)}catch{}console.log(JSON.stringify(s,null,2));break}if(!o||o==="--help"||o==="-h"){console.log(`
488
485
  ${h("state")} \u2014 dump raw runtime state
489
486
 
490
487
  subcommands:
@@ -507,7 +504,7 @@ ${s}
507
504
  ${h("state")} scroll feed
508
505
  ${h("state")} scroll-hit 360 420
509
506
  ${h("state")} hit 200 720
510
- `);break}let t;switch(o){case"shell":t=await le(d,500);break;case"worker":t=await Ie(d,"__sootsimRenderHost.queryStats");break;case"ownership":t=await d.send({type:"evaluate",code:`(() => {
507
+ `);break}let t;switch(o){case"shell":t=await le(d,500);break;case"worker":t=await Fe(d,"__sootsimRenderHost.queryStats");break;case"ownership":t=await d.send({type:"evaluate",code:`(() => {
511
508
  const h = window.__sootsimRenderHost
512
509
  if (!h || typeof h.getOwnershipSnapshot !== 'function') {
513
510
  return { error: 'getOwnershipSnapshot not available' }
@@ -562,7 +559,7 @@ ${s}
562
559
  ${h("shell")} open-card clock 800
563
560
  ${h("shell")} appearance dark
564
561
  ${h("shell")} lock
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:`;(() => {
562
+ `);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:Ye}),i=!!await pe(d,"launchApp",r,f),{settled:u,state:p}=await Te(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 L("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 Te(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 Te(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 Te(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 L("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 Zt(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 Zt(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:`;(() => {
566
563
  const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
567
564
  if (typeof reloadExternalApp === 'function') {
568
565
  reloadExternalApp()
@@ -570,7 +567,7 @@ ${s}
570
567
  }
571
568
  window.location.reload()
572
569
  return { kind: 'page' }
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(`
570
+ })()`});r=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let i=d,u=null;if(r)u=await Re(d,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await Z(300);let p=await ht(_,j,I,{timeoutMs:1e4,simIdSource:R});p?(i=p,u=await Re(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=Do(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 we(i,10);if(i!==d&&i.close(),Array.isArray(p)&&p.length>0){console.log(`
574
571
  \u26A0 ${p.length} error(s) during mount:
575
572
  `);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(`
576
573
  `).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 () => {
@@ -611,7 +608,7 @@ ${s}
611
608
 
612
609
  return globals
613
610
  })()`});console.log(` sootsim JS API:
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(`
611
+ `);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 Ot({bridge:d,args:e,positional:a});break}case"perf":{let o=a[1];if(!o||o==="--help"||o==="-h"){console.log(`
615
612
  ${h("perf")} \u2014 performance profiling
616
613
 
617
614
  subcommands:
@@ -815,7 +812,7 @@ ${s}
815
812
  mode: 'main-thread',
816
813
  frames: (stats.recentFrames || []).slice(-${t}),
817
814
  }
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 () => {
815
+ })()`});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(""),Be(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(", ")}`),Be(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 () => {
819
816
  if (window.__sootsimRenderHost) {
820
817
  const session = window.${se} || {}
821
818
  if (session.active) {
@@ -870,7 +867,7 @@ ${s}
870
867
  examples:
871
868
  ${h("perf")} transition goHome --timeout 10000
872
869
  ${h("perf")} transition appSwitcher
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 () => {
870
+ `);break}let r=`sootsim:${t}`;Pe(` profiling ${t} transition...`),Pe(" (use --timeout 10000 if this times out)");let i=await d.send({type:"evaluate",code:`(async () => {
874
871
  // only supported in render-worker mode
875
872
  if (!window.__sootsimRenderHost) {
876
873
  return { error: 'transition profiling requires render-worker mode' }
@@ -947,29 +944,29 @@ ${s}
947
944
  p50: ${i.p50.toFixed(2)}ms
948
945
  p95: ${i.p95.toFixed(2)}ms
949
946
  p99: ${i.p99.toFixed(2)}ms
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):
947
+ jank: ${i.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(i.samples)&&i.samples.length>0&&(console.log(""),Be(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 at(d),A(l)?P({cleared:!0}):console.log(" error buffer cleared");break}let t=o?Number(o):20,s=await we(d,t);if(A(l)){P(s);break}if(s.length===0){console.log(" no errors captured");break}console.log(` ${s.length} error(s):
951
948
  `);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(`
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):
949
+ `).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 it(d,o);if(A(l)){P(t);break}if(t.length===0){console.log(" no warnings captured");break}console.log(` ${t.length} warning(s):
953
950
  `);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):
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)"}:
951
+ `);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 ct(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 lt(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)"}:
955
952
  `);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:`(() => {
956
953
  const obs = window.__sootsimObservability;
957
954
  if (!obs) return null;
958
955
  return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(F)}) || null;
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).
956
+ })()`});b||(console.error(` no entry with id ${F}`),process.exit(1)),w?console.log(JSON.stringify(b,null,2)):Bo(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).
960
957
  to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let x=async()=>{let F=await d.send({type:"evaluate",code:`(() => {
961
958
  const obs = window.__sootsimObservability;
962
959
  if (!obs) return { ok: false };
963
960
  return { ok: true, entries: obs.network.getSnapshot() };
964
961
  })()`});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):
965
962
  `:` ${b.length} request(s):
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.
963
+ `);for(let $ of b)Gt($);break}console.log(` tailing network (ctrl-c to stop)...
964
+ `);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($)):Gt($)));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 ut(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).
965
+ to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let O=()=>dt(d),q=b=>mt(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):
966
+ `);for(let v of $)Vt(v,f);break}console.log(` tailing logs (ctrl-c to stop)...
967
+ `);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)):Vt(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 Ge(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 St(d,_,s[1]);else if(/^no sim connected$/.test(t))$t(_);else if(r)if(await Ao(d)){let p=g??"describe";process.stderr.write(` the sim is still responsive \u2014 '${p}' just exceeded the ${r[1]}s command budget.
971
968
  the screen's node tree is large; narrow the query or raise the budget:
972
969
  sootsim ${p} --testid <id> # scope to one subtree
973
970
  sootsim find --testid <id> # targeted single-node lookup
974
971
  sootsim ${p} --timeout 60000 # raise per-command budget (ms)
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};
972
+ `)}else Yt();else if(i)Yt();else{try{await bt(d)}catch{}try{await X({includeTail:!0})}catch{}try{await W({includeTail:!0})}catch{}}process.exit(1)}finally{d.close()}}export{Rn as runInspect};