sootsim 0.1.151 → 0.1.153

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 (149) hide show
  1. package/dist-cli/bin.js +3 -3
  2. package/dist-cli/chunks/{agent-HF26UPHZ.js → agent-VUP4VAVS.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-4HZHSIBM.js → agent-wrapper-D4ESDAXG.js} +2 -2
  4. package/dist-cli/chunks/{app-fonts-QX4EBH3Y.js → app-fonts-ZYYLH4SC.js} +2 -2
  5. package/dist-cli/chunks/{assert-X3FR2NZ2.js → assert-BFLCTPDL.js} +2 -2
  6. package/dist-cli/chunks/auto-bootstrap-COJBYU4X.js +2 -0
  7. package/dist-cli/chunks/beta-3KCKUADE.js +2 -0
  8. package/dist-cli/chunks/{camera-LPNM5TWG.js → camera-FSKBR7NQ.js} +2 -2
  9. package/dist-cli/chunks/{chunk-TGU3ZYMR.js → chunk-2IWPNBFB.js} +2 -2
  10. package/dist-cli/chunks/{chunk-O27REOF5.js → chunk-3H2TX3GH.js} +3 -3
  11. package/dist-cli/chunks/{chunk-5H6GZFYN.js → chunk-4FLQLE7X.js} +1 -1
  12. package/dist-cli/chunks/{chunk-RTKF3UI6.js → chunk-7ZMQBJPJ.js} +2 -2
  13. package/dist-cli/chunks/chunk-BH3U25T4.js +1 -0
  14. package/dist-cli/chunks/{chunk-BVS5TAH2.js → chunk-BI5YCP4N.js} +1 -1
  15. package/dist-cli/chunks/{chunk-HTX5H2GP.js → chunk-BKX7SEPA.js} +1 -1
  16. package/dist-cli/chunks/{chunk-TTWUL3IS.js → chunk-D46GUIMS.js} +1 -1
  17. package/dist-cli/chunks/{chunk-H43XNA63.js → chunk-D7LOPY4O.js} +2 -2
  18. package/dist-cli/chunks/{chunk-O6EXHRXC.js → chunk-EXCVVWAW.js} +2 -2
  19. package/dist-cli/chunks/{chunk-BOLOMY35.js → chunk-EYBETMFT.js} +2 -2
  20. package/dist-cli/chunks/{chunk-LKQ2DNH2.js → chunk-FHNZ72F2.js} +1 -1
  21. package/dist-cli/chunks/{chunk-QKGVXTZI.js → chunk-FRAH3R5M.js} +2 -2
  22. package/dist-cli/chunks/{chunk-EATQR7G4.js → chunk-GRE44V25.js} +1 -1
  23. package/dist-cli/chunks/{chunk-F24Q4SHJ.js → chunk-H66V4LS4.js} +2 -2
  24. package/dist-cli/chunks/{chunk-FVWECVSR.js → chunk-HWXC2EGB.js} +1 -1
  25. package/dist-cli/chunks/{chunk-AWNUBM2E.js → chunk-IEJ4RC3G.js} +1 -1
  26. package/dist-cli/chunks/{chunk-ESKWHYHW.js → chunk-J62KE5RK.js} +1 -1
  27. package/dist-cli/chunks/{chunk-SESGIWXA.js → chunk-JWOALEME.js} +2 -2
  28. package/dist-cli/chunks/{chunk-5JIRUN6N.js → chunk-KM6DRJEI.js} +2 -2
  29. package/dist-cli/chunks/{chunk-3FGC5AEV.js → chunk-KWCYMNNZ.js} +3 -3
  30. package/dist-cli/chunks/{chunk-TDEMJJSM.js → chunk-LB6OTENV.js} +2 -2
  31. package/dist-cli/chunks/{chunk-EKJWBS67.js → chunk-LGXJNSQ7.js} +2 -2
  32. package/dist-cli/chunks/{chunk-6WDJBOEC.js → chunk-OEKYS3CU.js} +2 -2
  33. package/dist-cli/chunks/chunk-OQWKR3A5.js +2 -0
  34. package/dist-cli/chunks/{chunk-IFVPMU3W.js → chunk-OVL52WGS.js} +1 -1
  35. package/dist-cli/chunks/{chunk-KIEHXEK7.js → chunk-PR4A6ZBX.js} +1 -1
  36. package/dist-cli/chunks/chunk-PUYHI5PX.js +1 -0
  37. package/dist-cli/chunks/{chunk-PWRZZZPB.js → chunk-PZNY2IMY.js} +2 -2
  38. package/dist-cli/chunks/chunk-QJT4LINK.js +1 -0
  39. package/dist-cli/chunks/{chunk-5KZSTOC3.js → chunk-QR5D3PYK.js} +1 -1
  40. package/dist-cli/chunks/{chunk-YMXGXIXH.js → chunk-R2CHKR3F.js} +2 -2
  41. package/dist-cli/chunks/{chunk-R3PWYPRY.js → chunk-RSGKJDBB.js} +2 -2
  42. package/dist-cli/chunks/{chunk-PBMOGVVU.js → chunk-SMYWVHZJ.js} +2 -2
  43. package/dist-cli/chunks/{chunk-UKNZBRJA.js → chunk-SQJ7EOXE.js} +2 -2
  44. package/dist-cli/chunks/{chunk-KBR532N6.js → chunk-UDN3JDKK.js} +2 -2
  45. package/dist-cli/chunks/{chunk-D6TQZJYX.js → chunk-V6OMDU5O.js} +2 -2
  46. package/dist-cli/chunks/{chunk-UYSK2W2E.js → chunk-V6T7LUYX.js} +3 -3
  47. package/dist-cli/chunks/{chunk-DT6P4QPA.js → chunk-VHNOMO4C.js} +2 -2
  48. package/dist-cli/chunks/{chunk-SFJL7VJD.js → chunk-VKGXM77Z.js} +1 -1
  49. package/dist-cli/chunks/{chunk-YBFFAGCA.js → chunk-W2JRJNRF.js} +1 -1
  50. package/dist-cli/chunks/{chunk-4D7OSBQW.js → chunk-W4H7MQVB.js} +1 -1
  51. package/dist-cli/chunks/{chunk-OYZ5C2UW.js → chunk-XPQOPN7M.js} +2 -2
  52. package/dist-cli/chunks/{chunk-NJ5IKC7D.js → chunk-YAMN6VOF.js} +1 -1
  53. package/dist-cli/chunks/{chunk-6OX6ZCDK.js → chunk-YNAS44F7.js} +1 -1
  54. package/dist-cli/chunks/cli-version-XHYPGWVW.js +2 -0
  55. package/dist-cli/chunks/{compat-OY6OZ5JL.js → compat-3R3EOAHC.js} +3 -3
  56. package/dist-cli/chunks/{config-XT46L34R.js → config-M5QFP3HY.js} +2 -2
  57. package/dist-cli/chunks/{control-JSU4YZEU.js → control-VYNHMIGQ.js} +2 -2
  58. package/dist-cli/chunks/{cpu-profile-2YFNBTUY.js → cpu-profile-IXGMLKLH.js} +2 -2
  59. package/dist-cli/chunks/{daemon-FU7YT33F.js → daemon-UBTYY6D4.js} +2 -2
  60. package/dist-cli/chunks/{debug-FEQNYGBL.js → debug-LV3MG5PC.js} +3 -3
  61. package/dist-cli/chunks/{detox-ONWHXJQW.js → detox-Q47VQ5PD.js} +2 -2
  62. package/dist-cli/chunks/{device-Q4JEXXDO.js → device-YCYTUZMI.js} +2 -2
  63. package/dist-cli/chunks/{diagnose-ABW6RT2M.js → diagnose-ST3MONQ7.js} +2 -2
  64. package/dist-cli/chunks/drivers-MBE4KVMK.js +2 -0
  65. package/dist-cli/chunks/{electron-S6DSORXV.js → electron-ZCYDKW2J.js} +3 -3
  66. package/dist-cli/chunks/flow-UQX7RP42.js +2 -0
  67. package/dist-cli/chunks/help-EWU4IV5Y.js +2 -0
  68. package/dist-cli/chunks/{hints-6UNUXIZD.js → hints-F7FLRJZB.js} +2 -2
  69. package/dist-cli/chunks/{home-paths-7MZVETWY.js → home-paths-XQ3Z7MZ2.js} +2 -2
  70. package/dist-cli/chunks/{inspect-D2BQ276F.js → inspect-T3HU4JTX.js} +114 -105
  71. package/dist-cli/chunks/install-NNYE7LQ7.js +2 -0
  72. package/dist-cli/chunks/{install-desktop-ZQSDFGUC.js → install-desktop-XEBZ4KIS.js} +3 -3
  73. package/dist-cli/chunks/{keys-TEXYT224.js → keys-GLJBONHU.js} +2 -2
  74. package/dist-cli/chunks/{launch-DER37SAB.js → launch-JQRLMLEL.js} +3 -3
  75. package/dist-cli/chunks/{login-XGRAXI4M.js → login-GWOXMZL2.js} +4 -4
  76. package/dist-cli/chunks/{logout-54RCAVHR.js → logout-WHUPTLE2.js} +2 -2
  77. package/dist-cli/chunks/{maestro-UOI22ZJK.js → maestro-D6JKMP67.js} +2 -2
  78. package/dist-cli/chunks/optional-demo-registry-MQJP3RHL.js +2 -0
  79. package/dist-cli/chunks/{preview-4P3JDGUK.js → preview-UBF5FA32.js} +2 -2
  80. package/dist-cli/chunks/{profile-CAT2T2SL.js → profile-GTP2VYXL.js} +2 -2
  81. package/dist-cli/chunks/{react-BARNSA53.js → react-KITQMQJH.js} +2 -2
  82. package/dist-cli/chunks/{record-6XRDBFJH.js → record-DR37W3JA.js} +2 -2
  83. package/dist-cli/chunks/runtime-NQXJVL2M.js +2 -0
  84. package/dist-cli/chunks/{runtime-delivery-M6AZKBA5.js → runtime-delivery-DNETQTB7.js} +2 -2
  85. package/dist-cli/chunks/{screenshot-NCQJZ2UA.js → screenshot-YFSYOMN2.js} +2 -2
  86. package/dist-cli/chunks/{screenshot-mode-WCMNSQPA.js → screenshot-mode-OPRSV6SC.js} +2 -2
  87. package/dist-cli/chunks/{screenshots-KRUJCP3C.js → screenshots-ZW7O7GUN.js} +2 -2
  88. package/dist-cli/chunks/{server-7M7623HK.js → server-P6LFB6TE.js} +3 -3
  89. package/dist-cli/chunks/setup-repo-OXIAB6PS.js +2 -0
  90. package/dist-cli/chunks/{skills-QYZYYG2J.js → skills-ET4YCGCE.js} +2 -2
  91. package/dist-cli/chunks/{slides-KBNA4WNE.js → slides-YBQMTQDC.js} +2 -2
  92. package/dist-cli/chunks/{start-IETLWS52.js → start-ETZPDPFI.js} +4 -4
  93. package/dist-cli/chunks/store-NAABILLN.js +2 -0
  94. package/dist-cli/chunks/telemetry-FEMV2Q4T.js +2 -0
  95. package/dist-cli/chunks/{test-XFMRNPRE.js → test-7ONSXHTV.js} +3 -3
  96. package/dist-cli/chunks/{three-mode-F7HISUUI.js → three-mode-NJOEKCOV.js} +2 -2
  97. package/dist-cli/chunks/{timeline-6J64INHT.js → timeline-4HDF2MVZ.js} +2 -2
  98. package/dist-cli/chunks/{upgrade-YLUSFIAT.js → upgrade-P5OKZBKQ.js} +2 -2
  99. package/dist-cli/chunks/upload-IQU5LLDG.js +2 -0
  100. package/dist-cli/chunks/{version-SHVMZDZG.js → version-CKVITOE4.js} +2 -2
  101. package/dist-cli/chunks/{web-HTNW72DU.js → web-NZ6X3775.js} +2 -2
  102. package/dist-cli/chunks/{what-happened-5C5Y4QM3.js → what-happened-C22PRVY2.js} +2 -2
  103. package/dist-cli/chunks/{whoami-SGY5QNCO.js → whoami-ILT2PJHK.js} +2 -2
  104. package/dist-lib/agent-daemon-client.cjs +1 -1
  105. package/dist-lib/agent-events.cjs +1 -1
  106. package/dist-lib/agent-sessions.cjs +1 -1
  107. package/dist-lib/attached-projects.cjs +1 -1
  108. package/dist-lib/auth/shared-session.cjs +1 -1
  109. package/dist-lib/backend-origin.cjs +1 -1
  110. package/dist-lib/beta.cjs +1 -1
  111. package/dist-lib/beta.mjs +1 -1
  112. package/dist-lib/bridge-constants.cjs +1 -1
  113. package/dist-lib/cli-constants.cjs +1 -1
  114. package/dist-lib/config.cjs +1 -1
  115. package/dist-lib/detox/index.cjs +1 -1
  116. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  117. package/dist-lib/home-paths.cjs +1 -1
  118. package/dist-lib/host/bridge-host.cjs +1 -1
  119. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  120. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  121. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  122. package/dist-lib/host/websocket-proxy.cjs +1 -1
  123. package/dist-lib/index.cjs +1 -1
  124. package/dist-lib/metro.cjs +1 -1
  125. package/dist-lib/profiles.cjs +1 -1
  126. package/dist-lib/render-mode.cjs +1 -1
  127. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  128. package/dist-lib/sdk.cjs +1 -1
  129. package/dist-lib/sdk.mjs +1 -1
  130. package/dist-lib/skills.cjs +2 -2
  131. package/dist-lib/vite.cjs +1 -1
  132. package/package.json +1 -1
  133. package/dist-cli/chunks/auto-bootstrap-UDZRGLRQ.js +0 -2
  134. package/dist-cli/chunks/beta-J2ZMH6QE.js +0 -2
  135. package/dist-cli/chunks/chunk-4GGBZKRO.js +0 -1
  136. package/dist-cli/chunks/chunk-5QT4UDE6.js +0 -1
  137. package/dist-cli/chunks/chunk-KKH6VZK2.js +0 -2
  138. package/dist-cli/chunks/chunk-TVNSALAZ.js +0 -1
  139. package/dist-cli/chunks/cli-version-45JCT2ZY.js +0 -2
  140. package/dist-cli/chunks/drivers-SI4Q6422.js +0 -2
  141. package/dist-cli/chunks/flow-C5BYKBI7.js +0 -2
  142. package/dist-cli/chunks/help-STIHU2FY.js +0 -2
  143. package/dist-cli/chunks/install-YT6QYQEY.js +0 -2
  144. package/dist-cli/chunks/optional-demo-registry-ZHLX4N4H.js +0 -2
  145. package/dist-cli/chunks/runtime-EP46YAAA.js +0 -2
  146. package/dist-cli/chunks/setup-repo-42YJPORX.js +0 -2
  147. package/dist-cli/chunks/store-DCTO3QUM.js +0 -2
  148. package/dist-cli/chunks/telemetry-SWSO644L.js +0 -2
  149. package/dist-cli/chunks/upload-CNH4T5T3.js +0 -2
@@ -1,9 +1,9 @@
1
- /*! sootsim v0.1.151 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as Y}from"./chunk-PBMOGVVU.js";import{a as wt,b as xt}from"./chunk-ESKWHYHW.js";import{a as Ge,g as $e,j as ee}from"./chunk-UKNZBRJA.js";import{b as $t,c as St,j as vt}from"./chunk-DT6P4QPA.js";import"./chunk-6WDJBOEC.js";import{a as Z,b as A,c as P,d as Pe,e as re,f as G,g as ce,h as pe,i as yt,j as ht,k as Re,l as bt}from"./chunk-5JIRUN6N.js";import{A as ut,B as mt,F as pt,H as le,I as ft,O as gt,a as be,b as Ye,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,q as Ae,r as nt,s as rt,t as we,u as it,v as xe,w as at,x as lt,y as ct,z as dt}from"./chunk-EATQR7G4.js";import"./chunk-TTWUL3IS.js";import{c as He,e as Ue,f as Ke,g as ze,h as Fe}from"./chunk-TDEMJJSM.js";import"./chunk-6OX6ZCDK.js";import"./chunk-OYZ5C2UW.js";import"./chunk-AWNUBM2E.js";import"./chunk-PWRZZZPB.js";import"./chunk-5QT4UDE6.js";import"./chunk-HTX5H2GP.js";import{b as qe}from"./chunk-BVS5TAH2.js";import{a as Le}from"./chunk-FVWECVSR.js";import{a as Ie,c as Ne}from"./chunk-4D7OSBQW.js";import{a as We}from"./chunk-KKH6VZK2.js";import"./chunk-5H6GZFYN.js";import"./chunk-LKQ2DNH2.js";import"./chunk-NJ5IKC7D.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(),r=l.cooldownMs??xo,g=So(m),y=ko(e,c),T=g.entries[y];return T&&T.signature===n&&m-T.updatedAt<r?!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,r=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(r=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:r,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 () => {
1
+ /*! sootsim v0.1.153 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as Y}from"./chunk-SMYWVHZJ.js";import{a as vt,b as kt}from"./chunk-J62KE5RK.js";import{a as Qe,g as ve,j as te}from"./chunk-SQJ7EOXE.js";import{b as Tt,c as Mt,j as It}from"./chunk-VHNOMO4C.js";import"./chunk-OEKYS3CU.js";import{a as ee,b as A,c as P,d as Re,e as ie,f as G,g as ue,h as fe,i as xt,j as $t,k as De,l as St}from"./chunk-KM6DRJEI.js";import{A as gt,B as yt,F as bt,H as ce,I as ht,O as wt,a as xe,b as Ze,c as et,d as tt,e as ot,f as st,g as nt,h as rt,i as it,j as at,k as Ae,l as Pe,q as Ee,r as lt,s as ct,t as $e,u as ut,v as Se,w as dt,x as mt,y as pt,z as ft}from"./chunk-GRE44V25.js";import"./chunk-D46GUIMS.js";import{c as Ge,e as Ye,f as Xe,g as Ve,h as Oe}from"./chunk-LB6OTENV.js";import"./chunk-YNAS44F7.js";import"./chunk-XPQOPN7M.js";import"./chunk-IEJ4RC3G.js";import"./chunk-PZNY2IMY.js";import"./chunk-BH3U25T4.js";import"./chunk-BKX7SEPA.js";import{b as ze}from"./chunk-BI5YCP4N.js";import{a as Ke}from"./chunk-HWXC2EGB.js";import{a as Fe,c as _e}from"./chunk-W4H7MQVB.js";import{a as Ue}from"./chunk-OQWKR3A5.js";import"./chunk-4FLQLE7X.js";import"./chunk-FHNZ72F2.js";import"./chunk-YAMN6VOF.js";import{existsSync as fo,mkdirSync as go,readFileSync as yo,rmSync as Nt,writeFileSync as bo}from"fs";import{tmpdir as ho}from"os";import{dirname as wo,join as xo,resolve as $o}from"path";var ge=1,So="SOOTSIM_INSPECT_NOTICE_PATH",vo=300*1e3,ko=15e3;function Ft(){return $o(process.env[So]||xo(ho(),"sootsim-inspect-notice-state.json"))}function To(e,l){return Object.fromEntries(Object.entries(e).filter(([,n])=>typeof n?.signature=="string"&&Number.isFinite(n?.updatedAt)&&l-n.updatedAt<=vo))}function Mo(e){let l=Ft();if(!fo(l))return{version:ge,entries:{}};try{let n=JSON.parse(yo(l,"utf8"));return n.version!==ge||!n.entries||typeof n.entries!="object"?(Nt(l,{force:!0}),{version:ge,entries:{}}):{version:ge,entries:To(n.entries,e)}}catch{return Nt(l,{force:!0}),{version:ge,entries:{}}}}function Io(e){let l=Ft();go(wo(l),{recursive:!0}),bo(l,JSON.stringify(e,null,2)+`
3
+ `)}function No(e,l){let n=l.trim()||"default";return`${e}:${n}`}function Ce(e,l,n,c={}){let m=c.nowMs??Date.now(),i=c.cooldownMs??ko,g=Mo(m),y=No(e,l),T=g.entries[y];return T&&T.signature===n&&m-T.updatedAt<i?!1:(g.entries[y]={signature:n,updatedAt:m},Io(g),!0)}var Fo={initialWaitMs:3e3,deadlineMs:5e3,retryWaitMs:700},_o={initialWaitMs:1200,deadlineMs:2500,retryWaitMs:700};function Oo(e,l={}){return{...e?Fo:_o,...l}}function de(e){return!(!e||e.hit===!1||e.ok===!1||e.pointerTapHandled===!1&&!e.keyboardOpened&&!e.isTextInput)}function Ao(e,l){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??l??null,type:e.target?.type??e.match?.type??e.node?.type??null}}async function ye(e,l){let n=Oo(!!l.agent,l.timing),c=0,m=null,i=null;try{await te({bridge:e,maxMs:n.initialWaitMs,pollMs:32,stablePolls:2})}catch{}let g=Date.now()+n.deadlineMs;for(;Date.now()<=g||c===0;){c++;let y=await l.resolve();if(m=y,y?.error==="bridge-not-ready"||y?.ambiguous||y?.nthOutOfRange)return{payload:y,result:null,attempts:c,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:Ao(y,l.textFallback)});if(i=M,de(M))return{payload:y,result:M,attempts:c}}let T=g-Date.now();if(T<=0)break;try{await te({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:i,attempts:c,failure:m&&typeof m.cx=="number"?"missed":"not-found"}}async function _t(e,l,n,c){return e.send({type:"tap",x:l,y:n,...c?{target:c}:{}})}async function Ot(e,l,n={}){let c=JSON.stringify(l);return ye(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
- const n = (await t.findByTestId(${l})) || (await t.findById(${l}))
6
+ const n = (await t.findByTestId(${c})) || (await t.findById(${c}))
7
7
  if (!n || !n.absolutePosition || !n.layout) return { cx: null }
8
8
  const resolved =
9
9
  typeof n.nodeId === 'number' && typeof t.resolveTapTarget === 'function'
@@ -42,7 +42,7 @@ import{a as Y}from"./chunk-PBMOGVVU.js";import{a as wt,b as xt}from"./chunk-ESKW
42
42
  },
43
43
  strategy: (resolved && resolved.strategy) || 'matched-node',
44
44
  }
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 () => {
45
+ })()`})})}async function At(e,l,n={},c={}){let m=JSON.stringify({query:l,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 ye(e,{agent:c.agent,timing:c.timing,textFallback:l,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,11 +162,11 @@ import{a as Y}from"./chunk-PBMOGVVU.js";import{a as wt,b as xt}from"./chunk-ESKW
162
162
  total,
163
163
  idx,
164
164
  }
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 () => {
165
+ })()`})})}async function Pt(e,l,n={}){let c=JSON.stringify(l);return ye(e,{agent:n.agent,timing:n.timing,textFallback:l,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 =
169
- (await t.findByTestId(${l})) || (await t.findById(${l}))
169
+ (await t.findByTestId(${c})) || (await t.findById(${c}))
170
170
  if (byTestId && byTestId.absolutePosition && byTestId.layout) {
171
171
  return {
172
172
  strategy: 'testid',
@@ -181,7 +181,7 @@ import{a as Y}from"./chunk-PBMOGVVU.js";import{a as wt,b as xt}from"./chunk-ESKW
181
181
  },
182
182
  }
183
183
  }
184
- const byText = await t.findByText(${l})
184
+ const byText = await t.findByText(${c})
185
185
  if (byText && byText.absolutePosition && byText.layout) {
186
186
  return {
187
187
  strategy: 'text',
@@ -197,19 +197,19 @@ import{a as Y}from"./chunk-PBMOGVVU.js";import{a as wt,b as xt}from"./chunk-ESKW
197
197
  }
198
198
  }
199
199
  return { strategy: 'none' }
200
- })()`});if(!m||!("node"in m))return m;let r=m.node,g=r.absolutePosition.x+r.layout.width/2,y=r.absolutePosition.y+r.layout.height/2;return{...m,cx:g,cy:y,target:{id:r.id,testID:r.testID,text:m.strategy==="text"?c:r.text,type:r.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 De(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"),r=A(n),g=m&&!r,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=De(n,"--testid-like"),R=De(n,"--only"),j=De(n,"--subtree"),d=l[1]&&!l[1].startsWith("-")?l[1]:void 0,z=d?/[*?]/.test(d):!1,B=!z&&!R?d:void 0,D=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:D||void 0,subtreeRoot:j||void 0,compact:M,hideXy:h,includeOccluded:_}),N=S?.tree,L=S?.shell,W=S?.keyboard;if(r){P({shell:L,tree:N??"",keyboard:W});return}if(L&&typeof L=="object"){let C=[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);C.length>0&&console.log(` shell: ${C.join(" ")}`)}if(typeof N=="string"&&N.startsWith("__SUBTREE_NOT_FOUND__:")){let C=N.slice(22);console.log(` subtree root not found: ${C}`),Y("subtree-root-not-found",C);return}if(!N){let C=S?.nodeCount??0;console.log(" no matching nodes found"),!(B||I||D||j)&&C<10&&Y("app-still-loading",C);return}let X=N,Q=0;if(k&&typeof X=="string"){let C=X.split(`
201
- `),ae=[];for(let o of C){if(o.includes("(clipped:")){Q+=1;continue}ae.push(o)}X=ae.join(`
202
- `)}console.log(X),Q>0&&console.log(` ${Q} clipped row(s) hidden (omit --no-clipped to see)`);let ne=B||I||D||j;if((B||I||D)&&!y&&Y("describe-filter-context"),!ne&&!y&&N.split(`
203
- `).length>=80&&Y("describe-use-filters"),W&&W.visible){let C=W.spec,ae=[C?.keyboardType?`type=${C.keyboardType}`:null,C?.returnKeyType&&C.returnKeyType!=="default"?`return=${C.returnKeyType}`:null,W.mode!=="letters"?`mode=${W.mode}`:null,W.shifted?"shift":null,W.capsLock?"caps":null,C?.autoCapitalize&&C.autoCapitalize!=="sentences"?`autoCap=${C.autoCapitalize}`:null,W.accessoryBarId?`accessory=${W.accessoryBarId}`:null].filter(Boolean);console.log(`
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 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:r}=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(r("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:B,result:D}=z,V=A(n),te=n.includes("--verbose")||n.includes("--dump");if(V)B==="interactive-targets"&&Array.isArray(D)?P(_e(D).map(S=>({...S,tap:Oe(S)}))):P(D??null);else if(Array.isArray(D))if(D.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&&Y("app-still-loading",S)}else if(B==="interactive-targets"){let S=_e(D);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,C=Oe(N);console.log(` ${me}${X}${ne}${Q} ${W} ${L}`),console.log(` \u2192 ${C}`),te&&console.log(Ce(JSON.stringify(N,null,2)," "))}S.length>20&&console.log(` ... and ${S.length-20} more`)}else{console.log(` found ${D.length} node${D.length===1?"":"s"} (${B}):`);for(let S of D.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(Ce(JSON.stringify(S,null,2)," "))}D.length>20&&console.log(` ... and ${D.length-20} more`)}else if(D==null)console.log(` not found: ${d||T||M||h||""||B}`),T&&Y("wait-selector-for-missing-testid",T);else{let S=D;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(Ce(JSON.stringify(S,null,2)," "))}else console.log(JSON.stringify(D,null,2))}}function Ce(e,c){return e.split(`
206
- `).map(n=>c+n).join(`
207
- `)}async function Pt(e){let{bridge:c,args:n}=e,l=A(n);await ce(c,{verbose:!l});let m=n.includes("--styling"),r=await et(c,{styling:m});if(l){P({count:r.length,elements:r});return}console.log(` layout (${r.length} element${r.length===1?"":"s"}):
208
- `),console.log(tt(r,{styling: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:r,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: ${r}${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"),r=e.args.includes("--primary"),g=c.filter(y=>!(r&&!y.isPrimary||l&&!(y.url??"").includes(l)||m&&!(y.url??"").includes(`/rn/${m}`)||!n&&!l&&!m&&!r&&!(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 Dt(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(` live frames: ${l.liveFrames}`)}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 () => {
200
+ })()`});if(!m||!("node"in m))return m;let i=m.node,g=i.absolutePosition.x+i.layout.width/2,y=i.absolutePosition.y+i.layout.height/2;return{...m,cx:g,cy:y,target:{id:i.id,testID:i.testID,text:m.strategy==="text"?l:i.text,type:i.type}}}})}async function Et(e,l={args:[]}){let n=await et(e);if(A(l.args)){P(n);return}console.log(` nodes: ${n.nodes}`)}function Be(e,l){let n=e.indexOf(l);return n>=0&&n+1<e.length?e[n+1]:null}async function Rt(e){let{bridge:l,args:n,positional:c}=e,m=n.includes("--verbose")||n.includes("-v"),i=A(n),g=m&&!i,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=Be(n,"--testid-like"),E=Be(n,"--only"),j=Be(n,"--subtree"),u=c[1]&&!c[1].startsWith("-")?c[1]:void 0,z=u?/[*?]/.test(u):!1,B=!z&&!E?u:void 0,D=E??(z?u:void 0),Q=async()=>{await ue(l,{verbose:g});let S=await st(l,{describe:!0,verbose:m,filter:B||"",testIdLike:I||void 0,onlyGlob:D||void 0,subtreeRoot:j||void 0,compact:M,hideXy:h,includeOccluded:_}),N=S?.tree,J=S?.shell,W=S?.keyboard;if(i){P({shell:J,tree:N??"",keyboard:W});return}if(J&&typeof J=="object"){let C=[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);C.length>0&&console.log(` shell: ${C.join(" ")}`)}if(typeof N=="string"&&N.startsWith("__SUBTREE_NOT_FOUND__:")){let C=N.slice(22);console.log(` subtree root not found: ${C}`),Y("subtree-root-not-found",C);return}if(!N){let C=S?.nodeCount??0;console.log(" no matching nodes found"),!(B||I||D||j)&&C<10&&Y("app-still-loading",C);return}let V=N,Z=0;if(k&&typeof V=="string"){let C=V.split(`
201
+ `),le=[];for(let o of C){if(o.includes("(clipped:")){Z+=1;continue}le.push(o)}V=le.join(`
202
+ `)}console.log(V),Z>0&&console.log(` ${Z} clipped row(s) hidden (omit --no-clipped to see)`);let re=B||I||D||j;if((B||I||D)&&!y&&Y("describe-filter-context"),!re&&!y&&N.split(`
203
+ `).length>=80&&Y("describe-use-filters"),W&&W.visible){let C=W.spec,le=[C?.keyboardType?`type=${C.keyboardType}`:null,C?.returnKeyType&&C.returnKeyType!=="default"?`return=${C.returnKeyType}`:null,W.mode!=="letters"?`mode=${W.mode}`:null,W.shifted?"shift":null,W.capsLock?"caps":null,C?.autoCapitalize&&C.autoCapitalize!=="sentences"?`autoCap=${C.autoCapitalize}`:null,W.accessoryBarId?`accessory=${W.accessoryBarId}`:null].filter(Boolean);console.log(`
204
+ keyboard: ${le.join(" ")||"visible"}`)}};if(y)for(console.log(` watching... (Ctrl+C to stop)
205
+ `);;)console.clear(),await Q(),await ee(T);else await Q()}var Po=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function me(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let e of Po){let l=process.env[e];if(l&&l.trim()&&l!=="0")return!0}return!1}async function Dt(e){let{bridge:l,args:n,effectiveArgs:c,positional:m,inspectUsage:i}=e,g=S=>{let N=c.indexOf(S);return N>=0&&N+1<c.length?c[N+1]:null},y=S=>c.includes(S),T=g("--testid")||g("--test-id"),M=g("--role"),h=g("--type"),k=g("--text"),_=y("--pressable"),I=y("--visible"),E=y("--interactive-targets")||y("--actions"),j=!T&&!M&&!h&&!k&&!_&&!I&&!E?m[1]:null,u=k??j,z=await at(l,{testId:T,role:M,type:h,text:u,pressable:_,visible:I,interactive:E});z||(console.error(i("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:B,result:D}=z,Q=A(n),oe=n.includes("--verbose")||n.includes("--dump");if(Q)B==="interactive-targets"&&Array.isArray(D)?P(Ae(D).map(S=>({...S,tap:Pe(S)}))):P(D??null);else if(Array.isArray(D))if(D.length===0){console.log(` no ${B} nodes found`);let S=await l.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof S=="number"&&S<10&&Y("app-still-loading",S)}else if(B==="interactive-targets"){let S=Ae(D);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?",V=N.text?` "${N.text.slice(0,30)}"`:"",Z=N.testID?` #${N.testID}`:"",re=N.accessibilityLabel?` \u24D8"${String(N.accessibilityLabel).slice(0,24)}"`:"",pe=N.accessibilityRole?`[${N.accessibilityRole}]`:N.type,C=Pe(N);console.log(` ${pe}${V}${re}${Z} ${W} ${J}`),console.log(` \u2192 ${C}`),oe&&console.log(je(JSON.stringify(N,null,2)," "))}S.length>20&&console.log(` ... and ${S.length-20} more`)}else{console.log(` found ${D.length} node${D.length===1?"":"s"} (${B}):`);for(let S of D.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)}"`:"",V=S.testID?` #${S.testID}`:"",Z=S.pressable?" (tap)":"",re=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${re}${W}${V} ${J} ${N}${Z}`),oe&&console.log(je(JSON.stringify(S,null,2)," "))}D.length>20&&console.log(` ... and ${D.length-20} more`)}else if(D==null)console.log(` not found: ${u||T||M||h||""||B}`),T&&Y("wait-selector-for-missing-testid",T);else{let S=D;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)}"`:"",V=S.testID?` #${S.testID}`:"",Z=S.pressable?" (tap)":"",re=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${re}${W}${V} ${J} ${N}${Z}`),oe&&console.log(je(JSON.stringify(S,null,2)," "))}else console.log(JSON.stringify(D,null,2))}}function je(e,l){return e.split(`
206
+ `).map(n=>l+n).join(`
207
+ `)}async function Ct(e){let{bridge:l,args:n}=e,c=A(n);await ue(l,{verbose:!c});let m=n.includes("--styling"),i=await nt(l,{styling:m});if(c){P({count:i.length,elements:i});return}console.log(` layout (${i.length} element${i.length===1?"":"s"}):
208
+ `),console.log(rt(i,{styling:m}))}async function Bt(e,l={}){let n=await bt(e);if("error"in n&&(console.error(n.error),process.exit(1)),l.json){console.log(JSON.stringify(n,null,2));return}let{visible:c,spec:m,mode:i,shifted:g,capsLock:y,accessoryBarId:T}=n,M=[];M.push(`keyboard: ${c?"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: ${i}${g?" (shifted)":""}${y?" (caps)":""}`),T&&M.push(` accessoryBar: ${T}`),console.log(M.join(`
209
+ `))}async function jt(e){let l=await e.bridge.listSims(),n=e.args.includes("--all"),c=e.args.find((y,T)=>e.args[T-1]==="--bundle"),m=e.args.find((y,T)=>e.args[T-1]==="--app-port"),i=e.args.includes("--primary"),g=l.filter(y=>!(i&&!y.isPrimary||c&&!(y.url??"").includes(c)||m&&!(y.url??"").includes(`/rn/${m}`)||!n&&!c&&!m&&!i&&!(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}It(g,e.simId),g.length<l.length&&!A(e.args)&&console.log(` (${l.length-g.length} more hidden \u2014 pass --all to show)`)}function ae(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/1024/1024).toFixed(1)}MB`}function ke(e,l){return l<=0?"?":`${(e/l*100).toFixed(0)}%`}async function Lt(e,l={args:[]}){let n=await wt(e);if(A(l.args)){P(n);return}if(console.log(" memory:"),n.imageLoader){let c=n.imageLoader;console.log(" image-loader cache"),console.log(` entries: ${c.cacheEntries} / ${c.cacheMaxEntries} (${ke(c.cacheEntries,c.cacheMaxEntries)})`),console.log(` pixel bytes: ${ae(c.cachePixelBytes)} / ${ae(c.cachePixelBudget)} (${ke(c.cachePixelBytes,c.cachePixelBudget)})`),console.log(` pending: ${c.pendingFetches} fetches, ${c.pendingBytes} bytes`),console.log(` failed uris: ${c.failedUris}`),console.log(` snapshots: ${c.snapshots}`),console.log(` live frames: ${c.liveFrames}`)}else console.log(" image-loader cache: not available (engine pre-rebuild?)");if(n.workerHeap){let c=n.workerHeap;console.log(" worker heap (chrome only)"),console.log(` used: ${ae(c.usedJSHeapSize)} / ${ae(c.jsHeapSizeLimit)} (${ke(c.usedJSHeapSize,c.jsHeapSizeLimit)})`),console.log(` total: ${ae(c.totalJSHeapSize)}`)}if(n.hostHeap){let c=n.hostHeap;console.log(" host heap (chrome only)"),console.log(` used: ${ae(c.usedJSHeapSize)} / ${ae(c.jsHeapSizeLimit)} (${ke(c.usedJSHeapSize,c.jsHeapSizeLimit)})`),console.log(` total: ${ae(c.totalJSHeapSize)}`)}}var X="<redacted secure text>";function be(e){let l=e?.layout?.spec??e?.spec??null;return!!l?.secureTextEntry&&l.keyboardType!=="visible-password"}function Le(e,l){return be(l)?X:e}function Je(e){if(!e||!be(e))return e;let l=e.focusedInput;return!l||typeof l!="object"?e:{...e,focusedInput:{...l,secureTextEntry:!0,text:typeof l.text=="string"?X:l.text}}}function he(e){let l=e.indexOf("--testid");if(l>=0&&e[l+1])return{mode:"testid",value:e[l+1]};let n=e.indexOf("--test-id");if(n>=0&&e[n+1])return{mode:"testid",value:e[n+1]};let c=e.indexOf("--text");return c>=0&&e[c+1]?{mode:"text",value:e[c+1]}:null}async function Te(e,l){let n=JSON.stringify(l.value),c=l.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
- const n = ${l}
212
+ const n = ${c}
213
213
  if (!n || !n.absolutePosition || !n.layout) return null
214
214
  const resolved =
215
215
  typeof n.nodeId === 'number' && typeof t.resolveTapTarget === 'function'
@@ -228,18 +228,18 @@ import{a as Y}from"./chunk-PBMOGVVU.js";import{a as wt,b as xt}from"./chunk-ESKW
228
228
  y: cy,
229
229
  id: n.id ?? null,
230
230
  testID: n.testID ?? null,
231
- text: ${JSON.stringify(c.mode==="text")} ? ${n} : (n.text ?? n.accessibilityLabel ?? null),
231
+ text: ${JSON.stringify(l.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 ft(e);if(c.json){console.log(JSON.stringify({shell:m??null,nav:n,keyboard:l},null,2));return}let r=[];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)}%)`:"";r.push(`shell: ${g}${y}${T}`)}else r.push("shell: <unavailable>");if(n){let g=n.transitionPhase!=="idle"?` (${n.transitionPhase}, ${n.activeTransitionCount} active)`:"";if(r.push(`nav: phase=${n.transitionPhase}${g}`),n.screens.length===0)r.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}`:"";r.push(` ${T} #${y.id}${M}${h}${k}`)}}else r.push("nav: <runtime not available>");if(l&&l.visible){let g=l.spec?.keyboardType??"default",y=l.spec?.returnKeyType??"default";r.push(`keyboard: visible (${g}, return=${y}, mode=${l.mode??"?"})`)}else r.push("keyboard: hidden");console.log(r.join(`
235
- `))}async function Bt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1])*1e3:3e3,r=n.includes("--strict"),{elapsed:g,settled:y}=await ee({bridge:c,maxMs:m,strict:r});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 Jt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1]):5,{tree:r}=await Ve(c,m);if(A(n)){P({depth:m,tree:r??null});return}console.log(typeof r=="string"?r:JSON.stringify(r,null,2))}async function Lt(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:r}=e,g=r[1]?Number(r[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 r of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let g=n[r];typeof g=="string"&&g.length>0&&l.push(g)}let m=l.join(" ");return c.equals?l.some(r=>r===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,r=l[1];r||(console.error(m("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),qt.has(r)||console.error(` warning: '${r}' 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:[r],since:h==="cursor"?void 0:j,limit:50},B=await c.send({type:"evaluate",code:`(async () => {
234
+ })()`})??null}async function Jt(e,l={}){let{nav:n,keyboard:c,shell:m}=await ht(e);if(l.json){console.log(JSON.stringify({shell:m??null,nav:n,keyboard:c},null,2));return}let i=[];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)}%)`:"";i.push(`shell: ${g}${y}${T}`)}else i.push("shell: <unavailable>");if(n){let g=n.transitionPhase!=="idle"?` (${n.transitionPhase}, ${n.activeTransitionCount} active)`:"";if(i.push(`nav: phase=${n.transitionPhase}${g}`),n.screens.length===0)i.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}`:"";i.push(` ${T} #${y.id}${M}${h}${k}`)}}else i.push("nav: <runtime not available>");if(c&&c.visible){let g=c.spec?.keyboardType??"default",y=c.spec?.returnKeyType??"default";i.push(`keyboard: visible (${g}, return=${y}, mode=${c.mode??"?"})`)}else i.push("keyboard: hidden");console.log(i.join(`
235
+ `))}async function Wt(e){let{bridge:l,args:n,positional:c}=e,m=c[1]?Number(c[1])*1e3:3e3,i=n.includes("--strict"),{elapsed:g,settled:y}=await te({bridge:l,maxMs:m,strict:i});console.log(y?` settled in ${g}ms`:` timed out after ${g}ms (may still be animating)`)}async function qt(e){let l=e.positional[1]?Number(e.positional[1]):.5;(!Number.isFinite(l)||l<0)&&(console.error(e.inspectUsage("sleep","[seconds]")),process.exit(1)),await ee(l*1e3),console.log(` slept ${l}s`)}async function Ht(e){let{bridge:l,args:n,positional:c}=e,m=c[1]?Number(c[1]):5,{tree:i}=await tt(l,m);if(A(n)){P({depth:m,tree:i??null});return}console.log(typeof i=="string"?i:JSON.stringify(i,null,2))}async function Kt(e,l={args:[]}){let n=await ot(e);if(A(l.args)){P(n);return}console.log(n.url)}async function Ut(e){let{wsPort:l,commandTimeoutMs:n,simId:c,simIdSource:m,positional:i}=e,g=i[1]?Number(i[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 xt(l,n,c,{attempts:T,simIdSource:m});M||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),M.bridge.close(),ve({source:"inspect wait",step:{wait:y},summary:`wait ${Math.round(y/1e3)}s`}),console.log(` ready: ${M.count} nodes`)}var zt=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function Me(e,l){let n=e.indexOf(l);if(n>=0&&n+1<e.length)return e[n+1]}function Eo(e,l){if(!l.filter&&!l.equals)return!0;let n=e.data,c=[];if(n&&typeof n=="object")for(let i of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let g=n[i];typeof g=="string"&&g.length>0&&c.push(g)}let m=c.join(" ");return l.equals?c.some(i=>i===l.equals):l.filter?m.toLowerCase().includes(l.filter.toLowerCase()):!0}async function Gt(e){let{bridge:l,args:n,positional:c,inspectUsage:m}=e,i=c[1];i||(console.error(m("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),zt.has(i)||console.error(` warning: '${i}' is not a known timeline kind \u2014 waiting anyway. known: ${[...zt].sort().join(", ")}`);let g=Me(n,"--max-ms"),y=g&&Number.isFinite(Number(g))?Math.max(100,Number(g)):5e3,T=Me(n,"--filter"),M=Me(n,"--equals"),h=Me(n,"--since")??"now",k=n.includes("--json"),_=Date.now(),I=_+y,E=200,j=_;for(;Date.now()<I;){let z={kinds:[i],since:h==="cursor"?void 0:j,limit:50},B=await l.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 D=B.result.events??[];for(let V of D)if(_o(V,{filter:T,equals:M})){let te=Date.now()-_;console.log(k?JSON.stringify({found:!0,elapsedMs:te,event:V}):` ${r} 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:r,filter:T,equals:M})):console.error(` \u26A0 wait event ${r} 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:r,settled:g}=await ee({bridge:c,maxMs:m,strict:l});g?console.log(` idle in ${r}ms`):(console.error(` \u26A0 wait idle timed out after ${r}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:r,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-r,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 ${r+d.elapsed}ms \u2014 app mounted but did not settle (nodes: ${g}, targets: ${y})`),process.exit(1)),console.log(` ready in ${r+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 ${r}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,r=l[1];r||(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,r,y,{gone:T});if(T){M?console.log(` #${r} gone after ${k}ms`):(console.error(` \u26A0 wait selector #${r} --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 #${r} in ${k}ms ${I} ${_}`)}else console.error(` \u26A0 wait selector #${r} 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 Gt(){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 D=B.result.events??[];for(let Q of D)if(Eo(Q,{filter:T,equals:M})){let oe=Date.now()-_;console.log(k?JSON.stringify({found:!0,elapsedMs:oe,event:Q}):` ${i} event after ${oe}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`);return}B.result.watermark&&B.result.watermark>j&&(j=B.result.watermark),await new Promise(Q=>setTimeout(Q,E))}let u=Date.now()-_;k?console.log(JSON.stringify({found:!1,elapsedMs:u,kind:i,filter:T,equals:M})):console.error(` \u26A0 wait event ${i} timed out after ${u}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`),process.exit(1)}async function Yt(e){let{bridge:l,args:n}=e,c=n.includes("--strict"),m=xe(n,3e3),{elapsed:i,settled:g}=await te({bridge:l,maxMs:m,strict:c});g?console.log(` idle in ${i}ms`):(console.error(` \u26A0 wait idle timed out after ${i}ms (may still be animating)`),process.exit(1))}async function Xt(e){let{bridge:l,args:n}=e,c=xe(n,2e4),{ready:m,elapsedMs:i,nodes:g,targets:y,flag:T,loadingText:M,externalReady:h,externalError:k,errors:_}=await lt(l,c,{onProgress(E){console.error(` still waiting after ${E.elapsedMs}ms \u2014 ${Ee(E)} (nodes: ${E.nodes}, targets: ${E.targets}, errors: ${E.errors})`)}});if(m){let E=c-i,j=Math.max(100,Math.min(1e4,E)),u=await te({bridge:l,maxMs:j,pollMs:32,stablePolls:2});u.settled||(console.error(` \u26A0 wait ready timed out after ${i+u.elapsed}ms \u2014 app mounted but did not settle (nodes: ${g}, targets: ${y})`),process.exit(1)),console.log(` ready in ${i+u.elapsed}ms: ${g} nodes, ${y} targets`);return}let I=Ee({externalError:k,loadingText:M,externalReady:h,flag:T,targets:y});console.error(` \u26A0 wait ready timed out after ${i}ms \u2014 ${I} (nodes: ${g}, targets: ${y}, errors: ${_})`),process.exit(1)}async function Vt(e){let{bridge:l,args:n,positional:c,inspectUsage:m}=e,i=c[1];i||(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 ct(l,i,y,{gone:T});if(T){M?console.log(` #${i} gone after ${k}ms`):(console.error(` \u26A0 wait selector #${i} --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 #${i} in ${k}ms ${I} ${_}`)}else console.error(` \u26A0 wait selector #${i} timed out after ${k??y}ms`),process.exit(1)}function ro(e){return e==null?"\u2014":e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}K`:`${(e/1024/1024).toFixed(1)}M`}function io(e){return e==null?" \u2026":e<1e3?`${e}ms`.padStart(5):`${(e/1e3).toFixed(2)}s`.padStart(5)}function Qt(){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 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 () => {
242
+ `)}async function Do(e){try{return await e.send({type:"evaluate",code:"1"},{timeoutMs:3e3}),!0}catch{return!1}}async function Co(e,l){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,11 +258,14 @@ import{a as Y}from"./chunk-PBMOGVVU.js";import{a as wt,b as xt}from"./chunk-ESKW
258
258
  } catch {
259
259
  return []
260
260
  }
261
- })()`});if(!Array.isArray(n)||n.length===0)return;let l=c.toLowerCase(),m=n.map(r=>({id:r,score:Ro(l,r.toLowerCase())})).filter(r=>r.score<l.length+4).sort((r,g)=>r.score-g.score).slice(0,5);if(m.length===0)return;console.error(" similar testIDs:");for(let r of m)console.error(` ${r.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 r=n;n=l,l=r}return n[c.length]}function Do(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=Do(e).padEnd(3),l=e.method.padEnd(5),m=to(e.size).padStart(6),r=oo(e.durationMs);console.log(` [${c}] ${n} ${l} ${m} ${r} ${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",Jo="\x1B[2m";function Vt(e,c){let n=re(e.ts),l=e.level.toUpperCase().padEnd(5),m=e.args.join(" ");if(c){let r=jo[e.level];console.log(` ${Jo}[${n}]${Xt} ${r}${l}${Xt} ${m}`)}else console.log(` [${n}] ${l} ${m}`);if(e.stack&&e.level==="error"){let r=e.stack.split(`
262
- `).slice(0,5);for(let g of r)console.log(` ${g.trim()}`)}}var se="__sootsimCliPerf",Lo=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 r=_=>{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=r("--x"),y=r("--y"),T=r("--w"),M=r("--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 Je(e){return e.send({type:"evaluate",code:`(async () => {
261
+ })()`});if(!Array.isArray(n)||n.length===0)return;let c=l.toLowerCase(),m=n.map(i=>({id:i,score:Bo(c,i.toLowerCase())})).filter(i=>i.score<c.length+4).sort((i,g)=>i.score-g.score).slice(0,5);if(m.length===0)return;console.error(" similar testIDs:");for(let i of m)console.error(` ${i.id}`)}catch{}}function Bo(e,l){if(l===e)return 0;if(l.includes(e))return 1;if(e.includes(l))return 2;let n=0;for(;n<e.length&&n<l.length&&e[n]===l[n];)n+=1;return jo(e,l)-n}function jo(e,l){if(e===l)return 0;if(!e.length)return l.length;if(!l.length)return e.length;let n=new Array(l.length+1),c=new Array(l.length+1);for(let m=0;m<=l.length;m++)n[m]=m;for(let m=1;m<=e.length;m++){c[0]=m;for(let g=1;g<=l.length;g++)c[g]=Math.min(n[g]+1,c[g-1]+1,n[g-1]+(e[m-1]===l[g-1]?0:1));let i=n;n=c,c=i}return n[l.length]}function Lo(e){return e.error?"err":e.status==null?" \u2026 ":String(e.status)}function Jo(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 Zt(e){let l=ie(e.startTs),n=Lo(e).padEnd(3),c=e.method.padEnd(5),m=ro(e.size).padStart(6),i=io(e.durationMs);console.log(` [${l}] ${n} ${c} ${m} ${i} ${e.displayUrl}`),e.error&&console.log(` error: ${e.error}`)}function Wo(e){let l=[["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",ie(e.startTs)],["duration",io(e.durationMs).trim()],["size",ro(e.size)],["content-type",e.type??"\u2014"]];for(let[n,c]of l)console.log(` ${n.padEnd(13)} ${c}`)}var qo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},eo="\x1B[0m",Ho="\x1B[2m";function to(e,l){let n=ie(e.ts),c=e.level.toUpperCase().padEnd(5),m=e.args.join(" ");if(l){let i=qo[e.level];console.log(` ${Ho}[${n}]${eo} ${i}${c}${eo} ${m}`)}else console.log(` [${n}] ${c} ${m}`);if(e.stack&&e.level==="error"){let i=e.stack.split(`
262
+ `).slice(0,5);for(let g of i)console.log(` ${g.trim()}`)}}var ne="__sootsimCliPerf",Ko=120;async function oo(e,l){let n=e.find((_,I)=>e[I-1]==="--id"),c=e.find((_,I)=>e[I-1]==="--text");if(n||c){let _=await l.send({type:"evaluate",code:vt({id:n,text:c})});if(!_)throw new Error(n?`no node with id "${n}"`:`no node matching text "${c}"`);let{x:I,y:E,w:j,h:u}=_;return{x:I,y:E,w:j,h:u}}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,E,j,u]=_;return{x:I,y:E,w:j,h:u}}let i=_=>{let I=e.find((j,u)=>e[u-1]===_);if(I==null)return null;let E=Number(I);return Number.isFinite(E)?E:null},g=i("--x"),y=i("--y"),T=i("--w"),M=i("--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,E=1,j=1]=k;return{x:_,y:I,w:E,h:j}}return null}function We(e){let l={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let n of e)n<8?l["<8"]++:n<12?l["8-12"]++:n<16?l["12-16"]++:n<20?l["16-20"]++:n<33?l["20-33"]++:l[">33"]++;console.log(" histogram:");for(let[n,c]of Object.entries(l)){let m="\u2588".repeat(Math.ceil(c/e.length*40));console.log(` ${n.padEnd(6)} ${m} ${c}`)}}async function Ie(e,l,n){let c=Date.now()+l,m=await ce(e,l);for(;;){if(n(m))return{settled:!0,state:m};if(Date.now()>=c)return{settled:!1,state:m};await ee(16),m=await ce(e)}}async function He(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' }
266
+ const layout = typeof kb.getLayout === 'function' ? kb.getLayout() : null
267
+ const secureTextEntry =
268
+ !!layout?.spec?.secureTextEntry && layout?.spec?.keyboardType !== 'visible-password'
266
269
  const visible = kb.isVisible()
267
270
  const mode = kb.getMode()
268
271
  let focused = null
@@ -280,18 +283,20 @@ import{a as Y}from"./chunk-PBMOGVVU.js";import{a as wt,b as xt}from"./chunk-ESKW
280
283
  return {
281
284
  visible,
282
285
  mode,
286
+ layout,
283
287
  focusedInput: focused ? {
284
288
  nodeId: focused.nodeId ?? null,
285
289
  testID: focused.testID || null,
286
290
  id: focused.id || null,
287
291
  placeholder: focused.placeholder || null,
288
- text: focused.text || null,
292
+ secureTextEntry,
293
+ text: secureTextEntry ? ${JSON.stringify(X)} : (focused.text || null),
289
294
  } : null,
290
295
  phase: runtimeSnapshot?.keyboard?.phase ?? null,
291
296
  frame: runtimeSnapshot?.keyboard?.frame ?? null,
292
297
  focusedRect: runtimeSnapshot?.focused?.rect ?? null,
293
298
  }
294
- })()`})}async function Wo(e,c=600){let n=Date.now()+c;for(;Date.now()<=n;){let l=await Je(e);if(l.visible)return l;await Z(30)}return Je(e)}async function Me(e,c){let n=await Je(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 () => {
299
+ })()`}).then(l=>Je(l))}function Uo(e,l,n){if(!e.visible)return!1;let c=e.focusedInput;return!(l&&c&&!(c.testID===l||c.id===l)||n!==null&&be(e)!==n)}async function zo(e,l=600,n={}){let c=Date.now()+l;for(;Date.now()<=c;){let m=await He(e);if(Uo(m,n.targetId??null,n.secureTextEntry??null))return m;await ee(30)}return He(e)}async function Ne(e,l){let n=await He(e);if(n.visible)return n;console.error(` ${l} 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 so(e,l,n){return l==="appearance"?e.send({type:"evaluate",code:`(async () => {
295
300
  const requested = ${JSON.stringify(n??"toggle")}
296
301
  const rootBg = (document.documentElement?.style?.background || '').toLowerCase()
297
302
  const inferredCurrent = rootBg.includes('33') ? 'dark' : 'light'
@@ -306,27 +311,27 @@ import{a as Y}from"./chunk-PBMOGVVU.js";import{a as wt,b as xt}from"./chunk-ESKW
306
311
  : next
307
312
  return { ok: true, requested, value: next, applied }
308
313
  })()`}):e.send({type:"evaluate",code:`(async () => {
309
- window.dispatchEvent(new CustomEvent(${JSON.stringify(c==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
310
- return { ok: true, action: ${JSON.stringify(c)} }
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 J(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"]}),r=m.positional,g=r[0],y=n==="get"||n==="do"||n==="debug"||n==="wait"?n:"inspect",T=typeof l[0]=="string"&&Le.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 i=Ie(y,o);i&&(console.log(`${i}
312
- `),process.exit(0))}if(M==="shell"){let i=Ne("shell",o);i&&(console.log(`${i}
313
- `),process.exit(0))}let t=Ne("inspect",o),s=["do","get","debug","wait"].map(i=>Ie(i,o)).filter(i=>i!=null).join(`
314
+ window.dispatchEvent(new CustomEvent(${JSON.stringify(l==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
315
+ return { ok: true, action: ${JSON.stringify(l)} }
316
+ })()`})}function Go(e){let l={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(l[e])return l[e];let n=e.match(/^Digit([0-9])$/);if(n)return n[1];let c=e.match(/^Key([A-Z])$/);return c?c[1].toLowerCase():null}function Yo(e){if(typeof e!="string")return null;let l=e.replace(/\s+/g," ").trim();return l?l.slice(0,80):null}function ao(...e){for(let l of e){if(typeof l!="string")continue;let n=l.trim();if(n)return n}return null}function Xo(e){let l=e.indexOf("--node-id");if(l<0)return null;let n=e[l+1];if(!n)return null;let c=Number(n);return Number.isInteger(c)&&c>0?c:null}async function L(e,l,n){let c=ve({source:e,step:l,summary:n});c.active&&(c.replaced?console.error(` draft: replaced unkept action "${c.replaced.summary}" \u2014 \`flow keep\` commits one action at a time`):console.error(" draft: action pending \u2014 `sootsim flow keep` to commit"))}function no(e,l,n){if(!n||n.hit===!1)return null;let c=ao(n.responderTestID,n.testID);if(c)return{step:{tapOn:{id:c}},summary:`tap #${c}`};let m=Yo(n.text);return m?{step:{tapOn:m},summary:`tap "${m}"`}:{step:{tapAtCoords:{x:e,y:l}},summary:`tap @${Math.round(e)},${Math.round(l)}`}}function qe(e,l,n){let c=ao(l?.testID,l?.id);return c?{step:{tapOn:{id:c}},summary:`tap #${c}`}:n==="id"?{step:{tapOn:{id:e}},summary:`tap #${e}`}:{step:{tapOn:e},summary:`tap "${e}"`}}async function Jn(e,l){let n=e[0]==="get"||e[0]==="do"||e[0]==="debug"||e[0]==="wait"?e[0]:null,c=n?e.slice(1):e,m=Ge(c,{port:l.port,commandTimeoutMs:l.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"]}),i=m.positional,g=i[0],y=n==="get"||n==="do"||n==="debug"||n==="wait"?n:"inspect",T=typeof c[0]=="string"&&Ke.has(c[0]),M=T?c[0]:null,h=o=>T&&o===c[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:Ue};if(y==="do"||y==="get"||y==="debug"||y==="wait"){let r=Fe(y,o);r&&(console.log(`${r}
317
+ `),process.exit(0))}if(M==="shell"){let r=_e("shell",o);r&&(console.log(`${r}
318
+ `),process.exit(0))}let t=_e("inspect",o),s=["do","get","debug","wait"].map(r=>Fe(r,o)).filter(r=>r!=null).join(`
314
319
 
315
320
  `);console.log(`${t??""}
316
321
 
317
322
  ${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-SI4Q6422.js"),t=o();console.log(` available drivers (${t.length}):
319
- `);let s=Math.max(...t.map(a=>a.id.length),6),i=Math.max(...t.map(a=>a.kind.length),4);for(let a of t){let u=a.available?"\u2713":"\u2717",p=a.id.padEnd(s),b=a.kind.padEnd(i);console.log(` ${u} ${p} ${b} ${a.description}`),a.available&&a.detail?console.log(` ${a.detail}`):!a.available&&a.reason&&console.log(` unavailable: ${a.reason}`)}return}let d=Ue(m),z=I||"default",B=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),D=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 i=/<title[^>]*>([^<]+)<\/title>/i.exec(o)?.[1]?.trim(),a=/<body[^>]*>([\s\S]*?)<\//i.exec(o)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=i||a||"html error page";return`<html ${o.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return t.length<=D?t:`${t.slice(0,D)}\u2026 (+${t.length-D} 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:i}=await ee({bridge:o,maxMs:t,pollMs:32,stablePolls:2});s||process.stderr.write(` \u26A0 auto-wait timed out after ${i??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: ${xe},
323
+ `),process.exit(0)}let _=m.wsPort,I=m.simId,E=m.simIdSource,j=m.commandTimeoutMs;if(g==="list"&&c.some(o=>o==="--drivers"||o==="-D")){let{buildDriverListRows:o}=await import("./drivers-MBE4KVMK.js"),t=o();console.log(` available drivers (${t.length}):
324
+ `);let s=Math.max(...t.map(a=>a.id.length),6),r=Math.max(...t.map(a=>a.kind.length),4);for(let a of t){let d=a.available?"\u2713":"\u2717",p=a.id.padEnd(s),b=a.kind.padEnd(r);console.log(` ${d} ${p} ${b} ${a.description}`),a.available&&a.detail?console.log(` ${a.detail}`):!a.available&&a.reason&&console.log(` unavailable: ${a.reason}`)}return}let u=Ye(m),z=I||"default",B=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),D=200;function Q(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(),a=/<body[^>]*>([\s\S]*?)<\//i.exec(o)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),d=r||a||"html error page";return`<html ${o.length}B> "${d}" (body elided \u2014 add --json for the full payload)`}return t.length<=D?t:`${t.slice(0,D)}\u2026 (+${t.length-D} more bytes)`}function oe(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=me()?5e3:1500;try{let{settled:s,elapsed:r}=await te({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.
325
+ `)}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 u.send({type:"evaluate",code:`(() => ({
326
+ console: ${Se},
322
327
  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 G(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
- network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${h("requests")} 5`),!o.includeTail))return;let i=await G(d,"getFailedRequests",5);if(!(!Array.isArray(i)||i.length===0)){console.log(`
328
+ }))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function W(o={}){let t=o.counts!==void 0?o.counts:await G(u,"getRequestCounts");if(!t||typeof t!="object")return;let s=Math.max(0,Number(t.failed)||0);if(s===0||!o.includeTail&&!Ce("requests",z,String(s))||(console.log(`
329
+ network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${h("requests")} 5`),!o.includeTail))return;let r=await G(u,"getFailedRequests",5);if(!(!Array.isArray(r)||r.length===0)){console.log(`
325
330
  recent failed requests:
326
- `);for(let a of i){let u=re(a.timestamp);console.log(` [${u}] ${te(a)}`),a.responseBody?console.log(` ${V(a.responseBody)}`):a.error&&console.log(` ${a.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,i=Math.max(0,Number(s.errors)||0),a=Math.max(0,Number(s.warnings)||0);if(i===0&&a===0||!o.includeTail&&!Ee("console",z,`${i}:${a}`))return;let u=[];if(i>0&&u.push(`${i} console error${i===1?"":"s"}`),a>0&&u.push(`${a} console warning${a===1?"":"s"}`),console.log(`
327
- console: ${u.join(", ")}`),console.log(` inspect: ${h("errors")} 5`),a>0&&console.log(` inspect: ${h("warnings")} 5`),!o.includeTail||i===0)return;let p=await we(d,5);if(!(!Array.isArray(p)||p.length===0)){console.log(`
331
+ `);for(let a of r){let d=ie(a.timestamp);console.log(` [${d}] ${oe(a)}`),a.responseBody?console.log(` ${Q(a.responseBody)}`):a.error&&console.log(` ${a.error}`)}}}async function V(o={}){let t=o.counts!==void 0?o.counts:await u.send({type:"evaluate",code:Se});if(!t||typeof t!="object")return;let s=t,r=Math.max(0,Number(s.errors)||0),a=Math.max(0,Number(s.warnings)||0);if(r===0&&a===0||!o.includeTail&&!Ce("console",z,`${r}:${a}`))return;let d=[];if(r>0&&d.push(`${r} console error${r===1?"":"s"}`),a>0&&d.push(`${a} console warning${a===1?"":"s"}`),console.log(`
332
+ console: ${d.join(", ")}`),console.log(` inspect: ${h("errors")} 5`),a>0&&console.log(` inspect: ${h("warnings")} 5`),!o.includeTail||r===0)return;let p=await $e(u,5);if(!(!Array.isArray(p)||p.length===0)){console.log(`
328
333
  recent console errors:
329
- `);for(let b of p){let f=re(b.timestamp),x=Array.isArray(b.args)?b.args.map(O=>typeof O=="object"?JSON.stringify(O):String(O)).join(" "):String(b);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,`(() => {
334
+ `);for(let b of p){let f=ie(b.timestamp),w=Array.isArray(b.args)?b.args.map(O=>typeof O=="object"?JSON.stringify(O):String(O)).join(" "):String(b);console.log(` [${f}] ${w}`)}}}let Z=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function re(o){let t=ze(),s=null;try{s=await Ve(o,`(() => {
330
335
  const tl = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.timeline
331
336
  if (!tl || typeof tl.summary !== 'function') return null
332
337
  const cursorKey = ${JSON.stringify(t)}
@@ -342,9 +347,9 @@ ${s}
342
347
  }
343
348
  }
344
349
  return summary ? { summary, consoleSplit } : null
345
- })()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let i=s.summary.byKind??{},a=[],u=new Set;for(let p of Q){let b=i[p];if(b)if(u.add(p),p==="console"&&s.consoleSplit){let{error:f,warn:x}=s.consoleSplit;f>0&&a.push(`${f} error${f===1?"":"s"}`),x>0&&a.push(`${x} warning${x===1?"":"s"}`)}else a.push(`${b} ${p}${b===1?"":"s"}`)}for(let[p,b]of Object.entries(i))!u.has(p)&&b&&a.push(`${b} ${p}${b===1?"":"s"}`);if(a.length!==0&&(console.log(`
346
- since last: ${a.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"]),C=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),C.has(g)&&await ce(d,{verbose:ae});try{switch(g){case"list":{await Et({bridge:d,simId:I,args:l});break}case"tree":{await Jt({bridge:d,args:l,positional:r});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 i=t.label.length>50?t.label.slice(0,47)+"...":t.label;s.push(`"${i}"`)}if(t.hint&&s.push(`(hint: "${t.hint}")`),t.testID&&s.push(`#${t.testID}`),t.state){let i=[];t.state.disabled&&i.push("disabled"),t.state.selected&&i.push("selected"),t.state.checked===!0&&i.push("checked"),t.state.checked==="mixed"&&i.push("mixed"),t.state.busy&&i.push("busy"),t.state.expanded===!0&&i.push("expanded"),t.state.expanded===!1&&i.push("collapsed"),i.length&&s.push(`{${i.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:r,inspectUsage:k});break}case"count":{await _t(d,{args:l});break}case"keyboard":{await Rt(d,{json:e.includes("--json")});break}case"screens":{await Ct(d,{json:e.includes("--json")});break}case"memory":{await Dt(d,{args:l});break}case"wait":{await Wt({wsPort:_,commandTimeoutMs:j,simId:I,simIdSource:R,positional:r});break}case"sleep":{await jt({positional:r,inspectUsage:k});break}case"settle":{await Bt({bridge:d,args:e,positional:r});break}case"ready":{await Kt({bridge:d,args:e});break}case"idle":{await Ut({bridge:d,args:e,positional:r});break}case"selector":{await zt({bridge:d,args:e,positional:r,inspectUsage:k});break}case"event":{await Ht({bridge:d,args:e,positional:r,inspectUsage:k});break}case"layout":{let o=r[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((b,f)=>e[f-1]==="--output")||"/tmp/sootsim-inspect.png",s=await Qt(e,d),i={type:"screenshot"};s&&(i.crop=s);let u=(await d.send(i)).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:i,b:a,a:u,hex:p,samples:b}=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}, ${i}, ${a}, ${u}) ${f} ${b} samples`)}break}case"node":{let o=r[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 () => {
350
+ })()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let r=s.summary.byKind??{},a=[],d=new Set;for(let p of Z){let b=r[p];if(b)if(d.add(p),p==="console"&&s.consoleSplit){let{error:f,warn:w}=s.consoleSplit;f>0&&a.push(`${f} error${f===1?"":"s"}`),w>0&&a.push(`${w} warning${w===1?"":"s"}`)}else a.push(`${b} ${p}${b===1?"":"s"}`)}for(let[p,b]of Object.entries(r))!d.has(p)&&b&&a.push(`${b} ${p}${b===1?"":"s"}`);if(a.length!==0&&(console.log(`
351
+ since last: ${a.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await Oe(o,"SootSim.bridges.timeline.cursorAdvance",t,s.summary.lastAt)}catch{}}let pe=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"]),C=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"]),le=(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)),pe.has(g)&&await Xe(u),C.has(g)&&await ue(u,{verbose:le});try{switch(g){case"list":{await jt({bridge:u,simId:I,args:c});break}case"tree":{await Ht({bridge:u,args:c,positional:i});break}case"a11y":{let o=await it(u);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):
352
+ `);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 Dt({bridge:u,args:e,effectiveArgs:c,positional:i,inspectUsage:k});break}case"count":{await Et(u,{args:c});break}case"keyboard":{await Bt(u,{json:e.includes("--json")});break}case"screens":{await Jt(u,{json:e.includes("--json")});break}case"memory":{await Lt(u,{args:c});break}case"wait":{await Ut({wsPort:_,commandTimeoutMs:j,simId:I,simIdSource:E,positional:i});break}case"sleep":{await qt({positional:i,inspectUsage:k});break}case"settle":{await Wt({bridge:u,args:e,positional:i});break}case"ready":{await Xt({bridge:u,args:e});break}case"idle":{await Yt({bridge:u,args:e,positional:i});break}case"selector":{await Vt({bridge:u,args:e,positional:i,inspectUsage:k});break}case"event":{await Gt({bridge:u,args:e,positional:i,inspectUsage:k});break}case"layout":{let o=i[1];if(!o){await Ct({bridge:u,args:c});break}let t=await u.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((b,f)=>e[f-1]==="--output")||"/tmp/sootsim-inspect.png",s=await oo(e,u),r={type:"screenshot"};s&&(r.crop=s);let d=(await u.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(d,"base64")),console.log(` saved: ${t}`);break}case"sample-color":{let o=await oo(e,u);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 u.send({type:"evaluate",code:kt(o)});if(e.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:r,b:a,a:d,hex:p,samples:b}=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}, ${a}, ${d}) ${f} ${b} samples`)}break}case"node":{let o=i[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 u.send({type:"evaluate",code:`(async () => {
348
353
  const t = window.__sootsimTest
349
354
  const q = ${JSON.stringify(o)}
350
355
  let node = null
@@ -400,17 +405,17 @@ ${s}
400
405
  transform,
401
406
  parentChain,
402
407
  }
403
- })()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let o=Number(r[1]),t=Number(r[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"&&Y("wait-selector-for-missing-testid",s.value),process.exit(1)),de(u.result)||(N(`${s.mode} "${s.value}"`,u),process.exit(1));let b=eo(p.cx,p.cy,u.result);b&&await J("inspect tap",b.step,b.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 i=await Mt(d,o,t),a=eo(o,t,i);a&&await J("inspect tap",a.step,a.summary),console.log(JSON.stringify(i,null,2));break}case"drag":case"swipe":{let o=Number(r[1]),t=Number(r[2]),s=Number(r[3]),i=Number(r[4]),a=g==="swipe"?10:12,u=g==="swipe"?8:16,p=r[5]?Number(r[5]):a,b=r[6]?Number(r[6]):u;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(i)||!Number.isFinite(p)||!Number.isFinite(b))&&(console.error(k(g,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await d.send({type:"evaluate",code:`(async () => {
408
+ })()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let o=Number(i[1]),t=Number(i[2]),s=he(e);if(s){let d=await ye(u,{agent:me(),textFallback:s.mode==="text"?s.value:void 0,resolve:async()=>{let f=await Te(u,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=d.payload;(!p||typeof p.cx!="number")&&(console.error(` not found: ${s.value}`),s.mode==="testid"&&Y("wait-selector-for-missing-testid",s.value),process.exit(1)),de(d.result)||(N(`${s.mode} "${s.value}"`,d),process.exit(1));let b=no(p.cx,p.cy,d.result);b&&await L("inspect tap",b.step,b.summary),console.log(JSON.stringify({...d.attempts>1?{attempts:d.attempts}:{},...d.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 _t(u,o,t),a=no(o,t,r);a&&await L("inspect tap",a.step,a.summary),console.log(JSON.stringify(r,null,2));break}case"drag":case"swipe":{let o=Number(i[1]),t=Number(i[2]),s=Number(i[3]),r=Number(i[4]),a=g==="swipe"?10:12,d=g==="swipe"?8:16,p=i[5]?Number(i[5]):a,b=i[6]?Number(i[6]):d;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(p)||!Number.isFinite(b))&&(console.error(k(g,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await u.send({type:"evaluate",code:`(async () => {
404
409
  const interact = window.__sootsimInteract
405
410
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
406
- const value = await interact.drag(${o}, ${t}, ${s}, ${i}, ${Math.max(1,Math.round(p))}, ${Math.max(0,Math.round(b))})
411
+ const value = await interact.drag(${o}, ${t}, ${s}, ${r}, ${Math.max(1,Math.round(p))}, ${Math.max(0,Math.round(b))})
407
412
  return { ok: !!value, value }
408
- })()`});if(f?.ok){let x=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,b)));await J(`inspect ${g}`,{swipe:{start:`${o}, ${t}`,end:`${s}, ${i}`,duration:x}},`${g} ${o},${t} -> ${s},${i}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let o=Number(r[1]),t=Number(r[2]),s=Number(r[3]),i=Number(r[4]),a=Number(r[5]),u=Number(r[6]),p=Number(r[7]),b=Number(r[8]),f=r[9]?Number(r[9]):12,x=r[10]?Number(r[10]):16;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(i)||!Number.isFinite(a)||!Number.isFinite(u)||!Number.isFinite(p)||!Number.isFinite(b)||!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 () => {
413
+ })()`});if(f?.ok){let w=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,b)));await L(`inspect ${g}`,{swipe:{start:`${o}, ${t}`,end:`${s}, ${r}`,duration:w}},`${g} ${o},${t} -> ${s},${r}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let o=Number(i[1]),t=Number(i[2]),s=Number(i[3]),r=Number(i[4]),a=Number(i[5]),d=Number(i[6]),p=Number(i[7]),b=Number(i[8]),f=i[9]?Number(i[9]):12,w=i[10]?Number(i[10]):16;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(a)||!Number.isFinite(d)||!Number.isFinite(p)||!Number.isFinite(b)||!Number.isFinite(f)||!Number.isFinite(w))&&(console.error(k("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let O=await u.send({type:"evaluate",code:`(async () => {
409
414
  const interact = window.__sootsimInteract
410
415
  if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
411
- const value = await interact.pinch(${o}, ${t}, ${s}, ${i}, ${a}, ${u}, ${p}, ${b}, ${Math.max(1,Math.round(f))}, ${Math.max(0,Math.round(x))})
416
+ const value = await interact.pinch(${o}, ${t}, ${s}, ${r}, ${a}, ${d}, ${p}, ${b}, ${Math.max(1,Math.round(f))}, ${Math.max(0,Math.round(w))})
412
417
  return { ok: !!value, value }
413
- })()`});O?.ok&&await J("inspect pinch",{pinch:{from:[o,t,s,i],to:[a,u,p,b],steps:Math.max(1,Math.round(f)),stepMs:Math.max(0,Math.round(x))}},`pinch (${o},${t}) (${s},${i}) -> (${a},${u}) (${p},${b})`),console.log(JSON.stringify(O,null,2));break}case"tap-text":{let o=r[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),i=t("--nth")??t("--index"),a=i!==null?Number(i):null;a!==null&&!Number.isFinite(a)&&(console.error(` --nth/--index requires an integer, got: ${i}`),process.exit(1));let u=t("--within"),p=t("--role"),b=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 w={exact:b,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:a,first:f},$=await Nt(d,o,w,{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 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||a!==null?{nth:{index:v.idx,total:v.total}}:{},...$.attempts>1?{attempts:$.attempts}:{},result:$.result},null,2));break}case"tap-best":{let o=r[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 i=s.node;de(t.result)||(N(`best "${o}"`,t),process.exit(1));let a=je(o,{id:i.id,testID:i.testID,type:i.type,cx:s.cx,cy:s.cy},s.strategy==="testid"?"id":"text");await J("inspect tap-best",a.step,a.summary),console.log(JSON.stringify({matched:{strategy:s.strategy,nodeId:i.nodeId,id:i.id,testID:i.testID,type:i.type,text:i.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=r[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 i=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 J("inspect tap-id",i.step,i.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=r[1],t=r.slice(2).join(" ");(!o||!t)&&(console.error(k("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(o),i=await d.send({type:"evaluate",code:`(async () => {
418
+ })()`});O?.ok&&await L("inspect pinch",{pinch:{from:[o,t,s,r],to:[a,d,p,b],steps:Math.max(1,Math.round(f)),stepMs:Math.max(0,Math.round(w))}},`pinch (${o},${t}) (${s},${r}) -> (${a},${d}) (${p},${b})`),console.log(JSON.stringify(O,null,2));break}case"tap-text":{let o=i[1];o||(console.error(k("tap-text","<text>")),process.exit(1));let t=U=>{let R=e.indexOf(U);return R>=0&&R+1<e.length?e[R+1]:null},s=U=>e.includes(U),r=t("--nth")??t("--index"),a=r!==null?Number(r):null;a!==null&&!Number.isFinite(a)&&(console.error(` --nth/--index requires an integer, got: ${r}`),process.exit(1));let d=t("--within"),p=t("--role"),b=s("--exact"),f=s("--first"),w=t("--min-y"),O=t("--max-y"),q=t("--min-x"),H=t("--max-x");for(let[U,R]of[["--min-y",w],["--max-y",O],["--min-x",q],["--max-x",H]])R!==null&&!Number.isFinite(Number(R))&&(console.error(` ${U} requires a number, got: ${R}`),process.exit(1));let K=e.indexOf("--near"),F=null;if(K>=0){let U=Number(e[K+1]),R=Number(e[K+2]);(!Number.isFinite(U)||!Number.isFinite(R))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),F={x:U,y:R}}let x={exact:b,role:p,within:d,minX:q!==null?Number(q):null,maxX:H!==null?Number(H):null,minY:w!==null?Number(w):null,maxY:O!==null?Number(O):null,near:F,nth:a,first:f},$=await At(u,o,x,{agent:me()}),v=$.payload;if(v?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),v?.ambiguous){let U=v.candidates;console.error(` ambiguous: ${v.total} matches for "${o}"`);for(let R of U){let we=R.abs?`@(${Math.round(R.abs.x)},${Math.round(R.abs.y)})`:"",lo=R.layout?` ${R.layout.width}x${R.layout.height}`:"",co=R.testID?` #${R.testID}`:"",uo=R.text?` "${R.text}"`:"",mo=R.ancestorTestIDs.length>0?` within ${R.ancestorTestIDs.slice(0,3).map(po=>`#${po}`).join(" > ")}`:"";console.error(` [${R.idx}] <${R.type}>${uo}${co} ${we}${lo}${mo}`)}v.total>U.length&&console.error(` ... and ${v.total-U.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 se=qe(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",se.step,se.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||a!==null?{nth:{index:v.idx,total:v.total}}:{},...$.attempts>1?{attempts:$.attempts}:{},result:$.result},null,2));break}case"tap-best":{let o=i[1];o||(console.error(k("tap-best","<query>")),process.exit(1));let t=await Pt(u,o,{agent:me()}),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 a=qe(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",a.step,a.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=i[1];o||(console.error(k("tap-id","<id>")),process.exit(1));let t=await Ot(u,o,{agent:me()}),s=t.payload;(!s||typeof s.cx!="number")&&(console.error(` not found: ${o}`),await Co(u,o),process.exit(1)),de(t.result)||(N(`id "${o}"`,t),process.exit(1));let r=qe(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=i[1],t=i.slice(2).join(" ");(!o||!t)&&(console.error(k("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(o),r=await u.send({type:"evaluate",code:`(async () => {
414
419
  const t = window.__sootsimTest
415
420
  if (!t) return null
416
421
  const n = await (t.findByTestId(${s}) || t.findById(${s}))
@@ -422,9 +427,10 @@ ${s}
422
427
  testID: n.testID,
423
428
  type: n.type,
424
429
  isTextInput: !!n.isTextInput,
430
+ secureTextEntry: !!n.secureTextEntry,
425
431
  placeholder: n.placeholder || null,
426
432
  }
427
- })()`});(!i||typeof i.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),i.isTextInput||console.error(` warning: ${o} is not a text input (isTextInput: false)`);let a=await d.send({type:"tap",x:i.cx,y:i.cy,target:{id:i.id??o,testID:i.testID??o,text:null,type:i.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 J("inspect type-into",{tapOn:{id:o},inputText:t},`type-into #${o} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:o,isTextInput:i.isTextInput,keyboardOpened:u.visible??a?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:t},null,2));break}case"type":{let o=r.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 J("inspect type",{inputText:o},`type ${JSON.stringify(o)}`),console.log(` typed: ${JSON.stringify(o)}`);break}case"key":{let o=r[1];o||(console.error(k("key","<name>")),process.exit(1)),await Me(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=r.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 J("inspect key-sequence",{pressKey:o.join(" ")},`key-sequence ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"keycode":{let o=r.slice(1);o.length===0&&(console.error(k("keycode","<code> [<code> ...]")),process.exit(1));let t=o.map(i=>({code:i,key:qo(i)})),s=t.filter(i=>!i.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(i=>i.code).join(", ")}`),process.exit(1)),await Me(d,"keycode");for(let i of t)await d.send({type:"keyboard",action:"press",text:i.key});await J("inspect keycode",{pressKey:t.map(i=>i.key).join(" ")},`keycode ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"dispatch":{let o=r[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(r[1]),t=Number(r[2]),s=ye(e);if(s){let p=await ve(d,s);p||(console.error(` not found: ${s.value}`),s.mode==="testid"&&Y("wait-selector-for-missing-testid",s.value),process.exit(1)),o=p.x,t=p.y}let i=r[3]?Number(r[3]):80;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(i))&&(console.error(k("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let a=Math.max(0,Math.round(i)),u=await d.send({type:"evaluate",code:`(async () => {
433
+ })()`});(!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 a=await u.send({type:"tap",x:r.cx,y:r.cy,target:{id:r.id??o,testID:r.testID??o,text:null,type:r.type??null}}),d=r.secureTextEntry===!0,p=await zo(u,1e3,{targetId:o,secureTextEntry:d});p.visible||(console.error(` keyboard did not open after tapping ${o}`),process.exit(1));let b=p.focusedInput;b&&(b.testID===o||b.id===o||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(o)} but focus is on ${JSON.stringify(b.testID??b.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await u.send({type:"keyboard",action:"type",text:t});let f=d||be(p),w=f?X:Le(t,p),O=f&&p.focusedInput?{...p.focusedInput,secureTextEntry:!0,text:typeof p.focusedInput.text=="string"?X:p.focusedInput.text}:p.focusedInput??null;await L("inspect type-into",{tapOn:{id:o},inputText:w},w===X?`type-into #${o} ${X}`:`type-into #${o} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:o,isTextInput:r.isTextInput,secureTextEntry:f,keyboardOpened:p.visible??a?.keyboardOpened??!1,focusedInput:O,typed:w},null,2));break}case"type":{let o=i.slice(1).join(" ");o||(console.error(k("type","<text>")),process.exit(1));let t=await Ne(u,"type");await u.send({type:"keyboard",action:"type",text:o});let s=Le(o,t);await L("inspect type",{inputText:s},s===X?`type ${X}`:`type ${JSON.stringify(o)}`),console.log(s===X?` typed: ${X}`:` typed: ${JSON.stringify(o)}`);break}case"key":{let o=i[1];o||(console.error(k("key","<name>")),process.exit(1)),await Ne(u,"key"),await u.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=i.slice(1);o.length===0&&(console.error(k("key-sequence","<key> [<key> ...]")),process.exit(1)),await Ne(u,"key-sequence");for(let t of o)await u.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=i.slice(1);o.length===0&&(console.error(k("keycode","<code> [<code> ...]")),process.exit(1));let t=o.map(r=>({code:r,key:Go(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 Ne(u,"keycode");for(let r of t)await u.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=i[1];o||(console.error(k("dispatch","<char>")),process.exit(1)),await u.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 u.send({type:"keyboard",action:"dismiss"}),await L("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let o=Number(i[1]),t=Number(i[2]),s=he(e);if(s){let p=await Te(u,s);p||(console.error(` not found: ${s.value}`),s.mode==="testid"&&Y("wait-selector-for-missing-testid",s.value),process.exit(1)),o=p.x,t=p.y}let r=i[3]?Number(i[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 a=Math.max(0,Math.round(r)),d=await u.send({type:"evaluate",code:`(async () => {
428
434
  const interact = window.__sootsimInteract
429
435
  if (interact?.doubleTap) {
430
436
  return {
@@ -447,13 +453,13 @@ ${s}
447
453
  first,
448
454
  second,
449
455
  }
450
- })()`});u?.ok&&await J("inspect double-tap",{doubleTapAtCoords:{x:o,y:t,gapMs:a}},`double-tap @${o},${t}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let o=Number(r[1]),t=Number(r[2]),s=ye(e),i=null;if(s){let f=await ve(d,s);f||(console.error(` not found: ${s.value}`),s.mode==="testid"&&Y("wait-selector-for-missing-testid",s.value),process.exit(1)),o=f.x,t=f.y,i={id:f.id??null,testID:f.testID??null,text:f.text??null,type:f.type??null}}let a=s?r[1]:r[3],u=a?Number(a):600;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(u))&&(console.error(k("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let p=Math.max(0,Math.round(u)),b=await d.send({type:"longPress",x:o,y:t,durationMs:p,target:i});b?.ok&&await J("inspect long-press",{tapAtCoords:{x:o,y:t}},`long-press @${o},${t}`),console.log(JSON.stringify(b,null,2));break}case"touch":{let o=r[1],t=Number(r[2]),s=Number(r[3]),i=r[4]?Number(r[4]):999,a=o==="down"?"touchDown":o==="move"?"touchMove":o==="up"?"touchUp":o==="cancel"?"touchCancel":null;a||(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} } }));`:"",b=await d.send({type:"evaluate",code:`(async () => {
456
+ })()`});d?.ok&&await L("inspect double-tap",{doubleTapAtCoords:{x:o,y:t,gapMs:a}},`double-tap @${o},${t}`),console.log(JSON.stringify(d,null,2));break}case"long-press":{let o=Number(i[1]),t=Number(i[2]),s=he(e),r=null;if(s){let f=await Te(u,s);f||(console.error(` not found: ${s.value}`),s.mode==="testid"&&Y("wait-selector-for-missing-testid",s.value),process.exit(1)),o=f.x,t=f.y,r={id:f.id??null,testID:f.testID??null,text:f.text??null,type:f.type??null}}let a=s?i[1]:i[3],d=a?Number(a):600;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(d))&&(console.error(k("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let p=Math.max(0,Math.round(d)),b=await u.send({type:"longPress",x:o,y:t,durationMs:p,target:r});b?.ok&&await L("inspect long-press",{tapAtCoords:{x:o,y:t}},`long-press @${o},${t}`),console.log(JSON.stringify(b,null,2));break}case"touch":{let o=i[1],t=Number(i[2]),s=Number(i[3]),r=i[4]?Number(i[4]):999,a=o==="down"?"touchDown":o==="move"?"touchMove":o==="up"?"touchUp":o==="cancel"?"touchCancel":null;a||(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 d=o==="down"?"tap":o==="move"?"move":null,p=d&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${d}', x: ${t}, y: ${s} } }));`:"",b=await u.send({type:"evaluate",code:`(async () => {
451
457
  ${p}
452
458
  const interact = window.__sootsimInteract
453
459
  if (!interact?.${a}) return { ok: false, reason: 'no interact.${a}' }
454
- const value = ${o==="cancel"?`await interact.${a}(${Math.max(1,Math.round(i))})`:`await interact.${a}(${t}, ${s}, ${Math.max(1,Math.round(i))})`}
460
+ const value = ${o==="cancel"?`await interact.${a}(${Math.max(1,Math.round(r))})`:`await interact.${a}(${t}, ${s}, ${Math.max(1,Math.round(r))})`}
455
461
  return { ok: !!value, value }
456
- })()`});b?.ok&&o!=="cancel"&&await J("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${o} @${t},${s}`),console.log(JSON.stringify(b,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=r[1],s=r[2]?Number(r[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 i=await d.send({type:"evaluate",code:`(async () => {
462
+ })()`});b?.ok&&o!=="cancel"&&await L("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${o} @${t},${s}`),console.log(JSON.stringify(b,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=i[1],s=i[2]?Number(i[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 u.send({type:"evaluate",code:`(async () => {
457
463
  const spec = globalThis.__sootsimDeviceSpec || {}
458
464
  return {
459
465
  width: spec.width || window.innerWidth || 393,
@@ -461,12 +467,12 @@ ${s}
461
467
  statusBarHeight: spec.statusBarHeight || 0,
462
468
  homeIndicatorHeight: spec.homeIndicatorHeight || 0,
463
469
  }
464
- })()`}),a=Number(i?.width)||393,u=Number(i?.height)||852,p=Number(i?.statusBarHeight)||0,b=Number(i?.homeIndicatorHeight)||0,f=Math.round(a/2),x=Math.round(u/2),O=Math.max(24,p+18),q=Math.max(24,b+18),H=18,U=Math.min(220,Math.round(u*.24)),F=Math.min(180,Math.round(a*.32)),w=f,$=x,v=f,oe=x;switch(t){case"scroll-up":$=x+Math.round(U/2),oe=x-Math.round(U/2);break;case"scroll-down":$=x-Math.round(U/2),oe=x+Math.round(U/2);break;case"scroll-left":w=f+Math.round(F/2),v=f-Math.round(F/2);break;case"scroll-right":w=f-Math.round(F/2),v=f+Math.round(F/2);break;case"swipe-from-left-edge":w=H,$=x,v=Math.min(a-H,H+F);break;case"swipe-from-right-edge":w=a-H,$=x,v=Math.max(H,a-H-F);break;case"swipe-from-top-edge":w=f,$=O,oe=Math.min(u-q,O+U);break;case"swipe-from-bottom-edge":w=f,$=u-q,oe=Math.max(O,u-q-U);break}let K=Math.max(8,Math.round(s/16)),E=Math.max(1,Math.round(s/K)),he=await d.send({type:"evaluate",code:`(async () => {
470
+ })()`}),a=Number(r?.width)||393,d=Number(r?.height)||852,p=Number(r?.statusBarHeight)||0,b=Number(r?.homeIndicatorHeight)||0,f=Math.round(a/2),w=Math.round(d/2),O=Math.max(24,p+18),q=Math.max(24,b+18),H=18,K=Math.min(220,Math.round(d*.24)),F=Math.min(180,Math.round(a*.32)),x=f,$=w,v=f,se=w;switch(t){case"scroll-up":$=w+Math.round(K/2),se=w-Math.round(K/2);break;case"scroll-down":$=w-Math.round(K/2),se=w+Math.round(K/2);break;case"scroll-left":x=f+Math.round(F/2),v=f-Math.round(F/2);break;case"scroll-right":x=f-Math.round(F/2),v=f+Math.round(F/2);break;case"swipe-from-left-edge":x=H,$=w,v=Math.min(a-H,H+F);break;case"swipe-from-right-edge":x=a-H,$=w,v=Math.max(H,a-H-F);break;case"swipe-from-top-edge":x=f,$=O,se=Math.min(d-q,O+K);break;case"swipe-from-bottom-edge":x=f,$=d-q,se=Math.max(O,d-q-K);break}let U=Math.max(8,Math.round(s/16)),R=Math.max(1,Math.round(s/U)),we=await u.send({type:"evaluate",code:`(async () => {
465
471
  const interact = window.__sootsimInteract
466
472
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
467
- const value = await interact.drag(${w}, ${$}, ${v}, ${oe}, ${K}, ${E})
473
+ const value = await interact.drag(${x}, ${$}, ${v}, ${se}, ${U}, ${R})
468
474
  return { ok: !!value, value }
469
- })()`});he?.ok&&await J("inspect gesture",{swipe:{start:`${w}, ${$}`,end:`${v}, ${oe}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:w,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?r[1]:null,i=o||t!=null?1:2,a=Number(r[i]),u=Number(r[i+1]);(!s&&t==null||!Number.isFinite(a)||!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
+ })()`});we?.ok&&await L("inspect gesture",{swipe:{start:`${x}, ${$}`,end:`${v}, ${se}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x,y:$},to:{x:v,y:se},result:we},null,2));break}case"scroll":{let o=he(e),t=Xo(e),s=o?.mode==="testid"?o.value:t==null?i[1]:null,r=o||t!=null?1:2,a=Number(i[r]),d=Number(i[r+1]);(!s&&t==null||!Number.isFinite(a)||!Number.isFinite(d))&&(console.error(k("scroll","<id> <x> <y> | --testid <id> <x> <y> | --node-id <nodeId> <x> <y>")),process.exit(1));let p=await u.send({type:"evaluate",code:`(async () => {
470
476
  const t = window.__sootsimTest
471
477
  if (!t) return null
472
478
  const n = ${t!=null?`await t.inspectByNodeId(${JSON.stringify(t)})`:`await t.findByTestId(${JSON.stringify(s)})
@@ -476,7 +482,7 @@ ${s}
476
482
  cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
477
483
  cy: n.absolutePosition.y + (n.layout.height || 0) / 2,
478
484
  }
479
- })()`}),b=await G(d,"scrollTo",t!=null?{nodeId:t}:s,a,u,!1);if(b?.ok){let f=t!=null?`node ${t}`:`#${s}`;await J("inspect scroll",{scrollTo:{...t!=null?{nodeId:t}:{id:s},x:a,y:u}},`scroll ${f} -> ${a},${u}`)}console.log(JSON.stringify({...b,...p?{at:{x:p.cx,y:p.cy}}:{}},null,2));break}case"state":{let o=r[1];if(n==="get"&&!o){let s=await G(d,"getRuntimeState"),i=await d.send({type:"evaluate",code:xe});if(s&&typeof s=="object"&&s.diagnostics&&(s.diagnostics.errors=i?.errors??0,s.diagnostics.warnings=i?.warnings??0),s&&typeof s=="object"&&s.shell==null)try{let a=await le(d);a&&(s.shell=a)}catch{}console.log(JSON.stringify(s,null,2));break}if(!o||o==="--help"||o==="-h"){console.log(`
485
+ })()`}),b=await G(u,"scrollTo",t!=null?{nodeId:t}:s,a,d,!1);if(b?.ok){let f=t!=null?`node ${t}`:`#${s}`;await L("inspect scroll",{scrollTo:{...t!=null?{nodeId:t}:{id:s},x:a,y:d}},`scroll ${f} -> ${a},${d}`)}console.log(JSON.stringify({...b,...p?{at:{x:p.cx,y:p.cy}}:{}},null,2));break}case"state":{let o=i[1];if(n==="get"&&!o){let s=await G(u,"getRuntimeState"),r=await u.send({type:"evaluate",code:Se});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 a=await ce(u);a&&(s.shell=a)}catch{}console.log(JSON.stringify(s,null,2));break}if(!o||o==="--help"||o==="-h"){console.log(`
480
486
  ${h("state")} \u2014 dump raw runtime state
481
487
 
482
488
  subcommands:
@@ -499,17 +505,19 @@ ${s}
499
505
  ${h("state")} scroll feed
500
506
  ${h("state")} scroll-hit 360 420
501
507
  ${h("state")} hit 200 720
502
- `);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:`(() => {
508
+ `);break}let t;switch(o){case"shell":t=await ce(u,500);break;case"worker":t=await Oe(u,"__sootsimRenderHost.queryStats");break;case"ownership":t=await u.send({type:"evaluate",code:`(() => {
503
509
  const h = window.__sootsimRenderHost
504
510
  if (!h || typeof h.getOwnershipSnapshot !== 'function') {
505
511
  return { error: 'getOwnershipSnapshot not available' }
506
512
  }
507
513
  return h.getOwnershipSnapshot()
508
- })()`});break;case"keyboard":t=await d.send({type:"evaluate",code:`(async () => {
514
+ })()`});break;case"keyboard":t=await u.send({type:"evaluate",code:`(async () => {
509
515
  const kb = window.__sootsimKeyboard
510
516
  const test = window.__sootsimTest
511
517
  if (!kb) return { error: 'keyboard bridge not available' }
512
518
  const layout = typeof kb.getLayout === 'function' ? kb.getLayout() : null
519
+ const secureTextEntry =
520
+ !!layout?.spec?.secureTextEntry && layout?.spec?.keyboardType !== 'visible-password'
513
521
  const visible = kb.isVisible()
514
522
  const mode = kb.getMode()
515
523
  let focused = null
@@ -527,10 +535,11 @@ ${s}
527
535
  testID: focused.testID || null,
528
536
  id: focused.id || null,
529
537
  placeholder: focused.placeholder || null,
530
- text: focused.text || null,
538
+ secureTextEntry,
539
+ text: secureTextEntry ? ${JSON.stringify(X)} : (focused.text || null),
531
540
  } : null,
532
541
  }
533
- })()`});break;case"node":{let s=r[2];s||(console.error(` usage: ${h("state")} node <id>`),process.exit(1)),t=await G(d,"findByTestId",s)||await G(d,"findById",s);break}case"scroll":{let s=r[2];s||(console.error(` usage: ${h("state")} scroll <id>`),process.exit(1)),t=await G(d,"getScrollState",s);break}case"scroll-hit":{let s=Number(r[2]),i=Number(r[3]);(!Number.isFinite(s)||!Number.isFinite(i))&&(console.error(` usage: ${h("state")} scroll-hit <x> <y>`),process.exit(1)),t=await G(d,"getScrollStateAt",s,i);break}case"hit":{let s=Number(r[2]),i=Number(r[3]);(!Number.isFinite(s)||!Number.isFinite(i))&&(console.error(` usage: ${h("state")} hit <x> <y>`),process.exit(1)),t=await G(d,"debugHitAt",s,i);break}case"gesture":{let s=Number(r[2]),i=Number(r[3]);(!Number.isFinite(s)||!Number.isFinite(i))&&(console.error(` usage: ${h("state")} gesture <x> <y>`),process.exit(1)),t=await G(d,"debugGestureAt",s,i);break}default:console.error(` unknown state subcommand: ${o}`),process.exit(1)}console.log(JSON.stringify(t,null,2));break}case"shell":{let o=r[1];if(!o||o==="--help"||o==="-h"){console.log(`
542
+ })()`}),t=Je(t);break;case"node":{let s=i[2];s||(console.error(` usage: ${h("state")} node <id>`),process.exit(1)),t=await G(u,"findByTestId",s)||await G(u,"findById",s);break}case"scroll":{let s=i[2];s||(console.error(` usage: ${h("state")} scroll <id>`),process.exit(1)),t=await G(u,"getScrollState",s);break}case"scroll-hit":{let s=Number(i[2]),r=Number(i[3]);(!Number.isFinite(s)||!Number.isFinite(r))&&(console.error(` usage: ${h("state")} scroll-hit <x> <y>`),process.exit(1)),t=await G(u,"getScrollStateAt",s,r);break}case"hit":{let s=Number(i[2]),r=Number(i[3]);(!Number.isFinite(s)||!Number.isFinite(r))&&(console.error(` usage: ${h("state")} hit <x> <y>`),process.exit(1)),t=await G(u,"debugHitAt",s,r);break}case"gesture":{let s=Number(i[2]),r=Number(i[3]);(!Number.isFinite(s)||!Number.isFinite(r))&&(console.error(` usage: ${h("state")} gesture <x> <y>`),process.exit(1)),t=await G(u,"debugGestureAt",s,r);break}default:console.error(` unknown state subcommand: ${o}`),process.exit(1)}console.log(JSON.stringify(t,null,2));break}case"shell":{let o=i[1];if(!o||o==="--help"||o==="-h"){console.log(`
534
543
  ${h("shell")} \u2014 run built-in shell commands
535
544
 
536
545
  subcommands:
@@ -554,7 +563,7 @@ ${s}
554
563
  ${h("shell")} open-card clock 800
555
564
  ${h("shell")} appearance dark
556
565
  ${h("shell")} lock
557
- `);break}let t=o==="launch"||o==="open-card"||o==="home"||o==="switcher",s=o==="launch"||o==="open-card"?r[3]:r[2],i=s?Number(s):350;t&&(!Number.isFinite(i)||i<0)&&(console.error(k("shell",o==="launch"||o==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let a=!1,u=!1,p=null,b=e.includes("--clear-state");if(o==="launch"){let f=r[2];f||(console.error(k("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),b&&await d.send({type:"evaluate",code:Ge(!0)}),a=!!await pe(d,"launchApp",i,f),{settled:u,state:p}=await Te(d,Math.round(i),x=>!!x&&x.state==="app"&&x.activeApp===f&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.launchProgress=="number"&&x.launchProgress>=.98),a&&await J("inspect shell launch",b?{launchApp:{clearState:!0}}:{launchApp:{}},b?"launch app (clear state)":"launch app")}else if(o==="home")a=!!await pe(d,"goHome",i),{settled:u,state:p}=await Te(d,Math.round(i),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")a=!!await pe(d,"openSwitcher",i),{settled:u,state:p}=await Te(d,Math.round(i),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(Lo),p=await le(d));else if(o==="open-card"){let f=r[2];f||(console.error(k("shell","open-card <appId> [settleMs]")),process.exit(1)),a=!!await pe(d,"openSwitcherCard",i,f),{settled:u,state:p}=await Te(d,Math.round(i),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),a&&await J("inspect shell open-card",{openSwitcherCard:{appId:f}},`open switcher card ${f}`)}else if(o==="appearance"){let f=r[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(a=!!x?.ok,p={appearance:x},a){let O=x?.applied??f;console.log(` appearance: ${O}`)}}else if(o==="lock"||o==="shake"){let f=await Zt(d,o);a=!!f?.ok,p={[o]:f}}else console.error(` unknown shell subcommand: ${o}`),process.exit(1);console.log(JSON.stringify({ok:a,settled:u,state:p},null,2));break}case"url":{await Lt(d,{args:l});break}case"reload":{let s=!1,i=!1;try{await d.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let p=await d.send({type:"evaluate",code:`;(() => {
566
+ `);break}let t=o==="launch"||o==="open-card"||o==="home"||o==="switcher",s=o==="launch"||o==="open-card"?i[3]:i[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 a=!1,d=!1,p=null,b=e.includes("--clear-state");if(o==="launch"){let f=i[2];f||(console.error(k("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),b&&await u.send({type:"evaluate",code:Qe(!0)}),a=!!await fe(u,"launchApp",r,f),{settled:d,state:p}=await Ie(u,Math.round(r),w=>!!w&&w.state==="app"&&w.activeApp===f&&w.showSwitcher===!1&&w.switcherPhase==="idle"&&typeof w.launchProgress=="number"&&w.launchProgress>=.98),a&&await L("inspect shell launch",b?{launchApp:{clearState:!0}}:{launchApp:{}},b?"launch app (clear state)":"launch app")}else if(o==="home")a=!!await fe(u,"goHome",r),{settled:d,state:p}=await Ie(u,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")a=!!await fe(u,"openSwitcher",r),{settled:d,state:p}=await Ie(u,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),d&&(await ee(Ko),p=await ce(u));else if(o==="open-card"){let f=i[2];f||(console.error(k("shell","open-card <appId> [settleMs]")),process.exit(1)),a=!!await fe(u,"openSwitcherCard",r,f),{settled:d,state:p}=await Ie(u,Math.round(r),w=>!!w&&w.state==="app"&&w.activeApp===f&&w.showSwitcher===!1&&w.switcherPhase==="idle"&&typeof w.zoomLevel=="number"&&w.zoomLevel>=.98&&typeof w.horizontalZoom=="number"&&w.horizontalZoom>=.98),a&&await L("inspect shell open-card",{openSwitcherCard:{appId:f}},`open switcher card ${f}`)}else if(o==="appearance"){let f=i[2];(!f||!["light","dark","auto","toggle"].includes(f))&&(console.error(k("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let w=await so(u,"appearance",f);if(a=!!w?.ok,p={appearance:w},a){let O=w?.applied??f;console.log(` appearance: ${O}`)}}else if(o==="lock"||o==="shake"){let f=await so(u,o);a=!!f?.ok,p={[o]:f}}else console.error(` unknown shell subcommand: ${o}`),process.exit(1);console.log(JSON.stringify({ok:a,settled:d,state:p},null,2));break}case"url":{await Kt(u,{args:c});break}case"reload":{let s=!1,r=!1;try{await u.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let p=await u.send({type:"evaluate",code:`;(() => {
558
567
  const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
559
568
  if (typeof reloadExternalApp === 'function') {
560
569
  reloadExternalApp()
@@ -562,10 +571,10 @@ ${s}
562
571
  }
563
572
  window.location.reload()
564
573
  return { kind: 'page' }
565
- })()`});i=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let a=d,u=null;if(i)u=await Re(d,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await Z(300);let p=await ht(_,j,I,{timeoutMs:1e4,simIdSource:R});p?(a=p,u=await Re(p,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),a=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(a)try{let p=await we(a,10);if(a!==d&&a.close(),Array.isArray(p)&&p.length>0){console.log(`
574
+ })()`});r=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let a=u,d=null;if(r)d=await De(u,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await ee(300);let p=await $t(_,j,I,{timeoutMs:1e4,simIdSource:E});p?(a=p,d=await De(p,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),a=null)}if(d)if(d.ready){let p=d.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${d.elapsedMs}ms: ${d.nodes} nodes${p}`)}else if(d.source==="error-bail")console.log(` \u26A0 reload bailed after ${d.elapsedMs}ms: ${d.errors} console error(s), ready signal never fired`);else{let p=Jo(d);console.log(` \u26A0 reload timed out after ${d.elapsedMs}ms \u2014 ${p} (nodes: ${d.nodes}, targets: ${d.targets}, errors: ${d.errors})`)}if(a)try{let p=await $e(a,10);if(a!==u&&a.close(),Array.isArray(p)&&p.length>0){console.log(`
566
575
  \u26A0 ${p.length} error(s) during mount:
567
- `);for(let b of p){let f=b.args.map(x=>typeof x=="object"?JSON.stringify(x):x).join(" ");if(console.log(` ${f}`),b.stack){let x=b.stack.split(`
568
- `).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=r.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 i=o.toLowerCase(),a=[];(i.includes("sootsim:gohome")||i.includes("gohome"))&&a.push("sootsim shell home"),(i.includes("sootsim:appswitcher")||i.includes("appswitcher"))&&a.push("sootsim shell switcher"),(i.includes("keyboard.isvisible")||i.includes("keyboard.getmode"))&&a.push("sootsim debug state keyboard"),i.includes("interact.tap")&&a.push("sootsim do tap <x> <y>"),i.includes("keyboard.type")&&a.push("sootsim do type <text>"),(i.includes("keyboard.press")||i.includes("keyboard.dispatchkey"))&&a.push("sootsim do key <name>"),i.includes("keyboard.dismiss")&&a.push("sootsim do dismiss"),i.includes("dumptree")&&a.push("sootsim get tree"),i.includes("dumpaccessibilitytree")&&a.push("sootsim get a11y"),i.includes("getnodecount")&&a.push("sootsim get count"),i.includes("findbytext")&&a.push("sootsim find <text>"),(i.includes("findbytestid")||i.includes("findbyid"))&&a.push("sootsim find --testid <id>"),i.includes("document.hidden")&&a.push("sootsim debug state keyboard (includes tab health)"),a.length>0&&Y("prefer-cli-over-eval",a);break}case"globals":{let o=await d.send({type:"evaluate",code:`(async () => {
576
+ `);for(let b of p){let f=b.args.map(w=>typeof w=="object"?JSON.stringify(w):w).join(" ");if(console.log(` ${f}`),b.stack){let w=b.stack.split(`
577
+ `).slice(0,2);for(let O of w)console.log(` ${O.trim()}`)}}}}catch{}d&&!d.ready&&(process.exitCode=1);break}case"eval":case"js":{let o=i.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 u.send({type:"evaluate",code:t});console.log(JSON.stringify(s,null,2));let r=o.toLowerCase(),a=[];(r.includes("sootsim:gohome")||r.includes("gohome"))&&a.push("sootsim shell home"),(r.includes("sootsim:appswitcher")||r.includes("appswitcher"))&&a.push("sootsim shell switcher"),(r.includes("keyboard.isvisible")||r.includes("keyboard.getmode"))&&a.push("sootsim debug state keyboard"),r.includes("interact.tap")&&a.push("sootsim do tap <x> <y>"),r.includes("keyboard.type")&&a.push("sootsim do type <text>"),(r.includes("keyboard.press")||r.includes("keyboard.dispatchkey"))&&a.push("sootsim do key <name>"),r.includes("keyboard.dismiss")&&a.push("sootsim do dismiss"),r.includes("dumptree")&&a.push("sootsim get tree"),r.includes("dumpaccessibilitytree")&&a.push("sootsim get a11y"),r.includes("getnodecount")&&a.push("sootsim get count"),r.includes("findbytext")&&a.push("sootsim find <text>"),(r.includes("findbytestid")||r.includes("findbyid"))&&a.push("sootsim find --testid <id>"),r.includes("document.hidden")&&a.push("sootsim debug state keyboard (includes tab health)"),a.length>0&&Y("prefer-cli-over-eval",a);break}case"globals":{let o=await u.send({type:"evaluate",code:`(async () => {
569
578
  const globals = {}
570
579
 
571
580
  // test bridge (proxy in worker mode)
@@ -603,7 +612,7 @@ ${s}
603
612
 
604
613
  return globals
605
614
  })()`});console.log(` sootsim JS API:
606
- `);for(let[t,s]of Object.entries(o)){console.log(` ${t}:`);for(let i of s)console.log(` .${i}`);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:r});break}case"perf":{let o=r[1];if(!o||o==="--help"||o==="-h"){console.log(`
615
+ `);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 Rt({bridge:u,args:e,positional:i});break}case"perf":{let o=i[1];if(!o||o==="--help"||o==="-h"){console.log(`
607
616
  ${h("perf")} \u2014 performance profiling
608
617
 
609
618
  subcommands:
@@ -624,7 +633,7 @@ ${s}
624
633
  ${h("perf")} stop
625
634
  ${h("perf")} stop --json
626
635
  ${h("perf")} transition goHome
627
- `);break}switch(o){case"stats":{let t=await d.send({type:"evaluate",code:`(async () => {
636
+ `);break}switch(o){case"stats":{let t=await u.send({type:"evaluate",code:`(async () => {
628
637
  // worker mode (host exposes these)
629
638
  if (window.__sootsimPerfStats) {
630
639
  return await window.__sootsimPerfStats()
@@ -649,17 +658,17 @@ ${s}
649
658
  jankFrames: frameStats.recentFrames?.filter(f => f > 16.67).length || 0,
650
659
  recentCount: frameStats.recentFrames?.length || 0,
651
660
  }
652
- })()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),A(l)){P(t);break}let s=t.avgMs==="?"&&t.maxMs==="?",i=t.avgMs!=="?"?(1e3/parseFloat(t.avgMs)).toFixed(1):"?";console.log(" perf stats:"),console.log(` frames: ${t.frames}`),console.log(` avg: ${t.avgMs}ms (${i} fps)`),console.log(` max: ${t.maxMs}ms`),console.log(` layout: ${t.layoutMs}ms total`),console.log(` nodes: ${t.nodeCount}`),t.recentCount>0&&console.log(` jank: ${t.jankFrames}/${t.recentCount} frames >16.67ms`),s&&process.stderr.write(`
661
+ })()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),A(c)){P(t);break}let s=t.avgMs==="?"&&t.maxMs==="?",r=t.avgMs!=="?"?(1e3/parseFloat(t.avgMs)).toFixed(1):"?";console.log(" perf stats:"),console.log(` frames: ${t.frames}`),console.log(` avg: ${t.avgMs}ms (${r} fps)`),console.log(` max: ${t.maxMs}ms`),console.log(` layout: ${t.layoutMs}ms total`),console.log(` nodes: ${t.nodeCount}`),t.recentCount>0&&console.log(` jank: ${t.jankFrames}/${t.recentCount} frames >16.67ms`),s&&process.stderr.write(`
653
662
  \u26A0 frame timings are zero \u2014 enable them first:
654
663
  sootsim debug perf start # begin recording
655
664
  # \u2026 interact / run a flow / wait for the transition \u2026
656
665
  sootsim debug perf stop # full report
657
666
  sootsim debug perf stats # one-shot snapshot
658
- `);break}case"start":{await d.send({type:"evaluate",code:`(async () => {
667
+ `);break}case"start":{await u.send({type:"evaluate",code:`(async () => {
659
668
  // worker mode
660
669
  if (window.__sootsimPerfStart && window.__sootsimRenderHost) {
661
670
  const result = window.__sootsimPerfStart()
662
- window.${se} = {
671
+ window.${ne} = {
663
672
  active: true,
664
673
  mode: 'render-worker',
665
674
  lastSamples: [],
@@ -670,23 +679,23 @@ ${s}
670
679
  // main-thread mode
671
680
  window.__sootsimPerf?.enableFrameStats?.(true)
672
681
  window.__sootsimA11y?.resetProfile?.()
673
- window.${se} = {
682
+ window.${ne} = {
674
683
  active: true,
675
684
  mode: 'main-thread',
676
685
  lastSamples: [],
677
686
  startedAt: performance.now(),
678
687
  }
679
688
  return { started: true }
680
- })()`}),console.log(` profiling started \u2014 interact with the app, then run '${h("perf")} stop'`);break}case"stop":{let t=await d.send({type:"evaluate",code:`(async () => {
689
+ })()`}),console.log(` profiling started \u2014 interact with the app, then run '${h("perf")} stop'`);break}case"stop":{let t=await u.send({type:"evaluate",code:`(async () => {
681
690
  // worker mode
682
691
  if (window.__sootsimRenderHost) {
683
- const session = window.${se} || {}
692
+ const session = window.${ne} || {}
684
693
  const priorSamples = session.active && Array.isArray(session.lastSamples)
685
694
  ? session.lastSamples
686
695
  : []
687
696
  const flushedSamples = await window.__sootsimRenderHost.flushSamples()
688
697
  const samples = priorSamples.concat(flushedSamples)
689
- window.${se} = {
698
+ window.${ne} = {
690
699
  ...session,
691
700
  active: false,
692
701
  mode: 'render-worker',
@@ -750,8 +759,8 @@ ${s}
750
759
 
751
760
  // disable collection
752
761
  perf?.disableFrameStats?.()
753
- window.${se} = {
754
- ...(window.${se} || {}),
762
+ window.${ne} = {
763
+ ...(window.${ne} || {}),
755
764
  active: false,
756
765
  mode: 'main-thread',
757
766
  lastSamples: recent.map((ms, index) => [index, ms, 0, 0, 0, 0, 0]),
@@ -771,16 +780,16 @@ ${s}
771
780
  jankFrames: recent.filter(f => f > 16.67).length,
772
781
  sampleCount: recent.length,
773
782
  }
774
- })()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),A(l)){P(t);break}let s=t.avgMs>0?(1e3/t.avgMs).toFixed(1):"?",i=t.sampleCount>0?(t.jankFrames/t.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
775
- `),console.log(` frames: ${t.frames}`),console.log(` total: ${t.totalMs.toFixed(1)}ms`),console.log(` avg: ${t.avgMs.toFixed(2)}ms (${s} fps)`),console.log(` max: ${t.maxMs.toFixed(2)}ms`),console.log(""),t.layoutAvgMs!==void 0&&(console.log(" breakdown (avg per frame):"),console.log(` layout: ${t.layoutAvgMs.toFixed(2)}ms`),console.log(` render: ${t.renderAvgMs.toFixed(2)}ms`),console.log(` copy: ${t.copyAvgMs.toFixed(2)}ms`),t.auxAvgMs!==void 0&&console.log(` aux: ${t.auxAvgMs.toFixed(2)}ms`),t.otherAvgMs!==void 0&&console.log(` other: ${t.otherAvgMs.toFixed(2)}ms`),console.log("")),console.log(` distribution (${t.sampleCount} samples):`),console.log(` p50: ${t.p50.toFixed(2)}ms`),console.log(` p95: ${t.p95.toFixed(2)}ms`),console.log(` p99: ${t.p99.toFixed(2)}ms`),console.log(` jank: ${t.jankFrames} frames (${i}%) >16.67ms`);break}case"frames":{let t=r[2]?Number(r[2]):50;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${r[2]}"`),process.exit(1));let s=await d.send({type:"evaluate",code:`(async () => {
783
+ })()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),A(c)){P(t);break}let s=t.avgMs>0?(1e3/t.avgMs).toFixed(1):"?",r=t.sampleCount>0?(t.jankFrames/t.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
784
+ `),console.log(` frames: ${t.frames}`),console.log(` total: ${t.totalMs.toFixed(1)}ms`),console.log(` avg: ${t.avgMs.toFixed(2)}ms (${s} fps)`),console.log(` max: ${t.maxMs.toFixed(2)}ms`),console.log(""),t.layoutAvgMs!==void 0&&(console.log(" breakdown (avg per frame):"),console.log(` layout: ${t.layoutAvgMs.toFixed(2)}ms`),console.log(` render: ${t.renderAvgMs.toFixed(2)}ms`),console.log(` copy: ${t.copyAvgMs.toFixed(2)}ms`),t.auxAvgMs!==void 0&&console.log(` aux: ${t.auxAvgMs.toFixed(2)}ms`),t.otherAvgMs!==void 0&&console.log(` other: ${t.otherAvgMs.toFixed(2)}ms`),console.log("")),console.log(` distribution (${t.sampleCount} samples):`),console.log(` p50: ${t.p50.toFixed(2)}ms`),console.log(` p95: ${t.p95.toFixed(2)}ms`),console.log(` p99: ${t.p99.toFixed(2)}ms`),console.log(` jank: ${t.jankFrames} frames (${r}%) >16.67ms`);break}case"frames":{let t=i[2]?Number(i[2]):50;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${i[2]}"`),process.exit(1));let s=await u.send({type:"evaluate",code:`(async () => {
776
785
  if (window.__sootsimRenderHost) {
777
- const session = window.${se} || {}
786
+ const session = window.${ne} || {}
778
787
  if (session.active) {
779
788
  const priorSamples = Array.isArray(session.lastSamples) ? session.lastSamples : []
780
789
  const flushedSamples = await window.__sootsimRenderHost.flushSamples()
781
790
  const samples = priorSamples.concat(flushedSamples)
782
791
  window.__sootsimRenderHost.startSampling()
783
- window.${se} = {
792
+ window.${ne} = {
784
793
  ...session,
785
794
  active: true,
786
795
  mode: 'render-worker',
@@ -807,15 +816,15 @@ ${s}
807
816
  mode: 'main-thread',
808
817
  frames: (stats.recentFrames || []).slice(-${t}),
809
818
  }
810
- })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),A(l)){P(s);break}if(s.mode==="render-worker"){let a=Array.isArray(s.samples)?s.samples:[];if(a.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${a.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,p,b,f,x,O,q]of a)console.log(` ${p.toFixed(2).padStart(7)} ${b.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(a.map(u=>u[1])),s.live&&console.log(" sampling continues");break}let i=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(i.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${i.length} frame times (ms):`),console.log(` ${i.map(a=>a.toFixed(2)).join(", ")}`),Be(i);break}case"worst":{let t=r[2]?Number(r[2]):20;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${r[2]}"`),process.exit(1));let s=await d.send({type:"evaluate",code:`(async () => {
819
+ })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),A(c)){P(s);break}if(s.mode==="render-worker"){let a=Array.isArray(s.samples)?s.samples:[];if(a.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${a.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[d,p,b,f,w,O,q]of a)console.log(` ${p.toFixed(2).padStart(7)} ${b.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(d).padStart(5)}`);console.log(""),We(a.map(d=>d[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(a=>a.toFixed(2)).join(", ")}`),We(r);break}case"worst":{let t=i[2]?Number(i[2]):20;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${i[2]}"`),process.exit(1));let s=await u.send({type:"evaluate",code:`(async () => {
811
820
  if (window.__sootsimRenderHost) {
812
- const session = window.${se} || {}
821
+ const session = window.${ne} || {}
813
822
  if (session.active) {
814
823
  const priorSamples = Array.isArray(session.lastSamples) ? session.lastSamples : []
815
824
  const flushedSamples = await window.__sootsimRenderHost.flushSamples()
816
825
  const samples = priorSamples.concat(flushedSamples)
817
826
  window.__sootsimRenderHost.startSampling()
818
- window.${se} = {
827
+ window.${ne} = {
819
828
  ...session,
820
829
  active: true,
821
830
  mode: 'render-worker',
@@ -849,7 +858,7 @@ ${s}
849
858
  mode: 'main-thread',
850
859
  frames: recent.slice().sort((a, b) => b - a).slice(0, ${t}),
851
860
  }
852
- })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),A(l)){P(s);break}if(s.mode==="render-worker"){let a=Array.isArray(s.samples)?s.samples:[];if(a.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${a.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,p,b,f,x,O,q]of a)console.log(` ${p.toFixed(2).padStart(7)} ${b.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);s.live&&(console.log(""),console.log(" sampling continues"));break}let i=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(i.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${i.length} frame times (ms):`),console.log(` ${i.map(a=>a.toFixed(2)).join(", ")}`);break}case"transition":{let t=r[2];if(!t||!["goHome","appSwitcher","lockScreen"].includes(t)){console.log(`
861
+ })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),A(c)){P(s);break}if(s.mode==="render-worker"){let a=Array.isArray(s.samples)?s.samples:[];if(a.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${a.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[d,p,b,f,w,O,q]of a)console.log(` ${p.toFixed(2).padStart(7)} ${b.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(d).padStart(5)}`);s.live&&(console.log(""),console.log(" sampling continues"));break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${r.length} frame times (ms):`),console.log(` ${r.map(a=>a.toFixed(2)).join(", ")}`);break}case"transition":{let t=i[2];if(!t||!["goHome","appSwitcher","lockScreen"].includes(t)){console.log(`
853
862
  ${h("perf")} transition <event> \u2014 profile a shell transition
854
863
 
855
864
  events:
@@ -862,7 +871,7 @@ ${s}
862
871
  examples:
863
872
  ${h("perf")} transition goHome --timeout 10000
864
873
  ${h("perf")} transition appSwitcher
865
- `);break}let i=`sootsim:${t}`;Pe(` profiling ${t} transition...`),Pe(" (use --timeout 10000 if this times out)");let a=await d.send({type:"evaluate",code:`(async () => {
874
+ `);break}let r=`sootsim:${t}`;Re(` profiling ${t} transition...`),Re(" (use --timeout 10000 if this times out)");let a=await u.send({type:"evaluate",code:`(async () => {
866
875
  // only supported in render-worker mode
867
876
  if (!window.__sootsimRenderHost) {
868
877
  return { error: 'transition profiling requires render-worker mode' }
@@ -875,7 +884,7 @@ ${s}
875
884
  await new Promise(r => requestAnimationFrame(() => r(undefined)))
876
885
 
877
886
  // dispatch the shell event
878
- window.dispatchEvent(new Event('${i}'))
887
+ window.dispatchEvent(new Event('${r}'))
879
888
 
880
889
  // wait 600ms for transition to complete (shell animations are ~300-500ms)
881
890
  // using fixed timing avoids complex animation-end detection
@@ -921,11 +930,11 @@ ${s}
921
930
  jankFrames: frameTimes.filter(f => f > 16.67).length,
922
931
  samples,
923
932
  }
924
- })()`});if(a.error&&(console.error(` error: ${a.error}`),process.exit(1)),A(l)){P(a);break}if(a.warning&&console.log(` warning: ${a.warning}`),a.frames===0){console.log(" no frames captured");break}let u=a.avgMs>0?(1e3/a.avgMs).toFixed(1):"?",p=a.frames>0?(a.jankFrames/a.frames*100).toFixed(1):"0";console.log(` ${t} transition profiled:
933
+ })()`});if(a.error&&(console.error(` error: ${a.error}`),process.exit(1)),A(c)){P(a);break}if(a.warning&&console.log(` warning: ${a.warning}`),a.frames===0){console.log(" no frames captured");break}let d=a.avgMs>0?(1e3/a.avgMs).toFixed(1):"?",p=a.frames>0?(a.jankFrames/a.frames*100).toFixed(1):"0";console.log(` ${t} transition profiled:
925
934
 
926
935
  frames: ${a.frames}
927
936
  total: ${a.totalMs.toFixed(1)}ms
928
- avg: ${a.avgMs.toFixed(2)}ms (${u} fps)
937
+ avg: ${a.avgMs.toFixed(2)}ms (${d} fps)
929
938
  max: ${a.maxMs.toFixed(2)}ms
930
939
 
931
940
  breakdown (avg per frame):
@@ -939,29 +948,29 @@ ${s}
939
948
  p50: ${a.p50.toFixed(2)}ms
940
949
  p95: ${a.p95.toFixed(2)}ms
941
950
  p99: ${a.p99.toFixed(2)}ms
942
- jank: ${a.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(a.samples)&&a.samples.length>0&&(console.log(""),Be(a.samples.map(b=>b[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=r[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):
943
- `);for(let i of s){let a=re(i.timestamp),u=i.args.map(p=>typeof p=="object"?JSON.stringify(p):p).join(" ");if(console.log(` [${a}] ${u}`),i.stack){let p=i.stack.split(`
944
- `).slice(0,3);for(let b of p)console.log(` ${b.trim()}`)}}break}case"warnings":{let o=r[1]?Number(r[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):
945
- `);for(let s of t){let i=re(s.timestamp),a=s.args.map(u=>typeof u=="object"?JSON.stringify(u):u).join(" ");console.log(` [${i}] ${a}`)}break}case"animations":{let o=await G(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):
946
- `);for(let t of o){let s=String(t.kind).padEnd(6),i=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,a=Number(t.current??0).toFixed(2),u=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,b=t.loop?" loop":"",f=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${i.padEnd(14)} cur=${a.padEnd(7)} ${u.padStart(4)} ${p}${b}${f}`)}break}case"animation":{let o=r[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 G(d,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let o=r[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 G(d,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let o=r[1];if(o==="clear"){await ct(d),A(l)?P({cleared:!0}):console.log(" request buffer cleared");break}let t=o==="all",s=t?r[2]:o,i=s?Number(s):20,a=await lt(d,{failed:!t,limit:i});if(A(l)){P(a);break}if(a.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${a.length} ${t?"request(s)":"failed request(s)"}:
947
- `);for(let u of a){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=r[1],t=null,s=null,i=!1,a=!1,u=1e3,p=!1,b=!1;for(let F=0;F<l.length;F++){let w=l[F];if(w==="--filter")t=l[F+1]??null,F++;else if(w==="--limit"){let $=Number(l[F+1]);Number.isFinite($)&&(s=$),F++}else if(w==="--threshold"){let $=Number(l[F+1]);Number.isFinite($)&&$>0&&(u=$),F++}else w==="--failed"?i=!0:w==="--slow"?a=!0:w==="--tail"||w==="-f"?p=!0:w==="--json"&&(b=!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=r[2];F||(console.error(" usage: sootsim network get <id>"),process.exit(1));let w=await d.send({type:"evaluate",code:`(() => {
951
+ jank: ${a.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(a.samples)&&a.samples.length>0&&(console.log(""),We(a.samples.map(b=>b[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=i[1];if(o==="clear"){await dt(u),A(c)?P({cleared:!0}):console.log(" error buffer cleared");break}let t=o?Number(o):20,s=await $e(u,t);if(A(c)){P(s);break}if(s.length===0){console.log(" no errors captured");break}console.log(` ${s.length} error(s):
952
+ `);for(let r of s){let a=ie(r.timestamp),d=r.args.map(p=>typeof p=="object"?JSON.stringify(p):p).join(" ");if(console.log(` [${a}] ${d}`),r.stack){let p=r.stack.split(`
953
+ `).slice(0,3);for(let b of p)console.log(` ${b.trim()}`)}}break}case"warnings":{let o=i[1]?Number(i[1]):20,t=await ut(u,o);if(A(c)){P(t);break}if(t.length===0){console.log(" no warnings captured");break}console.log(` ${t.length} warning(s):
954
+ `);for(let s of t){let r=ie(s.timestamp),a=s.args.map(d=>typeof d=="object"?JSON.stringify(d):d).join(" ");console.log(` [${r}] ${a}`)}break}case"animations":{let o=await G(u,"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):
955
+ `);for(let t of o){let s=String(t.kind).padEnd(6),r=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,a=Number(t.current??0).toFixed(2),d=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,b=t.loop?" loop":"",f=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${r.padEnd(14)} cur=${a.padEnd(7)} ${d.padStart(4)} ${p}${b}${f}`)}break}case"animation":{let o=i[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 G(u,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let o=i[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 G(u,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let o=i[1];if(o==="clear"){await pt(u),A(c)?P({cleared:!0}):console.log(" request buffer cleared");break}let t=o==="all",s=t?i[2]:o,r=s?Number(s):20,a=await mt(u,{failed:!t,limit:r});if(A(c)){P(a);break}if(a.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${a.length} ${t?"request(s)":"failed request(s)"}:
956
+ `);for(let d of a){let p=ie(d.timestamp);console.log(` [${p}] ${oe(d)}`),d.responseBody?console.log(` ${d.responseBody}`):d.error&&console.log(` ${d.error}`)}break}case"network":{let o=i[1],t=null,s=null,r=!1,a=!1,d=1e3,p=!1,b=!1;for(let F=0;F<c.length;F++){let x=c[F];if(x==="--filter")t=c[F+1]??null,F++;else if(x==="--limit"){let $=Number(c[F+1]);Number.isFinite($)&&(s=$),F++}else if(x==="--threshold"){let $=Number(c[F+1]);Number.isFinite($)&&$>0&&(d=$),F++}else x==="--failed"?r=!0:x==="--slow"?a=!0:x==="--tail"||x==="-f"?p=!0:x==="--json"&&(b=!0)}if(o==="clear"){await u.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(o==="get"){let F=i[2];F||(console.error(" usage: sootsim network get <id>"),process.exit(1));let x=await u.send({type:"evaluate",code:`(() => {
948
957
  const obs = window.__sootsimObservability;
949
958
  if (!obs) return null;
950
959
  return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(F)}) || null;
951
- })()`});w||(console.error(` no entry with id ${F}`),process.exit(1)),b?console.log(JSON.stringify(w,null,2)):Bo(w);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).
952
- to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let x=async()=>{let F=await d.send({type:"evaluate",code:`(() => {
960
+ })()`});x||(console.error(` no entry with id ${F}`),process.exit(1)),b?console.log(JSON.stringify(x,null,2)):Wo(x);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).
961
+ to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let w=async()=>{let F=await u.send({type:"evaluate",code:`(() => {
953
962
  const obs = window.__sootsimObservability;
954
963
  if (!obs) return { ok: false };
955
964
  return { ok: true, entries: obs.network.getSnapshot() };
956
- })()`});if(!F||!F.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return F.entries??[]},O=F=>{let w=F;if(i&&(w=w.filter($=>!!$.error||$.status!=null&&$.status>=400)),a&&(w=w.filter($=>$.durationMs!=null&&$.durationMs>=u)),t){let $=t.toLowerCase();w=w.filter(v=>(v.displayUrl||v.url).toLowerCase().includes($))}return a&&!p&&(w=[...w].sort(($,v)=>(v.durationMs??0)-($.durationMs??0))),w};if(!p){let F=await x(),w=O(F).slice(-f);if(b){console.log(JSON.stringify(w,null,2));break}if(w.length===0){F.length===0?console.log(" no network requests captured"):console.log(a?` no requests slower than ${u}ms (${F.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(a?` ${w.length} request(s) slower than ${u}ms (sorted by duration desc):
957
- `:` ${w.length} request(s):
958
- `);for(let $ of w)Yt($);break}console.log(` tailing network (ctrl-c to stop)...
959
- `);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let F=await x(),w=O(F);for(let $ of w)$.durationMs!=null&&(q.has($.id)||(q.add($.id),b?console.log(JSON.stringify($)):Yt($)));await Z(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let o=r[1],t=null,s=null,i=null,a=!1,u=!1,p=!1;for(let w=0;w<l.length;w++){let $=l[w];if($==="--filter")t=l[w+1]??null,w++;else if($==="--limit"){let v=Number(l[w+1]);Number.isFinite(v)&&(s=v),w++}else $==="--level"?(i=l[w+1]??null,w++):$==="--tail"||$==="-f"?a=!0:$==="--json"?u=!0:($==="--internal"||$==="--all")&&(p=!0)}let b=i?new Set(i.split(",").map(w=>w.trim()).filter(w=>w==="log"||w==="info"||w==="warn"||w==="error"||w==="debug")):null;if(o==="clear"){await ut(d),console.log(" log buffer cleared");break}let f=!u&&process.stdout.isTTY===!0,x=s??(a?500:o?Number(o):50);Number.isFinite(x)||(console.error(` invalid limit: ${o} \u2014 \`logs\` takes a numeric count (e.g. ${h("logs")} 100).
960
- to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let O=()=>dt(d),q=w=>mt(w,{level:b,filter:t,showInternal:p});if(!a){let w=await O(),$=q(w).slice(-x);if(u){console.log(JSON.stringify($,null,2));break}if($.length===0){console.log(w.length===0?" no logs captured":" no matching logs");break}console.log(` ${$.length} log(s):
961
- `);for(let v of $)Vt(v,f);break}console.log(` tailing logs (ctrl-c to stop)...
962
- `);let H=new Set,U=!0,F=()=>{U=!1};process.on("SIGINT",F);try{for(;U;){let w=await O(),$=q(w);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 Ye(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),i=/^command timed out after (\d+)s$/.exec(t),a=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(i)if(await Ao(d)){let p=g??"describe";process.stderr.write(` the sim is still responsive \u2014 '${p}' just exceeded the ${i[1]}s command budget.
965
+ })()`});if(!F||!F.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return F.entries??[]},O=F=>{let x=F;if(r&&(x=x.filter($=>!!$.error||$.status!=null&&$.status>=400)),a&&(x=x.filter($=>$.durationMs!=null&&$.durationMs>=d)),t){let $=t.toLowerCase();x=x.filter(v=>(v.displayUrl||v.url).toLowerCase().includes($))}return a&&!p&&(x=[...x].sort(($,v)=>(v.durationMs??0)-($.durationMs??0))),x};if(!p){let F=await w(),x=O(F).slice(-f);if(b){console.log(JSON.stringify(x,null,2));break}if(x.length===0){F.length===0?console.log(" no network requests captured"):console.log(a?` no requests slower than ${d}ms (${F.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(a?` ${x.length} request(s) slower than ${d}ms (sorted by duration desc):
966
+ `:` ${x.length} request(s):
967
+ `);for(let $ of x)Zt($);break}console.log(` tailing network (ctrl-c to stop)...
968
+ `);let q=new Set,H=!0,K=()=>{H=!1};process.on("SIGINT",K);try{for(;H;){let F=await w(),x=O(F);for(let $ of x)$.durationMs!=null&&(q.has($.id)||(q.add($.id),b?console.log(JSON.stringify($)):Zt($)));await ee(250)}}finally{process.off("SIGINT",K)}break}case"logs":{let o=i[1],t=null,s=null,r=null,a=!1,d=!1,p=!1;for(let x=0;x<c.length;x++){let $=c[x];if($==="--filter")t=c[x+1]??null,x++;else if($==="--limit"){let v=Number(c[x+1]);Number.isFinite(v)&&(s=v),x++}else $==="--level"?(r=c[x+1]??null,x++):$==="--tail"||$==="-f"?a=!0:$==="--json"?d=!0:($==="--internal"||$==="--all")&&(p=!0)}let b=r?new Set(r.split(",").map(x=>x.trim()).filter(x=>x==="log"||x==="info"||x==="warn"||x==="error"||x==="debug")):null;if(o==="clear"){await gt(u),console.log(" log buffer cleared");break}let f=!d&&process.stdout.isTTY===!0,w=s??(a?500:o?Number(o):50);Number.isFinite(w)||(console.error(` invalid limit: ${o} \u2014 \`logs\` takes a numeric count (e.g. ${h("logs")} 100).
969
+ to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let O=()=>ft(u),q=x=>yt(x,{level:b,filter:t,showInternal:p});if(!a){let x=await O(),$=q(x).slice(-w);if(d){console.log(JSON.stringify($,null,2));break}if($.length===0){console.log(x.length===0?" no logs captured":" no matching logs");break}console.log(` ${$.length} log(s):
970
+ `);for(let v of $)to(v,f);break}console.log(` tailing logs (ctrl-c to stop)...
971
+ `);let H=new Set,K=!0,F=()=>{K=!1};process.on("SIGINT",F);try{for(;K;){let x=await O(),$=q(x);for(let v of $)H.has(v.id)||(H.add(v.id),d?console.log(JSON.stringify(v)):to(v,f));await ee(250)}}finally{process.off("SIGINT",F)}break}default:console.error(` unknown subcommand: ${g}`),process.exit(1)}if(pe.has(g)&&!e.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&!await Ze(u,g)&&await S(u),!B.has(g)&&!A(c))try{await re(u)}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),a=t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("could not connect to ws://");if(s)await Mt(u,_,s[1]);else if(/^no sim connected$/.test(t))Tt(_);else if(r)if(await Do(u)){let p=g??"describe";process.stderr.write(` the sim is still responsive \u2014 '${p}' just exceeded the ${r[1]}s command budget.
963
972
  the screen's node tree is large; narrow the query or raise the budget:
964
973
  sootsim ${p} --testid <id> # scope to one subtree
965
974
  sootsim find --testid <id> # targeted single-node lookup
966
975
  sootsim ${p} --timeout 60000 # raise per-command budget (ms)
967
- `)}else Gt();else if(a)Gt();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};
976
+ `)}else Qt();else if(a)Qt();else{try{await St(u)}catch{}try{await V({includeTail:!0})}catch{}try{await W({includeTail:!0})}catch{}}process.exit(1)}finally{u.close()}}export{Jn as runInspect};