sootsim 0.1.148 → 0.1.150

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 (153) hide show
  1. package/dist-cli/bin.js +3 -3
  2. package/dist-cli/chunks/{agent-A5AQOHSI.js → agent-LSSBQD6J.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-S6AUOIXU.js → agent-wrapper-HYZ3VS4M.js} +2 -2
  4. package/dist-cli/chunks/{app-fonts-MQDZ55OI.js → app-fonts-XXHCZZVE.js} +2 -2
  5. package/dist-cli/chunks/{assert-USJNKN7R.js → assert-7I2ANKDG.js} +2 -2
  6. package/dist-cli/chunks/auto-bootstrap-YJM7QYAO.js +2 -0
  7. package/dist-cli/chunks/beta-EQOZMXP3.js +2 -0
  8. package/dist-cli/chunks/{camera-C4SKSA76.js → camera-4D7T4PZW.js} +2 -2
  9. package/dist-cli/chunks/{chunk-BCWW5RSQ.js → chunk-36L4ANT2.js} +1 -1
  10. package/dist-cli/chunks/{chunk-AXLTLDHE.js → chunk-3CENW2HN.js} +2 -2
  11. package/dist-cli/chunks/{chunk-A57WJDB2.js → chunk-3J5I64W6.js} +2 -2
  12. package/dist-cli/chunks/{chunk-BCRYE4YH.js → chunk-3K237XV5.js} +1 -1
  13. package/dist-cli/chunks/{chunk-KZ6AQHHA.js → chunk-3MWCUIK4.js} +2 -2
  14. package/dist-cli/chunks/{chunk-BWE6H36P.js → chunk-3RRDJNXM.js} +2 -2
  15. package/dist-cli/chunks/{chunk-TWOGFNQ7.js → chunk-45XLWBNT.js} +1 -1
  16. package/dist-cli/chunks/{chunk-NOBEILT5.js → chunk-5Q464MLB.js} +1 -1
  17. package/dist-cli/chunks/{chunk-ZNYPWEMX.js → chunk-65GDTEX7.js} +3 -3
  18. package/dist-cli/chunks/{chunk-YXZD545S.js → chunk-6SXJQK5R.js} +3 -3
  19. package/dist-cli/chunks/{chunk-PMM6MNCR.js → chunk-6UA5JZ4E.js} +2 -2
  20. package/dist-cli/chunks/{chunk-GXHVONDU.js → chunk-7YEISEQ2.js} +2 -2
  21. package/dist-cli/chunks/chunk-B43JOK5N.js +119 -0
  22. package/dist-cli/chunks/{chunk-IYRFX6KX.js → chunk-BFGPENAX.js} +1 -1
  23. package/dist-cli/chunks/{chunk-T4FJHKU4.js → chunk-BUKMAGA6.js} +2 -2
  24. package/dist-cli/chunks/{chunk-NK6RKGX2.js → chunk-BWVKFTFM.js} +1 -1
  25. package/dist-cli/chunks/{chunk-TYHRA7FX.js → chunk-CDLPRRMH.js} +2 -2
  26. package/dist-cli/chunks/{chunk-4T5Q2CUU.js → chunk-DNTULI35.js} +1 -1
  27. package/dist-cli/chunks/{chunk-G5BKDQGP.js → chunk-GXFEY4YV.js} +1 -1
  28. package/dist-cli/chunks/chunk-H5YQDCRA.js +1 -0
  29. package/dist-cli/chunks/{chunk-2SDVI2JB.js → chunk-IADOI73U.js} +2 -2
  30. package/dist-cli/chunks/{chunk-S3WEUJM3.js → chunk-IIJQQIAP.js} +2 -2
  31. package/dist-cli/chunks/{chunk-2OJ53PGA.js → chunk-JPWK6SFZ.js} +1 -1
  32. package/dist-cli/chunks/{chunk-ZMG6VGYA.js → chunk-KIDONDPE.js} +2 -2
  33. package/dist-cli/chunks/{chunk-U2U22DTV.js → chunk-KO4VABY3.js} +1 -1
  34. package/dist-cli/chunks/{chunk-23QZQBTT.js → chunk-LBZGVNQE.js} +1 -1
  35. package/dist-cli/chunks/{chunk-K4QZ6WX6.js → chunk-LPVQM4H7.js} +2 -2
  36. package/dist-cli/chunks/{chunk-XYFPDYAI.js → chunk-MFPT2P6I.js} +1 -1
  37. package/dist-cli/chunks/{chunk-F3MFOV7R.js → chunk-NHDDW7WP.js} +1 -1
  38. package/dist-cli/chunks/{chunk-4JVDEEJJ.js → chunk-NI2TIFUK.js} +1 -1
  39. package/dist-cli/chunks/{chunk-UK7GX57G.js → chunk-NISJ26VT.js} +7 -32
  40. package/dist-cli/chunks/{chunk-NMN4JPG2.js → chunk-NK5T7NYR.js} +1 -1
  41. package/dist-cli/chunks/{chunk-CN3ACF52.js → chunk-NSEXBZUW.js} +2 -2
  42. package/dist-cli/chunks/chunk-OYWQKX2A.js +2 -0
  43. package/dist-cli/chunks/{chunk-YONGHIDE.js → chunk-PFFELWZN.js} +2 -2
  44. package/dist-cli/chunks/{chunk-Y5E53BEN.js → chunk-PGAGVXOZ.js} +2 -2
  45. package/dist-cli/chunks/chunk-PHRIZLTZ.js +1 -0
  46. package/dist-cli/chunks/{chunk-7EBPIOTW.js → chunk-QIGU47UD.js} +1 -1
  47. package/dist-cli/chunks/{chunk-BDKC2GLL.js → chunk-VJRAGYZ6.js} +2 -2
  48. package/dist-cli/chunks/{chunk-474QHKFY.js → chunk-WNJOX4AQ.js} +2 -2
  49. package/dist-cli/chunks/chunk-WQF5CLFD.js +463 -0
  50. package/dist-cli/chunks/{chunk-IQVOFR7U.js → chunk-WZ5JKRIA.js} +2 -2
  51. package/dist-cli/chunks/chunk-YKWGZWBE.js +1 -0
  52. package/dist-cli/chunks/{chunk-XWUUFV45.js → chunk-YLSVHL4W.js} +2 -2
  53. package/dist-cli/chunks/{chunk-2B26APLC.js → chunk-YSN32GSR.js} +2 -2
  54. package/dist-cli/chunks/cli-version-QHAJ7OMR.js +2 -0
  55. package/dist-cli/chunks/{compat-7NMHHJXV.js → compat-EPSPO3GI.js} +3 -3
  56. package/dist-cli/chunks/{config-XKL7G2P3.js → config-7YGGAVYO.js} +2 -2
  57. package/dist-cli/chunks/{control-ZGD3NJES.js → control-TMFCD2NX.js} +2 -2
  58. package/dist-cli/chunks/{cpu-profile-ITFDFMIJ.js → cpu-profile-44YYVMOE.js} +2 -2
  59. package/dist-cli/chunks/{daemon-LHFCZTK6.js → daemon-4XLAN5CC.js} +2 -2
  60. package/dist-cli/chunks/{debug-C3X2PP3H.js → debug-MUYM2RWK.js} +3 -3
  61. package/dist-cli/chunks/{detox-ITXRK6EB.js → detox-NZJVVCA3.js} +2 -2
  62. package/dist-cli/chunks/{device-PBA26VX4.js → device-7HMHAQ2Q.js} +2 -2
  63. package/dist-cli/chunks/{diagnose-IWYHJJ7K.js → diagnose-FXVOC7LV.js} +2 -2
  64. package/dist-cli/chunks/drivers-GM6GJG7Q.js +2 -0
  65. package/dist-cli/chunks/{electron-6NRCOUQ3.js → electron-NKK6Z2F3.js} +3 -3
  66. package/dist-cli/chunks/flow-3E4SG5M7.js +2 -0
  67. package/dist-cli/chunks/help-VIYWVIUB.js +2 -0
  68. package/dist-cli/chunks/{hints-RBTS7PGP.js → hints-BLVNUKRX.js} +2 -2
  69. package/dist-cli/chunks/{home-paths-XKUYGHWD.js → home-paths-2QMRDV5X.js} +2 -2
  70. package/dist-cli/chunks/{inspect-7V5RQUJM.js → inspect-E6Z6N3PK.js} +34 -34
  71. package/dist-cli/chunks/install-U7C5NDWU.js +2 -0
  72. package/dist-cli/chunks/{install-desktop-MD77SEFP.js → install-desktop-O2E7FC4R.js} +3 -3
  73. package/dist-cli/chunks/{keys-LJMI7F3J.js → keys-GWXMM5CC.js} +2 -2
  74. package/dist-cli/chunks/{launch-RKUIUORR.js → launch-KWMHPASG.js} +3 -3
  75. package/dist-cli/chunks/{login-M7EXKPAT.js → login-AJO4L3ZI.js} +4 -4
  76. package/dist-cli/chunks/{logout-OVAZMIW5.js → logout-ZVGPEGAB.js} +2 -2
  77. package/dist-cli/chunks/{maestro-S4RQPFHB.js → maestro-4QX23OEI.js} +2 -2
  78. package/dist-cli/chunks/optional-demo-registry-LKCGAST6.js +2 -0
  79. package/dist-cli/chunks/{preview-QSIZ6KNZ.js → preview-CGBGA343.js} +2 -2
  80. package/dist-cli/chunks/{profile-6QQ3G5X7.js → profile-RLKDXLSK.js} +2 -2
  81. package/dist-cli/chunks/{react-HR7OT4NK.js → react-W2VGA55C.js} +2 -2
  82. package/dist-cli/chunks/{record-ZRSPOPCY.js → record-CF2HMY5Y.js} +2 -2
  83. package/dist-cli/chunks/runtime-A7DUL4IU.js +2 -0
  84. package/dist-cli/chunks/{runtime-delivery-MFVXZGIF.js → runtime-delivery-DZWXR2A5.js} +2 -2
  85. package/dist-cli/chunks/{screenshot-QNQ4TJ3I.js → screenshot-YV7USPJA.js} +2 -2
  86. package/dist-cli/chunks/{screenshot-mode-27K7PUTV.js → screenshot-mode-V27UKIG6.js} +2 -2
  87. package/dist-cli/chunks/{screenshots-LH7R6LV3.js → screenshots-BUOMYKKW.js} +2 -2
  88. package/dist-cli/chunks/{server-QQRPB6AJ.js → server-6EZSHZV3.js} +3 -3
  89. package/dist-cli/chunks/setup-repo-MCAZJVL5.js +2 -0
  90. package/dist-cli/chunks/{skills-KNFHQD77.js → skills-NXDCB76R.js} +2 -2
  91. package/dist-cli/chunks/{slides-GWMFQQAF.js → slides-6LF76Q4J.js} +2 -2
  92. package/dist-cli/chunks/{start-4INDW3QD.js → start-5VNJWI56.js} +4 -4
  93. package/dist-cli/chunks/store-SX54DA6L.js +2 -0
  94. package/dist-cli/chunks/telemetry-PHXMPEY3.js +2 -0
  95. package/dist-cli/chunks/{test-Q3CEHSD5.js → test-KPKJXRDI.js} +3 -3
  96. package/dist-cli/chunks/{three-mode-GTKSFFV7.js → three-mode-RWCVKNGM.js} +2 -2
  97. package/dist-cli/chunks/{timeline-NBDNN5SP.js → timeline-SRG5UM44.js} +2 -2
  98. package/dist-cli/chunks/{upgrade-UE7B726I.js → upgrade-LMUTKCI4.js} +2 -2
  99. package/dist-cli/chunks/upload-3YJQJYAD.js +2 -0
  100. package/dist-cli/chunks/{version-SS32LC2F.js → version-P4LKM55A.js} +2 -2
  101. package/dist-cli/chunks/web-5ZYKOZJG.js +2 -0
  102. package/dist-cli/chunks/{what-happened-NVKZVCHT.js → what-happened-AFWB7XTD.js} +2 -2
  103. package/dist-cli/chunks/{whoami-FWRWWX2E.js → whoami-YXJ6KECJ.js} +2 -2
  104. package/dist-lib/agent-daemon-client.cjs +1 -1
  105. package/dist-lib/agent-events.cjs +1 -1
  106. package/dist-lib/agent-sessions.cjs +1 -1
  107. package/dist-lib/attached-projects.cjs +1 -1
  108. package/dist-lib/auth/shared-session.cjs +1 -1
  109. package/dist-lib/backend-origin.cjs +1 -1
  110. package/dist-lib/beta.cjs +1 -1
  111. package/dist-lib/beta.mjs +1 -1
  112. package/dist-lib/bridge-constants.cjs +1 -1
  113. package/dist-lib/cli-constants.cjs +1 -1
  114. package/dist-lib/config.cjs +1 -1
  115. package/dist-lib/detox/index.cjs +1 -1
  116. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  117. package/dist-lib/home-paths.cjs +1 -1
  118. package/dist-lib/host/bridge-host.cjs +1 -1
  119. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  120. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  121. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  122. package/dist-lib/host/websocket-proxy.cjs +1 -1
  123. package/dist-lib/index.cjs +1 -1
  124. package/dist-lib/metro.cjs +1 -1
  125. package/dist-lib/profiles.cjs +1 -1
  126. package/dist-lib/render-mode.cjs +1 -1
  127. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  128. package/dist-lib/sdk.cjs +1 -1
  129. package/dist-lib/sdk.mjs +1 -1
  130. package/dist-lib/skills.cjs +156 -59
  131. package/dist-lib/vite.cjs +1 -1
  132. package/package.json +1 -1
  133. package/src/vite-plugin.ts +24 -0
  134. package/dist-cli/chunks/auto-bootstrap-CKH5ZZSJ.js +0 -2
  135. package/dist-cli/chunks/beta-Q6IKT5HT.js +0 -2
  136. package/dist-cli/chunks/chunk-2GROEF3J.js +0 -386
  137. package/dist-cli/chunks/chunk-CKOXSYJ6.js +0 -119
  138. package/dist-cli/chunks/chunk-JQFOV34Q.js +0 -1
  139. package/dist-cli/chunks/chunk-ROADBGFV.js +0 -2
  140. package/dist-cli/chunks/chunk-SY5JYGZE.js +0 -1
  141. package/dist-cli/chunks/chunk-V4EYA5L5.js +0 -1
  142. package/dist-cli/chunks/cli-version-5KMLKVRO.js +0 -2
  143. package/dist-cli/chunks/drivers-5B4IZBF3.js +0 -2
  144. package/dist-cli/chunks/flow-ITIKFOJJ.js +0 -2
  145. package/dist-cli/chunks/help-A26MVCNK.js +0 -2
  146. package/dist-cli/chunks/install-AJ3BWZ2Z.js +0 -2
  147. package/dist-cli/chunks/optional-demo-registry-DA3SDA2G.js +0 -2
  148. package/dist-cli/chunks/runtime-X5RH4ZUA.js +0 -2
  149. package/dist-cli/chunks/setup-repo-CTPFDKV3.js +0 -2
  150. package/dist-cli/chunks/store-SIN5AXHS.js +0 -2
  151. package/dist-cli/chunks/telemetry-QHL6TKNR.js +0 -2
  152. package/dist-cli/chunks/upload-UXXFJA3K.js +0 -2
  153. package/dist-cli/chunks/web-A3EW2IWT.js +0 -2
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as G}from"./chunk-IQVOFR7U.js";import{a as wt,b as xt}from"./chunk-NOBEILT5.js";import{a as Ye,g as $e,j as ee}from"./chunk-UK7GX57G.js";import{b as $t,c as St,j as vt}from"./chunk-AXLTLDHE.js";import"./chunk-BDKC2GLL.js";import{a as Z,b as A,c as P,d as Pe,e as re,f as Y,g as ce,h as pe,i as yt,j as ht,k as Re,l as bt}from"./chunk-S3WEUJM3.js";import{A as ut,B as mt,F as pt,H as le,I as ft,O as gt,a as be,b as Ge,c as Xe,d as Ve,e as Qe,f as Ze,g as et,h as tt,i as ot,j as st,k as _e,l as Oe,q as Ae,r as nt,s as rt,t as we,u as it,v as xe,w as at,x as lt,y as ct,z as dt}from"./chunk-7EBPIOTW.js";import"./chunk-NMN4JPG2.js";import{c as He,e as Ue,f as Ke,g as ze,h as Fe}from"./chunk-PMM6MNCR.js";import"./chunk-IYRFX6KX.js";import"./chunk-474QHKFY.js";import"./chunk-23QZQBTT.js";import"./chunk-KZ6AQHHA.js";import"./chunk-V4EYA5L5.js";import"./chunk-BCWW5RSQ.js";import{b as qe}from"./chunk-4JVDEEJJ.js";import{a as Je}from"./chunk-TWOGFNQ7.js";import{a as Ie,c as Ne}from"./chunk-CKOXSYJ6.js";import{a as We}from"./chunk-ROADBGFV.js";import"./chunk-U2U22DTV.js";import"./chunk-F3MFOV7R.js";import"./chunk-XYFPDYAI.js";import{existsSync as co,mkdirSync as uo,readFileSync as mo,rmSync as kt,writeFileSync as po}from"fs";import{tmpdir as fo}from"os";import{dirname as go,join as yo,resolve as ho}from"path";var fe=1,bo="SOOTSIM_INSPECT_NOTICE_PATH",wo=300*1e3,xo=15e3;function Tt(){return ho(process.env[bo]||yo(fo(),"sootsim-inspect-notice-state.json"))}function $o(e,c){return Object.fromEntries(Object.entries(e).filter(([,n])=>typeof n?.signature=="string"&&Number.isFinite(n?.updatedAt)&&c-n.updatedAt<=wo))}function So(e){let c=Tt();if(!co(c))return{version:fe,entries:{}};try{let n=JSON.parse(mo(c,"utf8"));return n.version!==fe||!n.entries||typeof n.entries!="object"?(kt(c,{force:!0}),{version:fe,entries:{}}):{version:fe,entries:$o(n.entries,e)}}catch{return kt(c,{force:!0}),{version:fe,entries:{}}}}function vo(e){let c=Tt();uo(go(c),{recursive:!0}),po(c,JSON.stringify(e,null,2)+`
1
+ /*! sootsim v0.1.150 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as Y}from"./chunk-WZ5JKRIA.js";import{a as wt,b as xt}from"./chunk-5Q464MLB.js";import{a as Ge,g as $e,j as ee}from"./chunk-NISJ26VT.js";import{b as $t,c as St,j as vt}from"./chunk-3CENW2HN.js";import"./chunk-VJRAGYZ6.js";import{a as Z,b as A,c as P,d as Pe,e as re,f as G,g as ce,h as pe,i as yt,j as ht,k as Re,l as bt}from"./chunk-IIJQQIAP.js";import{A as ut,B as mt,F as pt,H as le,I as ft,O as gt,a as be,b as Ye,c as Xe,d as Ve,e as Qe,f as Ze,g as et,h as tt,i as ot,j as st,k as _e,l as Oe,q as Ae,r as nt,s as rt,t as we,u as it,v as xe,w as at,x as lt,y as ct,z as dt}from"./chunk-QIGU47UD.js";import"./chunk-NK5T7NYR.js";import{c as He,e as Ue,f as Ke,g as ze,h as Fe}from"./chunk-6UA5JZ4E.js";import"./chunk-BFGPENAX.js";import"./chunk-WNJOX4AQ.js";import"./chunk-LBZGVNQE.js";import"./chunk-3MWCUIK4.js";import"./chunk-YKWGZWBE.js";import"./chunk-36L4ANT2.js";import{b as qe}from"./chunk-NI2TIFUK.js";import{a as Le}from"./chunk-45XLWBNT.js";import{a as Ie,c as Ne}from"./chunk-B43JOK5N.js";import{a as We}from"./chunk-OYWQKX2A.js";import"./chunk-KO4VABY3.js";import"./chunk-NHDDW7WP.js";import"./chunk-MFPT2P6I.js";import{existsSync as co,mkdirSync as uo,readFileSync as mo,rmSync as kt,writeFileSync as po}from"fs";import{tmpdir as fo}from"os";import{dirname as go,join as yo,resolve as ho}from"path";var fe=1,bo="SOOTSIM_INSPECT_NOTICE_PATH",wo=300*1e3,xo=15e3;function Tt(){return ho(process.env[bo]||yo(fo(),"sootsim-inspect-notice-state.json"))}function $o(e,c){return Object.fromEntries(Object.entries(e).filter(([,n])=>typeof n?.signature=="string"&&Number.isFinite(n?.updatedAt)&&c-n.updatedAt<=wo))}function So(e){let c=Tt();if(!co(c))return{version:fe,entries:{}};try{let n=JSON.parse(mo(c,"utf8"));return n.version!==fe||!n.entries||typeof n.entries!="object"?(kt(c,{force:!0}),{version:fe,entries:{}}):{version:fe,entries:$o(n.entries,e)}}catch{return kt(c,{force:!0}),{version:fe,entries:{}}}}function vo(e){let c=Tt();uo(go(c),{recursive:!0}),po(c,JSON.stringify(e,null,2)+`
3
3
  `)}function ko(e,c){let n=c.trim()||"default";return`${e}:${n}`}function Ee(e,c,n,l={}){let m=l.nowMs??Date.now(),r=l.cooldownMs??xo,g=So(m),y=ko(e,c),T=g.entries[y];return T&&T.signature===n&&m-T.updatedAt<r?!1:(g.entries[y]={signature:n,updatedAt:m},vo(g),!0)}var To={initialWaitMs:3e3,deadlineMs:5e3,retryWaitMs:700},Mo={initialWaitMs:1200,deadlineMs:2500,retryWaitMs:700};function Io(e,c={}){return{...e?To:Mo,...c}}function de(e){return!(!e||e.hit===!1||e.ok===!1||e.pointerTapHandled===!1&&!e.keyboardOpened&&!e.isTextInput)}function No(e,c){return{id:e.target?.id??e.match?.id??e.node?.id??null,testID:e.target?.testID??e.match?.testID??e.node?.testID??null,text:e.target?.text??e.target?.accessibilityLabel??e.match?.text??e.match?.accessibilityLabel??e.node?.text??c??null,type:e.target?.type??e.match?.type??e.node?.type??null}}async function ge(e,c){let n=Io(!!c.agent,c.timing),l=0,m=null,r=null;try{await ee({bridge:e,maxMs:n.initialWaitMs,pollMs:32,stablePolls:2})}catch{}let g=Date.now()+n.deadlineMs;for(;Date.now()<=g||l===0;){l++;let y=await c.resolve();if(m=y,y?.error==="bridge-not-ready"||y?.ambiguous||y?.nthOutOfRange)return{payload:y,result:null,attempts:l,failure:"special"};if(y&&typeof y.cx=="number"&&typeof y.cy=="number"){let M=await e.send({type:"tap",x:y.cx,y:y.cy,target:No(y,c.textFallback)});if(r=M,de(M))return{payload:y,result:M,attempts:l}}let T=g-Date.now();if(T<=0)break;try{await ee({bridge:e,maxMs:Math.min(T,n.retryWaitMs),pollMs:32,stablePolls:2})}catch{await new Promise(M=>setTimeout(M,Math.min(120,T)))}}return{payload:m,result:r,attempts:l,failure:m&&typeof m.cx=="number"?"missed":"not-found"}}async function Mt(e,c,n,l){return e.send({type:"tap",x:c,y:n,...l?{target:l}:{}})}async function It(e,c,n={}){let l=JSON.stringify(c);return ge(e,{agent:n.agent,timing:n.timing,resolve:()=>e.send({type:"evaluate",code:`(async () => {
4
4
  const t = window.__sootsimTest
5
5
  if (!t) return null
@@ -197,12 +197,12 @@ import{a as G}from"./chunk-IQVOFR7U.js";import{a as wt,b as xt}from"./chunk-NOBE
197
197
  }
198
198
  }
199
199
  return { strategy: 'none' }
200
- })()`});if(!m||!("node"in m))return m;let r=m.node,g=r.absolutePosition.x+r.layout.width/2,y=r.absolutePosition.y+r.layout.height/2;return{...m,cx:g,cy:y,target:{id:r.id,testID:r.testID,text:m.strategy==="text"?c:r.text,type:r.type}}}})}async function _t(e,c={args:[]}){let n=await Xe(e);if(A(c.args)){P(n);return}console.log(` nodes: ${n.nodes}`)}function De(e,c){let n=e.indexOf(c);return n>=0&&n+1<e.length?e[n+1]:null}async function Ot(e){let{bridge:c,args:n,positional:l}=e,m=n.includes("--verbose")||n.includes("-v"),r=A(n),g=m&&!r,y=n.includes("--watch")||n.includes("-w"),T=1e3,M=n.includes("--compact"),h=n.includes("--no-xy"),k=n.includes("--no-clipped"),_=n.includes("--include-occluded"),I=De(n,"--testid-like"),R=De(n,"--only"),j=De(n,"--subtree"),d=l[1]&&!l[1].startsWith("-")?l[1]:void 0,z=d?/[*?]/.test(d):!1,B=!z&&!R?d:void 0,D=R??(z?d:void 0),V=async()=>{await ce(c,{verbose:g});let S=await Ze(c,{describe:!0,verbose:m,filter:B||"",testIdLike:I||void 0,onlyGlob:D||void 0,subtreeRoot:j||void 0,compact:M,hideXy:h,includeOccluded:_}),N=S?.tree,J=S?.shell,W=S?.keyboard;if(r){P({shell:J,tree:N??"",keyboard:W});return}if(J&&typeof J=="object"){let C=[J.state?`state=${J.state}`:null,J.activeApp?`app=${J.activeApp}`:null,J.showSwitcher?"switcher":null,J.switcherPhase&&J.switcherPhase!=="idle"?`phase=${J.switcherPhase}`:null].filter(Boolean);C.length>0&&console.log(` shell: ${C.join(" ")}`)}if(typeof N=="string"&&N.startsWith("__SUBTREE_NOT_FOUND__:")){let C=N.slice(22);console.log(` subtree root not found: ${C}`),G("subtree-root-not-found",C);return}if(!N){let C=S?.nodeCount??0;console.log(" no matching nodes found"),!(B||I||D||j)&&C<10&&G("app-still-loading",C);return}let X=N,Q=0;if(k&&typeof X=="string"){let C=X.split(`
200
+ })()`});if(!m||!("node"in m))return m;let r=m.node,g=r.absolutePosition.x+r.layout.width/2,y=r.absolutePosition.y+r.layout.height/2;return{...m,cx:g,cy:y,target:{id:r.id,testID:r.testID,text:m.strategy==="text"?c:r.text,type:r.type}}}})}async function _t(e,c={args:[]}){let n=await Xe(e);if(A(c.args)){P(n);return}console.log(` nodes: ${n.nodes}`)}function De(e,c){let n=e.indexOf(c);return n>=0&&n+1<e.length?e[n+1]:null}async function Ot(e){let{bridge:c,args:n,positional:l}=e,m=n.includes("--verbose")||n.includes("-v"),r=A(n),g=m&&!r,y=n.includes("--watch")||n.includes("-w"),T=1e3,M=n.includes("--compact"),h=n.includes("--no-xy"),k=n.includes("--no-clipped"),_=n.includes("--include-occluded"),I=De(n,"--testid-like"),R=De(n,"--only"),j=De(n,"--subtree"),d=l[1]&&!l[1].startsWith("-")?l[1]:void 0,z=d?/[*?]/.test(d):!1,B=!z&&!R?d:void 0,D=R??(z?d:void 0),V=async()=>{await ce(c,{verbose:g});let S=await Ze(c,{describe:!0,verbose:m,filter:B||"",testIdLike:I||void 0,onlyGlob:D||void 0,subtreeRoot:j||void 0,compact:M,hideXy:h,includeOccluded:_}),N=S?.tree,L=S?.shell,W=S?.keyboard;if(r){P({shell:L,tree:N??"",keyboard:W});return}if(L&&typeof L=="object"){let C=[L.state?`state=${L.state}`:null,L.activeApp?`app=${L.activeApp}`:null,L.showSwitcher?"switcher":null,L.switcherPhase&&L.switcherPhase!=="idle"?`phase=${L.switcherPhase}`:null].filter(Boolean);C.length>0&&console.log(` shell: ${C.join(" ")}`)}if(typeof N=="string"&&N.startsWith("__SUBTREE_NOT_FOUND__:")){let C=N.slice(22);console.log(` subtree root not found: ${C}`),Y("subtree-root-not-found",C);return}if(!N){let C=S?.nodeCount??0;console.log(" no matching nodes found"),!(B||I||D||j)&&C<10&&Y("app-still-loading",C);return}let X=N,Q=0;if(k&&typeof X=="string"){let C=X.split(`
201
201
  `),ae=[];for(let o of C){if(o.includes("(clipped:")){Q+=1;continue}ae.push(o)}X=ae.join(`
202
- `)}console.log(X),Q>0&&console.log(` ${Q} clipped row(s) hidden (omit --no-clipped to see)`);let ne=B||I||D||j;if((B||I||D)&&!y&&G("describe-filter-context"),!ne&&!y&&N.split(`
203
- `).length>=80&&G("describe-use-filters"),W&&W.visible){let C=W.spec,ae=[C?.keyboardType?`type=${C.keyboardType}`:null,C?.returnKeyType&&C.returnKeyType!=="default"?`return=${C.returnKeyType}`:null,W.mode!=="letters"?`mode=${W.mode}`:null,W.shifted?"shift":null,W.capsLock?"caps":null,C?.autoCapitalize&&C.autoCapitalize!=="sentences"?`autoCap=${C.autoCapitalize}`:null,W.accessoryBarId?`accessory=${W.accessoryBarId}`:null].filter(Boolean);console.log(`
202
+ `)}console.log(X),Q>0&&console.log(` ${Q} clipped row(s) hidden (omit --no-clipped to see)`);let ne=B||I||D||j;if((B||I||D)&&!y&&Y("describe-filter-context"),!ne&&!y&&N.split(`
203
+ `).length>=80&&Y("describe-use-filters"),W&&W.visible){let C=W.spec,ae=[C?.keyboardType?`type=${C.keyboardType}`:null,C?.returnKeyType&&C.returnKeyType!=="default"?`return=${C.returnKeyType}`:null,W.mode!=="letters"?`mode=${W.mode}`:null,W.shifted?"shift":null,W.capsLock?"caps":null,C?.autoCapitalize&&C.autoCapitalize!=="sentences"?`autoCap=${C.autoCapitalize}`:null,W.accessoryBarId?`accessory=${W.accessoryBarId}`:null].filter(Boolean);console.log(`
204
204
  keyboard: ${ae.join(" ")||"visible"}`)}};if(y)for(console.log(` watching... (Ctrl+C to stop)
205
- `);;)console.clear(),await V(),await Z(T);else await V()}var Fo=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function ue(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let e of Fo){let c=process.env[e];if(c&&c.trim()&&c!=="0")return!0}return!1}async function At(e){let{bridge:c,args:n,effectiveArgs:l,positional:m,inspectUsage:r}=e,g=S=>{let N=l.indexOf(S);return N>=0&&N+1<l.length?l[N+1]:null},y=S=>l.includes(S),T=g("--testid")||g("--test-id"),M=g("--role"),h=g("--type"),k=g("--text"),_=y("--pressable"),I=y("--visible"),R=y("--interactive-targets")||y("--actions"),j=!T&&!M&&!h&&!k&&!_&&!I&&!R?m[1]:null,d=k??j,z=await st(c,{testId:T,role:M,type:h,text:d,pressable:_,visible:I,interactive:R});z||(console.error(r("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:B,result:D}=z,V=A(n),te=n.includes("--verbose")||n.includes("--dump");if(V)B==="interactive-targets"&&Array.isArray(D)?P(_e(D).map(S=>({...S,tap:Oe(S)}))):P(D??null);else if(Array.isArray(D))if(D.length===0){console.log(` no ${B} nodes found`);let S=await c.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof S=="number"&&S<10&&G("app-still-loading",S)}else if(B==="interactive-targets"){let S=_e(D);console.log(` found ${S.length} interactive target${S.length===1?"":"s"} (sorted by score):`);for(let N of S.slice(0,20)){let J=N.absolutePosition?`@(${Math.round(N.absolutePosition.x)},${Math.round(N.absolutePosition.y)})`:"",W=N.layout?`${Math.round(N.layout.width)}x${Math.round(N.layout.height)}`:"?x?",X=N.text?` "${N.text.slice(0,30)}"`:"",Q=N.testID?` #${N.testID}`:"",ne=N.accessibilityLabel?` \u24D8"${String(N.accessibilityLabel).slice(0,24)}"`:"",me=N.accessibilityRole?`[${N.accessibilityRole}]`:N.type,C=Oe(N);console.log(` ${me}${X}${ne}${Q} ${W} ${J}`),console.log(` \u2192 ${C}`),te&&console.log(Ce(JSON.stringify(N,null,2)," "))}S.length>20&&console.log(` ... and ${S.length-20} more`)}else{console.log(` found ${D.length} node${D.length===1?"":"s"} (${B}):`);for(let S of D.slice(0,20)){let N=S.absolutePosition?`@(${Math.round(S.absolutePosition.x)},${Math.round(S.absolutePosition.y)})`:"",J=S.layout?`${Math.round(S.layout.width)}x${Math.round(S.layout.height)}`:"?x?",W=S.text?` "${S.text.slice(0,30)}"`:"",X=S.testID?` #${S.testID}`:"",Q=S.pressable?" (tap)":"",ne=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${ne}${W}${X} ${J} ${N}${Q}`),te&&console.log(Ce(JSON.stringify(S,null,2)," "))}D.length>20&&console.log(` ... and ${D.length-20} more`)}else if(D==null)console.log(` not found: ${d||T||M||h||""||B}`),T&&G("wait-selector-for-missing-testid",T);else{let S=D;if(S.type&&S.absolutePosition){let N=`@(${Math.round(S.absolutePosition.x)},${Math.round(S.absolutePosition.y)})`,J=S.layout?`${Math.round(S.layout.width)}x${Math.round(S.layout.height)}`:"?x?",W=S.text?` "${S.text.slice(0,40)}"`:"",X=S.testID?` #${S.testID}`:"",Q=S.pressable?" (tap)":"",ne=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${ne}${W}${X} ${J} ${N}${Q}`),te&&console.log(Ce(JSON.stringify(S,null,2)," "))}else console.log(JSON.stringify(D,null,2))}}function Ce(e,c){return e.split(`
205
+ `);;)console.clear(),await V(),await Z(T);else await V()}var Fo=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function ue(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let e of Fo){let c=process.env[e];if(c&&c.trim()&&c!=="0")return!0}return!1}async function At(e){let{bridge:c,args:n,effectiveArgs:l,positional:m,inspectUsage:r}=e,g=S=>{let N=l.indexOf(S);return N>=0&&N+1<l.length?l[N+1]:null},y=S=>l.includes(S),T=g("--testid")||g("--test-id"),M=g("--role"),h=g("--type"),k=g("--text"),_=y("--pressable"),I=y("--visible"),R=y("--interactive-targets")||y("--actions"),j=!T&&!M&&!h&&!k&&!_&&!I&&!R?m[1]:null,d=k??j,z=await st(c,{testId:T,role:M,type:h,text:d,pressable:_,visible:I,interactive:R});z||(console.error(r("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:B,result:D}=z,V=A(n),te=n.includes("--verbose")||n.includes("--dump");if(V)B==="interactive-targets"&&Array.isArray(D)?P(_e(D).map(S=>({...S,tap:Oe(S)}))):P(D??null);else if(Array.isArray(D))if(D.length===0){console.log(` no ${B} nodes found`);let S=await c.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof S=="number"&&S<10&&Y("app-still-loading",S)}else if(B==="interactive-targets"){let S=_e(D);console.log(` found ${S.length} interactive target${S.length===1?"":"s"} (sorted by score):`);for(let N of S.slice(0,20)){let L=N.absolutePosition?`@(${Math.round(N.absolutePosition.x)},${Math.round(N.absolutePosition.y)})`:"",W=N.layout?`${Math.round(N.layout.width)}x${Math.round(N.layout.height)}`:"?x?",X=N.text?` "${N.text.slice(0,30)}"`:"",Q=N.testID?` #${N.testID}`:"",ne=N.accessibilityLabel?` \u24D8"${String(N.accessibilityLabel).slice(0,24)}"`:"",me=N.accessibilityRole?`[${N.accessibilityRole}]`:N.type,C=Oe(N);console.log(` ${me}${X}${ne}${Q} ${W} ${L}`),console.log(` \u2192 ${C}`),te&&console.log(Ce(JSON.stringify(N,null,2)," "))}S.length>20&&console.log(` ... and ${S.length-20} more`)}else{console.log(` found ${D.length} node${D.length===1?"":"s"} (${B}):`);for(let S of D.slice(0,20)){let N=S.absolutePosition?`@(${Math.round(S.absolutePosition.x)},${Math.round(S.absolutePosition.y)})`:"",L=S.layout?`${Math.round(S.layout.width)}x${Math.round(S.layout.height)}`:"?x?",W=S.text?` "${S.text.slice(0,30)}"`:"",X=S.testID?` #${S.testID}`:"",Q=S.pressable?" (tap)":"",ne=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${ne}${W}${X} ${L} ${N}${Q}`),te&&console.log(Ce(JSON.stringify(S,null,2)," "))}D.length>20&&console.log(` ... and ${D.length-20} more`)}else if(D==null)console.log(` not found: ${d||T||M||h||""||B}`),T&&Y("wait-selector-for-missing-testid",T);else{let S=D;if(S.type&&S.absolutePosition){let N=`@(${Math.round(S.absolutePosition.x)},${Math.round(S.absolutePosition.y)})`,L=S.layout?`${Math.round(S.layout.width)}x${Math.round(S.layout.height)}`:"?x?",W=S.text?` "${S.text.slice(0,40)}"`:"",X=S.testID?` #${S.testID}`:"",Q=S.pressable?" (tap)":"",ne=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${ne}${W}${X} ${L} ${N}${Q}`),te&&console.log(Ce(JSON.stringify(S,null,2)," "))}else console.log(JSON.stringify(D,null,2))}}function Ce(e,c){return e.split(`
206
206
  `).map(n=>c+n).join(`
207
207
  `)}async function Pt(e){let{bridge:c,args:n}=e,l=A(n);await ce(c,{verbose:!l});let m=n.includes("--styling"),r=await et(c,{styling:m});if(l){P({count:r.length,elements:r});return}console.log(` layout (${r.length} element${r.length===1?"":"s"}):
208
208
  `),console.log(tt(r,{styling:m}))}async function Rt(e,c={}){let n=await pt(e);if("error"in n&&(console.error(n.error),process.exit(1)),c.json){console.log(JSON.stringify(n,null,2));return}let{visible:l,spec:m,mode:r,shifted:g,capsLock:y,accessoryBarId:T}=n,M=[];M.push(`keyboard: ${l?"visible":"hidden"}`),m?(M.push(` type: ${m.keyboardType}`),M.push(` returnKey: ${m.returnKeyType}`),M.push(` autoCap: ${m.autoCapitalize}`),M.push(` autoCorrect: ${m.autoCorrect?"on":"off"}`),M.push(` appearance: ${m.keyboardAppearance}`),m.secureTextEntry&&M.push(" secureTextEntry: true"),m.enablesReturnKeyAutomatically&&M.push(` return: ${m.currentTextIsEmpty?"disabled (empty)":"enabled"}`)):M.push(" spec: <none> (shown via dev-tools with no TextInput)"),M.push(` mode: ${r}${g?" (shifted)":""}${y?" (caps)":""}`),T&&M.push(` accessoryBar: ${T}`),console.log(M.join(`
@@ -232,11 +232,11 @@ import{a as G}from"./chunk-IQVOFR7U.js";import{a as wt,b as xt}from"./chunk-NOBE
232
232
  type: n.type ?? null,
233
233
  }
234
234
  })()`})??null}async function Ct(e,c={}){let{nav:n,keyboard:l,shell:m}=await ft(e);if(c.json){console.log(JSON.stringify({shell:m??null,nav:n,keyboard:l},null,2));return}let r=[];if(m){let g=m.activeApp??m.state??"<none>",y=m.showSwitcher?" (app switcher open)":"",T=typeof m.launchProgress=="number"&&m.launchProgress<.98?` launching (${Math.round(m.launchProgress*100)}%)`:"";r.push(`shell: ${g}${y}${T}`)}else r.push("shell: <unavailable>");if(n){let g=n.transitionPhase!=="idle"?` (${n.transitionPhase}, ${n.activeTransitionCount} active)`:"";if(r.push(`nav: phase=${n.transitionPhase}${g}`),n.screens.length===0)r.push(" <no registered screens \u2014 app may not use react-native-screens>");else for(let y of n.screens){let T=y.isActive?"\u25B6":" ",M=y.routeName?` ${y.routeName}`:"",h=y.headerHeight>0?` header=${y.headerHeight}`:"",k=y.largeTitleState&&y.largeTitleState!=="expanded"?` large-title=${y.largeTitleState}`:"";r.push(` ${T} #${y.id}${M}${h}${k}`)}}else r.push("nav: <runtime not available>");if(l&&l.visible){let g=l.spec?.keyboardType??"default",y=l.spec?.returnKeyType??"default";r.push(`keyboard: visible (${g}, return=${y}, mode=${l.mode??"?"})`)}else r.push("keyboard: hidden");console.log(r.join(`
235
- `))}async function Bt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1])*1e3:3e3,r=n.includes("--strict"),{elapsed:g,settled:y}=await ee({bridge:c,maxMs:m,strict:r});console.log(y?` settled in ${g}ms`:` timed out after ${g}ms (may still be animating)`)}async function jt(e){let c=e.positional[1]?Number(e.positional[1]):.5;(!Number.isFinite(c)||c<0)&&(console.error(e.inspectUsage("sleep","[seconds]")),process.exit(1)),await Z(c*1e3),console.log(` slept ${c}s`)}async function Lt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1]):5,{tree:r}=await Ve(c,m);if(A(n)){P({depth:m,tree:r??null});return}console.log(typeof r=="string"?r:JSON.stringify(r,null,2))}async function Jt(e,c={args:[]}){let n=await Qe(e);if(A(c.args)){P(n);return}console.log(n.url)}async function Wt(e){let{wsPort:c,commandTimeoutMs:n,simId:l,simIdSource:m,positional:r}=e,g=r[1]?Number(r[1]):30,y=Math.max(1e3,(Number.isFinite(g)?g:30)*1e3),T=Math.max(1,Math.ceil(y/500));console.log(" waiting for sim reconnect...");let M=await yt(c,n,l,{attempts:T,simIdSource:m});M||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),M.bridge.close(),$e({source:"inspect wait",step:{wait:y},summary:`wait ${Math.round(y/1e3)}s`}),console.log(` ready: ${M.count} nodes`)}var qt=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function ke(e,c){let n=e.indexOf(c);if(n>=0&&n+1<e.length)return e[n+1]}function _o(e,c){if(!c.filter&&!c.equals)return!0;let n=e.data,l=[];if(n&&typeof n=="object")for(let r of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let g=n[r];typeof g=="string"&&g.length>0&&l.push(g)}let m=l.join(" ");return c.equals?l.some(r=>r===c.equals):c.filter?m.toLowerCase().includes(c.filter.toLowerCase()):!0}async function Ht(e){let{bridge:c,args:n,positional:l,inspectUsage:m}=e,r=l[1];r||(console.error(m("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),qt.has(r)||console.error(` warning: '${r}' is not a known timeline kind \u2014 waiting anyway. known: ${[...qt].sort().join(", ")}`);let g=ke(n,"--max-ms"),y=g&&Number.isFinite(Number(g))?Math.max(100,Number(g)):5e3,T=ke(n,"--filter"),M=ke(n,"--equals"),h=ke(n,"--since")??"now",k=n.includes("--json"),_=Date.now(),I=_+y,R=200,j=_;for(;Date.now()<I;){let z={kinds:[r],since:h==="cursor"?void 0:j,limit:50},B=await c.send({type:"evaluate",code:`(async () => {
235
+ `))}async function Bt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1])*1e3:3e3,r=n.includes("--strict"),{elapsed:g,settled:y}=await ee({bridge:c,maxMs:m,strict:r});console.log(y?` settled in ${g}ms`:` timed out after ${g}ms (may still be animating)`)}async function jt(e){let c=e.positional[1]?Number(e.positional[1]):.5;(!Number.isFinite(c)||c<0)&&(console.error(e.inspectUsage("sleep","[seconds]")),process.exit(1)),await Z(c*1e3),console.log(` slept ${c}s`)}async function Jt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1]):5,{tree:r}=await Ve(c,m);if(A(n)){P({depth:m,tree:r??null});return}console.log(typeof r=="string"?r:JSON.stringify(r,null,2))}async function Lt(e,c={args:[]}){let n=await Qe(e);if(A(c.args)){P(n);return}console.log(n.url)}async function Wt(e){let{wsPort:c,commandTimeoutMs:n,simId:l,simIdSource:m,positional:r}=e,g=r[1]?Number(r[1]):30,y=Math.max(1e3,(Number.isFinite(g)?g:30)*1e3),T=Math.max(1,Math.ceil(y/500));console.log(" waiting for sim reconnect...");let M=await yt(c,n,l,{attempts:T,simIdSource:m});M||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),M.bridge.close(),$e({source:"inspect wait",step:{wait:y},summary:`wait ${Math.round(y/1e3)}s`}),console.log(` ready: ${M.count} nodes`)}var qt=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function ke(e,c){let n=e.indexOf(c);if(n>=0&&n+1<e.length)return e[n+1]}function _o(e,c){if(!c.filter&&!c.equals)return!0;let n=e.data,l=[];if(n&&typeof n=="object")for(let r of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let g=n[r];typeof g=="string"&&g.length>0&&l.push(g)}let m=l.join(" ");return c.equals?l.some(r=>r===c.equals):c.filter?m.toLowerCase().includes(c.filter.toLowerCase()):!0}async function Ht(e){let{bridge:c,args:n,positional:l,inspectUsage:m}=e,r=l[1];r||(console.error(m("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),qt.has(r)||console.error(` warning: '${r}' is not a known timeline kind \u2014 waiting anyway. known: ${[...qt].sort().join(", ")}`);let g=ke(n,"--max-ms"),y=g&&Number.isFinite(Number(g))?Math.max(100,Number(g)):5e3,T=ke(n,"--filter"),M=ke(n,"--equals"),h=ke(n,"--since")??"now",k=n.includes("--json"),_=Date.now(),I=_+y,R=200,j=_;for(;Date.now()<I;){let z={kinds:[r],since:h==="cursor"?void 0:j,limit:50},B=await c.send({type:"evaluate",code:`(async () => {
236
236
  const t = window.SootSim?.bridges?.timeline
237
237
  if (!t) return { ok: false, error: 'timeline bridge missing' }
238
238
  return { ok: true, result: await t.recent(${JSON.stringify(z)}) }
239
- })()`});(!B||!B.ok)&&(console.error(` could not query timeline: ${B&&"error"in B?B.error:"unknown"}`),process.exit(1));let D=B.result.events??[];for(let V of D)if(_o(V,{filter:T,equals:M})){let te=Date.now()-_;console.log(k?JSON.stringify({found:!0,elapsedMs:te,event:V}):` ${r} event after ${te}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`);return}B.result.watermark&&B.result.watermark>j&&(j=B.result.watermark),await new Promise(V=>setTimeout(V,R))}let d=Date.now()-_;k?console.log(JSON.stringify({found:!1,elapsedMs:d,kind:r,filter:T,equals:M})):console.error(` \u26A0 wait event ${r} timed out after ${d}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`),process.exit(1)}async function Ut(e){let{bridge:c,args:n}=e,l=n.includes("--strict"),m=be(n,3e3),{elapsed:r,settled:g}=await ee({bridge:c,maxMs:m,strict:l});g?console.log(` idle in ${r}ms`):(console.error(` \u26A0 wait idle timed out after ${r}ms (may still be animating)`),process.exit(1))}async function Kt(e){let{bridge:c,args:n}=e,l=be(n,2e4),{ready:m,elapsedMs:r,nodes:g,targets:y,flag:T,loadingText:M,externalReady:h,externalError:k,errors:_}=await nt(c,l,{onProgress(R){console.error(` still waiting after ${R.elapsedMs}ms \u2014 ${Ae(R)} (nodes: ${R.nodes}, targets: ${R.targets}, errors: ${R.errors})`)}});if(m){let R=l-r,j=Math.max(100,Math.min(1e4,R)),d=await ee({bridge:c,maxMs:j,pollMs:32,stablePolls:2});d.settled||(console.error(` \u26A0 wait ready timed out after ${r+d.elapsed}ms \u2014 app mounted but did not settle (nodes: ${g}, targets: ${y})`),process.exit(1)),console.log(` ready in ${r+d.elapsed}ms: ${g} nodes, ${y} targets`);return}let I=Ae({externalError:k,loadingText:M,externalReady:h,flag:T,targets:y});console.error(` \u26A0 wait ready timed out after ${r}ms \u2014 ${I} (nodes: ${g}, targets: ${y}, errors: ${_})`),process.exit(1)}async function zt(e){let{bridge:c,args:n,positional:l,inspectUsage:m}=e,r=l[1];r||(console.error(m("wait selector","<testid> [--max-ms 5000] [--gone]")),process.exit(1));let g=n.indexOf("--max-ms"),y=g>=0&&n[g+1]?Math.max(100,Number(n[g+1])):5e3,T=n.includes("--gone"),{found:M,node:h,elapsed:k}=await rt(c,r,y,{gone:T});if(T){M?console.log(` #${r} gone after ${k}ms`):(console.error(` \u26A0 wait selector #${r} --gone timed out after ${k??y}ms (still present)`),process.exit(1));return}if(M&&h){let _=h.absolutePosition?`@(${Math.round(h.absolutePosition.x)},${Math.round(h.absolutePosition.y)})`:"",I=h.layout?`${Math.round(h.layout.width)}x${Math.round(h.layout.height)}`:"?x?";console.log(` found #${r} in ${k}ms ${I} ${_}`)}else console.error(` \u26A0 wait selector #${r} timed out after ${k??y}ms`),process.exit(1)}function to(e){return e==null?"\u2014":e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}K`:`${(e/1024/1024).toFixed(1)}M`}function oo(e){return e==null?" \u2026":e<1e3?`${e}ms`.padStart(5):`${(e/1e3).toFixed(2)}s`.padStart(5)}function Yt(){process.stderr.write(` the sim is not responding. recover it with:
239
+ })()`});(!B||!B.ok)&&(console.error(` could not query timeline: ${B&&"error"in B?B.error:"unknown"}`),process.exit(1));let D=B.result.events??[];for(let V of D)if(_o(V,{filter:T,equals:M})){let te=Date.now()-_;console.log(k?JSON.stringify({found:!0,elapsedMs:te,event:V}):` ${r} event after ${te}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`);return}B.result.watermark&&B.result.watermark>j&&(j=B.result.watermark),await new Promise(V=>setTimeout(V,R))}let d=Date.now()-_;k?console.log(JSON.stringify({found:!1,elapsedMs:d,kind:r,filter:T,equals:M})):console.error(` \u26A0 wait event ${r} timed out after ${d}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`),process.exit(1)}async function Ut(e){let{bridge:c,args:n}=e,l=n.includes("--strict"),m=be(n,3e3),{elapsed:r,settled:g}=await ee({bridge:c,maxMs:m,strict:l});g?console.log(` idle in ${r}ms`):(console.error(` \u26A0 wait idle timed out after ${r}ms (may still be animating)`),process.exit(1))}async function Kt(e){let{bridge:c,args:n}=e,l=be(n,2e4),{ready:m,elapsedMs:r,nodes:g,targets:y,flag:T,loadingText:M,externalReady:h,externalError:k,errors:_}=await nt(c,l,{onProgress(R){console.error(` still waiting after ${R.elapsedMs}ms \u2014 ${Ae(R)} (nodes: ${R.nodes}, targets: ${R.targets}, errors: ${R.errors})`)}});if(m){let R=l-r,j=Math.max(100,Math.min(1e4,R)),d=await ee({bridge:c,maxMs:j,pollMs:32,stablePolls:2});d.settled||(console.error(` \u26A0 wait ready timed out after ${r+d.elapsed}ms \u2014 app mounted but did not settle (nodes: ${g}, targets: ${y})`),process.exit(1)),console.log(` ready in ${r+d.elapsed}ms: ${g} nodes, ${y} targets`);return}let I=Ae({externalError:k,loadingText:M,externalReady:h,flag:T,targets:y});console.error(` \u26A0 wait ready timed out after ${r}ms \u2014 ${I} (nodes: ${g}, targets: ${y}, errors: ${_})`),process.exit(1)}async function zt(e){let{bridge:c,args:n,positional:l,inspectUsage:m}=e,r=l[1];r||(console.error(m("wait selector","<testid> [--max-ms 5000] [--gone]")),process.exit(1));let g=n.indexOf("--max-ms"),y=g>=0&&n[g+1]?Math.max(100,Number(n[g+1])):5e3,T=n.includes("--gone"),{found:M,node:h,elapsed:k}=await rt(c,r,y,{gone:T});if(T){M?console.log(` #${r} gone after ${k}ms`):(console.error(` \u26A0 wait selector #${r} --gone timed out after ${k??y}ms (still present)`),process.exit(1));return}if(M&&h){let _=h.absolutePosition?`@(${Math.round(h.absolutePosition.x)},${Math.round(h.absolutePosition.y)})`:"",I=h.layout?`${Math.round(h.layout.width)}x${Math.round(h.layout.height)}`:"?x?";console.log(` found #${r} in ${k}ms ${I} ${_}`)}else console.error(` \u26A0 wait selector #${r} timed out after ${k??y}ms`),process.exit(1)}function to(e){return e==null?"\u2014":e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}K`:`${(e/1024/1024).toFixed(1)}M`}function oo(e){return e==null?" \u2026":e<1e3?`${e}ms`.padStart(5):`${(e/1e3).toFixed(2)}s`.padStart(5)}function Gt(){process.stderr.write(` the sim is not responding. recover it with:
240
240
  sootsim close --sim <id> # force-close the wedged sim
241
241
  sootsim list # confirm it's gone
242
242
  `)}async function Ao(e){try{return await e.send({type:"evaluate",code:"1"},{timeoutMs:3e3}),!0}catch{return!1}}async function Po(e,c){try{let n=await e.send({type:"evaluate",code:`(async () => {
@@ -258,8 +258,8 @@ import{a as G}from"./chunk-IQVOFR7U.js";import{a as wt,b as xt}from"./chunk-NOBE
258
258
  } catch {
259
259
  return []
260
260
  }
261
- })()`});if(!Array.isArray(n)||n.length===0)return;let l=c.toLowerCase(),m=n.map(r=>({id:r,score:Ro(l,r.toLowerCase())})).filter(r=>r.score<l.length+4).sort((r,g)=>r.score-g.score).slice(0,5);if(m.length===0)return;console.error(" similar testIDs:");for(let r of m)console.error(` ${r.id}`)}catch{}}function Ro(e,c){if(c===e)return 0;if(c.includes(e))return 1;if(e.includes(c))return 2;let n=0;for(;n<e.length&&n<c.length&&e[n]===c[n];)n+=1;return Eo(e,c)-n}function Eo(e,c){if(e===c)return 0;if(!e.length)return c.length;if(!c.length)return e.length;let n=new Array(c.length+1),l=new Array(c.length+1);for(let m=0;m<=c.length;m++)n[m]=m;for(let m=1;m<=e.length;m++){l[0]=m;for(let g=1;g<=c.length;g++)l[g]=Math.min(n[g]+1,l[g-1]+1,n[g-1]+(e[m-1]===c[g-1]?0:1));let r=n;n=l,l=r}return n[c.length]}function Do(e){return e.error?"err":e.status==null?" \u2026 ":String(e.status)}function Co(e){return e.externalError?`guest app errored: ${e.externalError}`:e.loadingText?`still showing "${e.loadingText}"`:e.externalReady===!1?"guest app is still loading":e.flag!==!0?"guest app has not emitted sootsim:externalAppReady":e.targets<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing"}function Gt(e){let c=re(e.startTs),n=Do(e).padEnd(3),l=e.method.padEnd(5),m=to(e.size).padStart(6),r=oo(e.durationMs);console.log(` [${c}] ${n} ${l} ${m} ${r} ${e.displayUrl}`),e.error&&console.log(` error: ${e.error}`)}function Bo(e){let c=[["id",e.id],["source",e.source],["kind",e.kind],["method",e.method],["status",e.error?`error: ${e.error}`:`${e.status??"\u2014"} ${e.statusText??""}`.trim()],["url",e.url],["started",re(e.startTs)],["duration",oo(e.durationMs).trim()],["size",to(e.size)],["content-type",e.type??"\u2014"]];for(let[n,l]of c)console.log(` ${n.padEnd(13)} ${l}`)}var jo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Xt="\x1B[0m",Lo="\x1B[2m";function Vt(e,c){let n=re(e.ts),l=e.level.toUpperCase().padEnd(5),m=e.args.join(" ");if(c){let r=jo[e.level];console.log(` ${Lo}[${n}]${Xt} ${r}${l}${Xt} ${m}`)}else console.log(` [${n}] ${l} ${m}`);if(e.stack&&e.level==="error"){let r=e.stack.split(`
262
- `).slice(0,5);for(let g of r)console.log(` ${g.trim()}`)}}var se="__sootsimCliPerf",Jo=120;async function Qt(e,c){let n=e.find((_,I)=>e[I-1]==="--id"),l=e.find((_,I)=>e[I-1]==="--text");if(n||l){let _=await c.send({type:"evaluate",code:wt({id:n,text:l})});if(!_)throw new Error(n?`no node with id "${n}"`:`no node matching text "${l}"`);let{x:I,y:R,w:j,h:d}=_;return{x:I,y:R,w:j,h:d}}let m=e.find((_,I)=>e[I-1]==="--area");if(m){let _=m.split(",").map(z=>Number(z.trim()));if(_.length!==4||_.some(z=>!Number.isFinite(z)))throw new Error(`--area expects x,y,w,h (got "${m}")`);let[I,R,j,d]=_;return{x:I,y:R,w:j,h:d}}let r=_=>{let I=e.find((j,d)=>e[d-1]===_);if(I==null)return null;let R=Number(I);return Number.isFinite(R)?R:null},g=r("--x"),y=r("--y"),T=r("--w"),M=r("--h");if(g!=null||y!=null||T!=null||M!=null)return{x:g??0,y:y??0,w:T??1,h:M??1};let k=e.filter((_,I)=>I>0&&!_.startsWith("-")&&e[I-1]!=="--output"&&e[I-1]!=="--area"&&e[I-1]!=="--id"&&e[I-1]!=="--text"&&e[I-1]!=="--x"&&e[I-1]!=="--y"&&e[I-1]!=="--w"&&e[I-1]!=="--h").map(Number).filter(_=>Number.isFinite(_));if(k.length>=2){let[_,I,R=1,j=1]=k;return{x:_,y:I,w:R,h:j}}return null}function Be(e){let c={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let n of e)n<8?c["<8"]++:n<12?c["8-12"]++:n<16?c["12-16"]++:n<20?c["16-20"]++:n<33?c["20-33"]++:c[">33"]++;console.log(" histogram:");for(let[n,l]of Object.entries(c)){let m="\u2588".repeat(Math.ceil(l/e.length*40));console.log(` ${n.padEnd(6)} ${m} ${l}`)}}async function Te(e,c,n){let l=Date.now()+c,m=await le(e,c);for(;;){if(n(m))return{settled:!0,state:m};if(Date.now()>=l)return{settled:!1,state:m};await Z(16),m=await le(e)}}async function Le(e){return e.send({type:"evaluate",code:`(async () => {
261
+ })()`});if(!Array.isArray(n)||n.length===0)return;let l=c.toLowerCase(),m=n.map(r=>({id:r,score:Ro(l,r.toLowerCase())})).filter(r=>r.score<l.length+4).sort((r,g)=>r.score-g.score).slice(0,5);if(m.length===0)return;console.error(" similar testIDs:");for(let r of m)console.error(` ${r.id}`)}catch{}}function Ro(e,c){if(c===e)return 0;if(c.includes(e))return 1;if(e.includes(c))return 2;let n=0;for(;n<e.length&&n<c.length&&e[n]===c[n];)n+=1;return Eo(e,c)-n}function Eo(e,c){if(e===c)return 0;if(!e.length)return c.length;if(!c.length)return e.length;let n=new Array(c.length+1),l=new Array(c.length+1);for(let m=0;m<=c.length;m++)n[m]=m;for(let m=1;m<=e.length;m++){l[0]=m;for(let g=1;g<=c.length;g++)l[g]=Math.min(n[g]+1,l[g-1]+1,n[g-1]+(e[m-1]===c[g-1]?0:1));let r=n;n=l,l=r}return n[c.length]}function Do(e){return e.error?"err":e.status==null?" \u2026 ":String(e.status)}function Co(e){return e.externalError?`guest app errored: ${e.externalError}`:e.loadingText?`still showing "${e.loadingText}"`:e.externalReady===!1?"guest app is still loading":e.flag!==!0?"guest app has not emitted sootsim:externalAppReady":e.targets<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing"}function Yt(e){let c=re(e.startTs),n=Do(e).padEnd(3),l=e.method.padEnd(5),m=to(e.size).padStart(6),r=oo(e.durationMs);console.log(` [${c}] ${n} ${l} ${m} ${r} ${e.displayUrl}`),e.error&&console.log(` error: ${e.error}`)}function Bo(e){let c=[["id",e.id],["source",e.source],["kind",e.kind],["method",e.method],["status",e.error?`error: ${e.error}`:`${e.status??"\u2014"} ${e.statusText??""}`.trim()],["url",e.url],["started",re(e.startTs)],["duration",oo(e.durationMs).trim()],["size",to(e.size)],["content-type",e.type??"\u2014"]];for(let[n,l]of c)console.log(` ${n.padEnd(13)} ${l}`)}var jo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Xt="\x1B[0m",Jo="\x1B[2m";function Vt(e,c){let n=re(e.ts),l=e.level.toUpperCase().padEnd(5),m=e.args.join(" ");if(c){let r=jo[e.level];console.log(` ${Jo}[${n}]${Xt} ${r}${l}${Xt} ${m}`)}else console.log(` [${n}] ${l} ${m}`);if(e.stack&&e.level==="error"){let r=e.stack.split(`
262
+ `).slice(0,5);for(let g of r)console.log(` ${g.trim()}`)}}var se="__sootsimCliPerf",Lo=120;async function Qt(e,c){let n=e.find((_,I)=>e[I-1]==="--id"),l=e.find((_,I)=>e[I-1]==="--text");if(n||l){let _=await c.send({type:"evaluate",code:wt({id:n,text:l})});if(!_)throw new Error(n?`no node with id "${n}"`:`no node matching text "${l}"`);let{x:I,y:R,w:j,h:d}=_;return{x:I,y:R,w:j,h:d}}let m=e.find((_,I)=>e[I-1]==="--area");if(m){let _=m.split(",").map(z=>Number(z.trim()));if(_.length!==4||_.some(z=>!Number.isFinite(z)))throw new Error(`--area expects x,y,w,h (got "${m}")`);let[I,R,j,d]=_;return{x:I,y:R,w:j,h:d}}let r=_=>{let I=e.find((j,d)=>e[d-1]===_);if(I==null)return null;let R=Number(I);return Number.isFinite(R)?R:null},g=r("--x"),y=r("--y"),T=r("--w"),M=r("--h");if(g!=null||y!=null||T!=null||M!=null)return{x:g??0,y:y??0,w:T??1,h:M??1};let k=e.filter((_,I)=>I>0&&!_.startsWith("-")&&e[I-1]!=="--output"&&e[I-1]!=="--area"&&e[I-1]!=="--id"&&e[I-1]!=="--text"&&e[I-1]!=="--x"&&e[I-1]!=="--y"&&e[I-1]!=="--w"&&e[I-1]!=="--h").map(Number).filter(_=>Number.isFinite(_));if(k.length>=2){let[_,I,R=1,j=1]=k;return{x:_,y:I,w:R,h:j}}return null}function Be(e){let c={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let n of e)n<8?c["<8"]++:n<12?c["8-12"]++:n<16?c["12-16"]++:n<20?c["16-20"]++:n<33?c["20-33"]++:c[">33"]++;console.log(" histogram:");for(let[n,l]of Object.entries(c)){let m="\u2588".repeat(Math.ceil(l/e.length*40));console.log(` ${n.padEnd(6)} ${m} ${l}`)}}async function Te(e,c,n){let l=Date.now()+c,m=await le(e,c);for(;;){if(n(m))return{settled:!0,state:m};if(Date.now()>=l)return{settled:!1,state:m};await Z(16),m=await le(e)}}async function Je(e){return e.send({type:"evaluate",code:`(async () => {
263
263
  const kb = window.__sootsimKeyboard
264
264
  const test = window.__sootsimTest
265
265
  if (!kb) return { error: 'keyboard bridge not available' }
@@ -291,7 +291,7 @@ import{a as G}from"./chunk-IQVOFR7U.js";import{a as wt,b as xt}from"./chunk-NOBE
291
291
  frame: runtimeSnapshot?.keyboard?.frame ?? null,
292
292
  focusedRect: runtimeSnapshot?.focused?.rect ?? null,
293
293
  }
294
- })()`})}async function Wo(e,c=600){let n=Date.now()+c;for(;Date.now()<=n;){let l=await Le(e);if(l.visible)return l;await Z(30)}return Le(e)}async function Me(e,c){let n=await Le(e);if(n.visible)return n;console.error(` ${c} requires the iOS keyboard to be visible. focus an input first with sootsim do tap-id/tap-text or sootsim do type-into.`),process.exit(1)}async function Zt(e,c,n){return c==="appearance"?e.send({type:"evaluate",code:`(async () => {
294
+ })()`})}async function Wo(e,c=600){let n=Date.now()+c;for(;Date.now()<=n;){let l=await Je(e);if(l.visible)return l;await Z(30)}return Je(e)}async function Me(e,c){let n=await Je(e);if(n.visible)return n;console.error(` ${c} requires the iOS keyboard to be visible. focus an input first with sootsim do tap-id/tap-text or sootsim do type-into.`),process.exit(1)}async function Zt(e,c,n){return c==="appearance"?e.send({type:"evaluate",code:`(async () => {
295
295
  const requested = ${JSON.stringify(n??"toggle")}
296
296
  const rootBg = (document.documentElement?.style?.background || '').toLowerCase()
297
297
  const inferredCurrent = rootBg.includes('33') ? 'dark' : 'light'
@@ -308,20 +308,20 @@ import{a as G}from"./chunk-IQVOFR7U.js";import{a as wt,b as xt}from"./chunk-NOBE
308
308
  })()`}):e.send({type:"evaluate",code:`(async () => {
309
309
  window.dispatchEvent(new CustomEvent(${JSON.stringify(c==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
310
310
  return { ok: true, action: ${JSON.stringify(c)} }
311
- })()`})}function qo(e){let c={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(c[e])return c[e];let n=e.match(/^Digit([0-9])$/);if(n)return n[1];let l=e.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function Ho(e){if(typeof e!="string")return null;let c=e.replace(/\s+/g," ").trim();return c?c.slice(0,80):null}function so(...e){for(let c of e){if(typeof c!="string")continue;let n=c.trim();if(n)return n}return null}function Uo(e){let c=e.indexOf("--node-id");if(c<0)return null;let n=e[c+1];if(!n)return null;let l=Number(n);return Number.isInteger(l)&&l>0?l:null}async function L(e,c,n){let l=$e({source:e,step:c,summary:n});l.active&&(l.replaced?console.error(` draft: replaced unkept action "${l.replaced.summary}" \u2014 \`flow keep\` commits one action at a time`):console.error(" draft: action pending \u2014 `sootsim flow keep` to commit"))}function eo(e,c,n){if(!n||n.hit===!1)return null;let l=so(n.responderTestID,n.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let m=Ho(n.text);return m?{step:{tapOn:m},summary:`tap "${m}"`}:{step:{tapAtCoords:{x:e,y:c}},summary:`tap @${Math.round(e)},${Math.round(c)}`}}function je(e,c,n){let l=so(c?.testID,c?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:n==="id"?{step:{tapOn:{id:e}},summary:`tap #${e}`}:{step:{tapOn:e},summary:`tap "${e}"`}}async function Rn(e,c){let n=e[0]==="get"||e[0]==="do"||e[0]==="debug"||e[0]==="wait"?e[0]:null,l=n?e.slice(1):e,m=He(l,{port:c.port,commandTimeoutMs:c.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--slow","--tail","-f","--interactive-targets","--actions","--internal","--compact","--no-xy","--no-clipped","--include-occluded"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--node-id","--max-ms","--filter","--limit","--level","--threshold","--equals","--since","--testid-like","--only","--subtree"]}),r=m.positional,g=r[0],y=n==="get"||n==="do"||n==="debug"||n==="wait"?n:"inspect",T=typeof l[0]=="string"&&Je.has(l[0]),M=T?l[0]:null,h=o=>T&&o===l[0]?`sootsim ${o}`:`sootsim ${y} ${o}`,k=(o,t)=>` usage: ${h(o)}${t?` ${t}`:""}`;if(!g||e.includes("--help")||e.includes("-h")){let o={bridgePort:7668,defaultShellUrl:We};if(y==="do"||y==="get"||y==="debug"||y==="wait"){let i=Ie(y,o);i&&(console.log(`${i}
311
+ })()`})}function qo(e){let c={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(c[e])return c[e];let n=e.match(/^Digit([0-9])$/);if(n)return n[1];let l=e.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function Ho(e){if(typeof e!="string")return null;let c=e.replace(/\s+/g," ").trim();return c?c.slice(0,80):null}function so(...e){for(let c of e){if(typeof c!="string")continue;let n=c.trim();if(n)return n}return null}function Uo(e){let c=e.indexOf("--node-id");if(c<0)return null;let n=e[c+1];if(!n)return null;let l=Number(n);return Number.isInteger(l)&&l>0?l:null}async function J(e,c,n){let l=$e({source:e,step:c,summary:n});l.active&&(l.replaced?console.error(` draft: replaced unkept action "${l.replaced.summary}" \u2014 \`flow keep\` commits one action at a time`):console.error(" draft: action pending \u2014 `sootsim flow keep` to commit"))}function eo(e,c,n){if(!n||n.hit===!1)return null;let l=so(n.responderTestID,n.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let m=Ho(n.text);return m?{step:{tapOn:m},summary:`tap "${m}"`}:{step:{tapAtCoords:{x:e,y:c}},summary:`tap @${Math.round(e)},${Math.round(c)}`}}function je(e,c,n){let l=so(c?.testID,c?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:n==="id"?{step:{tapOn:{id:e}},summary:`tap #${e}`}:{step:{tapOn:e},summary:`tap "${e}"`}}async function Rn(e,c){let n=e[0]==="get"||e[0]==="do"||e[0]==="debug"||e[0]==="wait"?e[0]:null,l=n?e.slice(1):e,m=He(l,{port:c.port,commandTimeoutMs:c.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--slow","--tail","-f","--interactive-targets","--actions","--internal","--compact","--no-xy","--no-clipped","--include-occluded"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--node-id","--max-ms","--filter","--limit","--level","--threshold","--equals","--since","--testid-like","--only","--subtree"]}),r=m.positional,g=r[0],y=n==="get"||n==="do"||n==="debug"||n==="wait"?n:"inspect",T=typeof l[0]=="string"&&Le.has(l[0]),M=T?l[0]:null,h=o=>T&&o===l[0]?`sootsim ${o}`:`sootsim ${y} ${o}`,k=(o,t)=>` usage: ${h(o)}${t?` ${t}`:""}`;if(!g||e.includes("--help")||e.includes("-h")){let o={bridgePort:7668,defaultShellUrl:We};if(y==="do"||y==="get"||y==="debug"||y==="wait"){let i=Ie(y,o);i&&(console.log(`${i}
312
312
  `),process.exit(0))}if(M==="shell"){let i=Ne("shell",o);i&&(console.log(`${i}
313
313
  `),process.exit(0))}let t=Ne("inspect",o),s=["do","get","debug","wait"].map(i=>Ie(i,o)).filter(i=>i!=null).join(`
314
314
 
315
315
  `);console.log(`${t??""}
316
316
 
317
317
  ${s}
318
- `),process.exit(0)}let _=m.wsPort,I=m.simId,R=m.simIdSource,j=m.commandTimeoutMs;if(g==="list"&&l.some(o=>o==="--drivers"||o==="-D")){let{buildDriverListRows:o}=await import("./drivers-5B4IZBF3.js"),t=o();console.log(` available drivers (${t.length}):
318
+ `),process.exit(0)}let _=m.wsPort,I=m.simId,R=m.simIdSource,j=m.commandTimeoutMs;if(g==="list"&&l.some(o=>o==="--drivers"||o==="-D")){let{buildDriverListRows:o}=await import("./drivers-GM6GJG7Q.js"),t=o();console.log(` available drivers (${t.length}):
319
319
  `);let s=Math.max(...t.map(a=>a.id.length),6),i=Math.max(...t.map(a=>a.kind.length),4);for(let a of t){let u=a.available?"\u2713":"\u2717",p=a.id.padEnd(s),b=a.kind.padEnd(i);console.log(` ${u} ${p} ${b} ${a.description}`),a.available&&a.detail?console.log(` ${a.detail}`):!a.available&&a.reason&&console.log(` unavailable: ${a.reason}`)}return}let d=Ue(m),z=I||"default",B=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),D=200;function V(o){let t=o.replace(/\s+/g," ").trim();if(!t)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(t)){let i=/<title[^>]*>([^<]+)<\/title>/i.exec(o)?.[1]?.trim(),a=/<body[^>]*>([\s\S]*?)<\//i.exec(o)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=i||a||"html error page";return`<html ${o.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return t.length<=D?t:`${t.slice(0,D)}\u2026 (+${t.length-D} more bytes)`}function te(o){let t=o.displayUrl||o.url;return o.status!=null?`${o.method} ${t} -> ${o.status}${o.statusText?` ${o.statusText}`:""}`:o.error?`${o.method} ${t} -> ${o.error}`:`${o.method} ${t}`}async function S(o){let t=ue()?5e3:1500;try{let{settled:s,elapsed:i}=await ee({bridge:o,maxMs:t,pollMs:32,stablePolls:2});s||process.stderr.write(` \u26A0 auto-wait timed out after ${i??t}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
320
- `)}catch{}}function N(o,t){console.error(` tap failed: ${o} stayed visible but did not receive a hittable press after ${t.attempts} attempt${t.attempts===1?"":"s"}`),t.result&&console.error(` last result: ${JSON.stringify(t.result)}`)}async function J(){try{return await d.send({type:"evaluate",code:`(() => ({
320
+ `)}catch{}}function N(o,t){console.error(` tap failed: ${o} stayed visible but did not receive a hittable press after ${t.attempts} attempt${t.attempts===1?"":"s"}`),t.result&&console.error(` last result: ${JSON.stringify(t.result)}`)}async function L(){try{return await d.send({type:"evaluate",code:`(() => ({
321
321
  console: ${xe},
322
322
  requests: window.__sootsimTest?.getRequestCounts?.() || null,
323
- }))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function W(o={}){let t=o.counts!==void 0?o.counts:await Y(d,"getRequestCounts");if(!t||typeof t!="object")return;let s=Math.max(0,Number(t.failed)||0);if(s===0||!o.includeTail&&!Ee("requests",z,String(s))||(console.log(`
324
- network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${h("requests")} 5`),!o.includeTail))return;let i=await Y(d,"getFailedRequests",5);if(!(!Array.isArray(i)||i.length===0)){console.log(`
323
+ }))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function W(o={}){let t=o.counts!==void 0?o.counts:await G(d,"getRequestCounts");if(!t||typeof t!="object")return;let s=Math.max(0,Number(t.failed)||0);if(s===0||!o.includeTail&&!Ee("requests",z,String(s))||(console.log(`
324
+ network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${h("requests")} 5`),!o.includeTail))return;let i=await G(d,"getFailedRequests",5);if(!(!Array.isArray(i)||i.length===0)){console.log(`
325
325
  recent failed requests:
326
326
  `);for(let a of i){let u=re(a.timestamp);console.log(` [${u}] ${te(a)}`),a.responseBody?console.log(` ${V(a.responseBody)}`):a.error&&console.log(` ${a.error}`)}}}async function X(o={}){let t=o.counts!==void 0?o.counts:await d.send({type:"evaluate",code:xe});if(!t||typeof t!="object")return;let s=t,i=Math.max(0,Number(s.errors)||0),a=Math.max(0,Number(s.warnings)||0);if(i===0&&a===0||!o.includeTail&&!Ee("console",z,`${i}:${a}`))return;let u=[];if(i>0&&u.push(`${i} console error${i===1?"":"s"}`),a>0&&u.push(`${a} console warning${a===1?"":"s"}`),console.log(`
327
327
  console: ${u.join(", ")}`),console.log(` inspect: ${h("errors")} 5`),a>0&&console.log(` inspect: ${h("warnings")} 5`),!o.includeTail||i===0)return;let p=await we(d,5);if(!(!Array.isArray(p)||p.length===0)){console.log(`
@@ -343,7 +343,7 @@ ${s}
343
343
  }
344
344
  return summary ? { summary, consoleSplit } : null
345
345
  })()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let i=s.summary.byKind??{},a=[],u=new Set;for(let p of Q){let b=i[p];if(b)if(u.add(p),p==="console"&&s.consoleSplit){let{error:f,warn:x}=s.consoleSplit;f>0&&a.push(`${f} error${f===1?"":"s"}`),x>0&&a.push(`${x} warning${x===1?"":"s"}`)}else a.push(`${b} ${p}${b===1?"":"s"}`)}for(let[p,b]of Object.entries(i))!u.has(p)&&b&&a.push(`${b} ${p}${b===1?"":"s"}`);if(a.length!==0&&(console.log(`
346
- since last: ${a.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await Fe(o,"SootSim.bridges.timeline.cursorAdvance",t,s.summary.lastAt)}catch{}}let me=new Set(["tap","double-tap","tap-text","tap-id","type","type-into","key","key-sequence","keycode","drag","swipe","long-press","touch","gesture","pinch","scroll","shell"]),C=new Set(["a11y","capture","count","double-tap","drag","find","gesture","layout","long-press","node","pinch","sample-color","scroll","screenshot","swipe","tap","tap-id","tap-text","touch","tree","type-into"]),ae=(e.includes("--verbose")||e.includes("-v"))&&!e.includes("--json");y==="do"&&g==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),me.has(g)&&await Ke(d),C.has(g)&&await ce(d,{verbose:ae});try{switch(g){case"list":{await Et({bridge:d,simId:I,args:l});break}case"tree":{await Lt({bridge:d,args:l,positional:r});break}case"a11y":{let o=await ot(d);if(!Array.isArray(o)||o.length===0){console.log(" no accessible nodes found");break}if(e.includes("--json"))console.log(JSON.stringify(o,null,2));else{console.log(` accessibility tree (${o.length} nodes):
346
+ since last: ${a.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await Fe(o,"SootSim.bridges.timeline.cursorAdvance",t,s.summary.lastAt)}catch{}}let me=new Set(["tap","double-tap","tap-text","tap-id","type","type-into","key","key-sequence","keycode","drag","swipe","long-press","touch","gesture","pinch","scroll","shell"]),C=new Set(["a11y","capture","count","double-tap","drag","find","gesture","layout","long-press","node","pinch","sample-color","scroll","screenshot","swipe","tap","tap-id","tap-text","touch","tree","type-into"]),ae=(e.includes("--verbose")||e.includes("-v"))&&!e.includes("--json");y==="do"&&g==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),me.has(g)&&await Ke(d),C.has(g)&&await ce(d,{verbose:ae});try{switch(g){case"list":{await Et({bridge:d,simId:I,args:l});break}case"tree":{await Jt({bridge:d,args:l,positional:r});break}case"a11y":{let o=await ot(d);if(!Array.isArray(o)||o.length===0){console.log(" no accessible nodes found");break}if(e.includes("--json"))console.log(JSON.stringify(o,null,2));else{console.log(` accessibility tree (${o.length} nodes):
347
347
  `);for(let t of o){let s=[];if(s.push(`[${t.role}]`),t.label){let i=t.label.length>50?t.label.slice(0,47)+"...":t.label;s.push(`"${i}"`)}if(t.hint&&s.push(`(hint: "${t.hint}")`),t.testID&&s.push(`#${t.testID}`),t.state){let i=[];t.state.disabled&&i.push("disabled"),t.state.selected&&i.push("selected"),t.state.checked===!0&&i.push("checked"),t.state.checked==="mixed"&&i.push("mixed"),t.state.busy&&i.push("busy"),t.state.expanded===!0&&i.push("expanded"),t.state.expanded===!1&&i.push("collapsed"),i.length&&s.push(`{${i.join(", ")}}`)}t.position&&s.push(`@(${t.position.x},${t.position.y})`),t.size&&s.push(`${t.size.w}x${t.size.h}`),console.log(" "+s.join(" "))}}break}case"find":{await At({bridge:d,args:e,effectiveArgs:l,positional:r,inspectUsage:k});break}case"count":{await _t(d,{args:l});break}case"keyboard":{await Rt(d,{json:e.includes("--json")});break}case"screens":{await Ct(d,{json:e.includes("--json")});break}case"memory":{await Dt(d,{args:l});break}case"wait":{await Wt({wsPort:_,commandTimeoutMs:j,simId:I,simIdSource:R,positional:r});break}case"sleep":{await jt({positional:r,inspectUsage:k});break}case"settle":{await Bt({bridge:d,args:e,positional:r});break}case"ready":{await Kt({bridge:d,args:e});break}case"idle":{await Ut({bridge:d,args:e,positional:r});break}case"selector":{await zt({bridge:d,args:e,positional:r,inspectUsage:k});break}case"event":{await Ht({bridge:d,args:e,positional:r,inspectUsage:k});break}case"layout":{let o=r[1];if(!o){await Pt({bridge:d,args:l});break}let t=await d.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(o)}))()`});console.log(JSON.stringify(t,null,2));break}case"capture":case"screenshot":{let t=e.find((b,f)=>e[f-1]==="--output")||"/tmp/sootsim-inspect.png",s=await Qt(e,d),i={type:"screenshot"};s&&(i.crop=s);let u=(await d.send(i)).replace(/^data:image\/png;base64,/,"");s&&console.log(` area: x=${s.x} y=${s.y} w=${s.w} h=${s.h}`),(await import("fs")).writeFileSync(t,Buffer.from(u,"base64")),console.log(` saved: ${t}`);break}case"sample-color":{let o=await Qt(e,d);o||(console.error(k("sample-color","<x> <y> [w] [h] | --id <testID> | --text <text>")),console.error(" samples an averaged color from the canvas. coords are logical sootsim units."),process.exit(1));let t=await d.send({type:"evaluate",code:xt(o)});if(e.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:i,b:a,a:u,hex:p,samples:b}=t,f=o.w===1&&o.h===1?`@(${o.x},${o.y})`:`@(${o.x},${o.y}) ${o.w}x${o.h}`;console.log(` ${p} rgba(${s}, ${i}, ${a}, ${u}) ${f} ${b} samples`)}break}case"node":{let o=r[1];o||(console.error(k("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let t=await d.send({type:"evaluate",code:`(async () => {
348
348
  const t = window.__sootsimTest
349
349
  const q = ${JSON.stringify(o)}
@@ -400,17 +400,17 @@ ${s}
400
400
  transform,
401
401
  parentChain,
402
402
  }
403
- })()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let o=Number(r[1]),t=Number(r[2]),s=ye(e);if(s){let u=await ge(d,{agent:ue(),textFallback:s.mode==="text"?s.value:void 0,resolve:async()=>{let f=await ve(d,s);return f?{cx:f.x,cy:f.y,match:{id:s.mode==="testid"?s.value:f.id??null,testID:s.mode==="testid"?s.value:f.testID??null,text:s.mode==="text"?s.value:f.text??null,type:f.type??null},target:{id:f.id??null,testID:f.testID??null,text:f.text??null,type:f.type??null}}:null}}),p=u.payload;(!p||typeof p.cx!="number")&&(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),de(u.result)||(N(`${s.mode} "${s.value}"`,u),process.exit(1));let b=eo(p.cx,p.cy,u.result);b&&await L("inspect tap",b.step,b.summary),console.log(JSON.stringify({...u.attempts>1?{attempts:u.attempts}:{},...u.result},null,2));break}(!Number.isFinite(o)||!Number.isFinite(t))&&(console.error(k("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let i=await Mt(d,o,t),a=eo(o,t,i);a&&await L("inspect tap",a.step,a.summary),console.log(JSON.stringify(i,null,2));break}case"drag":case"swipe":{let o=Number(r[1]),t=Number(r[2]),s=Number(r[3]),i=Number(r[4]),a=g==="swipe"?10:12,u=g==="swipe"?8:16,p=r[5]?Number(r[5]):a,b=r[6]?Number(r[6]):u;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(i)||!Number.isFinite(p)||!Number.isFinite(b))&&(console.error(k(g,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await d.send({type:"evaluate",code:`(async () => {
403
+ })()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let o=Number(r[1]),t=Number(r[2]),s=ye(e);if(s){let u=await ge(d,{agent:ue(),textFallback:s.mode==="text"?s.value:void 0,resolve:async()=>{let f=await ve(d,s);return f?{cx:f.x,cy:f.y,match:{id:s.mode==="testid"?s.value:f.id??null,testID:s.mode==="testid"?s.value:f.testID??null,text:s.mode==="text"?s.value:f.text??null,type:f.type??null},target:{id:f.id??null,testID:f.testID??null,text:f.text??null,type:f.type??null}}:null}}),p=u.payload;(!p||typeof p.cx!="number")&&(console.error(` not found: ${s.value}`),s.mode==="testid"&&Y("wait-selector-for-missing-testid",s.value),process.exit(1)),de(u.result)||(N(`${s.mode} "${s.value}"`,u),process.exit(1));let b=eo(p.cx,p.cy,u.result);b&&await J("inspect tap",b.step,b.summary),console.log(JSON.stringify({...u.attempts>1?{attempts:u.attempts}:{},...u.result},null,2));break}(!Number.isFinite(o)||!Number.isFinite(t))&&(console.error(k("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let i=await Mt(d,o,t),a=eo(o,t,i);a&&await J("inspect tap",a.step,a.summary),console.log(JSON.stringify(i,null,2));break}case"drag":case"swipe":{let o=Number(r[1]),t=Number(r[2]),s=Number(r[3]),i=Number(r[4]),a=g==="swipe"?10:12,u=g==="swipe"?8:16,p=r[5]?Number(r[5]):a,b=r[6]?Number(r[6]):u;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(i)||!Number.isFinite(p)||!Number.isFinite(b))&&(console.error(k(g,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await d.send({type:"evaluate",code:`(async () => {
404
404
  const interact = window.__sootsimInteract
405
405
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
406
406
  const value = await interact.drag(${o}, ${t}, ${s}, ${i}, ${Math.max(1,Math.round(p))}, ${Math.max(0,Math.round(b))})
407
407
  return { ok: !!value, value }
408
- })()`});if(f?.ok){let x=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,b)));await L(`inspect ${g}`,{swipe:{start:`${o}, ${t}`,end:`${s}, ${i}`,duration:x}},`${g} ${o},${t} -> ${s},${i}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let o=Number(r[1]),t=Number(r[2]),s=Number(r[3]),i=Number(r[4]),a=Number(r[5]),u=Number(r[6]),p=Number(r[7]),b=Number(r[8]),f=r[9]?Number(r[9]):12,x=r[10]?Number(r[10]):16;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(i)||!Number.isFinite(a)||!Number.isFinite(u)||!Number.isFinite(p)||!Number.isFinite(b)||!Number.isFinite(f)||!Number.isFinite(x))&&(console.error(k("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let O=await d.send({type:"evaluate",code:`(async () => {
408
+ })()`});if(f?.ok){let x=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,b)));await J(`inspect ${g}`,{swipe:{start:`${o}, ${t}`,end:`${s}, ${i}`,duration:x}},`${g} ${o},${t} -> ${s},${i}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let o=Number(r[1]),t=Number(r[2]),s=Number(r[3]),i=Number(r[4]),a=Number(r[5]),u=Number(r[6]),p=Number(r[7]),b=Number(r[8]),f=r[9]?Number(r[9]):12,x=r[10]?Number(r[10]):16;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(i)||!Number.isFinite(a)||!Number.isFinite(u)||!Number.isFinite(p)||!Number.isFinite(b)||!Number.isFinite(f)||!Number.isFinite(x))&&(console.error(k("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let O=await d.send({type:"evaluate",code:`(async () => {
409
409
  const interact = window.__sootsimInteract
410
410
  if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
411
411
  const value = await interact.pinch(${o}, ${t}, ${s}, ${i}, ${a}, ${u}, ${p}, ${b}, ${Math.max(1,Math.round(f))}, ${Math.max(0,Math.round(x))})
412
412
  return { ok: !!value, value }
413
- })()`});O?.ok&&await L("inspect pinch",{pinch:{from:[o,t,s,i],to:[a,u,p,b],steps:Math.max(1,Math.round(f)),stepMs:Math.max(0,Math.round(x))}},`pinch (${o},${t}) (${s},${i}) -> (${a},${u}) (${p},${b})`),console.log(JSON.stringify(O,null,2));break}case"tap-text":{let o=r[1];o||(console.error(k("tap-text","<text>")),process.exit(1));let t=K=>{let E=e.indexOf(K);return E>=0&&E+1<e.length?e[E+1]:null},s=K=>e.includes(K),i=t("--nth")??t("--index"),a=i!==null?Number(i):null;a!==null&&!Number.isFinite(a)&&(console.error(` --nth/--index requires an integer, got: ${i}`),process.exit(1));let u=t("--within"),p=t("--role"),b=s("--exact"),f=s("--first"),x=t("--min-y"),O=t("--max-y"),q=t("--min-x"),H=t("--max-x");for(let[K,E]of[["--min-y",x],["--max-y",O],["--min-x",q],["--max-x",H]])E!==null&&!Number.isFinite(Number(E))&&(console.error(` ${K} requires a number, got: ${E}`),process.exit(1));let U=e.indexOf("--near"),F=null;if(U>=0){let K=Number(e[U+1]),E=Number(e[U+2]);(!Number.isFinite(K)||!Number.isFinite(E))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),F={x:K,y:E}}let w={exact:b,role:p,within:u,minX:q!==null?Number(q):null,maxX:H!==null?Number(H):null,minY:x!==null?Number(x):null,maxY:O!==null?Number(O):null,near:F,nth:a,first:f},$=await Nt(d,o,w,{agent:ue()}),v=$.payload;if(v?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),v?.ambiguous){let K=v.candidates;console.error(` ambiguous: ${v.total} matches for "${o}"`);for(let E of K){let he=E.abs?`@(${Math.round(E.abs.x)},${Math.round(E.abs.y)})`:"",no=E.layout?` ${E.layout.width}x${E.layout.height}`:"",ro=E.testID?` #${E.testID}`:"",io=E.text?` "${E.text}"`:"",ao=E.ancestorTestIDs.length>0?` within ${E.ancestorTestIDs.slice(0,3).map(lo=>`#${lo}`).join(" > ")}`:"";console.error(` [${E.idx}] <${E.type}>${io}${ro} ${he}${no}${ao}`)}v.total>K.length&&console.error(` ... and ${v.total-K.length} more`),console.error(" pick one:"),console.error(" --nth <index> pick the nth match (top-to-bottom, left-to-right; negatives from end)"),console.error(" --within <testID> narrow to descendants of a node"),console.error(" --min-y / --max-y geometric filter (pixels, absolute)"),console.error(" --min-x / --max-x geometric filter (pixels, absolute)"),console.error(" --near <x> <y> pick the closest match to a point"),console.error(" --exact exact text match (default is substring)"),console.error(" --role <role> narrow to accessibilityRole"),console.error(" --first keep the old pick-first-silently behavior"),process.exit(2)}v?.nthOutOfRange&&(console.error(` not found: nth ${v.nth} of ${v.total} match${v.total===1?"":"es"} for "${o}"`),process.exit(1)),(!v||typeof v.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),de($.result)||(N(`text "${o}"`,$),process.exit(1));let oe=je(o,{id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},"text");await L("inspect tap-text",oe.step,oe.summary),console.log(JSON.stringify({matched:v.match,tapped:{nodeId:v.target?.nodeId??null,id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},...v.strategy&&v.strategy!=="matched-node"?{strategy:v.strategy}:{},...v.total>1||a!==null?{nth:{index:v.idx,total:v.total}}:{},...$.attempts>1?{attempts:$.attempts}:{},result:$.result},null,2));break}case"tap-best":{let o=r[1];o||(console.error(k("tap-best","<query>")),process.exit(1));let t=await Ft(d,o,{agent:ue()}),s=t.payload;s||(console.error(` tap-best: no testID or visible text matched "${o}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1)),"error"in s&&(console.error(` ${s.error}`),process.exit(1)),s.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${o}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1));let i=s.node;de(t.result)||(N(`best "${o}"`,t),process.exit(1));let a=je(o,{id:i.id,testID:i.testID,type:i.type,cx:s.cx,cy:s.cy},s.strategy==="testid"?"id":"text");await L("inspect tap-best",a.step,a.summary),console.log(JSON.stringify({matched:{strategy:s.strategy,nodeId:i.nodeId,id:i.id,testID:i.testID,type:i.type,text:i.text},tapped:{cx:s.cx,cy:s.cy},...t.attempts>1?{attempts:t.attempts}:{},result:t.result},null,2));break}case"tap-id":{let o=r[1];o||(console.error(k("tap-id","<id>")),process.exit(1));let t=await It(d,o,{agent:ue()}),s=t.payload;(!s||typeof s.cx!="number")&&(console.error(` not found: ${o}`),await Po(d,o),process.exit(1)),de(t.result)||(N(`id "${o}"`,t),process.exit(1));let i=je(o,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await L("inspect tap-id",i.step,i.summary),console.log(JSON.stringify({matched:s.match,tapped:{nodeId:s.target?.nodeId??null,id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},...s.strategy&&s.strategy!=="matched-node"?{strategy:s.strategy}:{},...t.attempts>1?{attempts:t.attempts}:{},result:t.result},null,2));break}case"type-into":{let o=r[1],t=r.slice(2).join(" ");(!o||!t)&&(console.error(k("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(o),i=await d.send({type:"evaluate",code:`(async () => {
413
+ })()`});O?.ok&&await J("inspect pinch",{pinch:{from:[o,t,s,i],to:[a,u,p,b],steps:Math.max(1,Math.round(f)),stepMs:Math.max(0,Math.round(x))}},`pinch (${o},${t}) (${s},${i}) -> (${a},${u}) (${p},${b})`),console.log(JSON.stringify(O,null,2));break}case"tap-text":{let o=r[1];o||(console.error(k("tap-text","<text>")),process.exit(1));let t=K=>{let E=e.indexOf(K);return E>=0&&E+1<e.length?e[E+1]:null},s=K=>e.includes(K),i=t("--nth")??t("--index"),a=i!==null?Number(i):null;a!==null&&!Number.isFinite(a)&&(console.error(` --nth/--index requires an integer, got: ${i}`),process.exit(1));let u=t("--within"),p=t("--role"),b=s("--exact"),f=s("--first"),x=t("--min-y"),O=t("--max-y"),q=t("--min-x"),H=t("--max-x");for(let[K,E]of[["--min-y",x],["--max-y",O],["--min-x",q],["--max-x",H]])E!==null&&!Number.isFinite(Number(E))&&(console.error(` ${K} requires a number, got: ${E}`),process.exit(1));let U=e.indexOf("--near"),F=null;if(U>=0){let K=Number(e[U+1]),E=Number(e[U+2]);(!Number.isFinite(K)||!Number.isFinite(E))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),F={x:K,y:E}}let w={exact:b,role:p,within:u,minX:q!==null?Number(q):null,maxX:H!==null?Number(H):null,minY:x!==null?Number(x):null,maxY:O!==null?Number(O):null,near:F,nth:a,first:f},$=await Nt(d,o,w,{agent:ue()}),v=$.payload;if(v?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),v?.ambiguous){let K=v.candidates;console.error(` ambiguous: ${v.total} matches for "${o}"`);for(let E of K){let he=E.abs?`@(${Math.round(E.abs.x)},${Math.round(E.abs.y)})`:"",no=E.layout?` ${E.layout.width}x${E.layout.height}`:"",ro=E.testID?` #${E.testID}`:"",io=E.text?` "${E.text}"`:"",ao=E.ancestorTestIDs.length>0?` within ${E.ancestorTestIDs.slice(0,3).map(lo=>`#${lo}`).join(" > ")}`:"";console.error(` [${E.idx}] <${E.type}>${io}${ro} ${he}${no}${ao}`)}v.total>K.length&&console.error(` ... and ${v.total-K.length} more`),console.error(" pick one:"),console.error(" --nth <index> pick the nth match (top-to-bottom, left-to-right; negatives from end)"),console.error(" --within <testID> narrow to descendants of a node"),console.error(" --min-y / --max-y geometric filter (pixels, absolute)"),console.error(" --min-x / --max-x geometric filter (pixels, absolute)"),console.error(" --near <x> <y> pick the closest match to a point"),console.error(" --exact exact text match (default is substring)"),console.error(" --role <role> narrow to accessibilityRole"),console.error(" --first keep the old pick-first-silently behavior"),process.exit(2)}v?.nthOutOfRange&&(console.error(` not found: nth ${v.nth} of ${v.total} match${v.total===1?"":"es"} for "${o}"`),process.exit(1)),(!v||typeof v.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),de($.result)||(N(`text "${o}"`,$),process.exit(1));let oe=je(o,{id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},"text");await J("inspect tap-text",oe.step,oe.summary),console.log(JSON.stringify({matched:v.match,tapped:{nodeId:v.target?.nodeId??null,id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},...v.strategy&&v.strategy!=="matched-node"?{strategy:v.strategy}:{},...v.total>1||a!==null?{nth:{index:v.idx,total:v.total}}:{},...$.attempts>1?{attempts:$.attempts}:{},result:$.result},null,2));break}case"tap-best":{let o=r[1];o||(console.error(k("tap-best","<query>")),process.exit(1));let t=await Ft(d,o,{agent:ue()}),s=t.payload;s||(console.error(` tap-best: no testID or visible text matched "${o}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1)),"error"in s&&(console.error(` ${s.error}`),process.exit(1)),s.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${o}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1));let i=s.node;de(t.result)||(N(`best "${o}"`,t),process.exit(1));let a=je(o,{id:i.id,testID:i.testID,type:i.type,cx:s.cx,cy:s.cy},s.strategy==="testid"?"id":"text");await J("inspect tap-best",a.step,a.summary),console.log(JSON.stringify({matched:{strategy:s.strategy,nodeId:i.nodeId,id:i.id,testID:i.testID,type:i.type,text:i.text},tapped:{cx:s.cx,cy:s.cy},...t.attempts>1?{attempts:t.attempts}:{},result:t.result},null,2));break}case"tap-id":{let o=r[1];o||(console.error(k("tap-id","<id>")),process.exit(1));let t=await It(d,o,{agent:ue()}),s=t.payload;(!s||typeof s.cx!="number")&&(console.error(` not found: ${o}`),await Po(d,o),process.exit(1)),de(t.result)||(N(`id "${o}"`,t),process.exit(1));let i=je(o,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await J("inspect tap-id",i.step,i.summary),console.log(JSON.stringify({matched:s.match,tapped:{nodeId:s.target?.nodeId??null,id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},...s.strategy&&s.strategy!=="matched-node"?{strategy:s.strategy}:{},...t.attempts>1?{attempts:t.attempts}:{},result:t.result},null,2));break}case"type-into":{let o=r[1],t=r.slice(2).join(" ");(!o||!t)&&(console.error(k("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(o),i=await d.send({type:"evaluate",code:`(async () => {
414
414
  const t = window.__sootsimTest
415
415
  if (!t) return null
416
416
  const n = await (t.findByTestId(${s}) || t.findById(${s}))
@@ -424,7 +424,7 @@ ${s}
424
424
  isTextInput: !!n.isTextInput,
425
425
  placeholder: n.placeholder || null,
426
426
  }
427
- })()`});(!i||typeof i.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),i.isTextInput||console.error(` warning: ${o} is not a text input (isTextInput: false)`);let a=await d.send({type:"tap",x:i.cx,y:i.cy,target:{id:i.id??o,testID:i.testID??o,text:null,type:i.type??null}}),u=await Wo(d);u.visible||(console.error(` keyboard did not open after tapping ${o}`),process.exit(1));let p=u.focusedInput;p&&(p.testID===o||p.id===o||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(o)} but focus is on ${JSON.stringify(p.testID??p.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await d.send({type:"keyboard",action:"type",text:t}),await L("inspect type-into",{tapOn:{id:o},inputText:t},`type-into #${o} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:o,isTextInput:i.isTextInput,keyboardOpened:u.visible??a?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:t},null,2));break}case"type":{let o=r.slice(1).join(" ");o||(console.error(k("type","<text>")),process.exit(1)),await Me(d,"type"),await d.send({type:"keyboard",action:"type",text:o}),await L("inspect type",{inputText:o},`type ${JSON.stringify(o)}`),console.log(` typed: ${JSON.stringify(o)}`);break}case"key":{let o=r[1];o||(console.error(k("key","<name>")),process.exit(1)),await Me(d,"key"),await d.send({type:"keyboard",action:"press",text:o}),await L("inspect key",{pressKey:o},`key ${o}`),console.log(` pressed: ${o}`);break}case"key-sequence":{let o=r.slice(1);o.length===0&&(console.error(k("key-sequence","<key> [<key> ...]")),process.exit(1)),await Me(d,"key-sequence");for(let t of o)await d.send({type:"keyboard",action:"press",text:t});await L("inspect key-sequence",{pressKey:o.join(" ")},`key-sequence ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"keycode":{let o=r.slice(1);o.length===0&&(console.error(k("keycode","<code> [<code> ...]")),process.exit(1));let t=o.map(i=>({code:i,key:qo(i)})),s=t.filter(i=>!i.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(i=>i.code).join(", ")}`),process.exit(1)),await Me(d,"keycode");for(let i of t)await d.send({type:"keyboard",action:"press",text:i.key});await L("inspect keycode",{pressKey:t.map(i=>i.key).join(" ")},`keycode ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"dispatch":{let o=r[1];o||(console.error(k("dispatch","<char>")),process.exit(1)),await d.send({type:"keyboard",action:"dispatchKey",text:o}),await L("inspect dispatch",{dispatchKey:o},`dispatch ${JSON.stringify(o)}`),console.log(` dispatched: ${o}`);break}case"dismiss":{await d.send({type:"keyboard",action:"dismiss"}),await L("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let o=Number(r[1]),t=Number(r[2]),s=ye(e);if(s){let p=await ve(d,s);p||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),o=p.x,t=p.y}let i=r[3]?Number(r[3]):80;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(i))&&(console.error(k("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let a=Math.max(0,Math.round(i)),u=await d.send({type:"evaluate",code:`(async () => {
427
+ })()`});(!i||typeof i.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),i.isTextInput||console.error(` warning: ${o} is not a text input (isTextInput: false)`);let a=await d.send({type:"tap",x:i.cx,y:i.cy,target:{id:i.id??o,testID:i.testID??o,text:null,type:i.type??null}}),u=await Wo(d);u.visible||(console.error(` keyboard did not open after tapping ${o}`),process.exit(1));let p=u.focusedInput;p&&(p.testID===o||p.id===o||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(o)} but focus is on ${JSON.stringify(p.testID??p.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await d.send({type:"keyboard",action:"type",text:t}),await J("inspect type-into",{tapOn:{id:o},inputText:t},`type-into #${o} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:o,isTextInput:i.isTextInput,keyboardOpened:u.visible??a?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:t},null,2));break}case"type":{let o=r.slice(1).join(" ");o||(console.error(k("type","<text>")),process.exit(1)),await Me(d,"type"),await d.send({type:"keyboard",action:"type",text:o}),await J("inspect type",{inputText:o},`type ${JSON.stringify(o)}`),console.log(` typed: ${JSON.stringify(o)}`);break}case"key":{let o=r[1];o||(console.error(k("key","<name>")),process.exit(1)),await Me(d,"key"),await d.send({type:"keyboard",action:"press",text:o}),await J("inspect key",{pressKey:o},`key ${o}`),console.log(` pressed: ${o}`);break}case"key-sequence":{let o=r.slice(1);o.length===0&&(console.error(k("key-sequence","<key> [<key> ...]")),process.exit(1)),await Me(d,"key-sequence");for(let t of o)await d.send({type:"keyboard",action:"press",text:t});await J("inspect key-sequence",{pressKey:o.join(" ")},`key-sequence ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"keycode":{let o=r.slice(1);o.length===0&&(console.error(k("keycode","<code> [<code> ...]")),process.exit(1));let t=o.map(i=>({code:i,key:qo(i)})),s=t.filter(i=>!i.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(i=>i.code).join(", ")}`),process.exit(1)),await Me(d,"keycode");for(let i of t)await d.send({type:"keyboard",action:"press",text:i.key});await J("inspect keycode",{pressKey:t.map(i=>i.key).join(" ")},`keycode ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"dispatch":{let o=r[1];o||(console.error(k("dispatch","<char>")),process.exit(1)),await d.send({type:"keyboard",action:"dispatchKey",text:o}),await J("inspect dispatch",{dispatchKey:o},`dispatch ${JSON.stringify(o)}`),console.log(` dispatched: ${o}`);break}case"dismiss":{await d.send({type:"keyboard",action:"dismiss"}),await J("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let o=Number(r[1]),t=Number(r[2]),s=ye(e);if(s){let p=await ve(d,s);p||(console.error(` not found: ${s.value}`),s.mode==="testid"&&Y("wait-selector-for-missing-testid",s.value),process.exit(1)),o=p.x,t=p.y}let i=r[3]?Number(r[3]):80;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(i))&&(console.error(k("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let a=Math.max(0,Math.round(i)),u=await d.send({type:"evaluate",code:`(async () => {
428
428
  const interact = window.__sootsimInteract
429
429
  if (interact?.doubleTap) {
430
430
  return {
@@ -447,13 +447,13 @@ ${s}
447
447
  first,
448
448
  second,
449
449
  }
450
- })()`});u?.ok&&await L("inspect double-tap",{doubleTapAtCoords:{x:o,y:t,gapMs:a}},`double-tap @${o},${t}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let o=Number(r[1]),t=Number(r[2]),s=ye(e),i=null;if(s){let f=await ve(d,s);f||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),o=f.x,t=f.y,i={id:f.id??null,testID:f.testID??null,text:f.text??null,type:f.type??null}}let a=s?r[1]:r[3],u=a?Number(a):600;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(u))&&(console.error(k("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let p=Math.max(0,Math.round(u)),b=await d.send({type:"longPress",x:o,y:t,durationMs:p,target:i});b?.ok&&await L("inspect long-press",{tapAtCoords:{x:o,y:t}},`long-press @${o},${t}`),console.log(JSON.stringify(b,null,2));break}case"touch":{let o=r[1],t=Number(r[2]),s=Number(r[3]),i=r[4]?Number(r[4]):999,a=o==="down"?"touchDown":o==="move"?"touchMove":o==="up"?"touchUp":o==="cancel"?"touchCancel":null;a||(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),o!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(s))&&(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let u=o==="down"?"tap":o==="move"?"move":null,p=u&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${t}, y: ${s} } }));`:"",b=await d.send({type:"evaluate",code:`(async () => {
450
+ })()`});u?.ok&&await J("inspect double-tap",{doubleTapAtCoords:{x:o,y:t,gapMs:a}},`double-tap @${o},${t}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let o=Number(r[1]),t=Number(r[2]),s=ye(e),i=null;if(s){let f=await ve(d,s);f||(console.error(` not found: ${s.value}`),s.mode==="testid"&&Y("wait-selector-for-missing-testid",s.value),process.exit(1)),o=f.x,t=f.y,i={id:f.id??null,testID:f.testID??null,text:f.text??null,type:f.type??null}}let a=s?r[1]:r[3],u=a?Number(a):600;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(u))&&(console.error(k("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let p=Math.max(0,Math.round(u)),b=await d.send({type:"longPress",x:o,y:t,durationMs:p,target:i});b?.ok&&await J("inspect long-press",{tapAtCoords:{x:o,y:t}},`long-press @${o},${t}`),console.log(JSON.stringify(b,null,2));break}case"touch":{let o=r[1],t=Number(r[2]),s=Number(r[3]),i=r[4]?Number(r[4]):999,a=o==="down"?"touchDown":o==="move"?"touchMove":o==="up"?"touchUp":o==="cancel"?"touchCancel":null;a||(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),o!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(s))&&(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let u=o==="down"?"tap":o==="move"?"move":null,p=u&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${t}, y: ${s} } }));`:"",b=await d.send({type:"evaluate",code:`(async () => {
451
451
  ${p}
452
452
  const interact = window.__sootsimInteract
453
453
  if (!interact?.${a}) return { ok: false, reason: 'no interact.${a}' }
454
454
  const value = ${o==="cancel"?`await interact.${a}(${Math.max(1,Math.round(i))})`:`await interact.${a}(${t}, ${s}, ${Math.max(1,Math.round(i))})`}
455
455
  return { ok: !!value, value }
456
- })()`});b?.ok&&o!=="cancel"&&await L("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${o} @${t},${s}`),console.log(JSON.stringify(b,null,2));break}case"gesture":{let o=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],t=r[1],s=r[2]?Number(r[2]):220;(!t||!Number.isFinite(s))&&(console.error(k("gesture","<preset> [durationMs]")),console.error(` presets: ${o.join(", ")}`),process.exit(1)),o.includes(t)||(console.error(` unknown gesture preset: ${t}`),console.error(` presets: ${o.join(", ")}`),process.exit(1));let i=await d.send({type:"evaluate",code:`(async () => {
456
+ })()`});b?.ok&&o!=="cancel"&&await J("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${o} @${t},${s}`),console.log(JSON.stringify(b,null,2));break}case"gesture":{let o=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],t=r[1],s=r[2]?Number(r[2]):220;(!t||!Number.isFinite(s))&&(console.error(k("gesture","<preset> [durationMs]")),console.error(` presets: ${o.join(", ")}`),process.exit(1)),o.includes(t)||(console.error(` unknown gesture preset: ${t}`),console.error(` presets: ${o.join(", ")}`),process.exit(1));let i=await d.send({type:"evaluate",code:`(async () => {
457
457
  const spec = globalThis.__sootsimDeviceSpec || {}
458
458
  return {
459
459
  width: spec.width || window.innerWidth || 393,
@@ -466,7 +466,7 @@ ${s}
466
466
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
467
467
  const value = await interact.drag(${w}, ${$}, ${v}, ${oe}, ${K}, ${E})
468
468
  return { ok: !!value, value }
469
- })()`});he?.ok&&await L("inspect gesture",{swipe:{start:`${w}, ${$}`,end:`${v}, ${oe}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:w,y:$},to:{x:v,y:oe},result:he},null,2));break}case"scroll":{let o=ye(e),t=Uo(e),s=o?.mode==="testid"?o.value:t==null?r[1]:null,i=o||t!=null?1:2,a=Number(r[i]),u=Number(r[i+1]);(!s&&t==null||!Number.isFinite(a)||!Number.isFinite(u))&&(console.error(k("scroll","<id> <x> <y> | --testid <id> <x> <y> | --node-id <nodeId> <x> <y>")),process.exit(1));let p=await d.send({type:"evaluate",code:`(async () => {
469
+ })()`});he?.ok&&await J("inspect gesture",{swipe:{start:`${w}, ${$}`,end:`${v}, ${oe}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:w,y:$},to:{x:v,y:oe},result:he},null,2));break}case"scroll":{let o=ye(e),t=Uo(e),s=o?.mode==="testid"?o.value:t==null?r[1]:null,i=o||t!=null?1:2,a=Number(r[i]),u=Number(r[i+1]);(!s&&t==null||!Number.isFinite(a)||!Number.isFinite(u))&&(console.error(k("scroll","<id> <x> <y> | --testid <id> <x> <y> | --node-id <nodeId> <x> <y>")),process.exit(1));let p=await d.send({type:"evaluate",code:`(async () => {
470
470
  const t = window.__sootsimTest
471
471
  if (!t) return null
472
472
  const n = ${t!=null?`await t.inspectByNodeId(${JSON.stringify(t)})`:`await t.findByTestId(${JSON.stringify(s)})
@@ -476,7 +476,7 @@ ${s}
476
476
  cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
477
477
  cy: n.absolutePosition.y + (n.layout.height || 0) / 2,
478
478
  }
479
- })()`}),b=await Y(d,"scrollTo",t!=null?{nodeId:t}:s,a,u,!1);if(b?.ok){let f=t!=null?`node ${t}`:`#${s}`;await L("inspect scroll",{scrollTo:{...t!=null?{nodeId:t}:{id:s},x:a,y:u}},`scroll ${f} -> ${a},${u}`)}console.log(JSON.stringify({...b,...p?{at:{x:p.cx,y:p.cy}}:{}},null,2));break}case"state":{let o=r[1];if(n==="get"&&!o){let s=await Y(d,"getRuntimeState"),i=await d.send({type:"evaluate",code:xe});if(s&&typeof s=="object"&&s.diagnostics&&(s.diagnostics.errors=i?.errors??0,s.diagnostics.warnings=i?.warnings??0),s&&typeof s=="object"&&s.shell==null)try{let a=await le(d);a&&(s.shell=a)}catch{}console.log(JSON.stringify(s,null,2));break}if(!o||o==="--help"||o==="-h"){console.log(`
479
+ })()`}),b=await G(d,"scrollTo",t!=null?{nodeId:t}:s,a,u,!1);if(b?.ok){let f=t!=null?`node ${t}`:`#${s}`;await J("inspect scroll",{scrollTo:{...t!=null?{nodeId:t}:{id:s},x:a,y:u}},`scroll ${f} -> ${a},${u}`)}console.log(JSON.stringify({...b,...p?{at:{x:p.cx,y:p.cy}}:{}},null,2));break}case"state":{let o=r[1];if(n==="get"&&!o){let s=await G(d,"getRuntimeState"),i=await d.send({type:"evaluate",code:xe});if(s&&typeof s=="object"&&s.diagnostics&&(s.diagnostics.errors=i?.errors??0,s.diagnostics.warnings=i?.warnings??0),s&&typeof s=="object"&&s.shell==null)try{let a=await le(d);a&&(s.shell=a)}catch{}console.log(JSON.stringify(s,null,2));break}if(!o||o==="--help"||o==="-h"){console.log(`
480
480
  ${h("state")} \u2014 dump raw runtime state
481
481
 
482
482
  subcommands:
@@ -530,7 +530,7 @@ ${s}
530
530
  text: focused.text || null,
531
531
  } : null,
532
532
  }
533
- })()`});break;case"node":{let s=r[2];s||(console.error(` usage: ${h("state")} node <id>`),process.exit(1)),t=await Y(d,"findByTestId",s)||await Y(d,"findById",s);break}case"scroll":{let s=r[2];s||(console.error(` usage: ${h("state")} scroll <id>`),process.exit(1)),t=await Y(d,"getScrollState",s);break}case"scroll-hit":{let s=Number(r[2]),i=Number(r[3]);(!Number.isFinite(s)||!Number.isFinite(i))&&(console.error(` usage: ${h("state")} scroll-hit <x> <y>`),process.exit(1)),t=await Y(d,"getScrollStateAt",s,i);break}case"hit":{let s=Number(r[2]),i=Number(r[3]);(!Number.isFinite(s)||!Number.isFinite(i))&&(console.error(` usage: ${h("state")} hit <x> <y>`),process.exit(1)),t=await Y(d,"debugHitAt",s,i);break}case"gesture":{let s=Number(r[2]),i=Number(r[3]);(!Number.isFinite(s)||!Number.isFinite(i))&&(console.error(` usage: ${h("state")} gesture <x> <y>`),process.exit(1)),t=await Y(d,"debugGestureAt",s,i);break}default:console.error(` unknown state subcommand: ${o}`),process.exit(1)}console.log(JSON.stringify(t,null,2));break}case"shell":{let o=r[1];if(!o||o==="--help"||o==="-h"){console.log(`
533
+ })()`});break;case"node":{let s=r[2];s||(console.error(` usage: ${h("state")} node <id>`),process.exit(1)),t=await G(d,"findByTestId",s)||await G(d,"findById",s);break}case"scroll":{let s=r[2];s||(console.error(` usage: ${h("state")} scroll <id>`),process.exit(1)),t=await G(d,"getScrollState",s);break}case"scroll-hit":{let s=Number(r[2]),i=Number(r[3]);(!Number.isFinite(s)||!Number.isFinite(i))&&(console.error(` usage: ${h("state")} scroll-hit <x> <y>`),process.exit(1)),t=await G(d,"getScrollStateAt",s,i);break}case"hit":{let s=Number(r[2]),i=Number(r[3]);(!Number.isFinite(s)||!Number.isFinite(i))&&(console.error(` usage: ${h("state")} hit <x> <y>`),process.exit(1)),t=await G(d,"debugHitAt",s,i);break}case"gesture":{let s=Number(r[2]),i=Number(r[3]);(!Number.isFinite(s)||!Number.isFinite(i))&&(console.error(` usage: ${h("state")} gesture <x> <y>`),process.exit(1)),t=await G(d,"debugGestureAt",s,i);break}default:console.error(` unknown state subcommand: ${o}`),process.exit(1)}console.log(JSON.stringify(t,null,2));break}case"shell":{let o=r[1];if(!o||o==="--help"||o==="-h"){console.log(`
534
534
  ${h("shell")} \u2014 run built-in shell commands
535
535
 
536
536
  subcommands:
@@ -554,7 +554,7 @@ ${s}
554
554
  ${h("shell")} open-card clock 800
555
555
  ${h("shell")} appearance dark
556
556
  ${h("shell")} lock
557
- `);break}let t=o==="launch"||o==="open-card"||o==="home"||o==="switcher",s=o==="launch"||o==="open-card"?r[3]:r[2],i=s?Number(s):350;t&&(!Number.isFinite(i)||i<0)&&(console.error(k("shell",o==="launch"||o==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let a=!1,u=!1,p=null,b=e.includes("--clear-state");if(o==="launch"){let f=r[2];f||(console.error(k("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),b&&await d.send({type:"evaluate",code:Ye}),a=!!await pe(d,"launchApp",i,f),{settled:u,state:p}=await Te(d,Math.round(i),x=>!!x&&x.state==="app"&&x.activeApp===f&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.launchProgress=="number"&&x.launchProgress>=.98),a&&await L("inspect shell launch",b?{launchApp:{clearState:!0}}:{launchApp:{}},b?"launch app (clear state)":"launch app")}else if(o==="home")a=!!await pe(d,"goHome",i),{settled:u,state:p}=await Te(d,Math.round(i),f=>!!f&&f.state==="home"&&f.activeApp==null&&f.showSwitcher===!1&&f.switcherPhase==="idle"&&typeof f.launchProgress=="number"&&f.launchProgress>=.98);else if(o==="switcher")a=!!await pe(d,"openSwitcher",i),{settled:u,state:p}=await Te(d,Math.round(i),f=>!!f&&f.state==="app"&&f.showSwitcher===!0&&f.switcherPhase==="idle"&&typeof f.zoomLevel=="number"&&Math.abs(f.zoomLevel)<=.02&&typeof f.horizontalZoom=="number"&&Math.abs(f.horizontalZoom)<=.02),u&&(await Z(Jo),p=await le(d));else if(o==="open-card"){let f=r[2];f||(console.error(k("shell","open-card <appId> [settleMs]")),process.exit(1)),a=!!await pe(d,"openSwitcherCard",i,f),{settled:u,state:p}=await Te(d,Math.round(i),x=>!!x&&x.state==="app"&&x.activeApp===f&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.zoomLevel=="number"&&x.zoomLevel>=.98&&typeof x.horizontalZoom=="number"&&x.horizontalZoom>=.98),a&&await L("inspect shell open-card",{openSwitcherCard:{appId:f}},`open switcher card ${f}`)}else if(o==="appearance"){let f=r[2];(!f||!["light","dark","auto","toggle"].includes(f))&&(console.error(k("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let x=await Zt(d,"appearance",f);if(a=!!x?.ok,p={appearance:x},a){let O=x?.applied??f;console.log(` appearance: ${O}`)}}else if(o==="lock"||o==="shake"){let f=await Zt(d,o);a=!!f?.ok,p={[o]:f}}else console.error(` unknown shell subcommand: ${o}`),process.exit(1);console.log(JSON.stringify({ok:a,settled:u,state:p},null,2));break}case"url":{await Jt(d,{args:l});break}case"reload":{let s=!1,i=!1;try{await d.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let p=await d.send({type:"evaluate",code:`;(() => {
557
+ `);break}let t=o==="launch"||o==="open-card"||o==="home"||o==="switcher",s=o==="launch"||o==="open-card"?r[3]:r[2],i=s?Number(s):350;t&&(!Number.isFinite(i)||i<0)&&(console.error(k("shell",o==="launch"||o==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let a=!1,u=!1,p=null,b=e.includes("--clear-state");if(o==="launch"){let f=r[2];f||(console.error(k("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),b&&await d.send({type:"evaluate",code:Ge(!0)}),a=!!await pe(d,"launchApp",i,f),{settled:u,state:p}=await Te(d,Math.round(i),x=>!!x&&x.state==="app"&&x.activeApp===f&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.launchProgress=="number"&&x.launchProgress>=.98),a&&await J("inspect shell launch",b?{launchApp:{clearState:!0}}:{launchApp:{}},b?"launch app (clear state)":"launch app")}else if(o==="home")a=!!await pe(d,"goHome",i),{settled:u,state:p}=await Te(d,Math.round(i),f=>!!f&&f.state==="home"&&f.activeApp==null&&f.showSwitcher===!1&&f.switcherPhase==="idle"&&typeof f.launchProgress=="number"&&f.launchProgress>=.98);else if(o==="switcher")a=!!await pe(d,"openSwitcher",i),{settled:u,state:p}=await Te(d,Math.round(i),f=>!!f&&f.state==="app"&&f.showSwitcher===!0&&f.switcherPhase==="idle"&&typeof f.zoomLevel=="number"&&Math.abs(f.zoomLevel)<=.02&&typeof f.horizontalZoom=="number"&&Math.abs(f.horizontalZoom)<=.02),u&&(await Z(Lo),p=await le(d));else if(o==="open-card"){let f=r[2];f||(console.error(k("shell","open-card <appId> [settleMs]")),process.exit(1)),a=!!await pe(d,"openSwitcherCard",i,f),{settled:u,state:p}=await Te(d,Math.round(i),x=>!!x&&x.state==="app"&&x.activeApp===f&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.zoomLevel=="number"&&x.zoomLevel>=.98&&typeof x.horizontalZoom=="number"&&x.horizontalZoom>=.98),a&&await J("inspect shell open-card",{openSwitcherCard:{appId:f}},`open switcher card ${f}`)}else if(o==="appearance"){let f=r[2];(!f||!["light","dark","auto","toggle"].includes(f))&&(console.error(k("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let x=await Zt(d,"appearance",f);if(a=!!x?.ok,p={appearance:x},a){let O=x?.applied??f;console.log(` appearance: ${O}`)}}else if(o==="lock"||o==="shake"){let f=await Zt(d,o);a=!!f?.ok,p={[o]:f}}else console.error(` unknown shell subcommand: ${o}`),process.exit(1);console.log(JSON.stringify({ok:a,settled:u,state:p},null,2));break}case"url":{await Lt(d,{args:l});break}case"reload":{let s=!1,i=!1;try{await d.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let p=await d.send({type:"evaluate",code:`;(() => {
558
558
  const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
559
559
  if (typeof reloadExternalApp === 'function') {
560
560
  reloadExternalApp()
@@ -565,7 +565,7 @@ ${s}
565
565
  })()`});i=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let a=d,u=null;if(i)u=await Re(d,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await Z(300);let p=await ht(_,j,I,{timeoutMs:1e4,simIdSource:R});p?(a=p,u=await Re(p,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),a=null)}if(u)if(u.ready){let p=u.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${u.elapsedMs}ms: ${u.nodes} nodes${p}`)}else if(u.source==="error-bail")console.log(` \u26A0 reload bailed after ${u.elapsedMs}ms: ${u.errors} console error(s), ready signal never fired`);else{let p=Co(u);console.log(` \u26A0 reload timed out after ${u.elapsedMs}ms \u2014 ${p} (nodes: ${u.nodes}, targets: ${u.targets}, errors: ${u.errors})`)}if(a)try{let p=await we(a,10);if(a!==d&&a.close(),Array.isArray(p)&&p.length>0){console.log(`
566
566
  \u26A0 ${p.length} error(s) during mount:
567
567
  `);for(let b of p){let f=b.args.map(x=>typeof x=="object"?JSON.stringify(x):x).join(" ");if(console.log(` ${f}`),b.stack){let x=b.stack.split(`
568
- `).slice(0,2);for(let O of x)console.log(` ${O.trim()}`)}}}}catch{}u&&!u.ready&&(process.exitCode=1);break}case"eval":case"js":{let o=r.slice(1).join(" ");o||(console.error(k("js","<javascript>")),console.error(""),console.error(" runs the snippet in the engine realm. SootSim is the"),console.error(" canonical state surface \u2014 reach into it directly."),console.error(""),console.error(" examples:"),console.error(` ${h("js")} SootSim.bridges.test.findByText("Sign in")`),console.error(` ${h("js")} SootSim.bridges.debug.snapshot("before")`),console.error(` ${h("js")} SootSim.bridges.keyboard.type("hello")`),console.error(` ${h("js")} SootSim.state.root.children.length`),process.exit(1));let t=o;t.startsWith("(async")||(t=`(async () => ${t})()`);let s=await d.send({type:"evaluate",code:t});console.log(JSON.stringify(s,null,2));let i=o.toLowerCase(),a=[];(i.includes("sootsim:gohome")||i.includes("gohome"))&&a.push("sootsim shell home"),(i.includes("sootsim:appswitcher")||i.includes("appswitcher"))&&a.push("sootsim shell switcher"),(i.includes("keyboard.isvisible")||i.includes("keyboard.getmode"))&&a.push("sootsim debug state keyboard"),i.includes("interact.tap")&&a.push("sootsim do tap <x> <y>"),i.includes("keyboard.type")&&a.push("sootsim do type <text>"),(i.includes("keyboard.press")||i.includes("keyboard.dispatchkey"))&&a.push("sootsim do key <name>"),i.includes("keyboard.dismiss")&&a.push("sootsim do dismiss"),i.includes("dumptree")&&a.push("sootsim get tree"),i.includes("dumpaccessibilitytree")&&a.push("sootsim get a11y"),i.includes("getnodecount")&&a.push("sootsim get count"),i.includes("findbytext")&&a.push("sootsim find <text>"),(i.includes("findbytestid")||i.includes("findbyid"))&&a.push("sootsim find --testid <id>"),i.includes("document.hidden")&&a.push("sootsim debug state keyboard (includes tab health)"),a.length>0&&G("prefer-cli-over-eval",a);break}case"globals":{let o=await d.send({type:"evaluate",code:`(async () => {
568
+ `).slice(0,2);for(let O of x)console.log(` ${O.trim()}`)}}}}catch{}u&&!u.ready&&(process.exitCode=1);break}case"eval":case"js":{let o=r.slice(1).join(" ");o||(console.error(k("js","<javascript>")),console.error(""),console.error(" runs the snippet in the engine realm. SootSim is the"),console.error(" canonical state surface \u2014 reach into it directly."),console.error(""),console.error(" examples:"),console.error(` ${h("js")} SootSim.bridges.test.findByText("Sign in")`),console.error(` ${h("js")} SootSim.bridges.debug.snapshot("before")`),console.error(` ${h("js")} SootSim.bridges.keyboard.type("hello")`),console.error(` ${h("js")} SootSim.state.root.children.length`),process.exit(1));let t=o;t.startsWith("(async")||(t=`(async () => ${t})()`);let s=await d.send({type:"evaluate",code:t});console.log(JSON.stringify(s,null,2));let i=o.toLowerCase(),a=[];(i.includes("sootsim:gohome")||i.includes("gohome"))&&a.push("sootsim shell home"),(i.includes("sootsim:appswitcher")||i.includes("appswitcher"))&&a.push("sootsim shell switcher"),(i.includes("keyboard.isvisible")||i.includes("keyboard.getmode"))&&a.push("sootsim debug state keyboard"),i.includes("interact.tap")&&a.push("sootsim do tap <x> <y>"),i.includes("keyboard.type")&&a.push("sootsim do type <text>"),(i.includes("keyboard.press")||i.includes("keyboard.dispatchkey"))&&a.push("sootsim do key <name>"),i.includes("keyboard.dismiss")&&a.push("sootsim do dismiss"),i.includes("dumptree")&&a.push("sootsim get tree"),i.includes("dumpaccessibilitytree")&&a.push("sootsim get a11y"),i.includes("getnodecount")&&a.push("sootsim get count"),i.includes("findbytext")&&a.push("sootsim find <text>"),(i.includes("findbytestid")||i.includes("findbyid"))&&a.push("sootsim find --testid <id>"),i.includes("document.hidden")&&a.push("sootsim debug state keyboard (includes tab health)"),a.length>0&&Y("prefer-cli-over-eval",a);break}case"globals":{let o=await d.send({type:"evaluate",code:`(async () => {
569
569
  const globals = {}
570
570
 
571
571
  // test bridge (proxy in worker mode)
@@ -942,8 +942,8 @@ ${s}
942
942
  jank: ${a.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(a.samples)&&a.samples.length>0&&(console.log(""),Be(a.samples.map(b=>b[1])));break}default:console.error(` unknown perf subcommand: ${o}`),console.error(" valid: stats, start, stop, frames, worst, transition"),/^--?reset$/.test(o)&&console.error(" note: 'perf start' already clears prior frames \u2014 no reset needed"),process.exit(1)}break}case"errors":{let o=r[1];if(o==="clear"){await at(d),A(l)?P({cleared:!0}):console.log(" error buffer cleared");break}let t=o?Number(o):20,s=await we(d,t);if(A(l)){P(s);break}if(s.length===0){console.log(" no errors captured");break}console.log(` ${s.length} error(s):
943
943
  `);for(let i of s){let a=re(i.timestamp),u=i.args.map(p=>typeof p=="object"?JSON.stringify(p):p).join(" ");if(console.log(` [${a}] ${u}`),i.stack){let p=i.stack.split(`
944
944
  `).slice(0,3);for(let b of p)console.log(` ${b.trim()}`)}}break}case"warnings":{let o=r[1]?Number(r[1]):20,t=await it(d,o);if(A(l)){P(t);break}if(t.length===0){console.log(" no warnings captured");break}console.log(` ${t.length} warning(s):
945
- `);for(let s of t){let i=re(s.timestamp),a=s.args.map(u=>typeof u=="object"?JSON.stringify(u):u).join(" ");console.log(` [${i}] ${a}`)}break}case"animations":{let o=await Y(d,"listAnimations")??[];if(e.includes("--json")){console.log(JSON.stringify(o,null,2));break}if(o.length===0){console.log(" no active animations");break}console.log(` ${o.length} active animation(s):
946
- `);for(let t of o){let s=String(t.kind).padEnd(6),i=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,a=Number(t.current??0).toFixed(2),u=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,b=t.loop?" loop":"",f=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${i.padEnd(14)} cur=${a.padEnd(7)} ${u.padStart(4)} ${p}${b}${f}`)}break}case"animation":{let o=r[1];(!o||o==="--help"||o==="-h")&&(console.error(` usage: ${h("animation")} <id>`),process.exit(1));let t=Number(o);Number.isFinite(t)||(console.error(` invalid id: ${o}`),process.exit(1));let s=await Y(d,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let o=r[1];(!o||o==="--help"||o==="-h")&&(console.error(` usage: ${h("stop-animation")} <id|all>`),process.exit(1));let t=o==="all"?"all":Number(o);t!=="all"&&!Number.isFinite(t)&&(console.error(` invalid id: ${o}`),process.exit(1));let s=await Y(d,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let o=r[1];if(o==="clear"){await ct(d),A(l)?P({cleared:!0}):console.log(" request buffer cleared");break}let t=o==="all",s=t?r[2]:o,i=s?Number(s):20,a=await lt(d,{failed:!t,limit:i});if(A(l)){P(a);break}if(a.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${a.length} ${t?"request(s)":"failed request(s)"}:
945
+ `);for(let s of t){let i=re(s.timestamp),a=s.args.map(u=>typeof u=="object"?JSON.stringify(u):u).join(" ");console.log(` [${i}] ${a}`)}break}case"animations":{let o=await G(d,"listAnimations")??[];if(e.includes("--json")){console.log(JSON.stringify(o,null,2));break}if(o.length===0){console.log(" no active animations");break}console.log(` ${o.length} active animation(s):
946
+ `);for(let t of o){let s=String(t.kind).padEnd(6),i=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,a=Number(t.current??0).toFixed(2),u=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,b=t.loop?" loop":"",f=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${i.padEnd(14)} cur=${a.padEnd(7)} ${u.padStart(4)} ${p}${b}${f}`)}break}case"animation":{let o=r[1];(!o||o==="--help"||o==="-h")&&(console.error(` usage: ${h("animation")} <id>`),process.exit(1));let t=Number(o);Number.isFinite(t)||(console.error(` invalid id: ${o}`),process.exit(1));let s=await G(d,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let o=r[1];(!o||o==="--help"||o==="-h")&&(console.error(` usage: ${h("stop-animation")} <id|all>`),process.exit(1));let t=o==="all"?"all":Number(o);t!=="all"&&!Number.isFinite(t)&&(console.error(` invalid id: ${o}`),process.exit(1));let s=await G(d,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let o=r[1];if(o==="clear"){await ct(d),A(l)?P({cleared:!0}):console.log(" request buffer cleared");break}let t=o==="all",s=t?r[2]:o,i=s?Number(s):20,a=await lt(d,{failed:!t,limit:i});if(A(l)){P(a);break}if(a.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${a.length} ${t?"request(s)":"failed request(s)"}:
947
947
  `);for(let u of a){let p=re(u.timestamp);console.log(` [${p}] ${te(u)}`),u.responseBody?console.log(` ${u.responseBody}`):u.error&&console.log(` ${u.error}`)}break}case"network":{let o=r[1],t=null,s=null,i=!1,a=!1,u=1e3,p=!1,b=!1;for(let F=0;F<l.length;F++){let w=l[F];if(w==="--filter")t=l[F+1]??null,F++;else if(w==="--limit"){let $=Number(l[F+1]);Number.isFinite($)&&(s=$),F++}else if(w==="--threshold"){let $=Number(l[F+1]);Number.isFinite($)&&$>0&&(u=$),F++}else w==="--failed"?i=!0:w==="--slow"?a=!0:w==="--tail"||w==="-f"?p=!0:w==="--json"&&(b=!0)}if(o==="clear"){await d.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(o==="get"){let F=r[2];F||(console.error(" usage: sootsim network get <id>"),process.exit(1));let w=await d.send({type:"evaluate",code:`(() => {
948
948
  const obs = window.__sootsimObservability;
949
949
  if (!obs) return null;
@@ -955,13 +955,13 @@ ${s}
955
955
  return { ok: true, entries: obs.network.getSnapshot() };
956
956
  })()`});if(!F||!F.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return F.entries??[]},O=F=>{let w=F;if(i&&(w=w.filter($=>!!$.error||$.status!=null&&$.status>=400)),a&&(w=w.filter($=>$.durationMs!=null&&$.durationMs>=u)),t){let $=t.toLowerCase();w=w.filter(v=>(v.displayUrl||v.url).toLowerCase().includes($))}return a&&!p&&(w=[...w].sort(($,v)=>(v.durationMs??0)-($.durationMs??0))),w};if(!p){let F=await x(),w=O(F).slice(-f);if(b){console.log(JSON.stringify(w,null,2));break}if(w.length===0){F.length===0?console.log(" no network requests captured"):console.log(a?` no requests slower than ${u}ms (${F.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(a?` ${w.length} request(s) slower than ${u}ms (sorted by duration desc):
957
957
  `:` ${w.length} request(s):
958
- `);for(let $ of w)Gt($);break}console.log(` tailing network (ctrl-c to stop)...
959
- `);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let F=await x(),w=O(F);for(let $ of w)$.durationMs!=null&&(q.has($.id)||(q.add($.id),b?console.log(JSON.stringify($)):Gt($)));await Z(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let o=r[1],t=null,s=null,i=null,a=!1,u=!1,p=!1;for(let w=0;w<l.length;w++){let $=l[w];if($==="--filter")t=l[w+1]??null,w++;else if($==="--limit"){let v=Number(l[w+1]);Number.isFinite(v)&&(s=v),w++}else $==="--level"?(i=l[w+1]??null,w++):$==="--tail"||$==="-f"?a=!0:$==="--json"?u=!0:($==="--internal"||$==="--all")&&(p=!0)}let b=i?new Set(i.split(",").map(w=>w.trim()).filter(w=>w==="log"||w==="info"||w==="warn"||w==="error"||w==="debug")):null;if(o==="clear"){await ut(d),console.log(" log buffer cleared");break}let f=!u&&process.stdout.isTTY===!0,x=s??(a?500:o?Number(o):50);Number.isFinite(x)||(console.error(` invalid limit: ${o} \u2014 \`logs\` takes a numeric count (e.g. ${h("logs")} 100).
958
+ `);for(let $ of w)Yt($);break}console.log(` tailing network (ctrl-c to stop)...
959
+ `);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let F=await x(),w=O(F);for(let $ of w)$.durationMs!=null&&(q.has($.id)||(q.add($.id),b?console.log(JSON.stringify($)):Yt($)));await Z(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let o=r[1],t=null,s=null,i=null,a=!1,u=!1,p=!1;for(let w=0;w<l.length;w++){let $=l[w];if($==="--filter")t=l[w+1]??null,w++;else if($==="--limit"){let v=Number(l[w+1]);Number.isFinite(v)&&(s=v),w++}else $==="--level"?(i=l[w+1]??null,w++):$==="--tail"||$==="-f"?a=!0:$==="--json"?u=!0:($==="--internal"||$==="--all")&&(p=!0)}let b=i?new Set(i.split(",").map(w=>w.trim()).filter(w=>w==="log"||w==="info"||w==="warn"||w==="error"||w==="debug")):null;if(o==="clear"){await ut(d),console.log(" log buffer cleared");break}let f=!u&&process.stdout.isTTY===!0,x=s??(a?500:o?Number(o):50);Number.isFinite(x)||(console.error(` invalid limit: ${o} \u2014 \`logs\` takes a numeric count (e.g. ${h("logs")} 100).
960
960
  to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let O=()=>dt(d),q=w=>mt(w,{level:b,filter:t,showInternal:p});if(!a){let w=await O(),$=q(w).slice(-x);if(u){console.log(JSON.stringify($,null,2));break}if($.length===0){console.log(w.length===0?" no logs captured":" no matching logs");break}console.log(` ${$.length} log(s):
961
961
  `);for(let v of $)Vt(v,f);break}console.log(` tailing logs (ctrl-c to stop)...
962
- `);let H=new Set,U=!0,F=()=>{U=!1};process.on("SIGINT",F);try{for(;U;){let w=await O(),$=q(w);for(let v of $)H.has(v.id)||(H.add(v.id),u?console.log(JSON.stringify(v)):Vt(v,f));await Z(250)}}finally{process.off("SIGINT",F)}break}default:console.error(` unknown subcommand: ${g}`),process.exit(1)}if(me.has(g)&&!e.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&!await Ge(d,g)&&await S(d),!B.has(g)&&!A(l))try{await ne(d)}catch{}}catch(o){let t=o instanceof Error?o.message:String(o);console.error(` ${g??"inspect"} failed: ${t}`);let s=/^no sim connected with id (.+)$/.exec(t),i=/^command timed out after (\d+)s$/.exec(t),a=t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("could not connect to ws://");if(s)await St(d,_,s[1]);else if(/^no sim connected$/.test(t))$t(_);else if(i)if(await Ao(d)){let p=g??"describe";process.stderr.write(` the sim is still responsive \u2014 '${p}' just exceeded the ${i[1]}s command budget.
962
+ `);let H=new Set,U=!0,F=()=>{U=!1};process.on("SIGINT",F);try{for(;U;){let w=await O(),$=q(w);for(let v of $)H.has(v.id)||(H.add(v.id),u?console.log(JSON.stringify(v)):Vt(v,f));await Z(250)}}finally{process.off("SIGINT",F)}break}default:console.error(` unknown subcommand: ${g}`),process.exit(1)}if(me.has(g)&&!e.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&!await Ye(d,g)&&await S(d),!B.has(g)&&!A(l))try{await ne(d)}catch{}}catch(o){let t=o instanceof Error?o.message:String(o);console.error(` ${g??"inspect"} failed: ${t}`);let s=/^no sim connected with id (.+)$/.exec(t),i=/^command timed out after (\d+)s$/.exec(t),a=t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("could not connect to ws://");if(s)await St(d,_,s[1]);else if(/^no sim connected$/.test(t))$t(_);else if(i)if(await Ao(d)){let p=g??"describe";process.stderr.write(` the sim is still responsive \u2014 '${p}' just exceeded the ${i[1]}s command budget.
963
963
  the screen's node tree is large; narrow the query or raise the budget:
964
964
  sootsim ${p} --testid <id> # scope to one subtree
965
965
  sootsim find --testid <id> # targeted single-node lookup
966
966
  sootsim ${p} --timeout 60000 # raise per-command budget (ms)
967
- `)}else Yt();else if(a)Yt();else{try{await bt(d)}catch{}try{await X({includeTail:!0})}catch{}try{await W({includeTail:!0})}catch{}}process.exit(1)}finally{d.close()}}export{Rn as runInspect};
967
+ `)}else Gt();else if(a)Gt();else{try{await bt(d)}catch{}try{await X({includeTail:!0})}catch{}try{await W({includeTail:!0})}catch{}}process.exit(1)}finally{d.close()}}export{Rn as runInspect};
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.150 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as o}from"./chunk-7YEISEQ2.js";import"./chunk-GXFEY4YV.js";import"./chunk-6SXJQK5R.js";import"./chunk-6UA5JZ4E.js";import"./chunk-NI2TIFUK.js";import"./chunk-PGAGVXOZ.js";import"./chunk-CDLPRRMH.js";import"./chunk-KO4VABY3.js";import"./chunk-NHDDW7WP.js";import"./chunk-MFPT2P6I.js";async function t(n){console.error(" note: `sootsim install` is now `sootsim setup-repo`. forwarding\u2026\n"),await o(n)}export{t as runInstall};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as k}from"./chunk-G5BKDQGP.js";import{a as x}from"./chunk-23QZQBTT.js";import"./chunk-XYFPDYAI.js";import{spawn as v,spawnSync as u}from"child_process";import{chmodSync as S,copyFileSync as T,createWriteStream as E,existsSync as w,mkdirSync as y,rmSync as g,statSync as P,unlinkSync as D}from"fs";import{tmpdir as M}from"os";import{dirname as A,join as f,resolve as b}from"path";var h="https://sootbean.com/api/electron-release";function O(){let n=process.arch;if(process.platform==="darwin"){let o=n==="arm64"?"mac-arm64":"mac-x64",e=`sootsim-latest-${o}.dmg`;return{platform:o,filename:e,url:`${h}/${e}`,install:L}}if(process.platform==="linux"){let o=n==="arm64"?"linux-arm64":"linux-x64",e=`sootsim-latest-${o}.AppImage`;return{platform:o,filename:e,url:`${h}/${e}`,install:C}}if(process.platform==="win32"){let o="sootsim-latest-win-x64.exe";return{platform:"win-x64",filename:o,url:`${h}/${o}`,install:B}}return null}async function I({url:n,dest:o,onProgress:e}){let s=await fetch(n,{redirect:"follow"});if(!s.ok)throw new Error(`${s.status} ${s.statusText} (${n})`);let t=s.headers.get("content-length"),a=t?Number(t):null;if(!s.body)throw new Error(`empty response body (${n})`);y(A(o),{recursive:!0});let i=E(o),d=s.body.getReader(),c=0;try{for(;;){let{done:l,value:p}=await d.read();if(l)break;i.write(Buffer.from(p)),c+=p.byteLength,e?.(c,a)}}finally{await new Promise((l,p)=>{i.end(r=>r?p(r):l())})}}function _(n,o){let e=(n/1048576).toFixed(1);if(!o)return` ${e} MB`;let s=Math.min(100,Math.round(n/o*100)),t=(o/(1024*1024)).toFixed(1),a=24,i=Math.round(s/100*a);return` ${"\u2588".repeat(i)+"\u2591".repeat(a-i)} ${s}% ${e} / ${t} MB`}async function L(n){let o=u("hdiutil",["attach","-nobrowse","-readonly",n],{encoding:"utf8"});if(o.status!==0)throw new Error(`hdiutil attach failed: ${o.stderr||o.stdout}`.trim());let e=o.stdout.trim().split(`
1
+ /*! sootsim v0.1.150 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as k}from"./chunk-GXFEY4YV.js";import{a as x}from"./chunk-LBZGVNQE.js";import"./chunk-MFPT2P6I.js";import{spawn as v,spawnSync as u}from"child_process";import{chmodSync as S,copyFileSync as T,createWriteStream as E,existsSync as w,mkdirSync as y,rmSync as g,statSync as P,unlinkSync as D}from"fs";import{tmpdir as M}from"os";import{dirname as A,join as f,resolve as b}from"path";var h="https://sootbean.com/api/electron-release";function O(){let n=process.arch;if(process.platform==="darwin"){let o=n==="arm64"?"mac-arm64":"mac-x64",e=`sootsim-latest-${o}.dmg`;return{platform:o,filename:e,url:`${h}/${e}`,install:L}}if(process.platform==="linux"){let o=n==="arm64"?"linux-arm64":"linux-x64",e=`sootsim-latest-${o}.AppImage`;return{platform:o,filename:e,url:`${h}/${e}`,install:C}}if(process.platform==="win32"){let o="sootsim-latest-win-x64.exe";return{platform:"win-x64",filename:o,url:`${h}/${o}`,install:B}}return null}async function I({url:n,dest:o,onProgress:e}){let s=await fetch(n,{redirect:"follow"});if(!s.ok)throw new Error(`${s.status} ${s.statusText} (${n})`);let t=s.headers.get("content-length"),a=t?Number(t):null;if(!s.body)throw new Error(`empty response body (${n})`);y(A(o),{recursive:!0});let i=E(o),d=s.body.getReader(),c=0;try{for(;;){let{done:l,value:p}=await d.read();if(l)break;i.write(Buffer.from(p)),c+=p.byteLength,e?.(c,a)}}finally{await new Promise((l,p)=>{i.end(r=>r?p(r):l())})}}function _(n,o){let e=(n/1048576).toFixed(1);if(!o)return` ${e} MB`;let s=Math.min(100,Math.round(n/o*100)),t=(o/(1024*1024)).toFixed(1),a=24,i=Math.round(s/100*a);return` ${"\u2588".repeat(i)+"\u2591".repeat(a-i)} ${s}% ${e} / ${t} MB`}async function L(n){let o=u("hdiutil",["attach","-nobrowse","-readonly",n],{encoding:"utf8"});if(o.status!==0)throw new Error(`hdiutil attach failed: ${o.stderr||o.stdout}`.trim());let e=o.stdout.trim().split(`
3
3
  `),t=e[e.length-1].split(" ").pop()?.trim();if(!t||!w(t))throw new Error(`could not determine dmg mount point (output: ${o.stdout})`);let a=f(t,"sootsim.app");if(!w(a))throw u("hdiutil",["detach","-force",t]),new Error(`sootsim.app not found inside ${t}`);let i="/Applications",d=b(process.env.HOME||"","Applications"),c=i;try{let m=f(i,`.sootsim-write-probe-${process.pid}`);u("touch",[m]),w(m)?g(m,{force:!0}):c=d}catch{c=d}c===d&&y(c,{recursive:!0});let l=f(c,"sootsim.app");w(l)&&g(l,{recursive:!0,force:!0});let p=u("cp",["-R",a,l]),r=u("hdiutil",["detach","-force",t]);if(p.status!==0)throw new Error(`copy to ${l} failed: ${p.stderr?.toString()||""}`.trim());return r.status!==0&&console.warn(` warning: failed to unmount ${t} (${r.stderr?.toString().trim()||"unknown error"})`),u("xattr",["-dr","com.apple.quarantine",l]),l}async function C(n){let o=b(process.env.HOME||"","Applications");y(o,{recursive:!0});let e=f(o,"sootsim.AppImage");return w(e)&&g(e,{force:!0}),T(n,e),D(n),S(e,493),e}async function B(n){return await new Promise((o,e)=>{let s=v("cmd",["/c","start",'""',"/wait",n],{stdio:"inherit"});s.once("error",e),s.once("exit",t=>{t===0?o():e(new Error(`installer exited with code ${t}`))})}),n}async function q(n){(n.includes("--help")||n.includes("-h"))&&(console.log(`
4
4
  sootsim install-desktop \u2014 download and install the optional desktop GUI
5
5
 
@@ -20,4 +20,4 @@ examples:
20
20
  `),process.exit(0));let o=n.includes("--yes")||n.includes("-y")||process.env.SOOTSIM_NO_PROMPT==="1"||process.env.CI==="1"||!process.stdin.isTTY,e=n.includes("--force"),s=x();if(s&&!e){console.log(` sootsim desktop already installed at: ${s.path}`),console.log(" pass --force to reinstall.");return}let t=O();if(t||(console.error(` no desktop build available for ${process.platform}/${process.arch}.`),console.error(" supported: darwin-arm64, darwin-x64, linux-x64, win32-x64"),process.exit(1)),console.log(` platform: ${t.platform}`),console.log(` download: ${t.url}`),console.log(),!o){if(!await k("download and install now?",!0)){console.log(" cancelled.");return}console.log()}let a=f(M(),`sootsim-install-${Date.now()}`),i=f(a,t.filename),d=0;process.stdout.write(` downloading ${t.filename}...
21
21
  `);try{await I({url:t.url,dest:i,onProgress:(r,m)=>{let $=Date.now();$-d<100&&r<(m??1/0)||(d=$,process.stdout.isTTY&&process.stdout.write(`\r\x1B[2K${_(r,m)}`))}})}catch(r){g(a,{recursive:!0,force:!0});let m=r instanceof Error?r.message:String(r);console.error(`
22
22
  download failed: ${m}`),console.error(` the ${t.platform} desktop build may not be published yet, or your`),console.error(" network blocked the request. check your connection and try again later;"),console.error(" the CLI + daemon work without the desktop app (run: sootsim --help)."),process.exit(1)}process.stdout.isTTY&&process.stdout.write(`
23
- `);let c=P(i).size;console.log(` downloaded ${(c/(1024*1024)).toFixed(1)} MB`),console.log(),console.log(" installing...");let{trackCliEvent:l,flushCliTelemetry:p}=await import("./telemetry-QHL6TKNR.js");try{let r=await t.install(i);l({event:"cli_install_desktop_succeeded",properties:{platform:t.platform,size_bytes:c}}),console.log(` installed: ${r}`)}catch(r){l({event:"cli_install_desktop_failed",properties:{platform:t.platform,error:r instanceof Error?r.message:String(r)}}),await p(),console.error(` install failed: ${r instanceof Error?r.message:String(r)}`),console.error(` keeping download at ${i} for manual install.`),process.exit(1)}finally{g(a,{recursive:!0,force:!0})}console.log(),console.log(" next steps:"),console.log(" sootsim electron launch the desktop app"),console.log(" sootsim open <target> open a demo or bundle in it")}export{q as runInstallDesktop};
23
+ `);let c=P(i).size;console.log(` downloaded ${(c/(1024*1024)).toFixed(1)} MB`),console.log(),console.log(" installing...");let{trackCliEvent:l,flushCliTelemetry:p}=await import("./telemetry-PHXMPEY3.js");try{let r=await t.install(i);l({event:"cli_install_desktop_succeeded",properties:{platform:t.platform,size_bytes:c}}),console.log(` installed: ${r}`)}catch(r){l({event:"cli_install_desktop_failed",properties:{platform:t.platform,error:r instanceof Error?r.message:String(r)}}),await p(),console.error(` install failed: ${r instanceof Error?r.message:String(r)}`),console.error(` keeping download at ${i} for manual install.`),process.exit(1)}finally{g(a,{recursive:!0,force:!0})}console.log(),console.log(" next steps:"),console.log(" sootsim electron launch the desktop app"),console.log(" sootsim open <target> open a demo or bundle in it")}export{q as runInstallDesktop};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as l,b as d,c as k,d as y,e as g}from"./chunk-A57WJDB2.js";import{d as c}from"./chunk-TYHRA7FX.js";import"./chunk-F3MFOV7R.js";import"./chunk-XYFPDYAI.js";async function a(){let s=await c();return s?.token||(process.stderr.write(" sootsim keys ... needs you to be signed in.\n run `sootsim login` first.\n"),process.exit(1)),{origin:s.origin,token:s.token}}function f(s){if(!s)return"never";try{return new Date(s).toLocaleString()}catch{return s}}async function h(s){let i=s[0];if(!i||i==="--help"||i==="-h"){u();return}if(i==="list"){let{origin:o,token:e}=await a(),n=await fetch(`${o.replace(/\/$/,"")}/api/sootsim/billing/keys`,{headers:{authorization:`Bearer ${e}`}});n.ok||(console.error(` keys list failed (${n.status})`),process.exit(1));let{keys:r}=await n.json();if(r.length===0){console.log(" no keys. create one with `sootsim keys create <label>`.");return}for(let t of r)console.log(` ${t.keyPrefix}\u2026 ${t.label.padEnd(24)} scopes=${t.scopes.join(",")} last=${f(t.lastUsedAt)} id=${t.id}`);return}if(i==="create"){let o=s[1]?.trim();o||(console.error(" usage: sootsim keys create <label>"),process.exit(1));let{origin:e,token:n}=await a(),r=await fetch(`${e.replace(/\/$/,"")}/api/sootsim/billing/keys`,{method:"POST",headers:{authorization:`Bearer ${n}`,"content-type":"application/json"},body:JSON.stringify({label:o})});r.ok||(console.error(` keys create failed (${r.status}): ${await r.text()}`),process.exit(1));let t=await r.json();console.log(`
1
+ /*! sootsim v0.1.150 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as l,b as d,c as k,d as y,e as g}from"./chunk-3J5I64W6.js";import{d as c}from"./chunk-CDLPRRMH.js";import"./chunk-NHDDW7WP.js";import"./chunk-MFPT2P6I.js";async function a(){let s=await c();return s?.token||(process.stderr.write(" sootsim keys ... needs you to be signed in.\n run `sootsim login` first.\n"),process.exit(1)),{origin:s.origin,token:s.token}}function f(s){if(!s)return"never";try{return new Date(s).toLocaleString()}catch{return s}}async function h(s){let i=s[0];if(!i||i==="--help"||i==="-h"){u();return}if(i==="list"){let{origin:o,token:e}=await a(),n=await fetch(`${o.replace(/\/$/,"")}/api/sootsim/billing/keys`,{headers:{authorization:`Bearer ${e}`}});n.ok||(console.error(` keys list failed (${n.status})`),process.exit(1));let{keys:r}=await n.json();if(r.length===0){console.log(" no keys. create one with `sootsim keys create <label>`.");return}for(let t of r)console.log(` ${t.keyPrefix}\u2026 ${t.label.padEnd(24)} scopes=${t.scopes.join(",")} last=${f(t.lastUsedAt)} id=${t.id}`);return}if(i==="create"){let o=s[1]?.trim();o||(console.error(" usage: sootsim keys create <label>"),process.exit(1));let{origin:e,token:n}=await a(),r=await fetch(`${e.replace(/\/$/,"")}/api/sootsim/billing/keys`,{method:"POST",headers:{authorization:`Bearer ${n}`,"content-type":"application/json"},body:JSON.stringify({label:o})});r.ok||(console.error(` keys create failed (${r.status}): ${await r.text()}`),process.exit(1));let t=await r.json();console.log(`
3
3
  created: ${t.record.label} (${t.record.keyPrefix}\u2026)`),console.log(` scopes: ${t.record.scopes.join(",")}`),console.log(`
4
4
  secret: ${t.secret}
5
5
  `),console.log(` copy this now \u2014 we can't show it again.
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.148 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import"./chunk-SY5JYGZE.js";import{b as h}from"./chunk-474QHKFY.js";import{a as d}from"./chunk-23QZQBTT.js";import"./chunk-KZ6AQHHA.js";import"./chunk-V4EYA5L5.js";import"./chunk-BCWW5RSQ.js";import"./chunk-4JVDEEJJ.js";import{A as t,B as u,F as m,G as r,H as a,h as l,i as c}from"./chunk-F3MFOV7R.js";import"./chunk-XYFPDYAI.js";import{spawn as v}from"child_process";import{existsSync as w}from"fs";async function O(n){if(n.includes("--help")||n.includes("-h")){console.log(`
1
+ /*! sootsim v0.1.150 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import"./chunk-H5YQDCRA.js";import{b as h}from"./chunk-WNJOX4AQ.js";import{a as d}from"./chunk-LBZGVNQE.js";import"./chunk-3MWCUIK4.js";import"./chunk-YKWGZWBE.js";import"./chunk-36L4ANT2.js";import"./chunk-NI2TIFUK.js";import{A as t,B as u,F as m,G as r,H as a,h as l,i as c}from"./chunk-NHDDW7WP.js";import"./chunk-MFPT2P6I.js";import{spawn as v}from"child_process";import{existsSync as w}from"fs";async function O(n){if(n.includes("--help")||n.includes("-h")){console.log(`
3
3
  sootsim launch \u2014 one-shot: install runtime if needed, start daemon, open app
4
4
 
5
5
  usage:
@@ -13,4 +13,4 @@ options:
13
13
  examples:
14
14
  sootsim launch
15
15
  sootsim launch --version 1.2.3
16
- `);return}let e=n.includes("--no-runtime-install"),i=n.indexOf("--channel"),s=i>=0&&n[i+1]?n[i+1]:"stable",o=n.indexOf("--version"),f=o>=0&&n[o+1]?n[o+1]:void 0;t(),await x({skipAutoInstall:e,channel:s,explicitVersion:f}),await p(),await k()}async function x(n){let e=u(),i=m();if(e&&i)return;n.skipAutoInstall&&(console.error(" no sootsim runtime installed. run `sootsim runtime install` first, or drop --no-runtime-install."),process.exit(1)),console.log("sootsim: first run \u2014 installing runtime");let{runRuntime:s}=await import("./runtime-X5RH4ZUA.js"),o=[];n.explicitVersion&&o.push(n.explicitVersion),n.channel!=="stable"&&o.push("--channel",n.channel),await s(["install",...o],{channel:n.channel})}async function p(){let n=r();if(a(n))return;if(c()){let o=l()?"this is a dev workstation (IS_TAMAGUI_DEV=1)":"this is a dev checkout";console.error(` not spawning a standalone sootsim daemon \u2014 ${o}.`),console.error(" the live `bun dev` stack hosts the bridge in-process (run it, or its electron);"),console.error(" set SOOTSIM_FORCE_DAEMON_INSTALL=1 to spawn one here on purpose."),process.exit(1)}console.log("sootsim: starting daemon");let e=g();v(e,["server","--quiet"],{detached:!0,stdio:"ignore",env:process.env}).unref();let s=Date.now()+8e3;for(;Date.now()<s;){let o=r();if(a(o))return;await D(150)}console.error(" daemon didn't become ready within 8s \u2014 check ~/.sootsim/ or run `sootsim server` in a terminal to see errors"),process.exit(1)}async function k(){d()||(console.error(" no sootsim desktop companion installed. run `sootsim install-desktop` to download electron + the shell."),process.exit(1));let e=await h.launch({});e.launched||(console.error(` ${e.message}`),process.exit(1)),console.log(` ${e.message}`)}function g(){let n=process.argv[1];return n&&w(n)?n:"sootsim"}function D(n){return new Promise(e=>setTimeout(e,n))}async function R(){t(),await p()}export{R as ensureDaemonRunning,O as runLaunch};
16
+ `);return}let e=n.includes("--no-runtime-install"),i=n.indexOf("--channel"),s=i>=0&&n[i+1]?n[i+1]:"stable",o=n.indexOf("--version"),f=o>=0&&n[o+1]?n[o+1]:void 0;t(),await x({skipAutoInstall:e,channel:s,explicitVersion:f}),await p(),await k()}async function x(n){let e=u(),i=m();if(e&&i)return;n.skipAutoInstall&&(console.error(" no sootsim runtime installed. run `sootsim runtime install` first, or drop --no-runtime-install."),process.exit(1)),console.log("sootsim: first run \u2014 installing runtime");let{runRuntime:s}=await import("./runtime-A7DUL4IU.js"),o=[];n.explicitVersion&&o.push(n.explicitVersion),n.channel!=="stable"&&o.push("--channel",n.channel),await s(["install",...o],{channel:n.channel})}async function p(){let n=r();if(a(n))return;if(c()){let o=l()?"this is a dev workstation (IS_TAMAGUI_DEV=1)":"this is a dev checkout";console.error(` not spawning a standalone sootsim daemon \u2014 ${o}.`),console.error(" the live `bun dev` stack hosts the bridge in-process (run it, or its electron);"),console.error(" set SOOTSIM_FORCE_DAEMON_INSTALL=1 to spawn one here on purpose."),process.exit(1)}console.log("sootsim: starting daemon");let e=g();v(e,["server","--quiet"],{detached:!0,stdio:"ignore",env:process.env}).unref();let s=Date.now()+8e3;for(;Date.now()<s;){let o=r();if(a(o))return;await D(150)}console.error(" daemon didn't become ready within 8s \u2014 check ~/.sootsim/ or run `sootsim server` in a terminal to see errors"),process.exit(1)}async function k(){d()||(console.error(" no sootsim desktop companion installed. run `sootsim install-desktop` to download electron + the shell."),process.exit(1));let e=await h.launch({});e.launched||(console.error(` ${e.message}`),process.exit(1)),console.log(` ${e.message}`)}function g(){let n=process.argv[1];return n&&w(n)?n:"sootsim"}function D(n){return new Promise(e=>setTimeout(e,n))}async function R(){t(),await p()}export{R as ensureDaemonRunning,O as runLaunch};