sootsim 0.1.51 → 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 (141) hide show
  1. package/dist-cli/bin.js +7 -7
  2. package/dist-cli/chunks/{agent-RLBVAUCW.js → agent-PA7ZGTHU.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-TWLPNETE.js → agent-wrapper-CVZFXQKJ.js} +2 -2
  4. package/dist-cli/chunks/{assert-JLQSBZPM.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-DBHV5S2L.js → chunk-2ZBZCRN6.js} +1 -1
  8. package/dist-cli/chunks/{chunk-L4OPPOPY.js → chunk-5Q3XBH5M.js} +2 -2
  9. package/dist-cli/chunks/{chunk-IEYPDVW2.js → chunk-5U2BN4IU.js} +2 -2
  10. package/dist-cli/chunks/{chunk-265YGINI.js → chunk-6A4CZMPO.js} +6 -3
  11. package/dist-cli/chunks/{chunk-LMINUIAR.js → chunk-6JZNIGOQ.js} +1 -1
  12. package/dist-cli/chunks/{chunk-VDUWPVZT.js → chunk-7IYYIF5B.js} +2 -2
  13. package/dist-cli/chunks/{chunk-SPMHQKNI.js → chunk-7ZHWA3WD.js} +78 -78
  14. package/dist-cli/chunks/{chunk-ET5NKJVL.js → chunk-AFXPU7YQ.js} +29 -29
  15. package/dist-cli/chunks/{chunk-DBYZF6KL.js → chunk-AYU6WUNF.js} +1 -1
  16. package/dist-cli/chunks/{chunk-67AZW4HJ.js → chunk-AZYLZGRV.js} +1 -1
  17. package/dist-cli/chunks/{chunk-ZT7672XM.js → chunk-BPXSSZJS.js} +3 -3
  18. package/dist-cli/chunks/chunk-CKZSGUTE.js +2 -0
  19. package/dist-cli/chunks/{chunk-M7HK7MWE.js → chunk-CRUPWYHV.js} +3 -3
  20. package/dist-cli/chunks/{chunk-P2IC3VRD.js → chunk-CTDDR7HW.js} +2 -2
  21. package/dist-cli/chunks/{chunk-54IIO5BV.js → chunk-CTGH5SFH.js} +1 -1
  22. package/dist-cli/chunks/{chunk-IENPCJTB.js → chunk-CW2X4KRW.js} +4 -4
  23. package/dist-cli/chunks/{chunk-FSTOUA6L.js → chunk-E3S6U2QR.js} +1 -1
  24. package/dist-cli/chunks/{chunk-CLSZB5BN.js → chunk-E4JTYQVY.js} +2 -2
  25. package/dist-cli/chunks/chunk-ELEP2COQ.js +3 -0
  26. package/dist-cli/chunks/{chunk-ZEIDKF3M.js → chunk-ERC46HTZ.js} +1 -1
  27. package/dist-cli/chunks/{chunk-PTW5KT4I.js → chunk-FDA2NX2E.js} +2 -2
  28. package/dist-cli/chunks/{chunk-BKXH674Z.js → chunk-GWGF4J4Y.js} +2 -2
  29. package/dist-cli/chunks/chunk-H4C3WE3C.js +1 -0
  30. package/dist-cli/chunks/{chunk-6NR6NFDC.js → chunk-IS5ORPFW.js} +2 -2
  31. package/dist-cli/chunks/{chunk-3BUWCNVX.js → chunk-LELB2PV3.js} +1 -1
  32. package/dist-cli/chunks/chunk-LL3XAMKC.js +16 -0
  33. package/dist-cli/chunks/{chunk-HATEGE6O.js → chunk-LYHVX7TD.js} +4 -4
  34. package/dist-cli/chunks/{chunk-AQN3BB3D.js → chunk-MX5HFYST.js} +1 -1
  35. package/dist-cli/chunks/{chunk-VR2UDTSA.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-AWQGGSDW.js → chunk-R3VVVXF3.js} +2 -2
  39. package/dist-cli/chunks/{chunk-FUHHRW7G.js → chunk-R5XV3WIE.js} +2 -2
  40. package/dist-cli/chunks/{chunk-P45EZ2VW.js → chunk-RBXJA2PW.js} +2 -2
  41. package/dist-cli/chunks/{chunk-VXLRXQER.js → chunk-SQZXAKBL.js} +2 -2
  42. package/dist-cli/chunks/{chunk-5PKYORP6.js → chunk-STWL7EXR.js} +1 -1
  43. package/dist-cli/chunks/{chunk-45XEBYVX.js → chunk-WBAIONOO.js} +2 -2
  44. package/dist-cli/chunks/{chunk-SLAAAEUZ.js → chunk-WXOAHKCZ.js} +1 -1
  45. package/dist-cli/chunks/{chunk-RSEV5NWY.js → chunk-XBP7BBSF.js} +2 -2
  46. package/dist-cli/chunks/{chunk-EOYTPHOU.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-BGZRRNK4.js → chunk-YEE4EO2P.js} +1 -1
  50. package/dist-cli/chunks/{chunk-XWHWPFBE.js → chunk-ZYITMTYD.js} +1 -1
  51. package/dist-cli/chunks/cli-version-NMWGV7OU.js +2 -0
  52. package/dist-cli/chunks/{compat-WUI6VQPS.js → compat-CHBJ7TDK.js} +3 -3
  53. package/dist-cli/chunks/{config-XCFL4A6Z.js → config-XTZOLM5E.js} +2 -2
  54. package/dist-cli/chunks/control-XAZGNLFM.js +2 -0
  55. package/dist-cli/chunks/{cpu-profile-CPOEDK5W.js → cpu-profile-EQHKYVOF.js} +2 -2
  56. package/dist-cli/chunks/{daemon-NFZOWPYN.js → daemon-K42MZR2E.js} +2 -2
  57. package/dist-cli/chunks/{debug-G6FBH3B4.js → debug-ULTTL5L2.js} +3 -3
  58. package/dist-cli/chunks/demo-app-registry-SO43B5HW.js +2 -0
  59. package/dist-cli/chunks/{detox-PUCPDKAO.js → detox-LU3G3EBC.js} +2 -2
  60. package/dist-cli/chunks/{device-IUUKTF7R.js → device-RYW4ZE4R.js} +2 -2
  61. package/dist-cli/chunks/diagnose-5YQAXWFB.js +41 -0
  62. package/dist-cli/chunks/drivers-SXP44QNY.js +2 -0
  63. package/dist-cli/chunks/{electron-HGY5WSFG.js → electron-ORBIXXTP.js} +3 -3
  64. package/dist-cli/chunks/flow-GP7GAXLT.js +2 -0
  65. package/dist-cli/chunks/{hints-H7IVKEWB.js → hints-V4SHPWCI.js} +2 -2
  66. package/dist-cli/chunks/{home-paths-U5CDMYH5.js → home-paths-UYEDTYXU.js} +2 -2
  67. package/dist-cli/chunks/{inspect-6WSCE3W3.js → inspect-K2FN4JPL.js} +105 -130
  68. package/dist-cli/chunks/install-R4H47HDX.js +2 -0
  69. package/dist-cli/chunks/{install-desktop-QTZ3IBQW.js → install-desktop-BDDNVONK.js} +3 -3
  70. package/dist-cli/chunks/{keys-DCQXAY66.js → keys-QH5VOSUK.js} +2 -2
  71. package/dist-cli/chunks/{launch-FTHBNATG.js → launch-K2LP5XFZ.js} +3 -3
  72. package/dist-cli/chunks/{login-4GUBAGPQ.js → login-5AJTPRVD.js} +4 -4
  73. package/dist-cli/chunks/{logout-N25HFETU.js → logout-45VCRSXX.js} +2 -2
  74. package/dist-cli/chunks/{maestro-WQBZZDTR.js → maestro-5LDII3YE.js} +9 -9
  75. package/dist-cli/chunks/{preview-6MWJ6BSM.js → preview-IA2UUMLO.js} +2 -2
  76. package/dist-cli/chunks/{profile-UXJEGF4I.js → profile-ZALUAYTJ.js} +2 -2
  77. package/dist-cli/chunks/{react-MHPIWH3F.js → react-KJBOHVG7.js} +2 -2
  78. package/dist-cli/chunks/record-UI226Z7F.js +41 -0
  79. package/dist-cli/chunks/runtime-JNHCYB5L.js +2 -0
  80. package/dist-cli/chunks/{runtime-delivery-IIDHK55K.js → runtime-delivery-Y4QVOPLO.js} +2 -2
  81. package/dist-cli/chunks/{screenshot-MDE5ZSST.js → screenshot-SV5S4UGU.js} +2 -2
  82. package/dist-cli/chunks/{screenshot-mode-7W7L7IN3.js → screenshot-mode-NCISGI6W.js} +2 -2
  83. package/dist-cli/chunks/{screenshots-24LEZPD7.js → screenshots-MQZDYKF5.js} +2 -2
  84. package/dist-cli/chunks/{server-52HFHX3S.js → server-RLDTPMHN.js} +11 -11
  85. package/dist-cli/chunks/setup-repo-F4RNWTDL.js +2 -0
  86. package/dist-cli/chunks/{skills-3DGYETTU.js → skills-NECP76E4.js} +2 -2
  87. package/dist-cli/chunks/{start-NFVPQX74.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-THI53N25.js → test-YJLRC3IE.js} +3 -3
  91. package/dist-cli/chunks/three-mode-NAAIMEHL.js +54 -0
  92. package/dist-cli/chunks/{timeline-KAJ6PR4S.js → timeline-BJXCTH7E.js} +2 -2
  93. package/dist-cli/chunks/{upgrade-APDFMQCW.js → upgrade-NRJOML2W.js} +2 -2
  94. package/dist-cli/chunks/upload-BQTZTOJL.js +2 -0
  95. package/dist-cli/chunks/web-P3IP7M5Q.js +2 -0
  96. package/dist-cli/chunks/{what-happened-4VMBEL5Z.js → what-happened-5Q2RBX5R.js} +2 -2
  97. package/dist-cli/chunks/{whoami-NJOQICNO.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 +63 -7
  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 +67 -7
  116. package/dist-lib/vite.cjs +1 -1
  117. package/package.json +1 -1
  118. package/dist-cli/chunks/auto-bootstrap-UKUFJBJA.js +0 -2
  119. package/dist-cli/chunks/beta-4OEWPO5F.js +0 -2
  120. package/dist-cli/chunks/chunk-2ZCJFJJN.js +0 -37
  121. package/dist-cli/chunks/chunk-3HO4Q25D.js +0 -1
  122. package/dist-cli/chunks/chunk-4D7Z64YQ.js +0 -2
  123. package/dist-cli/chunks/chunk-4QM4J2UK.js +0 -108
  124. package/dist-cli/chunks/chunk-ACQXOAQI.js +0 -2
  125. package/dist-cli/chunks/chunk-DV3SI64Q.js +0 -1
  126. package/dist-cli/chunks/chunk-EWSS4C2R.js +0 -1
  127. package/dist-cli/chunks/chunk-JZ65NOXB.js +0 -16
  128. package/dist-cli/chunks/control-KE4VM2BN.js +0 -2
  129. package/dist-cli/chunks/demo-app-registry-U4FCHIYP.js +0 -2
  130. package/dist-cli/chunks/diagnose-6RY4YXSP.js +0 -41
  131. package/dist-cli/chunks/drivers-2FY62QZA.js +0 -2
  132. package/dist-cli/chunks/flow-HEYPRCST.js +0 -2
  133. package/dist-cli/chunks/install-NPNUNOL6.js +0 -2
  134. package/dist-cli/chunks/record-K5DRP3G7.js +0 -18
  135. package/dist-cli/chunks/runtime-UVFYTDXE.js +0 -2
  136. package/dist-cli/chunks/setup-repo-ZHEBGISP.js +0 -2
  137. package/dist-cli/chunks/store-R2RI4XAS.js +0 -2
  138. package/dist-cli/chunks/telemetry-KGU6DBN6.js +0 -2
  139. package/dist-cli/chunks/three-mode-HUI4SESE.js +0 -39
  140. package/dist-cli/chunks/upload-K7OWH74D.js +0 -2
  141. package/dist-cli/chunks/web-XDGC5KGT.js +0 -2
@@ -1,12 +1,12 @@
1
- /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as G}from"./chunk-P45EZ2VW.js";import{a as De,b as Be}from"./chunk-XWHWPFBE.js";import{a as X,b as D,c as B,d as z,e as ce,f as ne,g as st,h as nt,i as $e}from"./chunk-2ZCJFJJN.js";import{D as ot,a as je,b as Le,c as Je,d as qe,e as We,f as we,g as xe,h as He,i as Ke,j as Ue,k as ze,l as Ye,m as Ge,n as Xe,o as Ve,p as Qe,q as Ze,u as et,w as se,x as tt}from"./chunk-4QM4J2UK.js";import{a as Ee,e as le}from"./chunk-SPMHQKNI.js";import{b as rt,c as it,i as at}from"./chunk-ZT7672XM.js";import"./chunk-SLAAAEUZ.js";import{a as Ce}from"./chunk-LMINUIAR.js";import"./chunk-265YGINI.js";import"./chunk-DBYZF6KL.js";import"./chunk-VDUWPVZT.js";import"./chunk-EWSS4C2R.js";import"./chunk-BGZRRNK4.js";import{a as ye,c as he,d as _e}from"./chunk-EOYTPHOU.js";import{a as Ie}from"./chunk-4D7Z64YQ.js";import{c as Ae,e as Pe,f as Oe,g as Re,h as be}from"./chunk-BKXH674Z.js";import{b as Fe}from"./chunk-5PKYORP6.js";import"./chunk-ACQXOAQI.js";import"./chunk-FSTOUA6L.js";import"./chunk-3BUWCNVX.js";import{existsSync as Lt,mkdirSync as Jt,readFileSync as qt,rmSync as lt,writeFileSync as Wt}from"fs";import{tmpdir as Ht}from"os";import{dirname as Kt,join as Ut,resolve as zt}from"path";var re=1,Yt="SOOTSIM_INSPECT_NOTICE_PATH",Gt=300*1e3,Xt=15e3;function ct(){return zt(process.env[Yt]||Ut(Ht(),"sootsim-inspect-notice-state.json"))}function Vt(s,d){return Object.fromEntries(Object.entries(s).filter(([,a])=>typeof a?.signature=="string"&&Number.isFinite(a?.updatedAt)&&d-a.updatedAt<=Gt))}function Qt(s){let d=ct();if(!Lt(d))return{version:re,entries:{}};try{let a=JSON.parse(qt(d,"utf8"));return a.version!==re||!a.entries||typeof a.entries!="object"?(lt(d,{force:!0}),{version:re,entries:{}}):{version:re,entries:Vt(a.entries,s)}}catch{return lt(d,{force:!0}),{version:re,entries:{}}}}function Zt(s){let d=ct();Jt(Kt(d),{recursive:!0}),Wt(d,JSON.stringify(s,null,2)+`
3
- `)}function eo(s,d){let a=d.trim()||"default";return`${s}:${a}`}function Se(s,d,a,l={}){let f=l.nowMs??Date.now(),i=l.cooldownMs??Xt,y=Qt(f),S=eo(s,d),I=y.entries[S];return I&&I.signature===a&&f-I.updatedAt<i?!1:(y.entries[S]={signature:a,updatedAt:f},Zt(y),!0)}async function dt(s,d={args:[]}){let a=await je(s);if(D(d.args)){B(a);return}console.log(` nodes: ${a.nodes}`)}function ke(s,d){let a=s.indexOf(d);return a>=0&&a+1<s.length?s[a+1]:null}async function ut(s){let{bridge:d,args:a,positional:l}=s,f=a.includes("--verbose")||a.includes("-v"),i=D(a),y=f&&!i,S=a.includes("--watch")||a.includes("-w"),I=1e3,v=a.includes("--compact"),b=a.includes("--no-xy"),k=ke(a,"--testid-like"),_=ke(a,"--only"),T=ke(a,"--subtree"),E=l[1],c=E?/[*?]/.test(E):!1,J=!c&&!_?E:void 0,U=_??(c?E:void 0),C=async()=>{await ce(d,{verbose:y});let Y=await qe(d,{describe:!0,verbose:f,filter:J||"",testIdLike:k||void 0,onlyGlob:U||void 0,subtreeRoot:T||void 0,compact:v,hideXy:b}),W=Y?.tree,w=Y?.shell,M=Y?.keyboard;if(i){B({shell:w,tree:W??"",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 W=="string"&&W.startsWith("__SUBTREE_NOT_FOUND__:")){let P=W.slice(22);console.log(` subtree root not found: ${P}`),G("subtree-root-not-found",P);return}if(!W){let P=Y?.nodeCount??0;console.log(" no matching nodes found"),!(J||k||U||T)&&P<10&&G("app-still-loading",P);return}if(console.log(W),!(J||k||U||T)&&!S&&W.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 C(),await X(I);else await C()}var to=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function mt(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let s of to){let d=process.env[s];if(d&&d.trim()&&d!=="0")return!0}return!1}async function pt(s){let{bridge:d,args:a,effectiveArgs:l,positional:f,inspectUsage:i}=s,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"),v=y("--role"),b=y("--type"),k=y("--text"),_=S("--pressable"),T=S("--visible"),E=S("--interactive-targets")||S("--actions"),c=!I&&!v&&!b&&!k&&!_&&!T&&!E?f[1]:null,J=k??c,U=await We(d,{testId:I,role:v,type:b,text:J,pressable:_,visible:T,interactive:E});U||(console.error(i("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:C,result:L}=U,Y=D(a),W=a.includes("--verbose")||a.includes("--dump");if(Y)C==="interactive-targets"&&Array.isArray(L)?B(we(L).map(w=>({...w,tap:xe(w)}))):B(L??null);else if(Array.isArray(L))if(L.length===0){console.log(` no ${C} 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(C==="interactive-targets"){let w=we(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)}"`:"",te=M.testID?` #${M.testID}`:"",e=M.accessibilityLabel?` \u24D8"${String(M.accessibilityLabel).slice(0,24)}"`:"",t=M.accessibilityRole?`[${M.accessibilityRole}]`:M.type,o=xe(M);console.log(` ${t}${V}${e}${te} ${P} ${Z}`),console.log(` \u2192 ${o}`),W&&console.log(ve(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"} (${C}):`);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}`:"",te=w.pressable?" (tap)":"",e=w.accessibilityRole?`[${w.accessibilityRole}]`:w.type;console.log(` ${e}${P}${V} ${Z} ${M}${te}`),W&&console.log(ve(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||v||b||""||C}`),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}`:"",te=w.pressable?" (tap)":"",e=w.accessibilityRole?`[${w.accessibilityRole}]`:w.type;console.log(` ${e}${P}${V} ${Z} ${M}${te}`),W&&console.log(ve(JSON.stringify(w,null,2)," "))}else console.log(JSON.stringify(L,null,2))}}function ve(s,d){return s.split(`
7
- `).map(a=>d+a).join(`
8
- `)}async function ft(s,d={}){let a=await et(s);if("error"in a&&(console.error(a.error),process.exit(1)),d.json){console.log(JSON.stringify(a,null,2));return}let{visible:l,spec:f,mode:i,shifted:y,capsLock:S,accessoryBarId:I}=a,v=[];v.push(`keyboard: ${l?"visible":"hidden"}`),f?(v.push(` type: ${f.keyboardType}`),v.push(` returnKey: ${f.returnKeyType}`),v.push(` autoCap: ${f.autoCapitalize}`),v.push(` autoCorrect: ${f.autoCorrect?"on":"off"}`),v.push(` appearance: ${f.keyboardAppearance}`),f.secureTextEntry&&v.push(" secureTextEntry: true"),f.enablesReturnKeyAutomatically&&v.push(` return: ${f.currentTextIsEmpty?"disabled (empty)":"enabled"}`)):v.push(" spec: <none> (shown via dev-tools with no TextInput)"),v.push(` mode: ${i}${y?" (shifted)":""}${S?" (caps)":""}`),I&&v.push(` accessoryBar: ${I}`),console.log(v.join(`
9
- `))}async function gt(s){let d=await s.bridge.listSims();if(D(s.args)){B(d.map(a=>({...a,active:a.id===s.simId})));return}at(d,s.simId)}function ee(s){return s<1024?`${s}B`:s<1024*1024?`${(s/1024).toFixed(1)}KB`:`${(s/1024/1024).toFixed(1)}MB`}function de(s,d){return d<=0?"?":`${(s/d*100).toFixed(0)}%`}async function yt(s,d={args:[]}){let a=await ot(s);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} (${de(l.cacheEntries,l.cacheMaxEntries)})`),console.log(` pixel bytes: ${ee(l.cachePixelBytes)} / ${ee(l.cachePixelBudget)} (${de(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: ${ee(l.usedJSHeapSize)} / ${ee(l.jsHeapSizeLimit)} (${de(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${ee(l.totalJSHeapSize)}`)}if(a.hostHeap){let l=a.hostHeap;console.log(" host heap (chrome only)"),console.log(` used: ${ee(l.usedJSHeapSize)} / ${ee(l.jsHeapSizeLimit)} (${de(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${ee(l.totalJSHeapSize)}`)}}function ie(s){let d=s.indexOf("--testid");if(d>=0&&s[d+1])return{mode:"testid",value:s[d+1]};let a=s.indexOf("--test-id");if(a>=0&&s[a+1])return{mode:"testid",value:s[a+1]};let l=s.indexOf("--text");return l>=0&&s[l+1]?{mode:"text",value:s[l+1]}:null}async function ue(s,d){let a=JSON.stringify(d.value),l=d.mode==="testid"?`(await t.findByTestId(${a})) || (await t.findById(${a}))`:`await t.findByText(${a})`;return await s.send({type:"evaluate",code:`(async () => {
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-P45EZ2VW.js";import{a as De,b as Be}from"./chunk-XWHW
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 ht(s,d={}){let{nav:a,keyboard:l,shell:f}=await tt(s);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":" ",v=S.routeName?` ${S.routeName}`:"",b=S.headerHeight>0?` header=${S.headerHeight}`:"",k=S.largeTitleState&&S.largeTitleState!=="expanded"?` large-title=${S.largeTitleState}`:"";i.push(` ${I} #${S.id}${v}${b}${k}`)}}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 oe({bridge:s,maxMs:d,pollMs:a=50,stablePolls:l=3,strict:f=!1}){let i=await s.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-P45EZ2VW.js";import{a as De,b as Be}from"./chunk-XWHW
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 bt(s){let{bridge:d,args:a,positional:l}=s,f=l[1]?Number(l[1])*1e3:3e3,i=a.includes("--strict"),{elapsed:y,settled:S}=await oe({bridge:d,maxMs:f,strict:i});console.log(S?` settled in ${y}ms`:` timed out after ${y}ms (may still be animating)`)}async function wt(s){let d=s.positional[1]?Number(s.positional[1]):.5;(!Number.isFinite(d)||d<0)&&(console.error(s.inspectUsage("sleep","[seconds]")),process.exit(1)),await X(d*1e3),console.log(` slept ${d}s`)}async function xt(s){let{bridge:d,args:a,positional:l}=s,f=l[1]?Number(l[1]):5,{tree:i}=await Le(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 $t(s,d={args:[]}){let a=await Je(s);if(D(d.args)){B(a);return}console.log(a.url)}async function St(s){let{wsPort:d,commandTimeoutMs:a,simId:l,positional:f}=s,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 st(d,a,l,{attempts:S});I||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),I.bridge.close(),le({source:"inspect wait",step:{wait:y},summary:`wait ${Math.round(y/1e3)}s`}),console.log(` ready: ${I.count} nodes`)}var kt=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function me(s,d){let a=s.indexOf(d);if(a>=0&&a+1<s.length)return s[a+1]}function oo(s,d){if(!d.filter&&!d.equals)return!0;let a=s.data,l=[];if(a&&typeof a=="object")for(let i of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let 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 vt(s){let{bridge:d,args:a,positional:l,inspectUsage:f}=s,i=l[1];i||(console.error(f("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),kt.has(i)||console.error(` warning: '${i}' is not a known timeline kind \u2014 waiting anyway. known: ${[...kt].sort().join(", ")}`);let y=me(a,"--max-ms"),S=y&&Number.isFinite(Number(y))?Math.max(100,Number(y)):5e3,I=me(a,"--filter"),v=me(a,"--equals"),b=me(a,"--since")??"now",k=a.includes("--json"),_=Date.now(),T=_+S,E=200,c=_;for(;Date.now()<T;){let U={kinds:[i],since:b==="cursor"?void 0:c,limit:50},C=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
- return { ok: true, result: await t.recent(${JSON.stringify(U)}) }
81
- })()`});(!C||!C.ok)&&(console.error(` could not query timeline: ${C&&"error"in C?C.error:"unknown"}`),process.exit(1));let L=C.result.events??[];for(let Y of L)if(oo(Y,{filter:I,equals:v})){let W=Date.now()-_;console.log(k?JSON.stringify({found:!0,elapsedMs:W,event:Y}):` ${i} event after ${W}ms${I?` (filter: ${I})`:""}${v?` (equals: ${v})`:""}`);return}C.result.watermark&&C.result.watermark>c&&(c=C.result.watermark),await new Promise(Y=>setTimeout(Y,E))}let J=Date.now()-_;k?console.log(JSON.stringify({found:!1,elapsedMs:J,kind:i,filter:I,equals:v})):console.error(` \u26A0 wait event ${i} timed out after ${J}ms${I?` (filter: ${I})`:""}${v?` (equals: ${v})`:""}`),process.exit(1)}async function Tt(s){let{bridge:d,args:a}=s,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 oe({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 Mt(s){let{bridge:d,args:a}=s,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 He(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 Nt(s){let{bridge:d,args:a,positional:l,inspectUsage:f}=s,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:v,elapsed:b}=await Ke(d,i,S);if(I&&v){let k=v.absolutePosition?`@(${Math.round(v.absolutePosition.x)},${Math.round(v.absolutePosition.y)})`:"",_=v.layout?`${Math.round(v.layout.width)}x${Math.round(v.layout.height)}`:"?x?";console.log(` found #${i} in ${b}ms ${_} ${k}`)}else console.error(` \u26A0 wait selector #${i} timed out after ${b??S}ms`),process.exit(1)}function Ot(s){return s==null?"\u2014":s<1024?`${s}B`:s<1024*1024?`${(s/1024).toFixed(1)}K`:`${(s/1024/1024).toFixed(1)}M`}function Rt(s){return s==null?" \u2026":s<1e3?`${s}ms`.padStart(5):`${(s/1e3).toFixed(2)}s`.padStart(5)}function no(s){return s.error?"err":s.status==null?" \u2026 ":String(s.status)}function It(s){let d=new Date(s.startTs).toLocaleTimeString(),a=no(s).padEnd(3),l=s.method.padEnd(5),f=Ot(s.size).padStart(6),i=Rt(s.durationMs);console.log(` [${d}] ${a} ${l} ${f} ${i} ${s.displayUrl}`),s.error&&console.log(` error: ${s.error}`)}function ro(s){let d=[["id",s.id],["source",s.source],["kind",s.kind],["method",s.method],["status",s.error?`error: ${s.error}`:`${s.status??"\u2014"} ${s.statusText??""}`.trim()],["url",s.url],["started",new Date(s.startTs).toLocaleTimeString()],["duration",Rt(s.durationMs).trim()],["size",Ot(s.size)],["content-type",s.type??"\u2014"]];for(let[a,l]of d)console.log(` ${a.padEnd(13)} ${l}`)}var io={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},_t="\x1B[0m",ao="\x1B[2m";function Ft(s,d){let a=new Date(s.ts).toLocaleTimeString(),l=s.level.toUpperCase().padEnd(5),f=s.args.join(" ");if(d){let i=io[s.level];console.log(` ${ao}[${a}]${_t} ${i}${l}${_t} ${f}`)}else console.log(` [${a}] ${l} ${f}`);if(s.stack&&s.level==="error"){let i=s.stack.split(`
82
- `).slice(0,5);for(let y of i)console.log(` ${y.trim()}`)}}var Q="__sootsimCliPerf",lo=120;async function At(s,d){let a=s.find((_,T)=>s[T-1]==="--id"),l=s.find((_,T)=>s[T-1]==="--text");if(a||l){let _=await d.send({type:"evaluate",code:De({id:a,text:l})});if(!_)throw new Error(a?`no node with id "${a}"`:`no node matching text "${l}"`);let{x:T,y:E,w:c,h:J}=_;return{x:T,y:E,w:c,h:J}}let f=s.find((_,T)=>s[T-1]==="--area");if(f){let _=f.split(",").map(U=>Number(U.trim()));if(_.length!==4||_.some(U=>!Number.isFinite(U)))throw new Error(`--area expects x,y,w,h (got "${f}")`);let[T,E,c,J]=_;return{x:T,y:E,w:c,h:J}}let i=_=>{let T=s.find((c,J)=>s[J-1]===_);if(T==null)return null;let E=Number(T);return Number.isFinite(E)?E:null},y=i("--x"),S=i("--y"),I=i("--w"),v=i("--h");if(y!=null||S!=null||I!=null||v!=null)return{x:y??0,y:S??0,w:I??1,h:v??1};let k=s.filter((_,T)=>T>0&&!_.startsWith("-")&&s[T-1]!=="--output"&&s[T-1]!=="--area"&&s[T-1]!=="--id"&&s[T-1]!=="--text"&&s[T-1]!=="--x"&&s[T-1]!=="--y"&&s[T-1]!=="--w"&&s[T-1]!=="--h").map(Number).filter(_=>Number.isFinite(_));if(k.length>=2){let[_,T,E=1,c=1]=k;return{x:_,y:T,w:E,h:c}}return null}function Te(s){let d={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let a of s)a<8?d["<8"]++:a<12?d["8-12"]++:a<16?d["12-16"]++:a<20?d["16-20"]++:a<33?d["20-33"]++:d[">33"]++;console.log(" histogram:");for(let[a,l]of Object.entries(d)){let f="\u2588".repeat(Math.ceil(l/s.length*40));console.log(` ${a.padEnd(6)} ${f} ${l}`)}}async function pe(s,d,a){let l=Date.now()+d,f=await se(s,d);for(;;){if(a(f))return{settled:!0,state:f};if(Date.now()>=l)return{settled:!1,state:f};await X(16),f=await se(s)}}async function Ne(s){return s.send({type:"evaluate",code:`(async () => {
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 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-P45EZ2VW.js";import{a as De,b as Be}from"./chunk-XWHW
111
111
  frame: runtimeSnapshot?.keyboard?.frame ?? null,
112
112
  focusedRect: runtimeSnapshot?.focused?.rect ?? null,
113
113
  }
114
- })()`})}async function co(s,d=600){let a=Date.now()+d;for(;Date.now()<=a;){let l=await Ne(s);if(l.visible)return l;await X(30)}return Ne(s)}async function fe(s,d){let a=await Ne(s);if(a.visible)return a;console.error(` ${d} requires the iOS keyboard to be visible. focus an input first with sootsim do tap-id/tap-text or sootsim do type-into.`),process.exit(1)}async function Pt(s,d,a){return d==="appearance"?s.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
@@ -125,28 +125,28 @@ import{a as G}from"./chunk-P45EZ2VW.js";import{a as De,b as Be}from"./chunk-XWHW
125
125
  ? (window.matchMedia?.('(prefers-color-scheme: dark)')?.matches ? 'dark' : 'light')
126
126
  : next
127
127
  return { ok: true, requested, value: next, applied }
128
- })()`}):s.send({type:"evaluate",code:`(async () => {
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 uo(s){let d={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(d[s])return d[s];let a=s.match(/^Digit([0-9])$/);if(a)return a[1];let l=s.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function mo(s){if(typeof s!="string")return null;let d=s.replace(/\s+/g," ").trim();return d?d.slice(0,80):null}function Et(...s){for(let d of s){if(typeof d!="string")continue;let a=d.trim();if(a)return a}return null}async function j(s,d,a){let l=le({source:s,step:d,summary:a});l.active&&(l.replaced?console.error(` draft: replaced unkept action "${l.replaced.summary}" \u2014 \`flow keep\` commits one action at a time`):console.error(" draft: action pending \u2014 `sootsim flow keep` to commit"))}function po(s,d,a){if(!a||a.hit===!1)return null;let l=Et(a.responderTestID,a.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let f=mo(a.text);return f?{step:{tapOn:f},summary:`tap "${f}"`}:{step:{tapAtCoords:{x:s,y:d}},summary:`tap @${Math.round(s)},${Math.round(d)}`}}function Me(s,d,a){let l=Et(d?.testID,d?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:a==="id"?{step:{tapOn:{id:s}},summary:`tap #${s}`}:{step:{tapOn:s},summary:`tap "${s}"`}}async function zs(s,d){let a=s[0]==="get"||s[0]==="do"||s[0]==="debug"||s[0]==="wait"?s[0]:null,l=a?s.slice(1):s,f=Ae(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"&&_e.has(l[0]),v=I?l[0]:null,b=e=>I&&e===l[0]?`sootsim ${e}`:`sootsim ${S} ${e}`,k=(e,t)=>` usage: ${b(e)}${t?` ${t}`:""}`;if(!y||s.includes("--help")||s.includes("-h")){let e={bridgePort:7668,defaultShellUrl:Ie};if(S==="do"||S==="get"||S==="debug"||S==="wait"){let r=ye(S,e);r&&(console.log(`${r}
132
- `),process.exit(0))}if(v==="shell"){let r=he("shell",e);r&&(console.log(`${r}
133
- `),process.exit(0))}let t=he("inspect",e),o=["do","get","debug","wait"].map(r=>ye(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
- ${o}
138
- `),process.exit(0)}let _=f.wsPort,T=f.simId,E=f.commandTimeoutMs;if(y==="list"&&l.some(e=>e==="--drivers"||e==="-D")){let{buildDriverListRows:e}=await import("./drivers-2FY62QZA.js"),t=e();console.log(` available drivers (${t.length}):
139
- `);let o=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(o),$=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=Pe(f),J=T||"default",U=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]);function C(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 L(e){let t=mt()?1200:350;try{let{settled:o,elapsed:r}=await oe({bridge:e,maxMs:t,pollMs:32,stablePolls:2});o||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.
140
- `)}catch{}}async function Y(){try{return await c.send({type:"evaluate",code:`(() => ({
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-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
+ `)}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 W(e={}){let t=e.counts!==void 0?e.counts:await z(c,"getRequestCounts");if(!t||typeof t!="object")return;let o=Math.max(0,Number(t.failed)||0);if(o===0||!e.includeTail&&!Se("requests",J,String(o))||(console.log(`
144
- network: ${o} failed request${o===1?"":"s"}`),console.log(` inspect: ${b("requests")} 5`),!e.includeTail))return;let r=await z(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}] ${C(n)}`),n.responseBody?console.log(` ${n.responseBody}`):n.error&&console.log(` ${n.error}`)}}}async function w(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 o=t,r=Math.max(0,Number(o.errors)||0),n=Math.max(0,Number(o.warnings)||0);if(r===0&&n===0||!e.includeTail&&!Se("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 M=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function Z(e){let t=Fe(),o=null;try{o=await Re(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 @@ ${o}
162
162
  }
163
163
  }
164
164
  return summary ? { summary, consoleSplit } : null
165
- })()`)}catch{return}if(!o||!o.summary||!o.summary.total)return;let r=o.summary.byKind??{},n=[],u=new Set;for(let m of M){let $=r[m];if($)if(u.add(m),m==="console"&&o.consoleSplit){let{error:g,warn:x}=o.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`),o.summary.lastAt))try{await be(e,"SootSim.bridges.timeline.cursorAdvance",t,o.summary.lastAt)}catch{}}let P=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"]),V=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"]),te=(s.includes("--verbose")||s.includes("-v"))&&!s.includes("--json");S==="do"&&y==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),P.has(y)&&await Oe(c),V.has(y)&&await ce(c,{verbose:te});try{switch(y){case"list":{await gt({bridge:c,simId:T,args:l});break}case"tree":{await xt({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(s.includes("--json"))console.log(JSON.stringify(t,null,2));else{console.log(` accessibility tree (${t.length} nodes):
195
- `);for(let o of t){let r=[];if(r.push(`[${o.role}]`),o.label){let n=o.label.length>50?o.label.slice(0,47)+"...":o.label;r.push(`"${n}"`)}if(o.hint&&r.push(`(hint: "${o.hint}")`),o.testID&&r.push(`#${o.testID}`),o.state){let n=[];o.state.disabled&&n.push("disabled"),o.state.selected&&n.push("selected"),o.state.checked===!0&&n.push("checked"),o.state.checked==="mixed"&&n.push("mixed"),o.state.busy&&n.push("busy"),o.state.expanded===!0&&n.push("expanded"),o.state.expanded===!1&&n.push("collapsed"),n.length&&r.push(`{${n.join(", ")}}`)}o.position&&r.push(`@(${o.position.x},${o.position.y})`),o.size&&r.push(`${o.size.w}x${o.size.h}`),console.log(" "+r.join(" "))}}break}case"find":{await pt({bridge:c,args:s,effectiveArgs:l,positional:i,inspectUsage:k});break}case"count":{await dt(c,{args:l});break}case"keyboard":{await ft(c,{json:s.includes("--json")});break}case"screens":{await ht(c,{json:s.includes("--json")});break}case"memory":{await yt(c,{args:l});break}case"wait":{await St({wsPort:_,commandTimeoutMs:E,simId:T,positional:i});break}case"sleep":{await wt({positional:i,inspectUsage:k});break}case"settle":{await bt({bridge:c,args:s,positional:i});break}case"ready":{await Mt({bridge:c,args:s});break}case"idle":{await Tt({bridge:c,args:s,positional:i});break}case"selector":{await Nt({bridge:c,args:s,positional:i,inspectUsage:k});break}case"event":{await vt({bridge:c,args:s,positional:i,inspectUsage:k});break}case"layout":{let e=i[1];e||(console.error(k("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=s.find(($,g)=>s[g-1]==="--output")||"/tmp/sootsim-inspect.png",o=await At(s,c),r={type:"screenshot"};o&&(r.crop=o);let u=(await c.send(r)).replace(/^data:image\/png;base64,/,"");o&&console.log(` area: x=${o.x} y=${o.y} w=${o.w} h=${o.h}`),(await import("fs")).writeFileSync(t,Buffer.from(u,"base64")),console.log(` saved: ${t}`);break}case"sample-color":{let e=await At(s,c);e||(console.error(k("sample-color","<x> <y> [w] [h] | --id <testID> | --text <text>")),console.error(" samples an averaged color from the canvas. coords are logical sootsim units."),process.exit(1));let t=await c.send({type:"evaluate",code:Be(e)});if(s.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:o,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(${o}, ${r}, ${n}, ${u}) ${g} ${$} samples`)}break}case"node":{let e=i[1];e||(console.error(k("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let t=await 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 @@ ${o}
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]),o=ie(s);if(o){let u=await ue(c,o);u||(console.error(` not found: ${o.value}`),o.mode==="testid"&&G("wait-selector-for-missing-testid",o.value),process.exit(1)),e=u.x,t=u.y}(!Number.isFinite(e)||!Number.isFinite(t))&&(console.error(k("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let r=await c.send({type:"tap",x:e,y:t}),n=po(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]),o=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(o)||!Number.isFinite(r)||!Number.isFinite(m)||!Number.isFinite($))&&(console.error(k(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}, ${o}, ${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:`${o}, ${r}`,duration:x}},`${y} ${e},${t} -> ${o},${r}`)}console.log(JSON.stringify(g,null,2));break}case"pinch":{let e=Number(i[1]),t=Number(i[2]),o=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(o)||!Number.isFinite(r)||!Number.isFinite(n)||!Number.isFinite(u)||!Number.isFinite(m)||!Number.isFinite($)||!Number.isFinite(g)||!Number.isFinite(x))&&(console.error(k("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}, ${o}, ${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,o,r],to:[n,u,m,$],steps:Math.max(1,Math.round(g)),stepMs:Math.max(0,Math.round(x))}},`pinch (${e},${t}) (${o},${r}) -> (${n},${u}) (${m},${$})`),console.log(JSON.stringify(F,null,2));break}case"tap-text":{let e=i[1];e||(console.error(k("tap-text","<text>")),process.exit(1));let t=R=>{let A=s.indexOf(R);return A>=0&&A+1<s.length?s[A+1]:null},o=R=>s.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"),$=o("--exact"),g=o("--first"),x=t("--min-y"),F=t("--max-y"),q=t("--min-x"),H=t("--max-x");for(let[R,A]of[["--min-y",x],["--max-y",F],["--min-x",q],["--max-x",H]])A!==null&&!Number.isFinite(Number(A))&&(console.error(` ${R} requires a number, got: ${A}`),process.exit(1));let K=s.indexOf("--near"),N=null;if(K>=0){let R=Number(s[K+1]),A=Number(s[K+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:q!==null?Number(q):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 @@ ${o}
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 ge=A.abs?`@(${Math.round(A.abs.x)},${Math.round(A.abs.y)})`:"",ae=A.layout?` ${A.layout.width}x${A.layout.height}`:"",Ct=A.testID?` #${A.testID}`:"",Dt=A.text?` "${A.text}"`:"",Bt=A.ancestorTestIDs.length>0?` within ${A.ancestorTestIDs.slice(0,3).map(jt=>`#${jt}`).join(" > ")}`:"";console.error(` [${A.idx}] <${A.type}>${Dt}${Ct} ${ge}${ae}${Bt}`)}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=Me(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(k("tap-best","<query>")),process.exit(1));let t=JSON.stringify(e),o=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 @@ ${o}
413
385
  }
414
386
  }
415
387
  return { strategy: 'none' }
416
- })()`});"error"in o&&(console.error(` ${o.error}`),process.exit(1)),o.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=o.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 $=Me(e,{id:r.id,testID:r.testID,type:r.type,cx:n,cy:u},o.strategy==="testid"?"id":"text");await j("inspect tap-best",$.step,$.summary)}console.log(JSON.stringify({matched:{strategy:o.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(k("tap-id","<id>")),process.exit(1));let t=JSON.stringify(e),o=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,10 +420,10 @@ ${o}
448
420
  },
449
421
  strategy: (resolved && resolved.strategy) || 'matched-node',
450
422
  }
451
- })()`});(!o||typeof o.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let r=await c.send({type:"tap",x:o.cx,y:o.cy});if(r?.hit!==!1&&r?.ok!==!1){let n=Me(e,{id:o.target?.id??null,testID:o.target?.testID??null,type:o.target?.type??null,cx:o.cx,cy:o.cy},"id");await j("inspect tap-id",n.step,n.summary)}console.log(JSON.stringify({matched:o.match,tapped:{nodeId:o.target?.nodeId??null,id:o.target?.id??null,testID:o.target?.testID??null,type:o.target?.type??null,cx:o.cx,cy:o.cy},...o.strategy&&o.strategy!=="matched-node"?{strategy:o.strategy}:{},result:r},null,2));break}case"type-into":{let e=i[1],t=i.slice(2).join(" ");(!e||!t)&&(console.error(k("type-into","<id> <text>")),process.exit(1));let o=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
- const n = await (t.findByTestId(${o}) || t.findById(${o}))
426
+ const n = await (t.findByTestId(${s}) || t.findById(${s}))
455
427
  if (!n || !n.absolutePosition || !n.layout) return null
456
428
  return {
457
429
  cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
@@ -460,41 +432,41 @@ ${o}
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 co(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(k("type","<text>")),process.exit(1)),await fe(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(k("key","<name>")),process.exit(1)),await fe(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(k("key-sequence","<key> [<key> ...]")),process.exit(1)),await fe(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(k("keycode","<code> [<code> ...]")),process.exit(1));let t=e.map(r=>({code:r,key:uo(r)})),o=t.filter(r=>!r.key);o.length>0&&(console.error(` unsupported keycode(s): ${o.map(r=>r.code).join(", ")}`),process.exit(1)),await fe(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(k("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]),o=ie(s);if(o){let m=await ue(c,o);m||(console.error(` not found: ${o.value}`),o.mode==="testid"&&G("wait-selector-for-missing-testid",o.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(k("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]),o=ie(s);if(o){let u=await ue(c,o);u||(console.error(` not found: ${o.value}`),o.mode==="testid"&&G("wait-selector-for-missing-testid",o.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(k("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]),o=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(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),e!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(o))&&(console.error(k("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(o)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${t}, y: ${o} } }));`:"",$=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}, ${o}, ${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:o}},`touch ${e} @${t},${o}`),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],o=i[2]?Number(i[2]):220;(!t||!Number.isFinite(o))&&(console.error(k("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 @@ ${o}
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),q=Math.max(24,$+18),H=18,K=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(K/2),R=x-Math.round(K/2);break;case"scroll-down":p=x-Math.round(K/2),R=x+Math.round(K/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-q,F+K);break;case"swipe-from-bottom-edge":h=g,p=u-q,R=Math.max(F,u-q-K);break}let A=Math.max(8,Math.round(o/16)),ge=Math.max(1,Math.round(o/A)),ae=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
- const value = await interact.drag(${h}, ${p}, ${O}, ${R}, ${A}, ${ge})
480
+ const value = await interact.drag(${h}, ${p}, ${O}, ${R}, ${A}, ${he})
509
481
  return { ok: !!value, value }
510
- })()`});ae?.ok&&await j("inspect gesture",{swipe:{start:`${h}, ${p}`,end:`${O}, ${R}`,duration:Math.max(1,Math.round(o))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:h,y:p},to:{x:O,y:R},result:ae},null,2));break}case"scroll":{let e=ie(s),t=e?.mode==="testid"?e.value:i[1],o=Number(i[e?1:2]),r=Number(i[e?2:3]);(!t||!Number.isFinite(o)||!Number.isFinite(r))&&(console.error(k("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 @@ ${o}
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 z(c,"scrollTo",t,o,r,!1);u?.ok&&await j("inspect scroll",{scrollTo:{id:t,x:o,y:r}},`scroll ${t} -> ${o},${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 o=await z(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
- })`});o&&typeof o=="object"&&o.diagnostics&&(o.diagnostics.errors=r?.errors??0,o.diagnostics.warnings=r?.warnings??0),console.log(JSON.stringify(o,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 @@ ${o}
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 se(c,500);break;case"worker":t=await be(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 @@ ${o}
574
546
  text: focused.text || null,
575
547
  } : null,
576
548
  }
577
- })()`});break;case"node":{let o=i[2];o||(console.error(` usage: ${b("state")} node <id>`),process.exit(1)),t=await z(c,"findByTestId",o)||await z(c,"findById",o);break}case"scroll":{let o=i[2];o||(console.error(` usage: ${b("state")} scroll <id>`),process.exit(1)),t=await z(c,"getScrollState",o);break}case"scroll-hit":{let o=Number(i[2]),r=Number(i[3]);(!Number.isFinite(o)||!Number.isFinite(r))&&(console.error(` usage: ${b("state")} scroll-hit <x> <y>`),process.exit(1)),t=await z(c,"getScrollStateAt",o,r);break}case"hit":{let o=Number(i[2]),r=Number(i[3]);(!Number.isFinite(o)||!Number.isFinite(r))&&(console.error(` usage: ${b("state")} hit <x> <y>`),process.exit(1)),t=await z(c,"debugHitAt",o,r);break}case"gesture":{let o=Number(i[2]),r=Number(i[3]);(!Number.isFinite(o)||!Number.isFinite(r))&&(console.error(` usage: ${b("state")} gesture <x> <y>`),process.exit(1)),t=await z(c,"debugGestureAt",o,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 @@ ${o}
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",o=e==="launch"||e==="open-card"?i[3]:i[2],r=o?Number(o):350;t&&(!Number.isFinite(r)||r<0)&&(console.error(k("shell",e==="launch"||e==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let n=!1,u=!1,m=null,$=s.includes("--clear-state");if(e==="launch"){let g=i[2];g||(console.error(k("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),$&&await c.send({type:"evaluate",code:Ee}),n=!!await ne(c,"launchApp",r,g),{settled:u,state:m}=await pe(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 ne(c,"goHome",r),{settled:u,state:m}=await pe(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 ne(c,"openSwitcher",r),{settled:u,state:m}=await pe(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(lo),m=await se(c));else if(e==="open-card"){let g=i[2];g||(console.error(k("shell","open-card <appId> [settleMs]")),process.exit(1)),n=!!await ne(c,"openSwitcherCard",r,g),{settled:u,state:m}=await pe(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(k("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let x=await Pt(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 Pt(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 $t(c,{args:l});break}case"reload":{let o=!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 @@ ${o}
606
578
  }
607
579
  window.location.reload()
608
580
  return { kind: 'page' }
609
- })()`});r=!!m&&m.kind==="external-app",o=!0}catch{}console.log(" reloading...");let n=c,u=null;if(r)u=await $e(c,{timeoutMs:1e4,errorGraceMs:3e3});else{o&&await X(300);let m=await nt(_,E,T,{timeoutMs:1e4});m?(n=m,u=await $e(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(k("js","<javascript>")),console.error(""),console.error(" runs the snippet in the engine realm. SootSim is the"),console.error(" canonical state surface \u2014 reach into it directly."),console.error(""),console.error(" examples:"),console.error(` ${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 o=await c.send({type:"evaluate",code:t});console.log(JSON.stringify(o,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 @@ ${o}
647
619
 
648
620
  return globals
649
621
  })()`});console.log(` sootsim JS API:
650
- `);for(let[t,o]of Object.entries(e)){console.log(` ${t}:`);for(let r of o)console.log(` .${r}`);console.log("")}console.log(` use: ${b("js")} <expression>`),console.log(` example: ${b("js")} test.findByText("Sign in")`);break}case"describe":{await ut({bridge:c,args:s,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:
@@ -688,7 +660,7 @@ ${o}
688
660
  jankFrames: frameStats.recentFrames?.filter(f => f > 16.67).length || 0,
689
661
  recentCount: frameStats.recentFrames?.length || 0,
690
662
  }
691
- })()`});t.error&&(console.error(` error: ${t.error}`),process.exit(1));let o=t.avgMs!=="?"?(1e3/parseFloat(t.avgMs)).toFixed(1):"?";console.log(" perf stats:"),console.log(` frames: ${t.frames}`),console.log(` avg: ${t.avgMs}ms (${o} fps)`),console.log(` max: ${t.maxMs}ms`),console.log(` layout: ${t.layoutMs}ms total`),console.log(` nodes: ${t.nodeCount}`),t.recentCount>0&&console.log(` jank: ${t.jankFrames}/${t.recentCount} frames >16.67ms`);break}case"start":{await c.send({type:"evaluate",code:`(async () => {
663
+ })()`});t.error&&(console.error(` error: ${t.error}`),process.exit(1));let s=t.avgMs!=="?"?(1e3/parseFloat(t.avgMs)).toFixed(1):"?";console.log(" perf stats:"),console.log(` frames: ${t.frames}`),console.log(` avg: ${t.avgMs}ms (${s} fps)`),console.log(` max: ${t.maxMs}ms`),console.log(` layout: ${t.layoutMs}ms total`),console.log(` nodes: ${t.nodeCount}`),t.recentCount>0&&console.log(` jank: ${t.jankFrames}/${t.recentCount} frames >16.67ms`);break}case"start":{await c.send({type:"evaluate",code:`(async () => {
692
664
  // worker mode
693
665
  if (window.__sootsimPerfStart && window.__sootsimRenderHost) {
694
666
  const result = window.__sootsimPerfStart()
@@ -804,8 +776,8 @@ ${o}
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 o=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 (${o} 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 o=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 @@ ${o}
840
812
  mode: 'main-thread',
841
813
  frames: (stats.recentFrames || []).slice(-${t}),
842
814
  }
843
- })()`});if(o.error&&(console.error(` error: ${o.error}`),process.exit(1)),o.mode==="render-worker"){let n=Array.isArray(o.samples)?o.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,q]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)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);console.log(""),Te(n.map(u=>u[1])),o.live&&console.log(" sampling continues");break}let r=Array.isArray(o.frames)?o.frames:Array.isArray(o)?o:[];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(", ")}`),Te(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 o=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 @@ ${o}
882
854
  mode: 'main-thread',
883
855
  frames: recent.slice().sort((a, b) => b - a).slice(0, ${t}),
884
856
  }
885
- })()`});if(o.error&&(console.error(` error: ${o.error}`),process.exit(1)),o.mode==="render-worker"){let n=Array.isArray(o.samples)?o.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,q]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)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);o.live&&(console.log(""),console.log(" sampling continues"));break}let r=Array.isArray(o.frames)?o.frames:Array.isArray(o)?o:[];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 @@ ${o}
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 @@ ${o}
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,42 +926,45 @@ ${o}
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(""),Te(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 Ye(c),D(l)?B({cleared:!0}):console.log(" error buffer cleared");break}let t=e?Number(e):20,o=await Ue(c,t);if(D(l)){B(o);break}if(o.length===0){console.log(" no errors captured");break}console.log(` ${o.length} error(s):
976
- `);for(let r of o){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 ze(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 o of t){let r=new Date(o.timestamp).toLocaleTimeString(),n=o.args.map(u=>typeof u=="object"?JSON.stringify(u):u).join(" ");console.log(` [${r}] ${n}`)}break}case"animations":{let e=await z(c,"listAnimations")??[];if(s.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 o=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} ${o} ${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 o=await z(c,"getAnimation",t);console.log(JSON.stringify(o,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 o=await z(c,"stopAnimation",t);console.log(` stopped ${o??0} animation(s)`);break}case"requests":{let e=i[1];if(e==="clear"){await Xe(c),D(l)?B({cleared:!0}):console.log(" request buffer cleared");break}let t=e==="all",o=t?i[2]:e,r=o?Number(o):20,n=await Ge(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}] ${C(u)}`),u.responseBody?console.log(` ${u.responseBody}`):u.error&&console.log(` ${u.error}`)}break}case"network":{let e=i[1],t=null,o=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)&&(o=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)):ro(h);break}let g=o??(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)It(p);break}console.log(` tailing network (ctrl-c to stop)...
992
- `);let q=new Set,H=!0,K=()=>{H=!1};process.on("SIGINT",K);try{for(;H;){let N=await x(),h=F(N);for(let p of h)p.durationMs!=null&&(q.has(p.id)||(q.add(p.id),$?console.log(JSON.stringify(p)):It(p)));await X(250)}}finally{process.off("SIGINT",K)}break}case"logs":{let e=i[1],t=null,o=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)&&(o=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 Qe(c),console.log(" log buffer cleared");break}let g=!u&&process.stdout.isTTY===!0,x=o??(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=()=>Ve(c),q=h=>Ze(h,{level:$,filter:t,showInternal:m});if(!n){let h=await F(),p=q(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)Ft(O,g);break}console.log(` tailing logs (ctrl-c to stop)...
995
- `);let H=new Set,K=!0,N=()=>{K=!1};process.on("SIGINT",N);try{for(;K;){let h=await F(),p=q(h);for(let O of p)H.has(O.id)||(H.add(O.id),u?console.log(JSON.stringify(O)):Ft(O,g));await X(250)}}finally{process.off("SIGINT",N)}break}default:console.error(` unknown subcommand: ${y}`),process.exit(1)}if(P.has(y)&&!s.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&await L(c),!U.has(y)&&!D(l))try{await Z(c)}catch{}}catch(e){let t=e instanceof Error?e.message:String(e);console.error(` ${y??"inspect"} failed: ${t}`);let o=/^no sim connected with id (.+)$/.exec(t);if(o)await it(c,_,o[1]);else if(/^no sim connected$/.test(t))rt(_);else{try{await Ce(c)}catch{}try{await w({includeTail:!0})}catch{}try{await W({includeTail:!0})}catch{}}process.exit(1)}finally{c.close()}}export{zs as runInspect};
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:
968
+ sootsim close --sim <id> # force-close the wedged sim
969
+ sootsim list # confirm it's gone
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};