sootsim 0.1.130 → 0.1.131
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.
- package/dist-cli/bin.js +3 -3
- package/dist-cli/chunks/{agent-KNT2MNHS.js → agent-E2VVCGQU.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-OQ6MXYSM.js → agent-wrapper-33VFUNED.js} +2 -2
- package/dist-cli/chunks/{app-fonts-5YH5C37X.js → app-fonts-3L2XX7Y7.js} +2 -2
- package/dist-cli/chunks/{assert-7GTOVITS.js → assert-IWNIHSQZ.js} +2 -2
- package/dist-cli/chunks/auto-bootstrap-HVFQYW3W.js +2 -0
- package/dist-cli/chunks/beta-DTH53ZBB.js +2 -0
- package/dist-cli/chunks/{chunk-TCYVPNQO.js → chunk-34474744.js} +3 -3
- package/dist-cli/chunks/chunk-3RAF5I5P.js +1 -0
- package/dist-cli/chunks/{chunk-PBYFOCRO.js → chunk-54UKEUZT.js} +3 -3
- package/dist-cli/chunks/{chunk-7YASUTHS.js → chunk-72F7IBXI.js} +2 -2
- package/dist-cli/chunks/{chunk-FGMOSDCQ.js → chunk-7FOWPTRL.js} +1 -1
- package/dist-cli/chunks/{chunk-5IYZIY67.js → chunk-7SHQYZAV.js} +1 -1
- package/dist-cli/chunks/{chunk-QDMM6U4X.js → chunk-APVJC2UU.js} +2 -2
- package/dist-cli/chunks/{chunk-MOO23TCK.js → chunk-BG5XSXNN.js} +1 -1
- package/dist-cli/chunks/{chunk-R35KFNWH.js → chunk-CIDY56TT.js} +2 -2
- package/dist-cli/chunks/{chunk-6YKC2PAW.js → chunk-CRRUICMV.js} +2 -2
- package/dist-cli/chunks/{chunk-XPYODDHV.js → chunk-CTJ2JTGG.js} +1 -1
- package/dist-cli/chunks/{chunk-H6WPFY4K.js → chunk-CTZWPA6E.js} +2 -2
- package/dist-cli/chunks/{chunk-6YFOOGMX.js → chunk-CUISMI5W.js} +1 -1
- package/dist-cli/chunks/{chunk-YYCJASBO.js → chunk-DHAAKK5S.js} +2 -2
- package/dist-cli/chunks/{chunk-T77EKSH4.js → chunk-DII4JH4V.js} +1 -1
- package/dist-cli/chunks/{chunk-XRIPNBCE.js → chunk-ENEBFN4F.js} +2 -2
- package/dist-cli/chunks/{chunk-VGCTSDGM.js → chunk-ENZN7H6M.js} +29 -21
- package/dist-cli/chunks/{chunk-7NG5U6NK.js → chunk-F5KSHD45.js} +3 -3
- package/dist-cli/chunks/{chunk-NEXDOXJ3.js → chunk-GU4JWEE2.js} +1 -1
- package/dist-cli/chunks/{chunk-DLYAXBRT.js → chunk-HGKXZJYM.js} +2 -2
- package/dist-cli/chunks/{chunk-SPJXGCEP.js → chunk-J6LN6U7I.js} +1 -1
- package/dist-cli/chunks/{chunk-KYJJSQWY.js → chunk-JB2XTOTE.js} +2 -2
- package/dist-cli/chunks/chunk-LCFEK3M3.js +2 -0
- package/dist-cli/chunks/{chunk-4KQKAI4R.js → chunk-LN2EUFKP.js} +1 -1
- package/dist-cli/chunks/{chunk-5QO3N7MG.js → chunk-LTDKALGE.js} +1 -1
- package/dist-cli/chunks/{chunk-K5N6S6MK.js → chunk-LTEPSJWI.js} +2 -2
- package/dist-cli/chunks/{chunk-RSJKAVWL.js → chunk-M3EAG7DW.js} +2 -2
- package/dist-cli/chunks/{chunk-77BLGF7T.js → chunk-MAWBNHA7.js} +2 -2
- package/dist-cli/chunks/{chunk-DRHDI7V4.js → chunk-NBV6N5JG.js} +2 -2
- package/dist-cli/chunks/{chunk-HCGT7RFQ.js → chunk-NF6TBFVQ.js} +1 -1
- package/dist-cli/chunks/{chunk-LBRLBJAS.js → chunk-NKLWLNTN.js} +1 -1
- package/dist-cli/chunks/chunk-QXDMTVKI.js +1 -0
- package/dist-cli/chunks/{chunk-IGQ54SMC.js → chunk-S2HUCQ2V.js} +2 -2
- package/dist-cli/chunks/{chunk-OHPV4WP2.js → chunk-SIHVPRJ5.js} +1 -1
- package/dist-cli/chunks/{chunk-SK4G3KBR.js → chunk-SL3QE2ZH.js} +2 -2
- package/dist-cli/chunks/chunk-SN35VFLV.js +1 -0
- package/dist-cli/chunks/{chunk-MWZ2K75V.js → chunk-T3EWCDR6.js} +1 -1
- package/dist-cli/chunks/{chunk-3QB2RIJ3.js → chunk-U6ZEGWUP.js} +2 -2
- package/dist-cli/chunks/{chunk-BIWTU6Y6.js → chunk-UDR5W52Q.js} +2 -2
- package/dist-cli/chunks/{chunk-OOTZNIHU.js → chunk-WBH7RWVG.js} +2 -2
- package/dist-cli/chunks/{chunk-4A5BPDNH.js → chunk-WCLVBJP6.js} +2 -2
- package/dist-cli/chunks/{chunk-YRRFLKL4.js → chunk-WMMBJ6EZ.js} +1 -1
- package/dist-cli/chunks/{chunk-JALLIXYA.js → chunk-WVXACDTN.js} +2 -2
- package/dist-cli/chunks/{chunk-OP5XM4ED.js → chunk-Y6P7ZGST.js} +2 -2
- package/dist-cli/chunks/cli-version-XAA6XJ3E.js +2 -0
- package/dist-cli/chunks/{compat-NXBN3X4Z.js → compat-G7MILF5C.js} +3 -3
- package/dist-cli/chunks/{config-TBUMHWAL.js → config-EK2MX5TM.js} +2 -2
- package/dist-cli/chunks/control-7D5EKP3M.js +2 -0
- package/dist-cli/chunks/{cpu-profile-UFGS2RPI.js → cpu-profile-WQLZZH22.js} +2 -2
- package/dist-cli/chunks/{daemon-BUW7GFTP.js → daemon-D667VAR5.js} +2 -2
- package/dist-cli/chunks/{debug-7TLF5GM5.js → debug-J6KCXN3Y.js} +3 -3
- package/dist-cli/chunks/{detox-MPVMCPWZ.js → detox-TVIZT3LO.js} +2 -2
- package/dist-cli/chunks/{device-APKKBXMJ.js → device-BI4WKSGV.js} +2 -2
- package/dist-cli/chunks/{diagnose-FVLVFNDW.js → diagnose-ACPZLWXQ.js} +2 -2
- package/dist-cli/chunks/drivers-NVAOF3WK.js +2 -0
- package/dist-cli/chunks/{electron-X2DEUVXA.js → electron-ZD5PU6TI.js} +3 -3
- package/dist-cli/chunks/flow-TL6WIR4C.js +2 -0
- package/dist-cli/chunks/help-42HSJPZ5.js +2 -0
- package/dist-cli/chunks/{hints-D47SYWGV.js → hints-2VDMGSC5.js} +2 -2
- package/dist-cli/chunks/{home-paths-23FGUKN4.js → home-paths-VO4BR5BK.js} +2 -2
- package/dist-cli/chunks/{inspect-HEJB6NB6.js → inspect-RM6DGHRB.js} +81 -81
- package/dist-cli/chunks/install-WEVANG74.js +2 -0
- package/dist-cli/chunks/{install-desktop-5ZBMF444.js → install-desktop-FRPHDKRC.js} +3 -3
- package/dist-cli/chunks/{keys-CI2XOBPT.js → keys-WUOPL5VX.js} +2 -2
- package/dist-cli/chunks/{launch-6R6RY6R5.js → launch-SAVHAJ6N.js} +3 -3
- package/dist-cli/chunks/{login-VLLUNVK7.js → login-7MA4OPGV.js} +4 -4
- package/dist-cli/chunks/{logout-D4YKYIDG.js → logout-YL5XHMYM.js} +2 -2
- package/dist-cli/chunks/{maestro-KLROSFMP.js → maestro-LCOVHJ7D.js} +2 -2
- package/dist-cli/chunks/{preview-O4365QYC.js → preview-BIKZNTRD.js} +2 -2
- package/dist-cli/chunks/{profile-VAEKDLEX.js → profile-KKIOWCDH.js} +2 -2
- package/dist-cli/chunks/{react-MMA3LE34.js → react-UJA6V4RC.js} +2 -2
- package/dist-cli/chunks/{record-GVWF4BNF.js → record-ACTA66DL.js} +2 -2
- package/dist-cli/chunks/runtime-ZPITJAAY.js +2 -0
- package/dist-cli/chunks/{runtime-delivery-4SSWMW25.js → runtime-delivery-Z7YPY56X.js} +2 -2
- package/dist-cli/chunks/{screenshot-C72QGUMV.js → screenshot-6CUMBC6A.js} +2 -2
- package/dist-cli/chunks/{screenshot-mode-OCTJDADF.js → screenshot-mode-YNBFDLFN.js} +2 -2
- package/dist-cli/chunks/{screenshots-AWDE4NDZ.js → screenshots-QVOIWNG6.js} +2 -2
- package/dist-cli/chunks/{server-K6KOFHSQ.js → server-YNEOBB5D.js} +3 -3
- package/dist-cli/chunks/setup-repo-HCDKAHBY.js +2 -0
- package/dist-cli/chunks/{skills-DIETG7L3.js → skills-CH3QSSBF.js} +2 -2
- package/dist-cli/chunks/{start-R54AVUYP.js → start-RYCAWIQ7.js} +4 -4
- package/dist-cli/chunks/store-32NRKG33.js +2 -0
- package/dist-cli/chunks/telemetry-HIY3SXVC.js +2 -0
- package/dist-cli/chunks/{test-6EZ2YHEN.js → test-37ZDD753.js} +3 -3
- package/dist-cli/chunks/{three-mode-FWE57WZP.js → three-mode-BSY6KVQM.js} +2 -2
- package/dist-cli/chunks/{timeline-4FFLAGNO.js → timeline-ZD3TGYAF.js} +2 -2
- package/dist-cli/chunks/{upgrade-RI62D65F.js → upgrade-UOAM4Q35.js} +2 -2
- package/dist-cli/chunks/upload-RVUDLEEB.js +2 -0
- package/dist-cli/chunks/{version-RHWBKIPW.js → version-O3YK6QEA.js} +2 -2
- package/dist-cli/chunks/{web-U4RROYGL.js → web-LAT537VP.js} +2 -2
- package/dist-cli/chunks/{what-happened-QYK3MLTS.js → what-happened-OXU5NEZK.js} +2 -2
- package/dist-cli/chunks/{whoami-XO5L3YTX.js → whoami-3OH4BMEA.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +1 -1
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/demo-app-registry.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +26 -9
- package/dist-lib/sdk.mjs +25 -9
- package/dist-lib/skills.cjs +1 -1
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/dist-cli/chunks/auto-bootstrap-7QUYTCK3.js +0 -2
- package/dist-cli/chunks/beta-TKYV2VUL.js +0 -2
- package/dist-cli/chunks/chunk-4TWK4GWQ.js +0 -2
- package/dist-cli/chunks/chunk-544KNXXS.js +0 -1
- package/dist-cli/chunks/chunk-HKKCAEKK.js +0 -1
- package/dist-cli/chunks/chunk-TOPGPGVZ.js +0 -1
- package/dist-cli/chunks/cli-version-SHSHHYXU.js +0 -2
- package/dist-cli/chunks/control-CAPNUH2B.js +0 -2
- package/dist-cli/chunks/drivers-QQJOT5IF.js +0 -2
- package/dist-cli/chunks/flow-SOFJ7QI3.js +0 -2
- package/dist-cli/chunks/help-ZFJBFDNU.js +0 -2
- package/dist-cli/chunks/install-5XBIUQGH.js +0 -2
- package/dist-cli/chunks/runtime-ZE6YLTHF.js +0 -2
- package/dist-cli/chunks/setup-repo-KZDLN5I2.js +0 -2
- package/dist-cli/chunks/store-3I5TVDYR.js +0 -2
- package/dist-cli/chunks/telemetry-MZWJNMXL.js +0 -2
- package/dist-cli/chunks/upload-2OQWKQOR.js +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{a as G}from"./chunk-
|
|
3
|
-
`)}function ko(e,c){let n=c.trim()||"default";return`${e}:${n}`}function Ee(e,c,n,l={}){let m=l.nowMs??Date.now(),
|
|
1
|
+
/*! sootsim v0.1.131 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as G}from"./chunk-WCLVBJP6.js";import{a as wt,b as xt}from"./chunk-7FOWPTRL.js";import{a as Ye,h as $e,k as ee}from"./chunk-72F7IBXI.js";import{b as $t,c as St,j as vt}from"./chunk-WVXACDTN.js";import"./chunk-HGKXZJYM.js";import{a as Z,b as A,c as P,d as Pe,e as re,f as Y,g as ce,h as pe,i as yt,j as ht,k as Re,l as bt}from"./chunk-DHAAKK5S.js";import{A as mt,E as pt,G as le,H as ft,N as gt,a as be,b as Ge,c as Xe,d as Ve,e as Qe,f as Ze,g as et,h as tt,i as ot,j as st,k as _e,l as Oe,p as Ae,q as nt,r as rt,s as we,t as it,u as xe,v as at,w as lt,x as ct,y as dt,z as ut}from"./chunk-ENZN7H6M.js";import"./chunk-NKLWLNTN.js";import{c as He,e as Ue,f as Ke,g as ze,h as Fe}from"./chunk-CIDY56TT.js";import"./chunk-M3EAG7DW.js";import"./chunk-GU4JWEE2.js";import"./chunk-SN35VFLV.js";import"./chunk-LTEPSJWI.js";import"./chunk-DII4JH4V.js";import{b as qe}from"./chunk-SIHVPRJ5.js";import{a as Je}from"./chunk-T3EWCDR6.js";import{a as Ie,c as Ne}from"./chunk-BG5XSXNN.js";import{a as We}from"./chunk-LCFEK3M3.js";import"./chunk-7SHQYZAV.js";import"./chunk-LTDKALGE.js";import"./chunk-LN2EUFKP.js";import{existsSync as co,mkdirSync as uo,readFileSync as mo,rmSync as kt,writeFileSync as po}from"fs";import{tmpdir as fo}from"os";import{dirname as go,join as yo,resolve as ho}from"path";var fe=1,bo="SOOTSIM_INSPECT_NOTICE_PATH",wo=300*1e3,xo=15e3;function Tt(){return ho(process.env[bo]||yo(fo(),"sootsim-inspect-notice-state.json"))}function $o(e,c){return Object.fromEntries(Object.entries(e).filter(([,n])=>typeof n?.signature=="string"&&Number.isFinite(n?.updatedAt)&&c-n.updatedAt<=wo))}function So(e){let c=Tt();if(!co(c))return{version:fe,entries:{}};try{let n=JSON.parse(mo(c,"utf8"));return n.version!==fe||!n.entries||typeof n.entries!="object"?(kt(c,{force:!0}),{version:fe,entries:{}}):{version:fe,entries:$o(n.entries,e)}}catch{return kt(c,{force:!0}),{version:fe,entries:{}}}}function vo(e){let c=Tt();uo(go(c),{recursive:!0}),po(c,JSON.stringify(e,null,2)+`
|
|
3
|
+
`)}function ko(e,c){let n=c.trim()||"default";return`${e}:${n}`}function Ee(e,c,n,l={}){let m=l.nowMs??Date.now(),r=l.cooldownMs??xo,g=So(m),y=ko(e,c),T=g.entries[y];return T&&T.signature===n&&m-T.updatedAt<r?!1:(g.entries[y]={signature:n,updatedAt:m},vo(g),!0)}var To={initialWaitMs:3e3,deadlineMs:5e3,retryWaitMs:700},Mo={initialWaitMs:1200,deadlineMs:2500,retryWaitMs:700};function Io(e,c={}){return{...e?To:Mo,...c}}function de(e){return!(!e||e.hit===!1||e.ok===!1||e.pointerTapHandled===!1&&!e.keyboardOpened&&!e.isTextInput)}function No(e,c){return{id:e.target?.id??e.match?.id??e.node?.id??null,testID:e.target?.testID??e.match?.testID??e.node?.testID??null,text:e.target?.text??e.target?.accessibilityLabel??e.match?.text??e.match?.accessibilityLabel??e.node?.text??c??null,type:e.target?.type??e.match?.type??e.node?.type??null}}async function ge(e,c){let n=Io(!!c.agent,c.timing),l=0,m=null,r=null;try{await ee({bridge:e,maxMs:n.initialWaitMs,pollMs:32,stablePolls:2})}catch{}let g=Date.now()+n.deadlineMs;for(;Date.now()<=g||l===0;){l++;let y=await c.resolve();if(m=y,y?.error==="bridge-not-ready"||y?.ambiguous||y?.nthOutOfRange)return{payload:y,result:null,attempts:l,failure:"special"};if(y&&typeof y.cx=="number"&&typeof y.cy=="number"){let M=await e.send({type:"tap",x:y.cx,y:y.cy,target:No(y,c.textFallback)});if(r=M,de(M))return{payload:y,result:M,attempts:l}}let T=g-Date.now();if(T<=0)break;try{await ee({bridge:e,maxMs:Math.min(T,n.retryWaitMs),pollMs:32,stablePolls:2})}catch{await new Promise(M=>setTimeout(M,Math.min(120,T)))}}return{payload:m,result:r,attempts:l,failure:m&&typeof m.cx=="number"?"missed":"not-found"}}async function Mt(e,c,n,l){return e.send({type:"tap",x:c,y:n,...l?{target:l}:{}})}async function It(e,c,n={}){let l=JSON.stringify(c);return ge(e,{agent:n.agent,timing:n.timing,resolve:()=>e.send({type:"evaluate",code:`(async () => {
|
|
4
4
|
const t = window.__sootsimTest
|
|
5
5
|
if (!t) return null
|
|
6
6
|
const n = (await t.findByTestId(${l})) || (await t.findById(${l}))
|
|
@@ -197,16 +197,16 @@ import{a as G}from"./chunk-4A5BPDNH.js";import{a as wt,b as xt}from"./chunk-FGMO
|
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
return { strategy: 'none' }
|
|
200
|
-
})()`});if(!m||!("node"in m))return m;let
|
|
200
|
+
})()`});if(!m||!("node"in m))return m;let r=m.node,g=r.absolutePosition.x+r.layout.width/2,y=r.absolutePosition.y+r.layout.height/2;return{...m,cx:g,cy:y,target:{id:r.id,testID:r.testID,text:m.strategy==="text"?c:r.text,type:r.type}}}})}async function _t(e,c={args:[]}){let n=await Xe(e);if(A(c.args)){P(n);return}console.log(` nodes: ${n.nodes}`)}function De(e,c){let n=e.indexOf(c);return n>=0&&n+1<e.length?e[n+1]:null}async function Ot(e){let{bridge:c,args:n,positional:l}=e,m=n.includes("--verbose")||n.includes("-v"),r=A(n),g=m&&!r,y=n.includes("--watch")||n.includes("-w"),T=1e3,M=n.includes("--compact"),h=n.includes("--no-xy"),k=n.includes("--no-clipped"),_=n.includes("--include-occluded"),I=De(n,"--testid-like"),R=De(n,"--only"),j=De(n,"--subtree"),d=l[1]&&!l[1].startsWith("-")?l[1]:void 0,z=d?/[*?]/.test(d):!1,B=!z&&!R?d:void 0,D=R??(z?d:void 0),V=async()=>{await ce(c,{verbose:g});let S=await Ze(c,{describe:!0,verbose:m,filter:B||"",testIdLike:I||void 0,onlyGlob:D||void 0,subtreeRoot:j||void 0,compact:M,hideXy:h,includeOccluded:_}),N=S?.tree,J=S?.shell,W=S?.keyboard;if(r){P({shell:J,tree:N??"",keyboard:W});return}if(J&&typeof J=="object"){let C=[J.state?`state=${J.state}`:null,J.activeApp?`app=${J.activeApp}`:null,J.showSwitcher?"switcher":null,J.switcherPhase&&J.switcherPhase!=="idle"?`phase=${J.switcherPhase}`:null].filter(Boolean);C.length>0&&console.log(` shell: ${C.join(" ")}`)}if(typeof N=="string"&&N.startsWith("__SUBTREE_NOT_FOUND__:")){let C=N.slice(22);console.log(` subtree root not found: ${C}`),G("subtree-root-not-found",C);return}if(!N){let C=S?.nodeCount??0;console.log(" no matching nodes found"),!(B||I||D||j)&&C<10&&G("app-still-loading",C);return}let X=N,Q=0;if(k&&typeof X=="string"){let C=X.split(`
|
|
201
201
|
`),ae=[];for(let o of C){if(o.includes("(clipped:")){Q+=1;continue}ae.push(o)}X=ae.join(`
|
|
202
202
|
`)}console.log(X),Q>0&&console.log(` ${Q} clipped row(s) hidden (omit --no-clipped to see)`);let ne=B||I||D||j;if((B||I||D)&&!y&&G("describe-filter-context"),!ne&&!y&&N.split(`
|
|
203
203
|
`).length>=80&&G("describe-use-filters"),W&&W.visible){let C=W.spec,ae=[C?.keyboardType?`type=${C.keyboardType}`:null,C?.returnKeyType&&C.returnKeyType!=="default"?`return=${C.returnKeyType}`:null,W.mode!=="letters"?`mode=${W.mode}`:null,W.shifted?"shift":null,W.capsLock?"caps":null,C?.autoCapitalize&&C.autoCapitalize!=="sentences"?`autoCap=${C.autoCapitalize}`:null,W.accessoryBarId?`accessory=${W.accessoryBarId}`:null].filter(Boolean);console.log(`
|
|
204
204
|
keyboard: ${ae.join(" ")||"visible"}`)}};if(y)for(console.log(` watching... (Ctrl+C to stop)
|
|
205
|
-
`);;)console.clear(),await V(),await Z(T);else await V()}var Fo=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function ue(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let e of Fo){let c=process.env[e];if(c&&c.trim()&&c!=="0")return!0}return!1}async function At(e){let{bridge:c,args:n,effectiveArgs:l,positional:m,inspectUsage:
|
|
205
|
+
`);;)console.clear(),await V(),await Z(T);else await V()}var Fo=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function ue(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let e of Fo){let c=process.env[e];if(c&&c.trim()&&c!=="0")return!0}return!1}async function At(e){let{bridge:c,args:n,effectiveArgs:l,positional:m,inspectUsage:r}=e,g=S=>{let N=l.indexOf(S);return N>=0&&N+1<l.length?l[N+1]:null},y=S=>l.includes(S),T=g("--testid")||g("--test-id"),M=g("--role"),h=g("--type"),k=g("--text"),_=y("--pressable"),I=y("--visible"),R=y("--interactive-targets")||y("--actions"),j=!T&&!M&&!h&&!k&&!_&&!I&&!R?m[1]:null,d=k??j,z=await st(c,{testId:T,role:M,type:h,text:d,pressable:_,visible:I,interactive:R});z||(console.error(r("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:B,result:D}=z,V=A(n),te=n.includes("--verbose")||n.includes("--dump");if(V)B==="interactive-targets"&&Array.isArray(D)?P(_e(D).map(S=>({...S,tap:Oe(S)}))):P(D??null);else if(Array.isArray(D))if(D.length===0){console.log(` no ${B} nodes found`);let S=await c.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof S=="number"&&S<10&&G("app-still-loading",S)}else if(B==="interactive-targets"){let S=_e(D);console.log(` found ${S.length} interactive target${S.length===1?"":"s"} (sorted by score):`);for(let N of S.slice(0,20)){let J=N.absolutePosition?`@(${Math.round(N.absolutePosition.x)},${Math.round(N.absolutePosition.y)})`:"",W=N.layout?`${Math.round(N.layout.width)}x${Math.round(N.layout.height)}`:"?x?",X=N.text?` "${N.text.slice(0,30)}"`:"",Q=N.testID?` #${N.testID}`:"",ne=N.accessibilityLabel?` \u24D8"${String(N.accessibilityLabel).slice(0,24)}"`:"",me=N.accessibilityRole?`[${N.accessibilityRole}]`:N.type,C=Oe(N);console.log(` ${me}${X}${ne}${Q} ${W} ${J}`),console.log(` \u2192 ${C}`),te&&console.log(Ce(JSON.stringify(N,null,2)," "))}S.length>20&&console.log(` ... and ${S.length-20} more`)}else{console.log(` found ${D.length} node${D.length===1?"":"s"} (${B}):`);for(let S of D.slice(0,20)){let N=S.absolutePosition?`@(${Math.round(S.absolutePosition.x)},${Math.round(S.absolutePosition.y)})`:"",J=S.layout?`${Math.round(S.layout.width)}x${Math.round(S.layout.height)}`:"?x?",W=S.text?` "${S.text.slice(0,30)}"`:"",X=S.testID?` #${S.testID}`:"",Q=S.pressable?" (tap)":"",ne=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${ne}${W}${X} ${J} ${N}${Q}`),te&&console.log(Ce(JSON.stringify(S,null,2)," "))}D.length>20&&console.log(` ... and ${D.length-20} more`)}else if(D==null)console.log(` not found: ${d||T||M||h||""||B}`),T&&G("wait-selector-for-missing-testid",T);else{let S=D;if(S.type&&S.absolutePosition){let N=`@(${Math.round(S.absolutePosition.x)},${Math.round(S.absolutePosition.y)})`,J=S.layout?`${Math.round(S.layout.width)}x${Math.round(S.layout.height)}`:"?x?",W=S.text?` "${S.text.slice(0,40)}"`:"",X=S.testID?` #${S.testID}`:"",Q=S.pressable?" (tap)":"",ne=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${ne}${W}${X} ${J} ${N}${Q}`),te&&console.log(Ce(JSON.stringify(S,null,2)," "))}else console.log(JSON.stringify(D,null,2))}}function Ce(e,c){return e.split(`
|
|
206
206
|
`).map(n=>c+n).join(`
|
|
207
|
-
`)}async function Pt(e){let{bridge:c,args:n}=e,l=A(n);await ce(c,{verbose:!l});let m=await et(c);if(l){P({count:
|
|
208
|
-
`),console.log(tt(
|
|
209
|
-
`))}async function Et(e){let c=await e.bridge.listSims(),n=e.args.includes("--all"),l=e.args.find((y,T)=>e.args[T-1]==="--bundle"),m=e.args.find((y,T)=>e.args[T-1]==="--app-port"),
|
|
207
|
+
`)}async function Pt(e){let{bridge:c,args:n}=e,l=A(n);await ce(c,{verbose:!l});let m=n.includes("--styling"),r=await et(c,{styling:m});if(l){P({count:r.length,elements:r});return}console.log(` layout (${r.length} element${r.length===1?"":"s"}):
|
|
208
|
+
`),console.log(tt(r,{styling:m}))}async function Rt(e,c={}){let n=await pt(e);if("error"in n&&(console.error(n.error),process.exit(1)),c.json){console.log(JSON.stringify(n,null,2));return}let{visible:l,spec:m,mode:r,shifted:g,capsLock:y,accessoryBarId:T}=n,M=[];M.push(`keyboard: ${l?"visible":"hidden"}`),m?(M.push(` type: ${m.keyboardType}`),M.push(` returnKey: ${m.returnKeyType}`),M.push(` autoCap: ${m.autoCapitalize}`),M.push(` autoCorrect: ${m.autoCorrect?"on":"off"}`),M.push(` appearance: ${m.keyboardAppearance}`),m.secureTextEntry&&M.push(" secureTextEntry: true"),m.enablesReturnKeyAutomatically&&M.push(` return: ${m.currentTextIsEmpty?"disabled (empty)":"enabled"}`)):M.push(" spec: <none> (shown via dev-tools with no TextInput)"),M.push(` mode: ${r}${g?" (shifted)":""}${y?" (caps)":""}`),T&&M.push(` accessoryBar: ${T}`),console.log(M.join(`
|
|
209
|
+
`))}async function Et(e){let c=await e.bridge.listSims(),n=e.args.includes("--all"),l=e.args.find((y,T)=>e.args[T-1]==="--bundle"),m=e.args.find((y,T)=>e.args[T-1]==="--app-port"),r=e.args.includes("--primary"),g=c.filter(y=>!(r&&!y.isPrimary||l&&!(y.url??"").includes(l)||m&&!(y.url??"").includes(`/rn/${m}`)||!n&&!l&&!m&&!r&&!(y.url&&(y.url.includes("bundle=")||y.url.includes("/index.bundle")))&&y.id!==e.simId));if(A(e.args)){P(g.map(y=>({...y,active:y.id===e.simId})));return}vt(g,e.simId),g.length<c.length&&!A(e.args)&&console.log(` (${c.length-g.length} more hidden \u2014 pass --all to show)`)}function ie(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/1024/1024).toFixed(1)}MB`}function Se(e,c){return c<=0?"?":`${(e/c*100).toFixed(0)}%`}async function Dt(e,c={args:[]}){let n=await gt(e);if(A(c.args)){P(n);return}if(console.log(" memory:"),n.imageLoader){let l=n.imageLoader;console.log(" image-loader cache"),console.log(` entries: ${l.cacheEntries} / ${l.cacheMaxEntries} (${Se(l.cacheEntries,l.cacheMaxEntries)})`),console.log(` pixel bytes: ${ie(l.cachePixelBytes)} / ${ie(l.cachePixelBudget)} (${Se(l.cachePixelBytes,l.cachePixelBudget)})`),console.log(` pending: ${l.pendingFetches} fetches, ${l.pendingBytes} bytes`),console.log(` failed uris: ${l.failedUris}`),console.log(` snapshots: ${l.snapshots}`),console.log(` camera frames: ${l.cameraFrames}`)}else console.log(" image-loader cache: not available (engine pre-rebuild?)");if(n.workerHeap){let l=n.workerHeap;console.log(" worker heap (chrome only)"),console.log(` used: ${ie(l.usedJSHeapSize)} / ${ie(l.jsHeapSizeLimit)} (${Se(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${ie(l.totalJSHeapSize)}`)}if(n.hostHeap){let l=n.hostHeap;console.log(" host heap (chrome only)"),console.log(` used: ${ie(l.usedJSHeapSize)} / ${ie(l.jsHeapSizeLimit)} (${Se(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${ie(l.totalJSHeapSize)}`)}}function ye(e){let c=e.indexOf("--testid");if(c>=0&&e[c+1])return{mode:"testid",value:e[c+1]};let n=e.indexOf("--test-id");if(n>=0&&e[n+1])return{mode:"testid",value:e[n+1]};let l=e.indexOf("--text");return l>=0&&e[l+1]?{mode:"text",value:e[l+1]}:null}async function ve(e,c){let n=JSON.stringify(c.value),l=c.mode==="testid"?`(await t.findByTestId(${n})) || (await t.findById(${n}))`:`await t.findByText(${n})`;return await e.send({type:"evaluate",code:`(async () => {
|
|
210
210
|
const t = window.__sootsimTest
|
|
211
211
|
if (!t) return null
|
|
212
212
|
const n = ${l}
|
|
@@ -231,12 +231,12 @@ import{a as G}from"./chunk-4A5BPDNH.js";import{a as wt,b as xt}from"./chunk-FGMO
|
|
|
231
231
|
text: ${JSON.stringify(c.mode==="text")} ? ${n} : (n.text ?? n.accessibilityLabel ?? null),
|
|
232
232
|
type: n.type ?? null,
|
|
233
233
|
}
|
|
234
|
-
})()`})??null}async function Ct(e,c={}){let{nav:n,keyboard:l,shell:m}=await ft(e);if(c.json){console.log(JSON.stringify({shell:m??null,nav:n,keyboard:l},null,2));return}let
|
|
235
|
-
`))}async function Bt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1])*1e3:3e3,
|
|
234
|
+
})()`})??null}async function Ct(e,c={}){let{nav:n,keyboard:l,shell:m}=await ft(e);if(c.json){console.log(JSON.stringify({shell:m??null,nav:n,keyboard:l},null,2));return}let r=[];if(m){let g=m.activeApp??m.state??"<none>",y=m.showSwitcher?" (app switcher open)":"",T=typeof m.launchProgress=="number"&&m.launchProgress<.98?` launching (${Math.round(m.launchProgress*100)}%)`:"";r.push(`shell: ${g}${y}${T}`)}else r.push("shell: <unavailable>");if(n){let g=n.transitionPhase!=="idle"?` (${n.transitionPhase}, ${n.activeTransitionCount} active)`:"";if(r.push(`nav: phase=${n.transitionPhase}${g}`),n.screens.length===0)r.push(" <no registered screens \u2014 app may not use react-native-screens>");else for(let y of n.screens){let T=y.isActive?"\u25B6":" ",M=y.routeName?` ${y.routeName}`:"",h=y.headerHeight>0?` header=${y.headerHeight}`:"",k=y.largeTitleState&&y.largeTitleState!=="expanded"?` large-title=${y.largeTitleState}`:"";r.push(` ${T} #${y.id}${M}${h}${k}`)}}else r.push("nav: <runtime not available>");if(l&&l.visible){let g=l.spec?.keyboardType??"default",y=l.spec?.returnKeyType??"default";r.push(`keyboard: visible (${g}, return=${y}, mode=${l.mode??"?"})`)}else r.push("keyboard: hidden");console.log(r.join(`
|
|
235
|
+
`))}async function Bt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1])*1e3:3e3,r=n.includes("--strict"),{elapsed:g,settled:y}=await ee({bridge:c,maxMs:m,strict:r});console.log(y?` settled in ${g}ms`:` timed out after ${g}ms (may still be animating)`)}async function jt(e){let c=e.positional[1]?Number(e.positional[1]):.5;(!Number.isFinite(c)||c<0)&&(console.error(e.inspectUsage("sleep","[seconds]")),process.exit(1)),await Z(c*1e3),console.log(` slept ${c}s`)}async function Lt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1]):5,{tree:r}=await Ve(c,m);if(A(n)){P({depth:m,tree:r??null});return}console.log(typeof r=="string"?r:JSON.stringify(r,null,2))}async function Jt(e,c={args:[]}){let n=await Qe(e);if(A(c.args)){P(n);return}console.log(n.url)}async function Wt(e){let{wsPort:c,commandTimeoutMs:n,simId:l,simIdSource:m,positional:r}=e,g=r[1]?Number(r[1]):30,y=Math.max(1e3,(Number.isFinite(g)?g:30)*1e3),T=Math.max(1,Math.ceil(y/500));console.log(" waiting for sim reconnect...");let M=await yt(c,n,l,{attempts:T,simIdSource:m});M||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),M.bridge.close(),$e({source:"inspect wait",step:{wait:y},summary:`wait ${Math.round(y/1e3)}s`}),console.log(` ready: ${M.count} nodes`)}var qt=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function ke(e,c){let n=e.indexOf(c);if(n>=0&&n+1<e.length)return e[n+1]}function _o(e,c){if(!c.filter&&!c.equals)return!0;let n=e.data,l=[];if(n&&typeof n=="object")for(let r of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let g=n[r];typeof g=="string"&&g.length>0&&l.push(g)}let m=l.join(" ");return c.equals?l.some(r=>r===c.equals):c.filter?m.toLowerCase().includes(c.filter.toLowerCase()):!0}async function Ht(e){let{bridge:c,args:n,positional:l,inspectUsage:m}=e,r=l[1];r||(console.error(m("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),qt.has(r)||console.error(` warning: '${r}' is not a known timeline kind \u2014 waiting anyway. known: ${[...qt].sort().join(", ")}`);let g=ke(n,"--max-ms"),y=g&&Number.isFinite(Number(g))?Math.max(100,Number(g)):5e3,T=ke(n,"--filter"),M=ke(n,"--equals"),h=ke(n,"--since")??"now",k=n.includes("--json"),_=Date.now(),I=_+y,R=200,j=_;for(;Date.now()<I;){let z={kinds:[r],since:h==="cursor"?void 0:j,limit:50},B=await c.send({type:"evaluate",code:`(async () => {
|
|
236
236
|
const t = window.SootSim?.bridges?.timeline
|
|
237
237
|
if (!t) return { ok: false, error: 'timeline bridge missing' }
|
|
238
238
|
return { ok: true, result: await t.recent(${JSON.stringify(z)}) }
|
|
239
|
-
})()`});(!B||!B.ok)&&(console.error(` could not query timeline: ${B&&"error"in B?B.error:"unknown"}`),process.exit(1));let D=B.result.events??[];for(let V of D)if(_o(V,{filter:T,equals:M})){let te=Date.now()-_;console.log(k?JSON.stringify({found:!0,elapsedMs:te,event:V}):` ${
|
|
239
|
+
})()`});(!B||!B.ok)&&(console.error(` could not query timeline: ${B&&"error"in B?B.error:"unknown"}`),process.exit(1));let D=B.result.events??[];for(let V of D)if(_o(V,{filter:T,equals:M})){let te=Date.now()-_;console.log(k?JSON.stringify({found:!0,elapsedMs:te,event:V}):` ${r} event after ${te}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`);return}B.result.watermark&&B.result.watermark>j&&(j=B.result.watermark),await new Promise(V=>setTimeout(V,R))}let d=Date.now()-_;k?console.log(JSON.stringify({found:!1,elapsedMs:d,kind:r,filter:T,equals:M})):console.error(` \u26A0 wait event ${r} timed out after ${d}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`),process.exit(1)}async function Ut(e){let{bridge:c,args:n}=e,l=n.includes("--strict"),m=be(n,3e3),{elapsed:r,settled:g}=await ee({bridge:c,maxMs:m,strict:l});g?console.log(` idle in ${r}ms`):(console.error(` \u26A0 wait idle timed out after ${r}ms (may still be animating)`),process.exit(1))}async function Kt(e){let{bridge:c,args:n}=e,l=be(n,2e4),{ready:m,elapsedMs:r,nodes:g,targets:y,flag:T,loadingText:M,externalReady:h,externalError:k,errors:_}=await nt(c,l,{onProgress(R){console.error(` still waiting after ${R.elapsedMs}ms \u2014 ${Ae(R)} (nodes: ${R.nodes}, targets: ${R.targets}, errors: ${R.errors})`)}});if(m){let R=l-r,j=Math.max(100,Math.min(1e4,R)),d=await ee({bridge:c,maxMs:j,pollMs:32,stablePolls:2});d.settled||(console.error(` \u26A0 wait ready timed out after ${r+d.elapsed}ms \u2014 app mounted but did not settle (nodes: ${g}, targets: ${y})`),process.exit(1)),console.log(` ready in ${r+d.elapsed}ms: ${g} nodes, ${y} targets`);return}let I=Ae({externalError:k,loadingText:M,externalReady:h,flag:T,targets:y});console.error(` \u26A0 wait ready timed out after ${r}ms \u2014 ${I} (nodes: ${g}, targets: ${y}, errors: ${_})`),process.exit(1)}async function zt(e){let{bridge:c,args:n,positional:l,inspectUsage:m}=e,r=l[1];r||(console.error(m("wait selector","<testid> [--max-ms 5000] [--gone]")),process.exit(1));let g=n.indexOf("--max-ms"),y=g>=0&&n[g+1]?Math.max(100,Number(n[g+1])):5e3,T=n.includes("--gone"),{found:M,node:h,elapsed:k}=await rt(c,r,y,{gone:T});if(T){M?console.log(` #${r} gone after ${k}ms`):(console.error(` \u26A0 wait selector #${r} --gone timed out after ${k??y}ms (still present)`),process.exit(1));return}if(M&&h){let _=h.absolutePosition?`@(${Math.round(h.absolutePosition.x)},${Math.round(h.absolutePosition.y)})`:"",I=h.layout?`${Math.round(h.layout.width)}x${Math.round(h.layout.height)}`:"?x?";console.log(` found #${r} in ${k}ms ${I} ${_}`)}else console.error(` \u26A0 wait selector #${r} timed out after ${k??y}ms`),process.exit(1)}function to(e){return e==null?"\u2014":e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}K`:`${(e/1024/1024).toFixed(1)}M`}function oo(e){return e==null?" \u2026":e<1e3?`${e}ms`.padStart(5):`${(e/1e3).toFixed(2)}s`.padStart(5)}function Yt(){process.stderr.write(` the sim is not responding. recover it with:
|
|
240
240
|
sootsim close --sim <id> # force-close the wedged sim
|
|
241
241
|
sootsim list # confirm it's gone
|
|
242
242
|
`)}async function Ao(e){try{return await e.send({type:"evaluate",code:"1"},{timeoutMs:3e3}),!0}catch{return!1}}async function Po(e,c){try{let n=await e.send({type:"evaluate",code:`(async () => {
|
|
@@ -258,8 +258,8 @@ import{a as G}from"./chunk-4A5BPDNH.js";import{a as wt,b as xt}from"./chunk-FGMO
|
|
|
258
258
|
} catch {
|
|
259
259
|
return []
|
|
260
260
|
}
|
|
261
|
-
})()`});if(!Array.isArray(n)||n.length===0)return;let l=c.toLowerCase(),m=n.map(
|
|
262
|
-
`).slice(0,5);for(let g of
|
|
261
|
+
})()`});if(!Array.isArray(n)||n.length===0)return;let l=c.toLowerCase(),m=n.map(r=>({id:r,score:Ro(l,r.toLowerCase())})).filter(r=>r.score<l.length+4).sort((r,g)=>r.score-g.score).slice(0,5);if(m.length===0)return;console.error(" similar testIDs:");for(let r of m)console.error(` ${r.id}`)}catch{}}function Ro(e,c){if(c===e)return 0;if(c.includes(e))return 1;if(e.includes(c))return 2;let n=0;for(;n<e.length&&n<c.length&&e[n]===c[n];)n+=1;return Eo(e,c)-n}function Eo(e,c){if(e===c)return 0;if(!e.length)return c.length;if(!c.length)return e.length;let n=new Array(c.length+1),l=new Array(c.length+1);for(let m=0;m<=c.length;m++)n[m]=m;for(let m=1;m<=e.length;m++){l[0]=m;for(let g=1;g<=c.length;g++)l[g]=Math.min(n[g]+1,l[g-1]+1,n[g-1]+(e[m-1]===c[g-1]?0:1));let r=n;n=l,l=r}return n[c.length]}function Do(e){return e.error?"err":e.status==null?" \u2026 ":String(e.status)}function Co(e){return e.externalError?`guest app errored: ${e.externalError}`:e.loadingText?`still showing "${e.loadingText}"`:e.externalReady===!1?"guest app is still loading":e.flag!==!0?"guest app has not emitted sootsim:externalAppReady":e.targets<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing"}function Gt(e){let c=re(e.startTs),n=Do(e).padEnd(3),l=e.method.padEnd(5),m=to(e.size).padStart(6),r=oo(e.durationMs);console.log(` [${c}] ${n} ${l} ${m} ${r} ${e.displayUrl}`),e.error&&console.log(` error: ${e.error}`)}function Bo(e){let c=[["id",e.id],["source",e.source],["kind",e.kind],["method",e.method],["status",e.error?`error: ${e.error}`:`${e.status??"\u2014"} ${e.statusText??""}`.trim()],["url",e.url],["started",re(e.startTs)],["duration",oo(e.durationMs).trim()],["size",to(e.size)],["content-type",e.type??"\u2014"]];for(let[n,l]of c)console.log(` ${n.padEnd(13)} ${l}`)}var jo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Xt="\x1B[0m",Lo="\x1B[2m";function Vt(e,c){let n=re(e.ts),l=e.level.toUpperCase().padEnd(5),m=e.args.join(" ");if(c){let r=jo[e.level];console.log(` ${Lo}[${n}]${Xt} ${r}${l}${Xt} ${m}`)}else console.log(` [${n}] ${l} ${m}`);if(e.stack&&e.level==="error"){let r=e.stack.split(`
|
|
262
|
+
`).slice(0,5);for(let g of r)console.log(` ${g.trim()}`)}}var se="__sootsimCliPerf",Jo=120;async function Qt(e,c){let n=e.find((_,I)=>e[I-1]==="--id"),l=e.find((_,I)=>e[I-1]==="--text");if(n||l){let _=await c.send({type:"evaluate",code:wt({id:n,text:l})});if(!_)throw new Error(n?`no node with id "${n}"`:`no node matching text "${l}"`);let{x:I,y:R,w:j,h:d}=_;return{x:I,y:R,w:j,h:d}}let m=e.find((_,I)=>e[I-1]==="--area");if(m){let _=m.split(",").map(z=>Number(z.trim()));if(_.length!==4||_.some(z=>!Number.isFinite(z)))throw new Error(`--area expects x,y,w,h (got "${m}")`);let[I,R,j,d]=_;return{x:I,y:R,w:j,h:d}}let r=_=>{let I=e.find((j,d)=>e[d-1]===_);if(I==null)return null;let R=Number(I);return Number.isFinite(R)?R:null},g=r("--x"),y=r("--y"),T=r("--w"),M=r("--h");if(g!=null||y!=null||T!=null||M!=null)return{x:g??0,y:y??0,w:T??1,h:M??1};let k=e.filter((_,I)=>I>0&&!_.startsWith("-")&&e[I-1]!=="--output"&&e[I-1]!=="--area"&&e[I-1]!=="--id"&&e[I-1]!=="--text"&&e[I-1]!=="--x"&&e[I-1]!=="--y"&&e[I-1]!=="--w"&&e[I-1]!=="--h").map(Number).filter(_=>Number.isFinite(_));if(k.length>=2){let[_,I,R=1,j=1]=k;return{x:_,y:I,w:R,h:j}}return null}function Be(e){let c={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let n of e)n<8?c["<8"]++:n<12?c["8-12"]++:n<16?c["12-16"]++:n<20?c["16-20"]++:n<33?c["20-33"]++:c[">33"]++;console.log(" histogram:");for(let[n,l]of Object.entries(c)){let m="\u2588".repeat(Math.ceil(l/e.length*40));console.log(` ${n.padEnd(6)} ${m} ${l}`)}}async function Te(e,c,n){let l=Date.now()+c,m=await le(e,c);for(;;){if(n(m))return{settled:!0,state:m};if(Date.now()>=l)return{settled:!1,state:m};await Z(16),m=await le(e)}}async function Le(e){return e.send({type:"evaluate",code:`(async () => {
|
|
263
263
|
const kb = window.__sootsimKeyboard
|
|
264
264
|
const test = window.__sootsimTest
|
|
265
265
|
if (!kb) return { error: 'keyboard bridge not available' }
|
|
@@ -308,23 +308,23 @@ import{a as G}from"./chunk-4A5BPDNH.js";import{a as wt,b as xt}from"./chunk-FGMO
|
|
|
308
308
|
})()`}):e.send({type:"evaluate",code:`(async () => {
|
|
309
309
|
window.dispatchEvent(new CustomEvent(${JSON.stringify(c==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
|
|
310
310
|
return { ok: true, action: ${JSON.stringify(c)} }
|
|
311
|
-
})()`})}function qo(e){let c={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(c[e])return c[e];let n=e.match(/^Digit([0-9])$/);if(n)return n[1];let l=e.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function Ho(e){if(typeof e!="string")return null;let c=e.replace(/\s+/g," ").trim();return c?c.slice(0,80):null}function so(...e){for(let c of e){if(typeof c!="string")continue;let n=c.trim();if(n)return n}return null}function Uo(e){let c=e.indexOf("--node-id");if(c<0)return null;let n=e[c+1];if(!n)return null;let l=Number(n);return Number.isInteger(l)&&l>0?l:null}async function L(e,c,n){let l=$e({source:e,step:c,summary:n});l.active&&(l.replaced?console.error(` draft: replaced unkept action "${l.replaced.summary}" \u2014 \`flow keep\` commits one action at a time`):console.error(" draft: action pending \u2014 `sootsim flow keep` to commit"))}function eo(e,c,n){if(!n||n.hit===!1)return null;let l=so(n.responderTestID,n.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let m=Ho(n.text);return m?{step:{tapOn:m},summary:`tap "${m}"`}:{step:{tapAtCoords:{x:e,y:c}},summary:`tap @${Math.round(e)},${Math.round(c)}`}}function je(e,c,n){let l=so(c?.testID,c?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:n==="id"?{step:{tapOn:{id:e}},summary:`tap #${e}`}:{step:{tapOn:e},summary:`tap "${e}"`}}async function Rn(e,c){let n=e[0]==="get"||e[0]==="do"||e[0]==="debug"||e[0]==="wait"?e[0]:null,l=n?e.slice(1):e,m=He(l,{port:c.port,commandTimeoutMs:c.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--slow","--tail","-f","--interactive-targets","--actions","--internal","--compact","--no-xy","--no-clipped","--include-occluded"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--node-id","--max-ms","--filter","--limit","--level","--threshold","--equals","--since","--testid-like","--only","--subtree"]}),
|
|
312
|
-
`),process.exit(0))}if(M==="shell"){let
|
|
313
|
-
`),process.exit(0))}let t=Ne("inspect",o),s=["do","get","debug","wait"].map(
|
|
311
|
+
})()`})}function qo(e){let c={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(c[e])return c[e];let n=e.match(/^Digit([0-9])$/);if(n)return n[1];let l=e.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function Ho(e){if(typeof e!="string")return null;let c=e.replace(/\s+/g," ").trim();return c?c.slice(0,80):null}function so(...e){for(let c of e){if(typeof c!="string")continue;let n=c.trim();if(n)return n}return null}function Uo(e){let c=e.indexOf("--node-id");if(c<0)return null;let n=e[c+1];if(!n)return null;let l=Number(n);return Number.isInteger(l)&&l>0?l:null}async function L(e,c,n){let l=$e({source:e,step:c,summary:n});l.active&&(l.replaced?console.error(` draft: replaced unkept action "${l.replaced.summary}" \u2014 \`flow keep\` commits one action at a time`):console.error(" draft: action pending \u2014 `sootsim flow keep` to commit"))}function eo(e,c,n){if(!n||n.hit===!1)return null;let l=so(n.responderTestID,n.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let m=Ho(n.text);return m?{step:{tapOn:m},summary:`tap "${m}"`}:{step:{tapAtCoords:{x:e,y:c}},summary:`tap @${Math.round(e)},${Math.round(c)}`}}function je(e,c,n){let l=so(c?.testID,c?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:n==="id"?{step:{tapOn:{id:e}},summary:`tap #${e}`}:{step:{tapOn:e},summary:`tap "${e}"`}}async function Rn(e,c){let n=e[0]==="get"||e[0]==="do"||e[0]==="debug"||e[0]==="wait"?e[0]:null,l=n?e.slice(1):e,m=He(l,{port:c.port,commandTimeoutMs:c.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--slow","--tail","-f","--interactive-targets","--actions","--internal","--compact","--no-xy","--no-clipped","--include-occluded"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--node-id","--max-ms","--filter","--limit","--level","--threshold","--equals","--since","--testid-like","--only","--subtree"]}),r=m.positional,g=r[0],y=n==="get"||n==="do"||n==="debug"||n==="wait"?n:"inspect",T=typeof l[0]=="string"&&Je.has(l[0]),M=T?l[0]:null,h=o=>T&&o===l[0]?`sootsim ${o}`:`sootsim ${y} ${o}`,k=(o,t)=>` usage: ${h(o)}${t?` ${t}`:""}`;if(!g||e.includes("--help")||e.includes("-h")){let o={bridgePort:7668,defaultShellUrl:We};if(y==="do"||y==="get"||y==="debug"||y==="wait"){let i=Ie(y,o);i&&(console.log(`${i}
|
|
312
|
+
`),process.exit(0))}if(M==="shell"){let i=Ne("shell",o);i&&(console.log(`${i}
|
|
313
|
+
`),process.exit(0))}let t=Ne("inspect",o),s=["do","get","debug","wait"].map(i=>Ie(i,o)).filter(i=>i!=null).join(`
|
|
314
314
|
|
|
315
315
|
`);console.log(`${t??""}
|
|
316
316
|
|
|
317
317
|
${s}
|
|
318
|
-
`),process.exit(0)}let _=m.wsPort,I=m.simId,R=m.simIdSource,j=m.commandTimeoutMs;if(g==="list"&&l.some(o=>o==="--drivers"||o==="-D")){let{buildDriverListRows:o}=await import("./drivers-
|
|
319
|
-
`);let s=Math.max(...t.map(
|
|
318
|
+
`),process.exit(0)}let _=m.wsPort,I=m.simId,R=m.simIdSource,j=m.commandTimeoutMs;if(g==="list"&&l.some(o=>o==="--drivers"||o==="-D")){let{buildDriverListRows:o}=await import("./drivers-NVAOF3WK.js"),t=o();console.log(` available drivers (${t.length}):
|
|
319
|
+
`);let s=Math.max(...t.map(a=>a.id.length),6),i=Math.max(...t.map(a=>a.kind.length),4);for(let a of t){let u=a.available?"\u2713":"\u2717",p=a.id.padEnd(s),b=a.kind.padEnd(i);console.log(` ${u} ${p} ${b} ${a.description}`),a.available&&a.detail?console.log(` ${a.detail}`):!a.available&&a.reason&&console.log(` unavailable: ${a.reason}`)}return}let d=Ue(m),z=I||"default",B=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),D=200;function V(o){let t=o.replace(/\s+/g," ").trim();if(!t)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(t)){let i=/<title[^>]*>([^<]+)<\/title>/i.exec(o)?.[1]?.trim(),a=/<body[^>]*>([\s\S]*?)<\//i.exec(o)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=i||a||"html error page";return`<html ${o.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return t.length<=D?t:`${t.slice(0,D)}\u2026 (+${t.length-D} more bytes)`}function te(o){let t=o.displayUrl||o.url;return o.status!=null?`${o.method} ${t} -> ${o.status}${o.statusText?` ${o.statusText}`:""}`:o.error?`${o.method} ${t} -> ${o.error}`:`${o.method} ${t}`}async function S(o){let t=ue()?5e3:1500;try{let{settled:s,elapsed:i}=await ee({bridge:o,maxMs:t,pollMs:32,stablePolls:2});s||process.stderr.write(` \u26A0 auto-wait timed out after ${i??t}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
|
|
320
320
|
`)}catch{}}function N(o,t){console.error(` tap failed: ${o} stayed visible but did not receive a hittable press after ${t.attempts} attempt${t.attempts===1?"":"s"}`),t.result&&console.error(` last result: ${JSON.stringify(t.result)}`)}async function J(){try{return await d.send({type:"evaluate",code:`(() => ({
|
|
321
321
|
console: ${xe},
|
|
322
322
|
requests: window.__sootsimTest?.getRequestCounts?.() || null,
|
|
323
323
|
}))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function W(o={}){let t=o.counts!==void 0?o.counts:await Y(d,"getRequestCounts");if(!t||typeof t!="object")return;let s=Math.max(0,Number(t.failed)||0);if(s===0||!o.includeTail&&!Ee("requests",z,String(s))||(console.log(`
|
|
324
|
-
network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${h("requests")} 5`),!o.includeTail))return;let
|
|
324
|
+
network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${h("requests")} 5`),!o.includeTail))return;let i=await Y(d,"getFailedRequests",5);if(!(!Array.isArray(i)||i.length===0)){console.log(`
|
|
325
325
|
recent failed requests:
|
|
326
|
-
`);for(let
|
|
327
|
-
console: ${u.join(", ")}`),console.log(` inspect: ${h("errors")} 5`),
|
|
326
|
+
`);for(let a of i){let u=re(a.timestamp);console.log(` [${u}] ${te(a)}`),a.responseBody?console.log(` ${V(a.responseBody)}`):a.error&&console.log(` ${a.error}`)}}}async function X(o={}){let t=o.counts!==void 0?o.counts:await d.send({type:"evaluate",code:xe});if(!t||typeof t!="object")return;let s=t,i=Math.max(0,Number(s.errors)||0),a=Math.max(0,Number(s.warnings)||0);if(i===0&&a===0||!o.includeTail&&!Ee("console",z,`${i}:${a}`))return;let u=[];if(i>0&&u.push(`${i} console error${i===1?"":"s"}`),a>0&&u.push(`${a} console warning${a===1?"":"s"}`),console.log(`
|
|
327
|
+
console: ${u.join(", ")}`),console.log(` inspect: ${h("errors")} 5`),a>0&&console.log(` inspect: ${h("warnings")} 5`),!o.includeTail||i===0)return;let p=await we(d,5);if(!(!Array.isArray(p)||p.length===0)){console.log(`
|
|
328
328
|
recent console errors:
|
|
329
329
|
`);for(let b of p){let f=re(b.timestamp),x=Array.isArray(b.args)?b.args.map(O=>typeof O=="object"?JSON.stringify(O):String(O)).join(" "):String(b);console.log(` [${f}] ${x}`)}}}let Q=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function ne(o){let t=qe(),s=null;try{s=await ze(o,`(() => {
|
|
330
330
|
const tl = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.timeline
|
|
@@ -342,9 +342,9 @@ ${s}
|
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
344
|
return summary ? { summary, consoleSplit } : null
|
|
345
|
-
})()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let
|
|
346
|
-
since last: ${
|
|
347
|
-
`);for(let t of o){let s=[];if(s.push(`[${t.role}]`),t.label){let
|
|
345
|
+
})()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let i=s.summary.byKind??{},a=[],u=new Set;for(let p of Q){let b=i[p];if(b)if(u.add(p),p==="console"&&s.consoleSplit){let{error:f,warn:x}=s.consoleSplit;f>0&&a.push(`${f} error${f===1?"":"s"}`),x>0&&a.push(`${x} warning${x===1?"":"s"}`)}else a.push(`${b} ${p}${b===1?"":"s"}`)}for(let[p,b]of Object.entries(i))!u.has(p)&&b&&a.push(`${b} ${p}${b===1?"":"s"}`);if(a.length!==0&&(console.log(`
|
|
346
|
+
since last: ${a.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await Fe(o,"SootSim.bridges.timeline.cursorAdvance",t,s.summary.lastAt)}catch{}}let me=new Set(["tap","double-tap","tap-text","tap-id","type","type-into","key","key-sequence","keycode","drag","swipe","long-press","touch","gesture","pinch","scroll","shell"]),C=new Set(["a11y","capture","count","double-tap","drag","find","gesture","layout","long-press","node","pinch","sample-color","scroll","screenshot","swipe","tap","tap-id","tap-text","touch","tree","type-into"]),ae=(e.includes("--verbose")||e.includes("-v"))&&!e.includes("--json");y==="do"&&g==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),me.has(g)&&await Ke(d),C.has(g)&&await ce(d,{verbose:ae});try{switch(g){case"list":{await Et({bridge:d,simId:I,args:l});break}case"tree":{await Lt({bridge:d,args:l,positional:r});break}case"a11y":{let o=await ot(d);if(!Array.isArray(o)||o.length===0){console.log(" no accessible nodes found");break}if(e.includes("--json"))console.log(JSON.stringify(o,null,2));else{console.log(` accessibility tree (${o.length} nodes):
|
|
347
|
+
`);for(let t of o){let s=[];if(s.push(`[${t.role}]`),t.label){let i=t.label.length>50?t.label.slice(0,47)+"...":t.label;s.push(`"${i}"`)}if(t.hint&&s.push(`(hint: "${t.hint}")`),t.testID&&s.push(`#${t.testID}`),t.state){let i=[];t.state.disabled&&i.push("disabled"),t.state.selected&&i.push("selected"),t.state.checked===!0&&i.push("checked"),t.state.checked==="mixed"&&i.push("mixed"),t.state.busy&&i.push("busy"),t.state.expanded===!0&&i.push("expanded"),t.state.expanded===!1&&i.push("collapsed"),i.length&&s.push(`{${i.join(", ")}}`)}t.position&&s.push(`@(${t.position.x},${t.position.y})`),t.size&&s.push(`${t.size.w}x${t.size.h}`),console.log(" "+s.join(" "))}}break}case"find":{await At({bridge:d,args:e,effectiveArgs:l,positional:r,inspectUsage:k});break}case"count":{await _t(d,{args:l});break}case"keyboard":{await Rt(d,{json:e.includes("--json")});break}case"screens":{await Ct(d,{json:e.includes("--json")});break}case"memory":{await Dt(d,{args:l});break}case"wait":{await Wt({wsPort:_,commandTimeoutMs:j,simId:I,simIdSource:R,positional:r});break}case"sleep":{await jt({positional:r,inspectUsage:k});break}case"settle":{await Bt({bridge:d,args:e,positional:r});break}case"ready":{await Kt({bridge:d,args:e});break}case"idle":{await Ut({bridge:d,args:e,positional:r});break}case"selector":{await zt({bridge:d,args:e,positional:r,inspectUsage:k});break}case"event":{await Ht({bridge:d,args:e,positional:r,inspectUsage:k});break}case"layout":{let o=r[1];if(!o){await Pt({bridge:d,args:l});break}let t=await d.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(o)}))()`});console.log(JSON.stringify(t,null,2));break}case"capture":case"screenshot":{let t=e.find((b,f)=>e[f-1]==="--output")||"/tmp/sootsim-inspect.png",s=await Qt(e,d),i={type:"screenshot"};s&&(i.crop=s);let u=(await d.send(i)).replace(/^data:image\/png;base64,/,"");s&&console.log(` area: x=${s.x} y=${s.y} w=${s.w} h=${s.h}`),(await import("fs")).writeFileSync(t,Buffer.from(u,"base64")),console.log(` saved: ${t}`);break}case"sample-color":{let o=await Qt(e,d);o||(console.error(k("sample-color","<x> <y> [w] [h] | --id <testID> | --text <text>")),console.error(" samples an averaged color from the canvas. coords are logical sootsim units."),process.exit(1));let t=await d.send({type:"evaluate",code:xt(o)});if(e.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:i,b:a,a:u,hex:p,samples:b}=t,f=o.w===1&&o.h===1?`@(${o.x},${o.y})`:`@(${o.x},${o.y}) ${o.w}x${o.h}`;console.log(` ${p} rgba(${s}, ${i}, ${a}, ${u}) ${f} ${b} samples`)}break}case"node":{let o=r[1];o||(console.error(k("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let t=await d.send({type:"evaluate",code:`(async () => {
|
|
348
348
|
const t = window.__sootsimTest
|
|
349
349
|
const q = ${JSON.stringify(o)}
|
|
350
350
|
let node = null
|
|
@@ -400,17 +400,17 @@ ${s}
|
|
|
400
400
|
transform,
|
|
401
401
|
parentChain,
|
|
402
402
|
}
|
|
403
|
-
})()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let o=Number(
|
|
403
|
+
})()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let o=Number(r[1]),t=Number(r[2]),s=ye(e);if(s){let u=await ge(d,{agent:ue(),textFallback:s.mode==="text"?s.value:void 0,resolve:async()=>{let f=await ve(d,s);return f?{cx:f.x,cy:f.y,match:{id:s.mode==="testid"?s.value:f.id??null,testID:s.mode==="testid"?s.value:f.testID??null,text:s.mode==="text"?s.value:f.text??null,type:f.type??null},target:{id:f.id??null,testID:f.testID??null,text:f.text??null,type:f.type??null}}:null}}),p=u.payload;(!p||typeof p.cx!="number")&&(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),de(u.result)||(N(`${s.mode} "${s.value}"`,u),process.exit(1));let b=eo(p.cx,p.cy,u.result);b&&await L("inspect tap",b.step,b.summary),console.log(JSON.stringify({...u.attempts>1?{attempts:u.attempts}:{},...u.result},null,2));break}(!Number.isFinite(o)||!Number.isFinite(t))&&(console.error(k("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let i=await Mt(d,o,t),a=eo(o,t,i);a&&await L("inspect tap",a.step,a.summary),console.log(JSON.stringify(i,null,2));break}case"drag":case"swipe":{let o=Number(r[1]),t=Number(r[2]),s=Number(r[3]),i=Number(r[4]),a=g==="swipe"?10:12,u=g==="swipe"?8:16,p=r[5]?Number(r[5]):a,b=r[6]?Number(r[6]):u;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(i)||!Number.isFinite(p)||!Number.isFinite(b))&&(console.error(k(g,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await d.send({type:"evaluate",code:`(async () => {
|
|
404
404
|
const interact = window.__sootsimInteract
|
|
405
405
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
406
|
-
const value = await interact.drag(${o}, ${t}, ${s}, ${
|
|
406
|
+
const value = await interact.drag(${o}, ${t}, ${s}, ${i}, ${Math.max(1,Math.round(p))}, ${Math.max(0,Math.round(b))})
|
|
407
407
|
return { ok: !!value, value }
|
|
408
|
-
})()`});if(f?.ok){let x=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,b)));await L(`inspect ${g}`,{swipe:{start:`${o}, ${t}`,end:`${s}, ${
|
|
408
|
+
})()`});if(f?.ok){let x=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,b)));await L(`inspect ${g}`,{swipe:{start:`${o}, ${t}`,end:`${s}, ${i}`,duration:x}},`${g} ${o},${t} -> ${s},${i}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let o=Number(r[1]),t=Number(r[2]),s=Number(r[3]),i=Number(r[4]),a=Number(r[5]),u=Number(r[6]),p=Number(r[7]),b=Number(r[8]),f=r[9]?Number(r[9]):12,x=r[10]?Number(r[10]):16;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(i)||!Number.isFinite(a)||!Number.isFinite(u)||!Number.isFinite(p)||!Number.isFinite(b)||!Number.isFinite(f)||!Number.isFinite(x))&&(console.error(k("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let O=await d.send({type:"evaluate",code:`(async () => {
|
|
409
409
|
const interact = window.__sootsimInteract
|
|
410
410
|
if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
|
|
411
|
-
const value = await interact.pinch(${o}, ${t}, ${s}, ${
|
|
411
|
+
const value = await interact.pinch(${o}, ${t}, ${s}, ${i}, ${a}, ${u}, ${p}, ${b}, ${Math.max(1,Math.round(f))}, ${Math.max(0,Math.round(x))})
|
|
412
412
|
return { ok: !!value, value }
|
|
413
|
-
})()`});O?.ok&&await L("inspect pinch",{pinch:{from:[o,t,s,
|
|
413
|
+
})()`});O?.ok&&await L("inspect pinch",{pinch:{from:[o,t,s,i],to:[a,u,p,b],steps:Math.max(1,Math.round(f)),stepMs:Math.max(0,Math.round(x))}},`pinch (${o},${t}) (${s},${i}) -> (${a},${u}) (${p},${b})`),console.log(JSON.stringify(O,null,2));break}case"tap-text":{let o=r[1];o||(console.error(k("tap-text","<text>")),process.exit(1));let t=K=>{let E=e.indexOf(K);return E>=0&&E+1<e.length?e[E+1]:null},s=K=>e.includes(K),i=t("--nth")??t("--index"),a=i!==null?Number(i):null;a!==null&&!Number.isFinite(a)&&(console.error(` --nth/--index requires an integer, got: ${i}`),process.exit(1));let u=t("--within"),p=t("--role"),b=s("--exact"),f=s("--first"),x=t("--min-y"),O=t("--max-y"),q=t("--min-x"),H=t("--max-x");for(let[K,E]of[["--min-y",x],["--max-y",O],["--min-x",q],["--max-x",H]])E!==null&&!Number.isFinite(Number(E))&&(console.error(` ${K} requires a number, got: ${E}`),process.exit(1));let U=e.indexOf("--near"),F=null;if(U>=0){let K=Number(e[U+1]),E=Number(e[U+2]);(!Number.isFinite(K)||!Number.isFinite(E))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),F={x:K,y:E}}let w={exact:b,role:p,within:u,minX:q!==null?Number(q):null,maxX:H!==null?Number(H):null,minY:x!==null?Number(x):null,maxY:O!==null?Number(O):null,near:F,nth:a,first:f},$=await Nt(d,o,w,{agent:ue()}),v=$.payload;if(v?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),v?.ambiguous){let K=v.candidates;console.error(` ambiguous: ${v.total} matches for "${o}"`);for(let E of K){let he=E.abs?`@(${Math.round(E.abs.x)},${Math.round(E.abs.y)})`:"",no=E.layout?` ${E.layout.width}x${E.layout.height}`:"",ro=E.testID?` #${E.testID}`:"",io=E.text?` "${E.text}"`:"",ao=E.ancestorTestIDs.length>0?` within ${E.ancestorTestIDs.slice(0,3).map(lo=>`#${lo}`).join(" > ")}`:"";console.error(` [${E.idx}] <${E.type}>${io}${ro} ${he}${no}${ao}`)}v.total>K.length&&console.error(` ... and ${v.total-K.length} more`),console.error(" pick one:"),console.error(" --nth <index> pick the nth match (top-to-bottom, left-to-right; negatives from end)"),console.error(" --within <testID> narrow to descendants of a node"),console.error(" --min-y / --max-y geometric filter (pixels, absolute)"),console.error(" --min-x / --max-x geometric filter (pixels, absolute)"),console.error(" --near <x> <y> pick the closest match to a point"),console.error(" --exact exact text match (default is substring)"),console.error(" --role <role> narrow to accessibilityRole"),console.error(" --first keep the old pick-first-silently behavior"),process.exit(2)}v?.nthOutOfRange&&(console.error(` not found: nth ${v.nth} of ${v.total} match${v.total===1?"":"es"} for "${o}"`),process.exit(1)),(!v||typeof v.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),de($.result)||(N(`text "${o}"`,$),process.exit(1));let oe=je(o,{id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},"text");await L("inspect tap-text",oe.step,oe.summary),console.log(JSON.stringify({matched:v.match,tapped:{nodeId:v.target?.nodeId??null,id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},...v.strategy&&v.strategy!=="matched-node"?{strategy:v.strategy}:{},...v.total>1||a!==null?{nth:{index:v.idx,total:v.total}}:{},...$.attempts>1?{attempts:$.attempts}:{},result:$.result},null,2));break}case"tap-best":{let o=r[1];o||(console.error(k("tap-best","<query>")),process.exit(1));let t=await Ft(d,o,{agent:ue()}),s=t.payload;s||(console.error(` tap-best: no testID or visible text matched "${o}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1)),"error"in s&&(console.error(` ${s.error}`),process.exit(1)),s.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${o}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1));let i=s.node;de(t.result)||(N(`best "${o}"`,t),process.exit(1));let a=je(o,{id:i.id,testID:i.testID,type:i.type,cx:s.cx,cy:s.cy},s.strategy==="testid"?"id":"text");await L("inspect tap-best",a.step,a.summary),console.log(JSON.stringify({matched:{strategy:s.strategy,nodeId:i.nodeId,id:i.id,testID:i.testID,type:i.type,text:i.text},tapped:{cx:s.cx,cy:s.cy},...t.attempts>1?{attempts:t.attempts}:{},result:t.result},null,2));break}case"tap-id":{let o=r[1];o||(console.error(k("tap-id","<id>")),process.exit(1));let t=await It(d,o,{agent:ue()}),s=t.payload;(!s||typeof s.cx!="number")&&(console.error(` not found: ${o}`),await Po(d,o),process.exit(1)),de(t.result)||(N(`id "${o}"`,t),process.exit(1));let i=je(o,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await L("inspect tap-id",i.step,i.summary),console.log(JSON.stringify({matched:s.match,tapped:{nodeId:s.target?.nodeId??null,id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},...s.strategy&&s.strategy!=="matched-node"?{strategy:s.strategy}:{},...t.attempts>1?{attempts:t.attempts}:{},result:t.result},null,2));break}case"type-into":{let o=r[1],t=r.slice(2).join(" ");(!o||!t)&&(console.error(k("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(o),i=await d.send({type:"evaluate",code:`(async () => {
|
|
414
414
|
const t = window.__sootsimTest
|
|
415
415
|
if (!t) return null
|
|
416
416
|
const n = await (t.findByTestId(${s}) || t.findById(${s}))
|
|
@@ -424,36 +424,36 @@ ${s}
|
|
|
424
424
|
isTextInput: !!n.isTextInput,
|
|
425
425
|
placeholder: n.placeholder || null,
|
|
426
426
|
}
|
|
427
|
-
})()`});(!
|
|
427
|
+
})()`});(!i||typeof i.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),i.isTextInput||console.error(` warning: ${o} is not a text input (isTextInput: false)`);let a=await d.send({type:"tap",x:i.cx,y:i.cy,target:{id:i.id??o,testID:i.testID??o,text:null,type:i.type??null}}),u=await Wo(d);u.visible||(console.error(` keyboard did not open after tapping ${o}`),process.exit(1));let p=u.focusedInput;p&&(p.testID===o||p.id===o||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(o)} but focus is on ${JSON.stringify(p.testID??p.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await d.send({type:"keyboard",action:"type",text:t}),await L("inspect type-into",{tapOn:{id:o},inputText:t},`type-into #${o} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:o,isTextInput:i.isTextInput,keyboardOpened:u.visible??a?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:t},null,2));break}case"type":{let o=r.slice(1).join(" ");o||(console.error(k("type","<text>")),process.exit(1)),await Me(d,"type"),await d.send({type:"keyboard",action:"type",text:o}),await L("inspect type",{inputText:o},`type ${JSON.stringify(o)}`),console.log(` typed: ${JSON.stringify(o)}`);break}case"key":{let o=r[1];o||(console.error(k("key","<name>")),process.exit(1)),await Me(d,"key"),await d.send({type:"keyboard",action:"press",text:o}),await L("inspect key",{pressKey:o},`key ${o}`),console.log(` pressed: ${o}`);break}case"key-sequence":{let o=r.slice(1);o.length===0&&(console.error(k("key-sequence","<key> [<key> ...]")),process.exit(1)),await Me(d,"key-sequence");for(let t of o)await d.send({type:"keyboard",action:"press",text:t});await L("inspect key-sequence",{pressKey:o.join(" ")},`key-sequence ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"keycode":{let o=r.slice(1);o.length===0&&(console.error(k("keycode","<code> [<code> ...]")),process.exit(1));let t=o.map(i=>({code:i,key:qo(i)})),s=t.filter(i=>!i.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(i=>i.code).join(", ")}`),process.exit(1)),await Me(d,"keycode");for(let i of t)await d.send({type:"keyboard",action:"press",text:i.key});await L("inspect keycode",{pressKey:t.map(i=>i.key).join(" ")},`keycode ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"dispatch":{let o=r[1];o||(console.error(k("dispatch","<char>")),process.exit(1)),await d.send({type:"keyboard",action:"dispatchKey",text:o}),await L("inspect dispatch",{dispatchKey:o},`dispatch ${JSON.stringify(o)}`),console.log(` dispatched: ${o}`);break}case"dismiss":{await d.send({type:"keyboard",action:"dismiss"}),await L("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let o=Number(r[1]),t=Number(r[2]),s=ye(e);if(s){let p=await ve(d,s);p||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),o=p.x,t=p.y}let i=r[3]?Number(r[3]):80;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(i))&&(console.error(k("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let a=Math.max(0,Math.round(i)),u=await d.send({type:"evaluate",code:`(async () => {
|
|
428
428
|
const interact = window.__sootsimInteract
|
|
429
429
|
if (interact?.doubleTap) {
|
|
430
430
|
return {
|
|
431
|
-
ok: !!(await interact.doubleTap(${o}, ${t}, ${
|
|
432
|
-
gapMs: ${
|
|
431
|
+
ok: !!(await interact.doubleTap(${o}, ${t}, ${a})),
|
|
432
|
+
gapMs: ${a},
|
|
433
433
|
}
|
|
434
434
|
}
|
|
435
435
|
if (!interact?.tap) {
|
|
436
|
-
return { ok: false, reason: 'no interact.tap', gapMs: ${
|
|
436
|
+
return { ok: false, reason: 'no interact.tap', gapMs: ${a} }
|
|
437
437
|
}
|
|
438
438
|
const first = await interact.tap(${o}, ${t})
|
|
439
439
|
if (!first || first.hit === false) {
|
|
440
|
-
return { ok: false, reason: 'first tap missed', gapMs: ${
|
|
440
|
+
return { ok: false, reason: 'first tap missed', gapMs: ${a}, first }
|
|
441
441
|
}
|
|
442
|
-
await new Promise((resolve) => setTimeout(resolve, ${
|
|
442
|
+
await new Promise((resolve) => setTimeout(resolve, ${a}))
|
|
443
443
|
const second = await interact.tap(${o}, ${t})
|
|
444
444
|
return {
|
|
445
445
|
ok: !!second && second.hit !== false,
|
|
446
|
-
gapMs: ${
|
|
446
|
+
gapMs: ${a},
|
|
447
447
|
first,
|
|
448
448
|
second,
|
|
449
449
|
}
|
|
450
|
-
})()`});u?.ok&&await L("inspect double-tap",{doubleTapAtCoords:{x:o,y:t,gapMs:
|
|
450
|
+
})()`});u?.ok&&await L("inspect double-tap",{doubleTapAtCoords:{x:o,y:t,gapMs:a}},`double-tap @${o},${t}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let o=Number(r[1]),t=Number(r[2]),s=ye(e),i=null;if(s){let f=await ve(d,s);f||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),o=f.x,t=f.y,i={id:f.id??null,testID:f.testID??null,text:f.text??null,type:f.type??null}}let a=s?r[1]:r[3],u=a?Number(a):600;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(u))&&(console.error(k("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let p=Math.max(0,Math.round(u)),b=await d.send({type:"longPress",x:o,y:t,durationMs:p,target:i});b?.ok&&await L("inspect long-press",{tapAtCoords:{x:o,y:t}},`long-press @${o},${t}`),console.log(JSON.stringify(b,null,2));break}case"touch":{let o=r[1],t=Number(r[2]),s=Number(r[3]),i=r[4]?Number(r[4]):999,a=o==="down"?"touchDown":o==="move"?"touchMove":o==="up"?"touchUp":o==="cancel"?"touchCancel":null;a||(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),o!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(s))&&(console.error(k("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let u=o==="down"?"tap":o==="move"?"move":null,p=u&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${t}, y: ${s} } }));`:"",b=await d.send({type:"evaluate",code:`(async () => {
|
|
451
451
|
${p}
|
|
452
452
|
const interact = window.__sootsimInteract
|
|
453
|
-
if (!interact?.${
|
|
454
|
-
const value = ${o==="cancel"?`await interact.${
|
|
453
|
+
if (!interact?.${a}) return { ok: false, reason: 'no interact.${a}' }
|
|
454
|
+
const value = ${o==="cancel"?`await interact.${a}(${Math.max(1,Math.round(i))})`:`await interact.${a}(${t}, ${s}, ${Math.max(1,Math.round(i))})`}
|
|
455
455
|
return { ok: !!value, value }
|
|
456
|
-
})()`});b?.ok&&o!=="cancel"&&await L("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${o} @${t},${s}`),console.log(JSON.stringify(b,null,2));break}case"gesture":{let o=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],t=
|
|
456
|
+
})()`});b?.ok&&o!=="cancel"&&await L("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${o} @${t},${s}`),console.log(JSON.stringify(b,null,2));break}case"gesture":{let o=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],t=r[1],s=r[2]?Number(r[2]):220;(!t||!Number.isFinite(s))&&(console.error(k("gesture","<preset> [durationMs]")),console.error(` presets: ${o.join(", ")}`),process.exit(1)),o.includes(t)||(console.error(` unknown gesture preset: ${t}`),console.error(` presets: ${o.join(", ")}`),process.exit(1));let i=await d.send({type:"evaluate",code:`(async () => {
|
|
457
457
|
const spec = globalThis.__sootsimDeviceSpec || {}
|
|
458
458
|
return {
|
|
459
459
|
width: spec.width || window.innerWidth || 393,
|
|
@@ -461,12 +461,12 @@ ${s}
|
|
|
461
461
|
statusBarHeight: spec.statusBarHeight || 0,
|
|
462
462
|
homeIndicatorHeight: spec.homeIndicatorHeight || 0,
|
|
463
463
|
}
|
|
464
|
-
})()`}),
|
|
464
|
+
})()`}),a=Number(i?.width)||393,u=Number(i?.height)||852,p=Number(i?.statusBarHeight)||0,b=Number(i?.homeIndicatorHeight)||0,f=Math.round(a/2),x=Math.round(u/2),O=Math.max(24,p+18),q=Math.max(24,b+18),H=18,U=Math.min(220,Math.round(u*.24)),F=Math.min(180,Math.round(a*.32)),w=f,$=x,v=f,oe=x;switch(t){case"scroll-up":$=x+Math.round(U/2),oe=x-Math.round(U/2);break;case"scroll-down":$=x-Math.round(U/2),oe=x+Math.round(U/2);break;case"scroll-left":w=f+Math.round(F/2),v=f-Math.round(F/2);break;case"scroll-right":w=f-Math.round(F/2),v=f+Math.round(F/2);break;case"swipe-from-left-edge":w=H,$=x,v=Math.min(a-H,H+F);break;case"swipe-from-right-edge":w=a-H,$=x,v=Math.max(H,a-H-F);break;case"swipe-from-top-edge":w=f,$=O,oe=Math.min(u-q,O+U);break;case"swipe-from-bottom-edge":w=f,$=u-q,oe=Math.max(O,u-q-U);break}let K=Math.max(8,Math.round(s/16)),E=Math.max(1,Math.round(s/K)),he=await d.send({type:"evaluate",code:`(async () => {
|
|
465
465
|
const interact = window.__sootsimInteract
|
|
466
466
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
467
467
|
const value = await interact.drag(${w}, ${$}, ${v}, ${oe}, ${K}, ${E})
|
|
468
468
|
return { ok: !!value, value }
|
|
469
|
-
})()`});he?.ok&&await L("inspect gesture",{swipe:{start:`${w}, ${$}`,end:`${v}, ${oe}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:w,y:$},to:{x:v,y:oe},result:he},null,2));break}case"scroll":{let o=ye(e),t=Uo(e),s=o?.mode==="testid"?o.value:t==null?
|
|
469
|
+
})()`});he?.ok&&await L("inspect gesture",{swipe:{start:`${w}, ${$}`,end:`${v}, ${oe}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:w,y:$},to:{x:v,y:oe},result:he},null,2));break}case"scroll":{let o=ye(e),t=Uo(e),s=o?.mode==="testid"?o.value:t==null?r[1]:null,i=o||t!=null?1:2,a=Number(r[i]),u=Number(r[i+1]);(!s&&t==null||!Number.isFinite(a)||!Number.isFinite(u))&&(console.error(k("scroll","<id> <x> <y> | --testid <id> <x> <y> | --node-id <nodeId> <x> <y>")),process.exit(1));let p=await d.send({type:"evaluate",code:`(async () => {
|
|
470
470
|
const t = window.__sootsimTest
|
|
471
471
|
if (!t) return null
|
|
472
472
|
const n = ${t!=null?`await t.inspectByNodeId(${JSON.stringify(t)})`:`await t.findByTestId(${JSON.stringify(s)})
|
|
@@ -476,7 +476,7 @@ ${s}
|
|
|
476
476
|
cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
|
|
477
477
|
cy: n.absolutePosition.y + (n.layout.height || 0) / 2,
|
|
478
478
|
}
|
|
479
|
-
})()`}),b=await Y(d,"scrollTo",t!=null?{nodeId:t}:s,
|
|
479
|
+
})()`}),b=await Y(d,"scrollTo",t!=null?{nodeId:t}:s,a,u,!1);if(b?.ok){let f=t!=null?`node ${t}`:`#${s}`;await L("inspect scroll",{scrollTo:{...t!=null?{nodeId:t}:{id:s},x:a,y:u}},`scroll ${f} -> ${a},${u}`)}console.log(JSON.stringify({...b,...p?{at:{x:p.cx,y:p.cy}}:{}},null,2));break}case"state":{let o=r[1];if(n==="get"&&!o){let s=await Y(d,"getRuntimeState"),i=await d.send({type:"evaluate",code:xe});if(s&&typeof s=="object"&&s.diagnostics&&(s.diagnostics.errors=i?.errors??0,s.diagnostics.warnings=i?.warnings??0),s&&typeof s=="object"&&s.shell==null)try{let a=await le(d);a&&(s.shell=a)}catch{}console.log(JSON.stringify(s,null,2));break}if(!o||o==="--help"||o==="-h"){console.log(`
|
|
480
480
|
${h("state")} \u2014 dump raw runtime state
|
|
481
481
|
|
|
482
482
|
subcommands:
|
|
@@ -530,7 +530,7 @@ ${s}
|
|
|
530
530
|
text: focused.text || null,
|
|
531
531
|
} : null,
|
|
532
532
|
}
|
|
533
|
-
})()`});break;case"node":{let s=
|
|
533
|
+
})()`});break;case"node":{let s=r[2];s||(console.error(` usage: ${h("state")} node <id>`),process.exit(1)),t=await Y(d,"findByTestId",s)||await Y(d,"findById",s);break}case"scroll":{let s=r[2];s||(console.error(` usage: ${h("state")} scroll <id>`),process.exit(1)),t=await Y(d,"getScrollState",s);break}case"scroll-hit":{let s=Number(r[2]),i=Number(r[3]);(!Number.isFinite(s)||!Number.isFinite(i))&&(console.error(` usage: ${h("state")} scroll-hit <x> <y>`),process.exit(1)),t=await Y(d,"getScrollStateAt",s,i);break}case"hit":{let s=Number(r[2]),i=Number(r[3]);(!Number.isFinite(s)||!Number.isFinite(i))&&(console.error(` usage: ${h("state")} hit <x> <y>`),process.exit(1)),t=await Y(d,"debugHitAt",s,i);break}case"gesture":{let s=Number(r[2]),i=Number(r[3]);(!Number.isFinite(s)||!Number.isFinite(i))&&(console.error(` usage: ${h("state")} gesture <x> <y>`),process.exit(1)),t=await Y(d,"debugGestureAt",s,i);break}default:console.error(` unknown state subcommand: ${o}`),process.exit(1)}console.log(JSON.stringify(t,null,2));break}case"shell":{let o=r[1];if(!o||o==="--help"||o==="-h"){console.log(`
|
|
534
534
|
${h("shell")} \u2014 run built-in shell commands
|
|
535
535
|
|
|
536
536
|
subcommands:
|
|
@@ -554,7 +554,7 @@ ${s}
|
|
|
554
554
|
${h("shell")} open-card clock 800
|
|
555
555
|
${h("shell")} appearance dark
|
|
556
556
|
${h("shell")} lock
|
|
557
|
-
`);break}let t=o==="launch"||o==="open-card"||o==="home"||o==="switcher",s=o==="launch"||o==="open-card"?
|
|
557
|
+
`);break}let t=o==="launch"||o==="open-card"||o==="home"||o==="switcher",s=o==="launch"||o==="open-card"?r[3]:r[2],i=s?Number(s):350;t&&(!Number.isFinite(i)||i<0)&&(console.error(k("shell",o==="launch"||o==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let a=!1,u=!1,p=null,b=e.includes("--clear-state");if(o==="launch"){let f=r[2];f||(console.error(k("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),b&&await d.send({type:"evaluate",code:Ye}),a=!!await pe(d,"launchApp",i,f),{settled:u,state:p}=await Te(d,Math.round(i),x=>!!x&&x.state==="app"&&x.activeApp===f&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.launchProgress=="number"&&x.launchProgress>=.98),a&&await L("inspect shell launch",b?{launchApp:{clearState:!0}}:{launchApp:{}},b?"launch app (clear state)":"launch app")}else if(o==="home")a=!!await pe(d,"goHome",i),{settled:u,state:p}=await Te(d,Math.round(i),f=>!!f&&f.state==="home"&&f.activeApp==null&&f.showSwitcher===!1&&f.switcherPhase==="idle"&&typeof f.launchProgress=="number"&&f.launchProgress>=.98);else if(o==="switcher")a=!!await pe(d,"openSwitcher",i),{settled:u,state:p}=await Te(d,Math.round(i),f=>!!f&&f.state==="app"&&f.showSwitcher===!0&&f.switcherPhase==="idle"&&typeof f.zoomLevel=="number"&&Math.abs(f.zoomLevel)<=.02&&typeof f.horizontalZoom=="number"&&Math.abs(f.horizontalZoom)<=.02),u&&(await Z(Jo),p=await le(d));else if(o==="open-card"){let f=r[2];f||(console.error(k("shell","open-card <appId> [settleMs]")),process.exit(1)),a=!!await pe(d,"openSwitcherCard",i,f),{settled:u,state:p}=await Te(d,Math.round(i),x=>!!x&&x.state==="app"&&x.activeApp===f&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.zoomLevel=="number"&&x.zoomLevel>=.98&&typeof x.horizontalZoom=="number"&&x.horizontalZoom>=.98),a&&await L("inspect shell open-card",{openSwitcherCard:{appId:f}},`open switcher card ${f}`)}else if(o==="appearance"){let f=r[2];(!f||!["light","dark","auto","toggle"].includes(f))&&(console.error(k("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let x=await Zt(d,"appearance",f);if(a=!!x?.ok,p={appearance:x},a){let O=x?.applied??f;console.log(` appearance: ${O}`)}}else if(o==="lock"||o==="shake"){let f=await Zt(d,o);a=!!f?.ok,p={[o]:f}}else console.error(` unknown shell subcommand: ${o}`),process.exit(1);console.log(JSON.stringify({ok:a,settled:u,state:p},null,2));break}case"url":{await Jt(d,{args:l});break}case"reload":{let s=!1,i=!1;try{await d.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let p=await d.send({type:"evaluate",code:`;(() => {
|
|
558
558
|
const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
|
|
559
559
|
if (typeof reloadExternalApp === 'function') {
|
|
560
560
|
reloadExternalApp()
|
|
@@ -562,10 +562,10 @@ ${s}
|
|
|
562
562
|
}
|
|
563
563
|
window.location.reload()
|
|
564
564
|
return { kind: 'page' }
|
|
565
|
-
})()`});
|
|
565
|
+
})()`});i=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let a=d,u=null;if(i)u=await Re(d,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await Z(300);let p=await ht(_,j,I,{timeoutMs:1e4,simIdSource:R});p?(a=p,u=await Re(p,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),a=null)}if(u)if(u.ready){let p=u.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${u.elapsedMs}ms: ${u.nodes} nodes${p}`)}else if(u.source==="error-bail")console.log(` \u26A0 reload bailed after ${u.elapsedMs}ms: ${u.errors} console error(s), ready signal never fired`);else{let p=Co(u);console.log(` \u26A0 reload timed out after ${u.elapsedMs}ms \u2014 ${p} (nodes: ${u.nodes}, targets: ${u.targets}, errors: ${u.errors})`)}if(a)try{let p=await we(a,10);if(a!==d&&a.close(),Array.isArray(p)&&p.length>0){console.log(`
|
|
566
566
|
\u26A0 ${p.length} error(s) during mount:
|
|
567
567
|
`);for(let b of p){let f=b.args.map(x=>typeof x=="object"?JSON.stringify(x):x).join(" ");if(console.log(` ${f}`),b.stack){let x=b.stack.split(`
|
|
568
|
-
`).slice(0,2);for(let O of x)console.log(` ${O.trim()}`)}}}}catch{}u&&!u.ready&&(process.exitCode=1);break}case"eval":case"js":{let o=
|
|
568
|
+
`).slice(0,2);for(let O of x)console.log(` ${O.trim()}`)}}}}catch{}u&&!u.ready&&(process.exitCode=1);break}case"eval":case"js":{let o=r.slice(1).join(" ");o||(console.error(k("js","<javascript>")),console.error(""),console.error(" runs the snippet in the engine realm. SootSim is the"),console.error(" canonical state surface \u2014 reach into it directly."),console.error(""),console.error(" examples:"),console.error(` ${h("js")} SootSim.bridges.test.findByText("Sign in")`),console.error(` ${h("js")} SootSim.bridges.debug.snapshot("before")`),console.error(` ${h("js")} SootSim.bridges.keyboard.type("hello")`),console.error(` ${h("js")} SootSim.state.root.children.length`),process.exit(1));let t=o;t.startsWith("(async")||(t=`(async () => ${t})()`);let s=await d.send({type:"evaluate",code:t});console.log(JSON.stringify(s,null,2));let i=o.toLowerCase(),a=[];(i.includes("sootsim:gohome")||i.includes("gohome"))&&a.push("sootsim shell home"),(i.includes("sootsim:appswitcher")||i.includes("appswitcher"))&&a.push("sootsim shell switcher"),(i.includes("keyboard.isvisible")||i.includes("keyboard.getmode"))&&a.push("sootsim debug state keyboard"),i.includes("interact.tap")&&a.push("sootsim do tap <x> <y>"),i.includes("keyboard.type")&&a.push("sootsim do type <text>"),(i.includes("keyboard.press")||i.includes("keyboard.dispatchkey"))&&a.push("sootsim do key <name>"),i.includes("keyboard.dismiss")&&a.push("sootsim do dismiss"),i.includes("dumptree")&&a.push("sootsim get tree"),i.includes("dumpaccessibilitytree")&&a.push("sootsim get a11y"),i.includes("getnodecount")&&a.push("sootsim get count"),i.includes("findbytext")&&a.push("sootsim find <text>"),(i.includes("findbytestid")||i.includes("findbyid"))&&a.push("sootsim find --testid <id>"),i.includes("document.hidden")&&a.push("sootsim debug state keyboard (includes tab health)"),a.length>0&&G("prefer-cli-over-eval",a);break}case"globals":{let o=await d.send({type:"evaluate",code:`(async () => {
|
|
569
569
|
const globals = {}
|
|
570
570
|
|
|
571
571
|
// test bridge (proxy in worker mode)
|
|
@@ -603,7 +603,7 @@ ${s}
|
|
|
603
603
|
|
|
604
604
|
return globals
|
|
605
605
|
})()`});console.log(` sootsim JS API:
|
|
606
|
-
`);for(let[t,s]of Object.entries(o)){console.log(` ${t}:`);for(let
|
|
606
|
+
`);for(let[t,s]of Object.entries(o)){console.log(` ${t}:`);for(let i of s)console.log(` .${i}`);console.log("")}console.log(` use: ${h("js")} <expression>`),console.log(` example: ${h("js")} test.findByText("Sign in")`);break}case"describe":{await Ot({bridge:d,args:e,positional:r});break}case"perf":{let o=r[1];if(!o||o==="--help"||o==="-h"){console.log(`
|
|
607
607
|
${h("perf")} \u2014 performance profiling
|
|
608
608
|
|
|
609
609
|
subcommands:
|
|
@@ -649,7 +649,7 @@ ${s}
|
|
|
649
649
|
jankFrames: frameStats.recentFrames?.filter(f => f > 16.67).length || 0,
|
|
650
650
|
recentCount: frameStats.recentFrames?.length || 0,
|
|
651
651
|
}
|
|
652
|
-
})()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),A(l)){P(t);break}let s=t.avgMs==="?"&&t.maxMs==="?",
|
|
652
|
+
})()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),A(l)){P(t);break}let s=t.avgMs==="?"&&t.maxMs==="?",i=t.avgMs!=="?"?(1e3/parseFloat(t.avgMs)).toFixed(1):"?";console.log(" perf stats:"),console.log(` frames: ${t.frames}`),console.log(` avg: ${t.avgMs}ms (${i} fps)`),console.log(` max: ${t.maxMs}ms`),console.log(` layout: ${t.layoutMs}ms total`),console.log(` nodes: ${t.nodeCount}`),t.recentCount>0&&console.log(` jank: ${t.jankFrames}/${t.recentCount} frames >16.67ms`),s&&process.stderr.write(`
|
|
653
653
|
\u26A0 frame timings are zero \u2014 enable them first:
|
|
654
654
|
sootsim debug perf start # begin recording
|
|
655
655
|
# \u2026 interact / run a flow / wait for the transition \u2026
|
|
@@ -771,8 +771,8 @@ ${s}
|
|
|
771
771
|
jankFrames: recent.filter(f => f > 16.67).length,
|
|
772
772
|
sampleCount: recent.length,
|
|
773
773
|
}
|
|
774
|
-
})()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),A(l)){P(t);break}let s=t.avgMs>0?(1e3/t.avgMs).toFixed(1):"?",
|
|
775
|
-
`),console.log(` frames: ${t.frames}`),console.log(` total: ${t.totalMs.toFixed(1)}ms`),console.log(` avg: ${t.avgMs.toFixed(2)}ms (${s} fps)`),console.log(` max: ${t.maxMs.toFixed(2)}ms`),console.log(""),t.layoutAvgMs!==void 0&&(console.log(" breakdown (avg per frame):"),console.log(` layout: ${t.layoutAvgMs.toFixed(2)}ms`),console.log(` render: ${t.renderAvgMs.toFixed(2)}ms`),console.log(` copy: ${t.copyAvgMs.toFixed(2)}ms`),t.auxAvgMs!==void 0&&console.log(` aux: ${t.auxAvgMs.toFixed(2)}ms`),t.otherAvgMs!==void 0&&console.log(` other: ${t.otherAvgMs.toFixed(2)}ms`),console.log("")),console.log(` distribution (${t.sampleCount} samples):`),console.log(` p50: ${t.p50.toFixed(2)}ms`),console.log(` p95: ${t.p95.toFixed(2)}ms`),console.log(` p99: ${t.p99.toFixed(2)}ms`),console.log(` jank: ${t.jankFrames} frames (${
|
|
774
|
+
})()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),A(l)){P(t);break}let s=t.avgMs>0?(1e3/t.avgMs).toFixed(1):"?",i=t.sampleCount>0?(t.jankFrames/t.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
|
|
775
|
+
`),console.log(` frames: ${t.frames}`),console.log(` total: ${t.totalMs.toFixed(1)}ms`),console.log(` avg: ${t.avgMs.toFixed(2)}ms (${s} fps)`),console.log(` max: ${t.maxMs.toFixed(2)}ms`),console.log(""),t.layoutAvgMs!==void 0&&(console.log(" breakdown (avg per frame):"),console.log(` layout: ${t.layoutAvgMs.toFixed(2)}ms`),console.log(` render: ${t.renderAvgMs.toFixed(2)}ms`),console.log(` copy: ${t.copyAvgMs.toFixed(2)}ms`),t.auxAvgMs!==void 0&&console.log(` aux: ${t.auxAvgMs.toFixed(2)}ms`),t.otherAvgMs!==void 0&&console.log(` other: ${t.otherAvgMs.toFixed(2)}ms`),console.log("")),console.log(` distribution (${t.sampleCount} samples):`),console.log(` p50: ${t.p50.toFixed(2)}ms`),console.log(` p95: ${t.p95.toFixed(2)}ms`),console.log(` p99: ${t.p99.toFixed(2)}ms`),console.log(` jank: ${t.jankFrames} frames (${i}%) >16.67ms`);break}case"frames":{let t=r[2]?Number(r[2]):50;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${r[2]}"`),process.exit(1));let s=await d.send({type:"evaluate",code:`(async () => {
|
|
776
776
|
if (window.__sootsimRenderHost) {
|
|
777
777
|
const session = window.${se} || {}
|
|
778
778
|
if (session.active) {
|
|
@@ -807,7 +807,7 @@ ${s}
|
|
|
807
807
|
mode: 'main-thread',
|
|
808
808
|
frames: (stats.recentFrames || []).slice(-${t}),
|
|
809
809
|
}
|
|
810
|
-
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),A(l)){P(s);break}if(s.mode==="render-worker"){let
|
|
810
|
+
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),A(l)){P(s);break}if(s.mode==="render-worker"){let a=Array.isArray(s.samples)?s.samples:[];if(a.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${a.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,p,b,f,x,O,q]of a)console.log(` ${p.toFixed(2).padStart(7)} ${b.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);console.log(""),Be(a.map(u=>u[1])),s.live&&console.log(" sampling continues");break}let i=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(i.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${i.length} frame times (ms):`),console.log(` ${i.map(a=>a.toFixed(2)).join(", ")}`),Be(i);break}case"worst":{let t=r[2]?Number(r[2]):20;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${r[2]}"`),process.exit(1));let s=await d.send({type:"evaluate",code:`(async () => {
|
|
811
811
|
if (window.__sootsimRenderHost) {
|
|
812
812
|
const session = window.${se} || {}
|
|
813
813
|
if (session.active) {
|
|
@@ -849,7 +849,7 @@ ${s}
|
|
|
849
849
|
mode: 'main-thread',
|
|
850
850
|
frames: recent.slice().sort((a, b) => b - a).slice(0, ${t}),
|
|
851
851
|
}
|
|
852
|
-
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),A(l)){P(s);break}if(s.mode==="render-worker"){let
|
|
852
|
+
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),A(l)){P(s);break}if(s.mode==="render-worker"){let a=Array.isArray(s.samples)?s.samples:[];if(a.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${a.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,p,b,f,x,O,q]of a)console.log(` ${p.toFixed(2).padStart(7)} ${b.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${q.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);s.live&&(console.log(""),console.log(" sampling continues"));break}let i=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(i.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${i.length} frame times (ms):`),console.log(` ${i.map(a=>a.toFixed(2)).join(", ")}`);break}case"transition":{let t=r[2];if(!t||!["goHome","appSwitcher","lockScreen"].includes(t)){console.log(`
|
|
853
853
|
${h("perf")} transition <event> \u2014 profile a shell transition
|
|
854
854
|
|
|
855
855
|
events:
|
|
@@ -862,7 +862,7 @@ ${s}
|
|
|
862
862
|
examples:
|
|
863
863
|
${h("perf")} transition goHome --timeout 10000
|
|
864
864
|
${h("perf")} transition appSwitcher
|
|
865
|
-
`);break}let
|
|
865
|
+
`);break}let i=`sootsim:${t}`;Pe(` profiling ${t} transition...`),Pe(" (use --timeout 10000 if this times out)");let a=await d.send({type:"evaluate",code:`(async () => {
|
|
866
866
|
// only supported in render-worker mode
|
|
867
867
|
if (!window.__sootsimRenderHost) {
|
|
868
868
|
return { error: 'transition profiling requires render-worker mode' }
|
|
@@ -875,7 +875,7 @@ ${s}
|
|
|
875
875
|
await new Promise(r => requestAnimationFrame(() => r(undefined)))
|
|
876
876
|
|
|
877
877
|
// dispatch the shell event
|
|
878
|
-
window.dispatchEvent(new Event('${
|
|
878
|
+
window.dispatchEvent(new Event('${i}'))
|
|
879
879
|
|
|
880
880
|
// wait 600ms for transition to complete (shell animations are ~300-500ms)
|
|
881
881
|
// using fixed timing avoids complex animation-end detection
|
|
@@ -921,30 +921,30 @@ ${s}
|
|
|
921
921
|
jankFrames: frameTimes.filter(f => f > 16.67).length,
|
|
922
922
|
samples,
|
|
923
923
|
}
|
|
924
|
-
})()`});if(
|
|
924
|
+
})()`});if(a.error&&(console.error(` error: ${a.error}`),process.exit(1)),A(l)){P(a);break}if(a.warning&&console.log(` warning: ${a.warning}`),a.frames===0){console.log(" no frames captured");break}let u=a.avgMs>0?(1e3/a.avgMs).toFixed(1):"?",p=a.frames>0?(a.jankFrames/a.frames*100).toFixed(1):"0";console.log(` ${t} transition profiled:
|
|
925
925
|
|
|
926
|
-
frames: ${
|
|
927
|
-
total: ${
|
|
928
|
-
avg: ${
|
|
929
|
-
max: ${
|
|
926
|
+
frames: ${a.frames}
|
|
927
|
+
total: ${a.totalMs.toFixed(1)}ms
|
|
928
|
+
avg: ${a.avgMs.toFixed(2)}ms (${u} fps)
|
|
929
|
+
max: ${a.maxMs.toFixed(2)}ms
|
|
930
930
|
|
|
931
931
|
breakdown (avg per frame):
|
|
932
|
-
layout: ${
|
|
933
|
-
render: ${
|
|
934
|
-
copy: ${
|
|
935
|
-
aux: ${
|
|
936
|
-
other: ${
|
|
937
|
-
|
|
938
|
-
distribution (${
|
|
939
|
-
p50: ${
|
|
940
|
-
p95: ${
|
|
941
|
-
p99: ${
|
|
942
|
-
jank: ${
|
|
943
|
-
`);for(let
|
|
944
|
-
`).slice(0,3);for(let b of p)console.log(` ${b.trim()}`)}}break}case"warnings":{let o=
|
|
945
|
-
`);for(let s of t){let
|
|
946
|
-
`);for(let t of o){let s=String(t.kind).padEnd(6),
|
|
947
|
-
`);for(let u of
|
|
932
|
+
layout: ${a.layoutAvgMs?.toFixed(2)||"?"}ms
|
|
933
|
+
render: ${a.renderAvgMs?.toFixed(2)||"?"}ms
|
|
934
|
+
copy: ${a.copyAvgMs?.toFixed(2)||"?"}ms
|
|
935
|
+
aux: ${a.auxAvgMs?.toFixed(2)||"?"}ms
|
|
936
|
+
other: ${a.otherAvgMs?.toFixed(2)||"?"}ms
|
|
937
|
+
|
|
938
|
+
distribution (${a.frames} samples):
|
|
939
|
+
p50: ${a.p50.toFixed(2)}ms
|
|
940
|
+
p95: ${a.p95.toFixed(2)}ms
|
|
941
|
+
p99: ${a.p99.toFixed(2)}ms
|
|
942
|
+
jank: ${a.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(a.samples)&&a.samples.length>0&&(console.log(""),Be(a.samples.map(b=>b[1])));break}default:console.error(` unknown perf subcommand: ${o}`),console.error(" valid: stats, start, stop, frames, worst, transition"),/^--?reset$/.test(o)&&console.error(" note: 'perf start' already clears prior frames \u2014 no reset needed"),process.exit(1)}break}case"errors":{let o=r[1];if(o==="clear"){await at(d),A(l)?P({cleared:!0}):console.log(" error buffer cleared");break}let t=o?Number(o):20,s=await we(d,t);if(A(l)){P(s);break}if(s.length===0){console.log(" no errors captured");break}console.log(` ${s.length} error(s):
|
|
943
|
+
`);for(let i of s){let a=re(i.timestamp),u=i.args.map(p=>typeof p=="object"?JSON.stringify(p):p).join(" ");if(console.log(` [${a}] ${u}`),i.stack){let p=i.stack.split(`
|
|
944
|
+
`).slice(0,3);for(let b of p)console.log(` ${b.trim()}`)}}break}case"warnings":{let o=r[1]?Number(r[1]):20,t=await it(d,o);if(A(l)){P(t);break}if(t.length===0){console.log(" no warnings captured");break}console.log(` ${t.length} warning(s):
|
|
945
|
+
`);for(let s of t){let i=re(s.timestamp),a=s.args.map(u=>typeof u=="object"?JSON.stringify(u):u).join(" ");console.log(` [${i}] ${a}`)}break}case"animations":{let o=await Y(d,"listAnimations")??[];if(e.includes("--json")){console.log(JSON.stringify(o,null,2));break}if(o.length===0){console.log(" no active animations");break}console.log(` ${o.length} active animation(s):
|
|
946
|
+
`);for(let t of o){let s=String(t.kind).padEnd(6),i=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,a=Number(t.current??0).toFixed(2),u=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,b=t.loop?" loop":"",f=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${i.padEnd(14)} cur=${a.padEnd(7)} ${u.padStart(4)} ${p}${b}${f}`)}break}case"animation":{let o=r[1];(!o||o==="--help"||o==="-h")&&(console.error(` usage: ${h("animation")} <id>`),process.exit(1));let t=Number(o);Number.isFinite(t)||(console.error(` invalid id: ${o}`),process.exit(1));let s=await Y(d,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let o=r[1];(!o||o==="--help"||o==="-h")&&(console.error(` usage: ${h("stop-animation")} <id|all>`),process.exit(1));let t=o==="all"?"all":Number(o);t!=="all"&&!Number.isFinite(t)&&(console.error(` invalid id: ${o}`),process.exit(1));let s=await Y(d,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let o=r[1];if(o==="clear"){await ct(d),A(l)?P({cleared:!0}):console.log(" request buffer cleared");break}let t=o==="all",s=t?r[2]:o,i=s?Number(s):20,a=await lt(d,{failed:!t,limit:i});if(A(l)){P(a);break}if(a.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${a.length} ${t?"request(s)":"failed request(s)"}:
|
|
947
|
+
`);for(let u of a){let p=re(u.timestamp);console.log(` [${p}] ${te(u)}`),u.responseBody?console.log(` ${u.responseBody}`):u.error&&console.log(` ${u.error}`)}break}case"network":{let o=r[1],t=null,s=null,i=!1,a=!1,u=1e3,p=!1,b=!1;for(let F=0;F<l.length;F++){let w=l[F];if(w==="--filter")t=l[F+1]??null,F++;else if(w==="--limit"){let $=Number(l[F+1]);Number.isFinite($)&&(s=$),F++}else if(w==="--threshold"){let $=Number(l[F+1]);Number.isFinite($)&&$>0&&(u=$),F++}else w==="--failed"?i=!0:w==="--slow"?a=!0:w==="--tail"||w==="-f"?p=!0:w==="--json"&&(b=!0)}if(o==="clear"){await d.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(o==="get"){let F=r[2];F||(console.error(" usage: sootsim network get <id>"),process.exit(1));let w=await d.send({type:"evaluate",code:`(() => {
|
|
948
948
|
const obs = window.__sootsimObservability;
|
|
949
949
|
if (!obs) return null;
|
|
950
950
|
return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(F)}) || null;
|
|
@@ -953,15 +953,15 @@ ${s}
|
|
|
953
953
|
const obs = window.__sootsimObservability;
|
|
954
954
|
if (!obs) return { ok: false };
|
|
955
955
|
return { ok: true, entries: obs.network.getSnapshot() };
|
|
956
|
-
})()`});if(!F||!F.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return F.entries??[]},O=F=>{let w=F;if(
|
|
956
|
+
})()`});if(!F||!F.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return F.entries??[]},O=F=>{let w=F;if(i&&(w=w.filter($=>!!$.error||$.status!=null&&$.status>=400)),a&&(w=w.filter($=>$.durationMs!=null&&$.durationMs>=u)),t){let $=t.toLowerCase();w=w.filter(v=>(v.displayUrl||v.url).toLowerCase().includes($))}return a&&!p&&(w=[...w].sort(($,v)=>(v.durationMs??0)-($.durationMs??0))),w};if(!p){let F=await x(),w=O(F).slice(-f);if(b){console.log(JSON.stringify(w,null,2));break}if(w.length===0){F.length===0?console.log(" no network requests captured"):console.log(a?` no requests slower than ${u}ms (${F.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(a?` ${w.length} request(s) slower than ${u}ms (sorted by duration desc):
|
|
957
957
|
`:` ${w.length} request(s):
|
|
958
958
|
`);for(let $ of w)Gt($);break}console.log(` tailing network (ctrl-c to stop)...
|
|
959
|
-
`);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let F=await x(),w=O(F);for(let $ of w)$.durationMs!=null&&(q.has($.id)||(q.add($.id),b?console.log(JSON.stringify($)):Gt($)));await Z(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let o=
|
|
960
|
-
to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let O=()=>dt(d),q=w=>mt(w,{level:b,filter:t,showInternal:p});if(!
|
|
959
|
+
`);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let F=await x(),w=O(F);for(let $ of w)$.durationMs!=null&&(q.has($.id)||(q.add($.id),b?console.log(JSON.stringify($)):Gt($)));await Z(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let o=r[1],t=null,s=null,i=null,a=!1,u=!1,p=!1;for(let w=0;w<l.length;w++){let $=l[w];if($==="--filter")t=l[w+1]??null,w++;else if($==="--limit"){let v=Number(l[w+1]);Number.isFinite(v)&&(s=v),w++}else $==="--level"?(i=l[w+1]??null,w++):$==="--tail"||$==="-f"?a=!0:$==="--json"?u=!0:($==="--internal"||$==="--all")&&(p=!0)}let b=i?new Set(i.split(",").map(w=>w.trim()).filter(w=>w==="log"||w==="info"||w==="warn"||w==="error"||w==="debug")):null;if(o==="clear"){await ut(d),console.log(" log buffer cleared");break}let f=!u&&process.stdout.isTTY===!0,x=s??(a?500:o?Number(o):50);Number.isFinite(x)||(console.error(` invalid limit: ${o} \u2014 \`logs\` takes a numeric count (e.g. ${h("logs")} 100).
|
|
960
|
+
to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let O=()=>dt(d),q=w=>mt(w,{level:b,filter:t,showInternal:p});if(!a){let w=await O(),$=q(w).slice(-x);if(u){console.log(JSON.stringify($,null,2));break}if($.length===0){console.log(w.length===0?" no logs captured":" no matching logs");break}console.log(` ${$.length} log(s):
|
|
961
961
|
`);for(let v of $)Vt(v,f);break}console.log(` tailing logs (ctrl-c to stop)...
|
|
962
|
-
`);let H=new Set,U=!0,F=()=>{U=!1};process.on("SIGINT",F);try{for(;U;){let w=await O(),$=q(w);for(let v of $)H.has(v.id)||(H.add(v.id),u?console.log(JSON.stringify(v)):Vt(v,f));await Z(250)}}finally{process.off("SIGINT",F)}break}default:console.error(` unknown subcommand: ${g}`),process.exit(1)}if(me.has(g)&&!e.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&!await Ge(d,g)&&await S(d),!B.has(g)&&!A(l))try{await ne(d)}catch{}}catch(o){let t=o instanceof Error?o.message:String(o);console.error(` ${g??"inspect"} failed: ${t}`);let s=/^no sim connected with id (.+)$/.exec(t),
|
|
962
|
+
`);let H=new Set,U=!0,F=()=>{U=!1};process.on("SIGINT",F);try{for(;U;){let w=await O(),$=q(w);for(let v of $)H.has(v.id)||(H.add(v.id),u?console.log(JSON.stringify(v)):Vt(v,f));await Z(250)}}finally{process.off("SIGINT",F)}break}default:console.error(` unknown subcommand: ${g}`),process.exit(1)}if(me.has(g)&&!e.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&!await Ge(d,g)&&await S(d),!B.has(g)&&!A(l))try{await ne(d)}catch{}}catch(o){let t=o instanceof Error?o.message:String(o);console.error(` ${g??"inspect"} failed: ${t}`);let s=/^no sim connected with id (.+)$/.exec(t),i=/^command timed out after (\d+)s$/.exec(t),a=t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("could not connect to ws://");if(s)await St(d,_,s[1]);else if(/^no sim connected$/.test(t))$t(_);else if(i)if(await Ao(d)){let p=g??"describe";process.stderr.write(` the sim is still responsive \u2014 '${p}' just exceeded the ${i[1]}s command budget.
|
|
963
963
|
the screen's node tree is large; narrow the query or raise the budget:
|
|
964
964
|
sootsim ${p} --testid <id> # scope to one subtree
|
|
965
965
|
sootsim find --testid <id> # targeted single-node lookup
|
|
966
966
|
sootsim ${p} --timeout 60000 # raise per-command budget (ms)
|
|
967
|
-
`)}else Yt();else if(
|
|
967
|
+
`)}else Yt();else if(a)Yt();else{try{await bt(d)}catch{}try{await X({includeTail:!0})}catch{}try{await W({includeTail:!0})}catch{}}process.exit(1)}finally{d.close()}}export{Rn as runInspect};
|