sootsim 0.1.54 → 0.1.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/dist-cli/bin.js +3 -3
  2. package/dist-cli/chunks/{agent-VZPUCYJ5.js → agent-K3IFO5CV.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-V7ALP2GU.js → agent-wrapper-QLSTAEJA.js} +2 -2
  4. package/dist-cli/chunks/{assert-7P4UILIO.js → assert-5YXZANCD.js} +2 -2
  5. package/dist-cli/chunks/auto-bootstrap-EXYDOLCY.js +2 -0
  6. package/dist-cli/chunks/beta-ER25Q3B4.js +2 -0
  7. package/dist-cli/chunks/chunk-2EGTJLOK.js +2 -0
  8. package/dist-cli/chunks/{chunk-ATMCM62D.js → chunk-4GLNQZFI.js} +2 -2
  9. package/dist-cli/chunks/{chunk-ZT6JZN2V.js → chunk-4OOZDIIQ.js} +2 -2
  10. package/dist-cli/chunks/{chunk-5FQNBWBM.js → chunk-6AEQVSS6.js} +2 -2
  11. package/dist-cli/chunks/{chunk-NZNOUWTN.js → chunk-6KGSLO4W.js} +1 -1
  12. package/dist-cli/chunks/{chunk-EE54B5YB.js → chunk-7CET27Q3.js} +2 -2
  13. package/dist-cli/chunks/{chunk-LHDZ4VZV.js → chunk-AO7LMODD.js} +10 -10
  14. package/dist-cli/chunks/chunk-APAO2IQW.js +1 -0
  15. package/dist-cli/chunks/{chunk-KK5EUVGJ.js → chunk-ATJEMKBT.js} +2 -2
  16. package/dist-cli/chunks/{chunk-ISHA4IUC.js → chunk-BNX3LAMN.js} +2 -2
  17. package/dist-cli/chunks/{chunk-E3P25GBM.js → chunk-BTP3PAIO.js} +2 -2
  18. package/dist-cli/chunks/{chunk-WYBVFDX7.js → chunk-CKNMXP6L.js} +1 -1
  19. package/dist-cli/chunks/{chunk-MAKAGEKD.js → chunk-CT3BVUCO.js} +2 -2
  20. package/dist-cli/chunks/{chunk-VWCU546H.js → chunk-DC7ANPA5.js} +1 -1
  21. package/dist-cli/chunks/{chunk-UYCFIVX6.js → chunk-DFNL55QN.js} +2 -2
  22. package/dist-cli/chunks/{chunk-VHKFU4S2.js → chunk-DVPSMF32.js} +1 -1
  23. package/dist-cli/chunks/{chunk-JBGQ23F4.js → chunk-EVARILGS.js} +1 -1
  24. package/dist-cli/chunks/{chunk-3HYJL6GY.js → chunk-ITS6IHOX.js} +1 -1
  25. package/dist-cli/chunks/{chunk-G33A5TWY.js → chunk-JHZ6QH6V.js} +2 -2
  26. package/dist-cli/chunks/{chunk-5SWIBDHV.js → chunk-LB4RU4OV.js} +1 -1
  27. package/dist-cli/chunks/{chunk-Y7ITI3X2.js → chunk-LBFWPKYG.js} +1 -1
  28. package/dist-cli/chunks/{chunk-QVCVU4DC.js → chunk-LOUL5QVO.js} +1 -1
  29. package/dist-cli/chunks/{chunk-XSZCYAXF.js → chunk-LXDHH3TW.js} +2 -2
  30. package/dist-cli/chunks/chunk-MTLPC2NY.js +2 -0
  31. package/dist-cli/chunks/{chunk-Z5YTYQHU.js → chunk-N5EKXLXC.js} +2 -2
  32. package/dist-cli/chunks/{chunk-IGM4OHW6.js → chunk-NCAKZ2QL.js} +2 -2
  33. package/dist-cli/chunks/{chunk-TJMYDDAG.js → chunk-OP4ALEJL.js} +1 -1
  34. package/dist-cli/chunks/{chunk-7FOK7RXF.js → chunk-PKYDQIBB.js} +3 -3
  35. package/dist-cli/chunks/{chunk-LZ7CVJAO.js → chunk-Q3LSFKVP.js} +2 -2
  36. package/dist-cli/chunks/{chunk-ACSKJEJV.js → chunk-Q5MLOHVB.js} +2 -2
  37. package/dist-cli/chunks/{chunk-NXR73Q5J.js → chunk-RN2SMUS4.js} +2 -2
  38. package/dist-cli/chunks/{chunk-MNGXYS2K.js → chunk-SDUNLEAF.js} +2 -2
  39. package/dist-cli/chunks/{chunk-TSXBCV5T.js → chunk-SPJQ6B6W.js} +2 -2
  40. package/dist-cli/chunks/chunk-T6NGCA35.js +1 -0
  41. package/dist-cli/chunks/{chunk-A2BA2KJN.js → chunk-UF27WZ7Q.js} +3 -3
  42. package/dist-cli/chunks/chunk-UNLFZUUU.js +1 -0
  43. package/dist-cli/chunks/{chunk-XFI4SBWQ.js → chunk-VPYEMRIC.js} +2 -2
  44. package/dist-cli/chunks/{chunk-DNTCQJWP.js → chunk-VZH3VTOY.js} +3 -3
  45. package/dist-cli/chunks/{chunk-DLINRAGW.js → chunk-W3M6NG6B.js} +1 -1
  46. package/dist-cli/chunks/{chunk-ZBR6H6LW.js → chunk-WZDVJFJX.js} +1 -1
  47. package/dist-cli/chunks/{chunk-M3KFUEUN.js → chunk-X46ROUJY.js} +1 -1
  48. package/dist-cli/chunks/chunk-X4VUDSXT.js +3 -0
  49. package/dist-cli/chunks/{chunk-EDU6E62D.js → chunk-YDKX4GPS.js} +2 -2
  50. package/dist-cli/chunks/{chunk-4PVSZ6GE.js → chunk-ZNXPOJDD.js} +1 -1
  51. package/dist-cli/chunks/cli-version-FQQ7DWZU.js +2 -0
  52. package/dist-cli/chunks/{compat-XQTJJGFN.js → compat-7EFQ4K63.js} +3 -3
  53. package/dist-cli/chunks/{config-SREAYZNH.js → config-BXQ5RYP3.js} +2 -2
  54. package/dist-cli/chunks/control-J7H2HTKN.js +2 -0
  55. package/dist-cli/chunks/{cpu-profile-CUXZKZ4Z.js → cpu-profile-P2HBDYZ3.js} +2 -2
  56. package/dist-cli/chunks/{daemon-MCR7OR22.js → daemon-EMP5NFIK.js} +2 -2
  57. package/dist-cli/chunks/{debug-XZBCUV3A.js → debug-VG2EYIRM.js} +3 -3
  58. package/dist-cli/chunks/demo-app-registry-X3JPEPV6.js +2 -0
  59. package/dist-cli/chunks/{detox-X3G5ASPP.js → detox-6N2GHBJD.js} +2 -2
  60. package/dist-cli/chunks/{device-BV3VJE3V.js → device-L4MPWY7S.js} +2 -2
  61. package/dist-cli/chunks/{diagnose-F52LKBS6.js → diagnose-M7L2CKMA.js} +2 -2
  62. package/dist-cli/chunks/drivers-LCWLVDG3.js +2 -0
  63. package/dist-cli/chunks/{electron-VFZMSSGO.js → electron-TYPTY4Y7.js} +3 -3
  64. package/dist-cli/chunks/flow-IUMVR5GK.js +2 -0
  65. package/dist-cli/chunks/{hints-VANECRXI.js → hints-CLDM5YBJ.js} +2 -2
  66. package/dist-cli/chunks/{home-paths-J6PSRIMF.js → home-paths-CIRYHGNC.js} +2 -2
  67. package/dist-cli/chunks/{inspect-SNFMIN2L.js → inspect-IPLQLR2B.js} +94 -94
  68. package/dist-cli/chunks/install-3IBRZDCU.js +2 -0
  69. package/dist-cli/chunks/{install-desktop-X53RE7IV.js → install-desktop-DMIJXVAQ.js} +3 -3
  70. package/dist-cli/chunks/{keys-TS7M56JL.js → keys-6NSIIG5W.js} +2 -2
  71. package/dist-cli/chunks/{launch-OW5YEDFK.js → launch-WZPZT7QA.js} +3 -3
  72. package/dist-cli/chunks/{login-4TXQM3BF.js → login-DVAESD5E.js} +4 -4
  73. package/dist-cli/chunks/{logout-3C3FPCG7.js → logout-ZPNORUPW.js} +2 -2
  74. package/dist-cli/chunks/{maestro-N74HJGTI.js → maestro-TCIBCLOE.js} +2 -2
  75. package/dist-cli/chunks/{preview-FXVS46B5.js → preview-QXRUBXPI.js} +2 -2
  76. package/dist-cli/chunks/{profile-TPFRKRKJ.js → profile-YQMD5RSB.js} +2 -2
  77. package/dist-cli/chunks/{react-6Q34SQFO.js → react-TU4SHD4N.js} +2 -2
  78. package/dist-cli/chunks/{record-7F6XI6Z3.js → record-VWCIULWT.js} +2 -2
  79. package/dist-cli/chunks/runtime-AFEO53IB.js +2 -0
  80. package/dist-cli/chunks/{runtime-delivery-7TRQ44Z6.js → runtime-delivery-U65W6ABO.js} +2 -2
  81. package/dist-cli/chunks/{screenshot-M2F3KS6M.js → screenshot-2NP6RB6K.js} +2 -2
  82. package/dist-cli/chunks/{screenshot-mode-HZAPMY7V.js → screenshot-mode-HTTJRZXJ.js} +2 -2
  83. package/dist-cli/chunks/{screenshots-PKBYEBBM.js → screenshots-YOGPCEDA.js} +2 -2
  84. package/dist-cli/chunks/{server-OU3NTCYI.js → server-ZTCVFCWZ.js} +2 -2
  85. package/dist-cli/chunks/setup-repo-ITPK57UJ.js +2 -0
  86. package/dist-cli/chunks/{skills-L5EPL5WL.js → skills-EC7Q2ISG.js} +2 -2
  87. package/dist-cli/chunks/{start-XLPRV6L7.js → start-MODFVXM3.js} +4 -4
  88. package/dist-cli/chunks/store-2EL3VFR5.js +2 -0
  89. package/dist-cli/chunks/telemetry-3CH4GAWO.js +2 -0
  90. package/dist-cli/chunks/{test-W5YAIGGY.js → test-QASBXD56.js} +3 -3
  91. package/dist-cli/chunks/{three-mode-NXKHTAYK.js → three-mode-ANW4NQAP.js} +2 -2
  92. package/dist-cli/chunks/{timeline-5UL2A7L2.js → timeline-NQUBPM67.js} +2 -2
  93. package/dist-cli/chunks/{upgrade-K4WXKMQI.js → upgrade-A3TXVNAC.js} +2 -2
  94. package/dist-cli/chunks/upload-URNEXJIS.js +2 -0
  95. package/dist-cli/chunks/{web-SLKO5KZU.js → web-DH4EW3I6.js} +2 -2
  96. package/dist-cli/chunks/{what-happened-NYYYNWGO.js → what-happened-AWHOPBQ3.js} +2 -2
  97. package/dist-cli/chunks/{whoami-OUJMAWR7.js → whoami-ZZYOBY77.js} +2 -2
  98. package/dist-lib/agent-daemon-client.cjs +1 -1
  99. package/dist-lib/agent-events.cjs +1 -1
  100. package/dist-lib/agent-sessions.cjs +1 -1
  101. package/dist-lib/attached-projects.cjs +1 -1
  102. package/dist-lib/auth/shared-session.cjs +1 -1
  103. package/dist-lib/backend-origin.cjs +1 -1
  104. package/dist-lib/bridge-constants.cjs +1 -1
  105. package/dist-lib/cli-constants.cjs +1 -1
  106. package/dist-lib/config.cjs +1 -1
  107. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  108. package/dist-lib/home-paths.cjs +1 -1
  109. package/dist-lib/host/bridge-host.cjs +1 -1
  110. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  111. package/dist-lib/index.cjs +1 -1
  112. package/dist-lib/metro.cjs +1 -1
  113. package/dist-lib/profiles.cjs +1 -1
  114. package/dist-lib/render-mode.cjs +1 -1
  115. package/dist-lib/vite-base.cjs +1 -1
  116. package/dist-lib/vite.cjs +1 -1
  117. package/package.json +1 -1
  118. package/dist-cli/chunks/auto-bootstrap-45LPPN26.js +0 -2
  119. package/dist-cli/chunks/beta-YJTC67JV.js +0 -2
  120. package/dist-cli/chunks/chunk-76WUDRCG.js +0 -2
  121. package/dist-cli/chunks/chunk-ARLGT7VR.js +0 -1
  122. package/dist-cli/chunks/chunk-BS3ITOUF.js +0 -1
  123. package/dist-cli/chunks/chunk-CKZ4LXSQ.js +0 -1
  124. package/dist-cli/chunks/chunk-ISQUXL6J.js +0 -3
  125. package/dist-cli/chunks/chunk-J6CCM5BR.js +0 -2
  126. package/dist-cli/chunks/cli-version-TG76CSHZ.js +0 -2
  127. package/dist-cli/chunks/control-LZR3EEK6.js +0 -2
  128. package/dist-cli/chunks/demo-app-registry-TTMQ5X4I.js +0 -2
  129. package/dist-cli/chunks/drivers-A75SQEWU.js +0 -2
  130. package/dist-cli/chunks/flow-5LTGWXWP.js +0 -2
  131. package/dist-cli/chunks/install-NEFJEKEX.js +0 -2
  132. package/dist-cli/chunks/runtime-UHC43LJI.js +0 -2
  133. package/dist-cli/chunks/setup-repo-4WQXPADN.js +0 -2
  134. package/dist-cli/chunks/store-TUCLRZNK.js +0 -2
  135. package/dist-cli/chunks/telemetry-PHCMEH7N.js +0 -2
  136. package/dist-cli/chunks/upload-LVC4KCUG.js +0 -2
@@ -1,12 +1,12 @@
1
- /*! sootsim v0.1.54 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as G}from"./chunk-ACSKJEJV.js";import{a as je,b as Je}from"./chunk-3HYJL6GY.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-ISQUXL6J.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-LHDZ4VZV.js";import{a as De,g as ce}from"./chunk-E3P25GBM.js";import{b as lt,c as ct,i as dt}from"./chunk-XSZCYAXF.js";import"./chunk-QVCVU4DC.js";import{a as Be}from"./chunk-JBGQ23F4.js";import"./chunk-UYCFIVX6.js";import"./chunk-5SWIBDHV.js";import"./chunk-ARLGT7VR.js";import"./chunk-LZ7CVJAO.js";import"./chunk-Y7ITI3X2.js";import{a as be,c as we,d as Ae}from"./chunk-WYBVFDX7.js";import{a as Fe}from"./chunk-76WUDRCG.js";import{c as Oe,e as Re,f as Ee,g as Ce,h as $e}from"./chunk-TSXBCV5T.js";import{b as Pe}from"./chunk-4PVSZ6GE.js";import"./chunk-J6CCM5BR.js";import"./chunk-ZBR6H6LW.js";import"./chunk-TJMYDDAG.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
- `).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(`
1
+ /*! sootsim v0.1.55 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as G}from"./chunk-Q5MLOHVB.js";import{a as Je,b as Le}from"./chunk-ITS6IHOX.js";import{a as X,b as D,c as B,d as z,e as de,f as re,g as at,h as lt,i as ke}from"./chunk-X4VUDSXT.js";import{B as se,C as rt,I as it,a as We,b as qe,c as He,d as Ue,e as Ke,f as ze,g as Se,h as ve,m as Ye,n as Ge,o as Xe,p as Ve,q as Qe,r as Ze,s as et,t as tt,u as ot,v as st,z as nt}from"./chunk-AO7LMODD.js";import{a as Be,g as ce}from"./chunk-BTP3PAIO.js";import{b as ct,c as dt,i as ut}from"./chunk-LXDHH3TW.js";import"./chunk-LOUL5QVO.js";import{a as je}from"./chunk-EVARILGS.js";import"./chunk-DFNL55QN.js";import"./chunk-LB4RU4OV.js";import"./chunk-UNLFZUUU.js";import"./chunk-Q3LSFKVP.js";import"./chunk-LBFWPKYG.js";import{a as we,c as $e,d as Pe}from"./chunk-CKNMXP6L.js";import{a as Ae}from"./chunk-MTLPC2NY.js";import{c as Re,e as Ee,f as Ce,g as De,h as xe}from"./chunk-SPJQ6B6W.js";import{b as Oe}from"./chunk-ZNXPOJDD.js";import"./chunk-2EGTJLOK.js";import"./chunk-WZDVJFJX.js";import"./chunk-OP4ALEJL.js";import{existsSync as Ht,mkdirSync as Ut,readFileSync as Kt,rmSync as mt,writeFileSync as zt}from"fs";import{tmpdir as Yt}from"os";import{dirname as Gt,join as Xt,resolve as Vt}from"path";var ie=1,Qt="SOOTSIM_INSPECT_NOTICE_PATH",Zt=300*1e3,eo=15e3;function pt(){return Vt(process.env[Qt]||Xt(Yt(),"sootsim-inspect-notice-state.json"))}function to(o,d){return Object.fromEntries(Object.entries(o).filter(([,i])=>typeof i?.signature=="string"&&Number.isFinite(i?.updatedAt)&&d-i.updatedAt<=Zt))}function oo(o){let d=pt();if(!Ht(d))return{version:ie,entries:{}};try{let i=JSON.parse(Kt(d,"utf8"));return i.version!==ie||!i.entries||typeof i.entries!="object"?(mt(d,{force:!0}),{version:ie,entries:{}}):{version:ie,entries:to(i.entries,o)}}catch{return mt(d,{force:!0}),{version:ie,entries:{}}}}function so(o){let d=pt();Ut(Gt(d),{recursive:!0}),zt(d,JSON.stringify(o,null,2)+`
3
+ `)}function no(o,d){let i=d.trim()||"default";return`${o}:${i}`}function Te(o,d,i,l={}){let f=l.nowMs??Date.now(),a=l.cooldownMs??eo,y=oo(f),S=no(o,d),N=y.entries[S];return N&&N.signature===i&&f-N.updatedAt<a?!1:(y.entries[S]={signature:i,updatedAt:f},so(y),!0)}async function ft(o,d={args:[]}){let i=await We(o);if(D(d.args)){B(i);return}console.log(` nodes: ${i.nodes}`)}function Me(o,d){let i=o.indexOf(d);return i>=0&&i+1<o.length?o[i+1]:null}async function gt(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"),N=1e3,k=i.includes("--compact"),b=i.includes("--no-xy"),v=Me(i,"--testid-like"),_=Me(i,"--only"),T=Me(i,"--subtree"),E=l[1],L=E?/[*?]/.test(E):!1,c=!L&&!_?E:void 0,K=_??(L?E:void 0),j=async()=>{await de(d,{verbose:y});let Y=await Ue(d,{describe:!0,verbose:f,filter:c||"",testIdLike:v||void 0,onlyGlob:K||void 0,subtreeRoot:T||void 0,compact:k,hideXy:b}),W=Y?.tree,w=Y?.shell,I=Y?.keyboard;if(a){B({shell:w,tree:W??"",keyboard:I});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"),!(c||v||K||T)&&P<10&&G("app-still-loading",P);return}if(console.log(W),!(c||v||K||T)&&!S&&W.split(`
4
+ `).length>=80&&G("describe-use-filters"),I&&I.visible){let P=I.spec,V=[P?.keyboardType?`type=${P.keyboardType}`:null,P?.returnKeyType&&P.returnKeyType!=="default"?`return=${P.returnKeyType}`:null,I.mode!=="letters"?`mode=${I.mode}`:null,I.shifted?"shift":null,I.capsLock?"caps":null,P?.autoCapitalize&&P.autoCapitalize!=="sentences"?`autoCap=${P.autoCapitalize}`:null,I.accessoryBarId?`accessory=${I.accessoryBarId}`:null].filter(Boolean);console.log(`
5
5
  keyboard: ${V.join(" ")||"visible"}`)}};if(S)for(console.log(` watching... (Ctrl+C to stop)
6
- `);;)console.clear(),await E(),await X(I);else await E()}var 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(`
6
+ `);;)console.clear(),await j(),await X(N);else await j()}var ro=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function yt(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let o of ro){let d=process.env[o];if(d&&d.trim()&&d!=="0")return!0}return!1}async function ht(o){let{bridge:d,args:i,effectiveArgs:l,positional:f,inspectUsage:a}=o,y=w=>{let I=l.indexOf(w);return I>=0&&I+1<l.length?l[I+1]:null},S=w=>l.includes(w),N=y("--testid")||y("--test-id"),k=y("--role"),b=y("--type"),v=y("--text"),_=S("--pressable"),T=S("--visible"),E=S("--interactive-targets")||S("--actions"),L=!N&&!k&&!b&&!v&&!_&&!T&&!E?f[1]:null,c=v??L,K=await ze(d,{testId:N,role:k,type:b,text:c,pressable:_,visible:T,interactive:E});K||(console.error(a("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:j,result:C}=K,Y=D(i),W=i.includes("--verbose")||i.includes("--dump");if(Y)j==="interactive-targets"&&Array.isArray(C)?B(Se(C).map(w=>({...w,tap:ve(w)}))):B(C??null);else if(Array.isArray(C))if(C.length===0){console.log(` no ${j} 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(j==="interactive-targets"){let w=Se(C);console.log(` found ${w.length} interactive target${w.length===1?"":"s"} (sorted by score):`);for(let I of w.slice(0,20)){let Z=I.absolutePosition?`@(${Math.round(I.absolutePosition.x)},${Math.round(I.absolutePosition.y)})`:"",P=I.layout?`${Math.round(I.layout.width)}x${Math.round(I.layout.height)}`:"?x?",V=I.text?` "${I.text.slice(0,30)}"`:"",oe=I.testID?` #${I.testID}`:"",ee=I.accessibilityLabel?` \u24D8"${String(I.accessibilityLabel).slice(0,24)}"`:"",ye=I.accessibilityRole?`[${I.accessibilityRole}]`:I.type,he=ve(I);console.log(` ${ye}${V}${ee}${oe} ${P} ${Z}`),console.log(` \u2192 ${he}`),W&&console.log(Ie(JSON.stringify(I,null,2)," "))}w.length>20&&console.log(` ... and ${w.length-20} more`)}else{console.log(` found ${C.length} node${C.length===1?"":"s"} (${j}):`);for(let w of C.slice(0,20)){let I=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}`:"",oe=w.pressable?" (tap)":"",ee=w.accessibilityRole?`[${w.accessibilityRole}]`:w.type;console.log(` ${ee}${P}${V} ${Z} ${I}${oe}`),W&&console.log(Ie(JSON.stringify(w,null,2)," "))}C.length>20&&console.log(` ... and ${C.length-20} more`)}else if(C==null)console.log(` not found: ${c||N||k||b||""||j}`),N&&G("wait-selector-for-missing-testid",N);else{let w=C;if(w.type&&w.absolutePosition){let I=`@(${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}`:"",oe=w.pressable?" (tap)":"",ee=w.accessibilityRole?`[${w.accessibilityRole}]`:w.type;console.log(` ${ee}${P}${V} ${Z} ${I}${oe}`),W&&console.log(Ie(JSON.stringify(w,null,2)," "))}else console.log(JSON.stringify(C,null,2))}}function Ie(o,d){return o.split(`
7
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 () => {
8
+ `)}async function bt(o,d={}){let i=await nt(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:N}=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)":""}`),N&&k.push(` accessoryBar: ${N}`),console.log(k.join(`
9
+ `))}async function wt(o){let d=await o.bridge.listSims();if(D(o.args)){B(d.map(i=>({...i,active:i.id===o.simId})));return}ut(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 $t(o,d={args:[]}){let i=await it(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,7 +24,7 @@ import{a as G}from"./chunk-ACSKJEJV.js";import{a as je,b as Je}from"./chunk-3HYJ
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 $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(`
27
+ })()`})??null}async function xt(o,d={}){let{nav:i,keyboard:l,shell:f}=await rt(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)":"",N=typeof f.launchProgress=="number"&&f.launchProgress<.98?` launching (${Math.round(f.launchProgress*100)}%)`:"";a.push(`shell: ${y}${S}${N}`)}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 N=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(` ${N} #${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
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))}
@@ -74,12 +74,12 @@ import{a as G}from"./chunk-ACSKJEJV.js";import{a as je,b as Je}from"./chunk-3HYJ
74
74
  await sleep(pollMs)
75
75
  }
76
76
  return { settled: false, elapsed: Date.now() - start }
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 () => {
77
+ })()`}),{elapsed:y,settled:S}=a??{};return{elapsed:typeof y=="number"?y:d,settled:S===!0}}async function St(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 vt(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 kt(o){let{bridge:d,args:i,positional:l}=o,f=l[1]?Number(l[1]):5,{tree:a}=await qe(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 Tt(o,d={args:[]}){let i=await He(o);if(D(d.args)){B(i);return}console.log(i.url)}async function Mt(o){let{wsPort:d,commandTimeoutMs:i,simId:l,simIdSource:f,positional:a}=o,y=a[1]?Number(a[1]):30,S=Math.max(1e3,(Number.isFinite(y)?y:30)*1e3),N=Math.max(1,Math.ceil(S/500));console.log(" waiting for sim reconnect...");let k=await at(d,i,l,{attempts:N,simIdSource:f});k||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),k.bridge.close(),ce({source:"inspect wait",step:{wait:S},summary:`wait ${Math.round(S/1e3)}s`}),console.log(` ready: ${k.count} nodes`)}var It=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function pe(o,d){let i=o.indexOf(d);if(i>=0&&i+1<o.length)return o[i+1]}function io(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)),It.has(a)||console.error(` warning: '${a}' is not a known timeline kind \u2014 waiting anyway. known: ${[...It].sort().join(", ")}`);let y=pe(i,"--max-ms"),S=y&&Number.isFinite(Number(y))?Math.max(100,Number(y)):5e3,N=pe(i,"--filter"),k=pe(i,"--equals"),b=pe(i,"--since")??"now",v=i.includes("--json"),_=Date.now(),T=_+S,E=200,L=_;for(;Date.now()<T;){let K={kinds:[a],since:b==="cursor"?void 0:L,limit:50},j=await d.send({type:"evaluate",code:`(async () => {
78
78
  const t = window.SootSim?.bridges?.timeline
79
79
  if (!t) return { ok: false, error: 'timeline bridge missing' }
80
80
  return { ok: true, result: await t.recent(${JSON.stringify(K)}) }
81
- })()`});(!E||!E.ok)&&(console.error(` could not query timeline: ${E&&"error"in E?E.error:"unknown"}`),process.exit(1));let 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 () => {
81
+ })()`});(!j||!j.ok)&&(console.error(` could not query timeline: ${j&&"error"in j?j.error:"unknown"}`),process.exit(1));let C=j.result.events??[];for(let Y of C)if(io(Y,{filter:N,equals:k})){let W=Date.now()-_;console.log(v?JSON.stringify({found:!0,elapsedMs:W,event:Y}):` ${a} event after ${W}ms${N?` (filter: ${N})`:""}${k?` (equals: ${k})`:""}`);return}j.result.watermark&&j.result.watermark>L&&(L=j.result.watermark),await new Promise(Y=>setTimeout(Y,E))}let c=Date.now()-_;v?console.log(JSON.stringify({found:!1,elapsedMs:c,kind:a,filter:N,equals:k})):console.error(` \u26A0 wait event ${a} timed out after ${c}ms${N?` (filter: ${N})`:""}${k?` (equals: ${k})`:""}`),process.exit(1)}async function _t(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 Ft(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 Ye(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 At(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:N,node:k,elapsed:b}=await Ge(d,a,S);if(N&&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 Dt(o){return o==null?"\u2014":o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}K`:`${(o/1024/1024).toFixed(1)}M`}function Bt(o){return o==null?" \u2026":o<1e3?`${o}ms`.padStart(5):`${(o/1e3).toFixed(2)}s`.padStart(5)}function lo(o){return o.error?"err":o.status==null?" \u2026 ":String(o.status)}function Pt(o){let d=new Date(o.startTs).toLocaleTimeString(),i=lo(o).padEnd(3),l=o.method.padEnd(5),f=Dt(o.size).padStart(6),a=Bt(o.durationMs);console.log(` [${d}] ${i} ${l} ${f} ${a} ${o.displayUrl}`),o.error&&console.log(` error: ${o.error}`)}function co(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",Bt(o.durationMs).trim()],["size",Dt(o.size)],["content-type",o.type??"\u2014"]];for(let[i,l]of d)console.log(` ${i.padEnd(13)} ${l}`)}var uo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Ot="\x1B[0m",mo="\x1B[2m";function Rt(o,d){let i=new Date(o.ts).toLocaleTimeString(),l=o.level.toUpperCase().padEnd(5),f=o.args.join(" ");if(d){let a=uo[o.level];console.log(` ${mo}[${i}]${Ot} ${a}${l}${Ot} ${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",po=120;async function Et(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:E,w:L,h:c}=_;return{x:T,y:E,w:L,h:c}}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,E,L,c]=_;return{x:T,y:E,w:L,h:c}}let a=_=>{let T=o.find((L,c)=>o[c-1]===_);if(T==null)return null;let E=Number(T);return Number.isFinite(E)?E:null},y=a("--x"),S=a("--y"),N=a("--w"),k=a("--h");if(y!=null||S!=null||N!=null||k!=null)return{x:y??0,y:S??0,w:N??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,E=1,L=1]=v;return{x:_,y:T,w:E,h:L}}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 Fe(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,7 +111,7 @@ import{a as G}from"./chunk-ACSKJEJV.js";import{a as je,b as Je}from"./chunk-3HYJ
111
111
  frame: runtimeSnapshot?.keyboard?.frame ?? null,
112
112
  focusedRect: runtimeSnapshot?.focused?.rect ?? null,
113
113
  }
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 () => {
114
+ })()`})}async function fo(o,d=600){let i=Date.now()+d;for(;Date.now()<=i;){let l=await Fe(o);if(l.visible)return l;await X(30)}return Fe(o)}async function ge(o,d){let i=await Fe(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 Ct(o,d,i){return d==="appearance"?o.send({type:"evaluate",code:`(async () => {
115
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'
@@ -128,28 +128,28 @@ import{a as G}from"./chunk-ACSKJEJV.js";import{a as je,b as Je}from"./chunk-3HYJ
128
128
  })()`}):o.send({type:"evaluate",code:`(async () => {
129
129
  window.dispatchEvent(new CustomEvent(${JSON.stringify(d==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
130
130
  return { ok: true, action: ${JSON.stringify(d)} }
131
- })()`})}function 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(`
131
+ })()`})}function go(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 yo(o){if(typeof o!="string")return null;let d=o.replace(/\s+/g," ").trim();return d?d.slice(0,80):null}function jt(...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 ho(o,d,i){if(!i||i.hit===!1)return null;let l=jt(i.responderTestID,i.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let f=yo(i.text);return f?{step:{tapOn:f},summary:`tap "${f}"`}:{step:{tapAtCoords:{x:o,y:d}},summary:`tap @${Math.round(o)},${Math.round(d)}`}}function _e(o,d,i){let l=jt(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 Vs(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=Re(l,{port:d.port,commandTimeoutMs:d.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--slow","--tail","-f","--interactive-targets","--actions","--internal"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--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",N=typeof l[0]=="string"&&Pe.has(l[0]),k=N?l[0]:null,b=t=>N&&t===l[0]?`sootsim ${t}`:`sootsim ${S} ${t}`,v=(t,e)=>` usage: ${b(t)}${e?` ${e}`:""}`;if(!y||o.includes("--help")||o.includes("-h")){let t={bridgePort:7668,defaultShellUrl:Ae};if(S==="do"||S==="get"||S==="debug"||S==="wait"){let n=we(S,t);n&&(console.log(`${n}
132
+ `),process.exit(0))}if(k==="shell"){let n=$e("shell",t);n&&(console.log(`${n}
133
+ `),process.exit(0))}let e=$e("inspect",t),s=["do","get","debug","wait"].map(n=>we(n,t)).filter(n=>n!=null).join(`
134
134
 
135
- `);console.log(`${t??""}
135
+ `);console.log(`${e??""}
136
136
 
137
137
  ${s}
138
- `),process.exit(0)}let _=f.wsPort,T=f.simId,C=f.commandTimeoutMs;if(y==="list"&&l.some(e=>e==="--drivers"||e==="-D")){let{buildDriverListRows:e}=await import("./drivers-A75SQEWU.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:`(() => ({
138
+ `),process.exit(0)}let _=f.wsPort,T=f.simId,E=f.simIdSource,L=f.commandTimeoutMs;if(y==="list"&&l.some(t=>t==="--drivers"||t==="-D")){let{buildDriverListRows:t}=await import("./drivers-LCWLVDG3.js"),e=t();console.log(` available drivers (${e.length}):
139
+ `);let s=Math.max(...e.map(r=>r.id.length),6),n=Math.max(...e.map(r=>r.kind.length),4);for(let r of e){let u=r.available?"\u2713":"\u2717",m=r.id.padEnd(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=Ee(f),K=T||"default",j=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),C=200;function Y(t){let e=t.replace(/\s+/g," ").trim();if(!e)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(e)){let n=/<title[^>]*>([^<]+)<\/title>/i.exec(t)?.[1]?.trim(),r=/<body[^>]*>([\s\S]*?)<\//i.exec(t)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=n||r||"html error page";return`<html ${t.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return e.length<=C?e:`${e.slice(0,C)}\u2026 (+${e.length-C} more bytes)`}function W(t){let e=t.displayUrl||t.url;return t.status!=null?`${t.method} ${e} -> ${t.status}${t.statusText?` ${t.statusText}`:""}`:t.error?`${t.method} ${e} -> ${t.error}`:`${t.method} ${e}`}async function w(t){let e=yt()?1200:350;try{let{settled:s,elapsed:n}=await ne({bridge:t,maxMs:e,pollMs:32,stablePolls:2});s||process.stderr.write(` \u26A0 auto-wait timed out after ${n??e}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
140
+ `)}catch{}}async function I(){try{return await c.send({type:"evaluate",code:`(() => ({
141
141
  console: window.__sootsimConsole?.count?.() || null,
142
142
  requests: window.__sootsimTest?.getRequestCounts?.() || null,
143
- }))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function M(e={}){let t=e.counts!==void 0?e.counts:await Y(c,"getRequestCounts");if(!t||typeof t!="object")return;let s=Math.max(0,Number(t.failed)||0);if(s===0||!e.includeTail&&!ke("requests",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(`
143
+ }))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function Z(t={}){let e=t.counts!==void 0?t.counts:await z(c,"getRequestCounts");if(!e||typeof e!="object")return;let s=Math.max(0,Number(e.failed)||0);if(s===0||!t.includeTail&&!Te("requests",K,String(s))||(console.log(`
144
+ network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${b("requests")} 5`),!t.includeTail))return;let n=await z(c,"getFailedRequests",5);if(!(!Array.isArray(n)||n.length===0)){console.log(`
145
145
  recent failed requests:
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(`
146
+ `);for(let r of n){let u=new Date(r.timestamp).toLocaleTimeString();console.log(` [${u}] ${W(r)}`),r.responseBody?console.log(` ${Y(r.responseBody)}`):r.error&&console.log(` ${r.error}`)}}}async function P(t={}){let e=t.counts!==void 0?t.counts:await c.send({type:"evaluate",code:"window.__sootsimConsole?.count?.() || { errors: 0, warnings: 0, total: 0 }"});if(!e||typeof e!="object")return;let s=e,n=Math.max(0,Number(s.errors)||0),r=Math.max(0,Number(s.warnings)||0);if(n===0&&r===0||!t.includeTail&&!Te("console",K,`${n}:${r}`))return;let u=[];if(n>0&&u.push(`${n} console error${n===1?"":"s"}`),r>0&&u.push(`${r} console warning${r===1?"":"s"}`),console.log(`
147
+ console: ${u.join(", ")}`),console.log(` inspect: ${b("errors")} 5`),r>0&&console.log(` inspect: ${b("warnings")} 5`),!t.includeTail||n===0)return;let m=await c.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors?.(5) || []"});if(!(!Array.isArray(m)||m.length===0)){console.log(`
148
148
  recent console errors:
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,`(() => {
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 V=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function oe(t){let e=Oe(),s=null;try{s=await De(t,`(() => {
150
150
  const tl = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.timeline
151
151
  if (!tl || typeof tl.summary !== 'function') return null
152
- const cursorKey = ${JSON.stringify(t)}
152
+ const cursorKey = ${JSON.stringify(e)}
153
153
  const summary = tl.summary({ sinceCursor: cursorKey })
154
154
  let consoleSplit = null
155
155
  if (summary && summary.byKind && summary.byKind.console) {
@@ -162,11 +162,11 @@ ${s}
162
162
  }
163
163
  }
164
164
  return summary ? { summary, consoleSplit } : null
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 () => {
165
+ })()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let n=s.summary.byKind??{},r=[],u=new Set;for(let m of V){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 xe(t,"SootSim.bridges.timeline.cursorAdvance",e,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"]),ye=new Set(["a11y","capture","count","double-tap","drag","find","gesture","layout","long-press","node","pinch","sample-color","scroll","screenshot","swipe","tap","tap-id","tap-text","touch","tree","type-into"]),he=(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 Ce(c),ye.has(y)&&await de(c,{verbose:he});try{switch(y){case"list":{await wt({bridge:c,simId:T,args:l});break}case"tree":{await kt({bridge:c,args:l,positional:a});break}case"a11y":{let t=await Ke(c);if(!Array.isArray(t)||t.length===0){console.log(" no accessible nodes found");break}if(o.includes("--json"))console.log(JSON.stringify(t,null,2));else{console.log(` accessibility tree (${t.length} nodes):
167
+ `);for(let e of t){let s=[];if(s.push(`[${e.role}]`),e.label){let n=e.label.length>50?e.label.slice(0,47)+"...":e.label;s.push(`"${n}"`)}if(e.hint&&s.push(`(hint: "${e.hint}")`),e.testID&&s.push(`#${e.testID}`),e.state){let n=[];e.state.disabled&&n.push("disabled"),e.state.selected&&n.push("selected"),e.state.checked===!0&&n.push("checked"),e.state.checked==="mixed"&&n.push("mixed"),e.state.busy&&n.push("busy"),e.state.expanded===!0&&n.push("expanded"),e.state.expanded===!1&&n.push("collapsed"),n.length&&s.push(`{${n.join(", ")}}`)}e.position&&s.push(`@(${e.position.x},${e.position.y})`),e.size&&s.push(`${e.size.w}x${e.size.h}`),console.log(" "+s.join(" "))}}break}case"find":{await ht({bridge:c,args:o,effectiveArgs:l,positional:a,inspectUsage:v});break}case"count":{await ft(c,{args:l});break}case"keyboard":{await bt(c,{json:o.includes("--json")});break}case"screens":{await xt(c,{json:o.includes("--json")});break}case"memory":{await $t(c,{args:l});break}case"wait":{await Mt({wsPort:_,commandTimeoutMs:L,simId:T,simIdSource:E,positional:a});break}case"sleep":{await vt({positional:a,inspectUsage:v});break}case"settle":{await St({bridge:c,args:o,positional:a});break}case"ready":{await Ft({bridge:c,args:o});break}case"idle":{await _t({bridge:c,args:o,positional:a});break}case"selector":{await At({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 t=a[1];t||(console.error(v("layout","<id>")),process.exit(1));let e=await c.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(t)}))()`});console.log(JSON.stringify(e,null,2));break}case"capture":case"screenshot":{let e=o.find((x,g)=>o[g-1]==="--output")||"/tmp/sootsim-inspect.png",s=await Et(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(e,Buffer.from(u,"base64")),console.log(` saved: ${e}`);break}case"sample-color":{let t=await Et(o,c);t||(console.error(v("sample-color","<x> <y> [w] [h] | --id <testID> | --text <text>")),console.error(" samples an averaged color from the canvas. coords are logical sootsim units."),process.exit(1));let e=await c.send({type:"evaluate",code:Le(t)});if(o.includes("--json"))console.log(JSON.stringify(e,null,2));else{let{r:s,g:n,b:r,a:u,hex:m,samples:x}=e,g=t.w===1&&t.h===1?`@(${t.x},${t.y})`:`@(${t.x},${t.y}) ${t.w}x${t.h}`;console.log(` ${m} rgba(${s}, ${n}, ${r}, ${u}) ${g} ${x} samples`)}break}case"node":{let t=a[1];t||(console.error(v("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let e=await c.send({type:"evaluate",code:`(async () => {
168
168
  const t = window.__sootsimTest
169
- const q = ${JSON.stringify(e)}
169
+ const q = ${JSON.stringify(t)}
170
170
  let node = null
171
171
  let via = null
172
172
  if (t.findByTestId) { node = await t.findByTestId(q); if (node) via = 'testID' }
@@ -220,17 +220,17 @@ ${s}
220
220
  transform,
221
221
  parentChain,
222
222
  }
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 () => {
223
+ })()`});console.log(JSON.stringify(e,null,2));break}case"tap":{let t=Number(a[1]),e=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)),t=u.x,e=u.y}(!Number.isFinite(t)||!Number.isFinite(e))&&(console.error(v("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let n=await c.send({type:"tap",x:t,y:e}),r=ho(t,e,n);r&&await J("inspect tap",r.step,r.summary),console.log(JSON.stringify(n,null,2));break}case"drag":case"swipe":{let t=Number(a[1]),e=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(t)||!Number.isFinite(e)||!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 () => {
224
224
  const interact = window.__sootsimInteract
225
225
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
226
- const value = await interact.drag(${e}, ${t}, ${s}, ${n}, ${Math.max(1,Math.round(m))}, ${Math.max(0,Math.round(x))})
226
+ const value = await interact.drag(${t}, ${e}, ${s}, ${n}, ${Math.max(1,Math.round(m))}, ${Math.max(0,Math.round(x))})
227
227
  return { ok: !!value, value }
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 () => {
228
+ })()`});if(g?.ok){let $=Math.max(1,Math.round(Math.max(1,m)*Math.max(0,x)));await J(`inspect ${y}`,{swipe:{start:`${t}, ${e}`,end:`${s}, ${n}`,duration:$}},`${y} ${t},${e} -> ${s},${n}`)}console.log(JSON.stringify(g,null,2));break}case"pinch":{let t=Number(a[1]),e=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(t)||!Number.isFinite(e)||!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 () => {
229
229
  const interact = window.__sootsimInteract
230
230
  if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
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($))})
231
+ const value = await interact.pinch(${t}, ${e}, ${s}, ${n}, ${r}, ${u}, ${m}, ${x}, ${Math.max(1,Math.round(g))}, ${Math.max(0,Math.round($))})
232
232
  return { ok: !!value, value }
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 () => {
233
+ })()`});F?.ok&&await J("inspect pinch",{pinch:{from:[t,e,s,n],to:[r,u,m,x],steps:Math.max(1,Math.round(g)),stepMs:Math.max(0,Math.round($))}},`pinch (${t},${e}) (${s},${n}) -> (${r},${u}) (${m},${x})`),console.log(JSON.stringify(F,null,2));break}case"tap-text":{let t=a[1];t||(console.error(v("tap-text","<text>")),process.exit(1));let e=R=>{let A=o.indexOf(R);return A>=0&&A+1<o.length?o[A+1]:null},s=R=>o.includes(R),n=e("--nth")??e("--index"),r=n!==null?Number(n):null;r!==null&&!Number.isFinite(r)&&(console.error(` --nth/--index requires an integer, got: ${n}`),process.exit(1));let u=e("--within"),m=e("--role"),x=s("--exact"),g=s("--first"),$=e("--min-y"),F=e("--max-y"),q=e("--min-x"),H=e("--max-x");for(let[R,A]of[["--min-y",$],["--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 U=o.indexOf("--near"),M=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)),M={x:R,y:A}}let h=JSON.stringify({query:t,exact:x,role:m,within:u,minX:q!==null?Number(q):null,maxX:H!==null?Number(H):null,minY:$!==null?Number($):null,maxY:F!==null?Number(F):null,near:M,nth:r,first:g}),p=await c.send({type:"evaluate",code:`(async () => {
234
234
  const t = window.__sootsimTest
235
235
  if (!t) return { error: 'bridge-not-ready' }
236
236
  const F = ${h}
@@ -344,13 +344,13 @@ ${s}
344
344
  total,
345
345
  idx,
346
346
  }
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 () => {
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 "${t}"`);for(let A of R){let be=A.abs?`@(${Math.round(A.abs.x)},${Math.round(A.abs.y)})`:"",le=A.layout?` ${A.layout.width}x${A.layout.height}`:"",Jt=A.testID?` #${A.testID}`:"",Lt=A.text?` "${A.text}"`:"",Wt=A.ancestorTestIDs.length>0?` within ${A.ancestorTestIDs.slice(0,3).map(qt=>`#${qt}`).join(" > ")}`:"";console.error(` [${A.idx}] <${A.type}>${Lt}${Jt} ${be}${le}${Wt}`)}p.total>R.length&&console.error(` ... and ${p.total-R.length} more`),console.error(" pick one:"),console.error(" --nth <index> pick the nth match (top-to-bottom, left-to-right; negatives from end)"),console.error(" --within <testID> narrow to descendants of a node"),console.error(" --min-y / --max-y geometric filter (pixels, absolute)"),console.error(" --min-x / --max-x geometric filter (pixels, absolute)"),console.error(" --near <x> <y> pick the closest match to a point"),console.error(" --exact exact text match (default is substring)"),console.error(" --role <role> narrow to accessibilityRole"),console.error(" --first keep the old pick-first-silently behavior"),process.exit(2)}p?.nthOutOfRange&&(console.error(` not found: nth ${p.nth} of ${p.total} match${p.total===1?"":"es"} for "${t}"`),process.exit(1)),(!p||typeof p.cx!="number")&&(console.error(` not found: ${t}`),process.exit(1));let O=await c.send({type:"tap",x:p.cx,y:p.cy});if(O?.hit!==!1&&O?.ok!==!1){let R=_e(t,{id:p.target?.id??null,testID:p.target?.testID??null,type:p.target?.type??null,cx:p.cx,cy:p.cy},"text");await 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 t=a[1];t||(console.error(v("tap-best","<query>")),process.exit(1));let e=JSON.stringify(t),s=await c.send({type:"evaluate",code:`(async () => {
348
348
  const t = window.__sootsimTest
349
349
  if (!t) return { error: 'bridge-not-ready' }
350
350
  // try testID first \u2014 strongest signal of "this is the
351
351
  // intended tap target".
352
352
  const byTestId =
353
- (await t.findByTestId(${t})) || (await t.findById(${t}))
353
+ (await t.findByTestId(${e})) || (await t.findById(${e}))
354
354
  if (byTestId && byTestId.absolutePosition && byTestId.layout) {
355
355
  return {
356
356
  strategy: 'testid',
@@ -369,7 +369,7 @@ ${s}
369
369
  // 0 or 2+ matches \u2014 to disambiguate we'd send the user
370
370
  // back to tap-text with --nth, which is the right
371
371
  // failure mode.
372
- const byText = await t.findByText(${t})
372
+ const byText = await t.findByText(${e})
373
373
  if (byText && byText.absolutePosition && byText.layout) {
374
374
  return {
375
375
  strategy: 'text',
@@ -385,10 +385,10 @@ ${s}
385
385
  }
386
386
  }
387
387
  return { strategy: 'none' }
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 () => {
388
+ })()`});"error"in s&&(console.error(` ${s.error}`),process.exit(1)),s.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${t}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1));let n=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=_e(t,{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 t=a[1];t||(console.error(v("tap-id","<id>")),process.exit(1));let e=JSON.stringify(t),s=await c.send({type:"evaluate",code:`(async () => {
389
389
  const t = window.__sootsimTest
390
390
  if (!t) return null
391
- const n = (await t.findByTestId(${t})) || (await t.findById(${t}))
391
+ const n = (await t.findByTestId(${e})) || (await t.findById(${e}))
392
392
  if (!n || !n.absolutePosition || !n.layout) return { cx: null }
393
393
  const resolved =
394
394
  typeof n.nodeId === 'number' && typeof t.resolveTapTarget === 'function'
@@ -420,7 +420,7 @@ ${s}
420
420
  },
421
421
  strategy: (resolved && resolved.strategy) || 'matched-node',
422
422
  }
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 () => {
423
+ })()`});(!s||typeof s.cx!="number")&&(console.error(` not found: ${t}`),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=_e(t,{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 t=a[1],e=a.slice(2).join(" ");(!t||!e)&&(console.error(v("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(t),n=await c.send({type:"evaluate",code:`(async () => {
424
424
  const t = window.__sootsimTest
425
425
  if (!t) return null
426
426
  const n = await (t.findByTestId(${s}) || t.findById(${s}))
@@ -432,41 +432,41 @@ ${s}
432
432
  isTextInput: !!n.isTextInput,
433
433
  placeholder: n.placeholder || null,
434
434
  }
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 () => {
435
+ })()`});(!n||typeof n.cx!="number")&&(console.error(` not found: ${t}`),process.exit(1)),n.isTextInput||console.error(` warning: ${t} is not a text input (isTextInput: false)`);let r=await c.send({type:"tap",x:n.cx,y:n.cy}),u=await fo(c);u.visible||(console.error(` keyboard did not open after tapping ${t}`),process.exit(1));let m=u.focusedInput;m&&(m.testID===t||m.id===t||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(t)} but focus is on ${JSON.stringify(m.testID??m.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await c.send({type:"keyboard",action:"type",text:e}),await J("inspect type-into",{tapOn:{id:t},inputText:e},`type-into #${t} ${JSON.stringify(e)}`),console.log(JSON.stringify({target:t,isTextInput:n.isTextInput,keyboardOpened:u.visible??r?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:e},null,2));break}case"type":{let t=a.slice(1).join(" ");t||(console.error(v("type","<text>")),process.exit(1)),await ge(c,"type"),await c.send({type:"keyboard",action:"type",text:t}),await J("inspect type",{inputText:t},`type ${JSON.stringify(t)}`),console.log(` typed: ${JSON.stringify(t)}`);break}case"key":{let t=a[1];t||(console.error(v("key","<name>")),process.exit(1)),await ge(c,"key"),await c.send({type:"keyboard",action:"press",text:t}),await J("inspect key",{pressKey:t},`key ${t}`),console.log(` pressed: ${t}`);break}case"key-sequence":{let t=a.slice(1);t.length===0&&(console.error(v("key-sequence","<key> [<key> ...]")),process.exit(1)),await ge(c,"key-sequence");for(let e of t)await c.send({type:"keyboard",action:"press",text:e});await J("inspect key-sequence",{pressKey:t.join(" ")},`key-sequence ${t.join(" ")}`),console.log(` pressed: ${t.join(", ")}`);break}case"keycode":{let t=a.slice(1);t.length===0&&(console.error(v("keycode","<code> [<code> ...]")),process.exit(1));let e=t.map(n=>({code:n,key:go(n)})),s=e.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 e)await c.send({type:"keyboard",action:"press",text:n.key});await J("inspect keycode",{pressKey:e.map(n=>n.key).join(" ")},`keycode ${t.join(" ")}`),console.log(` pressed: ${t.join(", ")}`);break}case"dispatch":{let t=a[1];t||(console.error(v("dispatch","<char>")),process.exit(1)),await c.send({type:"keyboard",action:"dispatchKey",text:t}),await J("inspect dispatch",{dispatchKey:t},`dispatch ${JSON.stringify(t)}`),console.log(` dispatched: ${t}`);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 t=Number(a[1]),e=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)),t=m.x,e=m.y}let n=a[3]?Number(a[3]):80;(!Number.isFinite(t)||!Number.isFinite(e)||!Number.isFinite(n))&&(console.error(v("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let r=Math.max(0,Math.round(n)),u=await c.send({type:"evaluate",code:`(async () => {
436
436
  const interact = window.__sootsimInteract
437
437
  if (interact?.doubleTap) {
438
438
  return {
439
- ok: !!(await interact.doubleTap(${e}, ${t}, ${r})),
439
+ ok: !!(await interact.doubleTap(${t}, ${e}, ${r})),
440
440
  gapMs: ${r},
441
441
  }
442
442
  }
443
443
  if (!interact?.tap) {
444
444
  return { ok: false, reason: 'no interact.tap', gapMs: ${r} }
445
445
  }
446
- const first = await interact.tap(${e}, ${t})
446
+ const first = await interact.tap(${t}, ${e})
447
447
  if (!first || first.hit === false) {
448
448
  return { ok: false, reason: 'first tap missed', gapMs: ${r}, first }
449
449
  }
450
450
  await new Promise((resolve) => setTimeout(resolve, ${r}))
451
- const second = await interact.tap(${e}, ${t})
451
+ const second = await interact.tap(${t}, ${e})
452
452
  return {
453
453
  ok: !!second && second.hit !== false,
454
454
  gapMs: ${r},
455
455
  first,
456
456
  second,
457
457
  }
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 () => {
458
+ })()`});u?.ok&&await J("inspect double-tap",{doubleTapAtCoords:{x:t,y:e,gapMs:r}},`double-tap @${t},${e}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let t=Number(a[1]),e=Number(a[2]),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)),t=u.x,e=u.y}let n=a[3]?Number(a[3]):600;(!Number.isFinite(t)||!Number.isFinite(e)||!Number.isFinite(n))&&(console.error(v("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let r=await c.send({type:"evaluate",code:`(async () => {
459
459
  const interact = window.__sootsimInteract
460
460
  if (!interact?.longPress) return { ok: false, reason: 'no interact.longPress' }
461
- const value = await interact.longPress(${e}, ${t}, ${Math.max(0,Math.round(n))})
461
+ const value = await interact.longPress(${t}, ${e}, ${Math.max(0,Math.round(n))})
462
462
  return { ok: !!value, value }
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 () => {
463
+ })()`});r?.ok&&await J("inspect long-press",{tapAtCoords:{x:t,y:e}},`long-press @${t},${e}`),console.log(JSON.stringify(r,null,2));break}case"touch":{let t=a[1],e=Number(a[2]),s=Number(a[3]),n=a[4]?Number(a[4]):999,r=t==="down"?"touchDown":t==="move"?"touchMove":t==="up"?"touchUp":t==="cancel"?"touchCancel":null;r||(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),t!=="cancel"&&(!Number.isFinite(e)||!Number.isFinite(s))&&(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let u=t==="down"?"tap":t==="move"?"move":null,m=u&&Number.isFinite(e)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${e}, y: ${s} } }));`:"",x=await c.send({type:"evaluate",code:`(async () => {
464
464
  ${m}
465
465
  const interact = window.__sootsimInteract
466
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))})`}
467
+ const value = ${t==="cancel"?`await interact.${r}(${Math.max(1,Math.round(n))})`:`await interact.${r}(${e}, ${s}, ${Math.max(1,Math.round(n))})`}
468
468
  return { ok: !!value, value }
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 () => {
469
+ })()`});x?.ok&&t!=="cancel"&&await J("inspect touch",{tapAtCoords:{x:e,y:s}},`touch ${t} @${e},${s}`),console.log(JSON.stringify(x,null,2));break}case"gesture":{let t=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],e=a[1],s=a[2]?Number(a[2]):220;(!e||!Number.isFinite(s))&&(console.error(v("gesture","<preset> [durationMs]")),console.error(` presets: ${t.join(", ")}`),process.exit(1)),t.includes(e)||(console.error(` unknown gesture preset: ${e}`),console.error(` presets: ${t.join(", ")}`),process.exit(1));let n=await c.send({type:"evaluate",code:`(async () => {
470
470
  const spec = globalThis.__sootsimDeviceSpec || {}
471
471
  return {
472
472
  width: spec.width || window.innerWidth || 393,
@@ -474,25 +474,25 @@ ${s}
474
474
  statusBarHeight: spec.statusBarHeight || 0,
475
475
  homeIndicatorHeight: spec.homeIndicatorHeight || 0,
476
476
  }
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 () => {
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),q=Math.max(24,x+18),H=18,U=Math.min(220,Math.round(u*.24)),M=Math.min(180,Math.round(r*.32)),h=g,p=$,O=g,R=$;switch(e){case"scroll-up":p=$+Math.round(U/2),R=$-Math.round(U/2);break;case"scroll-down":p=$-Math.round(U/2),R=$+Math.round(U/2);break;case"scroll-left":h=g+Math.round(M/2),O=g-Math.round(M/2);break;case"scroll-right":h=g-Math.round(M/2),O=g+Math.round(M/2);break;case"swipe-from-left-edge":h=H,p=$,O=Math.min(r-H,H+M);break;case"swipe-from-right-edge":h=r-H,p=$,O=Math.max(H,r-H-M);break;case"swipe-from-top-edge":h=g,p=F,R=Math.min(u-q,F+U);break;case"swipe-from-bottom-edge":h=g,p=u-q,R=Math.max(F,u-q-U);break}let A=Math.max(8,Math.round(s/16)),be=Math.max(1,Math.round(s/A)),le=await c.send({type:"evaluate",code:`(async () => {
478
478
  const interact = window.__sootsimInteract
479
479
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
480
- const value = await interact.drag(${h}, ${p}, ${O}, ${R}, ${A}, ${he})
480
+ const value = await interact.drag(${h}, ${p}, ${O}, ${R}, ${A}, ${be})
481
481
  return { ok: !!value, value }
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 () => {
482
+ })()`});le?.ok&&await J("inspect gesture",{swipe:{start:`${h}, ${p}`,end:`${O}, ${R}`,duration:Math.max(1,Math.round(s))}},`gesture ${e}`),console.log(JSON.stringify({preset:e,from:{x:h,y:p},to:{x:O,y:R},result:le},null,2));break}case"scroll":{let t=ae(o),e=t?.mode==="testid"?t.value:a[1],s=Number(a[t?1:2]),n=Number(a[t?2:3]);(!e||!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 () => {
483
483
  const t = window.__sootsimTest
484
484
  if (!t) return null
485
- const n = await t.findByTestId(${JSON.stringify(t)})
486
- || await t.findById(${JSON.stringify(t)})
485
+ const n = await t.findByTestId(${JSON.stringify(e)})
486
+ || await t.findById(${JSON.stringify(e)})
487
487
  if (!n || !n.absolutePosition || !n.layout) return null
488
488
  return {
489
489
  cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
490
490
  cy: n.absolutePosition.y + (n.layout.height || 0) / 2,
491
491
  }
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:`({
492
+ })()`}),u=await z(c,"scrollTo",e,s,n,!1);u?.ok&&await J("inspect scroll",{scrollTo:{id:e,x:s,y:n}},`scroll ${e} -> ${s},${n}`),console.log(JSON.stringify({...u,...r?{at:{x:r.cx,y:r.cy}}:{}},null,2));break}case"state":{let t=a[1];if(i==="get"&&!t){let s=await z(c,"getRuntimeState"),n=await c.send({type:"evaluate",code:`({
493
493
  errors: window.__sootsimConsole?.getErrors?.()?.length ?? 0,
494
494
  warnings: window.__sootsimConsole?.getWarnings?.()?.length ?? 0,
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(`
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(!t||t==="--help"||t==="-h"){console.log(`
496
496
  ${b("state")} \u2014 dump raw runtime state
497
497
 
498
498
  subcommands:
@@ -515,13 +515,13 @@ ${s}
515
515
  ${b("state")} scroll feed
516
516
  ${b("state")} scroll-hit 360 420
517
517
  ${b("state")} hit 200 720
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:`(() => {
518
+ `);break}let e;switch(t){case"shell":e=await se(c,500);break;case"worker":e=await xe(c,"__sootsimRenderHost.queryStats");break;case"ownership":e=await c.send({type:"evaluate",code:`(() => {
519
519
  const h = window.__sootsimRenderHost
520
520
  if (!h || typeof h.getOwnershipSnapshot !== 'function') {
521
521
  return { error: 'getOwnershipSnapshot not available' }
522
522
  }
523
523
  return h.getOwnershipSnapshot()
524
- })()`});break;case"keyboard":t=await c.send({type:"evaluate",code:`(async () => {
524
+ })()`});break;case"keyboard":e=await c.send({type:"evaluate",code:`(async () => {
525
525
  const kb = window.__sootsimKeyboard
526
526
  const test = window.__sootsimTest
527
527
  if (!kb) return { error: 'keyboard bridge not available' }
@@ -546,7 +546,7 @@ ${s}
546
546
  text: focused.text || null,
547
547
  } : null,
548
548
  }
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(`
549
+ })()`});break;case"node":{let s=a[2];s||(console.error(` usage: ${b("state")} node <id>`),process.exit(1)),e=await z(c,"findByTestId",s)||await z(c,"findById",s);break}case"scroll":{let s=a[2];s||(console.error(` usage: ${b("state")} scroll <id>`),process.exit(1)),e=await z(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)),e=await z(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)),e=await z(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)),e=await z(c,"debugGestureAt",s,n);break}default:console.error(` unknown state subcommand: ${t}`),process.exit(1)}console.log(JSON.stringify(e,null,2));break}case"shell":{let t=a[1];if(!t||t==="--help"||t==="-h"){console.log(`
550
550
  ${b("shell")} \u2014 run built-in shell commands
551
551
 
552
552
  subcommands:
@@ -570,7 +570,7 @@ ${s}
570
570
  ${b("shell")} open-card clock 800
571
571
  ${b("shell")} appearance dark
572
572
  ${b("shell")} lock
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:`;(() => {
573
+ `);break}let e=t==="launch"||t==="open-card"||t==="home"||t==="switcher",s=t==="launch"||t==="open-card"?a[3]:a[2],n=s?Number(s):350;e&&(!Number.isFinite(n)||n<0)&&(console.error(v("shell",t==="launch"||t==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let r=!1,u=!1,m=null,x=o.includes("--clear-state");if(t==="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:Be}),r=!!await re(c,"launchApp",n,g),{settled:u,state:m}=await fe(c,Math.round(n),$=>!!$&&$.state==="app"&&$.activeApp===g&&$.showSwitcher===!1&&$.switcherPhase==="idle"&&typeof $.launchProgress=="number"&&$.launchProgress>=.98),r&&await J("inspect shell launch",x?{launchApp:{clearState:!0}}:{launchApp:{}},x?"launch app (clear state)":"launch app")}else if(t==="home")r=!!await re(c,"goHome",n),{settled:u,state:m}=await fe(c,Math.round(n),g=>!!g&&g.state==="home"&&g.activeApp==null&&g.showSwitcher===!1&&g.switcherPhase==="idle"&&typeof g.launchProgress=="number"&&g.launchProgress>=.98);else if(t==="switcher")r=!!await re(c,"openSwitcher",n),{settled:u,state:m}=await fe(c,Math.round(n),g=>!!g&&g.state==="app"&&g.showSwitcher===!0&&g.switcherPhase==="idle"&&typeof g.zoomLevel=="number"&&Math.abs(g.zoomLevel)<=.02&&typeof g.horizontalZoom=="number"&&Math.abs(g.horizontalZoom)<=.02),u&&(await X(po),m=await se(c));else if(t==="open-card"){let g=a[2];g||(console.error(v("shell","open-card <appId> [settleMs]")),process.exit(1)),r=!!await re(c,"openSwitcherCard",n,g),{settled:u,state:m}=await fe(c,Math.round(n),$=>!!$&&$.state==="app"&&$.activeApp===g&&$.showSwitcher===!1&&$.switcherPhase==="idle"&&typeof $.zoomLevel=="number"&&$.zoomLevel>=.98&&typeof $.horizontalZoom=="number"&&$.horizontalZoom>=.98),r&&await J("inspect shell open-card",{openSwitcherCard:{appId:g}},`open switcher card ${g}`)}else if(t==="appearance"){let g=a[2];(!g||!["light","dark","auto","toggle"].includes(g))&&(console.error(v("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let $=await Ct(c,"appearance",g);if(r=!!$?.ok,m={appearance:$},r){let F=$?.applied??g;console.log(` appearance: ${F}`)}}else if(t==="lock"||t==="shake"){let g=await Ct(c,t);r=!!g?.ok,m={[t]:g}}else console.error(` unknown shell subcommand: ${t}`),process.exit(1);console.log(JSON.stringify({ok:r,settled:u,state:m},null,2));break}case"url":{await Tt(c,{args:l});break}case"reload":{let s=!1,n=!1;try{await c.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let m=await c.send({type:"evaluate",code:`;(() => {
574
574
  const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
575
575
  if (typeof reloadExternalApp === 'function') {
576
576
  reloadExternalApp()
@@ -578,10 +578,10 @@ ${s}
578
578
  }
579
579
  window.location.reload()
580
580
  return { kind: 'page' }
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(`
581
+ })()`});n=!!m&&m.kind==="external-app",s=!0}catch{}console.log(" reloading...");let r=c,u=null;if(n)u=await ke(c,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await X(300);let m=await lt(_,L,T,{timeoutMs:1e4,simIdSource:E});m?(r=m,u=await ke(m,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),r=null)}if(u)if(u.ready){let m=u.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${u.elapsedMs}ms: ${u.nodes} nodes${m}`)}else u.source==="error-bail"?console.log(` \u26A0 reload bailed after ${u.elapsedMs}ms: ${u.errors} console error(s), ready signal never fired`):console.log(` \u26A0 reload timed out after ${u.elapsedMs}ms (${u.nodes} nodes, ${u.errors} errors)`);if(r)try{let m=await r.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors(10) || []"});if(r!==c&&r.close(),Array.isArray(m)&&m.length>0){console.log(`
582
582
  \u26A0 ${m.length} error(s) during mount:
583
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 () => {
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 t=a.slice(1).join(" ");t||(console.error(v("js","<javascript>")),console.error(""),console.error(" runs the snippet in the engine realm. SootSim is the"),console.error(" canonical state surface \u2014 reach into it directly."),console.error(""),console.error(" examples:"),console.error(` ${b("js")} SootSim.bridges.test.findByText("Sign in")`),console.error(` ${b("js")} SootSim.bridges.debug.snapshot("before")`),console.error(` ${b("js")} SootSim.bridges.keyboard.type("hello")`),console.error(` ${b("js")} SootSim.state.root.children.length`),process.exit(1));let e=t;e.startsWith("(async")||(e=`(async () => ${e})()`);let s=await c.send({type:"evaluate",code:e});console.log(JSON.stringify(s,null,2));let n=t.toLowerCase(),r=[];(n.includes("sootsim:gohome")||n.includes("gohome"))&&r.push("sootsim shell home"),(n.includes("sootsim:appswitcher")||n.includes("appswitcher"))&&r.push("sootsim shell switcher"),(n.includes("keyboard.isvisible")||n.includes("keyboard.getmode"))&&r.push("sootsim debug state keyboard"),n.includes("interact.tap")&&r.push("sootsim do tap <x> <y>"),n.includes("keyboard.type")&&r.push("sootsim do type <text>"),(n.includes("keyboard.press")||n.includes("keyboard.dispatchkey"))&&r.push("sootsim do key <name>"),n.includes("keyboard.dismiss")&&r.push("sootsim do dismiss"),n.includes("dumptree")&&r.push("sootsim get tree"),n.includes("dumpaccessibilitytree")&&r.push("sootsim get a11y"),n.includes("getnodecount")&&r.push("sootsim get count"),n.includes("findbytext")&&r.push("sootsim find <text>"),(n.includes("findbytestid")||n.includes("findbyid"))&&r.push("sootsim find --testid <id>"),n.includes("document.hidden")&&r.push("sootsim debug state keyboard (includes tab health)"),r.length>0&&G("prefer-cli-over-eval",r);break}case"globals":{let t=await c.send({type:"evaluate",code:`(async () => {
585
585
  const globals = {}
586
586
 
587
587
  // test bridge (proxy in worker mode)
@@ -619,7 +619,7 @@ ${s}
619
619
 
620
620
  return globals
621
621
  })()`});console.log(` sootsim JS API:
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(`
622
+ `);for(let[e,s]of Object.entries(t)){console.log(` ${e}:`);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 gt({bridge:c,args:o,positional:a});break}case"perf":{let t=a[1];if(!t||t==="--help"||t==="-h"){console.log(`
623
623
  ${b("perf")} \u2014 performance profiling
624
624
 
625
625
  subcommands:
@@ -635,7 +635,7 @@ ${s}
635
635
  # ... interact with the app ...
636
636
  ${b("perf")} stop
637
637
  ${b("perf")} transition goHome
638
- `);break}switch(e){case"stats":{let t=await c.send({type:"evaluate",code:`(async () => {
638
+ `);break}switch(t){case"stats":{let e=await c.send({type:"evaluate",code:`(async () => {
639
639
  // worker mode (host exposes these)
640
640
  if (window.__sootsimPerfStats) {
641
641
  return await window.__sootsimPerfStats()
@@ -660,7 +660,7 @@ ${s}
660
660
  jankFrames: frameStats.recentFrames?.filter(f => f > 16.67).length || 0,
661
661
  recentCount: frameStats.recentFrames?.length || 0,
662
662
  }
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 () => {
663
+ })()`});e.error&&(console.error(` error: ${e.error}`),process.exit(1));let s=e.avgMs!=="?"?(1e3/parseFloat(e.avgMs)).toFixed(1):"?";console.log(" perf stats:"),console.log(` frames: ${e.frames}`),console.log(` avg: ${e.avgMs}ms (${s} fps)`),console.log(` max: ${e.maxMs}ms`),console.log(` layout: ${e.layoutMs}ms total`),console.log(` nodes: ${e.nodeCount}`),e.recentCount>0&&console.log(` jank: ${e.jankFrames}/${e.recentCount} frames >16.67ms`);break}case"start":{await c.send({type:"evaluate",code:`(async () => {
664
664
  // worker mode
665
665
  if (window.__sootsimPerfStart && window.__sootsimRenderHost) {
666
666
  const result = window.__sootsimPerfStart()
@@ -682,7 +682,7 @@ ${s}
682
682
  startedAt: performance.now(),
683
683
  }
684
684
  return { started: true }
685
- })()`}),console.log(` profiling started \u2014 interact with the app, then run '${b("perf")} stop'`);break}case"stop":{let t=await c.send({type:"evaluate",code:`(async () => {
685
+ })()`}),console.log(` profiling started \u2014 interact with the app, then run '${b("perf")} stop'`);break}case"stop":{let e=await c.send({type:"evaluate",code:`(async () => {
686
686
  // worker mode
687
687
  if (window.__sootsimRenderHost) {
688
688
  const session = window.${Q} || {}
@@ -776,8 +776,8 @@ ${s}
776
776
  jankFrames: recent.filter(f => f > 16.67).length,
777
777
  sampleCount: recent.length,
778
778
  }
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 () => {
779
+ })()`});e.error&&(console.error(` error: ${e.error}`),process.exit(1));let s=e.avgMs>0?(1e3/e.avgMs).toFixed(1):"?",n=e.sampleCount>0?(e.jankFrames/e.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
780
+ `),console.log(` frames: ${e.frames}`),console.log(` total: ${e.totalMs.toFixed(1)}ms`),console.log(` avg: ${e.avgMs.toFixed(2)}ms (${s} fps)`),console.log(` max: ${e.maxMs.toFixed(2)}ms`),console.log(""),e.layoutAvgMs!==void 0&&(console.log(" breakdown (avg per frame):"),console.log(` layout: ${e.layoutAvgMs.toFixed(2)}ms`),console.log(` render: ${e.renderAvgMs.toFixed(2)}ms`),console.log(` copy: ${e.copyAvgMs.toFixed(2)}ms`),e.auxAvgMs!==void 0&&console.log(` aux: ${e.auxAvgMs.toFixed(2)}ms`),e.otherAvgMs!==void 0&&console.log(` other: ${e.otherAvgMs.toFixed(2)}ms`),console.log("")),console.log(` distribution (${e.sampleCount} samples):`),console.log(` p50: ${e.p50.toFixed(2)}ms`),console.log(` p95: ${e.p95.toFixed(2)}ms`),console.log(` p99: ${e.p99.toFixed(2)}ms`),console.log(` jank: ${e.jankFrames} frames (${n}%) >16.67ms`);break}case"frames":{let e=a[2]?Number(a[2]):50;(!Number.isFinite(e)||e<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await c.send({type:"evaluate",code:`(async () => {
781
781
  if (window.__sootsimRenderHost) {
782
782
  const session = window.${Q} || {}
783
783
  if (session.active) {
@@ -795,13 +795,13 @@ ${s}
795
795
  return {
796
796
  mode: 'render-worker',
797
797
  live: true,
798
- samples: samples.slice(-${t}),
798
+ samples: samples.slice(-${e}),
799
799
  }
800
800
  }
801
801
  return {
802
802
  mode: 'render-worker',
803
803
  live: false,
804
- samples: (session.lastSamples || []).slice(-${t}),
804
+ samples: (session.lastSamples || []).slice(-${e}),
805
805
  }
806
806
  }
807
807
  // main-thread mode
@@ -810,9 +810,9 @@ ${s}
810
810
  const stats = perf.getFrameStats?.() || {}
811
811
  return {
812
812
  mode: 'main-thread',
813
- frames: (stats.recentFrames || []).slice(-${t}),
813
+ frames: (stats.recentFrames || []).slice(-${e}),
814
814
  }
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 () => {
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,q]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)} ${q.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 e=a[2]?Number(a[2]):20;(!Number.isFinite(e)||e<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await c.send({type:"evaluate",code:`(async () => {
816
816
  if (window.__sootsimRenderHost) {
817
817
  const session = window.${Q} || {}
818
818
  if (session.active) {
@@ -833,7 +833,7 @@ ${s}
833
833
  samples: samples
834
834
  .slice()
835
835
  .sort((a, b) => b[1] - a[1])
836
- .slice(0, ${t}),
836
+ .slice(0, ${e}),
837
837
  }
838
838
  }
839
839
  const samples = Array.isArray(session.lastSamples) ? session.lastSamples : []
@@ -843,7 +843,7 @@ ${s}
843
843
  samples: samples
844
844
  .slice()
845
845
  .sort((a, b) => b[1] - a[1])
846
- .slice(0, ${t}),
846
+ .slice(0, ${e}),
847
847
  }
848
848
  }
849
849
  const perf = window.__sootsimPerf
@@ -852,9 +852,9 @@ ${s}
852
852
  const recent = Array.isArray(stats.recentFrames) ? stats.recentFrames : []
853
853
  return {
854
854
  mode: 'main-thread',
855
- frames: recent.slice().sort((a, b) => b - a).slice(0, ${t}),
855
+ frames: recent.slice().sort((a, b) => b - a).slice(0, ${e}),
856
856
  }
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(`
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,q]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)} ${q.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 e=a[2];if(!e||!["goHome","appSwitcher","lockScreen"].includes(e)){console.log(`
858
858
  ${b("perf")} transition <event> \u2014 profile a shell transition
859
859
 
860
860
  events:
@@ -867,7 +867,7 @@ ${s}
867
867
  examples:
868
868
  ${b("perf")} transition goHome --timeout 10000
869
869
  ${b("perf")} transition appSwitcher
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 () => {
870
+ `);break}let n=`sootsim:${e}`;console.log(` profiling ${e} transition...`),console.log(" (use --timeout 10000 if this times out)");let r=await c.send({type:"evaluate",code:`(async () => {
871
871
  // only supported in render-worker mode
872
872
  if (!window.__sootsimRenderHost) {
873
873
  return { error: 'transition profiling requires render-worker mode' }
@@ -905,7 +905,7 @@ ${s}
905
905
  const otherTotal = otherTimes.reduce((a, b) => a + b, 0)
906
906
 
907
907
  return {
908
- event: '${t}',
908
+ event: '${e}',
909
909
  frames: frameTimes.length,
910
910
  totalMs: total,
911
911
  avgMs: avg,
@@ -926,7 +926,7 @@ ${s}
926
926
  jankFrames: frameTimes.filter(f => f > 16.67).length,
927
927
  samples,
928
928
  }
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:
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(` ${e} transition profiled:
930
930
 
931
931
  frames: ${r.frames}
932
932
  total: ${r.totalMs.toFixed(1)}ms
@@ -944,27 +944,27 @@ ${s}
944
944
  p50: ${r.p50.toFixed(2)}ms
945
945
  p95: ${r.p95.toFixed(2)}ms
946
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):
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: ${t}`),process.exit(1)}break}case"errors":{let t=a[1];if(t==="clear"){await Qe(c),D(l)?B({cleared:!0}):console.log(" error buffer cleared");break}let e=t?Number(t):20,s=await Xe(c,e);if(D(l)){B(s);break}if(s.length===0){console.log(" no errors captured");break}console.log(` ${s.length} error(s):
948
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:`(() => {
949
+ `).slice(0,3);for(let x of m)console.log(` ${x.trim()}`)}}break}case"warnings":{let t=a[1]?Number(a[1]):20,e=await Ve(c,t);if(D(l)){B(e);break}if(e.length===0){console.log(" no warnings captured");break}console.log(` ${e.length} warning(s):
950
+ `);for(let s of e){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 t=await z(c,"listAnimations")??[];if(o.includes("--json")){console.log(JSON.stringify(t,null,2));break}if(t.length===0){console.log(" no active animations");break}console.log(` ${t.length} active animation(s):
951
+ `);for(let e of t){let s=String(e.kind).padEnd(6),n=`${Number(e.from).toFixed(2)}\u2192${Number(e.to).toFixed(2)}`,r=Number(e.current??0).toFixed(2),u=`${Math.round((e.progress??0)*100)}%`,m=`${Math.round(e.elapsedMs??0)}ms`,x=e.loop?" loop":"",g=e.layoutBound?" layout":"";console.log(` #${e.id} ${s} ${n.padEnd(14)} cur=${r.padEnd(7)} ${u.padStart(4)} ${m}${x}${g}`)}break}case"animation":{let t=a[1];(!t||t==="--help"||t==="-h")&&(console.error(` usage: ${b("animation")} <id>`),process.exit(1));let e=Number(t);Number.isFinite(e)||(console.error(` invalid id: ${t}`),process.exit(1));let s=await z(c,"getAnimation",e);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let t=a[1];(!t||t==="--help"||t==="-h")&&(console.error(` usage: ${b("stop-animation")} <id|all>`),process.exit(1));let e=t==="all"?"all":Number(t);e!=="all"&&!Number.isFinite(e)&&(console.error(` invalid id: ${t}`),process.exit(1));let s=await z(c,"stopAnimation",e);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let t=a[1];if(t==="clear"){await et(c),D(l)?B({cleared:!0}):console.log(" request buffer cleared");break}let e=t==="all",s=e?a[2]:t,n=s?Number(s):20,r=await Ze(c,{failed:!e,limit:n});if(D(l)){B(r);break}if(r.length===0){console.log(e?" no requests captured":" no failed requests captured");break}console.log(` ${r.length} ${e?"request(s)":"failed request(s)"}:
952
+ `);for(let u of r){let m=new Date(u.timestamp).toLocaleTimeString();console.log(` [${m}] ${W(u)}`),u.responseBody?console.log(` ${u.responseBody}`):u.error&&console.log(` ${u.error}`)}break}case"network":{let t=a[1],e=null,s=null,n=!1,r=!1,u=1e3,m=!1,x=!1;for(let M=0;M<l.length;M++){let h=l[M];if(h==="--filter")e=l[M+1]??null,M++;else if(h==="--limit"){let p=Number(l[M+1]);Number.isFinite(p)&&(s=p),M++}else if(h==="--threshold"){let p=Number(l[M+1]);Number.isFinite(p)&&p>0&&(u=p),M++}else h==="--failed"?n=!0:h==="--slow"?r=!0:h==="--tail"||h==="-f"?m=!0:h==="--json"&&(x=!0)}if(t==="clear"){await c.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(t==="get"){let M=a[2];M||(console.error(" usage: sootsim network get <id>"),process.exit(1));let h=await c.send({type:"evaluate",code:`(() => {
953
953
  const obs = window.__sootsimObservability;
954
954
  if (!obs) return null;
955
- return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(N)}) || null;
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:`(() => {
955
+ return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(M)}) || null;
956
+ })()`});h||(console.error(` no entry with id ${M}`),process.exit(1)),x?console.log(JSON.stringify(h,null,2)):co(h);break}let g=s??(m?200:t?Number(t):20);Number.isFinite(g)||(console.error(` invalid limit: ${t} \u2014 \`network\` takes a numeric count (e.g. ${b("network")} 100).
957
+ to target a specific sim, use \`--sim ${t}\` instead.`),process.exit(1));let $=async()=>{let M=await c.send({type:"evaluate",code:`(() => {
958
958
  const obs = window.__sootsimObservability;
959
959
  if (!obs) return { ok: false };
960
960
  return { ok: true, entries: obs.network.getSnapshot() };
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):
961
+ })()`});if(!M||!M.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return M.entries??[]},F=M=>{let h=M;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)),e){let p=e.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 M=await $(),h=F(M).slice(-g);if(x){console.log(JSON.stringify(h,null,2));break}if(h.length===0){M.length===0?console.log(" no network requests captured"):console.log(r?` no requests slower than ${u}ms (${M.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(r?` ${h.length} request(s) slower than ${u}ms (sorted by duration desc):
962
962
  `:` ${h.length} request(s):
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:
963
+ `);for(let p of h)Pt(p);break}console.log(` tailing network (ctrl-c to stop)...
964
+ `);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let M=await $(),h=F(M);for(let p of h)p.durationMs!=null&&(q.has(p.id)||(q.add(p.id),x?console.log(JSON.stringify(p)):Pt(p)));await X(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let t=a[1],e=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")e=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(t==="clear"){await ot(c),console.log(" log buffer cleared");break}let g=!u&&process.stdout.isTTY===!0,$=s??(r?500:t?Number(t):50);Number.isFinite($)||(console.error(` invalid limit: ${t} \u2014 \`logs\` takes a numeric count (e.g. ${b("logs")} 100).
965
+ to target a specific sim, use \`--sim ${t}\` instead.`),process.exit(1));let F=()=>tt(c),q=h=>st(h,{level:x,filter:e,showInternal:m});if(!r){let h=await F(),p=q(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)Rt(O,g);break}console.log(` tailing logs (ctrl-c to stop)...
967
+ `);let H=new Set,U=!0,M=()=>{U=!1};process.on("SIGINT",M);try{for(;U;){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)):Rt(O,g));await X(250)}}finally{process.off("SIGINT",M)}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 w(c),!j.has(y)&&!D(l))try{await oe(c)}catch{}}catch(t){let e=t instanceof Error?t.message:String(t);console.error(` ${y??"inspect"} failed: ${e}`);let s=/^no sim connected with id (.+)$/.exec(e),n=/^command timed out after \d+s$/.test(e)||e.startsWith("sim disconnected:")||e.startsWith("bridge never reconnected")||e.startsWith("could not connect to ws://");if(s)await dt(c,_,s[1]);else if(/^no sim connected$/.test(e))ct(_);else if(n)process.stderr.write(` the sim is not responding. recover it with:
968
968
  sootsim close --sim <id> # force-close the wedged sim
969
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};
970
+ `);else{try{await je(c)}catch{}try{await P({includeTail:!0})}catch{}try{await Z({includeTail:!0})}catch{}}process.exit(1)}finally{c.close()}}export{Vs as runInspect};