sootsim 0.1.52 → 0.1.53

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 (139) hide show
  1. package/dist-cli/bin.js +3 -3
  2. package/dist-cli/chunks/{agent-RUWGJCSS.js → agent-PA7ZGTHU.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-FBCGP5N7.js → agent-wrapper-CVZFXQKJ.js} +2 -2
  4. package/dist-cli/chunks/{assert-IOU2NWE2.js → assert-6LHIY63B.js} +2 -2
  5. package/dist-cli/chunks/auto-bootstrap-SVBAUCSM.js +2 -0
  6. package/dist-cli/chunks/beta-YEBFYYIB.js +2 -0
  7. package/dist-cli/chunks/{chunk-EYRQG47K.js → chunk-2ZBZCRN6.js} +1 -1
  8. package/dist-cli/chunks/{chunk-EJYVXNQL.js → chunk-5Q3XBH5M.js} +2 -2
  9. package/dist-cli/chunks/{chunk-MWGIKDXO.js → chunk-5U2BN4IU.js} +2 -2
  10. package/dist-cli/chunks/{chunk-H4G7IRXG.js → chunk-6A4CZMPO.js} +2 -2
  11. package/dist-cli/chunks/{chunk-HRIQRZX3.js → chunk-6JZNIGOQ.js} +1 -1
  12. package/dist-cli/chunks/{chunk-EQPRFEHH.js → chunk-7IYYIF5B.js} +2 -2
  13. package/dist-cli/chunks/{chunk-FPIJBBYW.js → chunk-7ZHWA3WD.js} +2 -2
  14. package/dist-cli/chunks/{chunk-UCCSXQ2P.js → chunk-AFXPU7YQ.js} +3 -3
  15. package/dist-cli/chunks/{chunk-I5WEW3ES.js → chunk-AYU6WUNF.js} +1 -1
  16. package/dist-cli/chunks/{chunk-Q2424XB2.js → chunk-AZYLZGRV.js} +1 -1
  17. package/dist-cli/chunks/{chunk-ABEYZDD7.js → chunk-BPXSSZJS.js} +2 -2
  18. package/dist-cli/chunks/chunk-CKZSGUTE.js +2 -0
  19. package/dist-cli/chunks/{chunk-PZJSYDQ7.js → chunk-CRUPWYHV.js} +3 -3
  20. package/dist-cli/chunks/{chunk-DNKB2V2W.js → chunk-CTDDR7HW.js} +2 -2
  21. package/dist-cli/chunks/{chunk-IQU56D6C.js → chunk-CTGH5SFH.js} +1 -1
  22. package/dist-cli/chunks/{chunk-IXITVIJV.js → chunk-CW2X4KRW.js} +2 -2
  23. package/dist-cli/chunks/{chunk-JPLTR6JM.js → chunk-E3S6U2QR.js} +1 -1
  24. package/dist-cli/chunks/{chunk-UXE5BFPK.js → chunk-E4JTYQVY.js} +2 -2
  25. package/dist-cli/chunks/chunk-ELEP2COQ.js +3 -0
  26. package/dist-cli/chunks/{chunk-U3UHXJNE.js → chunk-ERC46HTZ.js} +1 -1
  27. package/dist-cli/chunks/{chunk-4TSGUAV3.js → chunk-FDA2NX2E.js} +2 -2
  28. package/dist-cli/chunks/{chunk-MBH3NFBC.js → chunk-GWGF4J4Y.js} +2 -2
  29. package/dist-cli/chunks/chunk-H4C3WE3C.js +1 -0
  30. package/dist-cli/chunks/{chunk-BF7F45CZ.js → chunk-IS5ORPFW.js} +2 -2
  31. package/dist-cli/chunks/{chunk-6QDFLMJL.js → chunk-LELB2PV3.js} +1 -1
  32. package/dist-cli/chunks/chunk-LL3XAMKC.js +16 -0
  33. package/dist-cli/chunks/{chunk-MSKCUZ5B.js → chunk-LYHVX7TD.js} +3 -3
  34. package/dist-cli/chunks/{chunk-YDKXZS7D.js → chunk-MX5HFYST.js} +1 -1
  35. package/dist-cli/chunks/{chunk-USGUHWUJ.js → chunk-N3RWXMD3.js} +2 -2
  36. package/dist-cli/chunks/chunk-NIHI6NXE.js +1 -0
  37. package/dist-cli/chunks/chunk-QTVGSFY6.js +305 -0
  38. package/dist-cli/chunks/{chunk-T6RAXKVI.js → chunk-R3VVVXF3.js} +2 -2
  39. package/dist-cli/chunks/{chunk-JPX7OS7B.js → chunk-R5XV3WIE.js} +2 -2
  40. package/dist-cli/chunks/{chunk-3DDSYQHM.js → chunk-RBXJA2PW.js} +2 -2
  41. package/dist-cli/chunks/{chunk-7Y3FYPJH.js → chunk-SQZXAKBL.js} +2 -2
  42. package/dist-cli/chunks/{chunk-CTEXZ7BE.js → chunk-STWL7EXR.js} +1 -1
  43. package/dist-cli/chunks/{chunk-GNQSOQXZ.js → chunk-WBAIONOO.js} +2 -2
  44. package/dist-cli/chunks/{chunk-3MIWVHCX.js → chunk-WXOAHKCZ.js} +1 -1
  45. package/dist-cli/chunks/{chunk-FVBSPGBR.js → chunk-XBP7BBSF.js} +2 -2
  46. package/dist-cli/chunks/{chunk-PDZ4JVAW.js → chunk-XC3T7UDH.js} +1 -1
  47. package/dist-cli/chunks/chunk-XO4UV6EO.js +1 -0
  48. package/dist-cli/chunks/chunk-YCPH4ZTS.js +2 -0
  49. package/dist-cli/chunks/{chunk-MTE3DEWY.js → chunk-YEE4EO2P.js} +1 -1
  50. package/dist-cli/chunks/{chunk-EXQJSXDF.js → chunk-ZYITMTYD.js} +1 -1
  51. package/dist-cli/chunks/cli-version-NMWGV7OU.js +2 -0
  52. package/dist-cli/chunks/{compat-ZBLH6EWV.js → compat-CHBJ7TDK.js} +3 -3
  53. package/dist-cli/chunks/{config-DH2GG63H.js → config-XTZOLM5E.js} +2 -2
  54. package/dist-cli/chunks/control-XAZGNLFM.js +2 -0
  55. package/dist-cli/chunks/{cpu-profile-3PRCXZMV.js → cpu-profile-EQHKYVOF.js} +2 -2
  56. package/dist-cli/chunks/{daemon-XSFKUDKZ.js → daemon-K42MZR2E.js} +2 -2
  57. package/dist-cli/chunks/{debug-VAWCOXQ3.js → debug-ULTTL5L2.js} +3 -3
  58. package/dist-cli/chunks/demo-app-registry-SO43B5HW.js +2 -0
  59. package/dist-cli/chunks/{detox-UABOFTDQ.js → detox-LU3G3EBC.js} +2 -2
  60. package/dist-cli/chunks/{device-LCB4N66D.js → device-RYW4ZE4R.js} +2 -2
  61. package/dist-cli/chunks/{diagnose-MT3WMY4M.js → diagnose-5YQAXWFB.js} +2 -2
  62. package/dist-cli/chunks/drivers-SXP44QNY.js +2 -0
  63. package/dist-cli/chunks/{electron-WVNFRA4S.js → electron-ORBIXXTP.js} +3 -3
  64. package/dist-cli/chunks/flow-GP7GAXLT.js +2 -0
  65. package/dist-cli/chunks/{hints-PFAKBGFX.js → hints-V4SHPWCI.js} +2 -2
  66. package/dist-cli/chunks/{home-paths-X6RB72PF.js → home-paths-UYEDTYXU.js} +2 -2
  67. package/dist-cli/chunks/{inspect-UFYXDO6B.js → inspect-K2FN4JPL.js} +96 -124
  68. package/dist-cli/chunks/install-R4H47HDX.js +2 -0
  69. package/dist-cli/chunks/{install-desktop-W6QJX52Y.js → install-desktop-BDDNVONK.js} +3 -3
  70. package/dist-cli/chunks/{keys-ORDSAMP7.js → keys-QH5VOSUK.js} +2 -2
  71. package/dist-cli/chunks/{launch-NQZTWTPY.js → launch-K2LP5XFZ.js} +3 -3
  72. package/dist-cli/chunks/{login-J2NVLHK5.js → login-5AJTPRVD.js} +4 -4
  73. package/dist-cli/chunks/{logout-HI7A6PFH.js → logout-45VCRSXX.js} +2 -2
  74. package/dist-cli/chunks/{maestro-KIOOFK5M.js → maestro-5LDII3YE.js} +2 -2
  75. package/dist-cli/chunks/{preview-QUJO4B4G.js → preview-IA2UUMLO.js} +2 -2
  76. package/dist-cli/chunks/{profile-U6RWYQV2.js → profile-ZALUAYTJ.js} +2 -2
  77. package/dist-cli/chunks/{react-3V65RTQC.js → react-KJBOHVG7.js} +2 -2
  78. package/dist-cli/chunks/{record-476LFCQV.js → record-UI226Z7F.js} +2 -2
  79. package/dist-cli/chunks/runtime-JNHCYB5L.js +2 -0
  80. package/dist-cli/chunks/{runtime-delivery-BSRHUXJQ.js → runtime-delivery-Y4QVOPLO.js} +2 -2
  81. package/dist-cli/chunks/{screenshot-2S3BCN35.js → screenshot-SV5S4UGU.js} +2 -2
  82. package/dist-cli/chunks/{screenshot-mode-SZCHOYZV.js → screenshot-mode-NCISGI6W.js} +2 -2
  83. package/dist-cli/chunks/{screenshots-LGP7LA3M.js → screenshots-MQZDYKF5.js} +2 -2
  84. package/dist-cli/chunks/{server-G4BGS6GE.js → server-RLDTPMHN.js} +2 -2
  85. package/dist-cli/chunks/setup-repo-F4RNWTDL.js +2 -0
  86. package/dist-cli/chunks/{skills-2YOLQVV6.js → skills-NECP76E4.js} +2 -2
  87. package/dist-cli/chunks/{start-SF3I4SLN.js → start-K4ASMK7D.js} +4 -4
  88. package/dist-cli/chunks/store-TLB2YDDQ.js +2 -0
  89. package/dist-cli/chunks/telemetry-EXCKYRZL.js +2 -0
  90. package/dist-cli/chunks/{test-YYHXTVDI.js → test-YJLRC3IE.js} +3 -3
  91. package/dist-cli/chunks/three-mode-NAAIMEHL.js +54 -0
  92. package/dist-cli/chunks/{timeline-IOEIFEH2.js → timeline-BJXCTH7E.js} +2 -2
  93. package/dist-cli/chunks/{upgrade-YF2U5QJY.js → upgrade-NRJOML2W.js} +2 -2
  94. package/dist-cli/chunks/upload-BQTZTOJL.js +2 -0
  95. package/dist-cli/chunks/{web-GAOXH77P.js → web-P3IP7M5Q.js} +2 -2
  96. package/dist-cli/chunks/{what-happened-DBI2RQVE.js → what-happened-5Q2RBX5R.js} +2 -2
  97. package/dist-cli/chunks/{whoami-YDAMLYNA.js → whoami-7W6WPTVA.js} +2 -2
  98. package/dist-lib/agent-daemon-client.cjs +1 -1
  99. package/dist-lib/agent-events.cjs +1 -1
  100. package/dist-lib/agent-sessions.cjs +1 -1
  101. package/dist-lib/attached-projects.cjs +1 -1
  102. package/dist-lib/auth/shared-session.cjs +1 -1
  103. package/dist-lib/backend-origin.cjs +1 -1
  104. package/dist-lib/bridge-constants.cjs +1 -1
  105. package/dist-lib/cli-constants.cjs +1 -1
  106. package/dist-lib/config.cjs +1 -1
  107. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  108. package/dist-lib/home-paths.cjs +1 -1
  109. package/dist-lib/host/bridge-host.cjs +1 -1
  110. package/dist-lib/host/fetch-proxy-handler.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-OYBDYAZM.js +0 -2
  119. package/dist-cli/chunks/beta-D4OEPOSE.js +0 -2
  120. package/dist-cli/chunks/chunk-2QNHBNWB.js +0 -16
  121. package/dist-cli/chunks/chunk-A3YSGT76.js +0 -37
  122. package/dist-cli/chunks/chunk-DSJ7PGU3.js +0 -2
  123. package/dist-cli/chunks/chunk-DVCE2KQL.js +0 -108
  124. package/dist-cli/chunks/chunk-KVQWMXDV.js +0 -2
  125. package/dist-cli/chunks/chunk-SEETW74F.js +0 -1
  126. package/dist-cli/chunks/chunk-ULHAQFCE.js +0 -1
  127. package/dist-cli/chunks/chunk-YVGHAT6Q.js +0 -1
  128. package/dist-cli/chunks/cli-version-2VO66OZ6.js +0 -2
  129. package/dist-cli/chunks/control-W3BOP6AT.js +0 -2
  130. package/dist-cli/chunks/demo-app-registry-7GNP7WE4.js +0 -2
  131. package/dist-cli/chunks/drivers-YGVUWGMB.js +0 -2
  132. package/dist-cli/chunks/flow-OUOMEOSC.js +0 -2
  133. package/dist-cli/chunks/install-NBUHIXEP.js +0 -2
  134. package/dist-cli/chunks/runtime-4TK5DY5R.js +0 -2
  135. package/dist-cli/chunks/setup-repo-5LUDPPSI.js +0 -2
  136. package/dist-cli/chunks/store-LLUQKQB7.js +0 -2
  137. package/dist-cli/chunks/telemetry-RDTORLS2.js +0 -2
  138. package/dist-cli/chunks/three-mode-5U3H4QDF.js +0 -39
  139. package/dist-cli/chunks/upload-3DFSK4NV.js +0 -2
@@ -1,12 +1,12 @@
1
- /*! sootsim v0.1.52 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as G}from"./chunk-3DDSYQHM.js";import{a as je,b as Le}from"./chunk-EXQJSXDF.js";import{a as X,b as D,c as B,d as Y,e as de,f as re,g as rt,h as it,i as ve}from"./chunk-A3YSGT76.js";import{D as nt,a as Je,b as We,c as qe,d as He,e as Ue,f as $e,g as Se,h as Ke,i as ze,j as Ye,k as Ge,l as Xe,m as Ve,n as Qe,o as Ze,p as et,q as tt,u as ot,w as ne,x as st}from"./chunk-DVCE2KQL.js";import{a as De,g as ce}from"./chunk-FPIJBBYW.js";import{b as at,c as lt,i as ct}from"./chunk-ABEYZDD7.js";import"./chunk-3MIWVHCX.js";import{a as Be}from"./chunk-HRIQRZX3.js";import"./chunk-H4G7IRXG.js";import"./chunk-I5WEW3ES.js";import"./chunk-YVGHAT6Q.js";import"./chunk-EQPRFEHH.js";import"./chunk-MTE3DEWY.js";import{a as be,c as we,d as Ae}from"./chunk-PDZ4JVAW.js";import{a as Fe}from"./chunk-KVQWMXDV.js";import{c as Oe,e as Re,f as Ee,g as Ce,h as xe}from"./chunk-MBH3NFBC.js";import{b as Pe}from"./chunk-CTEXZ7BE.js";import"./chunk-DSJ7PGU3.js";import"./chunk-JPLTR6JM.js";import"./chunk-6QDFLMJL.js";import{existsSync as Wt,mkdirSync as qt,readFileSync as Ht,rmSync as dt,writeFileSync as Ut}from"fs";import{tmpdir as Kt}from"os";import{dirname as zt,join as Yt,resolve as Gt}from"path";var ie=1,Xt="SOOTSIM_INSPECT_NOTICE_PATH",Vt=300*1e3,Qt=15e3;function ut(){return Gt(process.env[Xt]||Yt(Kt(),"sootsim-inspect-notice-state.json"))}function Zt(o,d){return Object.fromEntries(Object.entries(o).filter(([,a])=>typeof a?.signature=="string"&&Number.isFinite(a?.updatedAt)&&d-a.updatedAt<=Vt))}function eo(o){let d=ut();if(!Wt(d))return{version:ie,entries:{}};try{let a=JSON.parse(Ht(d,"utf8"));return a.version!==ie||!a.entries||typeof a.entries!="object"?(dt(d,{force:!0}),{version:ie,entries:{}}):{version:ie,entries:Zt(a.entries,o)}}catch{return dt(d,{force:!0}),{version:ie,entries:{}}}}function to(o){let d=ut();qt(zt(d),{recursive:!0}),Ut(d,JSON.stringify(o,null,2)+`
3
- `)}function oo(o,d){let a=d.trim()||"default";return`${o}:${a}`}function ke(o,d,a,l={}){let f=l.nowMs??Date.now(),i=l.cooldownMs??Qt,y=eo(f),S=oo(o,d),I=y.entries[S];return I&&I.signature===a&&f-I.updatedAt<i?!1:(y.entries[S]={signature:a,updatedAt:f},to(y),!0)}async function mt(o,d={args:[]}){let a=await Je(o);if(D(d.args)){B(a);return}console.log(` nodes: ${a.nodes}`)}function Te(o,d){let a=o.indexOf(d);return a>=0&&a+1<o.length?o[a+1]:null}async function pt(o){let{bridge:d,args:a,positional:l}=o,f=a.includes("--verbose")||a.includes("-v"),i=D(a),y=f&&!i,S=a.includes("--watch")||a.includes("-w"),I=1e3,k=a.includes("--compact"),b=a.includes("--no-xy"),v=Te(a,"--testid-like"),_=Te(a,"--only"),T=Te(a,"--subtree"),C=l[1],c=C?/[*?]/.test(C):!1,J=!c&&!_?C:void 0,K=_??(c?C:void 0),E=async()=>{await de(d,{verbose:y});let z=await He(d,{describe:!0,verbose:f,filter:J||"",testIdLike:v||void 0,onlyGlob:K||void 0,subtreeRoot:T||void 0,compact:k,hideXy:b}),q=z?.tree,w=z?.shell,M=z?.keyboard;if(i){B({shell:w,tree:q??"",keyboard:M});return}if(w&&typeof w=="object"){let P=[w.state?`state=${w.state}`:null,w.activeApp?`app=${w.activeApp}`:null,w.showSwitcher?"switcher":null,w.switcherPhase&&w.switcherPhase!=="idle"?`phase=${w.switcherPhase}`:null].filter(Boolean);P.length>0&&console.log(` shell: ${P.join(" ")}`)}if(typeof q=="string"&&q.startsWith("__SUBTREE_NOT_FOUND__:")){let P=q.slice(22);console.log(` subtree root not found: ${P}`),G("subtree-root-not-found",P);return}if(!q){let P=z?.nodeCount??0;console.log(" no matching nodes found"),!(J||v||K||T)&&P<10&&G("app-still-loading",P);return}if(console.log(q),!(J||v||K||T)&&!S&&q.split(`
1
+ /*! sootsim v0.1.53 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as G}from"./chunk-RBXJA2PW.js";import{a as je,b as Je}from"./chunk-ZYITMTYD.js";import{a as X,b as D,c as B,d as Y,e as de,f as re,g as it,h as at,i as ve}from"./chunk-ELEP2COQ.js";import{B as se,C as nt,I as rt,a as Le,b as We,c as qe,d as He,e as Ue,f as Ke,g as xe,h as Se,m as ze,n as Ye,o as Ge,p as Xe,q as Ve,r as Qe,s as Ze,t as et,u as tt,v as ot,z as st}from"./chunk-QTVGSFY6.js";import{a as De,g as ce}from"./chunk-7ZHWA3WD.js";import{b as lt,c as ct,i as dt}from"./chunk-BPXSSZJS.js";import"./chunk-WXOAHKCZ.js";import{a as Be}from"./chunk-6JZNIGOQ.js";import"./chunk-6A4CZMPO.js";import"./chunk-AYU6WUNF.js";import"./chunk-NIHI6NXE.js";import"./chunk-7IYYIF5B.js";import"./chunk-YEE4EO2P.js";import{a as be,c as we,d as Ae}from"./chunk-XC3T7UDH.js";import{a as Fe}from"./chunk-CKZSGUTE.js";import{c as Oe,e as Re,f as Ee,g as Ce,h as $e}from"./chunk-GWGF4J4Y.js";import{b as Pe}from"./chunk-STWL7EXR.js";import"./chunk-YCPH4ZTS.js";import"./chunk-E3S6U2QR.js";import"./chunk-LELB2PV3.js";import{existsSync as qt,mkdirSync as Ht,readFileSync as Ut,rmSync as ut,writeFileSync as Kt}from"fs";import{tmpdir as zt}from"os";import{dirname as Yt,join as Gt,resolve as Xt}from"path";var ie=1,Vt="SOOTSIM_INSPECT_NOTICE_PATH",Qt=300*1e3,Zt=15e3;function mt(){return Xt(process.env[Vt]||Gt(zt(),"sootsim-inspect-notice-state.json"))}function eo(o,d){return Object.fromEntries(Object.entries(o).filter(([,i])=>typeof i?.signature=="string"&&Number.isFinite(i?.updatedAt)&&d-i.updatedAt<=Qt))}function to(o){let d=mt();if(!qt(d))return{version:ie,entries:{}};try{let i=JSON.parse(Ut(d,"utf8"));return i.version!==ie||!i.entries||typeof i.entries!="object"?(ut(d,{force:!0}),{version:ie,entries:{}}):{version:ie,entries:eo(i.entries,o)}}catch{return ut(d,{force:!0}),{version:ie,entries:{}}}}function oo(o){let d=mt();Ht(Yt(d),{recursive:!0}),Kt(d,JSON.stringify(o,null,2)+`
3
+ `)}function so(o,d){let i=d.trim()||"default";return`${o}:${i}`}function ke(o,d,i,l={}){let f=l.nowMs??Date.now(),a=l.cooldownMs??Zt,y=to(f),S=so(o,d),I=y.entries[S];return I&&I.signature===i&&f-I.updatedAt<a?!1:(y.entries[S]={signature:i,updatedAt:f},oo(y),!0)}async function pt(o,d={args:[]}){let i=await Le(o);if(D(d.args)){B(i);return}console.log(` nodes: ${i.nodes}`)}function Te(o,d){let i=o.indexOf(d);return i>=0&&i+1<o.length?o[i+1]:null}async function ft(o){let{bridge:d,args:i,positional:l}=o,f=i.includes("--verbose")||i.includes("-v"),a=D(i),y=f&&!a,S=i.includes("--watch")||i.includes("-w"),I=1e3,k=i.includes("--compact"),b=i.includes("--no-xy"),v=Te(i,"--testid-like"),_=Te(i,"--only"),T=Te(i,"--subtree"),C=l[1],c=C?/[*?]/.test(C):!1,L=!c&&!_?C:void 0,K=_??(c?C:void 0),E=async()=>{await de(d,{verbose:y});let z=await He(d,{describe:!0,verbose:f,filter:L||"",testIdLike:v||void 0,onlyGlob:K||void 0,subtreeRoot:T||void 0,compact:k,hideXy:b}),q=z?.tree,w=z?.shell,M=z?.keyboard;if(a){B({shell:w,tree:q??"",keyboard:M});return}if(w&&typeof w=="object"){let P=[w.state?`state=${w.state}`:null,w.activeApp?`app=${w.activeApp}`:null,w.showSwitcher?"switcher":null,w.switcherPhase&&w.switcherPhase!=="idle"?`phase=${w.switcherPhase}`:null].filter(Boolean);P.length>0&&console.log(` shell: ${P.join(" ")}`)}if(typeof q=="string"&&q.startsWith("__SUBTREE_NOT_FOUND__:")){let P=q.slice(22);console.log(` subtree root not found: ${P}`),G("subtree-root-not-found",P);return}if(!q){let P=z?.nodeCount??0;console.log(" no matching nodes found"),!(L||v||K||T)&&P<10&&G("app-still-loading",P);return}if(console.log(q),!(L||v||K||T)&&!S&&q.split(`
4
4
  `).length>=80&&G("describe-use-filters"),M&&M.visible){let P=M.spec,V=[P?.keyboardType?`type=${P.keyboardType}`:null,P?.returnKeyType&&P.returnKeyType!=="default"?`return=${P.returnKeyType}`:null,M.mode!=="letters"?`mode=${M.mode}`:null,M.shifted?"shift":null,M.capsLock?"caps":null,P?.autoCapitalize&&P.autoCapitalize!=="sentences"?`autoCap=${P.autoCapitalize}`:null,M.accessoryBarId?`accessory=${M.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 E(),await X(I);else await E()}var so=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function ft(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let o of so){let d=process.env[o];if(d&&d.trim()&&d!=="0")return!0}return!1}async function gt(o){let{bridge:d,args:a,effectiveArgs:l,positional:f,inspectUsage:i}=o,y=w=>{let M=l.indexOf(w);return M>=0&&M+1<l.length?l[M+1]:null},S=w=>l.includes(w),I=y("--testid")||y("--test-id"),k=y("--role"),b=y("--type"),v=y("--text"),_=S("--pressable"),T=S("--visible"),C=S("--interactive-targets")||S("--actions"),c=!I&&!k&&!b&&!v&&!_&&!T&&!C?f[1]:null,J=v??c,K=await Ue(d,{testId:I,role:k,type:b,text:J,pressable:_,visible:T,interactive:C});K||(console.error(i("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:E,result:L}=K,z=D(a),q=a.includes("--verbose")||a.includes("--dump");if(z)E==="interactive-targets"&&Array.isArray(L)?B($e(L).map(w=>({...w,tap:Se(w)}))):B(L??null);else if(Array.isArray(L))if(L.length===0){console.log(` no ${E} nodes found`);let w=await d.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof w=="number"&&w<10&&G("app-still-loading",w)}else if(E==="interactive-targets"){let w=$e(L);console.log(` found ${w.length} interactive target${w.length===1?"":"s"} (sorted by score):`);for(let M of w.slice(0,20)){let Z=M.absolutePosition?`@(${Math.round(M.absolutePosition.x)},${Math.round(M.absolutePosition.y)})`:"",P=M.layout?`${Math.round(M.layout.width)}x${Math.round(M.layout.height)}`:"?x?",V=M.text?` "${M.text.slice(0,30)}"`:"",ee=M.testID?` #${M.testID}`:"",oe=M.accessibilityLabel?` \u24D8"${String(M.accessibilityLabel).slice(0,24)}"`:"",ye=M.accessibilityRole?`[${M.accessibilityRole}]`:M.type,e=Se(M);console.log(` ${ye}${V}${oe}${ee} ${P} ${Z}`),console.log(` \u2192 ${e}`),q&&console.log(Me(JSON.stringify(M,null,2)," "))}w.length>20&&console.log(` ... and ${w.length-20} more`)}else{console.log(` found ${L.length} node${L.length===1?"":"s"} (${E}):`);for(let w of L.slice(0,20)){let M=w.absolutePosition?`@(${Math.round(w.absolutePosition.x)},${Math.round(w.absolutePosition.y)})`:"",Z=w.layout?`${Math.round(w.layout.width)}x${Math.round(w.layout.height)}`:"?x?",P=w.text?` "${w.text.slice(0,30)}"`:"",V=w.testID?` #${w.testID}`:"",ee=w.pressable?" (tap)":"",oe=w.accessibilityRole?`[${w.accessibilityRole}]`:w.type;console.log(` ${oe}${P}${V} ${Z} ${M}${ee}`),q&&console.log(Me(JSON.stringify(w,null,2)," "))}L.length>20&&console.log(` ... and ${L.length-20} more`)}else if(L==null)console.log(` not found: ${J||I||k||b||""||E}`),I&&G("wait-selector-for-missing-testid",I);else{let w=L;if(w.type&&w.absolutePosition){let M=`@(${Math.round(w.absolutePosition.x)},${Math.round(w.absolutePosition.y)})`,Z=w.layout?`${Math.round(w.layout.width)}x${Math.round(w.layout.height)}`:"?x?",P=w.text?` "${w.text.slice(0,40)}"`:"",V=w.testID?` #${w.testID}`:"",ee=w.pressable?" (tap)":"",oe=w.accessibilityRole?`[${w.accessibilityRole}]`:w.type;console.log(` ${oe}${P}${V} ${Z} ${M}${ee}`),q&&console.log(Me(JSON.stringify(w,null,2)," "))}else console.log(JSON.stringify(L,null,2))}}function Me(o,d){return o.split(`
7
- `).map(a=>d+a).join(`
8
- `)}async function yt(o,d={}){let a=await ot(o);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:f,mode:i,shifted:y,capsLock:S,accessoryBarId:I}=a,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: ${i}${y?" (shifted)":""}${S?" (caps)":""}`),I&&k.push(` accessoryBar: ${I}`),console.log(k.join(`
9
- `))}async function ht(o){let d=await o.bridge.listSims();if(D(o.args)){B(d.map(a=>({...a,active:a.id===o.simId})));return}ct(d,o.simId)}function te(o){return o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}KB`:`${(o/1024/1024).toFixed(1)}MB`}function ue(o,d){return d<=0?"?":`${(o/d*100).toFixed(0)}%`}async function bt(o,d={args:[]}){let a=await nt(o);if(D(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} (${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(a.workerHeap){let l=a.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(a.hostHeap){let l=a.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(o){let d=o.indexOf("--testid");if(d>=0&&o[d+1])return{mode:"testid",value:o[d+1]};let a=o.indexOf("--test-id");if(a>=0&&o[a+1])return{mode:"testid",value:o[a+1]};let l=o.indexOf("--text");return l>=0&&o[l+1]?{mode:"text",value:o[l+1]}:null}async function me(o,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 o.send({type:"evaluate",code:`(async () => {
6
+ `);;)console.clear(),await E(),await X(I);else await E()}var no=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function gt(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let o of no){let d=process.env[o];if(d&&d.trim()&&d!=="0")return!0}return!1}async function yt(o){let{bridge:d,args:i,effectiveArgs:l,positional:f,inspectUsage:a}=o,y=w=>{let M=l.indexOf(w);return M>=0&&M+1<l.length?l[M+1]:null},S=w=>l.includes(w),I=y("--testid")||y("--test-id"),k=y("--role"),b=y("--type"),v=y("--text"),_=S("--pressable"),T=S("--visible"),C=S("--interactive-targets")||S("--actions"),c=!I&&!k&&!b&&!v&&!_&&!T&&!C?f[1]:null,L=v??c,K=await Ke(d,{testId:I,role:k,type:b,text:L,pressable:_,visible:T,interactive:C});K||(console.error(a("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:E,result:J}=K,z=D(i),q=i.includes("--verbose")||i.includes("--dump");if(z)E==="interactive-targets"&&Array.isArray(J)?B(xe(J).map(w=>({...w,tap:Se(w)}))):B(J??null);else if(Array.isArray(J))if(J.length===0){console.log(` no ${E} nodes found`);let w=await d.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof w=="number"&&w<10&&G("app-still-loading",w)}else if(E==="interactive-targets"){let w=xe(J);console.log(` found ${w.length} interactive target${w.length===1?"":"s"} (sorted by score):`);for(let M of w.slice(0,20)){let Z=M.absolutePosition?`@(${Math.round(M.absolutePosition.x)},${Math.round(M.absolutePosition.y)})`:"",P=M.layout?`${Math.round(M.layout.width)}x${Math.round(M.layout.height)}`:"?x?",V=M.text?` "${M.text.slice(0,30)}"`:"",ee=M.testID?` #${M.testID}`:"",oe=M.accessibilityLabel?` \u24D8"${String(M.accessibilityLabel).slice(0,24)}"`:"",ye=M.accessibilityRole?`[${M.accessibilityRole}]`:M.type,e=Se(M);console.log(` ${ye}${V}${oe}${ee} ${P} ${Z}`),console.log(` \u2192 ${e}`),q&&console.log(Me(JSON.stringify(M,null,2)," "))}w.length>20&&console.log(` ... and ${w.length-20} more`)}else{console.log(` found ${J.length} node${J.length===1?"":"s"} (${E}):`);for(let w of J.slice(0,20)){let M=w.absolutePosition?`@(${Math.round(w.absolutePosition.x)},${Math.round(w.absolutePosition.y)})`:"",Z=w.layout?`${Math.round(w.layout.width)}x${Math.round(w.layout.height)}`:"?x?",P=w.text?` "${w.text.slice(0,30)}"`:"",V=w.testID?` #${w.testID}`:"",ee=w.pressable?" (tap)":"",oe=w.accessibilityRole?`[${w.accessibilityRole}]`:w.type;console.log(` ${oe}${P}${V} ${Z} ${M}${ee}`),q&&console.log(Me(JSON.stringify(w,null,2)," "))}J.length>20&&console.log(` ... and ${J.length-20} more`)}else if(J==null)console.log(` not found: ${L||I||k||b||""||E}`),I&&G("wait-selector-for-missing-testid",I);else{let w=J;if(w.type&&w.absolutePosition){let M=`@(${Math.round(w.absolutePosition.x)},${Math.round(w.absolutePosition.y)})`,Z=w.layout?`${Math.round(w.layout.width)}x${Math.round(w.layout.height)}`:"?x?",P=w.text?` "${w.text.slice(0,40)}"`:"",V=w.testID?` #${w.testID}`:"",ee=w.pressable?" (tap)":"",oe=w.accessibilityRole?`[${w.accessibilityRole}]`:w.type;console.log(` ${oe}${P}${V} ${Z} ${M}${ee}`),q&&console.log(Me(JSON.stringify(w,null,2)," "))}else console.log(JSON.stringify(J,null,2))}}function Me(o,d){return o.split(`
7
+ `).map(i=>d+i).join(`
8
+ `)}async function ht(o,d={}){let i=await st(o);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:I}=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)":""}`),I&&k.push(` accessoryBar: ${I}`),console.log(k.join(`
9
+ `))}async function bt(o){let d=await o.bridge.listSims();if(D(o.args)){B(d.map(i=>({...i,active:i.id===o.simId})));return}dt(d,o.simId)}function te(o){return o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}KB`:`${(o/1024/1024).toFixed(1)}MB`}function ue(o,d){return d<=0?"?":`${(o/d*100).toFixed(0)}%`}async function wt(o,d={args:[]}){let i=await rt(o);if(D(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(o){let d=o.indexOf("--testid");if(d>=0&&o[d+1])return{mode:"testid",value:o[d+1]};let i=o.indexOf("--test-id");if(i>=0&&o[i+1])return{mode:"testid",value:o[i+1]};let l=o.indexOf("--text");return l>=0&&o[l+1]?{mode:"text",value:o[l+1]}:null}async function me(o,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 o.send({type:"evaluate",code:`(async () => {
10
10
  const t = window.__sootsimTest
11
11
  if (!t) return null
12
12
  const n = ${l}
@@ -24,11 +24,11 @@ import{a as G}from"./chunk-3DDSYQHM.js";import{a as je,b as Le}from"./chunk-EXQJ
24
24
  ? resolved.cy
25
25
  : n.absolutePosition.y + (n.layout.height || 0) / 2
26
26
  return { x: cx, y: cy, testID: n.testID, text: n.text }
27
- })()`})??null}async function wt(o,d={}){let{nav:a,keyboard:l,shell:f}=await st(o);if(d.json){console.log(JSON.stringify({shell:f??null,nav:a,keyboard:l},null,2));return}let i=[];if(f){let y=f.activeApp??f.state??"<none>",S=f.showSwitcher?" (app switcher open)":"",I=typeof f.launchProgress=="number"&&f.launchProgress<.98?` launching (${Math.round(f.launchProgress*100)}%)`:"";i.push(`shell: ${y}${S}${I}`)}else i.push("shell: <unavailable>");if(a){let y=a.transitionPhase!=="idle"?` (${a.transitionPhase}, ${a.activeTransitionCount} active)`:"";if(i.push(`nav: phase=${a.transitionPhase}${y}`),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 y=l.spec?.keyboardType??"default",S=l.spec?.returnKeyType??"default";i.push(`keyboard: visible (${y}, return=${S}, mode=${l.mode??"?"})`)}else i.push("keyboard: hidden");console.log(i.join(`
28
- `))}async function se({bridge:o,maxMs:d,pollMs:a=50,stablePolls:l=3,strict:f=!1}){let i=await o.send({type:"evaluate",code:`(async () => {
27
+ })()`})??null}async function $t(o,d={}){let{nav:i,keyboard:l,shell:f}=await nt(o);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)":"",I=typeof f.launchProgress=="number"&&f.launchProgress<.98?` launching (${Math.round(f.launchProgress*100)}%)`:"";a.push(`shell: ${y}${S}${I}`)}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 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}`:"";a.push(` ${I} #${S.id}${k}${b}${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(`
28
+ `))}async function ne({bridge:o,maxMs:d,pollMs:i=50,stablePolls:l=3,strict:f=!1}){let a=await o.send({type:"evaluate",code:`(async () => {
29
29
  const start = Date.now()
30
30
  const deadline = start + ${Math.max(0,Math.round(d))}
31
- const pollMs = ${Math.max(1,Math.round(a))}
31
+ const pollMs = ${Math.max(1,Math.round(i))}
32
32
  const requiredStablePolls = ${Math.max(1,Math.round(l))}
33
33
  const strict = ${f?"true":"false"}
34
34
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
@@ -74,12 +74,12 @@ import{a as G}from"./chunk-3DDSYQHM.js";import{a as je,b as Le}from"./chunk-EXQJ
74
74
  await sleep(pollMs)
75
75
  }
76
76
  return { settled: false, elapsed: Date.now() - start }
77
- })()`}),{elapsed:y,settled:S}=i??{};return{elapsed:typeof y=="number"?y:d,settled:S===!0}}async function xt(o){let{bridge:d,args:a,positional:l}=o,f=l[1]?Number(l[1])*1e3:3e3,i=a.includes("--strict"),{elapsed:y,settled:S}=await se({bridge:d,maxMs:f,strict:i});console.log(S?` settled in ${y}ms`:` timed out after ${y}ms (may still be animating)`)}async function $t(o){let d=o.positional[1]?Number(o.positional[1]):.5;(!Number.isFinite(d)||d<0)&&(console.error(o.inspectUsage("sleep","[seconds]")),process.exit(1)),await X(d*1e3),console.log(` slept ${d}s`)}async function St(o){let{bridge:d,args:a,positional:l}=o,f=l[1]?Number(l[1]):5,{tree:i}=await We(d,f);if(D(a)){B({depth:f,tree:i??null});return}console.log(typeof i=="string"?i:JSON.stringify(i,null,2))}async function vt(o,d={args:[]}){let a=await qe(o);if(D(d.args)){B(a);return}console.log(a.url)}async function kt(o){let{wsPort:d,commandTimeoutMs:a,simId:l,positional:f}=o,i=f[1]?Number(f[1]):30,y=Math.max(1e3,(Number.isFinite(i)?i:30)*1e3),S=Math.max(1,Math.ceil(y/500));console.log(" waiting for sim reconnect...");let I=await rt(d,a,l,{attempts:S});I||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),I.bridge.close(),ce({source:"inspect wait",step:{wait:y},summary:`wait ${Math.round(y/1e3)}s`}),console.log(` ready: ${I.count} nodes`)}var Tt=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(o,d){let a=o.indexOf(d);if(a>=0&&a+1<o.length)return o[a+1]}function no(o,d){if(!d.filter&&!d.equals)return!0;let a=o.data,l=[];if(a&&typeof a=="object")for(let i of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let y=a[i];typeof y=="string"&&y.length>0&&l.push(y)}let f=l.join(" ");return d.equals?l.some(i=>i===d.equals):d.filter?f.toLowerCase().includes(d.filter.toLowerCase()):!0}async function Mt(o){let{bridge:d,args:a,positional:l,inspectUsage:f}=o,i=l[1];i||(console.error(f("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),Tt.has(i)||console.error(` warning: '${i}' is not a known timeline kind \u2014 waiting anyway. known: ${[...Tt].sort().join(", ")}`);let y=pe(a,"--max-ms"),S=y&&Number.isFinite(Number(y))?Math.max(100,Number(y)):5e3,I=pe(a,"--filter"),k=pe(a,"--equals"),b=pe(a,"--since")??"now",v=a.includes("--json"),_=Date.now(),T=_+S,C=200,c=_;for(;Date.now()<T;){let K={kinds:[i],since:b==="cursor"?void 0:c,limit:50},E=await d.send({type:"evaluate",code:`(async () => {
77
+ })()`}),{elapsed:y,settled:S}=a??{};return{elapsed:typeof y=="number"?y:d,settled:S===!0}}async function xt(o){let{bridge:d,args:i,positional:l}=o,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 St(o){let d=o.positional[1]?Number(o.positional[1]):.5;(!Number.isFinite(d)||d<0)&&(console.error(o.inspectUsage("sleep","[seconds]")),process.exit(1)),await X(d*1e3),console.log(` slept ${d}s`)}async function vt(o){let{bridge:d,args:i,positional:l}=o,f=l[1]?Number(l[1]):5,{tree:a}=await We(d,f);if(D(i)){B({depth:f,tree:a??null});return}console.log(typeof a=="string"?a:JSON.stringify(a,null,2))}async function kt(o,d={args:[]}){let i=await qe(o);if(D(d.args)){B(i);return}console.log(i.url)}async function Tt(o){let{wsPort:d,commandTimeoutMs:i,simId:l,positional:f}=o,a=f[1]?Number(f[1]):30,y=Math.max(1e3,(Number.isFinite(a)?a:30)*1e3),S=Math.max(1,Math.ceil(y/500));console.log(" waiting for sim reconnect...");let I=await it(d,i,l,{attempts:S});I||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),I.bridge.close(),ce({source:"inspect wait",step:{wait:y},summary:`wait ${Math.round(y/1e3)}s`}),console.log(` ready: ${I.count} nodes`)}var Mt=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(o,d){let i=o.indexOf(d);if(i>=0&&i+1<o.length)return o[i+1]}function ro(o,d){if(!d.filter&&!d.equals)return!0;let i=o.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(o){let{bridge:d,args:i,positional:l,inspectUsage:f}=o,a=l[1];a||(console.error(f("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),Mt.has(a)||console.error(` warning: '${a}' is not a known timeline kind \u2014 waiting anyway. known: ${[...Mt].sort().join(", ")}`);let y=pe(i,"--max-ms"),S=y&&Number.isFinite(Number(y))?Math.max(100,Number(y)):5e3,I=pe(i,"--filter"),k=pe(i,"--equals"),b=pe(i,"--since")??"now",v=i.includes("--json"),_=Date.now(),T=_+S,C=200,c=_;for(;Date.now()<T;){let K={kinds:[a],since:b==="cursor"?void 0:c,limit:50},E=await d.send({type:"evaluate",code:`(async () => {
78
78
  const t = window.SootSim?.bridges?.timeline
79
79
  if (!t) return { ok: false, error: 'timeline bridge missing' }
80
80
  return { ok: true, result: await t.recent(${JSON.stringify(K)}) }
81
- })()`});(!E||!E.ok)&&(console.error(` could not query timeline: ${E&&"error"in E?E.error:"unknown"}`),process.exit(1));let L=E.result.events??[];for(let z of L)if(no(z,{filter:I,equals:k})){let q=Date.now()-_;console.log(v?JSON.stringify({found:!0,elapsedMs:q,event:z}):` ${i} event after ${q}ms${I?` (filter: ${I})`:""}${k?` (equals: ${k})`:""}`);return}E.result.watermark&&E.result.watermark>c&&(c=E.result.watermark),await new Promise(z=>setTimeout(z,C))}let J=Date.now()-_;v?console.log(JSON.stringify({found:!1,elapsedMs:J,kind:i,filter:I,equals:k})):console.error(` \u26A0 wait event ${i} timed out after ${J}ms${I?` (filter: ${I})`:""}${k?` (equals: ${k})`:""}`),process.exit(1)}async function Nt(o){let{bridge:d,args:a}=o,l=a.includes("--strict"),f=a.indexOf("--max-ms"),i=f>=0&&a[f+1]?Math.max(100,Number(a[f+1])):3e3,{elapsed:y,settled:S}=await se({bridge:d,maxMs:i,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 It(o){let{bridge:d,args:a}=o,l=2e4,f=a.indexOf("--max-ms");f>=0&&a[f+1]&&(l=Math.max(100,Number(a[f+1])));let{ready:i,elapsedMs:y,nodes:S}=await Ke(d,l);if(i){console.log(` ready in ${y}ms: ${S} nodes (flag)`);return}console.error(` \u26A0 wait ready timed out after ${y}ms \u2014 guest app did not emit sootsim:externalAppReady (nodes: ${S})`),process.exit(1)}async function _t(o){let{bridge:d,args:a,positional:l,inspectUsage:f}=o,i=l[1];i||(console.error(f("wait selector","<testid> [--max-ms 5000]")),process.exit(1));let y=a.indexOf("--max-ms"),S=y>=0&&a[y+1]?Math.max(100,Number(a[y+1])):5e3,{found:I,node:k,elapsed:b}=await ze(d,i,S);if(I&&k){let v=k.absolutePosition?`@(${Math.round(k.absolutePosition.x)},${Math.round(k.absolutePosition.y)})`:"",_=k.layout?`${Math.round(k.layout.width)}x${Math.round(k.layout.height)}`:"?x?";console.log(` found #${i} in ${b}ms ${_} ${v}`)}else console.error(` \u26A0 wait selector #${i} timed out after ${b??S}ms`),process.exit(1)}function Et(o){return o==null?"\u2014":o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}K`:`${(o/1024/1024).toFixed(1)}M`}function Ct(o){return o==null?" \u2026":o<1e3?`${o}ms`.padStart(5):`${(o/1e3).toFixed(2)}s`.padStart(5)}function io(o){return o.error?"err":o.status==null?" \u2026 ":String(o.status)}function Ft(o){let d=new Date(o.startTs).toLocaleTimeString(),a=io(o).padEnd(3),l=o.method.padEnd(5),f=Et(o.size).padStart(6),i=Ct(o.durationMs);console.log(` [${d}] ${a} ${l} ${f} ${i} ${o.displayUrl}`),o.error&&console.log(` error: ${o.error}`)}function ao(o){let d=[["id",o.id],["source",o.source],["kind",o.kind],["method",o.method],["status",o.error?`error: ${o.error}`:`${o.status??"\u2014"} ${o.statusText??""}`.trim()],["url",o.url],["started",new Date(o.startTs).toLocaleTimeString()],["duration",Ct(o.durationMs).trim()],["size",Et(o.size)],["content-type",o.type??"\u2014"]];for(let[a,l]of d)console.log(` ${a.padEnd(13)} ${l}`)}var lo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},At="\x1B[0m",co="\x1B[2m";function Pt(o,d){let a=new Date(o.ts).toLocaleTimeString(),l=o.level.toUpperCase().padEnd(5),f=o.args.join(" ");if(d){let i=lo[o.level];console.log(` ${co}[${a}]${At} ${i}${l}${At} ${f}`)}else console.log(` [${a}] ${l} ${f}`);if(o.stack&&o.level==="error"){let i=o.stack.split(`
82
- `).slice(0,5);for(let y of i)console.log(` ${y.trim()}`)}}var Q="__sootsimCliPerf",uo=120;async function Ot(o,d){let a=o.find((_,T)=>o[T-1]==="--id"),l=o.find((_,T)=>o[T-1]==="--text");if(a||l){let _=await d.send({type:"evaluate",code:je({id:a,text:l})});if(!_)throw new Error(a?`no node with id "${a}"`:`no node matching text "${l}"`);let{x:T,y:C,w:c,h:J}=_;return{x:T,y:C,w:c,h:J}}let f=o.find((_,T)=>o[T-1]==="--area");if(f){let _=f.split(",").map(K=>Number(K.trim()));if(_.length!==4||_.some(K=>!Number.isFinite(K)))throw new Error(`--area expects x,y,w,h (got "${f}")`);let[T,C,c,J]=_;return{x:T,y:C,w:c,h:J}}let i=_=>{let T=o.find((c,J)=>o[J-1]===_);if(T==null)return null;let C=Number(T);return Number.isFinite(C)?C:null},y=i("--x"),S=i("--y"),I=i("--w"),k=i("--h");if(y!=null||S!=null||I!=null||k!=null)return{x:y??0,y:S??0,w:I??1,h:k??1};let v=o.filter((_,T)=>T>0&&!_.startsWith("-")&&o[T-1]!=="--output"&&o[T-1]!=="--area"&&o[T-1]!=="--id"&&o[T-1]!=="--text"&&o[T-1]!=="--x"&&o[T-1]!=="--y"&&o[T-1]!=="--w"&&o[T-1]!=="--h").map(Number).filter(_=>Number.isFinite(_));if(v.length>=2){let[_,T,C=1,c=1]=v;return{x:_,y:T,w:C,h:c}}return null}function Ne(o){let d={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let a of o)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 f="\u2588".repeat(Math.ceil(l/o.length*40));console.log(` ${a.padEnd(6)} ${f} ${l}`)}}async function fe(o,d,a){let l=Date.now()+d,f=await ne(o,d);for(;;){if(a(f))return{settled:!0,state:f};if(Date.now()>=l)return{settled:!1,state:f};await X(16),f=await ne(o)}}async function _e(o){return o.send({type:"evaluate",code:`(async () => {
81
+ })()`});(!E||!E.ok)&&(console.error(` could not query timeline: ${E&&"error"in E?E.error:"unknown"}`),process.exit(1));let J=E.result.events??[];for(let z of J)if(ro(z,{filter:I,equals:k})){let q=Date.now()-_;console.log(v?JSON.stringify({found:!0,elapsedMs:q,event:z}):` ${a} event after ${q}ms${I?` (filter: ${I})`:""}${k?` (equals: ${k})`:""}`);return}E.result.watermark&&E.result.watermark>c&&(c=E.result.watermark),await new Promise(z=>setTimeout(z,C))}let L=Date.now()-_;v?console.log(JSON.stringify({found:!1,elapsedMs:L,kind:a,filter:I,equals:k})):console.error(` \u26A0 wait event ${a} timed out after ${L}ms${I?` (filter: ${I})`:""}${k?` (equals: ${k})`:""}`),process.exit(1)}async function It(o){let{bridge:d,args:i}=o,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(o){let{bridge:d,args:i}=o,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}=await ze(d,l);if(a){console.log(` ready in ${y}ms: ${S} nodes (flag)`);return}console.error(` \u26A0 wait ready timed out after ${y}ms \u2014 guest app did not emit sootsim:externalAppReady (nodes: ${S})`),process.exit(1)}async function Ft(o){let{bridge:d,args:i,positional:l,inspectUsage:f}=o,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:I,node:k,elapsed:b}=await Ye(d,a,S);if(I&&k){let v=k.absolutePosition?`@(${Math.round(k.absolutePosition.x)},${Math.round(k.absolutePosition.y)})`:"",_=k.layout?`${Math.round(k.layout.width)}x${Math.round(k.layout.height)}`:"?x?";console.log(` found #${a} in ${b}ms ${_} ${v}`)}else console.error(` \u26A0 wait selector #${a} timed out after ${b??S}ms`),process.exit(1)}function Ct(o){return o==null?"\u2014":o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}K`:`${(o/1024/1024).toFixed(1)}M`}function Dt(o){return o==null?" \u2026":o<1e3?`${o}ms`.padStart(5):`${(o/1e3).toFixed(2)}s`.padStart(5)}function ao(o){return o.error?"err":o.status==null?" \u2026 ":String(o.status)}function At(o){let d=new Date(o.startTs).toLocaleTimeString(),i=ao(o).padEnd(3),l=o.method.padEnd(5),f=Ct(o.size).padStart(6),a=Dt(o.durationMs);console.log(` [${d}] ${i} ${l} ${f} ${a} ${o.displayUrl}`),o.error&&console.log(` error: ${o.error}`)}function lo(o){let d=[["id",o.id],["source",o.source],["kind",o.kind],["method",o.method],["status",o.error?`error: ${o.error}`:`${o.status??"\u2014"} ${o.statusText??""}`.trim()],["url",o.url],["started",new Date(o.startTs).toLocaleTimeString()],["duration",Dt(o.durationMs).trim()],["size",Ct(o.size)],["content-type",o.type??"\u2014"]];for(let[i,l]of d)console.log(` ${i.padEnd(13)} ${l}`)}var co={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Pt="\x1B[0m",uo="\x1B[2m";function Ot(o,d){let i=new Date(o.ts).toLocaleTimeString(),l=o.level.toUpperCase().padEnd(5),f=o.args.join(" ");if(d){let a=co[o.level];console.log(` ${uo}[${i}]${Pt} ${a}${l}${Pt} ${f}`)}else console.log(` [${i}] ${l} ${f}`);if(o.stack&&o.level==="error"){let a=o.stack.split(`
82
+ `).slice(0,5);for(let y of a)console.log(` ${y.trim()}`)}}var Q="__sootsimCliPerf",mo=120;async function Rt(o,d){let i=o.find((_,T)=>o[T-1]==="--id"),l=o.find((_,T)=>o[T-1]==="--text");if(i||l){let _=await d.send({type:"evaluate",code:je({id:i,text:l})});if(!_)throw new Error(i?`no node with id "${i}"`:`no node matching text "${l}"`);let{x:T,y:C,w:c,h:L}=_;return{x:T,y:C,w:c,h:L}}let f=o.find((_,T)=>o[T-1]==="--area");if(f){let _=f.split(",").map(K=>Number(K.trim()));if(_.length!==4||_.some(K=>!Number.isFinite(K)))throw new Error(`--area expects x,y,w,h (got "${f}")`);let[T,C,c,L]=_;return{x:T,y:C,w:c,h:L}}let a=_=>{let T=o.find((c,L)=>o[L-1]===_);if(T==null)return null;let C=Number(T);return Number.isFinite(C)?C:null},y=a("--x"),S=a("--y"),I=a("--w"),k=a("--h");if(y!=null||S!=null||I!=null||k!=null)return{x:y??0,y:S??0,w:I??1,h:k??1};let v=o.filter((_,T)=>T>0&&!_.startsWith("-")&&o[T-1]!=="--output"&&o[T-1]!=="--area"&&o[T-1]!=="--id"&&o[T-1]!=="--text"&&o[T-1]!=="--x"&&o[T-1]!=="--y"&&o[T-1]!=="--w"&&o[T-1]!=="--h").map(Number).filter(_=>Number.isFinite(_));if(v.length>=2){let[_,T,C=1,c=1]=v;return{x:_,y:T,w:C,h:c}}return null}function Ne(o){let d={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let i of o)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/o.length*40));console.log(` ${i.padEnd(6)} ${f} ${l}`)}}async function fe(o,d,i){let l=Date.now()+d,f=await se(o,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(o)}}async function _e(o){return o.send({type:"evaluate",code:`(async () => {
83
83
  const kb = window.__sootsimKeyboard
84
84
  const test = window.__sootsimTest
85
85
  if (!kb) return { error: 'keyboard bridge not available' }
@@ -111,8 +111,8 @@ import{a as G}from"./chunk-3DDSYQHM.js";import{a as je,b as Le}from"./chunk-EXQJ
111
111
  frame: runtimeSnapshot?.keyboard?.frame ?? null,
112
112
  focusedRect: runtimeSnapshot?.focused?.rect ?? null,
113
113
  }
114
- })()`})}async function mo(o,d=600){let a=Date.now()+d;for(;Date.now()<=a;){let l=await _e(o);if(l.visible)return l;await X(30)}return _e(o)}async function ge(o,d){let a=await _e(o);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 Rt(o,d,a){return d==="appearance"?o.send({type:"evaluate",code:`(async () => {
115
- const requested = ${JSON.stringify(a??"toggle")}
114
+ })()`})}async function po(o,d=600){let i=Date.now()+d;for(;Date.now()<=i;){let l=await _e(o);if(l.visible)return l;await X(30)}return _e(o)}async function ge(o,d){let i=await _e(o);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 Et(o,d,i){return d==="appearance"?o.send({type:"evaluate",code:`(async () => {
115
+ const requested = ${JSON.stringify(i??"toggle")}
116
116
  const rootBg = (document.documentElement?.style?.background || '').toLowerCase()
117
117
  const inferredCurrent = rootBg.includes('33') ? 'dark' : 'light'
118
118
  let next = requested
@@ -128,25 +128,25 @@ import{a as G}from"./chunk-3DDSYQHM.js";import{a as je,b as Le}from"./chunk-EXQJ
128
128
  })()`}):o.send({type:"evaluate",code:`(async () => {
129
129
  window.dispatchEvent(new CustomEvent(${JSON.stringify(d==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
130
130
  return { ok: true, action: ${JSON.stringify(d)} }
131
- })()`})}function po(o){let d={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(d[o])return d[o];let a=o.match(/^Digit([0-9])$/);if(a)return a[1];let l=o.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function fo(o){if(typeof o!="string")return null;let d=o.replace(/\s+/g," ").trim();return d?d.slice(0,80):null}function Dt(...o){for(let d of o){if(typeof d!="string")continue;let a=d.trim();if(a)return a}return null}async function j(o,d,a){let l=ce({source:o,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 go(o,d,a){if(!a||a.hit===!1)return null;let l=Dt(a.responderTestID,a.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let f=fo(a.text);return f?{step:{tapOn:f},summary:`tap "${f}"`}:{step:{tapAtCoords:{x:o,y:d}},summary:`tap @${Math.round(o)},${Math.round(d)}`}}function Ie(o,d,a){let l=Dt(d?.testID,d?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:a==="id"?{step:{tapOn:{id:o}},summary:`tap #${o}`}:{step:{tapOn:o},summary:`tap "${o}"`}}async function Gs(o,d){let a=o[0]==="get"||o[0]==="do"||o[0]==="debug"||o[0]==="wait"?o[0]:null,l=a?o.slice(1):o,f=Oe(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","--max-ms","--filter","--limit","--level","--threshold","--equals","--since"]}),i=f.positional,y=i[0],S=a==="get"||a==="do"||a==="debug"||a==="wait"?a:"inspect",I=typeof l[0]=="string"&&Ae.has(l[0]),k=I?l[0]:null,b=e=>I&&e===l[0]?`sootsim ${e}`:`sootsim ${S} ${e}`,v=(e,t)=>` usage: ${b(e)}${t?` ${t}`:""}`;if(!y||o.includes("--help")||o.includes("-h")){let e={bridgePort:7668,defaultShellUrl:Fe};if(S==="do"||S==="get"||S==="debug"||S==="wait"){let r=be(S,e);r&&(console.log(`${r}
132
- `),process.exit(0))}if(k==="shell"){let r=we("shell",e);r&&(console.log(`${r}
133
- `),process.exit(0))}let t=we("inspect",e),s=["do","get","debug","wait"].map(r=>be(r,e)).filter(r=>r!=null).join(`
131
+ })()`})}function fo(o){let d={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(d[o])return d[o];let i=o.match(/^Digit([0-9])$/);if(i)return i[1];let l=o.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function go(o){if(typeof o!="string")return null;let d=o.replace(/\s+/g," ").trim();return d?d.slice(0,80):null}function Bt(...o){for(let d of o){if(typeof d!="string")continue;let i=d.trim();if(i)return i}return null}async function j(o,d,i){let l=ce({source:o,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 yo(o,d,i){if(!i||i.hit===!1)return null;let l=Bt(i.responderTestID,i.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let f=go(i.text);return f?{step:{tapOn:f},summary:`tap "${f}"`}:{step:{tapAtCoords:{x:o,y:d}},summary:`tap @${Math.round(o)},${Math.round(d)}`}}function Ie(o,d,i){let l=Bt(d?.testID,d?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:i==="id"?{step:{tapOn:{id:o}},summary:`tap #${o}`}:{step:{tapOn:o},summary:`tap "${o}"`}}async function Xs(o,d){let i=o[0]==="get"||o[0]==="do"||o[0]==="debug"||o[0]==="wait"?o[0]:null,l=i?o.slice(1):o,f=Oe(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","--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",I=typeof l[0]=="string"&&Ae.has(l[0]),k=I?l[0]:null,b=e=>I&&e===l[0]?`sootsim ${e}`:`sootsim ${S} ${e}`,v=(e,t)=>` usage: ${b(e)}${t?` ${t}`:""}`;if(!y||o.includes("--help")||o.includes("-h")){let e={bridgePort:7668,defaultShellUrl:Fe};if(S==="do"||S==="get"||S==="debug"||S==="wait"){let n=be(S,e);n&&(console.log(`${n}
132
+ `),process.exit(0))}if(k==="shell"){let n=we("shell",e);n&&(console.log(`${n}
133
+ `),process.exit(0))}let t=we("inspect",e),s=["do","get","debug","wait"].map(n=>be(n,e)).filter(n=>n!=null).join(`
134
134
 
135
135
  `);console.log(`${t??""}
136
136
 
137
137
  ${s}
138
- `),process.exit(0)}let _=f.wsPort,T=f.simId,C=f.commandTimeoutMs;if(y==="list"&&l.some(e=>e==="--drivers"||e==="-D")){let{buildDriverListRows:e}=await import("./drivers-YGVUWGMB.js"),t=e();console.log(` available drivers (${t.length}):
139
- `);let s=Math.max(...t.map(n=>n.id.length),6),r=Math.max(...t.map(n=>n.kind.length),4);for(let n of t){let u=n.available?"\u2713":"\u2717",m=n.id.padEnd(s),$=n.kind.padEnd(r);console.log(` ${u} ${m} ${$} ${n.description}`),n.available&&n.detail?console.log(` ${n.detail}`):!n.available&&n.reason&&console.log(` unavailable: ${n.reason}`)}return}let c=Re(f),J=T||"default",K=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),E=200;function L(e){let t=e.replace(/\s+/g," ").trim();if(!t)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(t)){let r=/<title[^>]*>([^<]+)<\/title>/i.exec(e)?.[1]?.trim(),n=/<body[^>]*>([\s\S]*?)<\//i.exec(e)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=r||n||"html error page";return`<html ${e.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return t.length<=E?t:`${t.slice(0,E)}\u2026 (+${t.length-E} more bytes)`}function z(e){let t=e.displayUrl||e.url;return e.status!=null?`${e.method} ${t} -> ${e.status}${e.statusText?` ${e.statusText}`:""}`:e.error?`${e.method} ${t} -> ${e.error}`:`${e.method} ${t}`}async function q(e){let t=ft()?1200:350;try{let{settled:s,elapsed:r}=await se({bridge:e,maxMs:t,pollMs:32,stablePolls:2});s||process.stderr.write(` \u26A0 auto-wait timed out after ${r??t}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
138
+ `),process.exit(0)}let _=f.wsPort,T=f.simId,C=f.commandTimeoutMs;if(y==="list"&&l.some(e=>e==="--drivers"||e==="-D")){let{buildDriverListRows:e}=await import("./drivers-SXP44QNY.js"),t=e();console.log(` available drivers (${t.length}):
139
+ `);let s=Math.max(...t.map(r=>r.id.length),6),n=Math.max(...t.map(r=>r.kind.length),4);for(let r of t){let u=r.available?"\u2713":"\u2717",m=r.id.padEnd(s),x=r.kind.padEnd(n);console.log(` ${u} ${m} ${x} ${r.description}`),r.available&&r.detail?console.log(` ${r.detail}`):!r.available&&r.reason&&console.log(` unavailable: ${r.reason}`)}return}let c=Re(f),L=T||"default",K=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),E=200;function J(e){let t=e.replace(/\s+/g," ").trim();if(!t)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(t)){let n=/<title[^>]*>([^<]+)<\/title>/i.exec(e)?.[1]?.trim(),r=/<body[^>]*>([\s\S]*?)<\//i.exec(e)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=n||r||"html error page";return`<html ${e.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return t.length<=E?t:`${t.slice(0,E)}\u2026 (+${t.length-E} more bytes)`}function z(e){let t=e.displayUrl||e.url;return e.status!=null?`${e.method} ${t} -> ${e.status}${e.statusText?` ${e.statusText}`:""}`:e.error?`${e.method} ${t} -> ${e.error}`:`${e.method} ${t}`}async function q(e){let t=gt()?1200:350;try{let{settled:s,elapsed:n}=await ne({bridge:e,maxMs:t,pollMs:32,stablePolls:2});s||process.stderr.write(` \u26A0 auto-wait timed out after ${n??t}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
140
140
  `)}catch{}}async function w(){try{return await c.send({type:"evaluate",code:`(() => ({
141
141
  console: window.__sootsimConsole?.count?.() || null,
142
142
  requests: window.__sootsimTest?.getRequestCounts?.() || null,
143
- }))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function M(e={}){let t=e.counts!==void 0?e.counts:await Y(c,"getRequestCounts");if(!t||typeof t!="object")return;let s=Math.max(0,Number(t.failed)||0);if(s===0||!e.includeTail&&!ke("requests",J,String(s))||(console.log(`
144
- network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${b("requests")} 5`),!e.includeTail))return;let r=await Y(c,"getFailedRequests",5);if(!(!Array.isArray(r)||r.length===0)){console.log(`
143
+ }))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function M(e={}){let t=e.counts!==void 0?e.counts:await Y(c,"getRequestCounts");if(!t||typeof t!="object")return;let s=Math.max(0,Number(t.failed)||0);if(s===0||!e.includeTail&&!ke("requests",L,String(s))||(console.log(`
144
+ network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${b("requests")} 5`),!e.includeTail))return;let n=await Y(c,"getFailedRequests",5);if(!(!Array.isArray(n)||n.length===0)){console.log(`
145
145
  recent failed requests:
146
- `);for(let n of r){let u=new Date(n.timestamp).toLocaleTimeString();console.log(` [${u}] ${z(n)}`),n.responseBody?console.log(` ${L(n.responseBody)}`):n.error&&console.log(` ${n.error}`)}}}async function Z(e={}){let t=e.counts!==void 0?e.counts:await c.send({type:"evaluate",code:"window.__sootsimConsole?.count?.() || { errors: 0, warnings: 0, total: 0 }"});if(!t||typeof t!="object")return;let s=t,r=Math.max(0,Number(s.errors)||0),n=Math.max(0,Number(s.warnings)||0);if(r===0&&n===0||!e.includeTail&&!ke("console",J,`${r}:${n}`))return;let u=[];if(r>0&&u.push(`${r} console error${r===1?"":"s"}`),n>0&&u.push(`${n} console warning${n===1?"":"s"}`),console.log(`
147
- console: ${u.join(", ")}`),console.log(` inspect: ${b("errors")} 5`),n>0&&console.log(` inspect: ${b("warnings")} 5`),!e.includeTail||r===0)return;let m=await c.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors?.(5) || []"});if(!(!Array.isArray(m)||m.length===0)){console.log(`
146
+ `);for(let r of n){let u=new Date(r.timestamp).toLocaleTimeString();console.log(` [${u}] ${z(r)}`),r.responseBody?console.log(` ${J(r.responseBody)}`):r.error&&console.log(` ${r.error}`)}}}async function Z(e={}){let t=e.counts!==void 0?e.counts:await c.send({type:"evaluate",code:"window.__sootsimConsole?.count?.() || { errors: 0, warnings: 0, total: 0 }"});if(!t||typeof t!="object")return;let s=t,n=Math.max(0,Number(s.errors)||0),r=Math.max(0,Number(s.warnings)||0);if(n===0&&r===0||!e.includeTail&&!ke("console",L,`${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(`
147
+ console: ${u.join(", ")}`),console.log(` inspect: ${b("errors")} 5`),r>0&&console.log(` inspect: ${b("warnings")} 5`),!e.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(`
148
148
  recent console errors:
149
- `);for(let $ of m){let g=new Date($.timestamp).toLocaleTimeString(),x=Array.isArray($.args)?$.args.map(F=>typeof F=="object"?JSON.stringify(F):String(F)).join(" "):String($);console.log(` [${g}] ${x}`)}}}let P=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function V(e){let t=Pe(),s=null;try{s=await Ce(e,`(() => {
149
+ `);for(let x of m){let g=new Date(x.timestamp).toLocaleTimeString(),$=Array.isArray(x.args)?x.args.map(F=>typeof F=="object"?JSON.stringify(F):String(F)).join(" "):String(x);console.log(` [${g}] ${$}`)}}}let P=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function V(e){let t=Pe(),s=null;try{s=await Ce(e,`(() => {
150
150
  const tl = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.timeline
151
151
  if (!tl || typeof tl.summary !== 'function') return null
152
152
  const cursorKey = ${JSON.stringify(t)}
@@ -162,37 +162,9 @@ ${s}
162
162
  }
163
163
  }
164
164
  return summary ? { summary, consoleSplit } : null
165
- })()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let r=s.summary.byKind??{},n=[],u=new Set;for(let m of P){let $=r[m];if($)if(u.add(m),m==="console"&&s.consoleSplit){let{error:g,warn:x}=s.consoleSplit;g>0&&n.push(`${g} error${g===1?"":"s"}`),x>0&&n.push(`${x} warning${x===1?"":"s"}`)}else n.push(`${$} ${m}${$===1?"":"s"}`)}for(let[m,$]of Object.entries(r))!u.has(m)&&$&&n.push(`${$} ${m}${$===1?"":"s"}`);if(n.length!==0&&(console.log(`
166
- since last: ${n.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await xe(e,"SootSim.bridges.timeline.cursorAdvance",t,s.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"]),oe=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"]),ye=(o.includes("--verbose")||o.includes("-v"))&&!o.includes("--json");S==="do"&&y==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),ee.has(y)&&await Ee(c),oe.has(y)&&await de(c,{verbose:ye});try{switch(y){case"list":{await ht({bridge:c,simId:T,args:l});break}case"tree":{await St({bridge:c,args:l,positional:i});break}case"a11y":{let e=i[1]?Number(i[1]):5,t=await c.send({type:"evaluate",code:`(async () => {
167
- const t = window.__sootsimTest
168
- if (!t) return []
169
- const all = await t.queryAll({ pruneHidden: true })
170
- return all.filter(n => {
171
- // skip zero-size nodes
172
- if (!n.layout || n.layout.width <= 0 || n.layout.height <= 0) return false
173
- // keep nodes with explicit accessibility roles or labels
174
- if (n.accessibilityRole) return true
175
- if (n.accessibilityHint) return true
176
- if (n.isTextInput) return true
177
- if (n.pressable) return true
178
- // keep text leaf nodes
179
- if (n.type === 'text' && n.text) return true
180
- // keep views with intentional labels (not auto-derived)
181
- if (n.accessibilityLabel && n.accessibilityLabel.length <= 30
182
- && n.accessibilityLabel !== n.text) return true
183
- // skip container views without role (just concatenated child text)
184
- return false
185
- }).map(n => ({
186
- role: n.accessibilityRole || (n.pressable ? 'button' : n.isTextInput ? 'textfield' : n.type === 'text' ? 'statictext' : 'none'),
187
- label: n.accessibilityLabel || n.text || null,
188
- hint: n.accessibilityHint || null,
189
- state: n.accessibilityState || null,
190
- testID: n.testID || null,
191
- position: n.absolutePosition ? { x: Math.round(n.absolutePosition.x), y: Math.round(n.absolutePosition.y) } : null,
192
- size: n.layout ? { w: Math.round(n.layout.width), h: Math.round(n.layout.height) } : null,
193
- }))
194
- })()`});if(!Array.isArray(t)||t.length===0){console.log(" no accessible nodes found");break}if(o.includes("--json"))console.log(JSON.stringify(t,null,2));else{console.log(` accessibility tree (${t.length} nodes):
195
- `);for(let s of t){let r=[];if(r.push(`[${s.role}]`),s.label){let n=s.label.length>50?s.label.slice(0,47)+"...":s.label;r.push(`"${n}"`)}if(s.hint&&r.push(`(hint: "${s.hint}")`),s.testID&&r.push(`#${s.testID}`),s.state){let n=[];s.state.disabled&&n.push("disabled"),s.state.selected&&n.push("selected"),s.state.checked===!0&&n.push("checked"),s.state.checked==="mixed"&&n.push("mixed"),s.state.busy&&n.push("busy"),s.state.expanded===!0&&n.push("expanded"),s.state.expanded===!1&&n.push("collapsed"),n.length&&r.push(`{${n.join(", ")}}`)}s.position&&r.push(`@(${s.position.x},${s.position.y})`),s.size&&r.push(`${s.size.w}x${s.size.h}`),console.log(" "+r.join(" "))}}break}case"find":{await gt({bridge:c,args:o,effectiveArgs:l,positional:i,inspectUsage:v});break}case"count":{await mt(c,{args:l});break}case"keyboard":{await yt(c,{json:o.includes("--json")});break}case"screens":{await wt(c,{json:o.includes("--json")});break}case"memory":{await bt(c,{args:l});break}case"wait":{await kt({wsPort:_,commandTimeoutMs:C,simId:T,positional:i});break}case"sleep":{await $t({positional:i,inspectUsage:v});break}case"settle":{await xt({bridge:c,args:o,positional:i});break}case"ready":{await It({bridge:c,args:o});break}case"idle":{await Nt({bridge:c,args:o,positional:i});break}case"selector":{await _t({bridge:c,args:o,positional:i,inspectUsage:v});break}case"event":{await Mt({bridge:c,args:o,positional:i,inspectUsage:v});break}case"layout":{let e=i[1];e||(console.error(v("layout","<id>")),process.exit(1));let t=await c.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(e)}))()`});console.log(JSON.stringify(t,null,2));break}case"capture":case"screenshot":{let t=o.find(($,g)=>o[g-1]==="--output")||"/tmp/sootsim-inspect.png",s=await Ot(o,c),r={type:"screenshot"};s&&(r.crop=s);let u=(await c.send(r)).replace(/^data:image\/png;base64,/,"");s&&console.log(` area: x=${s.x} y=${s.y} w=${s.w} h=${s.h}`),(await import("fs")).writeFileSync(t,Buffer.from(u,"base64")),console.log(` saved: ${t}`);break}case"sample-color":{let e=await Ot(o,c);e||(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 t=await c.send({type:"evaluate",code:Le(e)});if(o.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:r,b:n,a:u,hex:m,samples:$}=t,g=e.w===1&&e.h===1?`@(${e.x},${e.y})`:`@(${e.x},${e.y}) ${e.w}x${e.h}`;console.log(` ${m} rgba(${s}, ${r}, ${n}, ${u}) ${g} ${$} samples`)}break}case"node":{let e=i[1];e||(console.error(v("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let t=await c.send({type:"evaluate",code:`(async () => {
165
+ })()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let n=s.summary.byKind??{},r=[],u=new Set;for(let m of P){let x=n[m];if(x)if(u.add(m),m==="console"&&s.consoleSplit){let{error:g,warn:$}=s.consoleSplit;g>0&&r.push(`${g} error${g===1?"":"s"}`),$>0&&r.push(`${$} warning${$===1?"":"s"}`)}else r.push(`${x} ${m}${x===1?"":"s"}`)}for(let[m,x]of Object.entries(n))!u.has(m)&&x&&r.push(`${x} ${m}${x===1?"":"s"}`);if(r.length!==0&&(console.log(`
166
+ since last: ${r.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await $e(e,"SootSim.bridges.timeline.cursorAdvance",t,s.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"]),oe=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"]),ye=(o.includes("--verbose")||o.includes("-v"))&&!o.includes("--json");S==="do"&&y==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),ee.has(y)&&await Ee(c),oe.has(y)&&await de(c,{verbose:ye});try{switch(y){case"list":{await bt({bridge:c,simId:T,args:l});break}case"tree":{await vt({bridge:c,args:l,positional:a});break}case"a11y":{let e=await Ue(c);if(!Array.isArray(e)||e.length===0){console.log(" no accessible nodes found");break}if(o.includes("--json"))console.log(JSON.stringify(e,null,2));else{console.log(` accessibility tree (${e.length} nodes):
167
+ `);for(let t of e){let s=[];if(s.push(`[${t.role}]`),t.label){let n=t.label.length>50?t.label.slice(0,47)+"...":t.label;s.push(`"${n}"`)}if(t.hint&&s.push(`(hint: "${t.hint}")`),t.testID&&s.push(`#${t.testID}`),t.state){let n=[];t.state.disabled&&n.push("disabled"),t.state.selected&&n.push("selected"),t.state.checked===!0&&n.push("checked"),t.state.checked==="mixed"&&n.push("mixed"),t.state.busy&&n.push("busy"),t.state.expanded===!0&&n.push("expanded"),t.state.expanded===!1&&n.push("collapsed"),n.length&&s.push(`{${n.join(", ")}}`)}t.position&&s.push(`@(${t.position.x},${t.position.y})`),t.size&&s.push(`${t.size.w}x${t.size.h}`),console.log(" "+s.join(" "))}}break}case"find":{await yt({bridge:c,args:o,effectiveArgs:l,positional:a,inspectUsage:v});break}case"count":{await pt(c,{args:l});break}case"keyboard":{await ht(c,{json:o.includes("--json")});break}case"screens":{await $t(c,{json:o.includes("--json")});break}case"memory":{await wt(c,{args:l});break}case"wait":{await Tt({wsPort:_,commandTimeoutMs:C,simId:T,positional:a});break}case"sleep":{await St({positional:a,inspectUsage:v});break}case"settle":{await xt({bridge:c,args:o,positional:a});break}case"ready":{await _t({bridge:c,args:o});break}case"idle":{await It({bridge:c,args:o,positional:a});break}case"selector":{await Ft({bridge:c,args:o,positional:a,inspectUsage:v});break}case"event":{await Nt({bridge:c,args:o,positional:a,inspectUsage:v});break}case"layout":{let e=a[1];e||(console.error(v("layout","<id>")),process.exit(1));let t=await c.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(e)}))()`});console.log(JSON.stringify(t,null,2));break}case"capture":case"screenshot":{let t=o.find((x,g)=>o[g-1]==="--output")||"/tmp/sootsim-inspect.png",s=await Rt(o,c),n={type:"screenshot"};s&&(n.crop=s);let u=(await c.send(n)).replace(/^data:image\/png;base64,/,"");s&&console.log(` area: x=${s.x} y=${s.y} w=${s.w} h=${s.h}`),(await import("fs")).writeFileSync(t,Buffer.from(u,"base64")),console.log(` saved: ${t}`);break}case"sample-color":{let e=await Rt(o,c);e||(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 t=await c.send({type:"evaluate",code:Je(e)});if(o.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:n,b:r,a:u,hex:m,samples:x}=t,g=e.w===1&&e.h===1?`@(${e.x},${e.y})`:`@(${e.x},${e.y}) ${e.w}x${e.h}`;console.log(` ${m} rgba(${s}, ${n}, ${r}, ${u}) ${g} ${x} samples`)}break}case"node":{let e=a[1];e||(console.error(v("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let t=await c.send({type:"evaluate",code:`(async () => {
196
168
  const t = window.__sootsimTest
197
169
  const q = ${JSON.stringify(e)}
198
170
  let node = null
@@ -248,17 +220,17 @@ ${s}
248
220
  transform,
249
221
  parentChain,
250
222
  }
251
- })()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let e=Number(i[1]),t=Number(i[2]),s=ae(o);if(s){let u=await me(c,s);u||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),e=u.x,t=u.y}(!Number.isFinite(e)||!Number.isFinite(t))&&(console.error(v("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let r=await c.send({type:"tap",x:e,y:t}),n=go(e,t,r);n&&await j("inspect tap",n.step,n.summary),console.log(JSON.stringify(r,null,2));break}case"drag":case"swipe":{let e=Number(i[1]),t=Number(i[2]),s=Number(i[3]),r=Number(i[4]),n=y==="swipe"?10:12,u=y==="swipe"?8:16,m=i[5]?Number(i[5]):n,$=i[6]?Number(i[6]):u;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(m)||!Number.isFinite($))&&(console.error(v(y,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let g=await c.send({type:"evaluate",code:`(async () => {
223
+ })()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let e=Number(a[1]),t=Number(a[2]),s=ae(o);if(s){let u=await me(c,s);u||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),e=u.x,t=u.y}(!Number.isFinite(e)||!Number.isFinite(t))&&(console.error(v("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let n=await c.send({type:"tap",x:e,y:t}),r=yo(e,t,n);r&&await j("inspect tap",r.step,r.summary),console.log(JSON.stringify(n,null,2));break}case"drag":case"swipe":{let e=Number(a[1]),t=Number(a[2]),s=Number(a[3]),n=Number(a[4]),r=y==="swipe"?10:12,u=y==="swipe"?8:16,m=a[5]?Number(a[5]):r,x=a[6]?Number(a[6]):u;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(n)||!Number.isFinite(m)||!Number.isFinite(x))&&(console.error(v(y,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let g=await c.send({type:"evaluate",code:`(async () => {
252
224
  const interact = window.__sootsimInteract
253
225
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
254
- const value = await interact.drag(${e}, ${t}, ${s}, ${r}, ${Math.max(1,Math.round(m))}, ${Math.max(0,Math.round($))})
226
+ const value = await interact.drag(${e}, ${t}, ${s}, ${n}, ${Math.max(1,Math.round(m))}, ${Math.max(0,Math.round(x))})
255
227
  return { ok: !!value, value }
256
- })()`});if(g?.ok){let x=Math.max(1,Math.round(Math.max(1,m)*Math.max(0,$)));await j(`inspect ${y}`,{swipe:{start:`${e}, ${t}`,end:`${s}, ${r}`,duration:x}},`${y} ${e},${t} -> ${s},${r}`)}console.log(JSON.stringify(g,null,2));break}case"pinch":{let e=Number(i[1]),t=Number(i[2]),s=Number(i[3]),r=Number(i[4]),n=Number(i[5]),u=Number(i[6]),m=Number(i[7]),$=Number(i[8]),g=i[9]?Number(i[9]):12,x=i[10]?Number(i[10]):16;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(n)||!Number.isFinite(u)||!Number.isFinite(m)||!Number.isFinite($)||!Number.isFinite(g)||!Number.isFinite(x))&&(console.error(v("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let F=await c.send({type:"evaluate",code:`(async () => {
228
+ })()`});if(g?.ok){let $=Math.max(1,Math.round(Math.max(1,m)*Math.max(0,x)));await j(`inspect ${y}`,{swipe:{start:`${e}, ${t}`,end:`${s}, ${n}`,duration:$}},`${y} ${e},${t} -> ${s},${n}`)}console.log(JSON.stringify(g,null,2));break}case"pinch":{let e=Number(a[1]),t=Number(a[2]),s=Number(a[3]),n=Number(a[4]),r=Number(a[5]),u=Number(a[6]),m=Number(a[7]),x=Number(a[8]),g=a[9]?Number(a[9]):12,$=a[10]?Number(a[10]):16;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(u)||!Number.isFinite(m)||!Number.isFinite(x)||!Number.isFinite(g)||!Number.isFinite($))&&(console.error(v("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let F=await c.send({type:"evaluate",code:`(async () => {
257
229
  const interact = window.__sootsimInteract
258
230
  if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
259
- const value = await interact.pinch(${e}, ${t}, ${s}, ${r}, ${n}, ${u}, ${m}, ${$}, ${Math.max(1,Math.round(g))}, ${Math.max(0,Math.round(x))})
231
+ const value = await interact.pinch(${e}, ${t}, ${s}, ${n}, ${r}, ${u}, ${m}, ${x}, ${Math.max(1,Math.round(g))}, ${Math.max(0,Math.round($))})
260
232
  return { ok: !!value, value }
261
- })()`});F?.ok&&await j("inspect pinch",{pinch:{from:[e,t,s,r],to:[n,u,m,$],steps:Math.max(1,Math.round(g)),stepMs:Math.max(0,Math.round(x))}},`pinch (${e},${t}) (${s},${r}) -> (${n},${u}) (${m},${$})`),console.log(JSON.stringify(F,null,2));break}case"tap-text":{let e=i[1];e||(console.error(v("tap-text","<text>")),process.exit(1));let t=R=>{let A=o.indexOf(R);return A>=0&&A+1<o.length?o[A+1]:null},s=R=>o.includes(R),r=t("--nth")??t("--index"),n=r!==null?Number(r):null;n!==null&&!Number.isFinite(n)&&(console.error(` --nth/--index requires an integer, got: ${r}`),process.exit(1));let u=t("--within"),m=t("--role"),$=s("--exact"),g=s("--first"),x=t("--min-y"),F=t("--max-y"),W=t("--min-x"),H=t("--max-x");for(let[R,A]of[["--min-y",x],["--max-y",F],["--min-x",W],["--max-x",H]])A!==null&&!Number.isFinite(Number(A))&&(console.error(` ${R} requires a number, got: ${A}`),process.exit(1));let U=o.indexOf("--near"),N=null;if(U>=0){let R=Number(o[U+1]),A=Number(o[U+2]);(!Number.isFinite(R)||!Number.isFinite(A))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),N={x:R,y:A}}let h=JSON.stringify({query:e,exact:$,role:m,within:u,minX:W!==null?Number(W):null,maxX:H!==null?Number(H):null,minY:x!==null?Number(x):null,maxY:F!==null?Number(F):null,near:N,nth:n,first:g}),p=await c.send({type:"evaluate",code:`(async () => {
233
+ })()`});F?.ok&&await j("inspect pinch",{pinch:{from:[e,t,s,n],to:[r,u,m,x],steps:Math.max(1,Math.round(g)),stepMs:Math.max(0,Math.round($))}},`pinch (${e},${t}) (${s},${n}) -> (${r},${u}) (${m},${x})`),console.log(JSON.stringify(F,null,2));break}case"tap-text":{let e=a[1];e||(console.error(v("tap-text","<text>")),process.exit(1));let t=R=>{let A=o.indexOf(R);return A>=0&&A+1<o.length?o[A+1]:null},s=R=>o.includes(R),n=t("--nth")??t("--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=t("--within"),m=t("--role"),x=s("--exact"),g=s("--first"),$=t("--min-y"),F=t("--max-y"),W=t("--min-x"),H=t("--max-x");for(let[R,A]of[["--min-y",$],["--max-y",F],["--min-x",W],["--max-x",H]])A!==null&&!Number.isFinite(Number(A))&&(console.error(` ${R} requires a number, got: ${A}`),process.exit(1));let U=o.indexOf("--near"),N=null;if(U>=0){let R=Number(o[U+1]),A=Number(o[U+2]);(!Number.isFinite(R)||!Number.isFinite(A))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),N={x:R,y:A}}let h=JSON.stringify({query:e,exact:x,role:m,within:u,minX:W!==null?Number(W):null,maxX:H!==null?Number(H):null,minY:$!==null?Number($):null,maxY:F!==null?Number(F):null,near:N,nth:r,first:g}),p=await c.send({type:"evaluate",code:`(async () => {
262
234
  const t = window.__sootsimTest
263
235
  if (!t) return { error: 'bridge-not-ready' }
264
236
  const F = ${h}
@@ -372,7 +344,7 @@ ${s}
372
344
  total,
373
345
  idx,
374
346
  }
375
- })()`});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 "${e}"`);for(let A of R){let he=A.abs?`@(${Math.round(A.abs.x)},${Math.round(A.abs.y)})`:"",le=A.layout?` ${A.layout.width}x${A.layout.height}`:"",Bt=A.testID?` #${A.testID}`:"",jt=A.text?` "${A.text}"`:"",Lt=A.ancestorTestIDs.length>0?` within ${A.ancestorTestIDs.slice(0,3).map(Jt=>`#${Jt}`).join(" > ")}`:"";console.error(` [${A.idx}] <${A.type}>${jt}${Bt} ${he}${le}${Lt}`)}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 "${e}"`),process.exit(1)),(!p||typeof p.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let O=await c.send({type:"tap",x:p.cx,y:p.cy});if(O?.hit!==!1&&O?.ok!==!1){let R=Ie(e,{id:p.target?.id??null,testID:p.target?.testID??null,type:p.target?.type??null,cx:p.cx,cy:p.cy},"text");await j("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||n!==null?{nth:{index:p.idx,total:p.total}}:{},result:O},null,2));break}case"tap-best":{let e=i[1];e||(console.error(v("tap-best","<query>")),process.exit(1));let t=JSON.stringify(e),s=await c.send({type:"evaluate",code:`(async () => {
347
+ })()`});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 "${e}"`);for(let A of R){let he=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}`:"",Jt=A.text?` "${A.text}"`:"",Lt=A.ancestorTestIDs.length>0?` within ${A.ancestorTestIDs.slice(0,3).map(Wt=>`#${Wt}`).join(" > ")}`:"";console.error(` [${A.idx}] <${A.type}>${Jt}${jt} ${he}${le}${Lt}`)}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 "${e}"`),process.exit(1)),(!p||typeof p.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let O=await c.send({type:"tap",x:p.cx,y:p.cy});if(O?.hit!==!1&&O?.ok!==!1){let R=Ie(e,{id:p.target?.id??null,testID:p.target?.testID??null,type:p.target?.type??null,cx:p.cx,cy:p.cy},"text");await j("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:O},null,2));break}case"tap-best":{let e=a[1];e||(console.error(v("tap-best","<query>")),process.exit(1));let t=JSON.stringify(e),s=await c.send({type:"evaluate",code:`(async () => {
376
348
  const t = window.__sootsimTest
377
349
  if (!t) return { error: 'bridge-not-ready' }
378
350
  // try testID first \u2014 strongest signal of "this is the
@@ -413,7 +385,7 @@ ${s}
413
385
  }
414
386
  }
415
387
  return { strategy: 'none' }
416
- })()`});"error"in s&&(console.error(` ${s.error}`),process.exit(1)),s.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${e}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1));let r=s.node,n=r.absolutePosition.x+r.layout.width/2,u=r.absolutePosition.y+r.layout.height/2,m=await c.send({type:"tap",x:n,y:u});if(m?.hit!==!1&&m?.ok!==!1){let $=Ie(e,{id:r.id,testID:r.testID,type:r.type,cx:n,cy:u},s.strategy==="testid"?"id":"text");await j("inspect tap-best",$.step,$.summary)}console.log(JSON.stringify({matched:{strategy:s.strategy,nodeId:r.nodeId,id:r.id,testID:r.testID,type:r.type,text:r.text},tapped:{cx:n,cy:u},result:m},null,2));break}case"tap-id":{let e=i[1];e||(console.error(v("tap-id","<id>")),process.exit(1));let t=JSON.stringify(e),s=await c.send({type:"evaluate",code:`(async () => {
388
+ })()`});"error"in s&&(console.error(` ${s.error}`),process.exit(1)),s.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${e}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1));let n=s.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});if(m?.hit!==!1&&m?.ok!==!1){let x=Ie(e,{id:n.id,testID:n.testID,type:n.type,cx:r,cy:u},s.strategy==="testid"?"id":"text");await j("inspect tap-best",x.step,x.summary)}console.log(JSON.stringify({matched:{strategy:s.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 e=a[1];e||(console.error(v("tap-id","<id>")),process.exit(1));let t=JSON.stringify(e),s=await c.send({type:"evaluate",code:`(async () => {
417
389
  const t = window.__sootsimTest
418
390
  if (!t) return null
419
391
  const n = (await t.findByTestId(${t})) || (await t.findById(${t}))
@@ -448,7 +420,7 @@ ${s}
448
420
  },
449
421
  strategy: (resolved && resolved.strategy) || 'matched-node',
450
422
  }
451
- })()`});(!s||typeof s.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let r=await c.send({type:"tap",x:s.cx,y:s.cy});if(r?.hit!==!1&&r?.ok!==!1){let n=Ie(e,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await j("inspect tap-id",n.step,n.summary)}console.log(JSON.stringify({matched:s.match,tapped:{nodeId:s.target?.nodeId??null,id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},...s.strategy&&s.strategy!=="matched-node"?{strategy:s.strategy}:{},result:r},null,2));break}case"type-into":{let e=i[1],t=i.slice(2).join(" ");(!e||!t)&&(console.error(v("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(e),r=await c.send({type:"evaluate",code:`(async () => {
423
+ })()`});(!s||typeof s.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let n=await c.send({type:"tap",x:s.cx,y:s.cy});if(n?.hit!==!1&&n?.ok!==!1){let r=Ie(e,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await j("inspect tap-id",r.step,r.summary)}console.log(JSON.stringify({matched:s.match,tapped:{nodeId:s.target?.nodeId??null,id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},...s.strategy&&s.strategy!=="matched-node"?{strategy:s.strategy}:{},result:n},null,2));break}case"type-into":{let e=a[1],t=a.slice(2).join(" ");(!e||!t)&&(console.error(v("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(e),n=await c.send({type:"evaluate",code:`(async () => {
452
424
  const t = window.__sootsimTest
453
425
  if (!t) return null
454
426
  const n = await (t.findByTestId(${s}) || t.findById(${s}))
@@ -460,41 +432,41 @@ ${s}
460
432
  isTextInput: !!n.isTextInput,
461
433
  placeholder: n.placeholder || null,
462
434
  }
463
- })()`});(!r||typeof r.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1)),r.isTextInput||console.error(` warning: ${e} is not a text input (isTextInput: false)`);let n=await c.send({type:"tap",x:r.cx,y:r.cy}),u=await mo(c);u.visible||(console.error(` keyboard did not open after tapping ${e}`),process.exit(1));let m=u.focusedInput;m&&(m.testID===e||m.id===e||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(e)} 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:t}),await j("inspect type-into",{tapOn:{id:e},inputText:t},`type-into #${e} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:e,isTextInput:r.isTextInput,keyboardOpened:u.visible??n?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:t},null,2));break}case"type":{let e=i.slice(1).join(" ");e||(console.error(v("type","<text>")),process.exit(1)),await ge(c,"type"),await c.send({type:"keyboard",action:"type",text:e}),await j("inspect type",{inputText:e},`type ${JSON.stringify(e)}`),console.log(` typed: ${JSON.stringify(e)}`);break}case"key":{let e=i[1];e||(console.error(v("key","<name>")),process.exit(1)),await ge(c,"key"),await c.send({type:"keyboard",action:"press",text:e}),await j("inspect key",{pressKey:e},`key ${e}`),console.log(` pressed: ${e}`);break}case"key-sequence":{let e=i.slice(1);e.length===0&&(console.error(v("key-sequence","<key> [<key> ...]")),process.exit(1)),await ge(c,"key-sequence");for(let t of e)await c.send({type:"keyboard",action:"press",text:t});await j("inspect key-sequence",{pressKey:e.join(" ")},`key-sequence ${e.join(" ")}`),console.log(` pressed: ${e.join(", ")}`);break}case"keycode":{let e=i.slice(1);e.length===0&&(console.error(v("keycode","<code> [<code> ...]")),process.exit(1));let t=e.map(r=>({code:r,key:po(r)})),s=t.filter(r=>!r.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(r=>r.code).join(", ")}`),process.exit(1)),await ge(c,"keycode");for(let r of t)await c.send({type:"keyboard",action:"press",text:r.key});await j("inspect keycode",{pressKey:t.map(r=>r.key).join(" ")},`keycode ${e.join(" ")}`),console.log(` pressed: ${e.join(", ")}`);break}case"dispatch":{let e=i[1];e||(console.error(v("dispatch","<char>")),process.exit(1)),await c.send({type:"keyboard",action:"dispatchKey",text:e}),await j("inspect dispatch",{dispatchKey:e},`dispatch ${JSON.stringify(e)}`),console.log(` dispatched: ${e}`);break}case"dismiss":{await c.send({type:"keyboard",action:"dismiss"}),await j("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let e=Number(i[1]),t=Number(i[2]),s=ae(o);if(s){let m=await me(c,s);m||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),e=m.x,t=m.y}let r=i[3]?Number(i[3]):80;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(r))&&(console.error(v("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let n=Math.max(0,Math.round(r)),u=await c.send({type:"evaluate",code:`(async () => {
435
+ })()`});(!n||typeof n.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1)),n.isTextInput||console.error(` warning: ${e} is not a text input (isTextInput: false)`);let r=await c.send({type:"tap",x:n.cx,y:n.cy}),u=await po(c);u.visible||(console.error(` keyboard did not open after tapping ${e}`),process.exit(1));let m=u.focusedInput;m&&(m.testID===e||m.id===e||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(e)} 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:t}),await j("inspect type-into",{tapOn:{id:e},inputText:t},`type-into #${e} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:e,isTextInput:n.isTextInput,keyboardOpened:u.visible??r?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:t},null,2));break}case"type":{let e=a.slice(1).join(" ");e||(console.error(v("type","<text>")),process.exit(1)),await ge(c,"type"),await c.send({type:"keyboard",action:"type",text:e}),await j("inspect type",{inputText:e},`type ${JSON.stringify(e)}`),console.log(` typed: ${JSON.stringify(e)}`);break}case"key":{let e=a[1];e||(console.error(v("key","<name>")),process.exit(1)),await ge(c,"key"),await c.send({type:"keyboard",action:"press",text:e}),await j("inspect key",{pressKey:e},`key ${e}`),console.log(` pressed: ${e}`);break}case"key-sequence":{let e=a.slice(1);e.length===0&&(console.error(v("key-sequence","<key> [<key> ...]")),process.exit(1)),await ge(c,"key-sequence");for(let t of e)await c.send({type:"keyboard",action:"press",text:t});await j("inspect key-sequence",{pressKey:e.join(" ")},`key-sequence ${e.join(" ")}`),console.log(` pressed: ${e.join(", ")}`);break}case"keycode":{let e=a.slice(1);e.length===0&&(console.error(v("keycode","<code> [<code> ...]")),process.exit(1));let t=e.map(n=>({code:n,key:fo(n)})),s=t.filter(n=>!n.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(n=>n.code).join(", ")}`),process.exit(1)),await ge(c,"keycode");for(let n of t)await c.send({type:"keyboard",action:"press",text:n.key});await j("inspect keycode",{pressKey:t.map(n=>n.key).join(" ")},`keycode ${e.join(" ")}`),console.log(` pressed: ${e.join(", ")}`);break}case"dispatch":{let e=a[1];e||(console.error(v("dispatch","<char>")),process.exit(1)),await c.send({type:"keyboard",action:"dispatchKey",text:e}),await j("inspect dispatch",{dispatchKey:e},`dispatch ${JSON.stringify(e)}`),console.log(` dispatched: ${e}`);break}case"dismiss":{await c.send({type:"keyboard",action:"dismiss"}),await j("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let e=Number(a[1]),t=Number(a[2]),s=ae(o);if(s){let m=await me(c,s);m||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),e=m.x,t=m.y}let n=a[3]?Number(a[3]):80;(!Number.isFinite(e)||!Number.isFinite(t)||!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 () => {
464
436
  const interact = window.__sootsimInteract
465
437
  if (interact?.doubleTap) {
466
438
  return {
467
- ok: !!(await interact.doubleTap(${e}, ${t}, ${n})),
468
- gapMs: ${n},
439
+ ok: !!(await interact.doubleTap(${e}, ${t}, ${r})),
440
+ gapMs: ${r},
469
441
  }
470
442
  }
471
443
  if (!interact?.tap) {
472
- return { ok: false, reason: 'no interact.tap', gapMs: ${n} }
444
+ return { ok: false, reason: 'no interact.tap', gapMs: ${r} }
473
445
  }
474
446
  const first = await interact.tap(${e}, ${t})
475
447
  if (!first || first.hit === false) {
476
- return { ok: false, reason: 'first tap missed', gapMs: ${n}, first }
448
+ return { ok: false, reason: 'first tap missed', gapMs: ${r}, first }
477
449
  }
478
- await new Promise((resolve) => setTimeout(resolve, ${n}))
450
+ await new Promise((resolve) => setTimeout(resolve, ${r}))
479
451
  const second = await interact.tap(${e}, ${t})
480
452
  return {
481
453
  ok: !!second && second.hit !== false,
482
- gapMs: ${n},
454
+ gapMs: ${r},
483
455
  first,
484
456
  second,
485
457
  }
486
- })()`});u?.ok&&await j("inspect double-tap",{doubleTapAtCoords:{x:e,y:t,gapMs:n}},`double-tap @${e},${t}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let e=Number(i[1]),t=Number(i[2]),s=ae(o);if(s){let u=await me(c,s);u||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),e=u.x,t=u.y}let r=i[3]?Number(i[3]):600;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(r))&&(console.error(v("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let n=await c.send({type:"evaluate",code:`(async () => {
458
+ })()`});u?.ok&&await j("inspect double-tap",{doubleTapAtCoords:{x:e,y:t,gapMs:r}},`double-tap @${e},${t}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let e=Number(a[1]),t=Number(a[2]),s=ae(o);if(s){let u=await me(c,s);u||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),e=u.x,t=u.y}let n=a[3]?Number(a[3]):600;(!Number.isFinite(e)||!Number.isFinite(t)||!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 () => {
487
459
  const interact = window.__sootsimInteract
488
460
  if (!interact?.longPress) return { ok: false, reason: 'no interact.longPress' }
489
- const value = await interact.longPress(${e}, ${t}, ${Math.max(0,Math.round(r))})
461
+ const value = await interact.longPress(${e}, ${t}, ${Math.max(0,Math.round(n))})
490
462
  return { ok: !!value, value }
491
- })()`});n?.ok&&await j("inspect long-press",{tapAtCoords:{x:e,y:t}},`long-press @${e},${t}`),console.log(JSON.stringify(n,null,2));break}case"touch":{let e=i[1],t=Number(i[2]),s=Number(i[3]),r=i[4]?Number(i[4]):999,n=e==="down"?"touchDown":e==="move"?"touchMove":e==="up"?"touchUp":e==="cancel"?"touchCancel":null;n||(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),e!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(s))&&(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let u=e==="down"?"tap":e==="move"?"move":null,m=u&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${t}, y: ${s} } }));`:"",$=await c.send({type:"evaluate",code:`(async () => {
463
+ })()`});r?.ok&&await j("inspect long-press",{tapAtCoords:{x:e,y:t}},`long-press @${e},${t}`),console.log(JSON.stringify(r,null,2));break}case"touch":{let e=a[1],t=Number(a[2]),s=Number(a[3]),n=a[4]?Number(a[4]):999,r=e==="down"?"touchDown":e==="move"?"touchMove":e==="up"?"touchUp":e==="cancel"?"touchCancel":null;r||(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),e!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(s))&&(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let u=e==="down"?"tap":e==="move"?"move":null,m=u&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${t}, y: ${s} } }));`:"",x=await c.send({type:"evaluate",code:`(async () => {
492
464
  ${m}
493
465
  const interact = window.__sootsimInteract
494
- if (!interact?.${n}) return { ok: false, reason: 'no interact.${n}' }
495
- const value = ${e==="cancel"?`await interact.${n}(${Math.max(1,Math.round(r))})`:`await interact.${n}(${t}, ${s}, ${Math.max(1,Math.round(r))})`}
466
+ if (!interact?.${r}) return { ok: false, reason: 'no interact.${r}' }
467
+ const value = ${e==="cancel"?`await interact.${r}(${Math.max(1,Math.round(n))})`:`await interact.${r}(${t}, ${s}, ${Math.max(1,Math.round(n))})`}
496
468
  return { ok: !!value, value }
497
- })()`});$?.ok&&e!=="cancel"&&await j("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${e} @${t},${s}`),console.log(JSON.stringify($,null,2));break}case"gesture":{let e=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],t=i[1],s=i[2]?Number(i[2]):220;(!t||!Number.isFinite(s))&&(console.error(v("gesture","<preset> [durationMs]")),console.error(` presets: ${e.join(", ")}`),process.exit(1)),e.includes(t)||(console.error(` unknown gesture preset: ${t}`),console.error(` presets: ${e.join(", ")}`),process.exit(1));let r=await c.send({type:"evaluate",code:`(async () => {
469
+ })()`});x?.ok&&e!=="cancel"&&await j("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${e} @${t},${s}`),console.log(JSON.stringify(x,null,2));break}case"gesture":{let e=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],t=a[1],s=a[2]?Number(a[2]):220;(!t||!Number.isFinite(s))&&(console.error(v("gesture","<preset> [durationMs]")),console.error(` presets: ${e.join(", ")}`),process.exit(1)),e.includes(t)||(console.error(` unknown gesture preset: ${t}`),console.error(` presets: ${e.join(", ")}`),process.exit(1));let n=await c.send({type:"evaluate",code:`(async () => {
498
470
  const spec = globalThis.__sootsimDeviceSpec || {}
499
471
  return {
500
472
  width: spec.width || window.innerWidth || 393,
@@ -502,12 +474,12 @@ ${s}
502
474
  statusBarHeight: spec.statusBarHeight || 0,
503
475
  homeIndicatorHeight: spec.homeIndicatorHeight || 0,
504
476
  }
505
- })()`}),n=Number(r?.width)||393,u=Number(r?.height)||852,m=Number(r?.statusBarHeight)||0,$=Number(r?.homeIndicatorHeight)||0,g=Math.round(n/2),x=Math.round(u/2),F=Math.max(24,m+18),W=Math.max(24,$+18),H=18,U=Math.min(220,Math.round(u*.24)),N=Math.min(180,Math.round(n*.32)),h=g,p=x,O=g,R=x;switch(t){case"scroll-up":p=x+Math.round(U/2),R=x-Math.round(U/2);break;case"scroll-down":p=x-Math.round(U/2),R=x+Math.round(U/2);break;case"scroll-left":h=g+Math.round(N/2),O=g-Math.round(N/2);break;case"scroll-right":h=g-Math.round(N/2),O=g+Math.round(N/2);break;case"swipe-from-left-edge":h=H,p=x,O=Math.min(n-H,H+N);break;case"swipe-from-right-edge":h=n-H,p=x,O=Math.max(H,n-H-N);break;case"swipe-from-top-edge":h=g,p=F,R=Math.min(u-W,F+U);break;case"swipe-from-bottom-edge":h=g,p=u-W,R=Math.max(F,u-W-U);break}let A=Math.max(8,Math.round(s/16)),he=Math.max(1,Math.round(s/A)),le=await c.send({type:"evaluate",code:`(async () => {
477
+ })()`}),r=Number(n?.width)||393,u=Number(n?.height)||852,m=Number(n?.statusBarHeight)||0,x=Number(n?.homeIndicatorHeight)||0,g=Math.round(r/2),$=Math.round(u/2),F=Math.max(24,m+18),W=Math.max(24,x+18),H=18,U=Math.min(220,Math.round(u*.24)),N=Math.min(180,Math.round(r*.32)),h=g,p=$,O=g,R=$;switch(t){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":h=g+Math.round(N/2),O=g-Math.round(N/2);break;case"scroll-right":h=g-Math.round(N/2),O=g+Math.round(N/2);break;case"swipe-from-left-edge":h=H,p=$,O=Math.min(r-H,H+N);break;case"swipe-from-right-edge":h=r-H,p=$,O=Math.max(H,r-H-N);break;case"swipe-from-top-edge":h=g,p=F,R=Math.min(u-W,F+U);break;case"swipe-from-bottom-edge":h=g,p=u-W,R=Math.max(F,u-W-U);break}let A=Math.max(8,Math.round(s/16)),he=Math.max(1,Math.round(s/A)),le=await c.send({type:"evaluate",code:`(async () => {
506
478
  const interact = window.__sootsimInteract
507
479
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
508
480
  const value = await interact.drag(${h}, ${p}, ${O}, ${R}, ${A}, ${he})
509
481
  return { ok: !!value, value }
510
- })()`});le?.ok&&await j("inspect gesture",{swipe:{start:`${h}, ${p}`,end:`${O}, ${R}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:h,y:p},to:{x:O,y:R},result:le},null,2));break}case"scroll":{let e=ae(o),t=e?.mode==="testid"?e.value:i[1],s=Number(i[e?1:2]),r=Number(i[e?2:3]);(!t||!Number.isFinite(s)||!Number.isFinite(r))&&(console.error(v("scroll","<id> <dx> <dy> | --testid <id> <dx> <dy>")),process.exit(1));let n=await c.send({type:"evaluate",code:`(async () => {
482
+ })()`});le?.ok&&await j("inspect gesture",{swipe:{start:`${h}, ${p}`,end:`${O}, ${R}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:h,y:p},to:{x:O,y:R},result:le},null,2));break}case"scroll":{let e=ae(o),t=e?.mode==="testid"?e.value:a[1],s=Number(a[e?1:2]),n=Number(a[e?2:3]);(!t||!Number.isFinite(s)||!Number.isFinite(n))&&(console.error(v("scroll","<id> <dx> <dy> | --testid <id> <dx> <dy>")),process.exit(1));let r=await c.send({type:"evaluate",code:`(async () => {
511
483
  const t = window.__sootsimTest
512
484
  if (!t) return null
513
485
  const n = await t.findByTestId(${JSON.stringify(t)})
@@ -517,10 +489,10 @@ ${s}
517
489
  cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
518
490
  cy: n.absolutePosition.y + (n.layout.height || 0) / 2,
519
491
  }
520
- })()`}),u=await Y(c,"scrollTo",t,s,r,!1);u?.ok&&await j("inspect scroll",{scrollTo:{id:t,x:s,y:r}},`scroll ${t} -> ${s},${r}`),console.log(JSON.stringify({...u,...n?{at:{x:n.cx,y:n.cy}}:{}},null,2));break}case"state":{let e=i[1];if(a==="get"&&!e){let s=await Y(c,"getRuntimeState"),r=await c.send({type:"evaluate",code:`({
492
+ })()`}),u=await Y(c,"scrollTo",t,s,n,!1);u?.ok&&await j("inspect scroll",{scrollTo:{id:t,x:s,y:n}},`scroll ${t} -> ${s},${n}`),console.log(JSON.stringify({...u,...r?{at:{x:r.cx,y:r.cy}}:{}},null,2));break}case"state":{let e=a[1];if(i==="get"&&!e){let s=await Y(c,"getRuntimeState"),n=await c.send({type:"evaluate",code:`({
521
493
  errors: window.__sootsimConsole?.getErrors?.()?.length ?? 0,
522
494
  warnings: window.__sootsimConsole?.getWarnings?.()?.length ?? 0,
523
- })`});s&&typeof s=="object"&&s.diagnostics&&(s.diagnostics.errors=r?.errors??0,s.diagnostics.warnings=r?.warnings??0),console.log(JSON.stringify(s,null,2));break}if(!e||e==="--help"||e==="-h"){console.log(`
495
+ })`});if(s&&typeof s=="object"&&s.diagnostics&&(s.diagnostics.errors=n?.errors??0,s.diagnostics.warnings=n?.warnings??0),s&&typeof s=="object"&&s.shell==null)try{let r=await se(c);r&&(s.shell=r)}catch{}console.log(JSON.stringify(s,null,2));break}if(!e||e==="--help"||e==="-h"){console.log(`
524
496
  ${b("state")} \u2014 dump raw runtime state
525
497
 
526
498
  subcommands:
@@ -543,7 +515,7 @@ ${s}
543
515
  ${b("state")} scroll feed
544
516
  ${b("state")} scroll-hit 360 420
545
517
  ${b("state")} hit 200 720
546
- `);break}let t;switch(e){case"shell":t=await ne(c,500);break;case"worker":t=await xe(c,"__sootsimRenderHost.queryStats");break;case"ownership":t=await c.send({type:"evaluate",code:`(() => {
518
+ `);break}let t;switch(e){case"shell":t=await se(c,500);break;case"worker":t=await $e(c,"__sootsimRenderHost.queryStats");break;case"ownership":t=await c.send({type:"evaluate",code:`(() => {
547
519
  const h = window.__sootsimRenderHost
548
520
  if (!h || typeof h.getOwnershipSnapshot !== 'function') {
549
521
  return { error: 'getOwnershipSnapshot not available' }
@@ -574,7 +546,7 @@ ${s}
574
546
  text: focused.text || null,
575
547
  } : null,
576
548
  }
577
- })()`});break;case"node":{let s=i[2];s||(console.error(` usage: ${b("state")} node <id>`),process.exit(1)),t=await Y(c,"findByTestId",s)||await Y(c,"findById",s);break}case"scroll":{let s=i[2];s||(console.error(` usage: ${b("state")} scroll <id>`),process.exit(1)),t=await Y(c,"getScrollState",s);break}case"scroll-hit":{let s=Number(i[2]),r=Number(i[3]);(!Number.isFinite(s)||!Number.isFinite(r))&&(console.error(` usage: ${b("state")} scroll-hit <x> <y>`),process.exit(1)),t=await Y(c,"getScrollStateAt",s,r);break}case"hit":{let s=Number(i[2]),r=Number(i[3]);(!Number.isFinite(s)||!Number.isFinite(r))&&(console.error(` usage: ${b("state")} hit <x> <y>`),process.exit(1)),t=await Y(c,"debugHitAt",s,r);break}case"gesture":{let s=Number(i[2]),r=Number(i[3]);(!Number.isFinite(s)||!Number.isFinite(r))&&(console.error(` usage: ${b("state")} gesture <x> <y>`),process.exit(1)),t=await Y(c,"debugGestureAt",s,r);break}default:console.error(` unknown state subcommand: ${e}`),process.exit(1)}console.log(JSON.stringify(t,null,2));break}case"shell":{let e=i[1];if(!e||e==="--help"||e==="-h"){console.log(`
549
+ })()`});break;case"node":{let s=a[2];s||(console.error(` usage: ${b("state")} node <id>`),process.exit(1)),t=await Y(c,"findByTestId",s)||await Y(c,"findById",s);break}case"scroll":{let s=a[2];s||(console.error(` usage: ${b("state")} scroll <id>`),process.exit(1)),t=await Y(c,"getScrollState",s);break}case"scroll-hit":{let s=Number(a[2]),n=Number(a[3]);(!Number.isFinite(s)||!Number.isFinite(n))&&(console.error(` usage: ${b("state")} scroll-hit <x> <y>`),process.exit(1)),t=await Y(c,"getScrollStateAt",s,n);break}case"hit":{let s=Number(a[2]),n=Number(a[3]);(!Number.isFinite(s)||!Number.isFinite(n))&&(console.error(` usage: ${b("state")} hit <x> <y>`),process.exit(1)),t=await Y(c,"debugHitAt",s,n);break}case"gesture":{let s=Number(a[2]),n=Number(a[3]);(!Number.isFinite(s)||!Number.isFinite(n))&&(console.error(` usage: ${b("state")} gesture <x> <y>`),process.exit(1)),t=await Y(c,"debugGestureAt",s,n);break}default:console.error(` unknown state subcommand: ${e}`),process.exit(1)}console.log(JSON.stringify(t,null,2));break}case"shell":{let e=a[1];if(!e||e==="--help"||e==="-h"){console.log(`
578
550
  ${b("shell")} \u2014 run built-in shell commands
579
551
 
580
552
  subcommands:
@@ -598,7 +570,7 @@ ${s}
598
570
  ${b("shell")} open-card clock 800
599
571
  ${b("shell")} appearance dark
600
572
  ${b("shell")} lock
601
- `);break}let t=e==="launch"||e==="open-card"||e==="home"||e==="switcher",s=e==="launch"||e==="open-card"?i[3]:i[2],r=s?Number(s):350;t&&(!Number.isFinite(r)||r<0)&&(console.error(v("shell",e==="launch"||e==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let n=!1,u=!1,m=null,$=o.includes("--clear-state");if(e==="launch"){let g=i[2];g||(console.error(v("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),$&&await c.send({type:"evaluate",code:De}),n=!!await re(c,"launchApp",r,g),{settled:u,state:m}=await fe(c,Math.round(r),x=>!!x&&x.state==="app"&&x.activeApp===g&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.launchProgress=="number"&&x.launchProgress>=.98),n&&await j("inspect shell launch",$?{launchApp:{clearState:!0}}:{launchApp:{}},$?"launch app (clear state)":"launch app")}else if(e==="home")n=!!await re(c,"goHome",r),{settled:u,state:m}=await fe(c,Math.round(r),g=>!!g&&g.state==="home"&&g.activeApp==null&&g.showSwitcher===!1&&g.switcherPhase==="idle"&&typeof g.launchProgress=="number"&&g.launchProgress>=.98);else if(e==="switcher")n=!!await re(c,"openSwitcher",r),{settled:u,state:m}=await fe(c,Math.round(r),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(uo),m=await ne(c));else if(e==="open-card"){let g=i[2];g||(console.error(v("shell","open-card <appId> [settleMs]")),process.exit(1)),n=!!await re(c,"openSwitcherCard",r,g),{settled:u,state:m}=await fe(c,Math.round(r),x=>!!x&&x.state==="app"&&x.activeApp===g&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.zoomLevel=="number"&&x.zoomLevel>=.98&&typeof x.horizontalZoom=="number"&&x.horizontalZoom>=.98),n&&await j("inspect shell open-card",{openSwitcherCard:{appId:g}},`open switcher card ${g}`)}else if(e==="appearance"){let g=i[2];(!g||!["light","dark","auto","toggle"].includes(g))&&(console.error(v("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let x=await Rt(c,"appearance",g);if(n=!!x?.ok,m={appearance:x},n){let F=x?.applied??g;console.log(` appearance: ${F}`)}}else if(e==="lock"||e==="shake"){let g=await Rt(c,e);n=!!g?.ok,m={[e]:g}}else console.error(` unknown shell subcommand: ${e}`),process.exit(1);console.log(JSON.stringify({ok:n,settled:u,state:m},null,2));break}case"url":{await vt(c,{args:l});break}case"reload":{let s=!1,r=!1;try{await c.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let m=await c.send({type:"evaluate",code:`;(() => {
573
+ `);break}let t=e==="launch"||e==="open-card"||e==="home"||e==="switcher",s=e==="launch"||e==="open-card"?a[3]:a[2],n=s?Number(s):350;t&&(!Number.isFinite(n)||n<0)&&(console.error(v("shell",e==="launch"||e==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let r=!1,u=!1,m=null,x=o.includes("--clear-state");if(e==="launch"){let g=a[2];g||(console.error(v("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),x&&await c.send({type:"evaluate",code:De}),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 j("inspect shell launch",x?{launchApp:{clearState:!0}}:{launchApp:{}},x?"launch app (clear state)":"launch app")}else if(e==="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(e==="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(mo),m=await se(c));else if(e==="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 j("inspect shell open-card",{openSwitcherCard:{appId:g}},`open switcher card ${g}`)}else if(e==="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 Et(c,"appearance",g);if(r=!!$?.ok,m={appearance:$},r){let F=$?.applied??g;console.log(` appearance: ${F}`)}}else if(e==="lock"||e==="shake"){let g=await Et(c,e);r=!!g?.ok,m={[e]:g}}else console.error(` unknown shell subcommand: ${e}`),process.exit(1);console.log(JSON.stringify({ok:r,settled:u,state:m},null,2));break}case"url":{await kt(c,{args:l});break}case"reload":{let s=!1,n=!1;try{await c.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let m=await c.send({type:"evaluate",code:`;(() => {
602
574
  const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
603
575
  if (typeof reloadExternalApp === 'function') {
604
576
  reloadExternalApp()
@@ -606,10 +578,10 @@ ${s}
606
578
  }
607
579
  window.location.reload()
608
580
  return { kind: 'page' }
609
- })()`});r=!!m&&m.kind==="external-app",s=!0}catch{}console.log(" reloading...");let n=c,u=null;if(r)u=await ve(c,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await X(300);let m=await it(_,C,T,{timeoutMs:1e4});m?(n=m,u=await ve(m,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),n=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(n)try{let m=await n.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors(10) || []"});if(n!==c&&n.close(),Array.isArray(m)&&m.length>0){console.log(`
581
+ })()`});n=!!m&&m.kind==="external-app",s=!0}catch{}console.log(" reloading...");let r=c,u=null;if(n)u=await ve(c,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await X(300);let m=await at(_,C,T,{timeoutMs:1e4});m?(r=m,u=await ve(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(`
610
582
  \u26A0 ${m.length} error(s) during mount:
611
- `);for(let $ of m){let g=$.args.map(x=>typeof x=="object"?JSON.stringify(x):x).join(" ");if(console.log(` ${g}`),$.stack){let x=$.stack.split(`
612
- `).slice(0,2);for(let F of x)console.log(` ${F.trim()}`)}}}}catch{}u&&!u.ready&&(process.exitCode=1);break}case"eval":case"js":{let e=i.slice(1).join(" ");e||(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 t=e;t.startsWith("(async")||(t=`(async () => ${t})()`);let s=await c.send({type:"evaluate",code:t});console.log(JSON.stringify(s,null,2));let r=e.toLowerCase(),n=[];(r.includes("sootsim:gohome")||r.includes("gohome"))&&n.push("sootsim shell home"),(r.includes("sootsim:appswitcher")||r.includes("appswitcher"))&&n.push("sootsim shell switcher"),(r.includes("keyboard.isvisible")||r.includes("keyboard.getmode"))&&n.push("sootsim debug state keyboard"),r.includes("interact.tap")&&n.push("sootsim do tap <x> <y>"),r.includes("keyboard.type")&&n.push("sootsim do type <text>"),(r.includes("keyboard.press")||r.includes("keyboard.dispatchkey"))&&n.push("sootsim do key <name>"),r.includes("keyboard.dismiss")&&n.push("sootsim do dismiss"),r.includes("dumptree")&&n.push("sootsim get tree"),r.includes("dumpaccessibilitytree")&&n.push("sootsim get a11y"),r.includes("getnodecount")&&n.push("sootsim get count"),r.includes("findbytext")&&n.push("sootsim find <text>"),(r.includes("findbytestid")||r.includes("findbyid"))&&n.push("sootsim find --testid <id>"),r.includes("document.hidden")&&n.push("sootsim debug state keyboard (includes tab health)"),n.length>0&&G("prefer-cli-over-eval",n);break}case"globals":{let e=await c.send({type:"evaluate",code:`(async () => {
583
+ `);for(let x of m){let g=x.args.map($=>typeof $=="object"?JSON.stringify($):$).join(" ");if(console.log(` ${g}`),x.stack){let $=x.stack.split(`
584
+ `).slice(0,2);for(let F of $)console.log(` ${F.trim()}`)}}}}catch{}u&&!u.ready&&(process.exitCode=1);break}case"eval":case"js":{let e=a.slice(1).join(" ");e||(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 t=e;t.startsWith("(async")||(t=`(async () => ${t})()`);let s=await c.send({type:"evaluate",code:t});console.log(JSON.stringify(s,null,2));let n=e.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 e=await c.send({type:"evaluate",code:`(async () => {
613
585
  const globals = {}
614
586
 
615
587
  // test bridge (proxy in worker mode)
@@ -647,7 +619,7 @@ ${s}
647
619
 
648
620
  return globals
649
621
  })()`});console.log(` sootsim JS API:
650
- `);for(let[t,s]of Object.entries(e)){console.log(` ${t}:`);for(let r of s)console.log(` .${r}`);console.log("")}console.log(` use: ${b("js")} <expression>`),console.log(` example: ${b("js")} test.findByText("Sign in")`);break}case"describe":{await pt({bridge:c,args:o,positional:i});break}case"perf":{let e=i[1];if(!e||e==="--help"||e==="-h"){console.log(`
622
+ `);for(let[t,s]of Object.entries(e)){console.log(` ${t}:`);for(let n of s)console.log(` .${n}`);console.log("")}console.log(` use: ${b("js")} <expression>`),console.log(` example: ${b("js")} test.findByText("Sign in")`);break}case"describe":{await ft({bridge:c,args:o,positional:a});break}case"perf":{let e=a[1];if(!e||e==="--help"||e==="-h"){console.log(`
651
623
  ${b("perf")} \u2014 performance profiling
652
624
 
653
625
  subcommands:
@@ -804,8 +776,8 @@ ${s}
804
776
  jankFrames: recent.filter(f => f > 16.67).length,
805
777
  sampleCount: recent.length,
806
778
  }
807
- })()`});t.error&&(console.error(` error: ${t.error}`),process.exit(1));let s=t.avgMs>0?(1e3/t.avgMs).toFixed(1):"?",r=t.sampleCount>0?(t.jankFrames/t.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
808
- `),console.log(` frames: ${t.frames}`),console.log(` total: ${t.totalMs.toFixed(1)}ms`),console.log(` avg: ${t.avgMs.toFixed(2)}ms (${s} fps)`),console.log(` max: ${t.maxMs.toFixed(2)}ms`),console.log(""),t.layoutAvgMs!==void 0&&(console.log(" breakdown (avg per frame):"),console.log(` layout: ${t.layoutAvgMs.toFixed(2)}ms`),console.log(` render: ${t.renderAvgMs.toFixed(2)}ms`),console.log(` copy: ${t.copyAvgMs.toFixed(2)}ms`),t.auxAvgMs!==void 0&&console.log(` aux: ${t.auxAvgMs.toFixed(2)}ms`),t.otherAvgMs!==void 0&&console.log(` other: ${t.otherAvgMs.toFixed(2)}ms`),console.log("")),console.log(` distribution (${t.sampleCount} samples):`),console.log(` p50: ${t.p50.toFixed(2)}ms`),console.log(` p95: ${t.p95.toFixed(2)}ms`),console.log(` p99: ${t.p99.toFixed(2)}ms`),console.log(` jank: ${t.jankFrames} frames (${r}%) >16.67ms`);break}case"frames":{let t=i[2]?Number(i[2]):50;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${i[2]}"`),process.exit(1));let s=await c.send({type:"evaluate",code:`(async () => {
779
+ })()`});t.error&&(console.error(` error: ${t.error}`),process.exit(1));let s=t.avgMs>0?(1e3/t.avgMs).toFixed(1):"?",n=t.sampleCount>0?(t.jankFrames/t.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
780
+ `),console.log(` frames: ${t.frames}`),console.log(` total: ${t.totalMs.toFixed(1)}ms`),console.log(` avg: ${t.avgMs.toFixed(2)}ms (${s} fps)`),console.log(` max: ${t.maxMs.toFixed(2)}ms`),console.log(""),t.layoutAvgMs!==void 0&&(console.log(" breakdown (avg per frame):"),console.log(` layout: ${t.layoutAvgMs.toFixed(2)}ms`),console.log(` render: ${t.renderAvgMs.toFixed(2)}ms`),console.log(` copy: ${t.copyAvgMs.toFixed(2)}ms`),t.auxAvgMs!==void 0&&console.log(` aux: ${t.auxAvgMs.toFixed(2)}ms`),t.otherAvgMs!==void 0&&console.log(` other: ${t.otherAvgMs.toFixed(2)}ms`),console.log("")),console.log(` distribution (${t.sampleCount} samples):`),console.log(` p50: ${t.p50.toFixed(2)}ms`),console.log(` p95: ${t.p95.toFixed(2)}ms`),console.log(` p99: ${t.p99.toFixed(2)}ms`),console.log(` jank: ${t.jankFrames} frames (${n}%) >16.67ms`);break}case"frames":{let t=a[2]?Number(a[2]):50;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await c.send({type:"evaluate",code:`(async () => {
809
781
  if (window.__sootsimRenderHost) {
810
782
  const session = window.${Q} || {}
811
783
  if (session.active) {
@@ -840,7 +812,7 @@ ${s}
840
812
  mode: 'main-thread',
841
813
  frames: (stats.recentFrames || []).slice(-${t}),
842
814
  }
843
- })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let n=Array.isArray(s.samples)?s.samples:[];if(n.length===0){console.log(` no frame data \u2014 run '${b("perf")} start' first`);break}console.log(` last ${n.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,m,$,g,x,F,W]of n)console.log(` ${m.toFixed(2).padStart(7)} ${$.toFixed(2).padStart(7)} ${g.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${F.toFixed(2).padStart(6)} ${W.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);console.log(""),Ne(n.map(u=>u[1])),s.live&&console.log(" sampling continues");break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${b("perf")} start' first`);break}console.log(` last ${r.length} frame times (ms):`),console.log(` ${r.map(n=>n.toFixed(2)).join(", ")}`),Ne(r);break}case"worst":{let t=i[2]?Number(i[2]):20;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${i[2]}"`),process.exit(1));let s=await c.send({type:"evaluate",code:`(async () => {
815
+ })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let r=Array.isArray(s.samples)?s.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,x,g,$,F,W]of r)console.log(` ${m.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${g.toFixed(2).padStart(7)} ${$.toFixed(2).padStart(7)} ${F.toFixed(2).padStart(6)} ${W.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);console.log(""),Ne(r.map(u=>u[1])),s.live&&console.log(" sampling continues");break}let n=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];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(", ")}`),Ne(n);break}case"worst":{let t=a[2]?Number(a[2]):20;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await c.send({type:"evaluate",code:`(async () => {
844
816
  if (window.__sootsimRenderHost) {
845
817
  const session = window.${Q} || {}
846
818
  if (session.active) {
@@ -882,7 +854,7 @@ ${s}
882
854
  mode: 'main-thread',
883
855
  frames: recent.slice().sort((a, b) => b - a).slice(0, ${t}),
884
856
  }
885
- })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let n=Array.isArray(s.samples)?s.samples:[];if(n.length===0){console.log(` no frame data \u2014 run '${b("perf")} start' first`);break}console.log(` worst ${n.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,m,$,g,x,F,W]of n)console.log(` ${m.toFixed(2).padStart(7)} ${$.toFixed(2).padStart(7)} ${g.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${F.toFixed(2).padStart(6)} ${W.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);s.live&&(console.log(""),console.log(" sampling continues"));break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${b("perf")} start' first`);break}console.log(` worst ${r.length} frame times (ms):`),console.log(` ${r.map(n=>n.toFixed(2)).join(", ")}`);break}case"transition":{let t=i[2];if(!t||!["goHome","appSwitcher","lockScreen"].includes(t)){console.log(`
857
+ })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let r=Array.isArray(s.samples)?s.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,x,g,$,F,W]of r)console.log(` ${m.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${g.toFixed(2).padStart(7)} ${$.toFixed(2).padStart(7)} ${F.toFixed(2).padStart(6)} ${W.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);s.live&&(console.log(""),console.log(" sampling continues"));break}let n=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];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 t=a[2];if(!t||!["goHome","appSwitcher","lockScreen"].includes(t)){console.log(`
886
858
  ${b("perf")} transition <event> \u2014 profile a shell transition
887
859
 
888
860
  events:
@@ -895,7 +867,7 @@ ${s}
895
867
  examples:
896
868
  ${b("perf")} transition goHome --timeout 10000
897
869
  ${b("perf")} transition appSwitcher
898
- `);break}let r=`sootsim:${t}`;console.log(` profiling ${t} transition...`),console.log(" (use --timeout 10000 if this times out)");let n=await c.send({type:"evaluate",code:`(async () => {
870
+ `);break}let n=`sootsim:${t}`;console.log(` profiling ${t} transition...`),console.log(" (use --timeout 10000 if this times out)");let r=await c.send({type:"evaluate",code:`(async () => {
899
871
  // only supported in render-worker mode
900
872
  if (!window.__sootsimRenderHost) {
901
873
  return { error: 'transition profiling requires render-worker mode' }
@@ -908,7 +880,7 @@ ${s}
908
880
  await new Promise(r => requestAnimationFrame(() => r(undefined)))
909
881
 
910
882
  // dispatch the shell event
911
- window.dispatchEvent(new Event('${r}'))
883
+ window.dispatchEvent(new Event('${n}'))
912
884
 
913
885
  // wait 600ms for transition to complete (shell animations are ~300-500ms)
914
886
  // using fixed timing avoids complex animation-end detection
@@ -954,45 +926,45 @@ ${s}
954
926
  jankFrames: frameTimes.filter(f => f > 16.67).length,
955
927
  samples,
956
928
  }
957
- })()`});if(n.error&&(console.error(` error: ${n.error}`),process.exit(1)),n.warning&&console.log(` warning: ${n.warning}`),n.frames===0){console.log(" no frames captured");break}let u=n.avgMs>0?(1e3/n.avgMs).toFixed(1):"?",m=n.frames>0?(n.jankFrames/n.frames*100).toFixed(1):"0";console.log(` ${t} transition profiled:
929
+ })()`});if(r.error&&(console.error(` error: ${r.error}`),process.exit(1)),r.warning&&console.log(` warning: ${r.warning}`),r.frames===0){console.log(" no frames captured");break}let u=r.avgMs>0?(1e3/r.avgMs).toFixed(1):"?",m=r.frames>0?(r.jankFrames/r.frames*100).toFixed(1):"0";console.log(` ${t} transition profiled:
958
930
 
959
- frames: ${n.frames}
960
- total: ${n.totalMs.toFixed(1)}ms
961
- avg: ${n.avgMs.toFixed(2)}ms (${u} fps)
962
- max: ${n.maxMs.toFixed(2)}ms
931
+ frames: ${r.frames}
932
+ total: ${r.totalMs.toFixed(1)}ms
933
+ avg: ${r.avgMs.toFixed(2)}ms (${u} fps)
934
+ max: ${r.maxMs.toFixed(2)}ms
963
935
 
964
936
  breakdown (avg per frame):
965
- layout: ${n.layoutAvgMs?.toFixed(2)||"?"}ms
966
- render: ${n.renderAvgMs?.toFixed(2)||"?"}ms
967
- copy: ${n.copyAvgMs?.toFixed(2)||"?"}ms
968
- aux: ${n.auxAvgMs?.toFixed(2)||"?"}ms
969
- other: ${n.otherAvgMs?.toFixed(2)||"?"}ms
970
-
971
- distribution (${n.frames} samples):
972
- p50: ${n.p50.toFixed(2)}ms
973
- p95: ${n.p95.toFixed(2)}ms
974
- p99: ${n.p99.toFixed(2)}ms
975
- jank: ${n.jankFrames} frames (${m}%) >16.67ms`),Array.isArray(n.samples)&&n.samples.length>0&&(console.log(""),Ne(n.samples.map($=>$[1])));break}default:console.error(` unknown perf subcommand: ${e}`),process.exit(1)}break}case"errors":{let e=i[1];if(e==="clear"){await Xe(c),D(l)?B({cleared:!0}):console.log(" error buffer cleared");break}let t=e?Number(e):20,s=await Ye(c,t);if(D(l)){B(s);break}if(s.length===0){console.log(" no errors captured");break}console.log(` ${s.length} error(s):
976
- `);for(let r of s){let n=new Date(r.timestamp).toLocaleTimeString(),u=r.args.map(m=>typeof m=="object"?JSON.stringify(m):m).join(" ");if(console.log(` [${n}] ${u}`),r.stack){let m=r.stack.split(`
977
- `).slice(0,3);for(let $ of m)console.log(` ${$.trim()}`)}}break}case"warnings":{let e=i[1]?Number(i[1]):20,t=await Ge(c,e);if(D(l)){B(t);break}if(t.length===0){console.log(" no warnings captured");break}console.log(` ${t.length} warning(s):
978
- `);for(let s of t){let r=new Date(s.timestamp).toLocaleTimeString(),n=s.args.map(u=>typeof u=="object"?JSON.stringify(u):u).join(" ");console.log(` [${r}] ${n}`)}break}case"animations":{let e=await Y(c,"listAnimations")??[];if(o.includes("--json")){console.log(JSON.stringify(e,null,2));break}if(e.length===0){console.log(" no active animations");break}console.log(` ${e.length} active animation(s):
979
- `);for(let t of e){let s=String(t.kind).padEnd(6),r=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,n=Number(t.current??0).toFixed(2),u=`${Math.round((t.progress??0)*100)}%`,m=`${Math.round(t.elapsedMs??0)}ms`,$=t.loop?" loop":"",g=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${r.padEnd(14)} cur=${n.padEnd(7)} ${u.padStart(4)} ${m}${$}${g}`)}break}case"animation":{let e=i[1];(!e||e==="--help"||e==="-h")&&(console.error(` usage: ${b("animation")} <id>`),process.exit(1));let t=Number(e);Number.isFinite(t)||(console.error(` invalid id: ${e}`),process.exit(1));let s=await Y(c,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let e=i[1];(!e||e==="--help"||e==="-h")&&(console.error(` usage: ${b("stop-animation")} <id|all>`),process.exit(1));let t=e==="all"?"all":Number(e);t!=="all"&&!Number.isFinite(t)&&(console.error(` invalid id: ${e}`),process.exit(1));let s=await Y(c,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let e=i[1];if(e==="clear"){await Qe(c),D(l)?B({cleared:!0}):console.log(" request buffer cleared");break}let t=e==="all",s=t?i[2]:e,r=s?Number(s):20,n=await Ve(c,{failed:!t,limit:r});if(D(l)){B(n);break}if(n.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${n.length} ${t?"request(s)":"failed request(s)"}:
980
- `);for(let u of n){let m=new Date(u.timestamp).toLocaleTimeString();console.log(` [${m}] ${z(u)}`),u.responseBody?console.log(` ${u.responseBody}`):u.error&&console.log(` ${u.error}`)}break}case"network":{let e=i[1],t=null,s=null,r=!1,n=!1,u=1e3,m=!1,$=!1;for(let N=0;N<l.length;N++){let h=l[N];if(h==="--filter")t=l[N+1]??null,N++;else if(h==="--limit"){let p=Number(l[N+1]);Number.isFinite(p)&&(s=p),N++}else if(h==="--threshold"){let p=Number(l[N+1]);Number.isFinite(p)&&p>0&&(u=p),N++}else h==="--failed"?r=!0:h==="--slow"?n=!0:h==="--tail"||h==="-f"?m=!0:h==="--json"&&($=!0)}if(e==="clear"){await c.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(e==="get"){let N=i[2];N||(console.error(" usage: sootsim network get <id>"),process.exit(1));let h=await c.send({type:"evaluate",code:`(() => {
937
+ layout: ${r.layoutAvgMs?.toFixed(2)||"?"}ms
938
+ render: ${r.renderAvgMs?.toFixed(2)||"?"}ms
939
+ copy: ${r.copyAvgMs?.toFixed(2)||"?"}ms
940
+ aux: ${r.auxAvgMs?.toFixed(2)||"?"}ms
941
+ other: ${r.otherAvgMs?.toFixed(2)||"?"}ms
942
+
943
+ distribution (${r.frames} samples):
944
+ p50: ${r.p50.toFixed(2)}ms
945
+ p95: ${r.p95.toFixed(2)}ms
946
+ p99: ${r.p99.toFixed(2)}ms
947
+ jank: ${r.jankFrames} frames (${m}%) >16.67ms`),Array.isArray(r.samples)&&r.samples.length>0&&(console.log(""),Ne(r.samples.map(x=>x[1])));break}default:console.error(` unknown perf subcommand: ${e}`),process.exit(1)}break}case"errors":{let e=a[1];if(e==="clear"){await Ve(c),D(l)?B({cleared:!0}):console.log(" error buffer cleared");break}let t=e?Number(e):20,s=await Ge(c,t);if(D(l)){B(s);break}if(s.length===0){console.log(" no errors captured");break}console.log(` ${s.length} error(s):
948
+ `);for(let n of s){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(`
949
+ `).slice(0,3);for(let x of m)console.log(` ${x.trim()}`)}}break}case"warnings":{let e=a[1]?Number(a[1]):20,t=await Xe(c,e);if(D(l)){B(t);break}if(t.length===0){console.log(" no warnings captured");break}console.log(` ${t.length} warning(s):
950
+ `);for(let s of t){let n=new Date(s.timestamp).toLocaleTimeString(),r=s.args.map(u=>typeof u=="object"?JSON.stringify(u):u).join(" ");console.log(` [${n}] ${r}`)}break}case"animations":{let e=await Y(c,"listAnimations")??[];if(o.includes("--json")){console.log(JSON.stringify(e,null,2));break}if(e.length===0){console.log(" no active animations");break}console.log(` ${e.length} active animation(s):
951
+ `);for(let t of e){let s=String(t.kind).padEnd(6),n=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,r=Number(t.current??0).toFixed(2),u=`${Math.round((t.progress??0)*100)}%`,m=`${Math.round(t.elapsedMs??0)}ms`,x=t.loop?" loop":"",g=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${n.padEnd(14)} cur=${r.padEnd(7)} ${u.padStart(4)} ${m}${x}${g}`)}break}case"animation":{let e=a[1];(!e||e==="--help"||e==="-h")&&(console.error(` usage: ${b("animation")} <id>`),process.exit(1));let t=Number(e);Number.isFinite(t)||(console.error(` invalid id: ${e}`),process.exit(1));let s=await Y(c,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let e=a[1];(!e||e==="--help"||e==="-h")&&(console.error(` usage: ${b("stop-animation")} <id|all>`),process.exit(1));let t=e==="all"?"all":Number(e);t!=="all"&&!Number.isFinite(t)&&(console.error(` invalid id: ${e}`),process.exit(1));let s=await Y(c,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let e=a[1];if(e==="clear"){await Ze(c),D(l)?B({cleared:!0}):console.log(" request buffer cleared");break}let t=e==="all",s=t?a[2]:e,n=s?Number(s):20,r=await Qe(c,{failed:!t,limit:n});if(D(l)){B(r);break}if(r.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${r.length} ${t?"request(s)":"failed request(s)"}:
952
+ `);for(let u of r){let m=new Date(u.timestamp).toLocaleTimeString();console.log(` [${m}] ${z(u)}`),u.responseBody?console.log(` ${u.responseBody}`):u.error&&console.log(` ${u.error}`)}break}case"network":{let e=a[1],t=null,s=null,n=!1,r=!1,u=1e3,m=!1,x=!1;for(let N=0;N<l.length;N++){let h=l[N];if(h==="--filter")t=l[N+1]??null,N++;else if(h==="--limit"){let p=Number(l[N+1]);Number.isFinite(p)&&(s=p),N++}else if(h==="--threshold"){let p=Number(l[N+1]);Number.isFinite(p)&&p>0&&(u=p),N++}else h==="--failed"?n=!0:h==="--slow"?r=!0:h==="--tail"||h==="-f"?m=!0:h==="--json"&&(x=!0)}if(e==="clear"){await c.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(e==="get"){let N=a[2];N||(console.error(" usage: sootsim network get <id>"),process.exit(1));let h=await c.send({type:"evaluate",code:`(() => {
981
953
  const obs = window.__sootsimObservability;
982
954
  if (!obs) return null;
983
955
  return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(N)}) || null;
984
- })()`});h||(console.error(` no entry with id ${N}`),process.exit(1)),$?console.log(JSON.stringify(h,null,2)):ao(h);break}let g=s??(m?200:e?Number(e):20);Number.isFinite(g)||(console.error(` invalid limit: ${e} \u2014 \`network\` takes a numeric count (e.g. ${b("network")} 100).
985
- to target a specific sim, use \`--sim ${e}\` instead.`),process.exit(1));let x=async()=>{let N=await c.send({type:"evaluate",code:`(() => {
956
+ })()`});h||(console.error(` no entry with id ${N}`),process.exit(1)),x?console.log(JSON.stringify(h,null,2)):lo(h);break}let g=s??(m?200:e?Number(e):20);Number.isFinite(g)||(console.error(` invalid limit: ${e} \u2014 \`network\` takes a numeric count (e.g. ${b("network")} 100).
957
+ to target a specific sim, use \`--sim ${e}\` instead.`),process.exit(1));let $=async()=>{let N=await c.send({type:"evaluate",code:`(() => {
986
958
  const obs = window.__sootsimObservability;
987
959
  if (!obs) return { ok: false };
988
960
  return { ok: true, entries: obs.network.getSnapshot() };
989
- })()`});if(!N||!N.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return N.entries??[]},F=N=>{let h=N;if(r&&(h=h.filter(p=>!!p.error||p.status!=null&&p.status>=400)),n&&(h=h.filter(p=>p.durationMs!=null&&p.durationMs>=u)),t){let p=t.toLowerCase();h=h.filter(O=>(O.displayUrl||O.url).toLowerCase().includes(p))}return n&&!m&&(h=[...h].sort((p,O)=>(O.durationMs??0)-(p.durationMs??0))),h};if(!m){let N=await x(),h=F(N).slice(-g);if($){console.log(JSON.stringify(h,null,2));break}if(h.length===0){N.length===0?console.log(" no network requests captured"):console.log(n?` no requests slower than ${u}ms (${N.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(n?` ${h.length} request(s) slower than ${u}ms (sorted by duration desc):
961
+ })()`});if(!N||!N.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return N.entries??[]},F=N=>{let h=N;if(n&&(h=h.filter(p=>!!p.error||p.status!=null&&p.status>=400)),r&&(h=h.filter(p=>p.durationMs!=null&&p.durationMs>=u)),t){let p=t.toLowerCase();h=h.filter(O=>(O.displayUrl||O.url).toLowerCase().includes(p))}return r&&!m&&(h=[...h].sort((p,O)=>(O.durationMs??0)-(p.durationMs??0))),h};if(!m){let N=await $(),h=F(N).slice(-g);if(x){console.log(JSON.stringify(h,null,2));break}if(h.length===0){N.length===0?console.log(" no network requests captured"):console.log(r?` no requests slower than ${u}ms (${N.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(r?` ${h.length} request(s) slower than ${u}ms (sorted by duration desc):
990
962
  `:` ${h.length} request(s):
991
- `);for(let p of h)Ft(p);break}console.log(` tailing network (ctrl-c to stop)...
992
- `);let W=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let N=await x(),h=F(N);for(let p of h)p.durationMs!=null&&(W.has(p.id)||(W.add(p.id),$?console.log(JSON.stringify(p)):Ft(p)));await X(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let e=i[1],t=null,s=null,r=null,n=!1,u=!1,m=!1;for(let h=0;h<l.length;h++){let p=l[h];if(p==="--filter")t=l[h+1]??null,h++;else if(p==="--limit"){let O=Number(l[h+1]);Number.isFinite(O)&&(s=O),h++}else p==="--level"?(r=l[h+1]??null,h++):p==="--tail"||p==="-f"?n=!0:p==="--json"?u=!0:(p==="--internal"||p==="--all")&&(m=!0)}let $=r?new Set(r.split(",").map(h=>h.trim()).filter(h=>h==="log"||h==="info"||h==="warn"||h==="error"||h==="debug")):null;if(e==="clear"){await et(c),console.log(" log buffer cleared");break}let g=!u&&process.stdout.isTTY===!0,x=s??(n?500:e?Number(e):50);Number.isFinite(x)||(console.error(` invalid limit: ${e} \u2014 \`logs\` takes a numeric count (e.g. ${b("logs")} 100).
993
- to target a specific sim, use \`--sim ${e}\` instead.`),process.exit(1));let F=()=>Ze(c),W=h=>tt(h,{level:$,filter:t,showInternal:m});if(!n){let h=await F(),p=W(h).slice(-x);if(u){console.log(JSON.stringify(p,null,2));break}if(p.length===0){console.log(h.length===0?" no logs captured":" no matching logs");break}console.log(` ${p.length} log(s):
994
- `);for(let O of p)Pt(O,g);break}console.log(` tailing logs (ctrl-c to stop)...
995
- `);let H=new Set,U=!0,N=()=>{U=!1};process.on("SIGINT",N);try{for(;U;){let h=await F(),p=W(h);for(let O of p)H.has(O.id)||(H.add(O.id),u?console.log(JSON.stringify(O)):Pt(O,g));await X(250)}}finally{process.off("SIGINT",N)}break}default:console.error(` unknown subcommand: ${y}`),process.exit(1)}if(ee.has(y)&&!o.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&await q(c),!K.has(y)&&!D(l))try{await V(c)}catch{}}catch(e){let t=e instanceof Error?e.message:String(e);console.error(` ${y??"inspect"} failed: ${t}`);let s=/^no sim connected with id (.+)$/.exec(t),r=/^command timed out after \d+s$/.test(t)||t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("could not connect to ws://");if(s)await lt(c,_,s[1]);else if(/^no sim connected$/.test(t))at(_);else if(r)process.stderr.write(` the sim is not responding. recover it with:
963
+ `);for(let p of h)At(p);break}console.log(` tailing network (ctrl-c to stop)...
964
+ `);let W=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let N=await $(),h=F(N);for(let p of h)p.durationMs!=null&&(W.has(p.id)||(W.add(p.id),x?console.log(JSON.stringify(p)):At(p)));await X(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let e=a[1],t=null,s=null,n=null,r=!1,u=!1,m=!1;for(let h=0;h<l.length;h++){let p=l[h];if(p==="--filter")t=l[h+1]??null,h++;else if(p==="--limit"){let O=Number(l[h+1]);Number.isFinite(O)&&(s=O),h++}else p==="--level"?(n=l[h+1]??null,h++):p==="--tail"||p==="-f"?r=!0:p==="--json"?u=!0:(p==="--internal"||p==="--all")&&(m=!0)}let x=n?new Set(n.split(",").map(h=>h.trim()).filter(h=>h==="log"||h==="info"||h==="warn"||h==="error"||h==="debug")):null;if(e==="clear"){await tt(c),console.log(" log buffer cleared");break}let g=!u&&process.stdout.isTTY===!0,$=s??(r?500:e?Number(e):50);Number.isFinite($)||(console.error(` invalid limit: ${e} \u2014 \`logs\` takes a numeric count (e.g. ${b("logs")} 100).
965
+ to target a specific sim, use \`--sim ${e}\` instead.`),process.exit(1));let F=()=>et(c),W=h=>ot(h,{level:x,filter:t,showInternal:m});if(!r){let h=await F(),p=W(h).slice(-$);if(u){console.log(JSON.stringify(p,null,2));break}if(p.length===0){console.log(h.length===0?" no logs captured":" no matching logs");break}console.log(` ${p.length} log(s):
966
+ `);for(let O of p)Ot(O,g);break}console.log(` tailing logs (ctrl-c to stop)...
967
+ `);let H=new Set,U=!0,N=()=>{U=!1};process.on("SIGINT",N);try{for(;U;){let h=await F(),p=W(h);for(let O of p)H.has(O.id)||(H.add(O.id),u?console.log(JSON.stringify(O)):Ot(O,g));await X(250)}}finally{process.off("SIGINT",N)}break}default:console.error(` unknown subcommand: ${y}`),process.exit(1)}if(ee.has(y)&&!o.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&await q(c),!K.has(y)&&!D(l))try{await V(c)}catch{}}catch(e){let t=e instanceof Error?e.message:String(e);console.error(` ${y??"inspect"} failed: ${t}`);let s=/^no sim connected with id (.+)$/.exec(t),n=/^command timed out after \d+s$/.test(t)||t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("could not connect to ws://");if(s)await ct(c,_,s[1]);else if(/^no sim connected$/.test(t))lt(_);else if(n)process.stderr.write(` the sim is not responding. recover it with:
996
968
  sootsim close --sim <id> # force-close the wedged sim
997
969
  sootsim list # confirm it's gone
998
- `);else{try{await Be(c)}catch{}try{await Z({includeTail:!0})}catch{}try{await M({includeTail:!0})}catch{}}process.exit(1)}finally{c.close()}}export{Gs as runInspect};
970
+ `);else{try{await Be(c)}catch{}try{await Z({includeTail:!0})}catch{}try{await M({includeTail:!0})}catch{}}process.exit(1)}finally{c.close()}}export{Xs as runInspect};