sootsim 0.1.304 → 0.1.305

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 (149) hide show
  1. package/dist-cli/bin.js +5 -5
  2. package/dist-cli/chunks/{agent-EK355OQM.js → agent-OJP4VF2K.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-LCJJWHZE.js → agent-wrapper-HMVFZKH3.js} +2 -2
  4. package/dist-cli/chunks/{app-fonts-LIPU2DLT.js → app-fonts-INFYQMIN.js} +2 -2
  5. package/dist-cli/chunks/{assert-OASKCPBX.js → assert-YSFBCP5P.js} +2 -2
  6. package/dist-cli/chunks/{auth-XYYKD33F.js → auth-M7RKDYQV.js} +2 -2
  7. package/dist-cli/chunks/{beta-TOL55XPM.js → beta-4NRMM37T.js} +2 -2
  8. package/dist-cli/chunks/{camera-PHKVEQHR.js → camera-MHLM35MB.js} +2 -2
  9. package/dist-cli/chunks/{chunk-GMILMS7P.js → chunk-2D7NF3XK.js} +2 -2
  10. package/dist-cli/chunks/{chunk-CMYVGJBQ.js → chunk-2UKSI3VX.js} +1 -1
  11. package/dist-cli/chunks/{chunk-AJYA6R3N.js → chunk-3PREBGTH.js} +2 -2
  12. package/dist-cli/chunks/{chunk-JDKWIB6V.js → chunk-43SNLCXR.js} +1 -1
  13. package/dist-cli/chunks/{chunk-3UUHIHA6.js → chunk-4Q42Y64Y.js} +2 -2
  14. package/dist-cli/chunks/{chunk-YAV6BH3A.js → chunk-54AINFEF.js} +2 -2
  15. package/dist-cli/chunks/{chunk-RT7TUHH7.js → chunk-6EXIYEOQ.js} +2 -2
  16. package/dist-cli/chunks/{chunk-ENXLKDQ6.js → chunk-6YE25EJB.js} +3 -3
  17. package/dist-cli/chunks/{chunk-5NJTX5OP.js → chunk-AJCL7DHI.js} +2 -2
  18. package/dist-cli/chunks/chunk-B65RMI7A.js +71 -0
  19. package/dist-cli/chunks/{chunk-INBBOCU4.js → chunk-BDNZULU7.js} +2 -2
  20. package/dist-cli/chunks/chunk-COD6QGS2.js +125 -0
  21. package/dist-cli/chunks/{chunk-ZONISYZ5.js → chunk-CWDEDUOZ.js} +1 -1
  22. package/dist-cli/chunks/{chunk-OSH6526H.js → chunk-DHDSGBZB.js} +1 -1
  23. package/dist-cli/chunks/{chunk-XCVSB47R.js → chunk-DTHOMSAA.js} +2 -2
  24. package/dist-cli/chunks/{chunk-7RFXZXKH.js → chunk-EBCXFB3K.js} +1 -1
  25. package/dist-cli/chunks/{chunk-LRXSLMX4.js → chunk-EPZG2F4I.js} +1 -1
  26. package/dist-cli/chunks/{chunk-2RLFUM3C.js → chunk-EWVEUNRO.js} +51 -118
  27. package/dist-cli/chunks/{chunk-ITDTSNN2.js → chunk-H5D6E3DR.js} +2 -2
  28. package/dist-cli/chunks/{chunk-RYQUO6LT.js → chunk-HHLH4TWF.js} +1 -1
  29. package/dist-cli/chunks/{chunk-SVFN66PF.js → chunk-HKPJYMJC.js} +2 -2
  30. package/dist-cli/chunks/{chunk-IWRRIQDJ.js → chunk-HMOYEM6V.js} +2 -2
  31. package/dist-cli/chunks/{chunk-NXYKNKNL.js → chunk-IJ64Z77P.js} +2 -2
  32. package/dist-cli/chunks/{chunk-GF3LDVWF.js → chunk-J653UMCU.js} +2 -2
  33. package/dist-cli/chunks/{chunk-XXS4TCOO.js → chunk-JKIPNRAK.js} +3 -3
  34. package/dist-cli/chunks/{chunk-Y5YM7XHU.js → chunk-JQRRJIMT.js} +1 -1
  35. package/dist-cli/chunks/{chunk-G4R7CPCY.js → chunk-KG2WUKD2.js} +2 -2
  36. package/dist-cli/chunks/{chunk-QWQHSUZC.js → chunk-KSZRLJPA.js} +2 -2
  37. package/dist-cli/chunks/{chunk-MSYPDBFG.js → chunk-KVLXMWV5.js} +2 -2
  38. package/dist-cli/chunks/{chunk-WNDYTKLC.js → chunk-KVOY4Z2X.js} +1 -1
  39. package/dist-cli/chunks/{chunk-XHYSASAX.js → chunk-LOF3WUKB.js} +1 -1
  40. package/dist-cli/chunks/{chunk-V6JDDX4B.js → chunk-NNR3BU5O.js} +2 -2
  41. package/dist-cli/chunks/{chunk-ABHNOM2C.js → chunk-OCRL2VU4.js} +1 -1
  42. package/dist-cli/chunks/{chunk-BPRMA4IC.js → chunk-PELXRGDN.js} +2 -2
  43. package/dist-cli/chunks/{chunk-VUR5QXVX.js → chunk-POIK3AHY.js} +2 -2
  44. package/dist-cli/chunks/{chunk-76OLOD2G.js → chunk-QJUKXBH5.js} +2 -2
  45. package/dist-cli/chunks/{chunk-UB3OWUVK.js → chunk-QVH276LI.js} +1 -1
  46. package/dist-cli/chunks/{chunk-2MEUZOSD.js → chunk-R5TBMYGH.js} +1 -1
  47. package/dist-cli/chunks/{chunk-HFA5ZACE.js → chunk-R6MBDR56.js} +1 -1
  48. package/dist-cli/chunks/{chunk-BJOT2LL6.js → chunk-SLCYXISJ.js} +2 -2
  49. package/dist-cli/chunks/{chunk-A4UYZTV7.js → chunk-SWBTXTEO.js} +2 -2
  50. package/dist-cli/chunks/{chunk-RQJDIDJ3.js → chunk-TRV5K6D2.js} +1 -1
  51. package/dist-cli/chunks/{chunk-RJWQ3VAD.js → chunk-UUKUKTV3.js} +2 -2
  52. package/dist-cli/chunks/{chunk-SN6ARNCL.js → chunk-VKBCGFOU.js} +2 -2
  53. package/dist-cli/chunks/{chunk-HFKQUS4I.js → chunk-W3M4676V.js} +3 -3
  54. package/dist-cli/chunks/{chunk-YXHO2OUL.js → chunk-WIRBJTTU.js} +1 -1
  55. package/dist-cli/chunks/{chunk-EXW6TH3O.js → chunk-WQYUHDBU.js} +2 -2
  56. package/dist-cli/chunks/{chunk-FNI75AD7.js → chunk-XI6CPN53.js} +1 -1
  57. package/dist-cli/chunks/{chunk-M3ETYVNL.js → chunk-XWMTLVCE.js} +1 -1
  58. package/dist-cli/chunks/{chunk-W3CSYOSQ.js → chunk-ZRQFYMTL.js} +1 -1
  59. package/dist-cli/chunks/{cleanup-GCTEGJMP.js → cleanup-ZJ7FQKED.js} +2 -2
  60. package/dist-cli/chunks/{cli-version-G72HUH4E.js → cli-version-5LGCFOAC.js} +2 -2
  61. package/dist-cli/chunks/{compat-IC4JHGBH.js → compat-EQACACVP.js} +2 -2
  62. package/dist-cli/chunks/{config-C65MZFU3.js → config-ADGNCDG5.js} +2 -2
  63. package/dist-cli/chunks/{control-RWLYBKQR.js → control-Y3E5IIMO.js} +2 -2
  64. package/dist-cli/chunks/daemon-A6CWUYMR.js +4 -0
  65. package/dist-cli/chunks/{debug-LEL32PDN.js → debug-PU73W33T.js} +3 -3
  66. package/dist-cli/chunks/{desktop-RDSISJH2.js → desktop-V675PYF4.js} +3 -3
  67. package/dist-cli/chunks/{detox-SCCWUIKK.js → detox-SHVVEPPX.js} +2 -2
  68. package/dist-cli/chunks/{device-MTDEKDUK.js → device-NMRUACB4.js} +2 -2
  69. package/dist-cli/chunks/{diagnose-UZJCKLPZ.js → diagnose-S2AVGABT.js} +2 -2
  70. package/dist-cli/chunks/disk-cleanup-EJEZIIT4.js +4 -0
  71. package/dist-cli/chunks/drivers-PM4PVYHY.js +4 -0
  72. package/dist-cli/chunks/{film-YBE544PG.js → film-UB7N4EKB.js} +3 -3
  73. package/dist-cli/chunks/flow-XJRNL25V.js +4 -0
  74. package/dist-cli/chunks/help-2ZJHCVUZ.js +4 -0
  75. package/dist-cli/chunks/{hidden-runtime-alias-KJYCJLSR.js → hidden-runtime-alias-M44SGZLM.js} +2 -2
  76. package/dist-cli/chunks/{home-paths-NSHWNEGK.js → home-paths-ZTEBHBUO.js} +2 -2
  77. package/dist-cli/chunks/inspect-L76RUF62.js +4 -0
  78. package/dist-cli/chunks/install-desktop-UIXKNXKF.js +4 -0
  79. package/dist-cli/chunks/{login-AEVUU72R.js → login-YQ3HRPPS.js} +4 -4
  80. package/dist-cli/chunks/{logout-72XHF6J2.js → logout-XGBDWO4J.js} +2 -2
  81. package/dist-cli/chunks/{maestro-OXSKQJ6B.js → maestro-CESBE2SF.js} +3 -3
  82. package/dist-cli/chunks/{maestro-generate-AKZFORVJ.js → maestro-generate-4IHISKJL.js} +3 -3
  83. package/dist-cli/chunks/{mode-U6KRG2PE.js → mode-BQGGZ737.js} +2 -2
  84. package/dist-cli/chunks/{optional-demo-registry-L3VIWBI2.js → optional-demo-registry-LWYRXVIE.js} +2 -2
  85. package/dist-cli/chunks/{perf-KF2BJZIN.js → perf-TUR22UTE.js} +2 -2
  86. package/dist-cli/chunks/{permissions-TRJG4QAI.js → permissions-POJIVSRV.js} +2 -2
  87. package/dist-cli/chunks/{record-TICJYZOA.js → record-Q55SGXLU.js} +3 -3
  88. package/dist-cli/chunks/{report-issue-OQPLBQMJ.js → report-issue-LRRX7VJV.js} +2 -2
  89. package/dist-cli/chunks/runtime-NHDHZJJN.js +4 -0
  90. package/dist-cli/chunks/{screenshot-command-XLERKHVW.js → screenshot-command-C7EU43J3.js} +6 -6
  91. package/dist-cli/chunks/screenshot-layers-NYVOJYUU.js +20 -0
  92. package/dist-cli/chunks/{screenshots-capture-B6OORSD4.js → screenshots-capture-AYKJKBLR.js} +2 -2
  93. package/dist-cli/chunks/{serve-5M7MIPWF.js → serve-EN3ZPJSA.js} +2 -2
  94. package/dist-cli/chunks/{setup-HJZDC4PK.js → setup-KKMKLJZE.js} +2 -2
  95. package/dist-cli/chunks/{skills-RXHLMGGL.js → skills-DR5DG2SK.js} +2 -2
  96. package/dist-cli/chunks/{storage-MMPD2XBS.js → storage-GMDBVTQ5.js} +2 -2
  97. package/dist-cli/chunks/store-QZEMKQDC.js +4 -0
  98. package/dist-cli/chunks/telemetry-TNX72J2B.js +4 -0
  99. package/dist-cli/chunks/{timeline-6PF5BZ37.js → timeline-VY3444AZ.js} +2 -2
  100. package/dist-cli/chunks/{upgrade-QSMIK3RC.js → upgrade-EUYCW55F.js} +2 -2
  101. package/dist-cli/chunks/upload-D43U7RGT.js +4 -0
  102. package/dist-cli/chunks/{version-WLTFXEDC.js → version-TEGM4WRU.js} +2 -2
  103. package/dist-cli/chunks/{web-DI73LQ7N.js → web-QF7LF4VB.js} +2 -2
  104. package/dist-cli/chunks/{what-happened-4SAMGZWR.js → what-happened-HDTJGNND.js} +2 -2
  105. package/dist-lib/agent-daemon-client.cjs +1 -1
  106. package/dist-lib/agent-events.cjs +1 -1
  107. package/dist-lib/agent-identity.cjs +1 -1
  108. package/dist-lib/agent-sessions.cjs +1 -1
  109. package/dist-lib/attached-projects.cjs +1 -1
  110. package/dist-lib/auth/shared-session.cjs +1 -1
  111. package/dist-lib/backend-origin.cjs +1 -1
  112. package/dist-lib/beta.cjs +1 -1
  113. package/dist-lib/beta.mjs +1 -1
  114. package/dist-lib/bridge-constants.cjs +1 -1
  115. package/dist-lib/cli-constants.cjs +1 -1
  116. package/dist-lib/config.cjs +1 -1
  117. package/dist-lib/detox/index.cjs +1 -1
  118. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  119. package/dist-lib/home-paths.cjs +1 -1
  120. package/dist-lib/host/bridge-host.cjs +1 -1
  121. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  122. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  123. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  124. package/dist-lib/host/websocket-proxy.cjs +1 -1
  125. package/dist-lib/index.cjs +1 -1
  126. package/dist-lib/jump-to-source-babel.cjs +1 -1
  127. package/dist-lib/menu.cjs +1 -1
  128. package/dist-lib/menu.mjs +1 -1
  129. package/dist-lib/metro.cjs +1 -1
  130. package/dist-lib/profiles.cjs +1 -1
  131. package/dist-lib/render-mode.cjs +1 -1
  132. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  133. package/dist-lib/sdk.cjs +1 -1
  134. package/dist-lib/sdk.mjs +1 -1
  135. package/dist-lib/skills.cjs +1 -1
  136. package/dist-lib/vite.cjs +1 -1
  137. package/package.json +1 -1
  138. package/dist-cli/chunks/chunk-ZDRI2LUG.js +0 -125
  139. package/dist-cli/chunks/daemon-D77E5G6Z.js +0 -4
  140. package/dist-cli/chunks/disk-cleanup-HLWRVTVW.js +0 -4
  141. package/dist-cli/chunks/drivers-Q7GMKTBM.js +0 -4
  142. package/dist-cli/chunks/flow-5VOVAVZN.js +0 -4
  143. package/dist-cli/chunks/help-2PESJ7V2.js +0 -4
  144. package/dist-cli/chunks/inspect-OIA3Q5MD.js +0 -4
  145. package/dist-cli/chunks/install-desktop-7KLACQUW.js +0 -4
  146. package/dist-cli/chunks/runtime-HDMLWNXW.js +0 -4
  147. package/dist-cli/chunks/store-APKY72ZY.js +0 -4
  148. package/dist-cli/chunks/telemetry-W3YRHE67.js +0 -4
  149. package/dist-cli/chunks/upload-HQEOYILQ.js +0 -4
@@ -1,81 +1,14 @@
1
- /*! sootsim v0.1.304 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.305 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
- import{a as de}from"./chunk-INBBOCU4.js";import{b as Et,c as Pt,l as At}from"./chunk-76OLOD2G.js";import{a as oe,b as D,c as A,d as Ie,e as ae,f as X,g as pe,h as ye,i as Ft,j as Ot,k as Te,l as Rt}from"./chunk-NXYKNKNL.js";import{A as wt,B as $t,C as xt,F as St,H as vt,J as ue,K as kt,Q as Le,a as ke,b as rt,c as it,d as at,e as lt,f as ct,g as dt,h as ut,i as pt,j as mt,k as Be,l as Ce,r as je,s as ft,t as gt,u as ge,v as yt,w as _e,x as qe,y as ht,z as bt}from"./chunk-HFA5ZACE.js";import{a as nt,f as _t,h as It,j as Tt,k as Mt,l as Nt,m as ce}from"./chunk-V6JDDX4B.js";import{a as ot}from"./chunk-2MEUZOSD.js";import{a as Q}from"./chunk-VUR5QXVX.js";import{c as st}from"./chunk-YXHO2OUL.js";import{c as Ae,e as De}from"./chunk-ZDRI2LUG.js";function We(e){return`(async () => {
4
+ import{a as de}from"./chunk-BDNZULU7.js";import{a as Pt,b as _t}from"./chunk-B65RMI7A.js";import{b as At,c as Dt,l as Bt}from"./chunk-QJUKXBH5.js";import{a as oe,b as D,c as A,d as Te,e as ae,f as X,g as pe,h as ye,i as Ot,j as Rt,k as Me,l as Et}from"./chunk-IJ64Z77P.js";import{A as wt,B as $t,C as xt,F as St,H as vt,J as ue,K as kt,Q as Le,a as ke,b as rt,c as it,d as at,e as lt,f as ct,g as dt,h as ut,i as pt,j as mt,k as Be,l as Ce,r as je,s as ft,t as gt,u as ge,v as yt,w as Ie,x as qe,y as ht,z as bt}from"./chunk-R6MBDR56.js";import{a as nt,f as It,h as Tt,j as Mt,k as Nt,l as Ft,m as ce}from"./chunk-NNR3BU5O.js";import{a as ot}from"./chunk-R5TBMYGH.js";import{a as Q}from"./chunk-POIK3AHY.js";import{c as st}from"./chunk-WIRBJTTU.js";import{c as Ae,e as De}from"./chunk-COD6QGS2.js";function We(e){return`(async () => {
5
5
  const bridge = globalThis.SootSim && globalThis.SootSim.bridges && globalThis.SootSim.bridges.hotRemount
6
6
  if (!bridge || typeof bridge.reloadExternalApp !== 'function') return false
7
7
  await bridge.reloadExternalApp({ resetStorage: ${e?"true":"false"} })
8
8
  return true
9
- })()`}function Dt(e){return`(async () => {
10
- const __t = window.__sootsimTest
11
- if (!__t) throw new Error('__sootsimTest not available')
12
- const __id = ${JSON.stringify(e.id||"")}
13
- const __text = ${JSON.stringify(e.text||"")}
14
- let __node = null
15
- if (__id) {
16
- __node = (__t.findByTestId && await __t.findByTestId(__id)) ||
17
- (__t.findById && await __t.findById(__id)) || null
18
- } else if (__text) {
19
- __node = __t.findByText ? await __t.findByText(__text) : null
20
- }
21
- if (!__node) return null
22
- const __pos = __node.absolutePosition || { x: __node.layout?.x || 0, y: __node.layout?.y || 0 }
23
- const __layout = __node.layout || {}
24
- return {
25
- x: __pos.x,
26
- y: __pos.y,
27
- w: __layout.width || 1,
28
- h: __layout.height || 1,
29
- }
30
- })()`}function Bt(e){return`(async () => {
31
- const __rect = ${JSON.stringify(e)}
32
- const __screenshot = window.__sootsimScreenshot
33
- if (typeof __screenshot !== 'function') {
34
- throw new Error('screenshot bridge not installed')
35
- }
36
- const __dataUrl = await __screenshot({ crop: __rect })
37
- const __img = await new Promise((res, rej) => {
38
- const img = new Image()
39
- img.onload = () => res(img)
40
- img.onerror = () => rej(new Error('failed to decode cropped screenshot'))
41
- img.src = __dataUrl
42
- })
43
- const __w = __img.naturalWidth
44
- const __h = __img.naturalHeight
45
- const __canvas = document.createElement('canvas')
46
- __canvas.width = __w
47
- __canvas.height = __h
48
- const __ctx = __canvas.getContext('2d')
49
- if (!__ctx) throw new Error('could not acquire 2d context')
50
- __ctx.drawImage(__img, 0, 0)
51
- const __data = __ctx.getImageData(0, 0, __w, __h).data
52
- const __n = __data.length / 4
53
- let __r = 0, __g = 0, __b = 0, __a = 0
54
- for (let __i = 0; __i < __data.length; __i += 4) {
55
- __r += __data[__i]
56
- __g += __data[__i + 1]
57
- __b += __data[__i + 2]
58
- __a += __data[__i + 3]
59
- }
60
- const __round = (v) => Math.round(v / __n)
61
- const __rr = __round(__r), __gg = __round(__g), __bb = __round(__b), __aa = __round(__a)
62
- const __hex =
63
- '#' +
64
- [__rr, __gg, __bb]
65
- .map((v) => v.toString(16).padStart(2, '0'))
66
- .join('')
67
- const __dpr = window.devicePixelRatio || 1
68
- return {
69
- r: __rr, g: __gg, b: __bb, a: __aa,
70
- hex: __hex,
71
- samples: __n,
72
- rect: { x: __rect.x, y: __rect.y, w: __rect.w, h: __rect.h },
73
- deviceWidth: __w / __dpr,
74
- deviceHeight: __h / __dpr,
75
- }
76
- })()`}import{existsSync as Po,mkdirSync as jt,readFileSync as Ao,rmSync as He,writeFileSync as qt}from"fs";import{tmpdir as Do}from"os";import{dirname as Lt,join as Bo,resolve as Wt}from"path";import*as Me from"fs";function Eo(e){let t={},s=e,i=f=>Array.isArray(f)?f:[],c=e.match(/^---\n([\s\S]*?)\n---\n?/);if(c){try{t=de.parse(c[1])??{}}catch(p){console.warn(` warn: could not parse frontmatter: ${p.message}`)}s=e.slice(c[0].length);let f=de.parse(s);return{frontmatter:t,steps:i(f)}}if(/\n---\s*\n/.test(e))try{let f=de.parseAllDocuments(e);if(f.length>=2){let p=f[0].toJS(),h=f[f.length-1].toJS();return{frontmatter:p&&typeof p=="object"?p:{},steps:i(h)}}}catch(f){console.warn(` warn: could not parse multi-doc flow: ${f.message}`)}let l=de.parse(s);return{frontmatter:t,steps:i(l)}}var Ct=new Set(["tapOn","inputText","pressKey","dispatchKey","hideKeyboard","swipe","pinch","scroll","scrollUntilVisible"]);function Je(e){let t=[];if(!Array.isArray(e)||e.length===0)return t.push("flow body must be a non-empty YAML array of steps"),t;let s=0;for(let i of e)i&&typeof i=="object"?Object.keys(i).some(l=>Ct.has(l))&&(s+=1):typeof i=="string"&&Ct.has(i)&&(s+=1);return s===0&&t.push("no interaction steps found (expected at least one tapOn / inputText / pressKey / swipe / scroll)"),t}function Ns(e){if(!Me.existsSync(e))return[`file not found: ${e}`];let t;try{t=Me.readFileSync(e,"utf8")}catch(s){return[`cannot read file: ${s.message}`]}if(t.trim().length===0)return["file is empty"];try{let s=Eo(t);return Je(s.steps)}catch(s){return[`yaml parse error: ${s.message}`]}}var Ke=1;function Ne(){return Wt(process.env.SOOTSIM_FLOW_SESSION_PATH||Bo(Do(),"sootsim-flow-session.json"))}function Ue(e){let t=Ne();jt(Lt(t),{recursive:!0}),qt(t,JSON.stringify(e,null,2)+`
77
- `)}function Ge(){let e=Ne();if(!Po(e))return null;try{let t=JSON.parse(Ao(e,"utf8"));return t.version!==Ke||!Array.isArray(t.steps)||typeof t.startedAt!="string"||typeof t.updatedAt!="string"?(He(e,{force:!0}),null):{version:Ke,startedAt:t.startedAt,updatedAt:t.updatedAt,steps:t.steps,candidate:t.candidate??null}}catch{return He(e,{force:!0}),null}}function Ds(){let e=new Date().toISOString(),t={version:Ke,startedAt:e,updatedAt:e,steps:[],candidate:null};return Ue(t),{path:Ne(),state:t}}function Co(){He(Ne(),{force:!0})}function Bs(){Co()}function Fe(e){let t=Ge();if(!t)return{active:!1};let s=t.candidate,i={...t,updatedAt:new Date().toISOString(),candidate:{step:e.step,summary:e.summary,source:e.source,recordedAt:new Date().toISOString()}};return Ue(i),{active:!0,candidate:i.candidate,replaced:s}}function Cs(){let e=Ge();if(!e)return{active:!1,kept:!1,reason:"no-session"};if(!e.candidate)return{active:!0,kept:!1,reason:"no-candidate"};let t=e.candidate,s={...e,updatedAt:new Date().toISOString(),steps:[...e.steps,t.step],candidate:null};return Ue(s),{active:!0,kept:!0,candidate:t,stepCount:s.steps.length}}function jo(e){return de.stringify(e).trimEnd()+`
78
- `}function js(e){let t=Ge();if(!t)return{active:!1};let s=jo(t.steps),i=Je(t.steps);if(i.length>0)return{active:!0,valid:!1,issues:i,yaml:s,stepCount:t.steps.length,outputPath:null};let c=null;return e&&(c=Wt(e),jt(Lt(c),{recursive:!0}),qt(c,s)),{active:!0,valid:!0,issues:[],yaml:s,stepCount:t.steps.length,outputPath:c}}import{existsSync as qo,mkdirSync as Lo,readFileSync as Wo,rmSync as Jt,writeFileSync as Jo}from"fs";import{tmpdir as Ho}from"os";import{dirname as Ko,join as Uo,resolve as Go}from"path";var he=1,Yo="SOOTSIM_INSPECT_NOTICE_PATH",zo=300*1e3,Xo=15e3;function Ht(){return Go(process.env[Yo]||Uo(Ho(),"sootsim-inspect-notice-state.json"))}function Vo(e,t){return Object.fromEntries(Object.entries(e).filter(([,s])=>typeof s?.signature=="string"&&Number.isFinite(s?.updatedAt)&&t-s.updatedAt<=zo))}function Qo(e){let t=Ht();if(!qo(t))return{version:he,entries:{}};try{let s=JSON.parse(Wo(t,"utf8"));return s.version!==he||!s.entries||typeof s.entries!="object"?(Jt(t,{force:!0}),{version:he,entries:{}}):{version:he,entries:Vo(s.entries,e)}}catch{return Jt(t,{force:!0}),{version:he,entries:{}}}}function Zo(e){let t=Ht();Lo(Ko(t),{recursive:!0}),Jo(t,JSON.stringify(e,null,2)+`
9
+ })()`}import{existsSync as _o,mkdirSync as jt,readFileSync as Ao,rmSync as He,writeFileSync as qt}from"fs";import{tmpdir as Do}from"os";import{dirname as Lt,join as Bo,resolve as Wt}from"path";import*as Ne from"fs";function Po(e){let t={},s=e,i=f=>Array.isArray(f)?f:[],c=e.match(/^---\n([\s\S]*?)\n---\n?/);if(c){try{t=de.parse(c[1])??{}}catch(p){console.warn(` warn: could not parse frontmatter: ${p.message}`)}s=e.slice(c[0].length);let f=de.parse(s);return{frontmatter:t,steps:i(f)}}if(/\n---\s*\n/.test(e))try{let f=de.parseAllDocuments(e);if(f.length>=2){let p=f[0].toJS(),h=f[f.length-1].toJS();return{frontmatter:p&&typeof p=="object"?p:{},steps:i(h)}}}catch(f){console.warn(` warn: could not parse multi-doc flow: ${f.message}`)}let l=de.parse(s);return{frontmatter:t,steps:i(l)}}var Ct=new Set(["tapOn","inputText","pressKey","dispatchKey","hideKeyboard","swipe","pinch","scroll","scrollUntilVisible"]);function Je(e){let t=[];if(!Array.isArray(e)||e.length===0)return t.push("flow body must be a non-empty YAML array of steps"),t;let s=0;for(let i of e)i&&typeof i=="object"?Object.keys(i).some(l=>Ct.has(l))&&(s+=1):typeof i=="string"&&Ct.has(i)&&(s+=1);return s===0&&t.push("no interaction steps found (expected at least one tapOn / inputText / pressKey / swipe / scroll)"),t}function Ns(e){if(!Ne.existsSync(e))return[`file not found: ${e}`];let t;try{t=Ne.readFileSync(e,"utf8")}catch(s){return[`cannot read file: ${s.message}`]}if(t.trim().length===0)return["file is empty"];try{let s=Po(t);return Je(s.steps)}catch(s){return[`yaml parse error: ${s.message}`]}}var Ke=1;function Fe(){return Wt(process.env.SOOTSIM_FLOW_SESSION_PATH||Bo(Do(),"sootsim-flow-session.json"))}function Ue(e){let t=Fe();jt(Lt(t),{recursive:!0}),qt(t,JSON.stringify(e,null,2)+`
10
+ `)}function Ge(){let e=Fe();if(!_o(e))return null;try{let t=JSON.parse(Ao(e,"utf8"));return t.version!==Ke||!Array.isArray(t.steps)||typeof t.startedAt!="string"||typeof t.updatedAt!="string"?(He(e,{force:!0}),null):{version:Ke,startedAt:t.startedAt,updatedAt:t.updatedAt,steps:t.steps,candidate:t.candidate??null}}catch{return He(e,{force:!0}),null}}function As(){let e=new Date().toISOString(),t={version:Ke,startedAt:e,updatedAt:e,steps:[],candidate:null};return Ue(t),{path:Fe(),state:t}}function Co(){He(Fe(),{force:!0})}function Ds(){Co()}function Oe(e){let t=Ge();if(!t)return{active:!1};let s=t.candidate,i={...t,updatedAt:new Date().toISOString(),candidate:{step:e.step,summary:e.summary,source:e.source,recordedAt:new Date().toISOString()}};return Ue(i),{active:!0,candidate:i.candidate,replaced:s}}function Bs(){let e=Ge();if(!e)return{active:!1,kept:!1,reason:"no-session"};if(!e.candidate)return{active:!0,kept:!1,reason:"no-candidate"};let t=e.candidate,s={...e,updatedAt:new Date().toISOString(),steps:[...e.steps,t.step],candidate:null};return Ue(s),{active:!0,kept:!0,candidate:t,stepCount:s.steps.length}}function jo(e){return de.stringify(e).trimEnd()+`
11
+ `}function Cs(e){let t=Ge();if(!t)return{active:!1};let s=jo(t.steps),i=Je(t.steps);if(i.length>0)return{active:!0,valid:!1,issues:i,yaml:s,stepCount:t.steps.length,outputPath:null};let c=null;return e&&(c=Wt(e),jt(Lt(c),{recursive:!0}),qt(c,s)),{active:!0,valid:!0,issues:[],yaml:s,stepCount:t.steps.length,outputPath:c}}import{existsSync as qo,mkdirSync as Lo,readFileSync as Wo,rmSync as Jt,writeFileSync as Jo}from"fs";import{tmpdir as Ho}from"os";import{dirname as Ko,join as Uo,resolve as Go}from"path";var he=1,Yo="SOOTSIM_INSPECT_NOTICE_PATH",zo=300*1e3,Xo=15e3;function Ht(){return Go(process.env[Yo]||Uo(Ho(),"sootsim-inspect-notice-state.json"))}function Vo(e,t){return Object.fromEntries(Object.entries(e).filter(([,s])=>typeof s?.signature=="string"&&Number.isFinite(s?.updatedAt)&&t-s.updatedAt<=zo))}function Qo(e){let t=Ht();if(!qo(t))return{version:he,entries:{}};try{let s=JSON.parse(Wo(t,"utf8"));return s.version!==he||!s.entries||typeof s.entries!="object"?(Jt(t,{force:!0}),{version:he,entries:{}}):{version:he,entries:Vo(s.entries,e)}}catch{return Jt(t,{force:!0}),{version:he,entries:{}}}}function Zo(e){let t=Ht();Lo(Ko(t),{recursive:!0}),Jo(t,JSON.stringify(e,null,2)+`
79
12
  `)}function es(e,t){let s=t.trim()||"default";return`${e}:${s}`}function Ye(e,t,s,i={}){let c=i.nowMs??Date.now(),l=i.cooldownMs??Xo,f=Qo(c),p=es(e,t),h=f.entries[p];return h&&h.signature===s&&c-h.updatedAt<l?!1:(f.entries[p]={signature:s,updatedAt:c},Zo(f),!0)}async function se({bridge:e,simId:t,maxMs:s,pollMs:i=50,stablePolls:c=3,strict:l=!1}){let f=await e.send({type:"evaluate",simId:t,code:`(async () => {
80
13
  const start = Date.now()
81
14
  const deadline = start + ${Math.max(0,Math.round(s))}
@@ -234,7 +167,7 @@ import{a as de}from"./chunk-INBBOCU4.js";import{b as Et,c as Pt,l as At}from"./c
234
167
  requestedTarget,
235
168
  coordinateTarget,
236
169
  }
237
- })()`});if(k?.error)return{payload:h,result:{hit:!1,reason:k.error,requestedTarget:b},attempts:i,failure:"special"};if(k?.requestedTargetMatched===!1)return{payload:h,result:{hit:!1,reason:"target-covered",...k},attempts:i,failure:"missed"};let N=await e.send({type:"tap",x:h.cx,y:h.cy,target:b}),M=N&&typeof N=="object"?{...N,...k}:{hit:!!N,...k};if(l=M,me(M))return{payload:h,result:M,attempts:i}}let $=f-Date.now();if($<=0)break;try{await se({bridge:e,maxMs:Math.min($,s.retryWaitMs),pollMs:32,stablePolls:2})}catch{await new Promise(b=>setTimeout(b,Math.min(120,$)))}}return{payload:c,result:l,attempts:i,failure:c&&typeof c.cx=="number"?"missed":"not-found"}}async function Kt(e,t,s,i){return e.send({type:"tap",x:t,y:s,...i?{target:i}:{}})}async function Ut(e,t,s={}){let i=JSON.stringify(t);return be(e,{agent:s.agent,timing:s.timing,resolve:()=>e.send({type:"evaluate",code:`(async () => {
170
+ })()`});if(k?.error)return{payload:h,result:{hit:!1,reason:k.error,requestedTarget:b},attempts:i,failure:"special"};if(k?.requestedTargetMatched===!1)return{payload:h,result:{hit:!1,reason:"target-covered",...k},attempts:i,failure:"missed"};let F=await e.send({type:"tap",x:h.cx,y:h.cy,target:b}),N=F&&typeof F=="object"?{...F,...k}:{hit:!!F,...k};if(l=N,me(N))return{payload:h,result:N,attempts:i}}let $=f-Date.now();if($<=0)break;try{await se({bridge:e,maxMs:Math.min($,s.retryWaitMs),pollMs:32,stablePolls:2})}catch{await new Promise(b=>setTimeout(b,Math.min(120,$)))}}return{payload:c,result:l,attempts:i,failure:c&&typeof c.cx=="number"?"missed":"not-found"}}async function Kt(e,t,s,i){return e.send({type:"tap",x:t,y:s,...i?{target:i}:{}})}async function Ut(e,t,s={}){let i=JSON.stringify(t);return be(e,{agent:s.agent,timing:s.timing,resolve:()=>e.send({type:"evaluate",code:`(async () => {
238
171
  const t = window.__sootsimTest
239
172
  if (!t) return null
240
173
  const n = (await t.findByTestId(${i})) || (await t.findById(${i}))
@@ -459,17 +392,17 @@ import{a as de}from"./chunk-INBBOCU4.js";import{b as Et,c as Pt,l as At}from"./c
459
392
  }
460
393
  }
461
394
  return { strategy: 'none' }
462
- })()`});if(!c||!("node"in c))return c;let l=c.node,f=l.absolutePosition.x+l.layout.width/2,p=l.absolutePosition.y+l.layout.height/2,h=c.screen??null,$=!!h&&(f<0||p<0||f>h.width||p>h.height);return{...c,cx:f,cy:p,...$?{offscreen:!0,screen:h}:{},target:{id:l.id,testID:l.testID,text:c.strategy==="text"?t:l.text,type:l.type}}}})}async function zt(e,t={args:[]}){let s=await it(e);if(D(t.args)){A(s);return}console.log(` nodes: ${s.nodes}`)}function ze(e,t){let s=e.indexOf(t);return s>=0&&s+1<e.length?e[s+1]:null}async function Xt(e){let{bridge:t,args:s,positional:i}=e,c=s.includes("--verbose")||s.includes("-v"),l=D(s),f=c&&!l,p=s.includes("--watch")||s.includes("-w"),h=1e3,$=s.includes("--compact"),b=s.includes("--no-xy"),k=s.includes("--no-clipped"),N=s.includes("--include-occluded"),M=ze(s,"--testid-like"),j=ze(s,"--only"),O=ze(s,"--subtree"),d=i[1]&&!i[1].startsWith("-")?i[1]:void 0,q=d?/[*?]/.test(d):!1,R=!q&&!j?d:void 0,P=j??(q?d:void 0),J=async()=>{await pe(t,{verbose:f});let _=await ct(t,{describe:!0,verbose:c,filter:R||"",testIdLike:M||void 0,onlyGlob:P||void 0,subtreeRoot:O||void 0,compact:$,hideXy:b,includeOccluded:N,fullText:l}),F=_?.tree,H=_?.shell,K=_?.keyboard;if(l){A({shell:H,tree:F??"",keyboard:K});return}if(H&&typeof H=="object"){let C=[H.state?`state=${H.state}`:null,H.activeApp?`app=${H.activeApp}`:null,H.showSwitcher?"switcher":null,H.switcherPhase&&H.switcherPhase!=="idle"?`phase=${H.switcherPhase}`:null].filter(Boolean);C.length>0&&console.log(` shell: ${C.join(" ")}`)}if(typeof F=="string"&&F.startsWith("__SUBTREE_NOT_FOUND__:")){let C=F.slice(22);console.log(` subtree root not found: ${C}`),Q("subtree-root-not-found",C);return}if(!F){let C=_?.nodeCount??0;console.log(" no matching nodes found"),!(R||M||P||O)&&C<10&&Q("app-still-loading",C);return}let ee=F,te=0;if(k&&typeof ee=="string"){let C=ee.split(`
395
+ })()`});if(!c||!("node"in c))return c;let l=c.node,f=l.absolutePosition.x+l.layout.width/2,p=l.absolutePosition.y+l.layout.height/2,h=c.screen??null,$=!!h&&(f<0||p<0||f>h.width||p>h.height);return{...c,cx:f,cy:p,...$?{offscreen:!0,screen:h}:{},target:{id:l.id,testID:l.testID,text:c.strategy==="text"?t:l.text,type:l.type}}}})}async function zt(e,t={args:[]}){let s=await it(e);if(D(t.args)){A(s);return}console.log(` nodes: ${s.nodes}`)}function ze(e,t){let s=e.indexOf(t);return s>=0&&s+1<e.length?e[s+1]:null}async function Xt(e){let{bridge:t,args:s,positional:i}=e,c=s.includes("--verbose")||s.includes("-v"),l=D(s),f=c&&!l,p=s.includes("--watch")||s.includes("-w"),h=1e3,$=s.includes("--compact"),b=s.includes("--no-xy"),k=s.includes("--no-clipped"),F=s.includes("--include-occluded"),N=ze(s,"--testid-like"),j=ze(s,"--only"),R=ze(s,"--subtree"),d=i[1]&&!i[1].startsWith("-")?i[1]:void 0,q=d?/[*?]/.test(d):!1,E=!q&&!j?d:void 0,_=j??(q?d:void 0),J=async()=>{await pe(t,{verbose:f});let I=await ct(t,{describe:!0,verbose:c,filter:E||"",testIdLike:N||void 0,onlyGlob:_||void 0,subtreeRoot:R||void 0,compact:$,hideXy:b,includeOccluded:F,fullText:l}),O=I?.tree,H=I?.shell,K=I?.keyboard;if(l){A({shell:H,tree:O??"",keyboard:K});return}if(H&&typeof H=="object"){let C=[H.state?`state=${H.state}`:null,H.activeApp?`app=${H.activeApp}`:null,H.showSwitcher?"switcher":null,H.switcherPhase&&H.switcherPhase!=="idle"?`phase=${H.switcherPhase}`:null].filter(Boolean);C.length>0&&console.log(` shell: ${C.join(" ")}`)}if(typeof O=="string"&&O.startsWith("__SUBTREE_NOT_FOUND__:")){let C=O.slice(22);console.log(` subtree root not found: ${C}`),Q("subtree-root-not-found",C);return}if(!O){let C=I?.nodeCount??0;console.log(" no matching nodes found"),!(E||N||_||R)&&C<10&&Q("app-still-loading",C);return}let ee=O,te=0;if(k&&typeof ee=="string"){let C=ee.split(`
463
396
  `),le=[];for(let Se of C){if(Se.includes("(clipped:")){te+=1;continue}le.push(Se)}ee=le.join(`
464
- `)}console.log(ee),te>0&&console.log(` ${te} clipped row(s) hidden (omit --no-clipped to see)`);let ie=R||M||P||O;if((R||M||P)&&!p&&Q("describe-filter-context"),!ie&&!p&&F.split(`
397
+ `)}console.log(ee),te>0&&console.log(` ${te} clipped row(s) hidden (omit --no-clipped to see)`);let ie=E||N||_||R;if((E||N||_)&&!p&&Q("describe-filter-context"),!ie&&!p&&O.split(`
465
398
  `).length>=80&&Q("describe-use-filters"),K&&K.visible){let C=K.spec,le=[C?.keyboardType?`type=${C.keyboardType}`:null,C?.returnKeyType&&C.returnKeyType!=="default"?`return=${C.returnKeyType}`:null,K.mode!=="letters"?`mode=${K.mode}`:null,K.shifted?"shift":null,K.capsLock?"caps":null,C?.autoCapitalize&&C.autoCapitalize!=="sentences"?`autoCap=${C.autoCapitalize}`:null,K.accessoryBarId?`accessory=${K.accessoryBarId}`:null].filter(Boolean);console.log(`
466
399
  keyboard: ${le.join(" ")||"visible"}`)}};if(p)for(console.log(` watching... (Ctrl+C to stop)
467
- `);;)console.clear(),await J(),await oe(h);else await J()}var rs=["SOOTSIM_AGENT","TM_SESSION","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function fe(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let e of rs){let t=process.env[e];if(t&&t.trim()&&t!=="0")return!0}return!1}async function Vt(e){let{bridge:t,args:s,effectiveArgs:i,positional:c,inspectUsage:l}=e,f=_=>{let F=i.indexOf(_);return F>=0&&F+1<i.length?i[F+1]:null},p=_=>i.includes(_),h=f("--testid")||f("--test-id"),$=f("--role"),b=f("--type"),k=f("--text"),N=p("--pressable"),M=p("--visible"),j=p("--interactive-targets")||p("--actions"),O=!h&&!$&&!b&&!k&&!N&&!M&&!j?c[1]:null,d=k??O,q=await mt(t,{testId:h,role:$,type:b,text:d,pressable:N,visible:M,interactive:j});q||(console.error(l("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:R,result:P}=q,J=D(s),U=s.includes("--verbose")||s.includes("--dump");if(J)R==="interactive-targets"&&Array.isArray(P)?A(Be(P).map(_=>({..._,tap:Ce(_)}))):A(P??null);else if(Array.isArray(P))if(P.length===0){console.log(` no ${R} nodes found`);let _=await t.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof _=="number"&&_<10&&Q("app-still-loading",_)}else if(R==="interactive-targets"){let _=Be(P);console.log(` found ${_.length} interactive target${_.length===1?"":"s"} (sorted by score):`);for(let F of _.slice(0,20)){let H=F.absolutePosition?`@(${Math.round(F.absolutePosition.x)},${Math.round(F.absolutePosition.y)})`:"",K=F.layout?`${Math.round(F.layout.width)}x${Math.round(F.layout.height)}`:"?x?",ee=F.text?` "${F.text.slice(0,30)}"`:"",te=F.testID?` #${F.testID}`:"",ie=F.accessibilityLabel?` \u24D8"${String(F.accessibilityLabel).slice(0,24)}"`:"",xe=F.accessibilityRole?`[${F.accessibilityRole}]`:F.type,C=Ce(F);console.log(` ${xe}${ee}${ie}${te} ${K} ${H}`),console.log(` \u2192 ${C}`),U&&console.log(Xe(JSON.stringify(F,null,2)," "))}_.length>20&&console.log(` ... and ${_.length-20} more`)}else{console.log(` found ${P.length} node${P.length===1?"":"s"} (${R}):`);for(let _ of P.slice(0,20)){let F=_.absolutePosition?`@(${Math.round(_.absolutePosition.x)},${Math.round(_.absolutePosition.y)})`:"",H=_.layout?`${Math.round(_.layout.width)}x${Math.round(_.layout.height)}`:"?x?",K=_.text?` "${_.text.slice(0,30)}"`:"",ee=_.testID?` #${_.testID}`:"",te=_.pressable?" (tap)":"",ie=_.accessibilityRole?`[${_.accessibilityRole}]`:_.type;console.log(` ${ie}${K}${ee} ${H} ${F}${te}`),U&&console.log(Xe(JSON.stringify(_,null,2)," "))}P.length>20&&console.log(` ... and ${P.length-20} more`)}else if(P==null)console.log(` not found: ${d||h||$||b||""||R}`),h&&Q("wait-selector-for-missing-testid",h);else{let _=P;if(_.type&&_.absolutePosition){let F=`@(${Math.round(_.absolutePosition.x)},${Math.round(_.absolutePosition.y)})`,H=_.layout?`${Math.round(_.layout.width)}x${Math.round(_.layout.height)}`:"?x?",K=_.text?` "${_.text.slice(0,40)}"`:"",ee=_.testID?` #${_.testID}`:"",te=_.pressable?" (tap)":"",ie=_.accessibilityRole?`[${_.accessibilityRole}]`:_.type;console.log(` ${ie}${K}${ee} ${H} ${F}${te}`),U&&console.log(Xe(JSON.stringify(_,null,2)," "))}else console.log(JSON.stringify(P,null,2))}}function Xe(e,t){return e.split(`
400
+ `);;)console.clear(),await J(),await oe(h);else await J()}var rs=["SOOTSIM_AGENT","TM_SESSION","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function fe(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let e of rs){let t=process.env[e];if(t&&t.trim()&&t!=="0")return!0}return!1}async function Vt(e){let{bridge:t,args:s,effectiveArgs:i,positional:c,inspectUsage:l}=e,f=I=>{let O=i.indexOf(I);return O>=0&&O+1<i.length?i[O+1]:null},p=I=>i.includes(I),h=f("--testid")||f("--test-id"),$=f("--role"),b=f("--type"),k=f("--text"),F=p("--pressable"),N=p("--visible"),j=p("--interactive-targets")||p("--actions"),R=!h&&!$&&!b&&!k&&!F&&!N&&!j?c[1]:null,d=k??R,q=await mt(t,{testId:h,role:$,type:b,text:d,pressable:F,visible:N,interactive:j});q||(console.error(l("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:E,result:_}=q,J=D(s),U=s.includes("--verbose")||s.includes("--dump");if(J)E==="interactive-targets"&&Array.isArray(_)?A(Be(_).map(I=>({...I,tap:Ce(I)}))):A(_??null);else if(Array.isArray(_))if(_.length===0){console.log(` no ${E} nodes found`);let I=await t.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof I=="number"&&I<10&&Q("app-still-loading",I)}else if(E==="interactive-targets"){let I=Be(_);console.log(` found ${I.length} interactive target${I.length===1?"":"s"} (sorted by score):`);for(let O of I.slice(0,20)){let H=O.absolutePosition?`@(${Math.round(O.absolutePosition.x)},${Math.round(O.absolutePosition.y)})`:"",K=O.layout?`${Math.round(O.layout.width)}x${Math.round(O.layout.height)}`:"?x?",ee=O.text?` "${O.text.slice(0,30)}"`:"",te=O.testID?` #${O.testID}`:"",ie=O.accessibilityLabel?` \u24D8"${String(O.accessibilityLabel).slice(0,24)}"`:"",xe=O.accessibilityRole?`[${O.accessibilityRole}]`:O.type,C=Ce(O);console.log(` ${xe}${ee}${ie}${te} ${K} ${H}`),console.log(` \u2192 ${C}`),U&&console.log(Xe(JSON.stringify(O,null,2)," "))}I.length>20&&console.log(` ... and ${I.length-20} more`)}else{console.log(` found ${_.length} node${_.length===1?"":"s"} (${E}):`);for(let I of _.slice(0,20)){let O=I.absolutePosition?`@(${Math.round(I.absolutePosition.x)},${Math.round(I.absolutePosition.y)})`:"",H=I.layout?`${Math.round(I.layout.width)}x${Math.round(I.layout.height)}`:"?x?",K=I.text?` "${I.text.slice(0,30)}"`:"",ee=I.testID?` #${I.testID}`:"",te=I.pressable?" (tap)":"",ie=I.accessibilityRole?`[${I.accessibilityRole}]`:I.type;console.log(` ${ie}${K}${ee} ${H} ${O}${te}`),U&&console.log(Xe(JSON.stringify(I,null,2)," "))}_.length>20&&console.log(` ... and ${_.length-20} more`)}else if(_==null)console.log(` not found: ${d||h||$||b||""||E}`),h&&Q("wait-selector-for-missing-testid",h);else{let I=_;if(I.type&&I.absolutePosition){let O=`@(${Math.round(I.absolutePosition.x)},${Math.round(I.absolutePosition.y)})`,H=I.layout?`${Math.round(I.layout.width)}x${Math.round(I.layout.height)}`:"?x?",K=I.text?` "${I.text.slice(0,40)}"`:"",ee=I.testID?` #${I.testID}`:"",te=I.pressable?" (tap)":"",ie=I.accessibilityRole?`[${I.accessibilityRole}]`:I.type;console.log(` ${ie}${K}${ee} ${H} ${O}${te}`),U&&console.log(Xe(JSON.stringify(I,null,2)," "))}else console.log(JSON.stringify(_,null,2))}}function Xe(e,t){return e.split(`
468
401
  `).map(s=>t+s).join(`
469
402
  `)}async function Qt(e){let{bridge:t,args:s}=e,i=D(s);await pe(t,{verbose:!i});let c=s.includes("--styling"),l=s.indexOf("--filter"),f=l>=0?s[l+1]:void 0,p=await dt(t,{styling:c,filter:f});if(i){A({count:p.length,elements:p});return}console.log(` layout (${p.length} element${p.length===1?"":"s"}):
470
403
  `),console.log(ut(p,{styling:c}))}async function Zt(e,t={}){let s=await vt(e);if("error"in s&&(console.error(s.error),process.exit(1)),t.json){console.log(JSON.stringify(s,null,2));return}let{visible:i,spec:c,mode:l,shifted:f,capsLock:p,accessoryBarId:h}=s,$=[];$.push(`keyboard: ${i?"visible":"hidden"}`),c?($.push(` type: ${c.keyboardType}`),$.push(` returnKey: ${c.returnKeyType}`),$.push(` autoCap: ${c.autoCapitalize}`),$.push(` autoCorrect: ${c.autoCorrect?"on":"off"}`),$.push(` appearance: ${c.keyboardAppearance}`),c.secureTextEntry&&$.push(" secureTextEntry: true"),c.enablesReturnKeyAutomatically&&$.push(` return: ${c.currentTextIsEmpty?"disabled (empty)":"enabled"}`)):$.push(" spec: <none> (shown via dev-tools with no TextInput)"),$.push(` mode: ${l}${f?" (shifted)":""}${p?" (caps)":""}`),h&&$.push(` accessoryBar: ${h}`),console.log($.join(`
471
- `))}async function eo(e){let t=await e.bridge.listSims(),s=e.args.includes("--all"),i=e.args.find((p,h)=>e.args[h-1]==="--bundle"),c=e.args.find((p,h)=>e.args[h-1]==="--app-port"),l=e.args.includes("--primary"),f=t.filter(p=>!(l&&!p.isPrimary||i&&!(p.url??"").includes(i)||c&&!(p.url??"").includes(`/rn/${c}`)||!s&&!i&&!c&&!l&&!(p.url&&(p.url.includes("bundle=")||p.url.includes("/index.bundle")))&&p.id!==e.simId));if(D(e.args)){A(f.map(p=>({...p,active:p.id===e.simId})));return}At(f,e.simId),f.length<t.length&&!D(e.args)&&console.log(` (${t.length-f.length} more hidden \u2014 pass --all to show)`)}function re(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/1024/1024).toFixed(1)}MB`}function is(e,t){return t<=0?"?":`${(e/t*100).toFixed(0)}%`}function as(e){let t={},s=(i,c)=>{c&&(c.nodesRegistered!=null&&(t[`${i}.nodes`]=c.nodesRegistered),c.nodesDetached!=null&&(t[`${i}.detached`]=c.nodesDetached),c.objects&&(t[`${i}.paragraphs`]=c.objects.paragraphs,t[`${i}.yogaNodes`]=c.objects.yogaNodes,t[`${i}.pictures`]=c.objects.pictures,t[`${i}.rasterImages`]=c.objects.rasterImages),c.imageLoader&&(t[`${i}.imageCacheEntries`]=c.imageLoader.cacheEntries,t[`${i}.imagePixelBytes`]=c.imageLoader.cachePixelBytes),c.workerHeap&&(t[`${i}.heapBytes`]=c.workerHeap.usedJSHeapSize),c.wasmHeapBytes!=null&&(t[`${i}.wasmHeapBytes`]=c.wasmHeapBytes))};return s("tenant",e.tenant),s("shell",e.shell),s("compositor",e.compositor),e.hostHeap&&(t["host.heapBytes"]=e.hostHeap.usedJSHeapSize),t}function to(e,t){return e.endsWith("Bytes")?re(t):String(t)}function Ve(e,t){if(!t){console.log(` ${e}: not available`);return}let s=t.objects;if(console.log(` ${e}`),t.nodesRegistered!=null&&console.log(` nodes registered: ${t.nodesRegistered}`),t.nodesDetached!=null){let i=Object.entries(t.detachedTypes??{}).map(([c,l])=>`${c}:${l}`).join(" ");console.log(` nodes detached: ${t.nodesDetached}${i?` (${i})`:""}`)}if(s&&(console.log(` paragraphs: ${s.paragraphs}`),console.log(` yoga nodes: ${s.yogaNodes}`),console.log(` pictures: ${s.pictures}`),console.log(` raster images: ${s.rasterImages}`)),t.activeNativeAnimations!=null&&console.log(` native anims: ${t.activeNativeAnimations}`),t.imageLoader){let i=t.imageLoader;console.log(` image cache: ${i.cacheEntries}/${i.cacheMaxEntries} entries, ${re(i.cachePixelBytes)}/${re(i.cachePixelBudget)} (${is(i.cachePixelBytes,i.cachePixelBudget)})`)}t.workerHeap&&console.log(` js heap: ${re(t.workerHeap.usedJSHeapSize)} used / ${re(t.workerHeap.totalJSHeapSize)} total`),t.wasmHeapBytes!=null&&console.log(` canvaskit wasm: ${re(t.wasmHeapBytes)}`)}function ls(e){console.log(" memory:"),Ve("tenant worker",e.tenant),Ve("shell worker",e.shell),Ve("compositor worker",e.compositor),e.hostHeap?(console.log(" host"),console.log(` js heap: ${re(e.hostHeap.usedJSHeapSize)} used / ${re(e.hostHeap.totalJSHeapSize)} total`)):console.log(" host js heap: not available (chrome only)")}function cs(e,t,s){let i=e.indexOf(t);if(i===-1)return s;let c=Number(e[i+1]);return Number.isFinite(c)&&c>0?c:s}async function oo(e,t={args:[]}){let s=D(t.args),i=t.args.indexOf("--watch");if(i===-1){let O=await Le(e);if(s){A(O);return}ls(O);return}let c=Number(t.args[i+1]),l=Number.isFinite(c)&&c>0?c:60,f=cs(t.args,"--interval",5),p=[],h=Date.now(),$=null;for(s||console.log(` sampling every ${f}s for ${l}s \u2014 deltas per tick:`);;){let O=await Le(e),d=(Date.now()-h)/1e3,q=as(O);if(p.push({tSec:d,counters:q}),!s){let R=[];for(let[P,J]of Object.entries(q)){let U=$&&P in $?J-$[P]:null;if(U===null||U===0)continue;let _=U>0?"+":"-",F=P.endsWith("Bytes")?`${_}${re(Math.abs(U))}`:`${_}${Math.abs(U)}`;R.push(`${P} ${to(P,J)} (${F})`)}console.log(` t+${d.toFixed(0)}s ${R.length?R.join(" "):$?"no change":Object.entries(q).map(([P,J])=>`${P} ${to(P,J)}`).join(" ")}`)}if($=q,d>=l)break;await new Promise(R=>setTimeout(R,f*1e3))}let b=p[0],k=p[p.length-1],N=Math.max(k.tSec-b.tSec,.001),M={};for(let O of Object.keys(k.counters))O in b.counters&&(M[O]=(k.counters[O]-b.counters[O])/N);if(s){A({samples:p,perSecond:M,elapsedSec:N});return}console.log(`
472
- slope over ${N.toFixed(0)}s:`);let j=Object.entries(M).filter(([,O])=>O!==0).sort((O,d)=>Math.abs(d[1])-Math.abs(O[1]));if(j.length===0){console.log(" all counters flat");return}for(let[O,d]of j){let q=O.endsWith("Bytes")?`${re(Math.abs(d))}/s${d<0?" (shrinking)":""}`:`${d>0?"+":""}${d.toFixed(2)}/s`;console.log(` ${O.padEnd(28)}${q}`)}}var Z="<redacted secure text>";function we(e){let t=e?.layout?.spec??e?.spec??null;return!!t?.secureTextEntry&&t.keyboardType!=="visible-password"}function Qe(e,t){return we(t)?Z:e}function Ze(e){if(!e||!we(e))return e;let t=e.focusedInput;return!t||typeof t!="object"?e:{...e,focusedInput:{...t,secureTextEntry:!0,text:typeof t.text=="string"?Z:t.text}}}function $e(e,t){let s=e.indexOf("--testid");if(s>=0&&e[s+1])return{mode:"testid",value:e[s+1]};let i=e.indexOf("--test-id");if(i>=0&&e[i+1])return{mode:"testid",value:e[i+1]};let c=e.indexOf("--text");if(c>=0&&e[c+1])return{mode:"text",value:e[c+1]};let l=t?.[1];return l&&!l.startsWith("-")&&!Number.isFinite(Number(l))?{mode:"testid",value:l}:null}async function Oe(e,t){let s=JSON.stringify(t.value),i=t.mode==="testid"?`(await t.findByTestId(${s})) || (await t.findById(${s}))`:`await t.findByText(${s})`;return await e.send({type:"evaluate",code:`(async () => {
404
+ `))}async function eo(e){let t=await e.bridge.listSims(),s=e.args.includes("--all"),i=e.args.find((p,h)=>e.args[h-1]==="--bundle"),c=e.args.find((p,h)=>e.args[h-1]==="--app-port"),l=e.args.includes("--primary"),f=t.filter(p=>!(l&&!p.isPrimary||i&&!(p.url??"").includes(i)||c&&!(p.url??"").includes(`/rn/${c}`)||!s&&!i&&!c&&!l&&!(p.url&&(p.url.includes("bundle=")||p.url.includes("/index.bundle")))&&p.id!==e.simId));if(D(e.args)){A(f.map(p=>({...p,active:p.id===e.simId})));return}Bt(f,e.simId),f.length<t.length&&!D(e.args)&&console.log(` (${t.length-f.length} more hidden \u2014 pass --all to show)`)}function re(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/1024/1024).toFixed(1)}MB`}function is(e,t){return t<=0?"?":`${(e/t*100).toFixed(0)}%`}function as(e){let t={},s=(i,c)=>{c&&(c.nodesRegistered!=null&&(t[`${i}.nodes`]=c.nodesRegistered),c.nodesDetached!=null&&(t[`${i}.detached`]=c.nodesDetached),c.objects&&(t[`${i}.paragraphs`]=c.objects.paragraphs,t[`${i}.yogaNodes`]=c.objects.yogaNodes,t[`${i}.pictures`]=c.objects.pictures,t[`${i}.rasterImages`]=c.objects.rasterImages),c.imageLoader&&(t[`${i}.imageCacheEntries`]=c.imageLoader.cacheEntries,t[`${i}.imagePixelBytes`]=c.imageLoader.cachePixelBytes),c.workerHeap&&(t[`${i}.heapBytes`]=c.workerHeap.usedJSHeapSize),c.wasmHeapBytes!=null&&(t[`${i}.wasmHeapBytes`]=c.wasmHeapBytes))};return s("tenant",e.tenant),s("shell",e.shell),s("compositor",e.compositor),e.hostHeap&&(t["host.heapBytes"]=e.hostHeap.usedJSHeapSize),t}function to(e,t){return e.endsWith("Bytes")?re(t):String(t)}function Ve(e,t){if(!t){console.log(` ${e}: not available`);return}let s=t.objects;if(console.log(` ${e}`),t.nodesRegistered!=null&&console.log(` nodes registered: ${t.nodesRegistered}`),t.nodesDetached!=null){let i=Object.entries(t.detachedTypes??{}).map(([c,l])=>`${c}:${l}`).join(" ");console.log(` nodes detached: ${t.nodesDetached}${i?` (${i})`:""}`)}if(s&&(console.log(` paragraphs: ${s.paragraphs}`),console.log(` yoga nodes: ${s.yogaNodes}`),console.log(` pictures: ${s.pictures}`),console.log(` raster images: ${s.rasterImages}`)),t.activeNativeAnimations!=null&&console.log(` native anims: ${t.activeNativeAnimations}`),t.imageLoader){let i=t.imageLoader;console.log(` image cache: ${i.cacheEntries}/${i.cacheMaxEntries} entries, ${re(i.cachePixelBytes)}/${re(i.cachePixelBudget)} (${is(i.cachePixelBytes,i.cachePixelBudget)})`)}t.workerHeap&&console.log(` js heap: ${re(t.workerHeap.usedJSHeapSize)} used / ${re(t.workerHeap.totalJSHeapSize)} total`),t.wasmHeapBytes!=null&&console.log(` canvaskit wasm: ${re(t.wasmHeapBytes)}`)}function ls(e){console.log(" memory:"),Ve("tenant worker",e.tenant),Ve("shell worker",e.shell),Ve("compositor worker",e.compositor),e.hostHeap?(console.log(" host"),console.log(` js heap: ${re(e.hostHeap.usedJSHeapSize)} used / ${re(e.hostHeap.totalJSHeapSize)} total`)):console.log(" host js heap: not available (chrome only)")}function cs(e,t,s){let i=e.indexOf(t);if(i===-1)return s;let c=Number(e[i+1]);return Number.isFinite(c)&&c>0?c:s}async function oo(e,t={args:[]}){let s=D(t.args),i=t.args.indexOf("--watch");if(i===-1){let R=await Le(e);if(s){A(R);return}ls(R);return}let c=Number(t.args[i+1]),l=Number.isFinite(c)&&c>0?c:60,f=cs(t.args,"--interval",5),p=[],h=Date.now(),$=null;for(s||console.log(` sampling every ${f}s for ${l}s \u2014 deltas per tick:`);;){let R=await Le(e),d=(Date.now()-h)/1e3,q=as(R);if(p.push({tSec:d,counters:q}),!s){let E=[];for(let[_,J]of Object.entries(q)){let U=$&&_ in $?J-$[_]:null;if(U===null||U===0)continue;let I=U>0?"+":"-",O=_.endsWith("Bytes")?`${I}${re(Math.abs(U))}`:`${I}${Math.abs(U)}`;E.push(`${_} ${to(_,J)} (${O})`)}console.log(` t+${d.toFixed(0)}s ${E.length?E.join(" "):$?"no change":Object.entries(q).map(([_,J])=>`${_} ${to(_,J)}`).join(" ")}`)}if($=q,d>=l)break;await new Promise(E=>setTimeout(E,f*1e3))}let b=p[0],k=p[p.length-1],F=Math.max(k.tSec-b.tSec,.001),N={};for(let R of Object.keys(k.counters))R in b.counters&&(N[R]=(k.counters[R]-b.counters[R])/F);if(s){A({samples:p,perSecond:N,elapsedSec:F});return}console.log(`
405
+ slope over ${F.toFixed(0)}s:`);let j=Object.entries(N).filter(([,R])=>R!==0).sort((R,d)=>Math.abs(d[1])-Math.abs(R[1]));if(j.length===0){console.log(" all counters flat");return}for(let[R,d]of j){let q=R.endsWith("Bytes")?`${re(Math.abs(d))}/s${d<0?" (shrinking)":""}`:`${d>0?"+":""}${d.toFixed(2)}/s`;console.log(` ${R.padEnd(28)}${q}`)}}var Z="<redacted secure text>";function we(e){let t=e?.layout?.spec??e?.spec??null;return!!t?.secureTextEntry&&t.keyboardType!=="visible-password"}function Qe(e,t){return we(t)?Z:e}function Ze(e){if(!e||!we(e))return e;let t=e.focusedInput;return!t||typeof t!="object"?e:{...e,focusedInput:{...t,secureTextEntry:!0,text:typeof t.text=="string"?Z:t.text}}}function $e(e,t){let s=e.indexOf("--testid");if(s>=0&&e[s+1])return{mode:"testid",value:e[s+1]};let i=e.indexOf("--test-id");if(i>=0&&e[i+1])return{mode:"testid",value:e[i+1]};let c=e.indexOf("--text");if(c>=0&&e[c+1])return{mode:"text",value:e[c+1]};let l=t?.[1];return l&&!l.startsWith("-")&&!Number.isFinite(Number(l))?{mode:"testid",value:l}:null}async function Re(e,t){let s=JSON.stringify(t.value),i=t.mode==="testid"?`(await t.findByTestId(${s})) || (await t.findById(${s}))`:`await t.findByText(${s})`;return await e.send({type:"evaluate",code:`(async () => {
473
406
  const t = window.__sootsimTest
474
407
  if (!t) return null
475
408
  const n = ${i}
@@ -494,12 +427,12 @@ import{a as de}from"./chunk-INBBOCU4.js";import{b as Et,c as Pt,l as At}from"./c
494
427
  text: ${JSON.stringify(t.mode==="text")} ? ${s} : (n.text ?? n.accessibilityLabel ?? null),
495
428
  type: n.type ?? null,
496
429
  }
497
- })()`})??null}async function so(e,t={}){let{nav:s,route:i,keyboard:c,shell:l}=await kt(e);if(t.json){console.log(JSON.stringify({shell:l??null,nav:s,route:i,keyboard:c},null,2));return}let f=[];if(l){let p=l.activeApp??l.state??"<none>",h=l.showSwitcher?" (app switcher open)":"",$=typeof l.launchProgress=="number"&&l.launchProgress<.98?` launching (${Math.round(l.launchProgress*100)}%)`:"";f.push(`shell: ${p}${h}${$}`)}else f.push("shell: <unavailable>");if(s){let p=s.transitionPhase!=="idle"?` (${s.transitionPhase}, ${s.activeTransitionCount} active)`:"";if(f.push(`nav: phase=${s.transitionPhase}${p}`),s.screens.length===0)f.push(" <no registered screens \u2014 app may not use react-native-screens>");else for(let h of s.screens){let $=h.isActive?"\u25B6":" ",b=h.routeName?` ${h.routeName}`:"",k=h.headerHeight>0?` header=${h.headerHeight}`:"",N=h.largeTitleState&&h.largeTitleState!=="expanded"?` large-title=${h.largeTitleState}`:"";f.push(` ${$} #${h.id}${b}${k}${N}`)}}else f.push("nav: <runtime not available>");if(f.push(`route: ${i?.currentPath??"<unavailable>"}`),i?.coveringPath&&f.push(`covered: a presented screen (${i.coveringPath}) is above this route`),c&&c.visible){let p=c.spec?.keyboardType??"default",h=c.spec?.returnKeyType??"default";f.push(`keyboard: visible (${p}, return=${h}, mode=${c.mode??"?"})`)}else f.push("keyboard: hidden");console.log(f.join(`
498
- `))}async function no(e){let{bridge:t,args:s,positional:i}=e,c=i[1]?Number(i[1])*1e3:3e3,l=s.includes("--strict"),{elapsed:f,settled:p}=await se({bridge:t,maxMs:c,strict:l});console.log(p?` settled in ${f}ms`:` timed out after ${f}ms (may still be animating)`)}async function ro(e){let t=e.positional[1]?Number(e.positional[1]):.5;(!Number.isFinite(t)||t<0)&&(console.error(e.inspectUsage("sleep","[seconds]")),process.exit(1)),await oe(t*1e3),console.log(` slept ${t}s`)}async function io(e){let{bridge:t,args:s,positional:i}=e,c=s.includes("--boxes"),l=i[1]?Number(i[1]):c?50:5,{tree:f}=await at(t,l,c?{format:"boxes"}:void 0);if(D(s)){A({depth:l,tree:f??null});return}console.log(typeof f=="string"?f:JSON.stringify(f,null,2))}async function ao(e,t={args:[]}){let s=await lt(e);if(D(t.args)){A(s);return}console.log(s.url)}async function lo(e){let{wsPort:t,commandTimeoutMs:s,simId:i,simIdSource:c,positional:l}=e,f=l[1]?Number(l[1]):30,p=Math.max(1e3,(Number.isFinite(f)?f:30)*1e3),h=Math.max(1,Math.ceil(p/500));console.log(" waiting for sim reconnect...");let $=await Ft(t,s,i,{attempts:h,simIdSource:c});$||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),$.bridge.close(),Fe({source:"inspect wait",step:{wait:p},summary:`wait ${Math.round(p/1e3)}s`}),console.log(` ready: ${$.count} nodes`)}var co=new Set(["app-launch","toast","keyboard","screen","flow-step","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function Re(e,t){let s=e.indexOf(t);if(s>=0&&s+1<e.length)return e[s+1]}function ds(e,t){if(!t.filter&&!t.equals)return!0;let s=e.data,i=[];if(s&&typeof s=="object")for(let l of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let f=s[l];typeof f=="string"&&f.length>0&&i.push(f)}let c=i.join(" ");return t.equals?i.some(l=>l===t.equals):t.filter?c.toLowerCase().includes(t.filter.toLowerCase()):!0}async function uo(e){let{bridge:t,args:s,positional:i,inspectUsage:c}=e,l=i[1];l||(console.error(c("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),co.has(l)||console.error(` warning: '${l}' is not a known timeline kind \u2014 waiting anyway. known: ${[...co].sort().join(", ")}`);let f=Re(s,"--max-ms"),p=f&&Number.isFinite(Number(f))?Math.max(100,Number(f)):5e3,h=Re(s,"--filter"),$=Re(s,"--equals"),b=Re(s,"--since")??"now",k=s.includes("--json"),N=Date.now(),M=N+p,j=200,O=N;for(;Date.now()<M;){let q={kinds:[l],since:b==="cursor"?void 0:O,limit:50},R=await t.send({type:"evaluate",code:`(async () => {
430
+ })()`})??null}async function so(e,t={}){let{nav:s,route:i,keyboard:c,shell:l}=await kt(e);if(t.json){console.log(JSON.stringify({shell:l??null,nav:s,route:i,keyboard:c},null,2));return}let f=[];if(l){let p=l.activeApp??l.state??"<none>",h=l.showSwitcher?" (app switcher open)":"",$=typeof l.launchProgress=="number"&&l.launchProgress<.98?` launching (${Math.round(l.launchProgress*100)}%)`:"";f.push(`shell: ${p}${h}${$}`)}else f.push("shell: <unavailable>");if(s){let p=s.transitionPhase!=="idle"?` (${s.transitionPhase}, ${s.activeTransitionCount} active)`:"";if(f.push(`nav: phase=${s.transitionPhase}${p}`),s.screens.length===0)f.push(" <no registered screens \u2014 app may not use react-native-screens>");else for(let h of s.screens){let $=h.isActive?"\u25B6":" ",b=h.routeName?` ${h.routeName}`:"",k=h.headerHeight>0?` header=${h.headerHeight}`:"",F=h.largeTitleState&&h.largeTitleState!=="expanded"?` large-title=${h.largeTitleState}`:"";f.push(` ${$} #${h.id}${b}${k}${F}`)}}else f.push("nav: <runtime not available>");if(f.push(`route: ${i?.currentPath??"<unavailable>"}`),i?.coveringPath&&f.push(`covered: a presented screen (${i.coveringPath}) is above this route`),c&&c.visible){let p=c.spec?.keyboardType??"default",h=c.spec?.returnKeyType??"default";f.push(`keyboard: visible (${p}, return=${h}, mode=${c.mode??"?"})`)}else f.push("keyboard: hidden");console.log(f.join(`
431
+ `))}async function no(e){let{bridge:t,args:s,positional:i}=e,c=i[1]?Number(i[1])*1e3:3e3,l=s.includes("--strict"),{elapsed:f,settled:p}=await se({bridge:t,maxMs:c,strict:l});console.log(p?` settled in ${f}ms`:` timed out after ${f}ms (may still be animating)`)}async function ro(e){let t=e.positional[1]?Number(e.positional[1]):.5;(!Number.isFinite(t)||t<0)&&(console.error(e.inspectUsage("sleep","[seconds]")),process.exit(1)),await oe(t*1e3),console.log(` slept ${t}s`)}async function io(e){let{bridge:t,args:s,positional:i}=e,c=s.includes("--boxes"),l=i[1]?Number(i[1]):c?50:5,{tree:f}=await at(t,l,c?{format:"boxes"}:void 0);if(D(s)){A({depth:l,tree:f??null});return}console.log(typeof f=="string"?f:JSON.stringify(f,null,2))}async function ao(e,t={args:[]}){let s=await lt(e);if(D(t.args)){A(s);return}console.log(s.url)}async function lo(e){let{wsPort:t,commandTimeoutMs:s,simId:i,simIdSource:c,positional:l}=e,f=l[1]?Number(l[1]):30,p=Math.max(1e3,(Number.isFinite(f)?f:30)*1e3),h=Math.max(1,Math.ceil(p/500));console.log(" waiting for sim reconnect...");let $=await Ot(t,s,i,{attempts:h,simIdSource:c});$||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),$.bridge.close(),Oe({source:"inspect wait",step:{wait:p},summary:`wait ${Math.round(p/1e3)}s`}),console.log(` ready: ${$.count} nodes`)}var co=new Set(["app-launch","toast","keyboard","screen","flow-step","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function Ee(e,t){let s=e.indexOf(t);if(s>=0&&s+1<e.length)return e[s+1]}function ds(e,t){if(!t.filter&&!t.equals)return!0;let s=e.data,i=[];if(s&&typeof s=="object")for(let l of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let f=s[l];typeof f=="string"&&f.length>0&&i.push(f)}let c=i.join(" ");return t.equals?i.some(l=>l===t.equals):t.filter?c.toLowerCase().includes(t.filter.toLowerCase()):!0}async function uo(e){let{bridge:t,args:s,positional:i,inspectUsage:c}=e,l=i[1];l||(console.error(c("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),co.has(l)||console.error(` warning: '${l}' is not a known timeline kind \u2014 waiting anyway. known: ${[...co].sort().join(", ")}`);let f=Ee(s,"--max-ms"),p=f&&Number.isFinite(Number(f))?Math.max(100,Number(f)):5e3,h=Ee(s,"--filter"),$=Ee(s,"--equals"),b=Ee(s,"--since")??"now",k=s.includes("--json"),F=Date.now(),N=F+p,j=200,R=F;for(;Date.now()<N;){let q={kinds:[l],since:b==="cursor"?void 0:R,limit:50},E=await t.send({type:"evaluate",code:`(async () => {
499
432
  const t = window.SootSim?.bridges?.timeline
500
433
  if (!t) return { ok: false, error: 'timeline bridge missing' }
501
434
  return { ok: true, result: await t.recent(${JSON.stringify(q)}) }
502
- })()`});(!R||!R.ok)&&(console.error(` could not query timeline: ${R&&"error"in R?R.error:"unknown"}`),process.exit(1));let P=R.result.events??[];for(let J of P)if(ds(J,{filter:h,equals:$})){let U=Date.now()-N;console.log(k?JSON.stringify({found:!0,elapsedMs:U,event:J}):` ${l} event after ${U}ms${h?` (filter: ${h})`:""}${$?` (equals: ${$})`:""}`);return}R.result.watermark&&R.result.watermark>O&&(O=R.result.watermark),await new Promise(J=>setTimeout(J,j))}let d=Date.now()-N;k?console.log(JSON.stringify({found:!1,elapsedMs:d,kind:l,filter:h,equals:$})):console.error(` \u26A0 wait event ${l} timed out after ${d}ms${h?` (filter: ${h})`:""}${$?` (equals: ${$})`:""}`),process.exit(1)}async function po(e){let{bridge:t,args:s}=e,i=s.includes("--strict"),c=ke(s,3e3),{elapsed:l,settled:f}=await se({bridge:t,maxMs:c,strict:i});f?console.log(` idle in ${l}ms`):(console.error(` \u26A0 wait idle timed out after ${l}ms (may still be animating)`),process.exit(1))}async function mo(e){let{bridge:t,args:s}=e,i=ke(s,2e4),{ready:c,elapsedMs:l,nodes:f,targets:p,liveFrameActive:h,liveFrameChannels:$,flag:b,loadingText:k,externalReady:N,externalError:M,suppressedEntryError:j,errors:O,bridgeError:d}=await ft(t,i,{onProgress(R){console.error(` still waiting after ${R.elapsedMs}ms \u2014 ${je(R)} (nodes: ${R.nodes}, targets: ${R.targets}, live surfaces: ${R.liveFrameActive?R.liveFrameChannels:0}, errors: ${R.errors})`)}});if(c){let R=i-l,P=Math.max(100,Math.min(1e4,R)),J=await se({bridge:t,maxMs:P,pollMs:32,stablePolls:2});J.settled||(console.error(` \u26A0 wait ready timed out after ${l+J.elapsed}ms \u2014 app mounted but did not settle (nodes: ${f}, targets: ${p})`),process.exit(1)),console.log(` ready in ${l+J.elapsed}ms: ${f} nodes, ${p} targets${h?`, ${$} live surfaces`:""}`);return}let q=je({externalError:M,loadingText:k,externalReady:N,flag:b,targets:p,suppressedEntryError:j,bridgeError:d});console.error(` \u26A0 wait ready timed out after ${l}ms \u2014 ${q} (nodes: ${f}, targets: ${p}, live surfaces: ${h?$:0}, errors: ${O})`),process.exit(1)}async function fo(e){let{bridge:t,args:s,positional:i,inspectUsage:c}=e,l=i[1];l||(console.error(c("wait selector","<testid> [--max-ms 5000] [--gone]")),process.exit(1));let f=s.indexOf("--max-ms"),p=f>=0&&s[f+1]?Math.max(100,Number(s[f+1])):5e3,h=s.includes("--gone"),{found:$,node:b,elapsed:k}=await gt(t,l,p,{gone:h});if(h){$?console.log(` #${l} gone after ${k}ms`):(console.error(` \u26A0 wait selector #${l} --gone timed out after ${k??p}ms (still present)`),process.exit(1));return}if($&&b){let N=b.absolutePosition?`@(${Math.round(b.absolutePosition.x)},${Math.round(b.absolutePosition.y)})`:"",M=b.layout?`${Math.round(b.layout.width)}x${Math.round(b.layout.height)}`:"?x?";console.log(` found #${l} in ${k}ms ${M} ${N}`)}else console.error(` \u26A0 wait selector #${l} timed out after ${k??p}ms`),process.exit(1)}function _o(e){return e==null?"\u2014":e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}K`:`${(e/1024/1024).toFixed(1)}M`}function Io(e){return e==null?" \u2026":e<1e3?`${e}ms`.padStart(5):`${(e/1e3).toFixed(2)}s`.padStart(5)}function go(){process.stderr.write(` the sim is not responding. recover it with:
435
+ })()`});(!E||!E.ok)&&(console.error(` could not query timeline: ${E&&"error"in E?E.error:"unknown"}`),process.exit(1));let _=E.result.events??[];for(let J of _)if(ds(J,{filter:h,equals:$})){let U=Date.now()-F;console.log(k?JSON.stringify({found:!0,elapsedMs:U,event:J}):` ${l} event after ${U}ms${h?` (filter: ${h})`:""}${$?` (equals: ${$})`:""}`);return}E.result.watermark&&E.result.watermark>R&&(R=E.result.watermark),await new Promise(J=>setTimeout(J,j))}let d=Date.now()-F;k?console.log(JSON.stringify({found:!1,elapsedMs:d,kind:l,filter:h,equals:$})):console.error(` \u26A0 wait event ${l} timed out after ${d}ms${h?` (filter: ${h})`:""}${$?` (equals: ${$})`:""}`),process.exit(1)}async function po(e){let{bridge:t,args:s}=e,i=s.includes("--strict"),c=ke(s,3e3),{elapsed:l,settled:f}=await se({bridge:t,maxMs:c,strict:i});f?console.log(` idle in ${l}ms`):(console.error(` \u26A0 wait idle timed out after ${l}ms (may still be animating)`),process.exit(1))}async function mo(e){let{bridge:t,args:s}=e,i=ke(s,2e4),{ready:c,elapsedMs:l,nodes:f,targets:p,liveFrameActive:h,liveFrameChannels:$,flag:b,loadingText:k,externalReady:F,externalError:N,suppressedEntryError:j,errors:R,bridgeError:d}=await ft(t,i,{onProgress(E){console.error(` still waiting after ${E.elapsedMs}ms \u2014 ${je(E)} (nodes: ${E.nodes}, targets: ${E.targets}, live surfaces: ${E.liveFrameActive?E.liveFrameChannels:0}, errors: ${E.errors})`)}});if(c){let E=i-l,_=Math.max(100,Math.min(1e4,E)),J=await se({bridge:t,maxMs:_,pollMs:32,stablePolls:2});J.settled||(console.error(` \u26A0 wait ready timed out after ${l+J.elapsed}ms \u2014 app mounted but did not settle (nodes: ${f}, targets: ${p})`),process.exit(1)),console.log(` ready in ${l+J.elapsed}ms: ${f} nodes, ${p} targets${h?`, ${$} live surfaces`:""}`);return}let q=je({externalError:N,loadingText:k,externalReady:F,flag:b,targets:p,suppressedEntryError:j,bridgeError:d});console.error(` \u26A0 wait ready timed out after ${l}ms \u2014 ${q} (nodes: ${f}, targets: ${p}, live surfaces: ${h?$:0}, errors: ${R})`),process.exit(1)}async function fo(e){let{bridge:t,args:s,positional:i,inspectUsage:c}=e,l=i[1];l||(console.error(c("wait selector","<testid> [--max-ms 5000] [--gone]")),process.exit(1));let f=s.indexOf("--max-ms"),p=f>=0&&s[f+1]?Math.max(100,Number(s[f+1])):5e3,h=s.includes("--gone"),{found:$,node:b,elapsed:k}=await gt(t,l,p,{gone:h});if(h){$?console.log(` #${l} gone after ${k}ms`):(console.error(` \u26A0 wait selector #${l} --gone timed out after ${k??p}ms (still present)`),process.exit(1));return}if($&&b){let F=b.absolutePosition?`@(${Math.round(b.absolutePosition.x)},${Math.round(b.absolutePosition.y)})`:"",N=b.layout?`${Math.round(b.layout.width)}x${Math.round(b.layout.height)}`:"?x?";console.log(` found #${l} in ${k}ms ${N} ${F}`)}else console.error(` \u26A0 wait selector #${l} timed out after ${k??p}ms`),process.exit(1)}function Io(e){return e==null?"\u2014":e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}K`:`${(e/1024/1024).toFixed(1)}M`}function To(e){return e==null?" \u2026":e<1e3?`${e}ms`.padStart(5):`${(e/1e3).toFixed(2)}s`.padStart(5)}function go(){process.stderr.write(` the sim is not responding. recover it with:
503
436
  sootsim close --sim <id> # force-close the wedged sim
504
437
  sootsim list # confirm it's gone
505
438
  `)}async function ps(e){try{return await e.send({type:"evaluate",code:"1"},{timeoutMs:3e3}),!0}catch{return!1}}async function ms(e,t){try{let s=await e.send({type:"evaluate",code:`(async () => {
@@ -521,9 +454,9 @@ import{a as de}from"./chunk-INBBOCU4.js";import{b as Et,c as Pt,l as At}from"./c
521
454
  } catch {
522
455
  return []
523
456
  }
524
- })()`});if(!Array.isArray(s)||s.length===0)return;let i=t.toLowerCase(),c=s.map(l=>({id:l,score:fs(i,l.toLowerCase())})).filter(l=>l.score<i.length+4).sort((l,f)=>l.score-f.score).slice(0,5);if(c.length===0)return;console.error(" similar testIDs:");for(let l of c)console.error(` ${l.id}`)}catch{}}function fs(e,t){if(t===e)return 0;if(t.includes(e))return 1;if(e.includes(t))return 2;let s=0;for(;s<e.length&&s<t.length&&e[s]===t[s];)s+=1;return gs(e,t)-s}function gs(e,t){if(e===t)return 0;if(!e.length)return t.length;if(!t.length)return e.length;let s=new Array(t.length+1),i=new Array(t.length+1);for(let c=0;c<=t.length;c++)s[c]=c;for(let c=1;c<=e.length;c++){i[0]=c;for(let f=1;f<=t.length;f++)i[f]=Math.min(s[f]+1,i[f-1]+1,s[f-1]+(e[c-1]===t[f-1]?0:1));let l=s;s=i,i=l}return s[t.length]}function ys(e){return e.error?"err":e.status==null?" \u2026 ":String(e.status)}function yo(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 ho(e){let t=ae(e.startTs),s=ys(e).padEnd(3),i=e.method.padEnd(5),c=_o(e.size).padStart(6),l=Io(e.durationMs);console.log(` [${t}] ${s} ${i} ${c} ${l} ${e.displayUrl}`),e.error&&console.log(` error: ${e.error}`)}function hs(e){let t=[["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",ae(e.startTs)],["duration",Io(e.durationMs).trim()],["size",_o(e.size)],["content-type",e.type??"\u2014"]];for(let[s,i]of t)console.log(` ${s.padEnd(13)} ${i}`)}var bs={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},bo="\x1B[0m",ws="\x1B[2m";function wo(e,t){let s=ae(e.ts),i=e.level.toUpperCase().padEnd(5),c=e.args.join(" ");if(t){let l=bs[e.level];console.log(` ${ws}[${s}]${bo} ${l}${i}${bo} ${c}`)}else console.log(` [${s}] ${i} ${c}`);if(e.stack&&e.level==="error"){let l=e.stack.split(`
525
- `).slice(0,5);for(let f of l)console.log(` ${f.trim()}`)}}var $s=120;async function $o(e,t){let s=e.find((N,M)=>e[M-1]==="--id"),i=e.find((N,M)=>e[M-1]==="--text");if(s||i){let N=await t.send({type:"evaluate",code:Dt({id:s,text:i})});if(!N)throw new Error(s?`no node with id "${s}"`:`no node matching text "${i}"`);let{x:M,y:j,w:O,h:d}=N;return{x:M,y:j,w:O,h:d}}let c=e.find((N,M)=>e[M-1]==="--area");if(c){let N=c.split(",").map(q=>Number(q.trim()));if(N.length!==4||N.some(q=>!Number.isFinite(q)))throw new Error(`--area expects x,y,w,h (got "${c}")`);let[M,j,O,d]=N;return{x:M,y:j,w:O,h:d}}let l=N=>{let M=e.find((O,d)=>e[d-1]===N);if(M==null)return null;let j=Number(M);return Number.isFinite(j)?j:null},f=l("--x"),p=l("--y"),h=l("--w"),$=l("--h");if(f!=null||p!=null||h!=null||$!=null)return{x:f??0,y:p??0,w:h??1,h:$??1};let k=e.filter((N,M)=>M>0&&!N.startsWith("-")&&e[M-1]!=="--output"&&e[M-1]!=="--area"&&e[M-1]!=="--id"&&e[M-1]!=="--text"&&e[M-1]!=="--x"&&e[M-1]!=="--y"&&e[M-1]!=="--w"&&e[M-1]!=="--h").map(Number).filter(N=>Number.isFinite(N));if(k.length>=2){let[N,M,j=1,O=1]=k;return{x:N,y:M,w:j,h:O}}return null}function xo(e,t){if(!t||typeof t!="object")return;console.log(""),console.log(` render profile \u2014 ${e} (per painted frame):`),console.log(` node visits: ${t.nodeVisitsPerFrame}`),console.log(` boundaries: ${t.recordsPerFrame} records (${t.avgBoundaryRecordMs}ms) / ${t.replaysPerFrame} replays`);let s=[t.boundaryRecordsInvalidated?`invalidated ${t.boundaryRecordsInvalidated}`:"",t.boundaryRecordsOrigin?`moved ${t.boundaryRecordsOrigin}`:"",t.boundaryRecordsScheme?`first-record ${t.boundaryRecordsScheme}`:""].filter(Boolean).join(" \xB7 ");s&&console.log(` why recorded: ${s}`),t.prewarmRecords&&console.log(` pre-recorded: ${t.prewarmRecords} boundaries at idle (${Number(t.prewarmRecordMs).toFixed(1)}ms total)`),console.log(` raster tier: ${t.rasterPromotionsPerFrame} promotions / ${t.rasterBlitsPerFrame} blits`);let i=[t.rasterRejectRebuild?`rebuild ${t.rasterRejectRebuild}`:"",t.rasterRejectLinear?`linear ${t.rasterRejectLinear}`:"",t.rasterRejectAnimated?`animated ${t.rasterRejectAnimated}`:"",t.rasterRejectTransform?`transform ${t.rasterRejectTransform}`:"",t.rasterRejectOpacity?`opacity ${t.rasterRejectOpacity}`:"",t.rasterRejectCacheable?`cacheable ${t.rasterRejectCacheable}`:"",t.rasterRejectBounds?`bounds ${t.rasterRejectBounds}`:"",t.rasterRejectPixels?`pixels ${t.rasterRejectPixels}`:"",t.rasterRejectBudget?`budget ${t.rasterRejectBudget}`:"",t.rasterWarming?`warming ${t.rasterWarming}`:""].filter(Boolean).join(" \xB7 ");i&&(console.log(` raster skips: ${i} (total across run)`),t.rasterRejectAlsoBlocked&&console.log(` ${"".padEnd(12)} ${t.rasterRejectAlsoBlocked} of those also fail a later gate \u2014 widening the named gate cannot promote them`)),console.log(` blur: ${t.avgBlurMs}ms`),(t.glassDownsampleActive||t.glassBackdropCacheMisses)&&console.log(` glass: ${t.glassDownsampleFactor}x downsample (${t.glassDownsampledDraws} draws) \xB7 cache ${t.glassBackdropCacheHits} hits / ${t.glassBackdropCacheMisses} misses / ${t.glassBackdropCacheInvalidations} invalidations`),console.log(` draw calls: text ${t.textDrawsPerFrame} \xB7 image ${t.imageDrawsPerFrame} \xB7 path ${t.pathDrawsPerFrame} \xB7 saveLayer ${t.saveLayersPerFrame}`)}function So(e){let t=e.avgMs>0?(1e3/e.avgMs).toFixed(1):"?",s=e.jank&&typeof e.jank=="object"?e.jank:null;if(console.log(` shell frame profile:
526
- `),s){let h=(Array.isArray(s.compositor)?s.compositor:[]).reduce(($,b)=>$+(b.jankPaints??0),0);console.log(` health: ${s.detected?"jank or cadence gaps observed":"no jank or cadence gaps observed"} \xB7 shell ${s.shell?.jankFrames??0} \xB7 compositor ${h} \xB7 host clock gaps ${s.hostGaps??0}`),console.log(" series: independent worker clocks, no per-frame pairing")}if(console.log(` painted frames: ${e.frames}${e.skippedFrames?` (+${e.skippedFrames} skipped idle ticks)`:""}`),console.log(` shell work avg: ${e.avgMs}ms (${t} fps) \xB7 worst observed ${e.maxMs}ms`),console.log(` shell p50/95/99:${e.p50} / ${e.p95} / ${e.p99} ms`),s){console.log(` shell jank: ${s.shell?.jankFrames??0}/${s.shell?.sampledFrames??0} (${s.shell?.jankPct??0}%) >16.67ms \xB7 max ${s.shell?.maxMs??0}ms`);for(let p of Array.isArray(s.compositor)?s.compositor:[])console.log(` ${String(p.surfaceId).padEnd(12)} ${p.jankPaints}/${p.sampledPaints} compositor paints (${p.jankPct}%) >16.67ms \xB7 max ${p.maxMs}ms`)}else console.log(` jank: ${e.jankFrames} frames (${e.jankPct}%) >16.67ms`);console.log(` avg per frame: overlay ${e.avgOverlayMs}ms \xB7 aux ${e.avgAuxMs}ms \xB7 layout ${e.avgLayoutMs}ms`);let i=e.cadence;i&&typeof i=="object"&&(console.log(""),console.log(` cadence (frame delivery, ${i.vsyncTicks} vsync ticks):`),console.log(` display clock: ${i.displayHz}hz \xB7 host rAF interval p50 ${i.hostIntervalP50} / p95 ${i.hostIntervalP95} / max ${i.hostIntervalMax} ms${i.hostGaps?` \xB7 ${i.hostGaps} gaps >1.5x (host rAF starved)`:""}`),console.log(` delivery lag: p50 ${i.deliveryLagP50} / p95 ${i.deliveryLagP95} / max ${i.deliveryLagMax} ms (vsync postMessage \u2192 shell receipt)`),console.log(` paint interval: p50 ${i.paintIntervalP50} / p95 ${i.paintIntervalP95} / max ${i.paintIntervalMax} ms${i.idleBreaks?` \xB7 ${i.idleBreaks} idle breaks excluded`:""}`));let c=e.compositorCadence;if(c&&typeof c=="object"){console.log(` compositor rAF: p50 ${c.p50} / p95 ${c.p95} / max ${c.max} ms \xB7 ${c.gaps} gaps >1.5x`);let p=(h,$)=>{$?.count&&console.log(` ${h}: ${$.count} samples \xB7 p50 ${$.p50.toFixed(2)} / p95 ${$.p95.toFixed(2)} / max ${$.max.toFixed(2)} ms`)};p("engine-empty rAF",c.phases?.uninterruptedEngineEmpty),p("rAF with CanvasKit flush",c.phases?.withCanvaskitFlush),p("rAF after CanvasKit flush",c.phases?.afterCanvaskitFlush),p("CanvasKit submission",c.canvaskitSubmission)}let l=Array.isArray(e.auxSurfaces)?e.auxSurfaces:[];if(l.length>0){console.log(""),console.log(" surfaces (last 100 frames):");for(let p of l)console.log(` ${String(p.surfaceId).padEnd(10)} ${String(p.frames).padStart(4)} paints avg ${p.avgMs}ms (layout ${p.avgLayoutMs}, render ${p.avgRenderMs}, flush ${p.avgFlushMs}) max ${p.maxMs}ms`),typeof p.gpuCacheBytes=="number"&&typeof p.gpuCacheLimitBytes=="number"&&console.log(` ${"".padEnd(10)} gpu cache ${(p.gpuCacheBytes/1024/1024).toFixed(1)}MB/${(p.gpuCacheLimitBytes/1024/1024).toFixed(1)}MB`)}xo("shell worker",e.renderProfile),xo("compositor worker",e.compositorRenderProfile);let f=Array.isArray(e.worstFrames)?e.worstFrames:[];if(f.length>0){console.log(""),console.log(" worst observations (shell and compositor series are unpaired):");for(let p of f){if(p.source==="compositor"){console.log(` ${String(p.totalMs).padStart(7)}ms compositor ${p.surfaceId} paint ${p.paint} \xB7 layout ${p.layoutMs} \xB7 render ${p.renderMs} \xB7 flush ${p.flushMs}`);continue}let h=(p.auxSurfaces??[]).map($=>`${$.surfaceId} ${$.totalMs}ms (layout ${$.layoutMs}, render ${$.renderMs})`).join(" \xB7 ");console.log(` ${String(p.totalMs).padStart(7)}ms overlay ${p.overlayMs} \xB7 aux ${p.auxMs} \xB7 layout ${p.layoutMs}${h?` [${h}]`:""}`)}}}async function Ee(e,t,s){let i=Date.now()+t,c=await ue(e,t);for(;;){if(s(c))return{settled:!0,state:c};if(Date.now()>=i)return{settled:!1,state:c};await oe(16),c=await ue(e)}}async function tt(e){return e.send({type:"evaluate",code:`(async () => {
457
+ })()`});if(!Array.isArray(s)||s.length===0)return;let i=t.toLowerCase(),c=s.map(l=>({id:l,score:fs(i,l.toLowerCase())})).filter(l=>l.score<i.length+4).sort((l,f)=>l.score-f.score).slice(0,5);if(c.length===0)return;console.error(" similar testIDs:");for(let l of c)console.error(` ${l.id}`)}catch{}}function fs(e,t){if(t===e)return 0;if(t.includes(e))return 1;if(e.includes(t))return 2;let s=0;for(;s<e.length&&s<t.length&&e[s]===t[s];)s+=1;return gs(e,t)-s}function gs(e,t){if(e===t)return 0;if(!e.length)return t.length;if(!t.length)return e.length;let s=new Array(t.length+1),i=new Array(t.length+1);for(let c=0;c<=t.length;c++)s[c]=c;for(let c=1;c<=e.length;c++){i[0]=c;for(let f=1;f<=t.length;f++)i[f]=Math.min(s[f]+1,i[f-1]+1,s[f-1]+(e[c-1]===t[f-1]?0:1));let l=s;s=i,i=l}return s[t.length]}function ys(e){return e.error?"err":e.status==null?" \u2026 ":String(e.status)}function yo(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 ho(e){let t=ae(e.startTs),s=ys(e).padEnd(3),i=e.method.padEnd(5),c=Io(e.size).padStart(6),l=To(e.durationMs);console.log(` [${t}] ${s} ${i} ${c} ${l} ${e.displayUrl}`),e.error&&console.log(` error: ${e.error}`)}function hs(e){let t=[["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",ae(e.startTs)],["duration",To(e.durationMs).trim()],["size",Io(e.size)],["content-type",e.type??"\u2014"]];for(let[s,i]of t)console.log(` ${s.padEnd(13)} ${i}`)}var bs={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},bo="\x1B[0m",ws="\x1B[2m";function wo(e,t){let s=ae(e.ts),i=e.level.toUpperCase().padEnd(5),c=e.args.join(" ");if(t){let l=bs[e.level];console.log(` ${ws}[${s}]${bo} ${l}${i}${bo} ${c}`)}else console.log(` [${s}] ${i} ${c}`);if(e.stack&&e.level==="error"){let l=e.stack.split(`
458
+ `).slice(0,5);for(let f of l)console.log(` ${f.trim()}`)}}var $s=120;async function $o(e,t){let s=e.find((F,N)=>e[N-1]==="--id"),i=e.find((F,N)=>e[N-1]==="--text");if(s||i){let F=await t.send({type:"evaluate",code:Pt({id:s,text:i})});if(!F)throw new Error(s?`no node with id "${s}"`:`no node matching text "${i}"`);let{x:N,y:j,w:R,h:d}=F;return{x:N,y:j,w:R,h:d}}let c=e.find((F,N)=>e[N-1]==="--area");if(c){let F=c.split(",").map(q=>Number(q.trim()));if(F.length!==4||F.some(q=>!Number.isFinite(q)))throw new Error(`--area expects x,y,w,h (got "${c}")`);let[N,j,R,d]=F;return{x:N,y:j,w:R,h:d}}let l=F=>{let N=e.find((R,d)=>e[d-1]===F);if(N==null)return null;let j=Number(N);return Number.isFinite(j)?j:null},f=l("--x"),p=l("--y"),h=l("--w"),$=l("--h");if(f!=null||p!=null||h!=null||$!=null)return{x:f??0,y:p??0,w:h??1,h:$??1};let k=e.filter((F,N)=>N>0&&!F.startsWith("-")&&e[N-1]!=="--output"&&e[N-1]!=="--area"&&e[N-1]!=="--id"&&e[N-1]!=="--text"&&e[N-1]!=="--x"&&e[N-1]!=="--y"&&e[N-1]!=="--w"&&e[N-1]!=="--h").map(Number).filter(F=>Number.isFinite(F));if(k.length>=2){let[F,N,j=1,R=1]=k;return{x:F,y:N,w:j,h:R}}return null}function xo(e,t){if(!t||typeof t!="object")return;console.log(""),console.log(` render profile \u2014 ${e} (per painted frame):`),console.log(` node visits: ${t.nodeVisitsPerFrame}`),console.log(` boundaries: ${t.recordsPerFrame} records (${t.avgBoundaryRecordMs}ms) / ${t.replaysPerFrame} replays`);let s=[t.boundaryRecordsInvalidated?`invalidated ${t.boundaryRecordsInvalidated}`:"",t.boundaryRecordsOrigin?`moved ${t.boundaryRecordsOrigin}`:"",t.boundaryRecordsScheme?`first-record ${t.boundaryRecordsScheme}`:""].filter(Boolean).join(" \xB7 ");s&&console.log(` why recorded: ${s}`),t.prewarmRecords&&console.log(` pre-recorded: ${t.prewarmRecords} boundaries at idle (${Number(t.prewarmRecordMs).toFixed(1)}ms total)`),console.log(` raster tier: ${t.rasterPromotionsPerFrame} promotions / ${t.rasterBlitsPerFrame} blits`);let i=[t.rasterRejectRebuild?`rebuild ${t.rasterRejectRebuild}`:"",t.rasterRejectLinear?`linear ${t.rasterRejectLinear}`:"",t.rasterRejectAnimated?`animated ${t.rasterRejectAnimated}`:"",t.rasterRejectTransform?`transform ${t.rasterRejectTransform}`:"",t.rasterRejectOpacity?`opacity ${t.rasterRejectOpacity}`:"",t.rasterRejectCacheable?`cacheable ${t.rasterRejectCacheable}`:"",t.rasterRejectBounds?`bounds ${t.rasterRejectBounds}`:"",t.rasterRejectPixels?`pixels ${t.rasterRejectPixels}`:"",t.rasterRejectBudget?`budget ${t.rasterRejectBudget}`:"",t.rasterWarming?`warming ${t.rasterWarming}`:""].filter(Boolean).join(" \xB7 ");i&&(console.log(` raster skips: ${i} (total across run)`),t.rasterRejectAlsoBlocked&&console.log(` ${"".padEnd(12)} ${t.rasterRejectAlsoBlocked} of those also fail a later gate \u2014 widening the named gate cannot promote them`)),console.log(` blur: ${t.avgBlurMs}ms`),(t.glassDownsampleActive||t.glassBackdropCacheMisses)&&console.log(` glass: ${t.glassDownsampleFactor}x downsample (${t.glassDownsampledDraws} draws) \xB7 cache ${t.glassBackdropCacheHits} hits / ${t.glassBackdropCacheMisses} misses / ${t.glassBackdropCacheInvalidations} invalidations`),console.log(` draw calls: text ${t.textDrawsPerFrame} \xB7 image ${t.imageDrawsPerFrame} \xB7 path ${t.pathDrawsPerFrame} \xB7 saveLayer ${t.saveLayersPerFrame}`)}function So(e){let t=e.avgMs>0?(1e3/e.avgMs).toFixed(1):"?",s=e.jank&&typeof e.jank=="object"?e.jank:null;if(console.log(` shell frame profile:
459
+ `),s){let h=(Array.isArray(s.compositor)?s.compositor:[]).reduce(($,b)=>$+(b.jankPaints??0),0);console.log(` health: ${s.detected?"jank or cadence gaps observed":"no jank or cadence gaps observed"} \xB7 shell ${s.shell?.jankFrames??0} \xB7 compositor ${h} \xB7 host clock gaps ${s.hostGaps??0}`),console.log(" series: independent worker clocks, no per-frame pairing")}if(console.log(` painted frames: ${e.frames}${e.skippedFrames?` (+${e.skippedFrames} skipped idle ticks)`:""}`),console.log(` shell work avg: ${e.avgMs}ms (${t} fps) \xB7 worst observed ${e.maxMs}ms`),console.log(` shell p50/95/99:${e.p50} / ${e.p95} / ${e.p99} ms`),s){console.log(` shell jank: ${s.shell?.jankFrames??0}/${s.shell?.sampledFrames??0} (${s.shell?.jankPct??0}%) >16.67ms \xB7 max ${s.shell?.maxMs??0}ms`);for(let p of Array.isArray(s.compositor)?s.compositor:[])console.log(` ${String(p.surfaceId).padEnd(12)} ${p.jankPaints}/${p.sampledPaints} compositor paints (${p.jankPct}%) >16.67ms \xB7 max ${p.maxMs}ms`)}else console.log(` jank: ${e.jankFrames} frames (${e.jankPct}%) >16.67ms`);console.log(` avg per frame: overlay ${e.avgOverlayMs}ms \xB7 aux ${e.avgAuxMs}ms \xB7 layout ${e.avgLayoutMs}ms`);let i=e.cadence;i&&typeof i=="object"&&(console.log(""),console.log(` cadence (frame delivery, ${i.vsyncTicks} vsync ticks):`),console.log(` display clock: ${i.displayHz}hz \xB7 host rAF interval p50 ${i.hostIntervalP50} / p95 ${i.hostIntervalP95} / max ${i.hostIntervalMax} ms${i.hostGaps?` \xB7 ${i.hostGaps} gaps >1.5x (host rAF starved)`:""}`),console.log(` delivery lag: p50 ${i.deliveryLagP50} / p95 ${i.deliveryLagP95} / max ${i.deliveryLagMax} ms (vsync postMessage \u2192 shell receipt)`),console.log(` paint interval: p50 ${i.paintIntervalP50} / p95 ${i.paintIntervalP95} / max ${i.paintIntervalMax} ms${i.idleBreaks?` \xB7 ${i.idleBreaks} idle breaks excluded`:""}`));let c=e.compositorCadence;if(c&&typeof c=="object"){console.log(` compositor rAF: p50 ${c.p50} / p95 ${c.p95} / max ${c.max} ms \xB7 ${c.gaps} gaps >1.5x`);let p=(h,$)=>{$?.count&&console.log(` ${h}: ${$.count} samples \xB7 p50 ${$.p50.toFixed(2)} / p95 ${$.p95.toFixed(2)} / max ${$.max.toFixed(2)} ms`)};p("engine-empty rAF",c.phases?.uninterruptedEngineEmpty),p("rAF with CanvasKit flush",c.phases?.withCanvaskitFlush),p("rAF after CanvasKit flush",c.phases?.afterCanvaskitFlush),p("CanvasKit submission",c.canvaskitSubmission)}let l=Array.isArray(e.auxSurfaces)?e.auxSurfaces:[];if(l.length>0){console.log(""),console.log(" surfaces (last 100 frames):");for(let p of l)console.log(` ${String(p.surfaceId).padEnd(10)} ${String(p.frames).padStart(4)} paints avg ${p.avgMs}ms (layout ${p.avgLayoutMs}, render ${p.avgRenderMs}, flush ${p.avgFlushMs}) max ${p.maxMs}ms`),typeof p.gpuCacheBytes=="number"&&typeof p.gpuCacheLimitBytes=="number"&&console.log(` ${"".padEnd(10)} gpu cache ${(p.gpuCacheBytes/1024/1024).toFixed(1)}MB/${(p.gpuCacheLimitBytes/1024/1024).toFixed(1)}MB`)}xo("shell worker",e.renderProfile),xo("compositor worker",e.compositorRenderProfile);let f=Array.isArray(e.worstFrames)?e.worstFrames:[];if(f.length>0){console.log(""),console.log(" worst observations (shell and compositor series are unpaired):");for(let p of f){if(p.source==="compositor"){console.log(` ${String(p.totalMs).padStart(7)}ms compositor ${p.surfaceId} paint ${p.paint} \xB7 layout ${p.layoutMs} \xB7 render ${p.renderMs} \xB7 flush ${p.flushMs}`);continue}let h=(p.auxSurfaces??[]).map($=>`${$.surfaceId} ${$.totalMs}ms (layout ${$.layoutMs}, render ${$.renderMs})`).join(" \xB7 ");console.log(` ${String(p.totalMs).padStart(7)}ms overlay ${p.overlayMs} \xB7 aux ${p.auxMs} \xB7 layout ${p.layoutMs}${h?` [${h}]`:""}`)}}}async function Pe(e,t,s){let i=Date.now()+t,c=await ue(e,t);for(;;){if(s(c))return{settled:!0,state:c};if(Date.now()>=i)return{settled:!1,state:c};await oe(16),c=await ue(e)}}async function tt(e){return e.send({type:"evaluate",code:`(async () => {
527
460
  const kb = window.__sootsimKeyboard
528
461
  const test = window.__sootsimTest
529
462
  if (!kb) return { error: 'keyboard bridge not available' }
@@ -560,7 +493,7 @@ import{a as de}from"./chunk-INBBOCU4.js";import{b as Et,c as Pt,l as At}from"./c
560
493
  frame: runtimeSnapshot?.keyboard?.frame ?? null,
561
494
  focusedRect: runtimeSnapshot?.focused?.rect ?? null,
562
495
  }
563
- })()`}).then(t=>Ze(t))}function xs(e,t,s){if(!e.visible)return!1;let i=e.focusedInput;return!(t&&i&&!(i.testID===t||i.id===t)||s!==null&&we(e)!==s)}async function Ss(e,t=600,s={}){let i=Date.now()+t;for(;Date.now()<=i;){let c=await tt(e);if(xs(c,s.targetId??null,s.secureTextEntry??null))return c;await oe(30)}return tt(e)}async function Pe(e,t){let s=await tt(e);if(s.visible&&s.focusedInput)return s;s.visible&&(console.error(` ${t} requires a focused TextInput. the iOS keyboard is visible, but no input owns focus.`),process.exit(1)),console.error(` ${t} 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 vo(e,t,s){return t==="appearance"?e.send({type:"evaluate",code:`(async () => {
496
+ })()`}).then(t=>Ze(t))}function xs(e,t,s){if(!e.visible)return!1;let i=e.focusedInput;return!(t&&i&&!(i.testID===t||i.id===t)||s!==null&&we(e)!==s)}async function Ss(e,t=600,s={}){let i=Date.now()+t;for(;Date.now()<=i;){let c=await tt(e);if(xs(c,s.targetId??null,s.secureTextEntry??null))return c;await oe(30)}return tt(e)}async function _e(e,t){let s=await tt(e);if(s.visible&&s.focusedInput)return s;s.visible&&(console.error(` ${t} requires a focused TextInput. the iOS keyboard is visible, but no input owns focus.`),process.exit(1)),console.error(` ${t} 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 vo(e,t,s){return t==="appearance"?e.send({type:"evaluate",code:`(async () => {
564
497
  const requested = ${JSON.stringify(s??"toggle")}
565
498
  // the engine owns toggle + auto resolution (settingsStore is the single
566
499
  // source of truth). never infer the current scheme client-side \u2014 the old
@@ -583,26 +516,26 @@ import{a as de}from"./chunk-INBBOCU4.js";import{b as Et,c as Pt,l as At}from"./c
583
516
  })()`}):e.send({type:"evaluate",code:`(async () => {
584
517
  window.dispatchEvent(new CustomEvent('sootsim:shake'))
585
518
  return { ok: true, action: 'shake' }
586
- })()`})}function vs(e){let t={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(t[e])return t[e];let s=e.match(/^Digit([0-9])$/);if(s)return s[1];let i=e.match(/^Key([A-Z])$/);return i?i[1].toLowerCase():null}function ks(e){if(typeof e!="string")return null;let t=e.replace(/\s+/g," ").trim();return t?t.slice(0,80):null}function To(...e){for(let t of e){if(typeof t!="string")continue;let s=t.trim();if(s)return s}return null}function _s(e){let t=e.indexOf("--node-id");if(t<0)return null;let s=e[t+1];if(!s)return null;let i=Number(s);return Number.isInteger(i)&&i>0?i:null}async function W(e,t,s){let i=Fe({source:e,step:t,summary:s});i.active&&(i.replaced?console.error(` draft: replaced unkept action "${i.replaced.summary}" \u2014 \`maestro keep\` commits one action at a time`):console.error(" draft: action pending \u2014 `sootsim maestro keep` to commit"))}function ko(e,t,s){if(!s||s.hit===!1)return null;let i=To(s.responderTestID,s.testID);if(i)return{step:{tapOn:{id:i}},summary:`tap #${i}`};let c=ks(s.text);return c?{step:{tapOn:c},summary:`tap "${c}"`}:{step:{tapAtCoords:{x:e,y:t}},summary:`tap @${Math.round(e)},${Math.round(t)}`}}function et(e,t,s){let i=To(t?.testID,t?.id);return i?{step:{tapOn:{id:i}},summary:`tap #${i}`}:s==="id"?{step:{tapOn:{id:e}},summary:`tap #${e}`}:{step:{tapOn:e},summary:`tap "${e}"`}}async function Rr(e,t){let s=e[0]==="get"||e[0]==="do"||e[0]==="debug"||e[0]==="wait"?e[0]:null,i=s?e.slice(1):e,c=It(i,{port:t.port,commandTimeoutMs:t.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"]}),l=c.positional,f=l[0],p=s==="get"||s==="do"||s==="debug"||s==="wait"?s:"inspect",h=typeof i[0]=="string"&&ot.has(i[0]),$=h?i[0]:null,b=x=>t.internalPerfCommand&&x==="perf"?`sootsim perf ${t.internalPerfCommand}`:h&&x===i[0]?`sootsim ${x}`:`sootsim ${p} ${x}`,k=(x,o)=>` usage: ${b(x)}${o?` ${o}`:""}`;if(!f||e.includes("--help")||e.includes("-h")){let x={bridgePort:7668,defaultShellUrl:nt};if(p==="do"||p==="get"||p==="debug"||p==="wait"){let r=Ae(p,x);r&&(console.log(`${r}
519
+ })()`})}function vs(e){let t={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(t[e])return t[e];let s=e.match(/^Digit([0-9])$/);if(s)return s[1];let i=e.match(/^Key([A-Z])$/);return i?i[1].toLowerCase():null}function ks(e){if(typeof e!="string")return null;let t=e.replace(/\s+/g," ").trim();return t?t.slice(0,80):null}function Mo(...e){for(let t of e){if(typeof t!="string")continue;let s=t.trim();if(s)return s}return null}function Is(e){let t=e.indexOf("--node-id");if(t<0)return null;let s=e[t+1];if(!s)return null;let i=Number(s);return Number.isInteger(i)&&i>0?i:null}async function W(e,t,s){let i=Oe({source:e,step:t,summary:s});i.active&&(i.replaced?console.error(` draft: replaced unkept action "${i.replaced.summary}" \u2014 \`maestro keep\` commits one action at a time`):console.error(" draft: action pending \u2014 `sootsim maestro keep` to commit"))}function ko(e,t,s){if(!s||s.hit===!1)return null;let i=Mo(s.responderTestID,s.testID);if(i)return{step:{tapOn:{id:i}},summary:`tap #${i}`};let c=ks(s.text);return c?{step:{tapOn:c},summary:`tap "${c}"`}:{step:{tapAtCoords:{x:e,y:t}},summary:`tap @${Math.round(e)},${Math.round(t)}`}}function et(e,t,s){let i=Mo(t?.testID,t?.id);return i?{step:{tapOn:{id:i}},summary:`tap #${i}`}:s==="id"?{step:{tapOn:{id:e}},summary:`tap #${e}`}:{step:{tapOn:e},summary:`tap "${e}"`}}async function Rr(e,t){let s=e[0]==="get"||e[0]==="do"||e[0]==="debug"||e[0]==="wait"?e[0]:null,i=s?e.slice(1):e,c=Tt(i,{port:t.port,commandTimeoutMs:t.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"]}),l=c.positional,f=l[0],p=s==="get"||s==="do"||s==="debug"||s==="wait"?s:"inspect",h=typeof i[0]=="string"&&ot.has(i[0]),$=h?i[0]:null,b=x=>t.internalPerfCommand&&x==="perf"?`sootsim perf ${t.internalPerfCommand}`:h&&x===i[0]?`sootsim ${x}`:`sootsim ${p} ${x}`,k=(x,o)=>` usage: ${b(x)}${o?` ${o}`:""}`;if(!f||e.includes("--help")||e.includes("-h")){let x={bridgePort:7668,defaultShellUrl:nt};if(p==="do"||p==="get"||p==="debug"||p==="wait"){let r=Ae(p,x);r&&(console.log(`${r}
587
520
  `),process.exit(0))}if($==="shell"){let r=De("shell",x);r&&(console.log(`${r}
588
521
  `),process.exit(0))}let o=De("inspect",x),n=["do","get","debug","wait"].map(r=>Ae(r,x)).filter(r=>r!=null).join(`
589
522
 
590
523
  `);console.log(`${o??""}
591
524
 
592
525
  ${n}
593
- `),process.exit(0)}let N=c.wsPort,M=c.simId,j=c.simIdSource,O=c.commandTimeoutMs;if(p==="get"&&f==="diagnosis"){let x=i.indexOf("diagnosis"),o=x>=0?[...i.slice(0,x),...i.slice(x+1)]:i,{runDiagnose:n}=await import("./diagnose-UZJCKLPZ.js"),r=await n(["recent",...o],t);process.exitCode=r;return}if(p==="do"&&f==="scan"){let{runCamera:x}=await import("./camera-PHKVEQHR.js");await x(i,{port:t.port});return}if(f==="list"&&i.some(x=>x==="--drivers"||x==="-D")){let{buildDriverListRows:x}=await import("./drivers-Q7GMKTBM.js"),o=x();console.log(` available drivers (${o.length}):
594
- `);let n=Math.max(...o.map(a=>a.id.length),6),r=Math.max(...o.map(a=>a.kind.length),4);for(let a of o){let u=a.available?"\u2713":"\u2717",m=a.id.padEnd(n),g=a.kind.padEnd(r);console.log(` ${u} ${m} ${g} ${a.description}`),a.available&&a.detail?console.log(` ${a.detail}`):!a.available&&a.reason&&console.log(` unavailable: ${a.reason}`)}return}let d=Tt(c),q=M||"default",R=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","storage-clear","list","wait","sleep"]),P=200;function J(x){let o=x.replace(/\s+/g," ").trim();if(!o)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(o)){let r=/<title[^>]*>([^<]+)<\/title>/i.exec(x)?.[1]?.trim(),a=/<body[^>]*>([\s\S]*?)<\//i.exec(x)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=r||a||"html error page";return`<html ${x.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return o.length<=P?o:`${o.slice(0,P)}\u2026 (+${o.length-P} more bytes)`}function U(x){let o=x.displayUrl||x.url;return x.status!=null?`${x.method} ${o} -> ${x.status}${x.statusText?` ${x.statusText}`:""}`:x.error?`${x.method} ${o} -> ${x.error}`:`${x.method} ${o}`}async function _(x){let o=fe()?400:200;try{let{settled:n,elapsed:r}=await se({bridge:x,maxMs:o,pollMs:32,stablePolls:2});n||process.stderr.write(` \u26A0 auto-wait timed out after ${r??o}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
595
- `)}catch{}}function F(x,o){if(o.result?.reason==="offscreen"){let{x:n,y:r,screen:a}=o.result;console.error(` tap failed: ${x} resolved to (${Math.round(n)},${Math.round(r)}), outside the ${a?.width}x${a?.height} screen`),console.error(" the node exists but is scrolled out of view \u2014 scroll it on-screen first (sootsim do scroll / swipe), then tap.");return}console.error(` tap failed: ${x} stayed visible but did not receive a hittable press after ${o.attempts} attempt${o.attempts===1?"":"s"}`),o.result&&console.error(` last result: ${JSON.stringify(o.result)}`)}async function H(){try{return await d.send({type:"evaluate",code:`(() => ({
596
- console: ${_e},
526
+ `),process.exit(0)}let F=c.wsPort,N=c.simId,j=c.simIdSource,R=c.commandTimeoutMs;if(p==="get"&&f==="diagnosis"){let x=i.indexOf("diagnosis"),o=x>=0?[...i.slice(0,x),...i.slice(x+1)]:i,{runDiagnose:n}=await import("./diagnose-S2AVGABT.js"),r=await n(["recent",...o],t);process.exitCode=r;return}if(p==="do"&&f==="scan"){let{runCamera:x}=await import("./camera-MHLM35MB.js");await x(i,{port:t.port});return}if(f==="list"&&i.some(x=>x==="--drivers"||x==="-D")){let{buildDriverListRows:x}=await import("./drivers-PM4PVYHY.js"),o=x();console.log(` available drivers (${o.length}):
527
+ `);let n=Math.max(...o.map(a=>a.id.length),6),r=Math.max(...o.map(a=>a.kind.length),4);for(let a of o){let u=a.available?"\u2713":"\u2717",m=a.id.padEnd(n),g=a.kind.padEnd(r);console.log(` ${u} ${m} ${g} ${a.description}`),a.available&&a.detail?console.log(` ${a.detail}`):!a.available&&a.reason&&console.log(` unavailable: ${a.reason}`)}return}let d=Mt(c),q=N||"default",E=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","storage-clear","list","wait","sleep"]),_=200;function J(x){let o=x.replace(/\s+/g," ").trim();if(!o)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(o)){let r=/<title[^>]*>([^<]+)<\/title>/i.exec(x)?.[1]?.trim(),a=/<body[^>]*>([\s\S]*?)<\//i.exec(x)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=r||a||"html error page";return`<html ${x.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return o.length<=_?o:`${o.slice(0,_)}\u2026 (+${o.length-_} more bytes)`}function U(x){let o=x.displayUrl||x.url;return x.status!=null?`${x.method} ${o} -> ${x.status}${x.statusText?` ${x.statusText}`:""}`:x.error?`${x.method} ${o} -> ${x.error}`:`${x.method} ${o}`}async function I(x){let o=fe()?400:200;try{let{settled:n,elapsed:r}=await se({bridge:x,maxMs:o,pollMs:32,stablePolls:2});n||process.stderr.write(` \u26A0 auto-wait timed out after ${r??o}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
528
+ `)}catch{}}function O(x,o){if(o.result?.reason==="offscreen"){let{x:n,y:r,screen:a}=o.result;console.error(` tap failed: ${x} resolved to (${Math.round(n)},${Math.round(r)}), outside the ${a?.width}x${a?.height} screen`),console.error(" the node exists but is scrolled out of view \u2014 scroll it on-screen first (sootsim do scroll / swipe), then tap.");return}console.error(` tap failed: ${x} stayed visible but did not receive a hittable press after ${o.attempts} attempt${o.attempts===1?"":"s"}`),o.result&&console.error(` last result: ${JSON.stringify(o.result)}`)}async function H(){try{return await d.send({type:"evaluate",code:`(() => ({
529
+ console: ${Ie},
597
530
  requests: window.__sootsimTest?.getRequestCounts?.() || null,
598
531
  }))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function K(x={}){let o=x.counts!==void 0?x.counts:await X(d,"getRequestCounts");if(!o||typeof o!="object")return;let n=Math.max(0,Number(o.failed)||0);if(n===0||!x.includeTail&&!Ye("requests",q,String(n))||(console.log(`
599
532
  network: ${n} failed request${n===1?"":"s"}`),console.log(` inspect: ${b("requests")} 5`),!x.includeTail))return;let r=await X(d,"getFailedRequests",5);if(!(!Array.isArray(r)||r.length===0)){console.log(`
600
533
  recent failed requests:
601
534
  `);for(let a of r){let u=ae(a.timestamp);console.log(` [${u}] ${U(a)}`),a.responseBody?console.log(` ${J(a.responseBody)}`):a.error&&console.log(` ${a.error}`)}}}function ee(x){for(let o of x){let n=o.title?` (\u201C${o.title}\u201D)`:"";console.error(`
602
- note: ${o.label} is open${n} \u2014 taps/drags hit it, not the app`)}}async function te(x={}){let o=x.counts!==void 0?x.counts:await d.send({type:"evaluate",code:_e});if(!o||typeof o!="object")return;let n=o,r=Math.max(0,Number(n.errors)||0),a=Math.max(0,Number(n.warnings)||0);if(r===0&&a===0||!x.includeTail&&!Ye("console",q,`${r}:${a}`))return;let u=[];if(r>0&&u.push(`${r} console error${r===1?"":"s"}`),a>0&&u.push(`${a} console warning${a===1?"":"s"}`),console.error(`
535
+ note: ${o.label} is open${n} \u2014 taps/drags hit it, not the app`)}}async function te(x={}){let o=x.counts!==void 0?x.counts:await d.send({type:"evaluate",code:Ie});if(!o||typeof o!="object")return;let n=o,r=Math.max(0,Number(n.errors)||0),a=Math.max(0,Number(n.warnings)||0);if(r===0&&a===0||!x.includeTail&&!Ye("console",q,`${r}:${a}`))return;let u=[];if(r>0&&u.push(`${r} console error${r===1?"":"s"}`),a>0&&u.push(`${a} console warning${a===1?"":"s"}`),console.error(`
603
536
  console: ${u.join(", ")}`),console.error(` inspect: ${b("errors")} 5`),a>0&&console.error(` inspect: ${b("warnings")} 5`),!x.includeTail||r===0)return;let m=await ge(d,5);if(!(!Array.isArray(m)||m.length===0)){console.error(`
604
537
  recent console errors:
605
- `);for(let g of m){let w=ae(g.timestamp),y=Array.isArray(g.args)?g.args.map(v=>typeof v=="object"?JSON.stringify(v):String(v)).join(" "):String(g);console.error(` [${w}] ${y}`)}}}let ie=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function xe(x){let o=st(),n=null;try{n=await Nt(x,`(() => {
538
+ `);for(let g of m){let w=ae(g.timestamp),y=Array.isArray(g.args)?g.args.map(v=>typeof v=="object"?JSON.stringify(v):String(v)).join(" "):String(g);console.error(` [${w}] ${y}`)}}}let ie=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function xe(x){let o=st(),n=null;try{n=await Ft(x,`(() => {
606
539
  const tl = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.timeline
607
540
  if (!tl || typeof tl.summary !== 'function') return null
608
541
  const cursorKey = ${JSON.stringify(o)}
@@ -619,8 +552,8 @@ ${n}
619
552
  }
620
553
  return summary ? { summary, consoleSplit } : null
621
554
  })()`)}catch{return}if(!n||!n.summary||!n.summary.total)return;let r=n.summary.byKind??{},a=[],u=new Set;for(let m of ie){let g=r[m];if(g)if(u.add(m),m==="console"&&n.consoleSplit){let{error:w,warn:y}=n.consoleSplit;w>0&&a.push(`${w} error${w===1?"":"s"}`),y>0&&a.push(`${y} warning${y===1?"":"s"}`)}else a.push(`${g} ${m}${g===1?"":"s"}`)}for(let[m,g]of Object.entries(r))!u.has(m)&&g&&a.push(`${g} ${m}${g===1?"":"s"}`);if(a.length!==0&&(console.error(`
622
- since last: ${a.join(" \xB7 ")} \u2014 sootsim what-happened`),n.summary.lastAt))try{await ce(x,"SootSim.bridges.timeline.cursorAdvance",o,n.summary.lastAt)}catch{}}let C=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","storage-clear"]),le=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"]),Se=(e.includes("--verbose")||e.includes("-v"))&&!e.includes("--json");p==="do"&&f==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),C.has(f)&&await Mt(d),le.has(f)&&await pe(d,{verbose:Se});try{let x=C.has(f)?await St(d):[];switch(f){case"list":{_t(c.wsPort),await eo({bridge:d,simId:M,args:i});break}case"tree":{await io({bridge:d,args:i,positional:l});break}case"a11y":{let o=await pt(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):
623
- `);for(let n of o){let r=[];if(r.push(`[${n.role}]`),n.label){let a=n.label.length>50?n.label.slice(0,47)+"...":n.label;r.push(`"${a}"`)}if(n.hint&&r.push(`(hint: "${n.hint}")`),n.testID&&r.push(`#${n.testID}`),n.state){let a=[];n.state.disabled&&a.push("disabled"),n.state.selected&&a.push("selected"),n.state.checked===!0&&a.push("checked"),n.state.checked==="mixed"&&a.push("mixed"),n.state.busy&&a.push("busy"),n.state.expanded===!0&&a.push("expanded"),n.state.expanded===!1&&a.push("collapsed"),a.length&&r.push(`{${a.join(", ")}}`)}n.position&&r.push(`@(${n.position.x},${n.position.y})`),n.size&&r.push(`${n.size.w}x${n.size.h}`),console.log(" "+r.join(" "))}}break}case"find":{await Vt({bridge:d,args:e,effectiveArgs:i,positional:l,inspectUsage:k});break}case"count":{await zt(d,{args:i});break}case"keyboard":{await Zt(d,{json:e.includes("--json")});break}case"screens":{await so(d,{json:e.includes("--json")});break}case"memory":{await oo(d,{args:i});break}case"wait":{await lo({wsPort:N,commandTimeoutMs:O,simId:M,simIdSource:j,positional:l});break}case"sleep":{await ro({positional:l,inspectUsage:k});break}case"settle":{await no({bridge:d,args:e,positional:l});break}case"ready":{await mo({bridge:d,args:e});break}case"idle":{await po({bridge:d,args:e,positional:l});break}case"selector":{await fo({bridge:d,args:e,positional:l,inspectUsage:k});break}case"event":{await uo({bridge:d,args:e,positional:l,inspectUsage:k});break}case"layout":{let o=l[1];if(!o){await Qt({bridge:d,args:i});break}let n=await d.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(o)}))()`});console.log(JSON.stringify(n,null,2));break}case"capture":case"screenshot":{let n=e.find((w,y)=>e[y-1]==="--output")||"/tmp/sootsim-inspect.png",r=await $o(e,d),a={type:"screenshot"};r&&(a.crop=r);let m=(await d.send(a)).replace(/^data:image\/png;base64,/,"");r&&console.log(` area: x=${r.x} y=${r.y} w=${r.w} h=${r.h}`),(await import("fs")).writeFileSync(n,Buffer.from(m,"base64")),console.log(` saved: ${n}`);break}case"sample-color":{let o=await $o(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 n=await d.send({type:"evaluate",code:Bt(o)});if(e.includes("--json"))console.log(JSON.stringify(n,null,2));else{let{r,g:a,b:u,a:m,hex:g,samples:w}=n,y=o.w===1&&o.h===1?`@(${o.x},${o.y})`:`@(${o.x},${o.y}) ${o.w}x${o.h}`;console.log(` ${g} rgba(${r}, ${a}, ${u}, ${m}) ${y} ${w} samples`)}break}case"node":{let o=l[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 n=await d.send({type:"evaluate",code:`(async () => {
555
+ since last: ${a.join(" \xB7 ")} \u2014 sootsim what-happened`),n.summary.lastAt))try{await ce(x,"SootSim.bridges.timeline.cursorAdvance",o,n.summary.lastAt)}catch{}}let C=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","storage-clear"]),le=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"]),Se=(e.includes("--verbose")||e.includes("-v"))&&!e.includes("--json");p==="do"&&f==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),C.has(f)&&await Nt(d),le.has(f)&&await pe(d,{verbose:Se});try{let x=C.has(f)?await St(d):[];switch(f){case"list":{It(c.wsPort),await eo({bridge:d,simId:N,args:i});break}case"tree":{await io({bridge:d,args:i,positional:l});break}case"a11y":{let o=await pt(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):
556
+ `);for(let n of o){let r=[];if(r.push(`[${n.role}]`),n.label){let a=n.label.length>50?n.label.slice(0,47)+"...":n.label;r.push(`"${a}"`)}if(n.hint&&r.push(`(hint: "${n.hint}")`),n.testID&&r.push(`#${n.testID}`),n.state){let a=[];n.state.disabled&&a.push("disabled"),n.state.selected&&a.push("selected"),n.state.checked===!0&&a.push("checked"),n.state.checked==="mixed"&&a.push("mixed"),n.state.busy&&a.push("busy"),n.state.expanded===!0&&a.push("expanded"),n.state.expanded===!1&&a.push("collapsed"),a.length&&r.push(`{${a.join(", ")}}`)}n.position&&r.push(`@(${n.position.x},${n.position.y})`),n.size&&r.push(`${n.size.w}x${n.size.h}`),console.log(" "+r.join(" "))}}break}case"find":{await Vt({bridge:d,args:e,effectiveArgs:i,positional:l,inspectUsage:k});break}case"count":{await zt(d,{args:i});break}case"keyboard":{await Zt(d,{json:e.includes("--json")});break}case"screens":{await so(d,{json:e.includes("--json")});break}case"memory":{await oo(d,{args:i});break}case"wait":{await lo({wsPort:F,commandTimeoutMs:R,simId:N,simIdSource:j,positional:l});break}case"sleep":{await ro({positional:l,inspectUsage:k});break}case"settle":{await no({bridge:d,args:e,positional:l});break}case"ready":{await mo({bridge:d,args:e});break}case"idle":{await po({bridge:d,args:e,positional:l});break}case"selector":{await fo({bridge:d,args:e,positional:l,inspectUsage:k});break}case"event":{await uo({bridge:d,args:e,positional:l,inspectUsage:k});break}case"layout":{let o=l[1];if(!o){await Qt({bridge:d,args:i});break}let n=await d.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(o)}))()`});console.log(JSON.stringify(n,null,2));break}case"capture":case"screenshot":{let n=e.find((w,y)=>e[y-1]==="--output")||"/tmp/sootsim-inspect.png",r=await $o(e,d),a={type:"screenshot"};r&&(a.crop=r);let m=(await d.send(a)).replace(/^data:image\/png;base64,/,"");r&&console.log(` area: x=${r.x} y=${r.y} w=${r.w} h=${r.h}`),(await import("fs")).writeFileSync(n,Buffer.from(m,"base64")),console.log(` saved: ${n}`);break}case"sample-color":{let o=await $o(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 n=await d.send({type:"evaluate",code:_t(o)});if(e.includes("--json"))console.log(JSON.stringify(n,null,2));else{let{r,g:a,b:u,a:m,hex:g,samples:w}=n,y=o.w===1&&o.h===1?`@(${o.x},${o.y})`:`@(${o.x},${o.y}) ${o.w}x${o.h}`;console.log(` ${g} rgba(${r}, ${a}, ${u}, ${m}) ${y} ${w} samples`)}break}case"node":{let o=l[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 n=await d.send({type:"evaluate",code:`(async () => {
624
557
  const t = window.__sootsimTest
625
558
  const q = ${JSON.stringify(o)}
626
559
  let node = null
@@ -676,7 +609,7 @@ ${n}
676
609
  transform,
677
610
  parentChain,
678
611
  }
679
- })()`});console.log(JSON.stringify(n,null,2));break}case"tap":{let o=Number(l[1]),n=Number(l[2]),r=$e(e,l);if(r){let m=await be(d,{agent:fe(),textFallback:r.mode==="text"?r.value:void 0,resolve:async()=>{let y=await Oe(d,r);return y?{cx:y.x,cy:y.y,match:{id:r.mode==="testid"?r.value:y.id??null,testID:r.mode==="testid"?r.value:y.testID??null,text:r.mode==="text"?r.value:y.text??null,type:y.type??null},target:{id:y.id??null,testID:y.testID??null,text:y.text??null,type:y.type??null}}:null}}),g=m.payload;(!g||typeof g.cx!="number")&&(console.error(` not found: ${r.value}`),r.mode==="testid"&&Q("wait-selector-for-missing-testid",r.value),process.exit(1)),me(m.result)||(F(`${r.mode} "${r.value}"`,m),process.exit(1));let w=ko(g.cx,g.cy,m.result);w&&await W("inspect tap",w.step,w.summary),console.log(JSON.stringify({...m.attempts>1?{attempts:m.attempts}:{},...m.result},null,2));break}(!Number.isFinite(o)||!Number.isFinite(n))&&(console.error(k("tap","<testid> | <x> <y> | --testid <id> | --text <t>")),process.exit(1));let a=await Kt(d,o,n),u=ko(o,n,a);u&&await W("inspect tap",u.step,u.summary),console.log(JSON.stringify(a,null,2));break}case"drag":case"swipe":{let o=Number(l[1]),n=Number(l[2]),r=Number(l[3]),a=Number(l[4]),u=f==="swipe"?10:12,m=f==="swipe"?8:16,g=l[5]?Number(l[5]):u,w=l[6]?Number(l[6]):m;(!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(a)||!Number.isFinite(g)||!Number.isFinite(w))&&(console.error(k(f,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let y=await d.send({type:"evaluate",code:`(async () => {
612
+ })()`});console.log(JSON.stringify(n,null,2));break}case"tap":{let o=Number(l[1]),n=Number(l[2]),r=$e(e,l);if(r){let m=await be(d,{agent:fe(),textFallback:r.mode==="text"?r.value:void 0,resolve:async()=>{let y=await Re(d,r);return y?{cx:y.x,cy:y.y,match:{id:r.mode==="testid"?r.value:y.id??null,testID:r.mode==="testid"?r.value:y.testID??null,text:r.mode==="text"?r.value:y.text??null,type:y.type??null},target:{id:y.id??null,testID:y.testID??null,text:y.text??null,type:y.type??null}}:null}}),g=m.payload;(!g||typeof g.cx!="number")&&(console.error(` not found: ${r.value}`),r.mode==="testid"&&Q("wait-selector-for-missing-testid",r.value),process.exit(1)),me(m.result)||(O(`${r.mode} "${r.value}"`,m),process.exit(1));let w=ko(g.cx,g.cy,m.result);w&&await W("inspect tap",w.step,w.summary),console.log(JSON.stringify({...m.attempts>1?{attempts:m.attempts}:{},...m.result},null,2));break}(!Number.isFinite(o)||!Number.isFinite(n))&&(console.error(k("tap","<testid> | <x> <y> | --testid <id> | --text <t>")),process.exit(1));let a=await Kt(d,o,n),u=ko(o,n,a);u&&await W("inspect tap",u.step,u.summary),console.log(JSON.stringify(a,null,2));break}case"drag":case"swipe":{let o=Number(l[1]),n=Number(l[2]),r=Number(l[3]),a=Number(l[4]),u=f==="swipe"?10:12,m=f==="swipe"?8:16,g=l[5]?Number(l[5]):u,w=l[6]?Number(l[6]):m;(!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(a)||!Number.isFinite(g)||!Number.isFinite(w))&&(console.error(k(f,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let y=await d.send({type:"evaluate",code:`(async () => {
680
613
  const interact = window.__sootsimInteract
681
614
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
682
615
  const value = await interact.drag(${o}, ${n}, ${r}, ${a}, ${Math.max(1,Math.round(g))}, ${Math.max(0,Math.round(w))})
@@ -686,7 +619,7 @@ ${n}
686
619
  if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
687
620
  const value = await interact.pinch(${o}, ${n}, ${r}, ${a}, ${u}, ${m}, ${g}, ${w}, ${Math.max(1,Math.round(y))}, ${Math.max(0,Math.round(v))})
688
621
  return { ok: !!value, value }
689
- })()`});L?.ok&&await W("inspect pinch",{pinch:{from:[o,n,r,a],to:[u,m,g,w],steps:Math.max(1,Math.round(y)),stepMs:Math.max(0,Math.round(v))}},`pinch (${o},${n}) (${r},${a}) -> (${u},${m}) (${g},${w})`),console.log(JSON.stringify(L,null,2));break}case"tap-text":{let o=l[1];o||(console.error(k("tap-text","<text>")),process.exit(1));let n=z=>{let B=e.indexOf(z);return B>=0&&B+1<e.length?e[B+1]:null},r=z=>e.includes(z),a=n("--nth")??n("--index"),u=a!==null?Number(a):null;u!==null&&!Number.isFinite(u)&&(console.error(` --nth/--index requires an integer, got: ${a}`),process.exit(1));let m=n("--within"),g=n("--role"),w=r("--exact"),y=r("--first"),v=n("--min-y"),L=n("--max-y"),V=n("--min-x"),G=n("--max-x");for(let[z,B]of[["--min-y",v],["--max-y",L],["--min-x",V],["--max-x",G]])B!==null&&!Number.isFinite(Number(B))&&(console.error(` ${z} requires a number, got: ${B}`),process.exit(1));let Y=e.indexOf("--near"),E=null;if(Y>=0){let z=Number(e[Y+1]),B=Number(e[Y+2]);(!Number.isFinite(z)||!Number.isFinite(B))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),E={x:z,y:B}}let S={exact:w,role:g,within:m,minX:V!==null?Number(V):null,maxX:G!==null?Number(G):null,minY:v!==null?Number(v):null,maxY:L!==null?Number(L):null,near:E,nth:u,first:y},I=await Gt(d,o,S,{agent:fe()}),T=I.payload;if(T?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),T?.ambiguous){let z=T.candidates;console.error(` ambiguous: ${T.total} matches for "${o}"`);for(let B of z){let ve=B.abs?`@(${Math.round(B.abs.x)},${Math.round(B.abs.y)})`:"",Mo=B.layout?` ${B.layout.width}x${B.layout.height}`:"",No=B.testID?` #${B.testID}`:"",Fo=B.text?` "${B.text}"`:"",Oo=B.ancestorTestIDs.length>0?` within ${B.ancestorTestIDs.slice(0,3).map(Ro=>`#${Ro}`).join(" > ")}`:"";console.error(` [${B.idx}] <${B.type}>${Fo}${No} ${ve}${Mo}${Oo}`)}T.total>z.length&&console.error(` ... and ${T.total-z.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)}T?.nthOutOfRange&&(console.error(` not found: nth ${T.nth} of ${T.total} match${T.total===1?"":"es"} for "${o}"`),process.exit(1)),(!T||typeof T.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),me(I.result)||(F(`text "${o}"`,I),process.exit(1));let ne=et(o,{id:T.target?.id??null,testID:T.target?.testID??null,type:T.target?.type??null,cx:T.cx,cy:T.cy},"text");await W("inspect tap-text",ne.step,ne.summary),console.log(JSON.stringify({matched:T.match,tapped:{nodeId:T.target?.nodeId??null,id:T.target?.id??null,testID:T.target?.testID??null,type:T.target?.type??null,cx:T.cx,cy:T.cy},...T.strategy&&T.strategy!=="matched-node"?{strategy:T.strategy}:{},...T.total>1||u!==null?{nth:{index:T.idx,total:T.total}}:{},...I.attempts>1?{attempts:I.attempts}:{},result:I.result},null,2));break}case"tap-best":{let o=l[1];o||(console.error(k("tap-best","<query>")),process.exit(1));let n=await Yt(d,o,{agent:fe()}),r=n.payload;r||(console.error(` tap-best: no testID or visible text matched "${o}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1)),"error"in r&&(console.error(` ${r.error}`),process.exit(1)),r.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 a=r.node;me(n.result)||(F(`best "${o}"`,n),process.exit(1));let u=et(o,{id:a.id,testID:a.testID,type:a.type,cx:r.cx,cy:r.cy},r.strategy==="testid"?"id":"text");await W("inspect tap-best",u.step,u.summary),console.log(JSON.stringify({matched:{strategy:r.strategy,nodeId:a.nodeId,id:a.id,testID:a.testID,type:a.type,text:a.text},tapped:{cx:r.cx,cy:r.cy},...n.attempts>1?{attempts:n.attempts}:{},result:n.result},null,2));break}case"tap-id":{let o=l[1];o||(console.error(k("tap-id","<id>")),process.exit(1));let n=await Ut(d,o,{agent:fe()}),r=n.payload;(!r||typeof r.cx!="number")&&(console.error(` not found: ${o}`),await ms(d,o),process.exit(1)),me(n.result)||(F(`id "${o}"`,n),process.exit(1));let a=et(o,{id:r.target?.id??null,testID:r.target?.testID??null,type:r.target?.type??null,cx:r.cx,cy:r.cy},"id");await W("inspect tap-id",a.step,a.summary),console.log(JSON.stringify({matched:r.match,tapped:{nodeId:r.target?.nodeId??null,id:r.target?.id??null,testID:r.target?.testID??null,type:r.target?.type??null,cx:r.cx,cy:r.cy},...r.strategy&&r.strategy!=="matched-node"?{strategy:r.strategy}:{},...n.attempts>1?{attempts:n.attempts}:{},result:n.result},null,2));break}case"type-into":{let o=l[1],n=l.slice(2).join(" ");(!o||!n)&&(console.error(k("type-into","<id> <text>")),process.exit(1));let r=JSON.stringify(o),a=await d.send({type:"evaluate",code:`(async () => {
622
+ })()`});L?.ok&&await W("inspect pinch",{pinch:{from:[o,n,r,a],to:[u,m,g,w],steps:Math.max(1,Math.round(y)),stepMs:Math.max(0,Math.round(v))}},`pinch (${o},${n}) (${r},${a}) -> (${u},${m}) (${g},${w})`),console.log(JSON.stringify(L,null,2));break}case"tap-text":{let o=l[1];o||(console.error(k("tap-text","<text>")),process.exit(1));let n=z=>{let B=e.indexOf(z);return B>=0&&B+1<e.length?e[B+1]:null},r=z=>e.includes(z),a=n("--nth")??n("--index"),u=a!==null?Number(a):null;u!==null&&!Number.isFinite(u)&&(console.error(` --nth/--index requires an integer, got: ${a}`),process.exit(1));let m=n("--within"),g=n("--role"),w=r("--exact"),y=r("--first"),v=n("--min-y"),L=n("--max-y"),V=n("--min-x"),G=n("--max-x");for(let[z,B]of[["--min-y",v],["--max-y",L],["--min-x",V],["--max-x",G]])B!==null&&!Number.isFinite(Number(B))&&(console.error(` ${z} requires a number, got: ${B}`),process.exit(1));let Y=e.indexOf("--near"),P=null;if(Y>=0){let z=Number(e[Y+1]),B=Number(e[Y+2]);(!Number.isFinite(z)||!Number.isFinite(B))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),P={x:z,y:B}}let S={exact:w,role:g,within:m,minX:V!==null?Number(V):null,maxX:G!==null?Number(G):null,minY:v!==null?Number(v):null,maxY:L!==null?Number(L):null,near:P,nth:u,first:y},T=await Gt(d,o,S,{agent:fe()}),M=T.payload;if(M?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),M?.ambiguous){let z=M.candidates;console.error(` ambiguous: ${M.total} matches for "${o}"`);for(let B of z){let ve=B.abs?`@(${Math.round(B.abs.x)},${Math.round(B.abs.y)})`:"",No=B.layout?` ${B.layout.width}x${B.layout.height}`:"",Fo=B.testID?` #${B.testID}`:"",Oo=B.text?` "${B.text}"`:"",Ro=B.ancestorTestIDs.length>0?` within ${B.ancestorTestIDs.slice(0,3).map(Eo=>`#${Eo}`).join(" > ")}`:"";console.error(` [${B.idx}] <${B.type}>${Oo}${Fo} ${ve}${No}${Ro}`)}M.total>z.length&&console.error(` ... and ${M.total-z.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)}M?.nthOutOfRange&&(console.error(` not found: nth ${M.nth} of ${M.total} match${M.total===1?"":"es"} for "${o}"`),process.exit(1)),(!M||typeof M.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),me(T.result)||(O(`text "${o}"`,T),process.exit(1));let ne=et(o,{id:M.target?.id??null,testID:M.target?.testID??null,type:M.target?.type??null,cx:M.cx,cy:M.cy},"text");await W("inspect tap-text",ne.step,ne.summary),console.log(JSON.stringify({matched:M.match,tapped:{nodeId:M.target?.nodeId??null,id:M.target?.id??null,testID:M.target?.testID??null,type:M.target?.type??null,cx:M.cx,cy:M.cy},...M.strategy&&M.strategy!=="matched-node"?{strategy:M.strategy}:{},...M.total>1||u!==null?{nth:{index:M.idx,total:M.total}}:{},...T.attempts>1?{attempts:T.attempts}:{},result:T.result},null,2));break}case"tap-best":{let o=l[1];o||(console.error(k("tap-best","<query>")),process.exit(1));let n=await Yt(d,o,{agent:fe()}),r=n.payload;r||(console.error(` tap-best: no testID or visible text matched "${o}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1)),"error"in r&&(console.error(` ${r.error}`),process.exit(1)),r.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 a=r.node;me(n.result)||(O(`best "${o}"`,n),process.exit(1));let u=et(o,{id:a.id,testID:a.testID,type:a.type,cx:r.cx,cy:r.cy},r.strategy==="testid"?"id":"text");await W("inspect tap-best",u.step,u.summary),console.log(JSON.stringify({matched:{strategy:r.strategy,nodeId:a.nodeId,id:a.id,testID:a.testID,type:a.type,text:a.text},tapped:{cx:r.cx,cy:r.cy},...n.attempts>1?{attempts:n.attempts}:{},result:n.result},null,2));break}case"tap-id":{let o=l[1];o||(console.error(k("tap-id","<id>")),process.exit(1));let n=await Ut(d,o,{agent:fe()}),r=n.payload;(!r||typeof r.cx!="number")&&(console.error(` not found: ${o}`),await ms(d,o),process.exit(1)),me(n.result)||(O(`id "${o}"`,n),process.exit(1));let a=et(o,{id:r.target?.id??null,testID:r.target?.testID??null,type:r.target?.type??null,cx:r.cx,cy:r.cy},"id");await W("inspect tap-id",a.step,a.summary),console.log(JSON.stringify({matched:r.match,tapped:{nodeId:r.target?.nodeId??null,id:r.target?.id??null,testID:r.target?.testID??null,type:r.target?.type??null,cx:r.cx,cy:r.cy},...r.strategy&&r.strategy!=="matched-node"?{strategy:r.strategy}:{},...n.attempts>1?{attempts:n.attempts}:{},result:n.result},null,2));break}case"type-into":{let o=l[1],n=l.slice(2).join(" ");(!o||!n)&&(console.error(k("type-into","<id> <text>")),process.exit(1));let r=JSON.stringify(o),a=await d.send({type:"evaluate",code:`(async () => {
690
623
  const t = window.__sootsimTest
691
624
  if (!t) return null
692
625
  const n = await (t.findByTestId(${r}) || t.findById(${r}))
@@ -701,7 +634,7 @@ ${n}
701
634
  secureTextEntry: !!n.secureTextEntry,
702
635
  placeholder: n.placeholder || null,
703
636
  }
704
- })()`});(!a||typeof a.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),a.isTextInput||console.error(` warning: ${o} is not a text input (isTextInput: false)`);let u=await d.send({type:"tap",x:a.cx,y:a.cy,target:{id:a.id??o,testID:a.testID??o,text:null,type:a.type??null}}),m=a.secureTextEntry===!0,g=await Ss(d,1e3,{targetId:o,secureTextEntry:m});g.visible||(console.error(` keyboard did not open after tapping ${o}`),process.exit(1));let w=g.focusedInput;w&&(w.testID===o||w.id===o||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(o)} but focus is on ${JSON.stringify(w.testID??w.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await d.send({type:"keyboard",action:"type",text:n});let y=m||we(g),v=y?Z:Qe(n,g),L=y&&g.focusedInput?{...g.focusedInput,secureTextEntry:!0,text:typeof g.focusedInput.text=="string"?Z:g.focusedInput.text}:g.focusedInput??null;await W("inspect type-into",{tapOn:{id:o},inputText:v},v===Z?`type-into #${o} ${Z}`:`type-into #${o} ${JSON.stringify(n)}`),console.log(JSON.stringify({target:o,isTextInput:a.isTextInput,secureTextEntry:y,keyboardOpened:g.visible??u?.keyboardOpened??!1,focusedInput:L,typed:v},null,2));break}case"type":{let o=l.slice(1).join(" ");o||(console.error(k("type","<text>")),process.exit(1));let n=await Pe(d,"type");await d.send({type:"keyboard",action:"type",text:o});let r=Qe(o,n);await W("inspect type",{inputText:r},r===Z?`type ${Z}`:`type ${JSON.stringify(o)}`),console.log(r===Z?` typed: ${Z}`:` typed: ${JSON.stringify(o)}`);break}case"key":{let o=l[1];o||(console.error(k("key","<name>")),process.exit(1)),await Pe(d,"key"),await d.send({type:"keyboard",action:"press",text:o}),await W("inspect key",{pressKey:o},`key ${o}`),console.log(` pressed: ${o}`);break}case"key-sequence":{let o=l.slice(1);o.length===0&&(console.error(k("key-sequence","<key> [<key> ...]")),process.exit(1)),await Pe(d,"key-sequence");for(let n of o)await d.send({type:"keyboard",action:"press",text:n});await W("inspect key-sequence",{pressKey:o.join(" ")},`key-sequence ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"keycode":{let o=l.slice(1);o.length===0&&(console.error(k("keycode","<code> [<code> ...]")),process.exit(1));let n=o.map(a=>({code:a,key:vs(a)})),r=n.filter(a=>!a.key);r.length>0&&(console.error(` unsupported keycode(s): ${r.map(a=>a.code).join(", ")}`),process.exit(1)),await Pe(d,"keycode");for(let a of n)await d.send({type:"keyboard",action:"press",text:a.key});await W("inspect keycode",{pressKey:n.map(a=>a.key).join(" ")},`keycode ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"dispatch":{let o=l[1];o||(console.error(k("dispatch","<char>")),process.exit(1)),await d.send({type:"keyboard",action:"dispatchKey",text:o}),await W("inspect dispatch",{dispatchKey:o},`dispatch ${JSON.stringify(o)}`),console.log(` dispatched: ${o}`);break}case"dismiss":{await d.send({type:"keyboard",action:"dismiss"}),await W("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let o=Number(l[1]),n=Number(l[2]),r=$e(e,l);if(r){let g=await Oe(d,r);g||(console.error(` not found: ${r.value}`),r.mode==="testid"&&Q("wait-selector-for-missing-testid",r.value),process.exit(1)),o=g.x,n=g.y}let a=l[3]?Number(l[3]):80;(!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(a))&&(console.error(k("double-tap","<testid> | <x> <y> [gapMs] | --testid <id>")),process.exit(1));let u=Math.max(0,Math.round(a)),m=await d.send({type:"evaluate",code:`(async () => {
637
+ })()`});(!a||typeof a.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),a.isTextInput||console.error(` warning: ${o} is not a text input (isTextInput: false)`);let u=await d.send({type:"tap",x:a.cx,y:a.cy,target:{id:a.id??o,testID:a.testID??o,text:null,type:a.type??null}}),m=a.secureTextEntry===!0,g=await Ss(d,1e3,{targetId:o,secureTextEntry:m});g.visible||(console.error(` keyboard did not open after tapping ${o}`),process.exit(1));let w=g.focusedInput;w&&(w.testID===o||w.id===o||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(o)} but focus is on ${JSON.stringify(w.testID??w.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await d.send({type:"keyboard",action:"type",text:n});let y=m||we(g),v=y?Z:Qe(n,g),L=y&&g.focusedInput?{...g.focusedInput,secureTextEntry:!0,text:typeof g.focusedInput.text=="string"?Z:g.focusedInput.text}:g.focusedInput??null;await W("inspect type-into",{tapOn:{id:o},inputText:v},v===Z?`type-into #${o} ${Z}`:`type-into #${o} ${JSON.stringify(n)}`),console.log(JSON.stringify({target:o,isTextInput:a.isTextInput,secureTextEntry:y,keyboardOpened:g.visible??u?.keyboardOpened??!1,focusedInput:L,typed:v},null,2));break}case"type":{let o=l.slice(1).join(" ");o||(console.error(k("type","<text>")),process.exit(1));let n=await _e(d,"type");await d.send({type:"keyboard",action:"type",text:o});let r=Qe(o,n);await W("inspect type",{inputText:r},r===Z?`type ${Z}`:`type ${JSON.stringify(o)}`),console.log(r===Z?` typed: ${Z}`:` typed: ${JSON.stringify(o)}`);break}case"key":{let o=l[1];o||(console.error(k("key","<name>")),process.exit(1)),await _e(d,"key"),await d.send({type:"keyboard",action:"press",text:o}),await W("inspect key",{pressKey:o},`key ${o}`),console.log(` pressed: ${o}`);break}case"key-sequence":{let o=l.slice(1);o.length===0&&(console.error(k("key-sequence","<key> [<key> ...]")),process.exit(1)),await _e(d,"key-sequence");for(let n of o)await d.send({type:"keyboard",action:"press",text:n});await W("inspect key-sequence",{pressKey:o.join(" ")},`key-sequence ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"keycode":{let o=l.slice(1);o.length===0&&(console.error(k("keycode","<code> [<code> ...]")),process.exit(1));let n=o.map(a=>({code:a,key:vs(a)})),r=n.filter(a=>!a.key);r.length>0&&(console.error(` unsupported keycode(s): ${r.map(a=>a.code).join(", ")}`),process.exit(1)),await _e(d,"keycode");for(let a of n)await d.send({type:"keyboard",action:"press",text:a.key});await W("inspect keycode",{pressKey:n.map(a=>a.key).join(" ")},`keycode ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"dispatch":{let o=l[1];o||(console.error(k("dispatch","<char>")),process.exit(1)),await d.send({type:"keyboard",action:"dispatchKey",text:o}),await W("inspect dispatch",{dispatchKey:o},`dispatch ${JSON.stringify(o)}`),console.log(` dispatched: ${o}`);break}case"dismiss":{await d.send({type:"keyboard",action:"dismiss"}),await W("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let o=Number(l[1]),n=Number(l[2]),r=$e(e,l);if(r){let g=await Re(d,r);g||(console.error(` not found: ${r.value}`),r.mode==="testid"&&Q("wait-selector-for-missing-testid",r.value),process.exit(1)),o=g.x,n=g.y}let a=l[3]?Number(l[3]):80;(!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(a))&&(console.error(k("double-tap","<testid> | <x> <y> [gapMs] | --testid <id>")),process.exit(1));let u=Math.max(0,Math.round(a)),m=await d.send({type:"evaluate",code:`(async () => {
705
638
  const interact = window.__sootsimInteract
706
639
  if (interact?.doubleTap) {
707
640
  return {
@@ -724,7 +657,7 @@ ${n}
724
657
  first,
725
658
  second,
726
659
  }
727
- })()`});m?.ok&&await W("inspect double-tap",{doubleTapAtCoords:{x:o,y:n,gapMs:u}},`double-tap @${o},${n}`),console.log(JSON.stringify(m,null,2));break}case"long-press":{let o=Number(l[1]),n=Number(l[2]),r=$e(e,l),a=null;if(r){let y=await Oe(d,r);y||(console.error(` not found: ${r.value}`),r.mode==="testid"&&Q("wait-selector-for-missing-testid",r.value),process.exit(1)),o=y.x,n=y.y,a={id:y.id??null,testID:y.testID??null,text:y.text??null,type:y.type??null}}let u=r?l[1]:l[3],m=u?Number(u):600;(!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(m))&&(console.error(k("long-press","<testid> | <x> <y> [durationMs] | --testid <id>")),process.exit(1));let g=Math.max(0,Math.round(m)),w=await d.send({type:"longPress",x:o,y:n,durationMs:g,target:a});w?.ok&&await W("inspect long-press",{tapAtCoords:{x:o,y:n}},`long-press @${o},${n}`),console.log(JSON.stringify(w,null,2));break}case"touch":{let o=l[1],n=Number(l[2]),r=Number(l[3]),a=l[4]?Number(l[4]):999,u=o==="down"?"touchDown":o==="move"?"touchMove":o==="up"?"touchUp":o==="cancel"?"touchCancel":null;u||(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),o!=="cancel"&&(!Number.isFinite(n)||!Number.isFinite(r))&&(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let m=o==="down"?"tap":o==="move"?"move":null,g=m&&Number.isFinite(n)&&Number.isFinite(r)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${m}', x: ${n}, y: ${r} } }));`:"",w=await d.send({type:"evaluate",code:`(async () => {
660
+ })()`});m?.ok&&await W("inspect double-tap",{doubleTapAtCoords:{x:o,y:n,gapMs:u}},`double-tap @${o},${n}`),console.log(JSON.stringify(m,null,2));break}case"long-press":{let o=Number(l[1]),n=Number(l[2]),r=$e(e,l),a=null;if(r){let y=await Re(d,r);y||(console.error(` not found: ${r.value}`),r.mode==="testid"&&Q("wait-selector-for-missing-testid",r.value),process.exit(1)),o=y.x,n=y.y,a={id:y.id??null,testID:y.testID??null,text:y.text??null,type:y.type??null}}let u=r?l[1]:l[3],m=u?Number(u):600;(!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(m))&&(console.error(k("long-press","<testid> | <x> <y> [durationMs] | --testid <id>")),process.exit(1));let g=Math.max(0,Math.round(m)),w=await d.send({type:"longPress",x:o,y:n,durationMs:g,target:a});w?.ok&&await W("inspect long-press",{tapAtCoords:{x:o,y:n}},`long-press @${o},${n}`),console.log(JSON.stringify(w,null,2));break}case"touch":{let o=l[1],n=Number(l[2]),r=Number(l[3]),a=l[4]?Number(l[4]):999,u=o==="down"?"touchDown":o==="move"?"touchMove":o==="up"?"touchUp":o==="cancel"?"touchCancel":null;u||(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),o!=="cancel"&&(!Number.isFinite(n)||!Number.isFinite(r))&&(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let m=o==="down"?"tap":o==="move"?"move":null,g=m&&Number.isFinite(n)&&Number.isFinite(r)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${m}', x: ${n}, y: ${r} } }));`:"",w=await d.send({type:"evaluate",code:`(async () => {
728
661
  ${g}
729
662
  const interact = window.__sootsimInteract
730
663
  if (!interact?.${u}) return { ok: false, reason: 'no interact.${u}' }
@@ -738,12 +671,12 @@ ${n}
738
671
  statusBarHeight: spec.statusBarHeight || 0,
739
672
  homeIndicatorHeight: spec.homeIndicatorHeight || 0,
740
673
  }
741
- })()`}),u=Number(a?.width)||393,m=Number(a?.height)||852,g=Number(a?.statusBarHeight)||0,w=Number(a?.homeIndicatorHeight)||0,y=Math.round(u/2),v=Math.round(m/2),L=Math.max(24,g+18),V=Math.max(24,w+18),G=18,Y=Math.min(220,Math.round(m*.24)),E=Math.min(180,Math.round(u*.32)),S=y,I=v,T=y,ne=v;switch(n){case"scroll-up":I=v+Math.round(Y/2),ne=v-Math.round(Y/2);break;case"scroll-down":I=v-Math.round(Y/2),ne=v+Math.round(Y/2);break;case"scroll-left":S=y+Math.round(E/2),T=y-Math.round(E/2);break;case"scroll-right":S=y-Math.round(E/2),T=y+Math.round(E/2);break;case"swipe-from-left-edge":S=G,I=v,T=Math.min(u-G,G+E);break;case"swipe-from-right-edge":S=u-G,I=v,T=Math.max(G,u-G-E);break;case"swipe-from-top-edge":S=y,I=L,ne=Math.min(m-V,L+Y);break;case"swipe-from-bottom-edge":S=y,I=m-V,ne=Math.max(L,m-V-Y);break}let z=Math.max(8,Math.round(r/16)),B=Math.max(1,Math.round(r/z)),ve=await d.send({type:"evaluate",code:`(async () => {
674
+ })()`}),u=Number(a?.width)||393,m=Number(a?.height)||852,g=Number(a?.statusBarHeight)||0,w=Number(a?.homeIndicatorHeight)||0,y=Math.round(u/2),v=Math.round(m/2),L=Math.max(24,g+18),V=Math.max(24,w+18),G=18,Y=Math.min(220,Math.round(m*.24)),P=Math.min(180,Math.round(u*.32)),S=y,T=v,M=y,ne=v;switch(n){case"scroll-up":T=v+Math.round(Y/2),ne=v-Math.round(Y/2);break;case"scroll-down":T=v-Math.round(Y/2),ne=v+Math.round(Y/2);break;case"scroll-left":S=y+Math.round(P/2),M=y-Math.round(P/2);break;case"scroll-right":S=y-Math.round(P/2),M=y+Math.round(P/2);break;case"swipe-from-left-edge":S=G,T=v,M=Math.min(u-G,G+P);break;case"swipe-from-right-edge":S=u-G,T=v,M=Math.max(G,u-G-P);break;case"swipe-from-top-edge":S=y,T=L,ne=Math.min(m-V,L+Y);break;case"swipe-from-bottom-edge":S=y,T=m-V,ne=Math.max(L,m-V-Y);break}let z=Math.max(8,Math.round(r/16)),B=Math.max(1,Math.round(r/z)),ve=await d.send({type:"evaluate",code:`(async () => {
742
675
  const interact = window.__sootsimInteract
743
676
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
744
- const value = await interact.drag(${S}, ${I}, ${T}, ${ne}, ${z}, ${B})
677
+ const value = await interact.drag(${S}, ${T}, ${M}, ${ne}, ${z}, ${B})
745
678
  return { ok: !!value, value }
746
- })()`});ve?.ok&&await W("inspect gesture",{swipe:{start:`${S}, ${I}`,end:`${T}, ${ne}`,duration:Math.max(1,Math.round(r))}},`gesture ${n}`),console.log(JSON.stringify({preset:n,from:{x:S,y:I},to:{x:T,y:ne},result:ve},null,2));break}case"scroll":{let o=$e(e),n=_s(e),r=o?.mode==="testid"?o.value:n==null?l[1]:null,a=o||n!=null?1:2,u=Number(l[a]),m=Number(l[a+1]);(!r&&n==null||!Number.isFinite(u)||!Number.isFinite(m))&&(console.error(k("scroll","<id> <x> <y> | --testid <id> <x> <y> | --node-id <nodeId> <x> <y>")),process.exit(1));let g=await d.send({type:"evaluate",code:`(async () => {
679
+ })()`});ve?.ok&&await W("inspect gesture",{swipe:{start:`${S}, ${T}`,end:`${M}, ${ne}`,duration:Math.max(1,Math.round(r))}},`gesture ${n}`),console.log(JSON.stringify({preset:n,from:{x:S,y:T},to:{x:M,y:ne},result:ve},null,2));break}case"scroll":{let o=$e(e),n=Is(e),r=o?.mode==="testid"?o.value:n==null?l[1]:null,a=o||n!=null?1:2,u=Number(l[a]),m=Number(l[a+1]);(!r&&n==null||!Number.isFinite(u)||!Number.isFinite(m))&&(console.error(k("scroll","<id> <x> <y> | --testid <id> <x> <y> | --node-id <nodeId> <x> <y>")),process.exit(1));let g=await d.send({type:"evaluate",code:`(async () => {
747
680
  const t = window.__sootsimTest
748
681
  if (!t) return null
749
682
  const n = ${n!=null?`await t.inspectByNodeId(${JSON.stringify(n)})`:`await t.findByTestId(${JSON.stringify(r)})
@@ -753,7 +686,7 @@ ${n}
753
686
  cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
754
687
  cy: n.absolutePosition.y + (n.layout.height || 0) / 2,
755
688
  }
756
- })()`}),w=await X(d,"scrollTo",n!=null?{nodeId:n}:r,u,m,!1);if(w?.ok){let y=n!=null?`node ${n}`:`#${r}`;await W("inspect scroll",{scrollTo:{...n!=null?{nodeId:n}:{id:r},x:u,y:m}},`scroll ${y} -> ${u},${m}`)}console.log(JSON.stringify({...w,...g?{at:{x:g.cx,y:g.cy}}:{}},null,2));break}case"state":{let o=l[1];if(s==="get"&&!o){let r=await X(d,"getRuntimeState"),a=await d.send({type:"evaluate",code:_e});if(r&&typeof r=="object"&&r.diagnostics&&(r.diagnostics.errors=a?.errors??0,r.diagnostics.warnings=a?.warnings??0),r&&typeof r=="object"&&r.shell==null)try{let u=await ue(d);u&&(r.shell=u)}catch{}console.log(JSON.stringify(r,null,2));break}if(!o||o==="--help"||o==="-h"){console.log(`
689
+ })()`}),w=await X(d,"scrollTo",n!=null?{nodeId:n}:r,u,m,!1);if(w?.ok){let y=n!=null?`node ${n}`:`#${r}`;await W("inspect scroll",{scrollTo:{...n!=null?{nodeId:n}:{id:r},x:u,y:m}},`scroll ${y} -> ${u},${m}`)}console.log(JSON.stringify({...w,...g?{at:{x:g.cx,y:g.cy}}:{}},null,2));break}case"state":{let o=l[1];if(s==="get"&&!o){let r=await X(d,"getRuntimeState"),a=await d.send({type:"evaluate",code:Ie});if(r&&typeof r=="object"&&r.diagnostics&&(r.diagnostics.errors=a?.errors??0,r.diagnostics.warnings=a?.warnings??0),r&&typeof r=="object"&&r.shell==null)try{let u=await ue(d);u&&(r.shell=u)}catch{}console.log(JSON.stringify(r,null,2));break}if(!o||o==="--help"||o==="-h"){console.log(`
757
690
  ${b("state")} \u2014 dump raw runtime state
758
691
 
759
692
  subcommands:
@@ -841,7 +774,7 @@ ${n}
841
774
  ${b("shell")} open-card clock 800
842
775
  ${b("shell")} appearance dark
843
776
  ${b("shell")} lock
844
- `);break}let n=o==="launch"||o==="open-card"||o==="home"||o==="switcher",r=o==="launch"||o==="open-card"?l[3]:l[2],a=r?Number(r):350;n&&(!Number.isFinite(a)||a<0)&&(console.error(k("shell",o==="launch"||o==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let u=!1,m=!1,g=null,w=e.includes("--clear-state");if(o==="launch"){let y=l[2];y||(console.error(k("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),w&&await d.send({type:"evaluate",code:We(!0)}),u=!!await ye(d,"launchApp",a,y),{settled:m,state:g}=await Ee(d,Math.round(a),v=>!!v&&v.state==="app"&&v.activeApp===y&&v.showSwitcher===!1&&v.switcherPhase==="idle"&&typeof v.launchProgress=="number"&&v.launchProgress>=.98),u&&await W("inspect shell launch",w?{launchApp:{clearState:!0}}:{launchApp:{}},w?"launch app (clear state)":"launch app")}else if(o==="home")u=!!await ye(d,"goHome",a),{settled:m,state:g}=await Ee(d,Math.round(a),y=>!!y&&y.state==="home"&&y.activeApp==null&&y.showSwitcher===!1&&y.switcherPhase==="idle"&&typeof y.launchProgress=="number"&&y.launchProgress>=.98);else if(o==="switcher")u=!!await ye(d,"openSwitcher",a),{settled:m,state:g}=await Ee(d,Math.round(a),y=>!!y&&y.state==="app"&&y.showSwitcher===!0&&y.switcherPhase==="idle"&&typeof y.zoomLevel=="number"&&Math.abs(y.zoomLevel)<=.02&&typeof y.horizontalZoom=="number"&&Math.abs(y.horizontalZoom)<=.02),m&&(await oe($s),g=await ue(d));else if(o==="open-card"){let y=l[2];y||(console.error(k("shell","open-card <appId> [settleMs]")),process.exit(1)),u=!!await ye(d,"openSwitcherCard",a,y),{settled:m,state:g}=await Ee(d,Math.round(a),v=>!!v&&v.state==="app"&&v.activeApp===y&&v.showSwitcher===!1&&v.switcherPhase==="idle"&&typeof v.zoomLevel=="number"&&v.zoomLevel>=.98&&typeof v.horizontalZoom=="number"&&v.horizontalZoom>=.98),u&&await W("inspect shell open-card",{openSwitcherCard:{appId:y}},`open switcher card ${y}`)}else if(o==="appearance"){let y=l[2];(!y||!["light","dark","auto","toggle"].includes(y))&&(console.error(k("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let v=await vo(d,"appearance",y);if(u=!!v?.ok,g={appearance:v},u){let L=v?.applied??y;console.log(` appearance: ${L}`)}}else if(o==="lock"||o==="shake"){let y=await vo(d,o);u=!!y?.ok,g={[o]:y}}else console.error(` unknown shell subcommand: ${o}`),process.exit(1);console.log(JSON.stringify({ok:u,settled:m,state:g},null,2));break}case"url":{await ao(d,{args:i});break}case"reload":{let r=!1,a=!1;try{await d.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let g=await d.send({type:"evaluate",code:`;(async () => {
777
+ `);break}let n=o==="launch"||o==="open-card"||o==="home"||o==="switcher",r=o==="launch"||o==="open-card"?l[3]:l[2],a=r?Number(r):350;n&&(!Number.isFinite(a)||a<0)&&(console.error(k("shell",o==="launch"||o==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let u=!1,m=!1,g=null,w=e.includes("--clear-state");if(o==="launch"){let y=l[2];y||(console.error(k("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),w&&await d.send({type:"evaluate",code:We(!0)}),u=!!await ye(d,"launchApp",a,y),{settled:m,state:g}=await Pe(d,Math.round(a),v=>!!v&&v.state==="app"&&v.activeApp===y&&v.showSwitcher===!1&&v.switcherPhase==="idle"&&typeof v.launchProgress=="number"&&v.launchProgress>=.98),u&&await W("inspect shell launch",w?{launchApp:{clearState:!0}}:{launchApp:{}},w?"launch app (clear state)":"launch app")}else if(o==="home")u=!!await ye(d,"goHome",a),{settled:m,state:g}=await Pe(d,Math.round(a),y=>!!y&&y.state==="home"&&y.activeApp==null&&y.showSwitcher===!1&&y.switcherPhase==="idle"&&typeof y.launchProgress=="number"&&y.launchProgress>=.98);else if(o==="switcher")u=!!await ye(d,"openSwitcher",a),{settled:m,state:g}=await Pe(d,Math.round(a),y=>!!y&&y.state==="app"&&y.showSwitcher===!0&&y.switcherPhase==="idle"&&typeof y.zoomLevel=="number"&&Math.abs(y.zoomLevel)<=.02&&typeof y.horizontalZoom=="number"&&Math.abs(y.horizontalZoom)<=.02),m&&(await oe($s),g=await ue(d));else if(o==="open-card"){let y=l[2];y||(console.error(k("shell","open-card <appId> [settleMs]")),process.exit(1)),u=!!await ye(d,"openSwitcherCard",a,y),{settled:m,state:g}=await Pe(d,Math.round(a),v=>!!v&&v.state==="app"&&v.activeApp===y&&v.showSwitcher===!1&&v.switcherPhase==="idle"&&typeof v.zoomLevel=="number"&&v.zoomLevel>=.98&&typeof v.horizontalZoom=="number"&&v.horizontalZoom>=.98),u&&await W("inspect shell open-card",{openSwitcherCard:{appId:y}},`open switcher card ${y}`)}else if(o==="appearance"){let y=l[2];(!y||!["light","dark","auto","toggle"].includes(y))&&(console.error(k("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let v=await vo(d,"appearance",y);if(u=!!v?.ok,g={appearance:v},u){let L=v?.applied??y;console.log(` appearance: ${L}`)}}else if(o==="lock"||o==="shake"){let y=await vo(d,o);u=!!y?.ok,g={[o]:y}}else console.error(` unknown shell subcommand: ${o}`),process.exit(1);console.log(JSON.stringify({ok:u,settled:m,state:g},null,2));break}case"url":{await ao(d,{args:i});break}case"reload":{let r=!1,a=!1;try{await d.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let g=await d.send({type:"evaluate",code:`;(async () => {
845
778
  // in-place guest reload is only valid while the page still runs
846
779
  // the engine build the server would serve NOW. the shell dev
847
780
  // server has no HMR client, so a long-lived sim tab otherwise
@@ -865,10 +798,10 @@ ${n}
865
798
  }
866
799
  window.location.reload()
867
800
  return { kind: 'page', engineStale }
868
- })()`});a=!!g&&g.kind==="external-app",r=!0,g&&g.engineStale&&console.log(" engine build changed since page load \u2014 full page reload")}catch{}console.log(" reloading...");let u=d,m=null;if(a)m=await Te(d,{timeoutMs:1e4,errorGraceMs:3e3});else{r&&await oe(300);let w=await Ot(N,O,M,{timeoutMs:3e4,simIdSource:j});w?(u=w,m=await Te(w,{timeoutMs:3e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 30000ms"),u=null)}if(m)if(m.ready){let g=m.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${m.elapsedMs}ms: ${m.nodes} nodes${g}`)}else if(m.source==="error-bail")console.log(` \u26A0 reload bailed after ${m.elapsedMs}ms: ${m.errors} console error(s), ready signal never fired`);else{let g=yo(m);console.log(` \u26A0 reload timed out after ${m.elapsedMs}ms \u2014 ${g} (nodes: ${m.nodes}, targets: ${m.targets}, errors: ${m.errors})`)}if(u)try{let g=await ge(u,10);if(u!==d&&u.close(),Array.isArray(g)&&g.length>0){console.log(`
801
+ })()`});a=!!g&&g.kind==="external-app",r=!0,g&&g.engineStale&&console.log(" engine build changed since page load \u2014 full page reload")}catch{}console.log(" reloading...");let u=d,m=null;if(a)m=await Me(d,{timeoutMs:1e4,errorGraceMs:3e3});else{r&&await oe(300);let w=await Rt(F,R,N,{timeoutMs:3e4,simIdSource:j});w?(u=w,m=await Me(w,{timeoutMs:3e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 30000ms"),u=null)}if(m)if(m.ready){let g=m.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${m.elapsedMs}ms: ${m.nodes} nodes${g}`)}else if(m.source==="error-bail")console.log(` \u26A0 reload bailed after ${m.elapsedMs}ms: ${m.errors} console error(s), ready signal never fired`);else{let g=yo(m);console.log(` \u26A0 reload timed out after ${m.elapsedMs}ms \u2014 ${g} (nodes: ${m.nodes}, targets: ${m.targets}, errors: ${m.errors})`)}if(u)try{let g=await ge(u,10);if(u!==d&&u.close(),Array.isArray(g)&&g.length>0){console.log(`
869
802
  \u26A0 ${g.length} error(s) during mount:
870
803
  `);for(let w of g){let y=w.args.map(v=>typeof v=="object"?JSON.stringify(v):v).join(" ");if(console.log(` ${y}`),w.stack){let v=w.stack.split(`
871
- `).slice(0,2);for(let L of v)console.log(` ${L.trim()}`)}}}}catch{}m&&!m.ready&&(process.exitCode=1);break}case"storage-clear":{if(await qe(d),await d.send({type:"evaluate",code:We(!0)})!==!0){D(i)?A({cleared:!1,ready:!1,error:"external app reload bridge is unavailable"}):console.error(" storage clear failed: external app reload bridge is unavailable"),process.exitCode=1;break}let a=await Te(d,{timeoutMs:1e4,errorGraceMs:3e3});if(D(i)){A({cleared:!0,ready:a.ready,reload:a}),a.ready||(process.exitCode=1);break}if(a.ready){let u=a.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` cleared tenant storage; ready in ${a.elapsedMs}ms: ${a.nodes} nodes${u}`)}else if(a.source==="error-bail")console.log(` \u26A0 storage clear reloaded but bailed after ${a.elapsedMs}ms: ${a.errors} console error(s), ready signal never fired`);else{let u=yo(a);console.log(` \u26A0 storage clear reloaded but timed out after ${a.elapsedMs}ms \u2014 ${u} (nodes: ${a.nodes}, targets: ${a.targets}, errors: ${a.errors})`)}try{let u=await ge(d,10);if(Array.isArray(u)&&u.length>0){console.log(`
804
+ `).slice(0,2);for(let L of v)console.log(` ${L.trim()}`)}}}}catch{}m&&!m.ready&&(process.exitCode=1);break}case"storage-clear":{if(await qe(d),await d.send({type:"evaluate",code:We(!0)})!==!0){D(i)?A({cleared:!1,ready:!1,error:"external app reload bridge is unavailable"}):console.error(" storage clear failed: external app reload bridge is unavailable"),process.exitCode=1;break}let a=await Me(d,{timeoutMs:1e4,errorGraceMs:3e3});if(D(i)){A({cleared:!0,ready:a.ready,reload:a}),a.ready||(process.exitCode=1);break}if(a.ready){let u=a.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` cleared tenant storage; ready in ${a.elapsedMs}ms: ${a.nodes} nodes${u}`)}else if(a.source==="error-bail")console.log(` \u26A0 storage clear reloaded but bailed after ${a.elapsedMs}ms: ${a.errors} console error(s), ready signal never fired`);else{let u=yo(a);console.log(` \u26A0 storage clear reloaded but timed out after ${a.elapsedMs}ms \u2014 ${u} (nodes: ${a.nodes}, targets: ${a.targets}, errors: ${a.errors})`)}try{let u=await ge(d,10);if(Array.isArray(u)&&u.length>0){console.log(`
872
805
  \u26A0 ${u.length} error(s) during mount:
873
806
  `);for(let m of u){let g=m.args.map(w=>typeof w=="object"?JSON.stringify(w):w).join(" ");if(console.log(` ${g}`),m.stack){let w=m.stack.split(`
874
807
  `).slice(0,2);for(let y of w)console.log(` ${y.trim()}`)}}}}catch{}a.ready||(process.exitCode=1);break}case"eval":case"js":{let o=l.slice(1).join(" ");if(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(` ${b("js")} SootSim.bridges.test.findByText("Sign in")`),console.error(` ${b("js")} SootSim.bridges.debug.snapshot("before")`),console.error(` ${b("js")} SootSim.bridges.keyboard.type("hello")`),console.error(` ${b("js")} SootSim.state.root.children.length`),process.exit(1)),e.includes("--tenant")){let m=l.slice(1).filter(w=>w!=="--tenant").join(" "),g=await d.send({type:"evaluate",code:`(async () => SootSim.bridges.test.evalInTenant(${JSON.stringify(m)}))()`});console.log(JSON.stringify(g,null,2));break}let n=o;n.startsWith("(async")||(n=`(async () => ${n})()`);let r=await d.send({type:"evaluate",code:n});console.log(JSON.stringify(r,null,2));let a=o.toLowerCase(),u=[];(a.includes("sootsim:gohome")||a.includes("gohome"))&&u.push("sootsim shell home"),(a.includes("sootsim:appswitcher")||a.includes("appswitcher"))&&u.push("sootsim shell switcher"),(a.includes("keyboard.isvisible")||a.includes("keyboard.getmode"))&&u.push("sootsim debug state keyboard"),a.includes("interact.tap")&&u.push("sootsim do tap <x> <y>"),a.includes("keyboard.type")&&u.push("sootsim do type <text>"),(a.includes("keyboard.press")||a.includes("keyboard.dispatchkey"))&&u.push("sootsim do key <name>"),a.includes("keyboard.dismiss")&&u.push("sootsim do dismiss"),a.includes("dumptree")&&u.push("sootsim get tree"),a.includes("dumpaccessibilitytree")&&u.push("sootsim get a11y"),a.includes("getnodecount")&&u.push("sootsim get count"),a.includes("findbytext")&&u.push("sootsim find <text>"),(a.includes("findbytestid")||a.includes("findbyid"))&&u.push("sootsim find --testid <id>"),a.includes("document.hidden")&&u.push("sootsim debug state keyboard (includes tab health)"),u.length>0&&Q("prefer-cli-over-eval",u);break}case"globals":{let o=await d.send({type:"evaluate",code:`(async () => {
@@ -979,7 +912,7 @@ ${n}
979
912
  examples:
980
913
  ${b("perf")} transition goHome --timeout 10000
981
914
  ${b("perf")} transition appSwitcher
982
- `);break}let a=`sootsim:${n}`;Ie(` profiling ${n} transition...`),Ie(" (use --timeout 10000 if this times out)");let u=await d.send({type:"evaluate",code:`(async () => {
915
+ `);break}let a=`sootsim:${n}`;Te(` profiling ${n} transition...`),Te(" (use --timeout 10000 if this times out)");let u=await d.send({type:"evaluate",code:`(async () => {
983
916
  if (!window.__sootsimShellPerf) {
984
917
  return { error: 'shell frame profile unavailable (__sootsimShellPerf missing on the page)' }
985
918
  }
@@ -991,29 +924,29 @@ ${n}
991
924
  // animation-end detection
992
925
  await new Promise(r => setTimeout(r, 600))
993
926
  return await window.__sootsimShellPerf.stop()
994
- })()`});if(u?.error&&(console.error(` error: ${u.error}`),process.exit(1)),D(i)){A(u);break}Ie(` ${n} transition profiled:`),So(u);break}default:console.error(` unknown perf subcommand: ${o}`),console.error(" valid: start, stop, transition"),/^--?reset$/.test(o)&&console.error(" note: 'perf start' already clears prior frames \u2014 no reset needed"),(o==="stats"||o==="frames"||o==="worst")&&(console.error(" note: the tenant sampler (stats/frames/worst) was removed \u2014 it hardcoded"),console.error(" layout/render/copy to zero because the shell worker owns every real paint."),console.error(" use 'perf start' / 'perf stop' (worst frames are in the stop report).")),process.exit(1)}break}case"errors":{let o=l[1];if(o==="clear"){await qe(d),D(i)?A({cleared:!0}):console.log(" error buffer cleared");break}let n=o?Number(o):20,r=await ge(d,n);if(D(i)){A(r);break}if(r.length===0){console.log(" no errors captured");break}console.log(` ${r.length} error(s):
927
+ })()`});if(u?.error&&(console.error(` error: ${u.error}`),process.exit(1)),D(i)){A(u);break}Te(` ${n} transition profiled:`),So(u);break}default:console.error(` unknown perf subcommand: ${o}`),console.error(" valid: start, stop, transition"),/^--?reset$/.test(o)&&console.error(" note: 'perf start' already clears prior frames \u2014 no reset needed"),(o==="stats"||o==="frames"||o==="worst")&&(console.error(" note: the tenant sampler (stats/frames/worst) was removed \u2014 it hardcoded"),console.error(" layout/render/copy to zero because the shell worker owns every real paint."),console.error(" use 'perf start' / 'perf stop' (worst frames are in the stop report).")),process.exit(1)}break}case"errors":{let o=l[1];if(o==="clear"){await qe(d),D(i)?A({cleared:!0}):console.log(" error buffer cleared");break}let n=o?Number(o):20,r=await ge(d,n);if(D(i)){A(r);break}if(r.length===0){console.log(" no errors captured");break}console.log(` ${r.length} error(s):
995
928
  `);for(let a of r){let u=ae(a.timestamp),m=a.args.map(g=>typeof g=="object"?JSON.stringify(g):g).join(" ");if(console.log(` [${u}] ${m}`),a.stack){let g=a.stack.split(`
996
929
  `).slice(0,3);for(let w of g)console.log(` ${w.trim()}`)}}break}case"warnings":{let o=l[1]?Number(l[1]):20,n=await yt(d,o);if(D(i)){A(n);break}if(n.length===0){console.log(" no warnings captured");break}console.log(` ${n.length} warning(s):
997
930
  `);for(let r of n){let a=ae(r.timestamp),u=r.args.map(m=>typeof m=="object"?JSON.stringify(m):m).join(" ");console.log(` [${a}] ${u}`)}break}case"animations":{let o=await X(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):
998
931
  `);for(let n of o){let r=String(n.realm??"tenant").padEnd(6),a=String(n.kind).padEnd(10),u=typeof n.from=="number"&&typeof n.to=="number"?`${n.from.toFixed(2)}\u2192${n.to.toFixed(2)}`:"\u2014",m=Number(n.current??0).toFixed(2),g=typeof n.progress=="number"?`${Math.round(n.progress*100)}%`:"\u2014",w=`${Math.round(n.elapsedMs??0)}ms`,y=[n.loop?"loop":null,n.layoutBound?"layout":null,n.remoteDriven?"remote-driven":n.graphBacked?"graph":null,n.visible===!1?"offscreen":null].filter(Boolean),v=y.length>0?` [${y.join(" ")}]`:"";console.log(` #${n.id} ${r} ${a} ${u.padEnd(14)} cur=${m.padEnd(7)} ${g.padStart(4)} ${w}${v}`)}break}case"animation":{let o=l[1];(!o||o==="--help"||o==="-h")&&(console.error(` usage: ${b("animation")} <id>`),process.exit(1));let n=Number(o);Number.isFinite(n)||(console.error(` invalid id: ${o}`),process.exit(1));let r=await X(d,"getAnimation",n);console.log(JSON.stringify(r,null,2));break}case"stop-animation":{let o=l[1];(!o||o==="--help"||o==="-h")&&(console.error(` usage: ${b("stop-animation")} <id|all>`),process.exit(1));let n=o==="all"?"all":Number(o);n!=="all"&&!Number.isFinite(n)&&(console.error(` invalid id: ${o}`),process.exit(1));let r=await X(d,"stopAnimation",n);console.log(` stopped ${r??0} animation(s)`);break}case"requests":{let o=l[1];if(o==="clear"){await bt(d),D(i)?A({cleared:!0}):console.log(" request buffer cleared");break}let n=o==="all",r=n?l[2]:o,a=r?Number(r):20,u=await ht(d,{failed:!n,limit:a});if(D(i)){A(u);break}if(u.length===0){console.log(n?" no requests captured":" no failed requests captured");break}console.log(` ${u.length} ${n?"request(s)":"failed request(s)"}:
999
- `);for(let m of u){let g=ae(m.timestamp);console.log(` [${g}] ${U(m)}`),m.responseBody?console.log(` ${m.responseBody}`):m.error&&console.log(` ${m.error}`)}break}case"network":{let o=l[1],n=null,r=null,a=!1,u=!1,m=1e3,g=!1,w=!1;for(let E=0;E<i.length;E++){let S=i[E];if(S==="--filter")n=i[E+1]??null,E++;else if(S==="--limit"){let I=Number(i[E+1]);Number.isFinite(I)&&(r=I),E++}else if(S==="--threshold"){let I=Number(i[E+1]);Number.isFinite(I)&&I>0&&(m=I),E++}else S==="--failed"?a=!0:S==="--slow"?u=!0:S==="--tail"||S==="-f"?g=!0:S==="--json"&&(w=!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 E=l[2];E||(console.error(" usage: sootsim network get <id>"),process.exit(1));let S=await d.send({type:"evaluate",code:`(() => {
932
+ `);for(let m of u){let g=ae(m.timestamp);console.log(` [${g}] ${U(m)}`),m.responseBody?console.log(` ${m.responseBody}`):m.error&&console.log(` ${m.error}`)}break}case"network":{let o=l[1],n=null,r=null,a=!1,u=!1,m=1e3,g=!1,w=!1;for(let P=0;P<i.length;P++){let S=i[P];if(S==="--filter")n=i[P+1]??null,P++;else if(S==="--limit"){let T=Number(i[P+1]);Number.isFinite(T)&&(r=T),P++}else if(S==="--threshold"){let T=Number(i[P+1]);Number.isFinite(T)&&T>0&&(m=T),P++}else S==="--failed"?a=!0:S==="--slow"?u=!0:S==="--tail"||S==="-f"?g=!0:S==="--json"&&(w=!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 P=l[2];P||(console.error(" usage: sootsim network get <id>"),process.exit(1));let S=await d.send({type:"evaluate",code:`(() => {
1000
933
  const obs = window.__sootsimObservability;
1001
934
  if (!obs) return null;
1002
- return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(E)}) || null;
1003
- })()`});S||(console.error(` no entry with id ${E}`),process.exit(1)),w?console.log(JSON.stringify(S,null,2)):hs(S);break}let y=r??(g?200:o?Number(o):20);Number.isFinite(y)||(console.error(` invalid limit: ${o} \u2014 \`network\` takes a numeric count (e.g. ${b("network")} 100).
1004
- to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let v=async()=>{let E=await d.send({type:"evaluate",code:`(() => {
935
+ return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(P)}) || null;
936
+ })()`});S||(console.error(` no entry with id ${P}`),process.exit(1)),w?console.log(JSON.stringify(S,null,2)):hs(S);break}let y=r??(g?200:o?Number(o):20);Number.isFinite(y)||(console.error(` invalid limit: ${o} \u2014 \`network\` takes a numeric count (e.g. ${b("network")} 100).
937
+ to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let v=async()=>{let P=await d.send({type:"evaluate",code:`(() => {
1005
938
  const obs = window.__sootsimObservability;
1006
939
  if (!obs) return { ok: false };
1007
940
  return { ok: true, entries: obs.network.getSnapshot() };
1008
- })()`});if(!E||!E.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return E.entries??[]},L=E=>{let S=E;if(a&&(S=S.filter(I=>!!I.error||I.status!=null&&I.status>=400)),u&&(S=S.filter(I=>I.durationMs!=null&&I.durationMs>=m)),n){let I=n.toLowerCase();S=S.filter(T=>(T.displayUrl||T.url).toLowerCase().includes(I))}return u&&!g&&(S=[...S].sort((I,T)=>(T.durationMs??0)-(I.durationMs??0))),S};if(!g){let E=await v(),S=L(E).slice(-y);if(w){console.log(JSON.stringify(S,null,2));break}if(S.length===0){E.length===0?console.log(" no network requests captured"):console.log(u?` no requests slower than ${m}ms (${E.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(u?` ${S.length} request(s) slower than ${m}ms (sorted by duration desc):
941
+ })()`});if(!P||!P.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return P.entries??[]},L=P=>{let S=P;if(a&&(S=S.filter(T=>!!T.error||T.status!=null&&T.status>=400)),u&&(S=S.filter(T=>T.durationMs!=null&&T.durationMs>=m)),n){let T=n.toLowerCase();S=S.filter(M=>(M.displayUrl||M.url).toLowerCase().includes(T))}return u&&!g&&(S=[...S].sort((T,M)=>(M.durationMs??0)-(T.durationMs??0))),S};if(!g){let P=await v(),S=L(P).slice(-y);if(w){console.log(JSON.stringify(S,null,2));break}if(S.length===0){P.length===0?console.log(" no network requests captured"):console.log(u?` no requests slower than ${m}ms (${P.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(u?` ${S.length} request(s) slower than ${m}ms (sorted by duration desc):
1009
942
  `:` ${S.length} request(s):
1010
- `);for(let I of S)ho(I);break}console.log(` tailing network (ctrl-c to stop)...
1011
- `);let V=new Set,G=!0,Y=()=>{G=!1};process.on("SIGINT",Y);try{for(;G;){let E=await v(),S=L(E);for(let I of S)I.durationMs!=null&&(V.has(I.id)||(V.add(I.id),w?console.log(JSON.stringify(I)):ho(I)));await oe(250)}}finally{process.off("SIGINT",Y)}break}case"logs":{let o=l[1],n=null,r=null,a=null,u=!1,m=!1,g=!1;for(let S=0;S<i.length;S++){let I=i[S];if(I==="--filter")n=i[S+1]??null,S++;else if(I==="--limit"){let T=Number(i[S+1]);Number.isFinite(T)&&(r=T),S++}else I==="--level"?(a=i[S+1]??null,S++):I==="--tail"||I==="-f"?u=!0:I==="--json"?m=!0:(I==="--internal"||I==="--all")&&(g=!0)}let w=a?new Set(a.split(",").map(S=>S.trim()).filter(S=>S==="log"||S==="info"||S==="warn"||S==="error"||S==="debug")):null;if(o==="clear"){await $t(d),console.log(" log buffer cleared");break}let y=!m&&process.stdout.isTTY===!0,v=r??(u?500:o?Number(o):50);Number.isFinite(v)||(console.error(` invalid limit: ${o} \u2014 \`logs\` takes a numeric count (e.g. ${b("logs")} 100).
1012
- to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let L=()=>wt(d),V=S=>xt(S,{level:w,filter:n,showInternal:g});if(!u){let S=await L(),I=V(S).slice(-v);if(m){console.log(JSON.stringify(I,null,2));break}if(I.length===0){console.log(S.length===0?" no logs captured":" no matching logs");break}console.log(` ${I.length} log(s):
1013
- `);for(let T of I)wo(T,y);break}console.log(` tailing logs (ctrl-c to stop)...
1014
- `);let G=new Set,Y=!0,E=()=>{Y=!1};process.on("SIGINT",E);try{for(;Y;){let S=await L(),I=V(S);for(let T of I)G.has(T.id)||(G.add(T.id),m?console.log(JSON.stringify(T)):wo(T,y));await oe(250)}}finally{process.off("SIGINT",E)}break}default:console.error(` unknown subcommand: ${f}`),process.exit(1)}if(C.has(f)&&!e.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&!await rt(d,f)&&await _(d),x.length>0&&ee(x),!R.has(f))try{await xe(d)}catch{}}catch(x){let o=x instanceof Error?x.message:String(x);console.error(` ${f??"inspect"} failed: ${o}`);let n=/^no sim connected with id ([^;]+)(?:; connected sims: .+)?$/.exec(o),r=/^command timed out after (\d+)s$/.exec(o),a=o.startsWith("sim disconnected:")||o.startsWith("bridge never reconnected")||o.startsWith("could not connect to ws://");if(n)await Pt(d,N,n[1]);else if(/^no sim connected$/.test(o))Et(N);else if(r)if(await ps(d)){let m=f??"describe";process.stderr.write(` the sim is still responsive \u2014 '${m}' just exceeded the ${r[1]}s command budget.
943
+ `);for(let T of S)ho(T);break}console.log(` tailing network (ctrl-c to stop)...
944
+ `);let V=new Set,G=!0,Y=()=>{G=!1};process.on("SIGINT",Y);try{for(;G;){let P=await v(),S=L(P);for(let T of S)T.durationMs!=null&&(V.has(T.id)||(V.add(T.id),w?console.log(JSON.stringify(T)):ho(T)));await oe(250)}}finally{process.off("SIGINT",Y)}break}case"logs":{let o=l[1],n=null,r=null,a=null,u=!1,m=!1,g=!1;for(let S=0;S<i.length;S++){let T=i[S];if(T==="--filter")n=i[S+1]??null,S++;else if(T==="--limit"){let M=Number(i[S+1]);Number.isFinite(M)&&(r=M),S++}else T==="--level"?(a=i[S+1]??null,S++):T==="--tail"||T==="-f"?u=!0:T==="--json"?m=!0:(T==="--internal"||T==="--all")&&(g=!0)}let w=a?new Set(a.split(",").map(S=>S.trim()).filter(S=>S==="log"||S==="info"||S==="warn"||S==="error"||S==="debug")):null;if(o==="clear"){await $t(d),console.log(" log buffer cleared");break}let y=!m&&process.stdout.isTTY===!0,v=r??(u?500:o?Number(o):50);Number.isFinite(v)||(console.error(` invalid limit: ${o} \u2014 \`logs\` takes a numeric count (e.g. ${b("logs")} 100).
945
+ to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let L=()=>wt(d),V=S=>xt(S,{level:w,filter:n,showInternal:g});if(!u){let S=await L(),T=V(S).slice(-v);if(m){console.log(JSON.stringify(T,null,2));break}if(T.length===0){console.log(S.length===0?" no logs captured":" no matching logs");break}console.log(` ${T.length} log(s):
946
+ `);for(let M of T)wo(M,y);break}console.log(` tailing logs (ctrl-c to stop)...
947
+ `);let G=new Set,Y=!0,P=()=>{Y=!1};process.on("SIGINT",P);try{for(;Y;){let S=await L(),T=V(S);for(let M of T)G.has(M.id)||(G.add(M.id),m?console.log(JSON.stringify(M)):wo(M,y));await oe(250)}}finally{process.off("SIGINT",P)}break}default:console.error(` unknown subcommand: ${f}`),process.exit(1)}if(C.has(f)&&!e.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&!await rt(d,f)&&await I(d),x.length>0&&ee(x),!E.has(f))try{await xe(d)}catch{}}catch(x){let o=x instanceof Error?x.message:String(x);console.error(` ${f??"inspect"} failed: ${o}`);let n=/^no sim connected with id ([^;]+)(?:; connected sims: .+)?$/.exec(o),r=/^command timed out after (\d+)s$/.exec(o),a=o.startsWith("sim disconnected:")||o.startsWith("bridge never reconnected")||o.startsWith("could not connect to ws://");if(n)await Dt(d,F,n[1]);else if(/^no sim connected$/.test(o))At(F);else if(r)if(await ps(d)){let m=f??"describe";process.stderr.write(` the sim is still responsive \u2014 '${m}' just exceeded the ${r[1]}s command budget.
1015
948
  the screen's node tree is large; narrow the query or raise the budget:
1016
949
  sootsim ${m} --testid <id> # scope to one subtree
1017
950
  sootsim find --testid <id> # targeted single-node lookup
1018
951
  sootsim ${m} --timeout 60000 # raise per-command budget (ms)
1019
- `)}else go();else if(a)go();else{try{await Rt(d)}catch{}try{await te({includeTail:!0})}catch{}try{await K({includeTail:!0})}catch{}}process.exit(1)}finally{d.close()}}export{We as a,Dt as b,Eo as c,Ns as d,Ds as e,Bs as f,Cs as g,js as h,se as i,So as j,Rr as k};
952
+ `)}else go();else if(a)go();else{try{await Et(d)}catch{}try{await te({includeTail:!0})}catch{}try{await K({includeTail:!0})}catch{}}process.exit(1)}finally{d.close()}}export{We as a,Po as b,Ns as c,As as d,Ds as e,Bs as f,Cs as g,se as h,So as i,Rr as j};