sootsim 0.1.63 → 0.1.64

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 (136) hide show
  1. package/dist-cli/bin.js +3 -3
  2. package/dist-cli/chunks/{agent-Z7M6NMR6.js → agent-SHMN3LWB.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-C7OMZWTX.js → agent-wrapper-ESDQSMYX.js} +2 -2
  4. package/dist-cli/chunks/{assert-OB4RMGU6.js → assert-X3GQJUDI.js} +2 -2
  5. package/dist-cli/chunks/auto-bootstrap-PH4II3F2.js +2 -0
  6. package/dist-cli/chunks/beta-YKR6YRXH.js +2 -0
  7. package/dist-cli/chunks/{chunk-EIKREDI4.js → chunk-2GAZ3JW7.js} +2 -2
  8. package/dist-cli/chunks/{chunk-SSTMIACF.js → chunk-346HJVD6.js} +1 -1
  9. package/dist-cli/chunks/{chunk-KX3FO4N4.js → chunk-34PKFCEI.js} +3 -3
  10. package/dist-cli/chunks/{chunk-VV265FEE.js → chunk-3R3BQDKC.js} +2 -2
  11. package/dist-cli/chunks/{chunk-HPVO7FJA.js → chunk-6X3I2LF4.js} +2 -2
  12. package/dist-cli/chunks/{chunk-GW77VHPI.js → chunk-ALDKVFW3.js} +2 -2
  13. package/dist-cli/chunks/{chunk-AYJGGZA4.js → chunk-BT6IVKHN.js} +1 -1
  14. package/dist-cli/chunks/chunk-CETSCOUK.js +1 -0
  15. package/dist-cli/chunks/{chunk-B3644N6L.js → chunk-DJIQVKM6.js} +10 -10
  16. package/dist-cli/chunks/{chunk-AMZB6WUA.js → chunk-DSLBZC6J.js} +2 -2
  17. package/dist-cli/chunks/{chunk-4H3UC4KB.js → chunk-E5EWHEA5.js} +2 -2
  18. package/dist-cli/chunks/{chunk-T7H7BKA7.js → chunk-FFVJK2R7.js} +2 -2
  19. package/dist-cli/chunks/{chunk-KRRNCL56.js → chunk-G4GM43A7.js} +2 -2
  20. package/dist-cli/chunks/{chunk-4232ZQOX.js → chunk-GKUKCZBA.js} +44 -44
  21. package/dist-cli/chunks/{chunk-AUMMYIP5.js → chunk-HERZHQFG.js} +2 -2
  22. package/dist-cli/chunks/{chunk-INXMOS35.js → chunk-J6TCNU6W.js} +1 -1
  23. package/dist-cli/chunks/chunk-KY2VMN66.js +1 -0
  24. package/dist-cli/chunks/{chunk-PX7QNGSM.js → chunk-L3MRXOBW.js} +3 -3
  25. package/dist-cli/chunks/{chunk-GICJIXEH.js → chunk-LKJI7RRW.js} +2 -2
  26. package/dist-cli/chunks/{chunk-7RZWW5VK.js → chunk-M4CADRP5.js} +2 -2
  27. package/dist-cli/chunks/{chunk-FSSJVHNV.js → chunk-N63QYSHT.js} +3 -3
  28. package/dist-cli/chunks/{chunk-PDMITY2P.js → chunk-OBL6OIK5.js} +1 -1
  29. package/dist-cli/chunks/chunk-OBSMT5TS.js +2 -0
  30. package/dist-cli/chunks/{chunk-ENACZPKI.js → chunk-PXRELDJJ.js} +2 -2
  31. package/dist-cli/chunks/{chunk-LJ7SH2KY.js → chunk-R6ZTREB6.js} +2 -2
  32. package/dist-cli/chunks/{chunk-C6UT7L2J.js → chunk-RKUDWRIN.js} +2 -2
  33. package/dist-cli/chunks/{chunk-2TVSYU32.js → chunk-RQHWF2OD.js} +2 -2
  34. package/dist-cli/chunks/{chunk-XILD5NPV.js → chunk-RRGCQNVD.js} +1 -1
  35. package/dist-cli/chunks/{chunk-DFRQMFUV.js → chunk-SMYSG4VE.js} +1 -1
  36. package/dist-cli/chunks/{chunk-4OW4EPBS.js → chunk-SVT7H2QF.js} +2 -2
  37. package/dist-cli/chunks/{chunk-PY25FDGX.js → chunk-T5TDH2UO.js} +1 -1
  38. package/dist-cli/chunks/{chunk-NWHQG4PG.js → chunk-UVDVALC7.js} +2 -2
  39. package/dist-cli/chunks/{chunk-E2EPTSHO.js → chunk-VE4QTDAY.js} +2 -2
  40. package/dist-cli/chunks/{chunk-MTTIJQ64.js → chunk-VGD57MTN.js} +2 -2
  41. package/dist-cli/chunks/{chunk-QW6P2JE2.js → chunk-WKVIKFMU.js} +1 -1
  42. package/dist-cli/chunks/chunk-WN4XOOK5.js +2 -0
  43. package/dist-cli/chunks/{chunk-IKFKEII6.js → chunk-X3QWOTLT.js} +1 -1
  44. package/dist-cli/chunks/chunk-XHD3XCT5.js +1 -0
  45. package/dist-cli/chunks/{chunk-DYUOXUBI.js → chunk-XHDHG6YH.js} +1 -1
  46. package/dist-cli/chunks/{chunk-5OZ7M24R.js → chunk-YGMHOMAJ.js} +2 -2
  47. package/dist-cli/chunks/{chunk-A3UFHDMY.js → chunk-YJIQYIHM.js} +1 -1
  48. package/dist-cli/chunks/{chunk-76MTBJ24.js → chunk-YXZFG3ZY.js} +1 -1
  49. package/dist-cli/chunks/{chunk-FEZCATWN.js → chunk-ZV2TI6OH.js} +2 -2
  50. package/dist-cli/chunks/cli-version-32VNOX3F.js +2 -0
  51. package/dist-cli/chunks/{compat-2AFC4MFV.js → compat-SOHG4UE5.js} +3 -3
  52. package/dist-cli/chunks/{config-KEEXBCOM.js → config-JQF6TGCG.js} +2 -2
  53. package/dist-cli/chunks/control-GIAGLNPG.js +2 -0
  54. package/dist-cli/chunks/{cpu-profile-RPSEEWCO.js → cpu-profile-3C7LHLJE.js} +2 -2
  55. package/dist-cli/chunks/{daemon-FCQLYFNH.js → daemon-SD773LNY.js} +2 -2
  56. package/dist-cli/chunks/{debug-QSYUF4WZ.js → debug-MNWVCAAF.js} +3 -3
  57. package/dist-cli/chunks/demo-app-registry-JUKLYD4R.js +2 -0
  58. package/dist-cli/chunks/{detox-6PJOIC7Z.js → detox-VOWHHVNU.js} +2 -2
  59. package/dist-cli/chunks/{device-H7GVARBE.js → device-TFKPS72A.js} +2 -2
  60. package/dist-cli/chunks/{diagnose-H47FC64H.js → diagnose-J2BTJTGW.js} +2 -2
  61. package/dist-cli/chunks/drivers-HVKRY4MB.js +2 -0
  62. package/dist-cli/chunks/{electron-54ZCOKJE.js → electron-NHJHQAOJ.js} +3 -3
  63. package/dist-cli/chunks/flow-D6MKC5NH.js +2 -0
  64. package/dist-cli/chunks/{hints-V4VBWK3W.js → hints-XONGBPNI.js} +2 -2
  65. package/dist-cli/chunks/{home-paths-GUUGF76T.js → home-paths-KK7NZVIK.js} +2 -2
  66. package/dist-cli/chunks/{inspect-NDLLEBJK.js → inspect-7AINMWI2.js} +100 -100
  67. package/dist-cli/chunks/install-YPSDICK4.js +2 -0
  68. package/dist-cli/chunks/{install-desktop-FBK4PRA3.js → install-desktop-CRFW4MDL.js} +3 -3
  69. package/dist-cli/chunks/{keys-IWDHA2GT.js → keys-PLJITE2X.js} +2 -2
  70. package/dist-cli/chunks/{launch-MQEJM5XD.js → launch-FHMTFUI3.js} +3 -3
  71. package/dist-cli/chunks/{login-FFLXNWYQ.js → login-DCFVFSY3.js} +4 -4
  72. package/dist-cli/chunks/{logout-X4NH4PZG.js → logout-55UH67FS.js} +2 -2
  73. package/dist-cli/chunks/{maestro-V3GTFFX6.js → maestro-HNNW73KG.js} +2 -2
  74. package/dist-cli/chunks/{preview-YHY7IHFE.js → preview-EYIZWAEJ.js} +2 -2
  75. package/dist-cli/chunks/{profile-CFYRAH3J.js → profile-UOG2ET7W.js} +2 -2
  76. package/dist-cli/chunks/{react-L7NP2D6J.js → react-MRICF5YD.js} +2 -2
  77. package/dist-cli/chunks/record-33ZECMTQ.js +50 -0
  78. package/dist-cli/chunks/runtime-OG4HGCYH.js +2 -0
  79. package/dist-cli/chunks/{runtime-delivery-CWSGC6RY.js → runtime-delivery-KYEJ3C24.js} +2 -2
  80. package/dist-cli/chunks/{screenshot-FAPUEO63.js → screenshot-B6B3CE2W.js} +2 -2
  81. package/dist-cli/chunks/{screenshot-mode-QB7FVHYI.js → screenshot-mode-QVII6GH6.js} +2 -2
  82. package/dist-cli/chunks/{screenshots-XAB5UKQB.js → screenshots-GYQ3JHAW.js} +2 -2
  83. package/dist-cli/chunks/{server-NLNCGLAT.js → server-G4WPXKFR.js} +2 -2
  84. package/dist-cli/chunks/setup-repo-2TQURG52.js +2 -0
  85. package/dist-cli/chunks/{skills-WBR5NZHN.js → skills-RF27H27Y.js} +2 -2
  86. package/dist-cli/chunks/{start-3I5VJI3S.js → start-EBOUYGAP.js} +4 -4
  87. package/dist-cli/chunks/store-FRMH2SYG.js +2 -0
  88. package/dist-cli/chunks/telemetry-EZIRTFFL.js +2 -0
  89. package/dist-cli/chunks/{test-LD2RIFI2.js → test-SATSKLC6.js} +3 -3
  90. package/dist-cli/chunks/{three-mode-5GPHB6BR.js → three-mode-XLTSGRVJ.js} +2 -2
  91. package/dist-cli/chunks/{timeline-AOVC2P3F.js → timeline-ELOCAU3S.js} +2 -2
  92. package/dist-cli/chunks/{upgrade-CU3DMD2C.js → upgrade-2OZLYETX.js} +2 -2
  93. package/dist-cli/chunks/upload-SJCUW6BT.js +2 -0
  94. package/dist-cli/chunks/{web-RNUV6WCK.js → web-YOKL7JUD.js} +2 -2
  95. package/dist-cli/chunks/{what-happened-BSRVVJPQ.js → what-happened-YGFJR2TI.js} +2 -2
  96. package/dist-cli/chunks/{whoami-ZAVHKQPY.js → whoami-GKH3GF3H.js} +2 -2
  97. package/dist-lib/agent-daemon-client.cjs +1 -1
  98. package/dist-lib/agent-events.cjs +1 -1
  99. package/dist-lib/agent-sessions.cjs +1 -1
  100. package/dist-lib/attached-projects.cjs +1 -1
  101. package/dist-lib/auth/shared-session.cjs +1 -1
  102. package/dist-lib/backend-origin.cjs +1 -1
  103. package/dist-lib/bridge-constants.cjs +1 -1
  104. package/dist-lib/cli-constants.cjs +1 -1
  105. package/dist-lib/config.cjs +1 -1
  106. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  107. package/dist-lib/home-paths.cjs +1 -1
  108. package/dist-lib/host/bridge-host.cjs +1 -1
  109. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  110. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  111. package/dist-lib/index.cjs +1 -1
  112. package/dist-lib/metro.cjs +1 -1
  113. package/dist-lib/profiles.cjs +1 -1
  114. package/dist-lib/render-mode.cjs +1 -1
  115. package/dist-lib/vite-base.cjs +1 -1
  116. package/dist-lib/vite.cjs +1 -1
  117. package/package.json +1 -1
  118. package/dist-cli/chunks/auto-bootstrap-JF7VEKGP.js +0 -2
  119. package/dist-cli/chunks/beta-SZGXUHPX.js +0 -2
  120. package/dist-cli/chunks/chunk-CAFGDFEU.js +0 -1
  121. package/dist-cli/chunks/chunk-DAO2KA4O.js +0 -1
  122. package/dist-cli/chunks/chunk-SOKY5FGT.js +0 -1
  123. package/dist-cli/chunks/chunk-U42HSSAI.js +0 -2
  124. package/dist-cli/chunks/chunk-WCMYVXHS.js +0 -2
  125. package/dist-cli/chunks/cli-version-BB3PGPZA.js +0 -2
  126. package/dist-cli/chunks/control-PI6FRLTV.js +0 -2
  127. package/dist-cli/chunks/demo-app-registry-SDP4RWXB.js +0 -2
  128. package/dist-cli/chunks/drivers-BFET7Y5U.js +0 -2
  129. package/dist-cli/chunks/flow-JC7BTILV.js +0 -2
  130. package/dist-cli/chunks/install-AXZ4MKSG.js +0 -2
  131. package/dist-cli/chunks/record-36R7J2BU.js +0 -45
  132. package/dist-cli/chunks/runtime-L2E4XOOB.js +0 -2
  133. package/dist-cli/chunks/setup-repo-XGSB77UN.js +0 -2
  134. package/dist-cli/chunks/store-3LACO57B.js +0 -2
  135. package/dist-cli/chunks/telemetry-6QW73WDZ.js +0 -2
  136. package/dist-cli/chunks/upload-32RTWBK5.js +0 -2
@@ -1,12 +1,12 @@
1
- /*! sootsim v0.1.63 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as G}from"./chunk-2TVSYU32.js";import{a as Le,b as Je}from"./chunk-DFRQMFUV.js";import{a as X,b as C,c as B,d as z,e as de,f as re,g as at,h as lt,i as ke}from"./chunk-4H3UC4KB.js";import{a as Be,h as ce}from"./chunk-5OZ7M24R.js";import{b as ct,c as dt,i as ut}from"./chunk-GICJIXEH.js";import"./chunk-C6UT7L2J.js";import{a as je}from"./chunk-PY25FDGX.js";import{B as se,C as rt,I as it,a as We,b as qe,c as He,d as Ue,e as Ke,f as ze,g as Se,h as ve,m as Ye,n as Ge,o as Xe,p as Ve,q as Qe,r as Ze,s as et,t as tt,u as ot,v as st,z as nt}from"./chunk-B3644N6L.js";import"./chunk-AMZB6WUA.js";import"./chunk-AUMMYIP5.js";import"./chunk-IKFKEII6.js";import"./chunk-CAFGDFEU.js";import"./chunk-EIKREDI4.js";import"./chunk-A3UFHDMY.js";import{a as we,c as xe,d as Oe}from"./chunk-4232ZQOX.js";import{a as Ae}from"./chunk-WCMYVXHS.js";import{c as Re,e as Ee,f as De,g as Ce,h as $e}from"./chunk-4OW4EPBS.js";import{b as Pe}from"./chunk-SSTMIACF.js";import"./chunk-U42HSSAI.js";import"./chunk-QW6P2JE2.js";import"./chunk-INXMOS35.js";import{existsSync as Ht,mkdirSync as Ut,readFileSync as Kt,rmSync as mt,writeFileSync as zt}from"fs";import{tmpdir as Yt}from"os";import{dirname as Gt,join as Xt,resolve as Vt}from"path";var ie=1,Qt="SOOTSIM_INSPECT_NOTICE_PATH",Zt=300*1e3,eo=15e3;function pt(){return Vt(process.env[Qt]||Xt(Yt(),"sootsim-inspect-notice-state.json"))}function to(s,d){return Object.fromEntries(Object.entries(s).filter(([,i])=>typeof i?.signature=="string"&&Number.isFinite(i?.updatedAt)&&d-i.updatedAt<=Zt))}function oo(s){let d=pt();if(!Ht(d))return{version:ie,entries:{}};try{let i=JSON.parse(Kt(d,"utf8"));return i.version!==ie||!i.entries||typeof i.entries!="object"?(mt(d,{force:!0}),{version:ie,entries:{}}):{version:ie,entries:to(i.entries,s)}}catch{return mt(d,{force:!0}),{version:ie,entries:{}}}}function so(s){let d=pt();Ut(Gt(d),{recursive:!0}),zt(d,JSON.stringify(s,null,2)+`
3
- `)}function no(s,d){let i=d.trim()||"default";return`${s}:${i}`}function Te(s,d,i,l={}){let f=l.nowMs??Date.now(),a=l.cooldownMs??eo,y=oo(f),S=no(s,d),T=y.entries[S];return T&&T.signature===i&&f-T.updatedAt<a?!1:(y.entries[S]={signature:i,updatedAt:f},so(y),!0)}async function ft(s,d={args:[]}){let i=await We(s);if(C(d.args)){B(i);return}console.log(` nodes: ${i.nodes}`)}function Me(s,d){let i=s.indexOf(d);return i>=0&&i+1<s.length?s[i+1]:null}async function gt(s){let{bridge:d,args:i,positional:l}=s,f=i.includes("--verbose")||i.includes("-v"),a=C(i),y=f&&!a,S=i.includes("--watch")||i.includes("-w"),T=1e3,k=i.includes("--compact"),h=i.includes("--no-xy"),v=Me(i,"--testid-like"),N=Me(i,"--only"),M=Me(i,"--subtree"),E=l[1],J=E?/[*?]/.test(E):!1,c=!J&&!N?E:void 0,K=N??(J?E:void 0),j=async()=>{await de(d,{verbose:y});let Y=await Ue(d,{describe:!0,verbose:f,filter:c||"",testIdLike:v||void 0,onlyGlob:K||void 0,subtreeRoot:M||void 0,compact:k,hideXy:h}),W=Y?.tree,x=Y?.shell,F=Y?.keyboard;if(a){B({shell:x,tree:W??"",keyboard:F});return}if(x&&typeof x=="object"){let O=[x.state?`state=${x.state}`:null,x.activeApp?`app=${x.activeApp}`:null,x.showSwitcher?"switcher":null,x.switcherPhase&&x.switcherPhase!=="idle"?`phase=${x.switcherPhase}`:null].filter(Boolean);O.length>0&&console.log(` shell: ${O.join(" ")}`)}if(typeof W=="string"&&W.startsWith("__SUBTREE_NOT_FOUND__:")){let O=W.slice(22);console.log(` subtree root not found: ${O}`),G("subtree-root-not-found",O);return}if(!W){let O=Y?.nodeCount??0;console.log(" no matching nodes found"),!(c||v||K||M)&&O<10&&G("app-still-loading",O);return}if(console.log(W),!(c||v||K||M)&&!S&&W.split(`
4
- `).length>=80&&G("describe-use-filters"),F&&F.visible){let O=F.spec,V=[O?.keyboardType?`type=${O.keyboardType}`:null,O?.returnKeyType&&O.returnKeyType!=="default"?`return=${O.returnKeyType}`:null,F.mode!=="letters"?`mode=${F.mode}`:null,F.shifted?"shift":null,F.capsLock?"caps":null,O?.autoCapitalize&&O.autoCapitalize!=="sentences"?`autoCap=${O.autoCapitalize}`:null,F.accessoryBarId?`accessory=${F.accessoryBarId}`:null].filter(Boolean);console.log(`
1
+ /*! sootsim v0.1.64 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as G}from"./chunk-RQHWF2OD.js";import{a as Je,b as We}from"./chunk-SMYSG4VE.js";import{a as X,b as C,c as B,d as z,e as ue,f as re,g as lt,h as ct,i as Te}from"./chunk-E5EWHEA5.js";import{a as je,h as ce}from"./chunk-YGMHOMAJ.js";import{b as dt,c as ut,i as mt}from"./chunk-LKJI7RRW.js";import"./chunk-RKUDWRIN.js";import{a as Le}from"./chunk-T5TDH2UO.js";import{A as rt,C as se,D as it,J as at,a as de,b as qe,c as He,d as Ue,e as Ke,f as ze,g as Ye,h as ve,i as ke,n as Ge,o as Xe,p as Ve,q as Qe,r as Ze,s as et,t as tt,u as ot,v as st,w as nt}from"./chunk-DJIQVKM6.js";import"./chunk-DSLBZC6J.js";import"./chunk-HERZHQFG.js";import"./chunk-X3QWOTLT.js";import"./chunk-XHD3XCT5.js";import"./chunk-2GAZ3JW7.js";import"./chunk-YJIQYIHM.js";import{a as xe,c as $e,d as Pe}from"./chunk-GKUKCZBA.js";import{a as Oe}from"./chunk-WN4XOOK5.js";import{c as Ee,e as De,f as Ce,g as Be,h as Se}from"./chunk-SVT7H2QF.js";import{b as Re}from"./chunk-346HJVD6.js";import"./chunk-OBSMT5TS.js";import"./chunk-WKVIKFMU.js";import"./chunk-J6TCNU6W.js";import{existsSync as Ut,mkdirSync as Kt,readFileSync as zt,rmSync as pt,writeFileSync as Yt}from"fs";import{tmpdir as Gt}from"os";import{dirname as Xt,join as Vt,resolve as Qt}from"path";var ie=1,Zt="SOOTSIM_INSPECT_NOTICE_PATH",eo=300*1e3,to=15e3;function ft(){return Qt(process.env[Zt]||Vt(Gt(),"sootsim-inspect-notice-state.json"))}function oo(s,d){return Object.fromEntries(Object.entries(s).filter(([,a])=>typeof a?.signature=="string"&&Number.isFinite(a?.updatedAt)&&d-a.updatedAt<=eo))}function so(s){let d=ft();if(!Ut(d))return{version:ie,entries:{}};try{let a=JSON.parse(zt(d,"utf8"));return a.version!==ie||!a.entries||typeof a.entries!="object"?(pt(d,{force:!0}),{version:ie,entries:{}}):{version:ie,entries:oo(a.entries,s)}}catch{return pt(d,{force:!0}),{version:ie,entries:{}}}}function no(s){let d=ft();Kt(Xt(d),{recursive:!0}),Yt(d,JSON.stringify(s,null,2)+`
3
+ `)}function ro(s,d){let a=d.trim()||"default";return`${s}:${a}`}function Me(s,d,a,l={}){let g=l.nowMs??Date.now(),i=l.cooldownMs??to,h=so(g),S=ro(s,d),I=h.entries[S];return I&&I.signature===a&&g-I.updatedAt<i?!1:(h.entries[S]={signature:a,updatedAt:g},no(h),!0)}async function gt(s,d={args:[]}){let a=await qe(s);if(C(d.args)){B(a);return}console.log(` nodes: ${a.nodes}`)}function Ie(s,d){let a=s.indexOf(d);return a>=0&&a+1<s.length?s[a+1]:null}async function yt(s){let{bridge:d,args:a,positional:l}=s,g=a.includes("--verbose")||a.includes("-v"),i=C(a),h=g&&!i,S=a.includes("--watch")||a.includes("-w"),I=1e3,k=a.includes("--compact"),b=a.includes("--no-xy"),v=Ie(a,"--testid-like"),F=Ie(a,"--only"),T=Ie(a,"--subtree"),E=l[1],J=E?/[*?]/.test(E):!1,c=!J&&!F?E:void 0,K=F??(J?E:void 0),j=async()=>{await ue(d,{verbose:h});let Y=await Ke(d,{describe:!0,verbose:g,filter:c||"",testIdLike:v||void 0,onlyGlob:K||void 0,subtreeRoot:T||void 0,compact:k,hideXy:b}),W=Y?.tree,x=Y?.shell,N=Y?.keyboard;if(i){B({shell:x,tree:W??"",keyboard:N});return}if(x&&typeof x=="object"){let O=[x.state?`state=${x.state}`:null,x.activeApp?`app=${x.activeApp}`:null,x.showSwitcher?"switcher":null,x.switcherPhase&&x.switcherPhase!=="idle"?`phase=${x.switcherPhase}`:null].filter(Boolean);O.length>0&&console.log(` shell: ${O.join(" ")}`)}if(typeof W=="string"&&W.startsWith("__SUBTREE_NOT_FOUND__:")){let O=W.slice(22);console.log(` subtree root not found: ${O}`),G("subtree-root-not-found",O);return}if(!W){let O=Y?.nodeCount??0;console.log(" no matching nodes found"),!(c||v||K||T)&&O<10&&G("app-still-loading",O);return}if(console.log(W),!(c||v||K||T)&&!S&&W.split(`
4
+ `).length>=80&&G("describe-use-filters"),N&&N.visible){let O=N.spec,V=[O?.keyboardType?`type=${O.keyboardType}`:null,O?.returnKeyType&&O.returnKeyType!=="default"?`return=${O.returnKeyType}`:null,N.mode!=="letters"?`mode=${N.mode}`:null,N.shifted?"shift":null,N.capsLock?"caps":null,O?.autoCapitalize&&O.autoCapitalize!=="sentences"?`autoCap=${O.autoCapitalize}`:null,N.accessoryBarId?`accessory=${N.accessoryBarId}`:null].filter(Boolean);console.log(`
5
5
  keyboard: ${V.join(" ")||"visible"}`)}};if(S)for(console.log(` watching... (Ctrl+C to stop)
6
- `);;)console.clear(),await j(),await X(T);else await j()}var ro=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function yt(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let s of ro){let d=process.env[s];if(d&&d.trim()&&d!=="0")return!0}return!1}async function ht(s){let{bridge:d,args:i,effectiveArgs:l,positional:f,inspectUsage:a}=s,y=x=>{let F=l.indexOf(x);return F>=0&&F+1<l.length?l[F+1]:null},S=x=>l.includes(x),T=y("--testid")||y("--test-id"),k=y("--role"),h=y("--type"),v=y("--text"),N=S("--pressable"),M=S("--visible"),E=S("--interactive-targets")||S("--actions"),J=!T&&!k&&!h&&!v&&!N&&!M&&!E?f[1]:null,c=v??J,K=await ze(d,{testId:T,role:k,type:h,text:c,pressable:N,visible:M,interactive:E});K||(console.error(a("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:j,result:D}=K,Y=C(i),W=i.includes("--verbose")||i.includes("--dump");if(Y)j==="interactive-targets"&&Array.isArray(D)?B(Se(D).map(x=>({...x,tap:ve(x)}))):B(D??null);else if(Array.isArray(D))if(D.length===0){console.log(` no ${j} nodes found`);let x=await d.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof x=="number"&&x<10&&G("app-still-loading",x)}else if(j==="interactive-targets"){let x=Se(D);console.log(` found ${x.length} interactive target${x.length===1?"":"s"} (sorted by score):`);for(let F of x.slice(0,20)){let Z=F.absolutePosition?`@(${Math.round(F.absolutePosition.x)},${Math.round(F.absolutePosition.y)})`:"",O=F.layout?`${Math.round(F.layout.width)}x${Math.round(F.layout.height)}`:"?x?",V=F.text?` "${F.text.slice(0,30)}"`:"",oe=F.testID?` #${F.testID}`:"",ee=F.accessibilityLabel?` \u24D8"${String(F.accessibilityLabel).slice(0,24)}"`:"",ye=F.accessibilityRole?`[${F.accessibilityRole}]`:F.type,he=ve(F);console.log(` ${ye}${V}${ee}${oe} ${O} ${Z}`),console.log(` \u2192 ${he}`),W&&console.log(Ie(JSON.stringify(F,null,2)," "))}x.length>20&&console.log(` ... and ${x.length-20} more`)}else{console.log(` found ${D.length} node${D.length===1?"":"s"} (${j}):`);for(let x of D.slice(0,20)){let F=x.absolutePosition?`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`:"",Z=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",O=x.text?` "${x.text.slice(0,30)}"`:"",V=x.testID?` #${x.testID}`:"",oe=x.pressable?" (tap)":"",ee=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${ee}${O}${V} ${Z} ${F}${oe}`),W&&console.log(Ie(JSON.stringify(x,null,2)," "))}D.length>20&&console.log(` ... and ${D.length-20} more`)}else if(D==null)console.log(` not found: ${c||T||k||h||""||j}`),T&&G("wait-selector-for-missing-testid",T);else{let x=D;if(x.type&&x.absolutePosition){let F=`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`,Z=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",O=x.text?` "${x.text.slice(0,40)}"`:"",V=x.testID?` #${x.testID}`:"",oe=x.pressable?" (tap)":"",ee=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${ee}${O}${V} ${Z} ${F}${oe}`),W&&console.log(Ie(JSON.stringify(x,null,2)," "))}else console.log(JSON.stringify(D,null,2))}}function Ie(s,d){return s.split(`
7
- `).map(i=>d+i).join(`
8
- `)}async function bt(s,d={}){let i=await nt(s);if("error"in i&&(console.error(i.error),process.exit(1)),d.json){console.log(JSON.stringify(i,null,2));return}let{visible:l,spec:f,mode:a,shifted:y,capsLock:S,accessoryBarId:T}=i,k=[];k.push(`keyboard: ${l?"visible":"hidden"}`),f?(k.push(` type: ${f.keyboardType}`),k.push(` returnKey: ${f.returnKeyType}`),k.push(` autoCap: ${f.autoCapitalize}`),k.push(` autoCorrect: ${f.autoCorrect?"on":"off"}`),k.push(` appearance: ${f.keyboardAppearance}`),f.secureTextEntry&&k.push(" secureTextEntry: true"),f.enablesReturnKeyAutomatically&&k.push(` return: ${f.currentTextIsEmpty?"disabled (empty)":"enabled"}`)):k.push(" spec: <none> (shown via dev-tools with no TextInput)"),k.push(` mode: ${a}${y?" (shifted)":""}${S?" (caps)":""}`),T&&k.push(` accessoryBar: ${T}`),console.log(k.join(`
9
- `))}async function wt(s){let d=await s.bridge.listSims();if(C(s.args)){B(d.map(i=>({...i,active:i.id===s.simId})));return}ut(d,s.simId)}function te(s){return s<1024?`${s}B`:s<1024*1024?`${(s/1024).toFixed(1)}KB`:`${(s/1024/1024).toFixed(1)}MB`}function ue(s,d){return d<=0?"?":`${(s/d*100).toFixed(0)}%`}async function xt(s,d={args:[]}){let i=await it(s);if(C(d.args)){B(i);return}if(console.log(" memory:"),i.imageLoader){let l=i.imageLoader;console.log(" image-loader cache"),console.log(` entries: ${l.cacheEntries} / ${l.cacheMaxEntries} (${ue(l.cacheEntries,l.cacheMaxEntries)})`),console.log(` pixel bytes: ${te(l.cachePixelBytes)} / ${te(l.cachePixelBudget)} (${ue(l.cachePixelBytes,l.cachePixelBudget)})`),console.log(` pending: ${l.pendingFetches} fetches, ${l.pendingBytes} bytes`),console.log(` failed uris: ${l.failedUris}`),console.log(` snapshots: ${l.snapshots}`),console.log(` camera frames: ${l.cameraFrames}`)}else console.log(" image-loader cache: not available (engine pre-rebuild?)");if(i.workerHeap){let l=i.workerHeap;console.log(" worker heap (chrome only)"),console.log(` used: ${te(l.usedJSHeapSize)} / ${te(l.jsHeapSizeLimit)} (${ue(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${te(l.totalJSHeapSize)}`)}if(i.hostHeap){let l=i.hostHeap;console.log(" host heap (chrome only)"),console.log(` used: ${te(l.usedJSHeapSize)} / ${te(l.jsHeapSizeLimit)} (${ue(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${te(l.totalJSHeapSize)}`)}}function ae(s){let d=s.indexOf("--testid");if(d>=0&&s[d+1])return{mode:"testid",value:s[d+1]};let i=s.indexOf("--test-id");if(i>=0&&s[i+1])return{mode:"testid",value:s[i+1]};let l=s.indexOf("--text");return l>=0&&s[l+1]?{mode:"text",value:s[l+1]}:null}async function me(s,d){let i=JSON.stringify(d.value),l=d.mode==="testid"?`(await t.findByTestId(${i})) || (await t.findById(${i}))`:`await t.findByText(${i})`;return await s.send({type:"evaluate",code:`(async () => {
6
+ `);;)console.clear(),await j(),await X(I);else await j()}var io=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function ht(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let s of io){let d=process.env[s];if(d&&d.trim()&&d!=="0")return!0}return!1}async function bt(s){let{bridge:d,args:a,effectiveArgs:l,positional:g,inspectUsage:i}=s,h=x=>{let N=l.indexOf(x);return N>=0&&N+1<l.length?l[N+1]:null},S=x=>l.includes(x),I=h("--testid")||h("--test-id"),k=h("--role"),b=h("--type"),v=h("--text"),F=S("--pressable"),T=S("--visible"),E=S("--interactive-targets")||S("--actions"),J=!I&&!k&&!b&&!v&&!F&&!T&&!E?g[1]:null,c=v??J,K=await Ye(d,{testId:I,role:k,type:b,text:c,pressable:F,visible:T,interactive:E});K||(console.error(i("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:j,result:D}=K,Y=C(a),W=a.includes("--verbose")||a.includes("--dump");if(Y)j==="interactive-targets"&&Array.isArray(D)?B(ve(D).map(x=>({...x,tap:ke(x)}))):B(D??null);else if(Array.isArray(D))if(D.length===0){console.log(` no ${j} nodes found`);let x=await d.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof x=="number"&&x<10&&G("app-still-loading",x)}else if(j==="interactive-targets"){let x=ve(D);console.log(` found ${x.length} interactive target${x.length===1?"":"s"} (sorted by score):`);for(let N of x.slice(0,20)){let Z=N.absolutePosition?`@(${Math.round(N.absolutePosition.x)},${Math.round(N.absolutePosition.y)})`:"",O=N.layout?`${Math.round(N.layout.width)}x${Math.round(N.layout.height)}`:"?x?",V=N.text?` "${N.text.slice(0,30)}"`:"",oe=N.testID?` #${N.testID}`:"",ee=N.accessibilityLabel?` \u24D8"${String(N.accessibilityLabel).slice(0,24)}"`:"",he=N.accessibilityRole?`[${N.accessibilityRole}]`:N.type,be=ke(N);console.log(` ${he}${V}${ee}${oe} ${O} ${Z}`),console.log(` \u2192 ${be}`),W&&console.log(Ne(JSON.stringify(N,null,2)," "))}x.length>20&&console.log(` ... and ${x.length-20} more`)}else{console.log(` found ${D.length} node${D.length===1?"":"s"} (${j}):`);for(let x of D.slice(0,20)){let N=x.absolutePosition?`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`:"",Z=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",O=x.text?` "${x.text.slice(0,30)}"`:"",V=x.testID?` #${x.testID}`:"",oe=x.pressable?" (tap)":"",ee=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${ee}${O}${V} ${Z} ${N}${oe}`),W&&console.log(Ne(JSON.stringify(x,null,2)," "))}D.length>20&&console.log(` ... and ${D.length-20} more`)}else if(D==null)console.log(` not found: ${c||I||k||b||""||j}`),I&&G("wait-selector-for-missing-testid",I);else{let x=D;if(x.type&&x.absolutePosition){let N=`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`,Z=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",O=x.text?` "${x.text.slice(0,40)}"`:"",V=x.testID?` #${x.testID}`:"",oe=x.pressable?" (tap)":"",ee=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${ee}${O}${V} ${Z} ${N}${oe}`),W&&console.log(Ne(JSON.stringify(x,null,2)," "))}else console.log(JSON.stringify(D,null,2))}}function Ne(s,d){return s.split(`
7
+ `).map(a=>d+a).join(`
8
+ `)}async function wt(s,d={}){let a=await rt(s);if("error"in a&&(console.error(a.error),process.exit(1)),d.json){console.log(JSON.stringify(a,null,2));return}let{visible:l,spec:g,mode:i,shifted:h,capsLock:S,accessoryBarId:I}=a,k=[];k.push(`keyboard: ${l?"visible":"hidden"}`),g?(k.push(` type: ${g.keyboardType}`),k.push(` returnKey: ${g.returnKeyType}`),k.push(` autoCap: ${g.autoCapitalize}`),k.push(` autoCorrect: ${g.autoCorrect?"on":"off"}`),k.push(` appearance: ${g.keyboardAppearance}`),g.secureTextEntry&&k.push(" secureTextEntry: true"),g.enablesReturnKeyAutomatically&&k.push(` return: ${g.currentTextIsEmpty?"disabled (empty)":"enabled"}`)):k.push(" spec: <none> (shown via dev-tools with no TextInput)"),k.push(` mode: ${i}${h?" (shifted)":""}${S?" (caps)":""}`),I&&k.push(` accessoryBar: ${I}`),console.log(k.join(`
9
+ `))}async function xt(s){let d=await s.bridge.listSims();if(C(s.args)){B(d.map(a=>({...a,active:a.id===s.simId})));return}mt(d,s.simId)}function te(s){return s<1024?`${s}B`:s<1024*1024?`${(s/1024).toFixed(1)}KB`:`${(s/1024/1024).toFixed(1)}MB`}function me(s,d){return d<=0?"?":`${(s/d*100).toFixed(0)}%`}async function $t(s,d={args:[]}){let a=await at(s);if(C(d.args)){B(a);return}if(console.log(" memory:"),a.imageLoader){let l=a.imageLoader;console.log(" image-loader cache"),console.log(` entries: ${l.cacheEntries} / ${l.cacheMaxEntries} (${me(l.cacheEntries,l.cacheMaxEntries)})`),console.log(` pixel bytes: ${te(l.cachePixelBytes)} / ${te(l.cachePixelBudget)} (${me(l.cachePixelBytes,l.cachePixelBudget)})`),console.log(` pending: ${l.pendingFetches} fetches, ${l.pendingBytes} bytes`),console.log(` failed uris: ${l.failedUris}`),console.log(` snapshots: ${l.snapshots}`),console.log(` camera frames: ${l.cameraFrames}`)}else console.log(" image-loader cache: not available (engine pre-rebuild?)");if(a.workerHeap){let l=a.workerHeap;console.log(" worker heap (chrome only)"),console.log(` used: ${te(l.usedJSHeapSize)} / ${te(l.jsHeapSizeLimit)} (${me(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${te(l.totalJSHeapSize)}`)}if(a.hostHeap){let l=a.hostHeap;console.log(" host heap (chrome only)"),console.log(` used: ${te(l.usedJSHeapSize)} / ${te(l.jsHeapSizeLimit)} (${me(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${te(l.totalJSHeapSize)}`)}}function ae(s){let d=s.indexOf("--testid");if(d>=0&&s[d+1])return{mode:"testid",value:s[d+1]};let a=s.indexOf("--test-id");if(a>=0&&s[a+1])return{mode:"testid",value:s[a+1]};let l=s.indexOf("--text");return l>=0&&s[l+1]?{mode:"text",value:s[l+1]}:null}async function pe(s,d){let a=JSON.stringify(d.value),l=d.mode==="testid"?`(await t.findByTestId(${a})) || (await t.findById(${a}))`:`await t.findByText(${a})`;return await s.send({type:"evaluate",code:`(async () => {
10
10
  const t = window.__sootsimTest
11
11
  if (!t) return null
12
12
  const n = ${l}
@@ -28,16 +28,16 @@ import{a as G}from"./chunk-2TVSYU32.js";import{a as Le,b as Je}from"./chunk-DFRQ
28
28
  y: cy,
29
29
  id: n.id ?? null,
30
30
  testID: n.testID ?? null,
31
- text: ${JSON.stringify(d.mode==="text")} ? ${i} : (n.text ?? n.accessibilityLabel ?? null),
31
+ text: ${JSON.stringify(d.mode==="text")} ? ${a} : (n.text ?? n.accessibilityLabel ?? null),
32
32
  type: n.type ?? null,
33
33
  }
34
- })()`})??null}async function $t(s,d={}){let{nav:i,keyboard:l,shell:f}=await rt(s);if(d.json){console.log(JSON.stringify({shell:f??null,nav:i,keyboard:l},null,2));return}let a=[];if(f){let y=f.activeApp??f.state??"<none>",S=f.showSwitcher?" (app switcher open)":"",T=typeof f.launchProgress=="number"&&f.launchProgress<.98?` launching (${Math.round(f.launchProgress*100)}%)`:"";a.push(`shell: ${y}${S}${T}`)}else a.push("shell: <unavailable>");if(i){let y=i.transitionPhase!=="idle"?` (${i.transitionPhase}, ${i.activeTransitionCount} active)`:"";if(a.push(`nav: phase=${i.transitionPhase}${y}`),i.screens.length===0)a.push(" <no registered screens \u2014 app may not use react-native-screens>");else for(let S of i.screens){let T=S.isActive?"\u25B6":" ",k=S.routeName?` ${S.routeName}`:"",h=S.headerHeight>0?` header=${S.headerHeight}`:"",v=S.largeTitleState&&S.largeTitleState!=="expanded"?` large-title=${S.largeTitleState}`:"";a.push(` ${T} #${S.id}${k}${h}${v}`)}}else a.push("nav: <runtime not available>");if(l&&l.visible){let y=l.spec?.keyboardType??"default",S=l.spec?.returnKeyType??"default";a.push(`keyboard: visible (${y}, return=${S}, mode=${l.mode??"?"})`)}else a.push("keyboard: hidden");console.log(a.join(`
35
- `))}async function ne({bridge:s,maxMs:d,pollMs:i=50,stablePolls:l=3,strict:f=!1}){let a=await s.send({type:"evaluate",code:`(async () => {
34
+ })()`})??null}async function St(s,d={}){let{nav:a,keyboard:l,shell:g}=await it(s);if(d.json){console.log(JSON.stringify({shell:g??null,nav:a,keyboard:l},null,2));return}let i=[];if(g){let h=g.activeApp??g.state??"<none>",S=g.showSwitcher?" (app switcher open)":"",I=typeof g.launchProgress=="number"&&g.launchProgress<.98?` launching (${Math.round(g.launchProgress*100)}%)`:"";i.push(`shell: ${h}${S}${I}`)}else i.push("shell: <unavailable>");if(a){let h=a.transitionPhase!=="idle"?` (${a.transitionPhase}, ${a.activeTransitionCount} active)`:"";if(i.push(`nav: phase=${a.transitionPhase}${h}`),a.screens.length===0)i.push(" <no registered screens \u2014 app may not use react-native-screens>");else for(let S of a.screens){let I=S.isActive?"\u25B6":" ",k=S.routeName?` ${S.routeName}`:"",b=S.headerHeight>0?` header=${S.headerHeight}`:"",v=S.largeTitleState&&S.largeTitleState!=="expanded"?` large-title=${S.largeTitleState}`:"";i.push(` ${I} #${S.id}${k}${b}${v}`)}}else i.push("nav: <runtime not available>");if(l&&l.visible){let h=l.spec?.keyboardType??"default",S=l.spec?.returnKeyType??"default";i.push(`keyboard: visible (${h}, return=${S}, mode=${l.mode??"?"})`)}else i.push("keyboard: hidden");console.log(i.join(`
35
+ `))}async function ne({bridge:s,maxMs:d,pollMs:a=50,stablePolls:l=3,strict:g=!1}){let i=await s.send({type:"evaluate",code:`(async () => {
36
36
  const start = Date.now()
37
37
  const deadline = start + ${Math.max(0,Math.round(d))}
38
- const pollMs = ${Math.max(1,Math.round(i))}
38
+ const pollMs = ${Math.max(1,Math.round(a))}
39
39
  const requiredStablePolls = ${Math.max(1,Math.round(l))}
40
- const strict = ${f?"true":"false"}
40
+ const strict = ${g?"true":"false"}
41
41
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
42
42
 
43
43
  // route-aware settle: a tap that pushes/pops a screen is async \u2014 the
@@ -114,12 +114,12 @@ import{a as G}from"./chunk-2TVSYU32.js";import{a as Le,b as Je}from"./chunk-DFRQ
114
114
  await sleep(pollMs)
115
115
  }
116
116
  return { settled: false, elapsed: Date.now() - start }
117
- })()`}),{elapsed:y,settled:S}=a??{};return{elapsed:typeof y=="number"?y:d,settled:S===!0}}async function St(s){let{bridge:d,args:i,positional:l}=s,f=l[1]?Number(l[1])*1e3:3e3,a=i.includes("--strict"),{elapsed:y,settled:S}=await ne({bridge:d,maxMs:f,strict:a});console.log(S?` settled in ${y}ms`:` timed out after ${y}ms (may still be animating)`)}async function vt(s){let d=s.positional[1]?Number(s.positional[1]):.5;(!Number.isFinite(d)||d<0)&&(console.error(s.inspectUsage("sleep","[seconds]")),process.exit(1)),await X(d*1e3),console.log(` slept ${d}s`)}async function kt(s){let{bridge:d,args:i,positional:l}=s,f=l[1]?Number(l[1]):5,{tree:a}=await qe(d,f);if(C(i)){B({depth:f,tree:a??null});return}console.log(typeof a=="string"?a:JSON.stringify(a,null,2))}async function Tt(s,d={args:[]}){let i=await He(s);if(C(d.args)){B(i);return}console.log(i.url)}async function Mt(s){let{wsPort:d,commandTimeoutMs:i,simId:l,simIdSource:f,positional:a}=s,y=a[1]?Number(a[1]):30,S=Math.max(1e3,(Number.isFinite(y)?y:30)*1e3),T=Math.max(1,Math.ceil(S/500));console.log(" waiting for sim reconnect...");let k=await at(d,i,l,{attempts:T,simIdSource:f});k||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),k.bridge.close(),ce({source:"inspect wait",step:{wait:S},summary:`wait ${Math.round(S/1e3)}s`}),console.log(` ready: ${k.count} nodes`)}var It=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function pe(s,d){let i=s.indexOf(d);if(i>=0&&i+1<s.length)return s[i+1]}function io(s,d){if(!d.filter&&!d.equals)return!0;let i=s.data,l=[];if(i&&typeof i=="object")for(let a of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let y=i[a];typeof y=="string"&&y.length>0&&l.push(y)}let f=l.join(" ");return d.equals?l.some(a=>a===d.equals):d.filter?f.toLowerCase().includes(d.filter.toLowerCase()):!0}async function Nt(s){let{bridge:d,args:i,positional:l,inspectUsage:f}=s,a=l[1];a||(console.error(f("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),It.has(a)||console.error(` warning: '${a}' is not a known timeline kind \u2014 waiting anyway. known: ${[...It].sort().join(", ")}`);let y=pe(i,"--max-ms"),S=y&&Number.isFinite(Number(y))?Math.max(100,Number(y)):5e3,T=pe(i,"--filter"),k=pe(i,"--equals"),h=pe(i,"--since")??"now",v=i.includes("--json"),N=Date.now(),M=N+S,E=200,J=N;for(;Date.now()<M;){let K={kinds:[a],since:h==="cursor"?void 0:J,limit:50},j=await d.send({type:"evaluate",code:`(async () => {
117
+ })()`}),{elapsed:h,settled:S}=i??{};return{elapsed:typeof h=="number"?h:d,settled:S===!0}}async function vt(s){let{bridge:d,args:a,positional:l}=s,g=l[1]?Number(l[1])*1e3:3e3,i=a.includes("--strict"),{elapsed:h,settled:S}=await ne({bridge:d,maxMs:g,strict:i});console.log(S?` settled in ${h}ms`:` timed out after ${h}ms (may still be animating)`)}async function kt(s){let d=s.positional[1]?Number(s.positional[1]):.5;(!Number.isFinite(d)||d<0)&&(console.error(s.inspectUsage("sleep","[seconds]")),process.exit(1)),await X(d*1e3),console.log(` slept ${d}s`)}async function Tt(s){let{bridge:d,args:a,positional:l}=s,g=l[1]?Number(l[1]):5,{tree:i}=await He(d,g);if(C(a)){B({depth:g,tree:i??null});return}console.log(typeof i=="string"?i:JSON.stringify(i,null,2))}async function Mt(s,d={args:[]}){let a=await Ue(s);if(C(d.args)){B(a);return}console.log(a.url)}async function It(s){let{wsPort:d,commandTimeoutMs:a,simId:l,simIdSource:g,positional:i}=s,h=i[1]?Number(i[1]):30,S=Math.max(1e3,(Number.isFinite(h)?h:30)*1e3),I=Math.max(1,Math.ceil(S/500));console.log(" waiting for sim reconnect...");let k=await lt(d,a,l,{attempts:I,simIdSource:g});k||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),k.bridge.close(),ce({source:"inspect wait",step:{wait:S},summary:`wait ${Math.round(S/1e3)}s`}),console.log(` ready: ${k.count} nodes`)}var Nt=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function fe(s,d){let a=s.indexOf(d);if(a>=0&&a+1<s.length)return s[a+1]}function ao(s,d){if(!d.filter&&!d.equals)return!0;let a=s.data,l=[];if(a&&typeof a=="object")for(let i of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let h=a[i];typeof h=="string"&&h.length>0&&l.push(h)}let g=l.join(" ");return d.equals?l.some(i=>i===d.equals):d.filter?g.toLowerCase().includes(d.filter.toLowerCase()):!0}async function Ft(s){let{bridge:d,args:a,positional:l,inspectUsage:g}=s,i=l[1];i||(console.error(g("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),Nt.has(i)||console.error(` warning: '${i}' is not a known timeline kind \u2014 waiting anyway. known: ${[...Nt].sort().join(", ")}`);let h=fe(a,"--max-ms"),S=h&&Number.isFinite(Number(h))?Math.max(100,Number(h)):5e3,I=fe(a,"--filter"),k=fe(a,"--equals"),b=fe(a,"--since")??"now",v=a.includes("--json"),F=Date.now(),T=F+S,E=200,J=F;for(;Date.now()<T;){let K={kinds:[i],since:b==="cursor"?void 0:J,limit:50},j=await d.send({type:"evaluate",code:`(async () => {
118
118
  const t = window.SootSim?.bridges?.timeline
119
119
  if (!t) return { ok: false, error: 'timeline bridge missing' }
120
120
  return { ok: true, result: await t.recent(${JSON.stringify(K)}) }
121
- })()`});(!j||!j.ok)&&(console.error(` could not query timeline: ${j&&"error"in j?j.error:"unknown"}`),process.exit(1));let D=j.result.events??[];for(let Y of D)if(io(Y,{filter:T,equals:k})){let W=Date.now()-N;console.log(v?JSON.stringify({found:!0,elapsedMs:W,event:Y}):` ${a} event after ${W}ms${T?` (filter: ${T})`:""}${k?` (equals: ${k})`:""}`);return}j.result.watermark&&j.result.watermark>J&&(J=j.result.watermark),await new Promise(Y=>setTimeout(Y,E))}let c=Date.now()-N;v?console.log(JSON.stringify({found:!1,elapsedMs:c,kind:a,filter:T,equals:k})):console.error(` \u26A0 wait event ${a} timed out after ${c}ms${T?` (filter: ${T})`:""}${k?` (equals: ${k})`:""}`),process.exit(1)}async function Ft(s){let{bridge:d,args:i}=s,l=i.includes("--strict"),f=i.indexOf("--max-ms"),a=f>=0&&i[f+1]?Math.max(100,Number(i[f+1])):3e3,{elapsed:y,settled:S}=await ne({bridge:d,maxMs:a,strict:l});S?console.log(` idle in ${y}ms`):(console.error(` \u26A0 wait idle timed out after ${y}ms (may still be animating)`),process.exit(1))}async function _t(s){let{bridge:d,args:i}=s,l=2e4,f=i.indexOf("--max-ms");f>=0&&i[f+1]&&(l=Math.max(100,Number(i[f+1])));let{ready:a,elapsedMs:y,nodes:S,targets:T,flag:k,loadingText:h,errors:v}=await Ye(d,l);if(a){console.log(` ready in ${y}ms: ${S} nodes, ${T} targets`);return}let N=h?`still showing "${h}"`:k!==!0?"guest app has not emitted sootsim:externalAppReady":T<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing";console.error(` \u26A0 wait ready timed out after ${y}ms \u2014 ${N} (nodes: ${S}, targets: ${T}, errors: ${v})`),process.exit(1)}async function At(s){let{bridge:d,args:i,positional:l,inspectUsage:f}=s,a=l[1];a||(console.error(f("wait selector","<testid> [--max-ms 5000]")),process.exit(1));let y=i.indexOf("--max-ms"),S=y>=0&&i[y+1]?Math.max(100,Number(i[y+1])):5e3,{found:T,node:k,elapsed:h}=await Ge(d,a,S);if(T&&k){let v=k.absolutePosition?`@(${Math.round(k.absolutePosition.x)},${Math.round(k.absolutePosition.y)})`:"",N=k.layout?`${Math.round(k.layout.width)}x${Math.round(k.layout.height)}`:"?x?";console.log(` found #${a} in ${h}ms ${N} ${v}`)}else console.error(` \u26A0 wait selector #${a} timed out after ${h??S}ms`),process.exit(1)}function Ct(s){return s==null?"\u2014":s<1024?`${s}B`:s<1024*1024?`${(s/1024).toFixed(1)}K`:`${(s/1024/1024).toFixed(1)}M`}function Bt(s){return s==null?" \u2026":s<1e3?`${s}ms`.padStart(5):`${(s/1e3).toFixed(2)}s`.padStart(5)}function lo(s){return s.error?"err":s.status==null?" \u2026 ":String(s.status)}function Ot(s){let d=new Date(s.startTs).toLocaleTimeString(),i=lo(s).padEnd(3),l=s.method.padEnd(5),f=Ct(s.size).padStart(6),a=Bt(s.durationMs);console.log(` [${d}] ${i} ${l} ${f} ${a} ${s.displayUrl}`),s.error&&console.log(` error: ${s.error}`)}function co(s){let d=[["id",s.id],["source",s.source],["kind",s.kind],["method",s.method],["status",s.error?`error: ${s.error}`:`${s.status??"\u2014"} ${s.statusText??""}`.trim()],["url",s.url],["started",new Date(s.startTs).toLocaleTimeString()],["duration",Bt(s.durationMs).trim()],["size",Ct(s.size)],["content-type",s.type??"\u2014"]];for(let[i,l]of d)console.log(` ${i.padEnd(13)} ${l}`)}var uo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Pt="\x1B[0m",mo="\x1B[2m";function Rt(s,d){let i=new Date(s.ts).toLocaleTimeString(),l=s.level.toUpperCase().padEnd(5),f=s.args.join(" ");if(d){let a=uo[s.level];console.log(` ${mo}[${i}]${Pt} ${a}${l}${Pt} ${f}`)}else console.log(` [${i}] ${l} ${f}`);if(s.stack&&s.level==="error"){let a=s.stack.split(`
122
- `).slice(0,5);for(let y of a)console.log(` ${y.trim()}`)}}var Q="__sootsimCliPerf",po=120;async function Et(s,d){let i=s.find((N,M)=>s[M-1]==="--id"),l=s.find((N,M)=>s[M-1]==="--text");if(i||l){let N=await d.send({type:"evaluate",code:Le({id:i,text:l})});if(!N)throw new Error(i?`no node with id "${i}"`:`no node matching text "${l}"`);let{x:M,y:E,w:J,h:c}=N;return{x:M,y:E,w:J,h:c}}let f=s.find((N,M)=>s[M-1]==="--area");if(f){let N=f.split(",").map(K=>Number(K.trim()));if(N.length!==4||N.some(K=>!Number.isFinite(K)))throw new Error(`--area expects x,y,w,h (got "${f}")`);let[M,E,J,c]=N;return{x:M,y:E,w:J,h:c}}let a=N=>{let M=s.find((J,c)=>s[c-1]===N);if(M==null)return null;let E=Number(M);return Number.isFinite(E)?E:null},y=a("--x"),S=a("--y"),T=a("--w"),k=a("--h");if(y!=null||S!=null||T!=null||k!=null)return{x:y??0,y:S??0,w:T??1,h:k??1};let v=s.filter((N,M)=>M>0&&!N.startsWith("-")&&s[M-1]!=="--output"&&s[M-1]!=="--area"&&s[M-1]!=="--id"&&s[M-1]!=="--text"&&s[M-1]!=="--x"&&s[M-1]!=="--y"&&s[M-1]!=="--w"&&s[M-1]!=="--h").map(Number).filter(N=>Number.isFinite(N));if(v.length>=2){let[N,M,E=1,J=1]=v;return{x:N,y:M,w:E,h:J}}return null}function Ne(s){let d={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let i of s)i<8?d["<8"]++:i<12?d["8-12"]++:i<16?d["12-16"]++:i<20?d["16-20"]++:i<33?d["20-33"]++:d[">33"]++;console.log(" histogram:");for(let[i,l]of Object.entries(d)){let f="\u2588".repeat(Math.ceil(l/s.length*40));console.log(` ${i.padEnd(6)} ${f} ${l}`)}}async function fe(s,d,i){let l=Date.now()+d,f=await se(s,d);for(;;){if(i(f))return{settled:!0,state:f};if(Date.now()>=l)return{settled:!1,state:f};await X(16),f=await se(s)}}async function _e(s){return s.send({type:"evaluate",code:`(async () => {
121
+ })()`});(!j||!j.ok)&&(console.error(` could not query timeline: ${j&&"error"in j?j.error:"unknown"}`),process.exit(1));let D=j.result.events??[];for(let Y of D)if(ao(Y,{filter:I,equals:k})){let W=Date.now()-F;console.log(v?JSON.stringify({found:!0,elapsedMs:W,event:Y}):` ${i} event after ${W}ms${I?` (filter: ${I})`:""}${k?` (equals: ${k})`:""}`);return}j.result.watermark&&j.result.watermark>J&&(J=j.result.watermark),await new Promise(Y=>setTimeout(Y,E))}let c=Date.now()-F;v?console.log(JSON.stringify({found:!1,elapsedMs:c,kind:i,filter:I,equals:k})):console.error(` \u26A0 wait event ${i} timed out after ${c}ms${I?` (filter: ${I})`:""}${k?` (equals: ${k})`:""}`),process.exit(1)}async function _t(s){let{bridge:d,args:a}=s,l=a.includes("--strict"),g=de(a,3e3),{elapsed:i,settled:h}=await ne({bridge:d,maxMs:g,strict:l});h?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 At(s){let{bridge:d,args:a}=s,l=de(a,2e4),{ready:g,elapsedMs:i,nodes:h,targets:S,flag:I,loadingText:k,errors:b}=await Ge(d,l);if(g){console.log(` ready in ${i}ms: ${h} nodes, ${S} targets`);return}let v=k?`still showing "${k}"`:I!==!0?"guest app has not emitted sootsim:externalAppReady":S<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing";console.error(` \u26A0 wait ready timed out after ${i}ms \u2014 ${v} (nodes: ${h}, targets: ${S}, errors: ${b})`),process.exit(1)}async function Ot(s){let{bridge:d,args:a,positional:l,inspectUsage:g}=s,i=l[1];i||(console.error(g("wait selector","<testid> [--max-ms 5000]")),process.exit(1));let h=a.indexOf("--max-ms"),S=h>=0&&a[h+1]?Math.max(100,Number(a[h+1])):5e3,{found:I,node:k,elapsed:b}=await Xe(d,i,S);if(I&&k){let v=k.absolutePosition?`@(${Math.round(k.absolutePosition.x)},${Math.round(k.absolutePosition.y)})`:"",F=k.layout?`${Math.round(k.layout.width)}x${Math.round(k.layout.height)}`:"?x?";console.log(` found #${i} in ${b}ms ${F} ${v}`)}else console.error(` \u26A0 wait selector #${i} timed out after ${b??S}ms`),process.exit(1)}function Bt(s){return s==null?"\u2014":s<1024?`${s}B`:s<1024*1024?`${(s/1024).toFixed(1)}K`:`${(s/1024/1024).toFixed(1)}M`}function jt(s){return s==null?" \u2026":s<1e3?`${s}ms`.padStart(5):`${(s/1e3).toFixed(2)}s`.padStart(5)}function co(s){return s.error?"err":s.status==null?" \u2026 ":String(s.status)}function Pt(s){let d=new Date(s.startTs).toLocaleTimeString(),a=co(s).padEnd(3),l=s.method.padEnd(5),g=Bt(s.size).padStart(6),i=jt(s.durationMs);console.log(` [${d}] ${a} ${l} ${g} ${i} ${s.displayUrl}`),s.error&&console.log(` error: ${s.error}`)}function uo(s){let d=[["id",s.id],["source",s.source],["kind",s.kind],["method",s.method],["status",s.error?`error: ${s.error}`:`${s.status??"\u2014"} ${s.statusText??""}`.trim()],["url",s.url],["started",new Date(s.startTs).toLocaleTimeString()],["duration",jt(s.durationMs).trim()],["size",Bt(s.size)],["content-type",s.type??"\u2014"]];for(let[a,l]of d)console.log(` ${a.padEnd(13)} ${l}`)}var mo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Rt="\x1B[0m",po="\x1B[2m";function Et(s,d){let a=new Date(s.ts).toLocaleTimeString(),l=s.level.toUpperCase().padEnd(5),g=s.args.join(" ");if(d){let i=mo[s.level];console.log(` ${po}[${a}]${Rt} ${i}${l}${Rt} ${g}`)}else console.log(` [${a}] ${l} ${g}`);if(s.stack&&s.level==="error"){let i=s.stack.split(`
122
+ `).slice(0,5);for(let h of i)console.log(` ${h.trim()}`)}}var Q="__sootsimCliPerf",fo=120;async function Dt(s,d){let a=s.find((F,T)=>s[T-1]==="--id"),l=s.find((F,T)=>s[T-1]==="--text");if(a||l){let F=await d.send({type:"evaluate",code:Je({id:a,text:l})});if(!F)throw new Error(a?`no node with id "${a}"`:`no node matching text "${l}"`);let{x:T,y:E,w:J,h:c}=F;return{x:T,y:E,w:J,h:c}}let g=s.find((F,T)=>s[T-1]==="--area");if(g){let F=g.split(",").map(K=>Number(K.trim()));if(F.length!==4||F.some(K=>!Number.isFinite(K)))throw new Error(`--area expects x,y,w,h (got "${g}")`);let[T,E,J,c]=F;return{x:T,y:E,w:J,h:c}}let i=F=>{let T=s.find((J,c)=>s[c-1]===F);if(T==null)return null;let E=Number(T);return Number.isFinite(E)?E:null},h=i("--x"),S=i("--y"),I=i("--w"),k=i("--h");if(h!=null||S!=null||I!=null||k!=null)return{x:h??0,y:S??0,w:I??1,h:k??1};let v=s.filter((F,T)=>T>0&&!F.startsWith("-")&&s[T-1]!=="--output"&&s[T-1]!=="--area"&&s[T-1]!=="--id"&&s[T-1]!=="--text"&&s[T-1]!=="--x"&&s[T-1]!=="--y"&&s[T-1]!=="--w"&&s[T-1]!=="--h").map(Number).filter(F=>Number.isFinite(F));if(v.length>=2){let[F,T,E=1,J=1]=v;return{x:F,y:T,w:E,h:J}}return null}function Fe(s){let d={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let a of s)a<8?d["<8"]++:a<12?d["8-12"]++:a<16?d["12-16"]++:a<20?d["16-20"]++:a<33?d["20-33"]++:d[">33"]++;console.log(" histogram:");for(let[a,l]of Object.entries(d)){let g="\u2588".repeat(Math.ceil(l/s.length*40));console.log(` ${a.padEnd(6)} ${g} ${l}`)}}async function ge(s,d,a){let l=Date.now()+d,g=await se(s,d);for(;;){if(a(g))return{settled:!0,state:g};if(Date.now()>=l)return{settled:!1,state:g};await X(16),g=await se(s)}}async function Ae(s){return s.send({type:"evaluate",code:`(async () => {
123
123
  const kb = window.__sootsimKeyboard
124
124
  const test = window.__sootsimTest
125
125
  if (!kb) return { error: 'keyboard bridge not available' }
@@ -151,8 +151,8 @@ import{a as G}from"./chunk-2TVSYU32.js";import{a as Le,b as Je}from"./chunk-DFRQ
151
151
  frame: runtimeSnapshot?.keyboard?.frame ?? null,
152
152
  focusedRect: runtimeSnapshot?.focused?.rect ?? null,
153
153
  }
154
- })()`})}async function fo(s,d=600){let i=Date.now()+d;for(;Date.now()<=i;){let l=await _e(s);if(l.visible)return l;await X(30)}return _e(s)}async function ge(s,d){let i=await _e(s);if(i.visible)return i;console.error(` ${d} 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 Dt(s,d,i){return d==="appearance"?s.send({type:"evaluate",code:`(async () => {
155
- const requested = ${JSON.stringify(i??"toggle")}
154
+ })()`})}async function go(s,d=600){let a=Date.now()+d;for(;Date.now()<=a;){let l=await Ae(s);if(l.visible)return l;await X(30)}return Ae(s)}async function ye(s,d){let a=await Ae(s);if(a.visible)return a;console.error(` ${d} 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 Ct(s,d,a){return d==="appearance"?s.send({type:"evaluate",code:`(async () => {
155
+ const requested = ${JSON.stringify(a??"toggle")}
156
156
  const rootBg = (document.documentElement?.style?.background || '').toLowerCase()
157
157
  const inferredCurrent = rootBg.includes('33') ? 'dark' : 'light'
158
158
  let next = requested
@@ -168,25 +168,25 @@ import{a as G}from"./chunk-2TVSYU32.js";import{a as Le,b as Je}from"./chunk-DFRQ
168
168
  })()`}):s.send({type:"evaluate",code:`(async () => {
169
169
  window.dispatchEvent(new CustomEvent(${JSON.stringify(d==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
170
170
  return { ok: true, action: ${JSON.stringify(d)} }
171
- })()`})}function go(s){let d={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(d[s])return d[s];let i=s.match(/^Digit([0-9])$/);if(i)return i[1];let l=s.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function yo(s){if(typeof s!="string")return null;let d=s.replace(/\s+/g," ").trim();return d?d.slice(0,80):null}function jt(...s){for(let d of s){if(typeof d!="string")continue;let i=d.trim();if(i)return i}return null}function ho(s){let d=s.indexOf("--node-id");if(d<0)return null;let i=s[d+1];if(!i)return null;let l=Number(i);return Number.isInteger(l)&&l>0?l:null}async function L(s,d,i){let l=ce({source:s,step:d,summary:i});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 bo(s,d,i){if(!i||i.hit===!1)return null;let l=jt(i.responderTestID,i.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let f=yo(i.text);return f?{step:{tapOn:f},summary:`tap "${f}"`}:{step:{tapAtCoords:{x:s,y:d}},summary:`tap @${Math.round(s)},${Math.round(d)}`}}function Fe(s,d,i){let l=jt(d?.testID,d?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:i==="id"?{step:{tapOn:{id:s}},summary:`tap #${s}`}:{step:{tapOn:s},summary:`tap "${s}"`}}async function Qs(s,d){let i=s[0]==="get"||s[0]==="do"||s[0]==="debug"||s[0]==="wait"?s[0]:null,l=i?s.slice(1):s,f=Re(l,{port:d.port,commandTimeoutMs:d.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--slow","--tail","-f","--interactive-targets","--actions","--internal"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--node-id","--max-ms","--filter","--limit","--level","--threshold","--equals","--since"]}),a=f.positional,y=a[0],S=i==="get"||i==="do"||i==="debug"||i==="wait"?i:"inspect",T=typeof l[0]=="string"&&Oe.has(l[0]),k=T?l[0]:null,h=t=>T&&t===l[0]?`sootsim ${t}`:`sootsim ${S} ${t}`,v=(t,e)=>` usage: ${h(t)}${e?` ${e}`:""}`;if(!y||s.includes("--help")||s.includes("-h")){let t={bridgePort:7668,defaultShellUrl:Ae};if(S==="do"||S==="get"||S==="debug"||S==="wait"){let n=we(S,t);n&&(console.log(`${n}
172
- `),process.exit(0))}if(k==="shell"){let n=xe("shell",t);n&&(console.log(`${n}
173
- `),process.exit(0))}let e=xe("inspect",t),o=["do","get","debug","wait"].map(n=>we(n,t)).filter(n=>n!=null).join(`
171
+ })()`})}function yo(s){let d={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(d[s])return d[s];let a=s.match(/^Digit([0-9])$/);if(a)return a[1];let l=s.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function ho(s){if(typeof s!="string")return null;let d=s.replace(/\s+/g," ").trim();return d?d.slice(0,80):null}function Lt(...s){for(let d of s){if(typeof d!="string")continue;let a=d.trim();if(a)return a}return null}function bo(s){let d=s.indexOf("--node-id");if(d<0)return null;let a=s[d+1];if(!a)return null;let l=Number(a);return Number.isInteger(l)&&l>0?l:null}async function L(s,d,a){let l=ce({source:s,step:d,summary:a});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 wo(s,d,a){if(!a||a.hit===!1)return null;let l=Lt(a.responderTestID,a.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let g=ho(a.text);return g?{step:{tapOn:g},summary:`tap "${g}"`}:{step:{tapAtCoords:{x:s,y:d}},summary:`tap @${Math.round(s)},${Math.round(d)}`}}function _e(s,d,a){let l=Lt(d?.testID,d?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:a==="id"?{step:{tapOn:{id:s}},summary:`tap #${s}`}:{step:{tapOn:s},summary:`tap "${s}"`}}async function en(s,d){let a=s[0]==="get"||s[0]==="do"||s[0]==="debug"||s[0]==="wait"?s[0]:null,l=a?s.slice(1):s,g=Ee(l,{port:d.port,commandTimeoutMs:d.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--slow","--tail","-f","--interactive-targets","--actions","--internal"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--node-id","--max-ms","--filter","--limit","--level","--threshold","--equals","--since"]}),i=g.positional,h=i[0],S=a==="get"||a==="do"||a==="debug"||a==="wait"?a:"inspect",I=typeof l[0]=="string"&&Pe.has(l[0]),k=I?l[0]:null,b=t=>I&&t===l[0]?`sootsim ${t}`:`sootsim ${S} ${t}`,v=(t,e)=>` usage: ${b(t)}${e?` ${e}`:""}`;if(!h||s.includes("--help")||s.includes("-h")){let t={bridgePort:7668,defaultShellUrl:Oe};if(S==="do"||S==="get"||S==="debug"||S==="wait"){let n=xe(S,t);n&&(console.log(`${n}
172
+ `),process.exit(0))}if(k==="shell"){let n=$e("shell",t);n&&(console.log(`${n}
173
+ `),process.exit(0))}let e=$e("inspect",t),o=["do","get","debug","wait"].map(n=>xe(n,t)).filter(n=>n!=null).join(`
174
174
 
175
175
  `);console.log(`${e??""}
176
176
 
177
177
  ${o}
178
- `),process.exit(0)}let N=f.wsPort,M=f.simId,E=f.simIdSource,J=f.commandTimeoutMs;if(y==="list"&&l.some(t=>t==="--drivers"||t==="-D")){let{buildDriverListRows:t}=await import("./drivers-BFET7Y5U.js"),e=t();console.log(` available drivers (${e.length}):
179
- `);let o=Math.max(...e.map(r=>r.id.length),6),n=Math.max(...e.map(r=>r.kind.length),4);for(let r of e){let u=r.available?"\u2713":"\u2717",m=r.id.padEnd(o),w=r.kind.padEnd(n);console.log(` ${u} ${m} ${w} ${r.description}`),r.available&&r.detail?console.log(` ${r.detail}`):!r.available&&r.reason&&console.log(` unavailable: ${r.reason}`)}return}let c=Ee(f),K=M||"default",j=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),D=200;function Y(t){let e=t.replace(/\s+/g," ").trim();if(!e)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(e)){let n=/<title[^>]*>([^<]+)<\/title>/i.exec(t)?.[1]?.trim(),r=/<body[^>]*>([\s\S]*?)<\//i.exec(t)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=n||r||"html error page";return`<html ${t.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return e.length<=D?e:`${e.slice(0,D)}\u2026 (+${e.length-D} more bytes)`}function W(t){let e=t.displayUrl||t.url;return t.status!=null?`${t.method} ${e} -> ${t.status}${t.statusText?` ${t.statusText}`:""}`:t.error?`${t.method} ${e} -> ${t.error}`:`${t.method} ${e}`}async function x(t){let e=yt()?5e3:1500;try{let{settled:o,elapsed:n}=await ne({bridge:t,maxMs:e,pollMs:32,stablePolls:2});o||process.stderr.write(` \u26A0 auto-wait timed out after ${n??e}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
180
- `)}catch{}}async function F(){try{return await c.send({type:"evaluate",code:`(() => ({
178
+ `),process.exit(0)}let F=g.wsPort,T=g.simId,E=g.simIdSource,J=g.commandTimeoutMs;if(h==="list"&&l.some(t=>t==="--drivers"||t==="-D")){let{buildDriverListRows:t}=await import("./drivers-HVKRY4MB.js"),e=t();console.log(` available drivers (${e.length}):
179
+ `);let o=Math.max(...e.map(r=>r.id.length),6),n=Math.max(...e.map(r=>r.kind.length),4);for(let r of e){let u=r.available?"\u2713":"\u2717",m=r.id.padEnd(o),w=r.kind.padEnd(n);console.log(` ${u} ${m} ${w} ${r.description}`),r.available&&r.detail?console.log(` ${r.detail}`):!r.available&&r.reason&&console.log(` unavailable: ${r.reason}`)}return}let c=De(g),K=T||"default",j=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),D=200;function Y(t){let e=t.replace(/\s+/g," ").trim();if(!e)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(e)){let n=/<title[^>]*>([^<]+)<\/title>/i.exec(t)?.[1]?.trim(),r=/<body[^>]*>([\s\S]*?)<\//i.exec(t)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=n||r||"html error page";return`<html ${t.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return e.length<=D?e:`${e.slice(0,D)}\u2026 (+${e.length-D} more bytes)`}function W(t){let e=t.displayUrl||t.url;return t.status!=null?`${t.method} ${e} -> ${t.status}${t.statusText?` ${t.statusText}`:""}`:t.error?`${t.method} ${e} -> ${t.error}`:`${t.method} ${e}`}async function x(t){let e=ht()?5e3:1500;try{let{settled:o,elapsed:n}=await ne({bridge:t,maxMs:e,pollMs:32,stablePolls:2});o||process.stderr.write(` \u26A0 auto-wait timed out after ${n??e}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
180
+ `)}catch{}}async function N(){try{return await c.send({type:"evaluate",code:`(() => ({
181
181
  console: window.__sootsimConsole?.count?.() || null,
182
182
  requests: window.__sootsimTest?.getRequestCounts?.() || null,
183
- }))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function Z(t={}){let e=t.counts!==void 0?t.counts:await z(c,"getRequestCounts");if(!e||typeof e!="object")return;let o=Math.max(0,Number(e.failed)||0);if(o===0||!t.includeTail&&!Te("requests",K,String(o))||(console.log(`
184
- network: ${o} failed request${o===1?"":"s"}`),console.log(` inspect: ${h("requests")} 5`),!t.includeTail))return;let n=await z(c,"getFailedRequests",5);if(!(!Array.isArray(n)||n.length===0)){console.log(`
183
+ }))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function Z(t={}){let e=t.counts!==void 0?t.counts:await z(c,"getRequestCounts");if(!e||typeof e!="object")return;let o=Math.max(0,Number(e.failed)||0);if(o===0||!t.includeTail&&!Me("requests",K,String(o))||(console.log(`
184
+ network: ${o} failed request${o===1?"":"s"}`),console.log(` inspect: ${b("requests")} 5`),!t.includeTail))return;let n=await z(c,"getFailedRequests",5);if(!(!Array.isArray(n)||n.length===0)){console.log(`
185
185
  recent failed requests:
186
- `);for(let r of n){let u=new Date(r.timestamp).toLocaleTimeString();console.log(` [${u}] ${W(r)}`),r.responseBody?console.log(` ${Y(r.responseBody)}`):r.error&&console.log(` ${r.error}`)}}}async function O(t={}){let e=t.counts!==void 0?t.counts:await c.send({type:"evaluate",code:"window.__sootsimConsole?.count?.() || { errors: 0, warnings: 0, total: 0 }"});if(!e||typeof e!="object")return;let o=e,n=Math.max(0,Number(o.errors)||0),r=Math.max(0,Number(o.warnings)||0);if(n===0&&r===0||!t.includeTail&&!Te("console",K,`${n}:${r}`))return;let u=[];if(n>0&&u.push(`${n} console error${n===1?"":"s"}`),r>0&&u.push(`${r} console warning${r===1?"":"s"}`),console.log(`
187
- console: ${u.join(", ")}`),console.log(` inspect: ${h("errors")} 5`),r>0&&console.log(` inspect: ${h("warnings")} 5`),!t.includeTail||n===0)return;let m=await c.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors?.(5) || []"});if(!(!Array.isArray(m)||m.length===0)){console.log(`
186
+ `);for(let r of n){let u=new Date(r.timestamp).toLocaleTimeString();console.log(` [${u}] ${W(r)}`),r.responseBody?console.log(` ${Y(r.responseBody)}`):r.error&&console.log(` ${r.error}`)}}}async function O(t={}){let e=t.counts!==void 0?t.counts:await c.send({type:"evaluate",code:"window.__sootsimConsole?.count?.() || { errors: 0, warnings: 0, total: 0 }"});if(!e||typeof e!="object")return;let o=e,n=Math.max(0,Number(o.errors)||0),r=Math.max(0,Number(o.warnings)||0);if(n===0&&r===0||!t.includeTail&&!Me("console",K,`${n}:${r}`))return;let u=[];if(n>0&&u.push(`${n} console error${n===1?"":"s"}`),r>0&&u.push(`${r} console warning${r===1?"":"s"}`),console.log(`
187
+ console: ${u.join(", ")}`),console.log(` inspect: ${b("errors")} 5`),r>0&&console.log(` inspect: ${b("warnings")} 5`),!t.includeTail||n===0)return;let m=await c.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors?.(5) || []"});if(!(!Array.isArray(m)||m.length===0)){console.log(`
188
188
  recent console errors:
189
- `);for(let w of m){let g=new Date(w.timestamp).toLocaleTimeString(),$=Array.isArray(w.args)?w.args.map(_=>typeof _=="object"?JSON.stringify(_):String(_)).join(" "):String(w);console.log(` [${g}] ${$}`)}}}let V=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function oe(t){let e=Pe(),o=null;try{o=await Ce(t,`(() => {
189
+ `);for(let w of m){let f=new Date(w.timestamp).toLocaleTimeString(),$=Array.isArray(w.args)?w.args.map(_=>typeof _=="object"?JSON.stringify(_):String(_)).join(" "):String(w);console.log(` [${f}] ${$}`)}}}let V=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function oe(t){let e=Re(),o=null;try{o=await Be(t,`(() => {
190
190
  const tl = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.timeline
191
191
  if (!tl || typeof tl.summary !== 'function') return null
192
192
  const cursorKey = ${JSON.stringify(e)}
@@ -202,9 +202,9 @@ ${o}
202
202
  }
203
203
  }
204
204
  return summary ? { summary, consoleSplit } : null
205
- })()`)}catch{return}if(!o||!o.summary||!o.summary.total)return;let n=o.summary.byKind??{},r=[],u=new Set;for(let m of V){let w=n[m];if(w)if(u.add(m),m==="console"&&o.consoleSplit){let{error:g,warn:$}=o.consoleSplit;g>0&&r.push(`${g} error${g===1?"":"s"}`),$>0&&r.push(`${$} warning${$===1?"":"s"}`)}else r.push(`${w} ${m}${w===1?"":"s"}`)}for(let[m,w]of Object.entries(n))!u.has(m)&&w&&r.push(`${w} ${m}${w===1?"":"s"}`);if(r.length!==0&&(console.log(`
206
- since last: ${r.join(" \xB7 ")} \u2014 sootsim what-happened`),o.summary.lastAt))try{await $e(t,"SootSim.bridges.timeline.cursorAdvance",e,o.summary.lastAt)}catch{}}let ee=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"]),ye=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"]),he=(s.includes("--verbose")||s.includes("-v"))&&!s.includes("--json");S==="do"&&y==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),ee.has(y)&&await De(c),ye.has(y)&&await de(c,{verbose:he});try{switch(y){case"list":{await wt({bridge:c,simId:M,args:l});break}case"tree":{await kt({bridge:c,args:l,positional:a});break}case"a11y":{let t=await Ke(c);if(!Array.isArray(t)||t.length===0){console.log(" no accessible nodes found");break}if(s.includes("--json"))console.log(JSON.stringify(t,null,2));else{console.log(` accessibility tree (${t.length} nodes):
207
- `);for(let e of t){let o=[];if(o.push(`[${e.role}]`),e.label){let n=e.label.length>50?e.label.slice(0,47)+"...":e.label;o.push(`"${n}"`)}if(e.hint&&o.push(`(hint: "${e.hint}")`),e.testID&&o.push(`#${e.testID}`),e.state){let n=[];e.state.disabled&&n.push("disabled"),e.state.selected&&n.push("selected"),e.state.checked===!0&&n.push("checked"),e.state.checked==="mixed"&&n.push("mixed"),e.state.busy&&n.push("busy"),e.state.expanded===!0&&n.push("expanded"),e.state.expanded===!1&&n.push("collapsed"),n.length&&o.push(`{${n.join(", ")}}`)}e.position&&o.push(`@(${e.position.x},${e.position.y})`),e.size&&o.push(`${e.size.w}x${e.size.h}`),console.log(" "+o.join(" "))}}break}case"find":{await ht({bridge:c,args:s,effectiveArgs:l,positional:a,inspectUsage:v});break}case"count":{await ft(c,{args:l});break}case"keyboard":{await bt(c,{json:s.includes("--json")});break}case"screens":{await $t(c,{json:s.includes("--json")});break}case"memory":{await xt(c,{args:l});break}case"wait":{await Mt({wsPort:N,commandTimeoutMs:J,simId:M,simIdSource:E,positional:a});break}case"sleep":{await vt({positional:a,inspectUsage:v});break}case"settle":{await St({bridge:c,args:s,positional:a});break}case"ready":{await _t({bridge:c,args:s});break}case"idle":{await Ft({bridge:c,args:s,positional:a});break}case"selector":{await At({bridge:c,args:s,positional:a,inspectUsage:v});break}case"event":{await Nt({bridge:c,args:s,positional:a,inspectUsage:v});break}case"layout":{let t=a[1];t||(console.error(v("layout","<id>")),process.exit(1));let e=await c.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(t)}))()`});console.log(JSON.stringify(e,null,2));break}case"capture":case"screenshot":{let e=s.find((w,g)=>s[g-1]==="--output")||"/tmp/sootsim-inspect.png",o=await Et(s,c),n={type:"screenshot"};o&&(n.crop=o);let u=(await c.send(n)).replace(/^data:image\/png;base64,/,"");o&&console.log(` area: x=${o.x} y=${o.y} w=${o.w} h=${o.h}`),(await import("fs")).writeFileSync(e,Buffer.from(u,"base64")),console.log(` saved: ${e}`);break}case"sample-color":{let t=await Et(s,c);t||(console.error(v("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 e=await c.send({type:"evaluate",code:Je(t)});if(s.includes("--json"))console.log(JSON.stringify(e,null,2));else{let{r:o,g:n,b:r,a:u,hex:m,samples:w}=e,g=t.w===1&&t.h===1?`@(${t.x},${t.y})`:`@(${t.x},${t.y}) ${t.w}x${t.h}`;console.log(` ${m} rgba(${o}, ${n}, ${r}, ${u}) ${g} ${w} samples`)}break}case"node":{let t=a[1];t||(console.error(v("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let e=await c.send({type:"evaluate",code:`(async () => {
205
+ })()`)}catch{return}if(!o||!o.summary||!o.summary.total)return;let n=o.summary.byKind??{},r=[],u=new Set;for(let m of V){let w=n[m];if(w)if(u.add(m),m==="console"&&o.consoleSplit){let{error:f,warn:$}=o.consoleSplit;f>0&&r.push(`${f} error${f===1?"":"s"}`),$>0&&r.push(`${$} warning${$===1?"":"s"}`)}else r.push(`${w} ${m}${w===1?"":"s"}`)}for(let[m,w]of Object.entries(n))!u.has(m)&&w&&r.push(`${w} ${m}${w===1?"":"s"}`);if(r.length!==0&&(console.log(`
206
+ since last: ${r.join(" \xB7 ")} \u2014 sootsim what-happened`),o.summary.lastAt))try{await Se(t,"SootSim.bridges.timeline.cursorAdvance",e,o.summary.lastAt)}catch{}}let ee=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"]),he=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"]),be=(s.includes("--verbose")||s.includes("-v"))&&!s.includes("--json");S==="do"&&h==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),ee.has(h)&&await Ce(c),he.has(h)&&await ue(c,{verbose:be});try{switch(h){case"list":{await xt({bridge:c,simId:T,args:l});break}case"tree":{await Tt({bridge:c,args:l,positional:i});break}case"a11y":{let t=await ze(c);if(!Array.isArray(t)||t.length===0){console.log(" no accessible nodes found");break}if(s.includes("--json"))console.log(JSON.stringify(t,null,2));else{console.log(` accessibility tree (${t.length} nodes):
207
+ `);for(let e of t){let o=[];if(o.push(`[${e.role}]`),e.label){let n=e.label.length>50?e.label.slice(0,47)+"...":e.label;o.push(`"${n}"`)}if(e.hint&&o.push(`(hint: "${e.hint}")`),e.testID&&o.push(`#${e.testID}`),e.state){let n=[];e.state.disabled&&n.push("disabled"),e.state.selected&&n.push("selected"),e.state.checked===!0&&n.push("checked"),e.state.checked==="mixed"&&n.push("mixed"),e.state.busy&&n.push("busy"),e.state.expanded===!0&&n.push("expanded"),e.state.expanded===!1&&n.push("collapsed"),n.length&&o.push(`{${n.join(", ")}}`)}e.position&&o.push(`@(${e.position.x},${e.position.y})`),e.size&&o.push(`${e.size.w}x${e.size.h}`),console.log(" "+o.join(" "))}}break}case"find":{await bt({bridge:c,args:s,effectiveArgs:l,positional:i,inspectUsage:v});break}case"count":{await gt(c,{args:l});break}case"keyboard":{await wt(c,{json:s.includes("--json")});break}case"screens":{await St(c,{json:s.includes("--json")});break}case"memory":{await $t(c,{args:l});break}case"wait":{await It({wsPort:F,commandTimeoutMs:J,simId:T,simIdSource:E,positional:i});break}case"sleep":{await kt({positional:i,inspectUsage:v});break}case"settle":{await vt({bridge:c,args:s,positional:i});break}case"ready":{await At({bridge:c,args:s});break}case"idle":{await _t({bridge:c,args:s,positional:i});break}case"selector":{await Ot({bridge:c,args:s,positional:i,inspectUsage:v});break}case"event":{await Ft({bridge:c,args:s,positional:i,inspectUsage:v});break}case"layout":{let t=i[1];t||(console.error(v("layout","<id>")),process.exit(1));let e=await c.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(t)}))()`});console.log(JSON.stringify(e,null,2));break}case"capture":case"screenshot":{let e=s.find((w,f)=>s[f-1]==="--output")||"/tmp/sootsim-inspect.png",o=await Dt(s,c),n={type:"screenshot"};o&&(n.crop=o);let u=(await c.send(n)).replace(/^data:image\/png;base64,/,"");o&&console.log(` area: x=${o.x} y=${o.y} w=${o.w} h=${o.h}`),(await import("fs")).writeFileSync(e,Buffer.from(u,"base64")),console.log(` saved: ${e}`);break}case"sample-color":{let t=await Dt(s,c);t||(console.error(v("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 e=await c.send({type:"evaluate",code:We(t)});if(s.includes("--json"))console.log(JSON.stringify(e,null,2));else{let{r:o,g:n,b:r,a:u,hex:m,samples:w}=e,f=t.w===1&&t.h===1?`@(${t.x},${t.y})`:`@(${t.x},${t.y}) ${t.w}x${t.h}`;console.log(` ${m} rgba(${o}, ${n}, ${r}, ${u}) ${f} ${w} samples`)}break}case"node":{let t=i[1];t||(console.error(v("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let e=await c.send({type:"evaluate",code:`(async () => {
208
208
  const t = window.__sootsimTest
209
209
  const q = ${JSON.stringify(t)}
210
210
  let node = null
@@ -260,20 +260,20 @@ ${o}
260
260
  transform,
261
261
  parentChain,
262
262
  }
263
- })()`});console.log(JSON.stringify(e,null,2));break}case"tap":{let t=Number(a[1]),e=Number(a[2]),o=ae(s),n=null;if(o){let m=await me(c,o);m||(console.error(` not found: ${o.value}`),o.mode==="testid"&&G("wait-selector-for-missing-testid",o.value),process.exit(1)),t=m.x,e=m.y,n=m}(!Number.isFinite(t)||!Number.isFinite(e))&&(console.error(v("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let r=await c.send({type:"tap",x:t,y:e,...o?{target:{id:n?.id??(o.mode==="testid"?o.value:null),testID:n?.testID??(o.mode==="testid"?o.value:null),text:n?.text??(o.mode==="text"?o.value:null),type:n?.type??null}}:{}}),u=bo(t,e,r);u&&await L("inspect tap",u.step,u.summary),console.log(JSON.stringify(r,null,2));break}case"drag":case"swipe":{let t=Number(a[1]),e=Number(a[2]),o=Number(a[3]),n=Number(a[4]),r=y==="swipe"?10:12,u=y==="swipe"?8:16,m=a[5]?Number(a[5]):r,w=a[6]?Number(a[6]):u;(!Number.isFinite(t)||!Number.isFinite(e)||!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(m)||!Number.isFinite(w))&&(console.error(v(y,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let g=await c.send({type:"evaluate",code:`(async () => {
263
+ })()`});console.log(JSON.stringify(e,null,2));break}case"tap":{let t=Number(i[1]),e=Number(i[2]),o=ae(s),n=null;if(o){let m=await pe(c,o);m||(console.error(` not found: ${o.value}`),o.mode==="testid"&&G("wait-selector-for-missing-testid",o.value),process.exit(1)),t=m.x,e=m.y,n=m}(!Number.isFinite(t)||!Number.isFinite(e))&&(console.error(v("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let r=await c.send({type:"tap",x:t,y:e,...o?{target:{id:n?.id??(o.mode==="testid"?o.value:null),testID:n?.testID??(o.mode==="testid"?o.value:null),text:n?.text??(o.mode==="text"?o.value:null),type:n?.type??null}}:{}}),u=wo(t,e,r);u&&await L("inspect tap",u.step,u.summary),console.log(JSON.stringify(r,null,2));break}case"drag":case"swipe":{let t=Number(i[1]),e=Number(i[2]),o=Number(i[3]),n=Number(i[4]),r=h==="swipe"?10:12,u=h==="swipe"?8:16,m=i[5]?Number(i[5]):r,w=i[6]?Number(i[6]):u;(!Number.isFinite(t)||!Number.isFinite(e)||!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(m)||!Number.isFinite(w))&&(console.error(v(h,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await c.send({type:"evaluate",code:`(async () => {
264
264
  const interact = window.__sootsimInteract
265
265
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
266
266
  const value = await interact.drag(${t}, ${e}, ${o}, ${n}, ${Math.max(1,Math.round(m))}, ${Math.max(0,Math.round(w))})
267
267
  return { ok: !!value, value }
268
- })()`});if(g?.ok){let $=Math.max(1,Math.round(Math.max(1,m)*Math.max(0,w)));await L(`inspect ${y}`,{swipe:{start:`${t}, ${e}`,end:`${o}, ${n}`,duration:$}},`${y} ${t},${e} -> ${o},${n}`)}console.log(JSON.stringify(g,null,2));break}case"pinch":{let t=Number(a[1]),e=Number(a[2]),o=Number(a[3]),n=Number(a[4]),r=Number(a[5]),u=Number(a[6]),m=Number(a[7]),w=Number(a[8]),g=a[9]?Number(a[9]):12,$=a[10]?Number(a[10]):16;(!Number.isFinite(t)||!Number.isFinite(e)||!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(u)||!Number.isFinite(m)||!Number.isFinite(w)||!Number.isFinite(g)||!Number.isFinite($))&&(console.error(v("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let _=await c.send({type:"evaluate",code:`(async () => {
268
+ })()`});if(f?.ok){let $=Math.max(1,Math.round(Math.max(1,m)*Math.max(0,w)));await L(`inspect ${h}`,{swipe:{start:`${t}, ${e}`,end:`${o}, ${n}`,duration:$}},`${h} ${t},${e} -> ${o},${n}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let t=Number(i[1]),e=Number(i[2]),o=Number(i[3]),n=Number(i[4]),r=Number(i[5]),u=Number(i[6]),m=Number(i[7]),w=Number(i[8]),f=i[9]?Number(i[9]):12,$=i[10]?Number(i[10]):16;(!Number.isFinite(t)||!Number.isFinite(e)||!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(u)||!Number.isFinite(m)||!Number.isFinite(w)||!Number.isFinite(f)||!Number.isFinite($))&&(console.error(v("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let _=await c.send({type:"evaluate",code:`(async () => {
269
269
  const interact = window.__sootsimInteract
270
270
  if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
271
- const value = await interact.pinch(${t}, ${e}, ${o}, ${n}, ${r}, ${u}, ${m}, ${w}, ${Math.max(1,Math.round(g))}, ${Math.max(0,Math.round($))})
271
+ const value = await interact.pinch(${t}, ${e}, ${o}, ${n}, ${r}, ${u}, ${m}, ${w}, ${Math.max(1,Math.round(f))}, ${Math.max(0,Math.round($))})
272
272
  return { ok: !!value, value }
273
- })()`});_?.ok&&await L("inspect pinch",{pinch:{from:[t,e,o,n],to:[r,u,m,w],steps:Math.max(1,Math.round(g)),stepMs:Math.max(0,Math.round($))}},`pinch (${t},${e}) (${o},${n}) -> (${r},${u}) (${m},${w})`),console.log(JSON.stringify(_,null,2));break}case"tap-text":{let t=a[1];t||(console.error(v("tap-text","<text>")),process.exit(1));let e=R=>{let A=s.indexOf(R);return A>=0&&A+1<s.length?s[A+1]:null},o=R=>s.includes(R),n=e("--nth")??e("--index"),r=n!==null?Number(n):null;r!==null&&!Number.isFinite(r)&&(console.error(` --nth/--index requires an integer, got: ${n}`),process.exit(1));let u=e("--within"),m=e("--role"),w=o("--exact"),g=o("--first"),$=e("--min-y"),_=e("--max-y"),q=e("--min-x"),H=e("--max-x");for(let[R,A]of[["--min-y",$],["--max-y",_],["--min-x",q],["--max-x",H]])A!==null&&!Number.isFinite(Number(A))&&(console.error(` ${R} requires a number, got: ${A}`),process.exit(1));let U=s.indexOf("--near"),I=null;if(U>=0){let R=Number(s[U+1]),A=Number(s[U+2]);(!Number.isFinite(R)||!Number.isFinite(A))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),I={x:R,y:A}}let b=JSON.stringify({query:t,exact:w,role:m,within:u,minX:q!==null?Number(q):null,maxX:H!==null?Number(H):null,minY:$!==null?Number($):null,maxY:_!==null?Number(_):null,near:I,nth:r,first:g}),p=await c.send({type:"evaluate",code:`(async () => {
273
+ })()`});_?.ok&&await L("inspect pinch",{pinch:{from:[t,e,o,n],to:[r,u,m,w],steps:Math.max(1,Math.round(f)),stepMs:Math.max(0,Math.round($))}},`pinch (${t},${e}) (${o},${n}) -> (${r},${u}) (${m},${w})`),console.log(JSON.stringify(_,null,2));break}case"tap-text":{let t=i[1];t||(console.error(v("tap-text","<text>")),process.exit(1));let e=R=>{let A=s.indexOf(R);return A>=0&&A+1<s.length?s[A+1]:null},o=R=>s.includes(R),n=e("--nth")??e("--index"),r=n!==null?Number(n):null;r!==null&&!Number.isFinite(r)&&(console.error(` --nth/--index requires an integer, got: ${n}`),process.exit(1));let u=e("--within"),m=e("--role"),w=o("--exact"),f=o("--first"),$=e("--min-y"),_=e("--max-y"),q=e("--min-x"),H=e("--max-x");for(let[R,A]of[["--min-y",$],["--max-y",_],["--min-x",q],["--max-x",H]])A!==null&&!Number.isFinite(Number(A))&&(console.error(` ${R} requires a number, got: ${A}`),process.exit(1));let U=s.indexOf("--near"),M=null;if(U>=0){let R=Number(s[U+1]),A=Number(s[U+2]);(!Number.isFinite(R)||!Number.isFinite(A))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),M={x:R,y:A}}let y=JSON.stringify({query:t,exact:w,role:m,within:u,minX:q!==null?Number(q):null,maxX:H!==null?Number(H):null,minY:$!==null?Number($):null,maxY:_!==null?Number(_):null,near:M,nth:r,first:f}),p=await c.send({type:"evaluate",code:`(async () => {
274
274
  const t = window.__sootsimTest
275
275
  if (!t) return { error: 'bridge-not-ready' }
276
- const F = ${b}
276
+ const F = ${y}
277
277
 
278
278
  const res = await t.queryTextCandidates({
279
279
  query: F.query,
@@ -390,7 +390,7 @@ ${o}
390
390
  total,
391
391
  idx,
392
392
  }
393
- })()`});if(p?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),p?.ambiguous){let R=p.candidates;console.error(` ambiguous: ${p.total} matches for "${t}"`);for(let A of R){let be=A.abs?`@(${Math.round(A.abs.x)},${Math.round(A.abs.y)})`:"",le=A.layout?` ${A.layout.width}x${A.layout.height}`:"",Lt=A.testID?` #${A.testID}`:"",Jt=A.text?` "${A.text}"`:"",Wt=A.ancestorTestIDs.length>0?` within ${A.ancestorTestIDs.slice(0,3).map(qt=>`#${qt}`).join(" > ")}`:"";console.error(` [${A.idx}] <${A.type}>${Jt}${Lt} ${be}${le}${Wt}`)}p.total>R.length&&console.error(` ... and ${p.total-R.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)}p?.nthOutOfRange&&(console.error(` not found: nth ${p.nth} of ${p.total} match${p.total===1?"":"es"} for "${t}"`),process.exit(1)),(!p||typeof p.cx!="number")&&(console.error(` not found: ${t}`),process.exit(1));let P=await c.send({type:"tap",x:p.cx,y:p.cy,target:{id:p.target?.id??null,testID:p.target?.testID??null,text:t,type:p.target?.type??null}});if(P?.hit!==!1&&P?.ok!==!1){let R=Fe(t,{id:p.target?.id??null,testID:p.target?.testID??null,type:p.target?.type??null,cx:p.cx,cy:p.cy},"text");await L("inspect tap-text",R.step,R.summary)}console.log(JSON.stringify({matched:p.match,tapped:{nodeId:p.target?.nodeId??null,id:p.target?.id??null,testID:p.target?.testID??null,type:p.target?.type??null,cx:p.cx,cy:p.cy},...p.strategy&&p.strategy!=="matched-node"?{strategy:p.strategy}:{},...p.total>1||r!==null?{nth:{index:p.idx,total:p.total}}:{},result:P},null,2));break}case"tap-best":{let t=a[1];t||(console.error(v("tap-best","<query>")),process.exit(1));let e=JSON.stringify(t),o=await c.send({type:"evaluate",code:`(async () => {
393
+ })()`});if(p?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),p?.ambiguous){let R=p.candidates;console.error(` ambiguous: ${p.total} matches for "${t}"`);for(let A of R){let we=A.abs?`@(${Math.round(A.abs.x)},${Math.round(A.abs.y)})`:"",le=A.layout?` ${A.layout.width}x${A.layout.height}`:"",Jt=A.testID?` #${A.testID}`:"",Wt=A.text?` "${A.text}"`:"",qt=A.ancestorTestIDs.length>0?` within ${A.ancestorTestIDs.slice(0,3).map(Ht=>`#${Ht}`).join(" > ")}`:"";console.error(` [${A.idx}] <${A.type}>${Wt}${Jt} ${we}${le}${qt}`)}p.total>R.length&&console.error(` ... and ${p.total-R.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)}p?.nthOutOfRange&&(console.error(` not found: nth ${p.nth} of ${p.total} match${p.total===1?"":"es"} for "${t}"`),process.exit(1)),(!p||typeof p.cx!="number")&&(console.error(` not found: ${t}`),process.exit(1));let P=await c.send({type:"tap",x:p.cx,y:p.cy,target:{id:p.target?.id??null,testID:p.target?.testID??null,text:t,type:p.target?.type??null}});if(P?.hit!==!1&&P?.ok!==!1){let R=_e(t,{id:p.target?.id??null,testID:p.target?.testID??null,type:p.target?.type??null,cx:p.cx,cy:p.cy},"text");await L("inspect tap-text",R.step,R.summary)}console.log(JSON.stringify({matched:p.match,tapped:{nodeId:p.target?.nodeId??null,id:p.target?.id??null,testID:p.target?.testID??null,type:p.target?.type??null,cx:p.cx,cy:p.cy},...p.strategy&&p.strategy!=="matched-node"?{strategy:p.strategy}:{},...p.total>1||r!==null?{nth:{index:p.idx,total:p.total}}:{},result:P},null,2));break}case"tap-best":{let t=i[1];t||(console.error(v("tap-best","<query>")),process.exit(1));let e=JSON.stringify(t),o=await c.send({type:"evaluate",code:`(async () => {
394
394
  const t = window.__sootsimTest
395
395
  if (!t) return { error: 'bridge-not-ready' }
396
396
  // try testID first \u2014 strongest signal of "this is the
@@ -431,7 +431,7 @@ ${o}
431
431
  }
432
432
  }
433
433
  return { strategy: 'none' }
434
- })()`});"error"in o&&(console.error(` ${o.error}`),process.exit(1)),o.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${t}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1));let n=o.node,r=n.absolutePosition.x+n.layout.width/2,u=n.absolutePosition.y+n.layout.height/2,m=await c.send({type:"tap",x:r,y:u,target:{id:n.id,testID:n.testID,text:o.strategy==="text"?t:null,type:n.type}});if(m?.hit!==!1&&m?.ok!==!1){let w=Fe(t,{id:n.id,testID:n.testID,type:n.type,cx:r,cy:u},o.strategy==="testid"?"id":"text");await L("inspect tap-best",w.step,w.summary)}console.log(JSON.stringify({matched:{strategy:o.strategy,nodeId:n.nodeId,id:n.id,testID:n.testID,type:n.type,text:n.text},tapped:{cx:r,cy:u},result:m},null,2));break}case"tap-id":{let t=a[1];t||(console.error(v("tap-id","<id>")),process.exit(1));let e=JSON.stringify(t),o=await c.send({type:"evaluate",code:`(async () => {
434
+ })()`});"error"in o&&(console.error(` ${o.error}`),process.exit(1)),o.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${t}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1));let n=o.node,r=n.absolutePosition.x+n.layout.width/2,u=n.absolutePosition.y+n.layout.height/2,m=await c.send({type:"tap",x:r,y:u,target:{id:n.id,testID:n.testID,text:o.strategy==="text"?t:null,type:n.type}});if(m?.hit!==!1&&m?.ok!==!1){let w=_e(t,{id:n.id,testID:n.testID,type:n.type,cx:r,cy:u},o.strategy==="testid"?"id":"text");await L("inspect tap-best",w.step,w.summary)}console.log(JSON.stringify({matched:{strategy:o.strategy,nodeId:n.nodeId,id:n.id,testID:n.testID,type:n.type,text:n.text},tapped:{cx:r,cy:u},result:m},null,2));break}case"tap-id":{let t=i[1];t||(console.error(v("tap-id","<id>")),process.exit(1));let e=JSON.stringify(t),o=await c.send({type:"evaluate",code:`(async () => {
435
435
  const t = window.__sootsimTest
436
436
  if (!t) return null
437
437
  const n = (await t.findByTestId(${e})) || (await t.findById(${e}))
@@ -473,7 +473,7 @@ ${o}
473
473
  },
474
474
  strategy: (resolved && resolved.strategy) || 'matched-node',
475
475
  }
476
- })()`});(!o||typeof o.cx!="number")&&(console.error(` not found: ${t}`),process.exit(1));let n=await c.send({type:"tap",x:o.cx,y:o.cy,target:{id:o.target?.id??o.match?.id??null,testID:o.target?.testID??o.match?.testID??null,text:o.target?.text??o.target?.accessibilityLabel??o.match?.text??o.match?.accessibilityLabel??null,type:o.target?.type??o.match?.type??null}});if(n?.hit!==!1&&n?.ok!==!1){let r=Fe(t,{id:o.target?.id??null,testID:o.target?.testID??null,type:o.target?.type??null,cx:o.cx,cy:o.cy},"id");await L("inspect tap-id",r.step,r.summary)}console.log(JSON.stringify({matched:o.match,tapped:{nodeId:o.target?.nodeId??null,id:o.target?.id??null,testID:o.target?.testID??null,type:o.target?.type??null,cx:o.cx,cy:o.cy},...o.strategy&&o.strategy!=="matched-node"?{strategy:o.strategy}:{},result:n},null,2));break}case"type-into":{let t=a[1],e=a.slice(2).join(" ");(!t||!e)&&(console.error(v("type-into","<id> <text>")),process.exit(1));let o=JSON.stringify(t),n=await c.send({type:"evaluate",code:`(async () => {
476
+ })()`});(!o||typeof o.cx!="number")&&(console.error(` not found: ${t}`),process.exit(1));let n=await c.send({type:"tap",x:o.cx,y:o.cy,target:{id:o.target?.id??o.match?.id??null,testID:o.target?.testID??o.match?.testID??null,text:o.target?.text??o.target?.accessibilityLabel??o.match?.text??o.match?.accessibilityLabel??null,type:o.target?.type??o.match?.type??null}});if(n?.hit!==!1&&n?.ok!==!1){let r=_e(t,{id:o.target?.id??null,testID:o.target?.testID??null,type:o.target?.type??null,cx:o.cx,cy:o.cy},"id");await L("inspect tap-id",r.step,r.summary)}console.log(JSON.stringify({matched:o.match,tapped:{nodeId:o.target?.nodeId??null,id:o.target?.id??null,testID:o.target?.testID??null,type:o.target?.type??null,cx:o.cx,cy:o.cy},...o.strategy&&o.strategy!=="matched-node"?{strategy:o.strategy}:{},result:n},null,2));break}case"type-into":{let t=i[1],e=i.slice(2).join(" ");(!t||!e)&&(console.error(v("type-into","<id> <text>")),process.exit(1));let o=JSON.stringify(t),n=await c.send({type:"evaluate",code:`(async () => {
477
477
  const t = window.__sootsimTest
478
478
  if (!t) return null
479
479
  const n = await (t.findByTestId(${o}) || t.findById(${o}))
@@ -487,7 +487,7 @@ ${o}
487
487
  isTextInput: !!n.isTextInput,
488
488
  placeholder: n.placeholder || null,
489
489
  }
490
- })()`});(!n||typeof n.cx!="number")&&(console.error(` not found: ${t}`),process.exit(1)),n.isTextInput||console.error(` warning: ${t} is not a text input (isTextInput: false)`);let r=await c.send({type:"tap",x:n.cx,y:n.cy,target:{id:n.id??t,testID:n.testID??t,text:null,type:n.type??null}}),u=await fo(c);u.visible||(console.error(` keyboard did not open after tapping ${t}`),process.exit(1));let m=u.focusedInput;m&&(m.testID===t||m.id===t||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(t)} but focus is on ${JSON.stringify(m.testID??m.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await c.send({type:"keyboard",action:"type",text:e}),await L("inspect type-into",{tapOn:{id:t},inputText:e},`type-into #${t} ${JSON.stringify(e)}`),console.log(JSON.stringify({target:t,isTextInput:n.isTextInput,keyboardOpened:u.visible??r?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:e},null,2));break}case"type":{let t=a.slice(1).join(" ");t||(console.error(v("type","<text>")),process.exit(1)),await ge(c,"type"),await c.send({type:"keyboard",action:"type",text:t}),await L("inspect type",{inputText:t},`type ${JSON.stringify(t)}`),console.log(` typed: ${JSON.stringify(t)}`);break}case"key":{let t=a[1];t||(console.error(v("key","<name>")),process.exit(1)),await ge(c,"key"),await c.send({type:"keyboard",action:"press",text:t}),await L("inspect key",{pressKey:t},`key ${t}`),console.log(` pressed: ${t}`);break}case"key-sequence":{let t=a.slice(1);t.length===0&&(console.error(v("key-sequence","<key> [<key> ...]")),process.exit(1)),await ge(c,"key-sequence");for(let e of t)await c.send({type:"keyboard",action:"press",text:e});await L("inspect key-sequence",{pressKey:t.join(" ")},`key-sequence ${t.join(" ")}`),console.log(` pressed: ${t.join(", ")}`);break}case"keycode":{let t=a.slice(1);t.length===0&&(console.error(v("keycode","<code> [<code> ...]")),process.exit(1));let e=t.map(n=>({code:n,key:go(n)})),o=e.filter(n=>!n.key);o.length>0&&(console.error(` unsupported keycode(s): ${o.map(n=>n.code).join(", ")}`),process.exit(1)),await ge(c,"keycode");for(let n of e)await c.send({type:"keyboard",action:"press",text:n.key});await L("inspect keycode",{pressKey:e.map(n=>n.key).join(" ")},`keycode ${t.join(" ")}`),console.log(` pressed: ${t.join(", ")}`);break}case"dispatch":{let t=a[1];t||(console.error(v("dispatch","<char>")),process.exit(1)),await c.send({type:"keyboard",action:"dispatchKey",text:t}),await L("inspect dispatch",{dispatchKey:t},`dispatch ${JSON.stringify(t)}`),console.log(` dispatched: ${t}`);break}case"dismiss":{await c.send({type:"keyboard",action:"dismiss"}),await L("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let t=Number(a[1]),e=Number(a[2]),o=ae(s);if(o){let m=await me(c,o);m||(console.error(` not found: ${o.value}`),o.mode==="testid"&&G("wait-selector-for-missing-testid",o.value),process.exit(1)),t=m.x,e=m.y}let n=a[3]?Number(a[3]):80;(!Number.isFinite(t)||!Number.isFinite(e)||!Number.isFinite(n))&&(console.error(v("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let r=Math.max(0,Math.round(n)),u=await c.send({type:"evaluate",code:`(async () => {
490
+ })()`});(!n||typeof n.cx!="number")&&(console.error(` not found: ${t}`),process.exit(1)),n.isTextInput||console.error(` warning: ${t} is not a text input (isTextInput: false)`);let r=await c.send({type:"tap",x:n.cx,y:n.cy,target:{id:n.id??t,testID:n.testID??t,text:null,type:n.type??null}}),u=await go(c);u.visible||(console.error(` keyboard did not open after tapping ${t}`),process.exit(1));let m=u.focusedInput;m&&(m.testID===t||m.id===t||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(t)} but focus is on ${JSON.stringify(m.testID??m.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await c.send({type:"keyboard",action:"type",text:e}),await L("inspect type-into",{tapOn:{id:t},inputText:e},`type-into #${t} ${JSON.stringify(e)}`),console.log(JSON.stringify({target:t,isTextInput:n.isTextInput,keyboardOpened:u.visible??r?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:e},null,2));break}case"type":{let t=i.slice(1).join(" ");t||(console.error(v("type","<text>")),process.exit(1)),await ye(c,"type"),await c.send({type:"keyboard",action:"type",text:t}),await L("inspect type",{inputText:t},`type ${JSON.stringify(t)}`),console.log(` typed: ${JSON.stringify(t)}`);break}case"key":{let t=i[1];t||(console.error(v("key","<name>")),process.exit(1)),await ye(c,"key"),await c.send({type:"keyboard",action:"press",text:t}),await L("inspect key",{pressKey:t},`key ${t}`),console.log(` pressed: ${t}`);break}case"key-sequence":{let t=i.slice(1);t.length===0&&(console.error(v("key-sequence","<key> [<key> ...]")),process.exit(1)),await ye(c,"key-sequence");for(let e of t)await c.send({type:"keyboard",action:"press",text:e});await L("inspect key-sequence",{pressKey:t.join(" ")},`key-sequence ${t.join(" ")}`),console.log(` pressed: ${t.join(", ")}`);break}case"keycode":{let t=i.slice(1);t.length===0&&(console.error(v("keycode","<code> [<code> ...]")),process.exit(1));let e=t.map(n=>({code:n,key:yo(n)})),o=e.filter(n=>!n.key);o.length>0&&(console.error(` unsupported keycode(s): ${o.map(n=>n.code).join(", ")}`),process.exit(1)),await ye(c,"keycode");for(let n of e)await c.send({type:"keyboard",action:"press",text:n.key});await L("inspect keycode",{pressKey:e.map(n=>n.key).join(" ")},`keycode ${t.join(" ")}`),console.log(` pressed: ${t.join(", ")}`);break}case"dispatch":{let t=i[1];t||(console.error(v("dispatch","<char>")),process.exit(1)),await c.send({type:"keyboard",action:"dispatchKey",text:t}),await L("inspect dispatch",{dispatchKey:t},`dispatch ${JSON.stringify(t)}`),console.log(` dispatched: ${t}`);break}case"dismiss":{await c.send({type:"keyboard",action:"dismiss"}),await L("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let t=Number(i[1]),e=Number(i[2]),o=ae(s);if(o){let m=await pe(c,o);m||(console.error(` not found: ${o.value}`),o.mode==="testid"&&G("wait-selector-for-missing-testid",o.value),process.exit(1)),t=m.x,e=m.y}let n=i[3]?Number(i[3]):80;(!Number.isFinite(t)||!Number.isFinite(e)||!Number.isFinite(n))&&(console.error(v("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let r=Math.max(0,Math.round(n)),u=await c.send({type:"evaluate",code:`(async () => {
491
491
  const interact = window.__sootsimInteract
492
492
  if (interact?.doubleTap) {
493
493
  return {
@@ -510,18 +510,18 @@ ${o}
510
510
  first,
511
511
  second,
512
512
  }
513
- })()`});u?.ok&&await L("inspect double-tap",{doubleTapAtCoords:{x:t,y:e,gapMs:r}},`double-tap @${t},${e}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let t=Number(a[1]),e=Number(a[2]),o=ae(s);if(o){let u=await me(c,o);u||(console.error(` not found: ${o.value}`),o.mode==="testid"&&G("wait-selector-for-missing-testid",o.value),process.exit(1)),t=u.x,e=u.y}let n=a[3]?Number(a[3]):600;(!Number.isFinite(t)||!Number.isFinite(e)||!Number.isFinite(n))&&(console.error(v("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let r=await c.send({type:"evaluate",code:`(async () => {
513
+ })()`});u?.ok&&await L("inspect double-tap",{doubleTapAtCoords:{x:t,y:e,gapMs:r}},`double-tap @${t},${e}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let t=Number(i[1]),e=Number(i[2]),o=ae(s);if(o){let u=await pe(c,o);u||(console.error(` not found: ${o.value}`),o.mode==="testid"&&G("wait-selector-for-missing-testid",o.value),process.exit(1)),t=u.x,e=u.y}let n=i[3]?Number(i[3]):600;(!Number.isFinite(t)||!Number.isFinite(e)||!Number.isFinite(n))&&(console.error(v("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let r=await c.send({type:"evaluate",code:`(async () => {
514
514
  const interact = window.__sootsimInteract
515
515
  if (!interact?.longPress) return { ok: false, reason: 'no interact.longPress' }
516
516
  const value = await interact.longPress(${t}, ${e}, ${Math.max(0,Math.round(n))})
517
517
  return { ok: !!value, value }
518
- })()`});r?.ok&&await L("inspect long-press",{tapAtCoords:{x:t,y:e}},`long-press @${t},${e}`),console.log(JSON.stringify(r,null,2));break}case"touch":{let t=a[1],e=Number(a[2]),o=Number(a[3]),n=a[4]?Number(a[4]):999,r=t==="down"?"touchDown":t==="move"?"touchMove":t==="up"?"touchUp":t==="cancel"?"touchCancel":null;r||(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),t!=="cancel"&&(!Number.isFinite(e)||!Number.isFinite(o))&&(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let u=t==="down"?"tap":t==="move"?"move":null,m=u&&Number.isFinite(e)&&Number.isFinite(o)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${e}, y: ${o} } }));`:"",w=await c.send({type:"evaluate",code:`(async () => {
518
+ })()`});r?.ok&&await L("inspect long-press",{tapAtCoords:{x:t,y:e}},`long-press @${t},${e}`),console.log(JSON.stringify(r,null,2));break}case"touch":{let t=i[1],e=Number(i[2]),o=Number(i[3]),n=i[4]?Number(i[4]):999,r=t==="down"?"touchDown":t==="move"?"touchMove":t==="up"?"touchUp":t==="cancel"?"touchCancel":null;r||(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),t!=="cancel"&&(!Number.isFinite(e)||!Number.isFinite(o))&&(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let u=t==="down"?"tap":t==="move"?"move":null,m=u&&Number.isFinite(e)&&Number.isFinite(o)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${e}, y: ${o} } }));`:"",w=await c.send({type:"evaluate",code:`(async () => {
519
519
  ${m}
520
520
  const interact = window.__sootsimInteract
521
521
  if (!interact?.${r}) return { ok: false, reason: 'no interact.${r}' }
522
522
  const value = ${t==="cancel"?`await interact.${r}(${Math.max(1,Math.round(n))})`:`await interact.${r}(${e}, ${o}, ${Math.max(1,Math.round(n))})`}
523
523
  return { ok: !!value, value }
524
- })()`});w?.ok&&t!=="cancel"&&await L("inspect touch",{tapAtCoords:{x:e,y:o}},`touch ${t} @${e},${o}`),console.log(JSON.stringify(w,null,2));break}case"gesture":{let t=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],e=a[1],o=a[2]?Number(a[2]):220;(!e||!Number.isFinite(o))&&(console.error(v("gesture","<preset> [durationMs]")),console.error(` presets: ${t.join(", ")}`),process.exit(1)),t.includes(e)||(console.error(` unknown gesture preset: ${e}`),console.error(` presets: ${t.join(", ")}`),process.exit(1));let n=await c.send({type:"evaluate",code:`(async () => {
524
+ })()`});w?.ok&&t!=="cancel"&&await L("inspect touch",{tapAtCoords:{x:e,y:o}},`touch ${t} @${e},${o}`),console.log(JSON.stringify(w,null,2));break}case"gesture":{let t=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],e=i[1],o=i[2]?Number(i[2]):220;(!e||!Number.isFinite(o))&&(console.error(v("gesture","<preset> [durationMs]")),console.error(` presets: ${t.join(", ")}`),process.exit(1)),t.includes(e)||(console.error(` unknown gesture preset: ${e}`),console.error(` presets: ${t.join(", ")}`),process.exit(1));let n=await c.send({type:"evaluate",code:`(async () => {
525
525
  const spec = globalThis.__sootsimDeviceSpec || {}
526
526
  return {
527
527
  width: spec.width || window.innerWidth || 393,
@@ -529,12 +529,12 @@ ${o}
529
529
  statusBarHeight: spec.statusBarHeight || 0,
530
530
  homeIndicatorHeight: spec.homeIndicatorHeight || 0,
531
531
  }
532
- })()`}),r=Number(n?.width)||393,u=Number(n?.height)||852,m=Number(n?.statusBarHeight)||0,w=Number(n?.homeIndicatorHeight)||0,g=Math.round(r/2),$=Math.round(u/2),_=Math.max(24,m+18),q=Math.max(24,w+18),H=18,U=Math.min(220,Math.round(u*.24)),I=Math.min(180,Math.round(r*.32)),b=g,p=$,P=g,R=$;switch(e){case"scroll-up":p=$+Math.round(U/2),R=$-Math.round(U/2);break;case"scroll-down":p=$-Math.round(U/2),R=$+Math.round(U/2);break;case"scroll-left":b=g+Math.round(I/2),P=g-Math.round(I/2);break;case"scroll-right":b=g-Math.round(I/2),P=g+Math.round(I/2);break;case"swipe-from-left-edge":b=H,p=$,P=Math.min(r-H,H+I);break;case"swipe-from-right-edge":b=r-H,p=$,P=Math.max(H,r-H-I);break;case"swipe-from-top-edge":b=g,p=_,R=Math.min(u-q,_+U);break;case"swipe-from-bottom-edge":b=g,p=u-q,R=Math.max(_,u-q-U);break}let A=Math.max(8,Math.round(o/16)),be=Math.max(1,Math.round(o/A)),le=await c.send({type:"evaluate",code:`(async () => {
532
+ })()`}),r=Number(n?.width)||393,u=Number(n?.height)||852,m=Number(n?.statusBarHeight)||0,w=Number(n?.homeIndicatorHeight)||0,f=Math.round(r/2),$=Math.round(u/2),_=Math.max(24,m+18),q=Math.max(24,w+18),H=18,U=Math.min(220,Math.round(u*.24)),M=Math.min(180,Math.round(r*.32)),y=f,p=$,P=f,R=$;switch(e){case"scroll-up":p=$+Math.round(U/2),R=$-Math.round(U/2);break;case"scroll-down":p=$-Math.round(U/2),R=$+Math.round(U/2);break;case"scroll-left":y=f+Math.round(M/2),P=f-Math.round(M/2);break;case"scroll-right":y=f-Math.round(M/2),P=f+Math.round(M/2);break;case"swipe-from-left-edge":y=H,p=$,P=Math.min(r-H,H+M);break;case"swipe-from-right-edge":y=r-H,p=$,P=Math.max(H,r-H-M);break;case"swipe-from-top-edge":y=f,p=_,R=Math.min(u-q,_+U);break;case"swipe-from-bottom-edge":y=f,p=u-q,R=Math.max(_,u-q-U);break}let A=Math.max(8,Math.round(o/16)),we=Math.max(1,Math.round(o/A)),le=await c.send({type:"evaluate",code:`(async () => {
533
533
  const interact = window.__sootsimInteract
534
534
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
535
- const value = await interact.drag(${b}, ${p}, ${P}, ${R}, ${A}, ${be})
535
+ const value = await interact.drag(${y}, ${p}, ${P}, ${R}, ${A}, ${we})
536
536
  return { ok: !!value, value }
537
- })()`});le?.ok&&await L("inspect gesture",{swipe:{start:`${b}, ${p}`,end:`${P}, ${R}`,duration:Math.max(1,Math.round(o))}},`gesture ${e}`),console.log(JSON.stringify({preset:e,from:{x:b,y:p},to:{x:P,y:R},result:le},null,2));break}case"scroll":{let t=ae(s),e=ho(s),o=t?.mode==="testid"?t.value:e==null?a[1]:null,n=t||e!=null?1:2,r=Number(a[n]),u=Number(a[n+1]);(!o&&e==null||!Number.isFinite(r)||!Number.isFinite(u))&&(console.error(v("scroll","<id> <x> <y> | --testid <id> <x> <y> | --node-id <nodeId> <x> <y>")),process.exit(1));let m=await c.send({type:"evaluate",code:`(async () => {
537
+ })()`});le?.ok&&await L("inspect gesture",{swipe:{start:`${y}, ${p}`,end:`${P}, ${R}`,duration:Math.max(1,Math.round(o))}},`gesture ${e}`),console.log(JSON.stringify({preset:e,from:{x:y,y:p},to:{x:P,y:R},result:le},null,2));break}case"scroll":{let t=ae(s),e=bo(s),o=t?.mode==="testid"?t.value:e==null?i[1]:null,n=t||e!=null?1:2,r=Number(i[n]),u=Number(i[n+1]);(!o&&e==null||!Number.isFinite(r)||!Number.isFinite(u))&&(console.error(v("scroll","<id> <x> <y> | --testid <id> <x> <y> | --node-id <nodeId> <x> <y>")),process.exit(1));let m=await c.send({type:"evaluate",code:`(async () => {
538
538
  const t = window.__sootsimTest
539
539
  if (!t) return null
540
540
  const n = ${e!=null?`await t.inspectByNodeId(${JSON.stringify(e)})`:`await t.findByTestId(${JSON.stringify(o)})
@@ -544,11 +544,11 @@ ${o}
544
544
  cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
545
545
  cy: n.absolutePosition.y + (n.layout.height || 0) / 2,
546
546
  }
547
- })()`}),w=await z(c,"scrollTo",e!=null?{nodeId:e}:o,r,u,!1);if(w?.ok){let g=e!=null?`node ${e}`:`#${o}`;await L("inspect scroll",{scrollTo:{...e!=null?{nodeId:e}:{id:o},x:r,y:u}},`scroll ${g} -> ${r},${u}`)}console.log(JSON.stringify({...w,...m?{at:{x:m.cx,y:m.cy}}:{}},null,2));break}case"state":{let t=a[1];if(i==="get"&&!t){let o=await z(c,"getRuntimeState"),n=await c.send({type:"evaluate",code:`({
547
+ })()`}),w=await z(c,"scrollTo",e!=null?{nodeId:e}:o,r,u,!1);if(w?.ok){let f=e!=null?`node ${e}`:`#${o}`;await L("inspect scroll",{scrollTo:{...e!=null?{nodeId:e}:{id:o},x:r,y:u}},`scroll ${f} -> ${r},${u}`)}console.log(JSON.stringify({...w,...m?{at:{x:m.cx,y:m.cy}}:{}},null,2));break}case"state":{let t=i[1];if(a==="get"&&!t){let o=await z(c,"getRuntimeState"),n=await c.send({type:"evaluate",code:`({
548
548
  errors: window.__sootsimConsole?.getErrors?.()?.length ?? 0,
549
549
  warnings: window.__sootsimConsole?.getWarnings?.()?.length ?? 0,
550
550
  })`});if(o&&typeof o=="object"&&o.diagnostics&&(o.diagnostics.errors=n?.errors??0,o.diagnostics.warnings=n?.warnings??0),o&&typeof o=="object"&&o.shell==null)try{let r=await se(c);r&&(o.shell=r)}catch{}console.log(JSON.stringify(o,null,2));break}if(!t||t==="--help"||t==="-h"){console.log(`
551
- ${h("state")} \u2014 dump raw runtime state
551
+ ${b("state")} \u2014 dump raw runtime state
552
552
 
553
553
  subcommands:
554
554
  shell dump shell transition/layout state
@@ -562,15 +562,15 @@ ${o}
562
562
  gesture <x> <y> dump gesture routing/debug info at coordinates
563
563
 
564
564
  examples:
565
- ${h("state")} shell
566
- ${h("state")} worker
567
- ${h("state")} keyboard
568
- ${h("state")} ownership
569
- ${h("state")} node photos
570
- ${h("state")} scroll feed
571
- ${h("state")} scroll-hit 360 420
572
- ${h("state")} hit 200 720
573
- `);break}let e;switch(t){case"shell":e=await se(c,500);break;case"worker":e=await $e(c,"__sootsimRenderHost.queryStats");break;case"ownership":e=await c.send({type:"evaluate",code:`(() => {
565
+ ${b("state")} shell
566
+ ${b("state")} worker
567
+ ${b("state")} keyboard
568
+ ${b("state")} ownership
569
+ ${b("state")} node photos
570
+ ${b("state")} scroll feed
571
+ ${b("state")} scroll-hit 360 420
572
+ ${b("state")} hit 200 720
573
+ `);break}let e;switch(t){case"shell":e=await se(c,500);break;case"worker":e=await Se(c,"__sootsimRenderHost.queryStats");break;case"ownership":e=await c.send({type:"evaluate",code:`(() => {
574
574
  const h = window.__sootsimRenderHost
575
575
  if (!h || typeof h.getOwnershipSnapshot !== 'function') {
576
576
  return { error: 'getOwnershipSnapshot not available' }
@@ -601,8 +601,8 @@ ${o}
601
601
  text: focused.text || null,
602
602
  } : null,
603
603
  }
604
- })()`});break;case"node":{let o=a[2];o||(console.error(` usage: ${h("state")} node <id>`),process.exit(1)),e=await z(c,"findByTestId",o)||await z(c,"findById",o);break}case"scroll":{let o=a[2];o||(console.error(` usage: ${h("state")} scroll <id>`),process.exit(1)),e=await z(c,"getScrollState",o);break}case"scroll-hit":{let o=Number(a[2]),n=Number(a[3]);(!Number.isFinite(o)||!Number.isFinite(n))&&(console.error(` usage: ${h("state")} scroll-hit <x> <y>`),process.exit(1)),e=await z(c,"getScrollStateAt",o,n);break}case"hit":{let o=Number(a[2]),n=Number(a[3]);(!Number.isFinite(o)||!Number.isFinite(n))&&(console.error(` usage: ${h("state")} hit <x> <y>`),process.exit(1)),e=await z(c,"debugHitAt",o,n);break}case"gesture":{let o=Number(a[2]),n=Number(a[3]);(!Number.isFinite(o)||!Number.isFinite(n))&&(console.error(` usage: ${h("state")} gesture <x> <y>`),process.exit(1)),e=await z(c,"debugGestureAt",o,n);break}default:console.error(` unknown state subcommand: ${t}`),process.exit(1)}console.log(JSON.stringify(e,null,2));break}case"shell":{let t=a[1];if(!t||t==="--help"||t==="-h"){console.log(`
605
- ${h("shell")} \u2014 run built-in shell commands
604
+ })()`});break;case"node":{let o=i[2];o||(console.error(` usage: ${b("state")} node <id>`),process.exit(1)),e=await z(c,"findByTestId",o)||await z(c,"findById",o);break}case"scroll":{let o=i[2];o||(console.error(` usage: ${b("state")} scroll <id>`),process.exit(1)),e=await z(c,"getScrollState",o);break}case"scroll-hit":{let o=Number(i[2]),n=Number(i[3]);(!Number.isFinite(o)||!Number.isFinite(n))&&(console.error(` usage: ${b("state")} scroll-hit <x> <y>`),process.exit(1)),e=await z(c,"getScrollStateAt",o,n);break}case"hit":{let o=Number(i[2]),n=Number(i[3]);(!Number.isFinite(o)||!Number.isFinite(n))&&(console.error(` usage: ${b("state")} hit <x> <y>`),process.exit(1)),e=await z(c,"debugHitAt",o,n);break}case"gesture":{let o=Number(i[2]),n=Number(i[3]);(!Number.isFinite(o)||!Number.isFinite(n))&&(console.error(` usage: ${b("state")} gesture <x> <y>`),process.exit(1)),e=await z(c,"debugGestureAt",o,n);break}default:console.error(` unknown state subcommand: ${t}`),process.exit(1)}console.log(JSON.stringify(e,null,2));break}case"shell":{let t=i[1];if(!t||t==="--help"||t==="-h"){console.log(`
605
+ ${b("shell")} \u2014 run built-in shell commands
606
606
 
607
607
  subcommands:
608
608
  launch <appId> [waitMs] [--clear-state]
@@ -617,15 +617,15 @@ ${o}
617
617
  shake trigger the simulator shake gesture
618
618
 
619
619
  examples:
620
- ${h("shell")} launch photos
621
- ${h("shell")} launch rn --clear-state
622
- ${h("shell")} launch photos 1500
623
- ${h("shell")} home 500
624
- ${h("shell")} switcher 800
625
- ${h("shell")} open-card clock 800
626
- ${h("shell")} appearance dark
627
- ${h("shell")} lock
628
- `);break}let e=t==="launch"||t==="open-card"||t==="home"||t==="switcher",o=t==="launch"||t==="open-card"?a[3]:a[2],n=o?Number(o):350;e&&(!Number.isFinite(n)||n<0)&&(console.error(v("shell",t==="launch"||t==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let r=!1,u=!1,m=null,w=s.includes("--clear-state");if(t==="launch"){let g=a[2];g||(console.error(v("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),w&&await c.send({type:"evaluate",code:Be}),r=!!await re(c,"launchApp",n,g),{settled:u,state:m}=await fe(c,Math.round(n),$=>!!$&&$.state==="app"&&$.activeApp===g&&$.showSwitcher===!1&&$.switcherPhase==="idle"&&typeof $.launchProgress=="number"&&$.launchProgress>=.98),r&&await L("inspect shell launch",w?{launchApp:{clearState:!0}}:{launchApp:{}},w?"launch app (clear state)":"launch app")}else if(t==="home")r=!!await re(c,"goHome",n),{settled:u,state:m}=await fe(c,Math.round(n),g=>!!g&&g.state==="home"&&g.activeApp==null&&g.showSwitcher===!1&&g.switcherPhase==="idle"&&typeof g.launchProgress=="number"&&g.launchProgress>=.98);else if(t==="switcher")r=!!await re(c,"openSwitcher",n),{settled:u,state:m}=await fe(c,Math.round(n),g=>!!g&&g.state==="app"&&g.showSwitcher===!0&&g.switcherPhase==="idle"&&typeof g.zoomLevel=="number"&&Math.abs(g.zoomLevel)<=.02&&typeof g.horizontalZoom=="number"&&Math.abs(g.horizontalZoom)<=.02),u&&(await X(po),m=await se(c));else if(t==="open-card"){let g=a[2];g||(console.error(v("shell","open-card <appId> [settleMs]")),process.exit(1)),r=!!await re(c,"openSwitcherCard",n,g),{settled:u,state:m}=await fe(c,Math.round(n),$=>!!$&&$.state==="app"&&$.activeApp===g&&$.showSwitcher===!1&&$.switcherPhase==="idle"&&typeof $.zoomLevel=="number"&&$.zoomLevel>=.98&&typeof $.horizontalZoom=="number"&&$.horizontalZoom>=.98),r&&await L("inspect shell open-card",{openSwitcherCard:{appId:g}},`open switcher card ${g}`)}else if(t==="appearance"){let g=a[2];(!g||!["light","dark","auto","toggle"].includes(g))&&(console.error(v("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let $=await Dt(c,"appearance",g);if(r=!!$?.ok,m={appearance:$},r){let _=$?.applied??g;console.log(` appearance: ${_}`)}}else if(t==="lock"||t==="shake"){let g=await Dt(c,t);r=!!g?.ok,m={[t]:g}}else console.error(` unknown shell subcommand: ${t}`),process.exit(1);console.log(JSON.stringify({ok:r,settled:u,state:m},null,2));break}case"url":{await Tt(c,{args:l});break}case"reload":{let o=!1,n=!1;try{await c.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let m=await c.send({type:"evaluate",code:`;(() => {
620
+ ${b("shell")} launch photos
621
+ ${b("shell")} launch rn --clear-state
622
+ ${b("shell")} launch photos 1500
623
+ ${b("shell")} home 500
624
+ ${b("shell")} switcher 800
625
+ ${b("shell")} open-card clock 800
626
+ ${b("shell")} appearance dark
627
+ ${b("shell")} lock
628
+ `);break}let e=t==="launch"||t==="open-card"||t==="home"||t==="switcher",o=t==="launch"||t==="open-card"?i[3]:i[2],n=o?Number(o):350;e&&(!Number.isFinite(n)||n<0)&&(console.error(v("shell",t==="launch"||t==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let r=!1,u=!1,m=null,w=s.includes("--clear-state");if(t==="launch"){let f=i[2];f||(console.error(v("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),w&&await c.send({type:"evaluate",code:je}),r=!!await re(c,"launchApp",n,f),{settled:u,state:m}=await ge(c,Math.round(n),$=>!!$&&$.state==="app"&&$.activeApp===f&&$.showSwitcher===!1&&$.switcherPhase==="idle"&&typeof $.launchProgress=="number"&&$.launchProgress>=.98),r&&await L("inspect shell launch",w?{launchApp:{clearState:!0}}:{launchApp:{}},w?"launch app (clear state)":"launch app")}else if(t==="home")r=!!await re(c,"goHome",n),{settled:u,state:m}=await ge(c,Math.round(n),f=>!!f&&f.state==="home"&&f.activeApp==null&&f.showSwitcher===!1&&f.switcherPhase==="idle"&&typeof f.launchProgress=="number"&&f.launchProgress>=.98);else if(t==="switcher")r=!!await re(c,"openSwitcher",n),{settled:u,state:m}=await ge(c,Math.round(n),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 X(fo),m=await se(c));else if(t==="open-card"){let f=i[2];f||(console.error(v("shell","open-card <appId> [settleMs]")),process.exit(1)),r=!!await re(c,"openSwitcherCard",n,f),{settled:u,state:m}=await ge(c,Math.round(n),$=>!!$&&$.state==="app"&&$.activeApp===f&&$.showSwitcher===!1&&$.switcherPhase==="idle"&&typeof $.zoomLevel=="number"&&$.zoomLevel>=.98&&typeof $.horizontalZoom=="number"&&$.horizontalZoom>=.98),r&&await L("inspect shell open-card",{openSwitcherCard:{appId:f}},`open switcher card ${f}`)}else if(t==="appearance"){let f=i[2];(!f||!["light","dark","auto","toggle"].includes(f))&&(console.error(v("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let $=await Ct(c,"appearance",f);if(r=!!$?.ok,m={appearance:$},r){let _=$?.applied??f;console.log(` appearance: ${_}`)}}else if(t==="lock"||t==="shake"){let f=await Ct(c,t);r=!!f?.ok,m={[t]:f}}else console.error(` unknown shell subcommand: ${t}`),process.exit(1);console.log(JSON.stringify({ok:r,settled:u,state:m},null,2));break}case"url":{await Mt(c,{args:l});break}case"reload":{let o=!1,n=!1;try{await c.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let m=await c.send({type:"evaluate",code:`;(() => {
629
629
  const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
630
630
  if (typeof reloadExternalApp === 'function') {
631
631
  reloadExternalApp()
@@ -633,10 +633,10 @@ ${o}
633
633
  }
634
634
  window.location.reload()
635
635
  return { kind: 'page' }
636
- })()`});n=!!m&&m.kind==="external-app",o=!0}catch{}console.log(" reloading...");let r=c,u=null;if(n)u=await ke(c,{timeoutMs:1e4,errorGraceMs:3e3});else{o&&await X(300);let m=await lt(N,J,M,{timeoutMs:1e4,simIdSource:E});m?(r=m,u=await ke(m,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),r=null)}if(u)if(u.ready){let m=u.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${u.elapsedMs}ms: ${u.nodes} nodes${m}`)}else u.source==="error-bail"?console.log(` \u26A0 reload bailed after ${u.elapsedMs}ms: ${u.errors} console error(s), ready signal never fired`):console.log(` \u26A0 reload timed out after ${u.elapsedMs}ms (${u.nodes} nodes, ${u.errors} errors)`);if(r)try{let m=await r.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors(10) || []"});if(r!==c&&r.close(),Array.isArray(m)&&m.length>0){console.log(`
636
+ })()`});n=!!m&&m.kind==="external-app",o=!0}catch{}console.log(" reloading...");let r=c,u=null;if(n)u=await Te(c,{timeoutMs:1e4,errorGraceMs:3e3});else{o&&await X(300);let m=await ct(F,J,T,{timeoutMs:1e4,simIdSource:E});m?(r=m,u=await Te(m,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),r=null)}if(u)if(u.ready){let m=u.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${u.elapsedMs}ms: ${u.nodes} nodes${m}`)}else u.source==="error-bail"?console.log(` \u26A0 reload bailed after ${u.elapsedMs}ms: ${u.errors} console error(s), ready signal never fired`):console.log(` \u26A0 reload timed out after ${u.elapsedMs}ms (${u.nodes} nodes, ${u.errors} errors)`);if(r)try{let m=await r.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors(10) || []"});if(r!==c&&r.close(),Array.isArray(m)&&m.length>0){console.log(`
637
637
  \u26A0 ${m.length} error(s) during mount:
638
- `);for(let w of m){let g=w.args.map($=>typeof $=="object"?JSON.stringify($):$).join(" ");if(console.log(` ${g}`),w.stack){let $=w.stack.split(`
639
- `).slice(0,2);for(let _ of $)console.log(` ${_.trim()}`)}}}}catch{}u&&!u.ready&&(process.exitCode=1);break}case"eval":case"js":{let t=a.slice(1).join(" ");t||(console.error(v("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 e=t;e.startsWith("(async")||(e=`(async () => ${e})()`);let o=await c.send({type:"evaluate",code:e});console.log(JSON.stringify(o,null,2));let n=t.toLowerCase(),r=[];(n.includes("sootsim:gohome")||n.includes("gohome"))&&r.push("sootsim shell home"),(n.includes("sootsim:appswitcher")||n.includes("appswitcher"))&&r.push("sootsim shell switcher"),(n.includes("keyboard.isvisible")||n.includes("keyboard.getmode"))&&r.push("sootsim debug state keyboard"),n.includes("interact.tap")&&r.push("sootsim do tap <x> <y>"),n.includes("keyboard.type")&&r.push("sootsim do type <text>"),(n.includes("keyboard.press")||n.includes("keyboard.dispatchkey"))&&r.push("sootsim do key <name>"),n.includes("keyboard.dismiss")&&r.push("sootsim do dismiss"),n.includes("dumptree")&&r.push("sootsim get tree"),n.includes("dumpaccessibilitytree")&&r.push("sootsim get a11y"),n.includes("getnodecount")&&r.push("sootsim get count"),n.includes("findbytext")&&r.push("sootsim find <text>"),(n.includes("findbytestid")||n.includes("findbyid"))&&r.push("sootsim find --testid <id>"),n.includes("document.hidden")&&r.push("sootsim debug state keyboard (includes tab health)"),r.length>0&&G("prefer-cli-over-eval",r);break}case"globals":{let t=await c.send({type:"evaluate",code:`(async () => {
638
+ `);for(let w of m){let f=w.args.map($=>typeof $=="object"?JSON.stringify($):$).join(" ");if(console.log(` ${f}`),w.stack){let $=w.stack.split(`
639
+ `).slice(0,2);for(let _ of $)console.log(` ${_.trim()}`)}}}}catch{}u&&!u.ready&&(process.exitCode=1);break}case"eval":case"js":{let t=i.slice(1).join(" ");t||(console.error(v("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(` ${b("js")} SootSim.bridges.test.findByText("Sign in")`),console.error(` ${b("js")} SootSim.bridges.debug.snapshot("before")`),console.error(` ${b("js")} SootSim.bridges.keyboard.type("hello")`),console.error(` ${b("js")} SootSim.state.root.children.length`),process.exit(1));let e=t;e.startsWith("(async")||(e=`(async () => ${e})()`);let o=await c.send({type:"evaluate",code:e});console.log(JSON.stringify(o,null,2));let n=t.toLowerCase(),r=[];(n.includes("sootsim:gohome")||n.includes("gohome"))&&r.push("sootsim shell home"),(n.includes("sootsim:appswitcher")||n.includes("appswitcher"))&&r.push("sootsim shell switcher"),(n.includes("keyboard.isvisible")||n.includes("keyboard.getmode"))&&r.push("sootsim debug state keyboard"),n.includes("interact.tap")&&r.push("sootsim do tap <x> <y>"),n.includes("keyboard.type")&&r.push("sootsim do type <text>"),(n.includes("keyboard.press")||n.includes("keyboard.dispatchkey"))&&r.push("sootsim do key <name>"),n.includes("keyboard.dismiss")&&r.push("sootsim do dismiss"),n.includes("dumptree")&&r.push("sootsim get tree"),n.includes("dumpaccessibilitytree")&&r.push("sootsim get a11y"),n.includes("getnodecount")&&r.push("sootsim get count"),n.includes("findbytext")&&r.push("sootsim find <text>"),(n.includes("findbytestid")||n.includes("findbyid"))&&r.push("sootsim find --testid <id>"),n.includes("document.hidden")&&r.push("sootsim debug state keyboard (includes tab health)"),r.length>0&&G("prefer-cli-over-eval",r);break}case"globals":{let t=await c.send({type:"evaluate",code:`(async () => {
640
640
  const globals = {}
641
641
 
642
642
  // test bridge (proxy in worker mode)
@@ -674,8 +674,8 @@ ${o}
674
674
 
675
675
  return globals
676
676
  })()`});console.log(` sootsim JS API:
677
- `);for(let[e,o]of Object.entries(t)){console.log(` ${e}:`);for(let n of o)console.log(` .${n}`);console.log("")}console.log(` use: ${h("js")} <expression>`),console.log(` example: ${h("js")} test.findByText("Sign in")`);break}case"describe":{await gt({bridge:c,args:s,positional:a});break}case"perf":{let t=a[1];if(!t||t==="--help"||t==="-h"){console.log(`
678
- ${h("perf")} \u2014 performance profiling
677
+ `);for(let[e,o]of Object.entries(t)){console.log(` ${e}:`);for(let n of o)console.log(` .${n}`);console.log("")}console.log(` use: ${b("js")} <expression>`),console.log(` example: ${b("js")} test.findByText("Sign in")`);break}case"describe":{await yt({bridge:c,args:s,positional:i});break}case"perf":{let t=i[1];if(!t||t==="--help"||t==="-h"){console.log(`
678
+ ${b("perf")} \u2014 performance profiling
679
679
 
680
680
  subcommands:
681
681
  stats one-shot stats (zero overhead query)
@@ -685,11 +685,11 @@ ${o}
685
685
  transition <e> profile a shell transition (goHome, appSwitcher, lockScreen)
686
686
 
687
687
  examples:
688
- ${h("perf")} stats
689
- ${h("perf")} start
688
+ ${b("perf")} stats
689
+ ${b("perf")} start
690
690
  # ... interact with the app ...
691
- ${h("perf")} stop
692
- ${h("perf")} transition goHome
691
+ ${b("perf")} stop
692
+ ${b("perf")} transition goHome
693
693
  `);break}switch(t){case"stats":{let e=await c.send({type:"evaluate",code:`(async () => {
694
694
  // worker mode (host exposes these)
695
695
  if (window.__sootsimPerfStats) {
@@ -737,7 +737,7 @@ ${o}
737
737
  startedAt: performance.now(),
738
738
  }
739
739
  return { started: true }
740
- })()`}),console.log(` profiling started \u2014 interact with the app, then run '${h("perf")} stop'`);break}case"stop":{let e=await c.send({type:"evaluate",code:`(async () => {
740
+ })()`}),console.log(` profiling started \u2014 interact with the app, then run '${b("perf")} stop'`);break}case"stop":{let e=await c.send({type:"evaluate",code:`(async () => {
741
741
  // worker mode
742
742
  if (window.__sootsimRenderHost) {
743
743
  const session = window.${Q} || {}
@@ -832,7 +832,7 @@ ${o}
832
832
  sampleCount: recent.length,
833
833
  }
834
834
  })()`});e.error&&(console.error(` error: ${e.error}`),process.exit(1));let o=e.avgMs>0?(1e3/e.avgMs).toFixed(1):"?",n=e.sampleCount>0?(e.jankFrames/e.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
835
- `),console.log(` frames: ${e.frames}`),console.log(` total: ${e.totalMs.toFixed(1)}ms`),console.log(` avg: ${e.avgMs.toFixed(2)}ms (${o} fps)`),console.log(` max: ${e.maxMs.toFixed(2)}ms`),console.log(""),e.layoutAvgMs!==void 0&&(console.log(" breakdown (avg per frame):"),console.log(` layout: ${e.layoutAvgMs.toFixed(2)}ms`),console.log(` render: ${e.renderAvgMs.toFixed(2)}ms`),console.log(` copy: ${e.copyAvgMs.toFixed(2)}ms`),e.auxAvgMs!==void 0&&console.log(` aux: ${e.auxAvgMs.toFixed(2)}ms`),e.otherAvgMs!==void 0&&console.log(` other: ${e.otherAvgMs.toFixed(2)}ms`),console.log("")),console.log(` distribution (${e.sampleCount} samples):`),console.log(` p50: ${e.p50.toFixed(2)}ms`),console.log(` p95: ${e.p95.toFixed(2)}ms`),console.log(` p99: ${e.p99.toFixed(2)}ms`),console.log(` jank: ${e.jankFrames} frames (${n}%) >16.67ms`);break}case"frames":{let e=a[2]?Number(a[2]):50;(!Number.isFinite(e)||e<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let o=await c.send({type:"evaluate",code:`(async () => {
835
+ `),console.log(` frames: ${e.frames}`),console.log(` total: ${e.totalMs.toFixed(1)}ms`),console.log(` avg: ${e.avgMs.toFixed(2)}ms (${o} fps)`),console.log(` max: ${e.maxMs.toFixed(2)}ms`),console.log(""),e.layoutAvgMs!==void 0&&(console.log(" breakdown (avg per frame):"),console.log(` layout: ${e.layoutAvgMs.toFixed(2)}ms`),console.log(` render: ${e.renderAvgMs.toFixed(2)}ms`),console.log(` copy: ${e.copyAvgMs.toFixed(2)}ms`),e.auxAvgMs!==void 0&&console.log(` aux: ${e.auxAvgMs.toFixed(2)}ms`),e.otherAvgMs!==void 0&&console.log(` other: ${e.otherAvgMs.toFixed(2)}ms`),console.log("")),console.log(` distribution (${e.sampleCount} samples):`),console.log(` p50: ${e.p50.toFixed(2)}ms`),console.log(` p95: ${e.p95.toFixed(2)}ms`),console.log(` p99: ${e.p99.toFixed(2)}ms`),console.log(` jank: ${e.jankFrames} frames (${n}%) >16.67ms`);break}case"frames":{let e=i[2]?Number(i[2]):50;(!Number.isFinite(e)||e<=0)&&(console.error(` error: expected a positive frame count, got "${i[2]}"`),process.exit(1));let o=await c.send({type:"evaluate",code:`(async () => {
836
836
  if (window.__sootsimRenderHost) {
837
837
  const session = window.${Q} || {}
838
838
  if (session.active) {
@@ -867,7 +867,7 @@ ${o}
867
867
  mode: 'main-thread',
868
868
  frames: (stats.recentFrames || []).slice(-${e}),
869
869
  }
870
- })()`});if(o.error&&(console.error(` error: ${o.error}`),process.exit(1)),o.mode==="render-worker"){let r=Array.isArray(o.samples)?o.samples:[];if(r.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${r.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,m,w,g,$,_,q]of r)console.log(` ${m.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${g.toFixed(2).padStart(7)} ${$.toFixed(2).padStart(7)} ${_.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);console.log(""),Ne(r.map(u=>u[1])),o.live&&console.log(" sampling continues");break}let n=Array.isArray(o.frames)?o.frames:Array.isArray(o)?o:[];if(n.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${n.length} frame times (ms):`),console.log(` ${n.map(r=>r.toFixed(2)).join(", ")}`),Ne(n);break}case"worst":{let e=a[2]?Number(a[2]):20;(!Number.isFinite(e)||e<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let o=await c.send({type:"evaluate",code:`(async () => {
870
+ })()`});if(o.error&&(console.error(` error: ${o.error}`),process.exit(1)),o.mode==="render-worker"){let r=Array.isArray(o.samples)?o.samples:[];if(r.length===0){console.log(` no frame data \u2014 run '${b("perf")} start' first`);break}console.log(` last ${r.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,m,w,f,$,_,q]of r)console.log(` ${m.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${$.toFixed(2).padStart(7)} ${_.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);console.log(""),Fe(r.map(u=>u[1])),o.live&&console.log(" sampling continues");break}let n=Array.isArray(o.frames)?o.frames:Array.isArray(o)?o:[];if(n.length===0){console.log(` no frame data \u2014 run '${b("perf")} start' first`);break}console.log(` last ${n.length} frame times (ms):`),console.log(` ${n.map(r=>r.toFixed(2)).join(", ")}`),Fe(n);break}case"worst":{let e=i[2]?Number(i[2]):20;(!Number.isFinite(e)||e<=0)&&(console.error(` error: expected a positive frame count, got "${i[2]}"`),process.exit(1));let o=await c.send({type:"evaluate",code:`(async () => {
871
871
  if (window.__sootsimRenderHost) {
872
872
  const session = window.${Q} || {}
873
873
  if (session.active) {
@@ -909,8 +909,8 @@ ${o}
909
909
  mode: 'main-thread',
910
910
  frames: recent.slice().sort((a, b) => b - a).slice(0, ${e}),
911
911
  }
912
- })()`});if(o.error&&(console.error(` error: ${o.error}`),process.exit(1)),o.mode==="render-worker"){let r=Array.isArray(o.samples)?o.samples:[];if(r.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${r.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,m,w,g,$,_,q]of r)console.log(` ${m.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${g.toFixed(2).padStart(7)} ${$.toFixed(2).padStart(7)} ${_.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);o.live&&(console.log(""),console.log(" sampling continues"));break}let n=Array.isArray(o.frames)?o.frames:Array.isArray(o)?o:[];if(n.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${n.length} frame times (ms):`),console.log(` ${n.map(r=>r.toFixed(2)).join(", ")}`);break}case"transition":{let e=a[2];if(!e||!["goHome","appSwitcher","lockScreen"].includes(e)){console.log(`
913
- ${h("perf")} transition <event> \u2014 profile a shell transition
912
+ })()`});if(o.error&&(console.error(` error: ${o.error}`),process.exit(1)),o.mode==="render-worker"){let r=Array.isArray(o.samples)?o.samples:[];if(r.length===0){console.log(` no frame data \u2014 run '${b("perf")} start' first`);break}console.log(` worst ${r.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,m,w,f,$,_,q]of r)console.log(` ${m.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${$.toFixed(2).padStart(7)} ${_.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);o.live&&(console.log(""),console.log(" sampling continues"));break}let n=Array.isArray(o.frames)?o.frames:Array.isArray(o)?o:[];if(n.length===0){console.log(` no frame data \u2014 run '${b("perf")} start' first`);break}console.log(` worst ${n.length} frame times (ms):`),console.log(` ${n.map(r=>r.toFixed(2)).join(", ")}`);break}case"transition":{let e=i[2];if(!e||!["goHome","appSwitcher","lockScreen"].includes(e)){console.log(`
913
+ ${b("perf")} transition <event> \u2014 profile a shell transition
914
914
 
915
915
  events:
916
916
  goHome swipe-to-home animation
@@ -920,8 +920,8 @@ ${o}
920
920
  note: uses 600ms capture window \u2014 may need --timeout 10000 flag
921
921
 
922
922
  examples:
923
- ${h("perf")} transition goHome --timeout 10000
924
- ${h("perf")} transition appSwitcher
923
+ ${b("perf")} transition goHome --timeout 10000
924
+ ${b("perf")} transition appSwitcher
925
925
  `);break}let n=`sootsim:${e}`;console.log(` profiling ${e} transition...`),console.log(" (use --timeout 10000 if this times out)");let r=await c.send({type:"evaluate",code:`(async () => {
926
926
  // only supported in render-worker mode
927
927
  if (!window.__sootsimRenderHost) {
@@ -999,27 +999,27 @@ ${o}
999
999
  p50: ${r.p50.toFixed(2)}ms
1000
1000
  p95: ${r.p95.toFixed(2)}ms
1001
1001
  p99: ${r.p99.toFixed(2)}ms
1002
- jank: ${r.jankFrames} frames (${m}%) >16.67ms`),Array.isArray(r.samples)&&r.samples.length>0&&(console.log(""),Ne(r.samples.map(w=>w[1])));break}default:console.error(` unknown perf subcommand: ${t}`),process.exit(1)}break}case"errors":{let t=a[1];if(t==="clear"){await Qe(c),C(l)?B({cleared:!0}):console.log(" error buffer cleared");break}let e=t?Number(t):20,o=await Xe(c,e);if(C(l)){B(o);break}if(o.length===0){console.log(" no errors captured");break}console.log(` ${o.length} error(s):
1002
+ jank: ${r.jankFrames} frames (${m}%) >16.67ms`),Array.isArray(r.samples)&&r.samples.length>0&&(console.log(""),Fe(r.samples.map(w=>w[1])));break}default:console.error(` unknown perf subcommand: ${t}`),process.exit(1)}break}case"errors":{let t=i[1];if(t==="clear"){await Ze(c),C(l)?B({cleared:!0}):console.log(" error buffer cleared");break}let e=t?Number(t):20,o=await Ve(c,e);if(C(l)){B(o);break}if(o.length===0){console.log(" no errors captured");break}console.log(` ${o.length} error(s):
1003
1003
  `);for(let n of o){let r=new Date(n.timestamp).toLocaleTimeString(),u=n.args.map(m=>typeof m=="object"?JSON.stringify(m):m).join(" ");if(console.log(` [${r}] ${u}`),n.stack){let m=n.stack.split(`
1004
- `).slice(0,3);for(let w of m)console.log(` ${w.trim()}`)}}break}case"warnings":{let t=a[1]?Number(a[1]):20,e=await Ve(c,t);if(C(l)){B(e);break}if(e.length===0){console.log(" no warnings captured");break}console.log(` ${e.length} warning(s):
1004
+ `).slice(0,3);for(let w of m)console.log(` ${w.trim()}`)}}break}case"warnings":{let t=i[1]?Number(i[1]):20,e=await Qe(c,t);if(C(l)){B(e);break}if(e.length===0){console.log(" no warnings captured");break}console.log(` ${e.length} warning(s):
1005
1005
  `);for(let o of e){let n=new Date(o.timestamp).toLocaleTimeString(),r=o.args.map(u=>typeof u=="object"?JSON.stringify(u):u).join(" ");console.log(` [${n}] ${r}`)}break}case"animations":{let t=await z(c,"listAnimations")??[];if(s.includes("--json")){console.log(JSON.stringify(t,null,2));break}if(t.length===0){console.log(" no active animations");break}console.log(` ${t.length} active animation(s):
1006
- `);for(let e of t){let o=String(e.kind).padEnd(6),n=`${Number(e.from).toFixed(2)}\u2192${Number(e.to).toFixed(2)}`,r=Number(e.current??0).toFixed(2),u=`${Math.round((e.progress??0)*100)}%`,m=`${Math.round(e.elapsedMs??0)}ms`,w=e.loop?" loop":"",g=e.layoutBound?" layout":"";console.log(` #${e.id} ${o} ${n.padEnd(14)} cur=${r.padEnd(7)} ${u.padStart(4)} ${m}${w}${g}`)}break}case"animation":{let t=a[1];(!t||t==="--help"||t==="-h")&&(console.error(` usage: ${h("animation")} <id>`),process.exit(1));let e=Number(t);Number.isFinite(e)||(console.error(` invalid id: ${t}`),process.exit(1));let o=await z(c,"getAnimation",e);console.log(JSON.stringify(o,null,2));break}case"stop-animation":{let t=a[1];(!t||t==="--help"||t==="-h")&&(console.error(` usage: ${h("stop-animation")} <id|all>`),process.exit(1));let e=t==="all"?"all":Number(t);e!=="all"&&!Number.isFinite(e)&&(console.error(` invalid id: ${t}`),process.exit(1));let o=await z(c,"stopAnimation",e);console.log(` stopped ${o??0} animation(s)`);break}case"requests":{let t=a[1];if(t==="clear"){await et(c),C(l)?B({cleared:!0}):console.log(" request buffer cleared");break}let e=t==="all",o=e?a[2]:t,n=o?Number(o):20,r=await Ze(c,{failed:!e,limit:n});if(C(l)){B(r);break}if(r.length===0){console.log(e?" no requests captured":" no failed requests captured");break}console.log(` ${r.length} ${e?"request(s)":"failed request(s)"}:
1007
- `);for(let u of r){let m=new Date(u.timestamp).toLocaleTimeString();console.log(` [${m}] ${W(u)}`),u.responseBody?console.log(` ${u.responseBody}`):u.error&&console.log(` ${u.error}`)}break}case"network":{let t=a[1],e=null,o=null,n=!1,r=!1,u=1e3,m=!1,w=!1;for(let I=0;I<l.length;I++){let b=l[I];if(b==="--filter")e=l[I+1]??null,I++;else if(b==="--limit"){let p=Number(l[I+1]);Number.isFinite(p)&&(o=p),I++}else if(b==="--threshold"){let p=Number(l[I+1]);Number.isFinite(p)&&p>0&&(u=p),I++}else b==="--failed"?n=!0:b==="--slow"?r=!0:b==="--tail"||b==="-f"?m=!0:b==="--json"&&(w=!0)}if(t==="clear"){await c.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(t==="get"){let I=a[2];I||(console.error(" usage: sootsim network get <id>"),process.exit(1));let b=await c.send({type:"evaluate",code:`(() => {
1006
+ `);for(let e of t){let o=String(e.kind).padEnd(6),n=`${Number(e.from).toFixed(2)}\u2192${Number(e.to).toFixed(2)}`,r=Number(e.current??0).toFixed(2),u=`${Math.round((e.progress??0)*100)}%`,m=`${Math.round(e.elapsedMs??0)}ms`,w=e.loop?" loop":"",f=e.layoutBound?" layout":"";console.log(` #${e.id} ${o} ${n.padEnd(14)} cur=${r.padEnd(7)} ${u.padStart(4)} ${m}${w}${f}`)}break}case"animation":{let t=i[1];(!t||t==="--help"||t==="-h")&&(console.error(` usage: ${b("animation")} <id>`),process.exit(1));let e=Number(t);Number.isFinite(e)||(console.error(` invalid id: ${t}`),process.exit(1));let o=await z(c,"getAnimation",e);console.log(JSON.stringify(o,null,2));break}case"stop-animation":{let t=i[1];(!t||t==="--help"||t==="-h")&&(console.error(` usage: ${b("stop-animation")} <id|all>`),process.exit(1));let e=t==="all"?"all":Number(t);e!=="all"&&!Number.isFinite(e)&&(console.error(` invalid id: ${t}`),process.exit(1));let o=await z(c,"stopAnimation",e);console.log(` stopped ${o??0} animation(s)`);break}case"requests":{let t=i[1];if(t==="clear"){await tt(c),C(l)?B({cleared:!0}):console.log(" request buffer cleared");break}let e=t==="all",o=e?i[2]:t,n=o?Number(o):20,r=await et(c,{failed:!e,limit:n});if(C(l)){B(r);break}if(r.length===0){console.log(e?" no requests captured":" no failed requests captured");break}console.log(` ${r.length} ${e?"request(s)":"failed request(s)"}:
1007
+ `);for(let u of r){let m=new Date(u.timestamp).toLocaleTimeString();console.log(` [${m}] ${W(u)}`),u.responseBody?console.log(` ${u.responseBody}`):u.error&&console.log(` ${u.error}`)}break}case"network":{let t=i[1],e=null,o=null,n=!1,r=!1,u=1e3,m=!1,w=!1;for(let M=0;M<l.length;M++){let y=l[M];if(y==="--filter")e=l[M+1]??null,M++;else if(y==="--limit"){let p=Number(l[M+1]);Number.isFinite(p)&&(o=p),M++}else if(y==="--threshold"){let p=Number(l[M+1]);Number.isFinite(p)&&p>0&&(u=p),M++}else y==="--failed"?n=!0:y==="--slow"?r=!0:y==="--tail"||y==="-f"?m=!0:y==="--json"&&(w=!0)}if(t==="clear"){await c.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(t==="get"){let M=i[2];M||(console.error(" usage: sootsim network get <id>"),process.exit(1));let y=await c.send({type:"evaluate",code:`(() => {
1008
1008
  const obs = window.__sootsimObservability;
1009
1009
  if (!obs) return null;
1010
- return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(I)}) || null;
1011
- })()`});b||(console.error(` no entry with id ${I}`),process.exit(1)),w?console.log(JSON.stringify(b,null,2)):co(b);break}let g=o??(m?200:t?Number(t):20);Number.isFinite(g)||(console.error(` invalid limit: ${t} \u2014 \`network\` takes a numeric count (e.g. ${h("network")} 100).
1012
- to target a specific sim, use \`--sim ${t}\` instead.`),process.exit(1));let $=async()=>{let I=await c.send({type:"evaluate",code:`(() => {
1010
+ return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(M)}) || null;
1011
+ })()`});y||(console.error(` no entry with id ${M}`),process.exit(1)),w?console.log(JSON.stringify(y,null,2)):uo(y);break}let f=o??(m?200:t?Number(t):20);Number.isFinite(f)||(console.error(` invalid limit: ${t} \u2014 \`network\` takes a numeric count (e.g. ${b("network")} 100).
1012
+ to target a specific sim, use \`--sim ${t}\` instead.`),process.exit(1));let $=async()=>{let M=await c.send({type:"evaluate",code:`(() => {
1013
1013
  const obs = window.__sootsimObservability;
1014
1014
  if (!obs) return { ok: false };
1015
1015
  return { ok: true, entries: obs.network.getSnapshot() };
1016
- })()`});if(!I||!I.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return I.entries??[]},_=I=>{let b=I;if(n&&(b=b.filter(p=>!!p.error||p.status!=null&&p.status>=400)),r&&(b=b.filter(p=>p.durationMs!=null&&p.durationMs>=u)),e){let p=e.toLowerCase();b=b.filter(P=>(P.displayUrl||P.url).toLowerCase().includes(p))}return r&&!m&&(b=[...b].sort((p,P)=>(P.durationMs??0)-(p.durationMs??0))),b};if(!m){let I=await $(),b=_(I).slice(-g);if(w){console.log(JSON.stringify(b,null,2));break}if(b.length===0){I.length===0?console.log(" no network requests captured"):console.log(r?` no requests slower than ${u}ms (${I.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(r?` ${b.length} request(s) slower than ${u}ms (sorted by duration desc):
1017
- `:` ${b.length} request(s):
1018
- `);for(let p of b)Ot(p);break}console.log(` tailing network (ctrl-c to stop)...
1019
- `);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let I=await $(),b=_(I);for(let p of b)p.durationMs!=null&&(q.has(p.id)||(q.add(p.id),w?console.log(JSON.stringify(p)):Ot(p)));await X(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let t=a[1],e=null,o=null,n=null,r=!1,u=!1,m=!1;for(let b=0;b<l.length;b++){let p=l[b];if(p==="--filter")e=l[b+1]??null,b++;else if(p==="--limit"){let P=Number(l[b+1]);Number.isFinite(P)&&(o=P),b++}else p==="--level"?(n=l[b+1]??null,b++):p==="--tail"||p==="-f"?r=!0:p==="--json"?u=!0:(p==="--internal"||p==="--all")&&(m=!0)}let w=n?new Set(n.split(",").map(b=>b.trim()).filter(b=>b==="log"||b==="info"||b==="warn"||b==="error"||b==="debug")):null;if(t==="clear"){await ot(c),console.log(" log buffer cleared");break}let g=!u&&process.stdout.isTTY===!0,$=o??(r?500:t?Number(t):50);Number.isFinite($)||(console.error(` invalid limit: ${t} \u2014 \`logs\` takes a numeric count (e.g. ${h("logs")} 100).
1020
- to target a specific sim, use \`--sim ${t}\` instead.`),process.exit(1));let _=()=>tt(c),q=b=>st(b,{level:w,filter:e,showInternal:m});if(!r){let b=await _(),p=q(b).slice(-$);if(u){console.log(JSON.stringify(p,null,2));break}if(p.length===0){console.log(b.length===0?" no logs captured":" no matching logs");break}console.log(` ${p.length} log(s):
1021
- `);for(let P of p)Rt(P,g);break}console.log(` tailing logs (ctrl-c to stop)...
1022
- `);let H=new Set,U=!0,I=()=>{U=!1};process.on("SIGINT",I);try{for(;U;){let b=await _(),p=q(b);for(let P of p)H.has(P.id)||(H.add(P.id),u?console.log(JSON.stringify(P)):Rt(P,g));await X(250)}}finally{process.off("SIGINT",I)}break}default:console.error(` unknown subcommand: ${y}`),process.exit(1)}if(ee.has(y)&&!s.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&await x(c),!j.has(y)&&!C(l))try{await oe(c)}catch{}}catch(t){let e=t instanceof Error?t.message:String(t);console.error(` ${y??"inspect"} failed: ${e}`);let o=/^no sim connected with id (.+)$/.exec(e),n=/^command timed out after \d+s$/.test(e)||e.startsWith("sim disconnected:")||e.startsWith("bridge never reconnected")||e.startsWith("could not connect to ws://");if(o)await dt(c,N,o[1]);else if(/^no sim connected$/.test(e))ct(N);else if(n)process.stderr.write(` the sim is not responding. recover it with:
1016
+ })()`});if(!M||!M.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return M.entries??[]},_=M=>{let y=M;if(n&&(y=y.filter(p=>!!p.error||p.status!=null&&p.status>=400)),r&&(y=y.filter(p=>p.durationMs!=null&&p.durationMs>=u)),e){let p=e.toLowerCase();y=y.filter(P=>(P.displayUrl||P.url).toLowerCase().includes(p))}return r&&!m&&(y=[...y].sort((p,P)=>(P.durationMs??0)-(p.durationMs??0))),y};if(!m){let M=await $(),y=_(M).slice(-f);if(w){console.log(JSON.stringify(y,null,2));break}if(y.length===0){M.length===0?console.log(" no network requests captured"):console.log(r?` no requests slower than ${u}ms (${M.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(r?` ${y.length} request(s) slower than ${u}ms (sorted by duration desc):
1017
+ `:` ${y.length} request(s):
1018
+ `);for(let p of y)Pt(p);break}console.log(` tailing network (ctrl-c to stop)...
1019
+ `);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let M=await $(),y=_(M);for(let p of y)p.durationMs!=null&&(q.has(p.id)||(q.add(p.id),w?console.log(JSON.stringify(p)):Pt(p)));await X(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let t=i[1],e=null,o=null,n=null,r=!1,u=!1,m=!1;for(let y=0;y<l.length;y++){let p=l[y];if(p==="--filter")e=l[y+1]??null,y++;else if(p==="--limit"){let P=Number(l[y+1]);Number.isFinite(P)&&(o=P),y++}else p==="--level"?(n=l[y+1]??null,y++):p==="--tail"||p==="-f"?r=!0:p==="--json"?u=!0:(p==="--internal"||p==="--all")&&(m=!0)}let w=n?new Set(n.split(",").map(y=>y.trim()).filter(y=>y==="log"||y==="info"||y==="warn"||y==="error"||y==="debug")):null;if(t==="clear"){await st(c),console.log(" log buffer cleared");break}let f=!u&&process.stdout.isTTY===!0,$=o??(r?500:t?Number(t):50);Number.isFinite($)||(console.error(` invalid limit: ${t} \u2014 \`logs\` takes a numeric count (e.g. ${b("logs")} 100).
1020
+ to target a specific sim, use \`--sim ${t}\` instead.`),process.exit(1));let _=()=>ot(c),q=y=>nt(y,{level:w,filter:e,showInternal:m});if(!r){let y=await _(),p=q(y).slice(-$);if(u){console.log(JSON.stringify(p,null,2));break}if(p.length===0){console.log(y.length===0?" no logs captured":" no matching logs");break}console.log(` ${p.length} log(s):
1021
+ `);for(let P of p)Et(P,f);break}console.log(` tailing logs (ctrl-c to stop)...
1022
+ `);let H=new Set,U=!0,M=()=>{U=!1};process.on("SIGINT",M);try{for(;U;){let y=await _(),p=q(y);for(let P of p)H.has(P.id)||(H.add(P.id),u?console.log(JSON.stringify(P)):Et(P,f));await X(250)}}finally{process.off("SIGINT",M)}break}default:console.error(` unknown subcommand: ${h}`),process.exit(1)}if(ee.has(h)&&!s.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&await x(c),!j.has(h)&&!C(l))try{await oe(c)}catch{}}catch(t){let e=t instanceof Error?t.message:String(t);console.error(` ${h??"inspect"} failed: ${e}`);let o=/^no sim connected with id (.+)$/.exec(e),n=/^command timed out after \d+s$/.test(e)||e.startsWith("sim disconnected:")||e.startsWith("bridge never reconnected")||e.startsWith("could not connect to ws://");if(o)await ut(c,F,o[1]);else if(/^no sim connected$/.test(e))dt(F);else if(n)process.stderr.write(` the sim is not responding. recover it with:
1023
1023
  sootsim close --sim <id> # force-close the wedged sim
1024
1024
  sootsim list # confirm it's gone
1025
- `);else{try{await je(c)}catch{}try{await O({includeTail:!0})}catch{}try{await Z({includeTail:!0})}catch{}}process.exit(1)}finally{c.close()}}export{Qs as runInspect};
1025
+ `);else{try{await Le(c)}catch{}try{await O({includeTail:!0})}catch{}try{await Z({includeTail:!0})}catch{}}process.exit(1)}finally{c.close()}}export{en as runInspect};